你所在的位置:微信群>互联网推广>正文

微信公众平台开发技术-功能设计

原创
发布时间: 2023-07-15 13:10:12 热度: 219 作者: 李斯特 来源: 微信加 本文共 11198 字 阅读需要 38 分钟
功能设计天气预报功能可以细分为天气预报和空气质量查询,用户在公众号内发送规定的文字信息,后台处理后将相关信息反馈给用户。
功能设计

天气预报功能可以细分为天气预报和空气质量查询,用户在公众号内发送规定的文字信息,后台处理后将相关信息反馈给用户。

设计天气预报发送格式为「天气:城市名称」,如「天气:重庆」。用户只需要在输入框内输入「天气:重庆」,并发送至公众号,公众号就会将此消息经微信服务器转发到微信接入框架,而框架会根据请求的内容去调用天气 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