微信公众平台开发技术-功能设计
原创天气预报功能可以细分为天气预报和空气质量查询,用户在公众号内发送规定的文字信息,后台处理后将相关信息反馈给用户。
设计天气预报发送格式为「天气:城市名称」,如「天气:重庆」。用户只需要在输入框内输入「天气:重庆」,并发送至公众号,公众号就会将此消息经微信服务器转发到微信接入框架,而框架会根据请求的内容去调用天气 API,获取到天气信息数据,之后将天气信息数据进行处理,转换成规定的格式,最后通过微信公众号反馈给用户。具体流程如图 9-5 所示。

图 9-5 气象消息处理流程
气象消息的主要步骤有如下几步。
步骤一:用户使用微信客户端向公众号发送消息。
步骤二:微信服务器将接收到的消息通过 HTTP POST 将消息发送到第三方服务器。
步骤三:第三方服务器接收并处理消息。
步骤四:返回处理结果。判定用户发送来的消息,调用阿里云 API 接口,获取天气 JSON 数据,然后将数据模式化处理,准备发送。
步骤五:将处理结果返回,通过公众号呈现给用户,此时也是通过微信服务器进行转发的。
当用户输入的消息内容不符合格式要求时给予提示,具体如图 9-6 所示。

图 9-6 格式不正确时的提示
当用户成功输入指定的天气后,系统会根据用户输入的城市去获取天气信息,然后将当前城市的天气实况,以及未来 5 小时内的天气进行预报,具体返回信息如图 9-7 所示。

图 9-7 天气预报信息
同样,当用户成功输入指定城市的空气质量格式后,系统根据用户输入的城市去获取空气质量数据,然后将当前城市的空气指数以及 PM2.5 和 PM10 数据返回给用户,具体如图 9-8 所示。
图 9-8 空气质量信息

开发实现主要经过消息接收、阿里云 API 接口调用、接口数据处理、消息发送 4 个步骤来处理。
消息接收消息接收使用的是 MVC 框架,关键的控制器是 WeixinController。从微信服务器发送过来的消息接收到消息解析,再到根据接收消息进行后台数据处理,再到消息发送,都是由该控制器中 Index 的 POST 方法完成的。也就是说,这是和微信服务器进行交互的关键点,将收到的 XML 文件经信息解析后根据不同类型进行相应的响应,把响应的数据再转换成 XML 发给微信服务器。
1. /// <summary> 2. /// 用户发送消息后,微信平台自动 POST 一个请求到这里,并等待响应 XML 3. /// </summary> 4. [HttpPost] 5. [ActionName(「Index」)] 6. public ActionResult Post(PostModel postModel) 7. { 8. if (!CheckSignature.Check(postModel.Signature, postModel.Timestamp, postModel.Nonce, Token)) 9. { 10. return Content(「参数错误!」); 11. } 12. #region 打包 PostModel 信息 13. postModel.Token = Token;//与自己后台的设置保持一致 14. postModel.EncodingAESKey = EncodingAESKey; //与自己后台的设置保持一致 15. postModel.AppId = AppId;//与自己后台的设置保持一致 16. #endregion 17. //v4.2.2 之后的版本,可以设置每个人上下文消息储存的最大数量,防止内存 //占用过多,如果该参数小于等于 0,则不限制 18. var maxRecordCount = 10; 19. //自定义 MessageHandler,对微信请求进行的详细判断操作都在这里面 20. var messageHandler = new CustomMessageHandler(Request. InputStream, postModel, maxRecordCount); 21. try 22. { 23. 24. /* 如果需要添加消息去重功能,只需打开 OmitRepeatedMessage 功能, SDK 会自动处理 25. * 收到重复消息通常是因为微信服务器没有及时收到响应,会持续发送 2~5 条相同内容的 RequestMessage*/ 26. messageHandler.OmitRepeatedMessage = true; 27. //执行微信处理过程 28. messageHandler.Execute(); 29. return new FixWeixinBugWeixinResult(messageHandler); //为了解决 5.0 版本换行 Bug 暂时添加的方法,平时用下面一种方法即可 30. //return new WeixinResult(messageHandler); 31. } 32. catch (Exception ex) 33. { 34. #region 异常处理 35. WeixinTrace.Log(「MessageHandler 错误:{0}」, ex.Message); 36. using (TextWriter tw = new StreamWriter(Server.MapPath (「~/App_Data/Error_」 + _getRandomFileName() + 「.txt」))) 37. { 38. tw.WriteLine(「ExecptionMessage:」 + ex.Message); 39. tw.WriteLine(ex.Source); 40. tw.WriteLine(ex.StackTrace); 41. if (messageHandler.ResponseDocument != null) 42. { 43. tw.WriteLine(messageHandler.ResponseDocument. ToString()); 44. } 45. if (ex.InnerException != null) 46. { 47. tw.WriteLine(「======= InnerException =======」); 48. tw.WriteLine(ex.InnerException.Message); 49. tw.WriteLine(ex.InnerException.Source); 50. tw.WriteLine(ex.InnerException.StackTrace); 51. } 52. tw.Flush(); 53. tw.Close(); 54. } 55. return Content(「」); 56. #endregion 57. } 58. }
上述代码中,messageHandler 对象的 CustomMessageHandler 类是 Senparc 框架中 MessageHandler 基类的继承类,就是在这个类里去实现消息的解析判定的。人们可以根据不同的类型进行不同后台操作,如接收到图片的操作方法为 OnImageRequest,音频为 OnVoiceRequest,对于本例的文本操作,具体使用的判定方法为处理文字请求的 OnTextRequest 方法。具体实现如下:
1. public override IResponseMessageBase OnTextRequest(RequestMessageText requestMessage) 2. { 3. //可参考 OnLocationRequest 方法或/Service/LocationSercice.cs 4. 5. var responseMessage = base.CreateResponseMessage<Response MessageNews>(); 6. string sendcontent = requestMessage.Content; 7. string cityname = sendcontent.Substring(sendcontent.IndexOf (':') + 1); 8. string substr = 「」; 9. if (sendcontent.IndexOf(『:』) != -1) 10. substr = sendcontent.Substring(0, sendcontent.IndexOf(『:』)); 11. //Log.Debug(「获取到响应及解析:」, sendcontent + 「;」 + cityname // + 「:」 + substr); 12. switch (substr) 13. { 14. case 「天气」: 15. ALiMessageHandler.ForcastGet(responseMessage, cityname); 16. break; 17. case 「空气质量」: 18. ALiMessageHandler.PMGet(responseMessage, cityname); 19. break; 20. default: 21. responseMessage.Articles.Add(new Article() 22. { 23. Title = 「预报格式为:天气:城市名称;空气质量:城市名称。」, 24. Description = 「您发送的内容是:」 + sendcontent, 25. PicUrl = 「」, 26. Url = 「」 27. }); 28. break; 29. } 30. 31. return responseMessage; 32. }
这里使用了两个关键的类实体:一个是 requestMessage,另一个是 responseMessage。前者是请求消息实体,也就是用户发过来的消息实体;后者为发送消息实体。具体过程:首先判断属性 MsgType 的类型是否为 Text,确定为文本信息消息后用属性 Content 获取用户发来的消息,并将这些消息的内容进行选择判定;然后判断是否有天气或空气质量字样,如果有,则进入阿里云调用接口,如果没有则输出提示内容。
API接口调用当判断发送过来的消息的格式为「天气:城市名称」或「空气质量:城市名称」时,则调用阿里云 API 获取天气或空气质量数据。调用阿里云 API 需要确定调用接口的方法及相关参数,调用 API 接口可以使用一个独立的项目 api-gateway-demo-sign-net,关键是可以使用其中的 ShowapiRequest 类,此类可以实现 HTTP 的 GET 和 POST 方法,核心代码如下:
1. public String doImagePost() 2. { 3. Dictionary<String, String> headers = new Dictionary<string, string>(); 4. headers.Add(HttpHeader.HTTP_HEADER_CONTENT_TYPE, ContentType.CONTENT_TYPE_JSON); 5. headers.Add(HttpHeader.HTTP_HEADER_ACCEPT, ContentType.CONTENT_TYPE_JSON); 6. headers.Add("Authorization", "APPCODE " + this.appcode); 7. 8. String ret = ""; 9. using (HttpWebResponse response = HttpUtil.HttpPost(this.host, this.path, this.appcode, this.readTimeout, headers, null, this.bodys)) 10. { 11. //Console.WriteLine(response.StatusCode); 12. //Console.WriteLine(response.Method); 13. //Console.WriteLine(response.Headers); 14. Stream st = response.GetResponseStream(); 15. StreamReader reader = new StreamReader(st, Encoding. GetEncoding("utf-8")); 16. ret = reader.ReadToEnd() + Constants.LF; 17. 18. } 19. return ret; 20. }
使用 ALiMessageHandler 类来处理天气报务,其中,方法 ForcastGet(responseMessage,cityname)用于获取天气预报,方法 PMGet(responseMessage, cityname)用于获取空气质量。下面以获取天气预报为例,将 API 获取到的 JSON 数据转换成 JObject,根据返回的不同格式来转换对象数据或对象。具体代码如下:
1. public class ALiMessageHandler 2. { 3. /// <summary> 4. /// 天气预报数据调用 5. /// </summary> 6. /// <param name=「rmn」></param> 7. /// <param name=「cityname」></param> 8. public static void ForcastGet(ResponseMessageNews rmn, String cityname) 9. { 10. ShowapiRequest req = new ShowapiRequest(「http://jisutqybmf. market.alicloudapi.com」, 「/weather/query」, 11. 「4ee9e3121f6d4b349c8 c51412e33eb7f」); 12. String ret = req.addTextPara(「city」, cityname).doGet(); //如果是 POST,则最后调用.doPost() 13. 14. //Log.Debug(「获取到的 JOSN 串:」, ret); 15. JObject jo = JObject.Parse(ret); 16. //JObject jo = (JObject)JsonConvert.DeserializeObject(ret); 17. string msg = jo[「msg」].ToString(); 18. 19. if (msg == 「ok」) 20. { 21. //总结果 22. var result = jo[「result」]; 23. //指数 24. var index = (JArray)result[「index」]; 25. //hourly 26. var hourly = (JArray)result[「hourly」]; 27. string city = jo[「result」][「city」].ToString(); 28. string content = city + 「天气预报:」; 29. content = content + 「[实况]温度」 + result[「temp」].ToString() + 「度,湿度」 + result[「humidity」].ToString(); 30. 31. //ResponseMessageNews rmn = new ResponseMessageNews(); 32. //rmn.Content = 「这里是正文内容,一共将发 2 条 Article。」; 33. rmn.Articles.Add(new Article() 34. { 35. Title = city + 「天气预报:」, 36. Description = 「」, 37. PicUrl = 「」, 38. Url = 「」 39. }); 40. string runtime = 「[实况]温度」 + result[「temp」].ToString() + 「度,湿度」 + result[「humidity」].ToString() + 「 」; 41. runtime = runtime + result[「winddirect」].ToString() + 「 」 + result[「windpower」].ToString() + 「发布时间:」 + result[「updatetime」]. ToString(); 42. rmn.Articles.Add(new Article() 43. { 44. Title = runtime, 45. Description = 「11」, 46. PicUrl = 「」, 47. Url = 「」 48. }); 49. int i = 0; 50. foreach (JObject aa in hourly) 51. { 52. string str1 = 「时间:」 + aa[「time」].ToString() + 「,」 + aa[「weather」].ToString() + 「,温度」 + aa[「temp」].ToString(); 53. string pathstr = 「WXProxy/icon/weathercn/」 + aa[「img」]. ToString() + 「.png」; 54. rmn.Articles.Add(new Article() 55. { 56. Title = str1, 57. Description = 「22」, 58. PicUrl = 「https://www.wechatadd.com/」 + pathstr, 59. Url = 「」 60. }); 61. i = i + 1; 62. if (i == 5) 63. break; 64. } 65. } 66. else 67. { 68. rmn.Articles.Add(new Article() 69. { 70. Title = 「天气预报格式为:天气:城市名称,如天气:重庆。」, 71. Description = 「您发送的内容是:天气:」 + cityname + 「 」 + msg, 72. PicUrl = 「」, 73. Url = 「」 74. }); 75. } 76. 77. } 78. }
版权保护: 本文由 李斯特 原创,转载请保留链接: https://www.wechatadd.com/artdet/9565
- 上一篇:微信公众平台开发技术-接口使用
- 下一篇:微信公众平台开发技术-游戏开发应用实例
阅读推荐
更多...- 齐心协力,共同经营——打造「命运共同体」 2023-07-18
- 直播销售:怎样发声才能带动直播气氛? 2023-05-22
- 什么样的人才算是富人? 2024-07-06
- 阿里巴巴、百度引流具体应该怎样做? 2023-08-26
- 猜准顾客的十大心理需求——销售技巧 2023-03-04
- 能力测试:销售前的准备充分吗 2023-03-24
- 走中国特色的创业之路 2023-10-08
- 让业绩高速增长!产品策略畅销品背后的智慧 2023-03-13
- 找到打开客户「心门」的钥匙:客户惯常的消费心理--销售的关键在哪里? 2023-03-13
- 旅行动力「面对挑战,我加倍努力,并取得成功。」(努力地工作心理)——销售技巧 2023-03-04
- 制定营销计划时如何制定预算? 2022-07-29
- (小红书运营)定位第二步:注册初期选择定位标签 2022-06-28
- 借助完美产品体验,给客户十分美妙的感觉「销售技巧」 2023-03-04
- 微信公众平台常用接口-关注事件消息 2023-07-11
- 是的……最终会有一个时刻能「达成」销售「销售技巧」 2023-03-02
- 「互联网+」背景下大学生微商创业的相关财务问题探讨 2023-07-14
- 和气生财是做销售的硬道理 2023-03-04
- 销售心理学:悟透这 3 步御心术,顾客乖乖听你话,赚钱不难 2023-05-22