消息的接收与响应
原创学习目标
• 掌握微信公众平台消息的流程及其分类。
• 掌握接收与回复消息的方法。
• 熟悉聊天机器人及其开发流程。
通过前面几章的学习,我们已经成功开启了开发者模式,并完成了开发环境的配置;对微信页面的调试和自定义菜单的开发也有了一定的了解。本章将要介绍如何接收各种类型的消息。
在学习这章内容之前,需要思考一个问题,公众平台的消息是如何交互的?这个问题的答案其实在开发者文档里已经提到:当普通微信用户向公众账号发送消息时,用户发送的消息首先会被发送到微信服务器上;然后微信服务器将 POST 消息的 XML 数据包发送到开发者填写的 URL 上;而对于每一个 POST 请求,开发者会在相应包中返回特定 XML 结构,并对该消息进行响应(目前支持回复文本、图片、图文、语音、视频、音乐)。消息交互的基本流程如图 4-1 所示。

图 4-1 消息交互流程
微信服务器与公众号服务器交互的消息分为接收普通用户消息、接收事件推送、回复消息 3 种类型。接收普通用户消息和接收事件推送是公众号服务器接收的来自微信服务器的消息,而回复消息是公众号服务器传给微信服务器的消息。
微信中的消息类型有文本、图片、语音、视频、小视频、地理位置、链接和事件消息。除了事件消息之外,其他的统称为普通消息。微信中消息的推送和响应都是以 XML 数据包传输的。
接收普通用户消息微信公众号能够接收普通用户发送的消息,包括文本消息、图片消息、语音消息、视频消息、小视频消息、地理位置消息和链接消息。
用户发送消息给公众号时,微信服务器在 5 s 之内收不到响应会断掉连接,并重新发起请求,总共重试 3 次。普通消息可以使用 MsgId 排重,以避免重复的消息对业务逻辑的影响。假如服务器无法保证在 5 s 内处理并回复消息,可以直接回复空串,微信服务器对此不会做任何处理,并且不会发起重试。需要注意的是,这里说的回复空串并不是指 XML 结构体中 content 字段的内容为空,而是指字节长度为 0 的空字符串。
封装接收消息结构当用户向公众号发送消息时,微信服务器将消息以 XML 格式通过 POST 的方式发送到填写的 URL 上。开发者文档上定义了所有普通消息类型的结构,不难发现每种类型的消息都包含参数 ToUserName、FromUserName、CreateTime、MsgType 与 MsgId,如表 4-1 所示。
表 4-1 所有消息的公有参数说明

由于所有的消息体都有表 4-1 所示的 5 个公有字段,为了减少代码冗余,可以将这些参数提取出来,封装成一个接收消息基类,不同的消息实体继承这个基类。接收消息基类的代码如下:
1. public class MessageBase 2. { 3. ///<summary> 4. ///开发者微信号 5. ///</summary> 6. public string ToUserName{ get; set; } 7. ///<summary> 8. ///发送方账号(OpenID) 9. ///</summary> 10. public string FromUserName{ get; set; } 11. ///<summary> 12. ///消息创建时间 13. ///</summary> 14. public DateTime CreateTime{ get; set; } 15. ///<summary> 16. ///消息类型 17. ///</summary> 18. public string MsgType{ get; set; } 19. ///<summary> 20. ///消息 ID 21. ///</summary> 22. public string MsgId{ get; set; } 23. }
消息的类型在前面已经提及过,别是文本(text)、图片(image)、语音(voice)、视频(video)、小视频(shortvideo)、地理位置(location)、链接(link)与事件(event)。本节主要介绍如何接收普通消息,因此这里不涉及事件 event,将在下节重点介绍。在 C#中,为了方便管理和代码编写,我们可以把这些消息类型写成一个枚举,具体如下:
1. ///<summary> 2. ///用户发送消息类型枚举 3. ///</summary> 4. public enum RequestMsgType 5. { 6. text, 7. image, 8. voice, 9. video, 10. shortvideo, 11. location, 12. link, 13. }
接下来建立继承于所有消息基类 MessageBase 的用户发送消息数据实体的基类 RequestMessageBase。
1. ///<summary> 2. ///用户发送消息基类 3. ///</summary> 4. public class RequestMessageBase:MessageBase 5. { 6. ///<summary> 7. ///用户发送消息类型 8. ///</summary> 9. public class virtual RequestMsgType MsgType 10. { 11. get { return RequestMsgType.Text;} 12. } 13. ///<summary> 14. ///消息 ID 15. ///</summary> 16. public long MsgId { get; set} 17. }
到了这里我们就可以建立用户发送消息实体,这些消息实体继承于用户发送消息数据实体的基类 RequestMessageBase。
文本消息当用户向公众号发送文本消息时,微信公众号接收到的 POST 消息的 XML 数据格式如下:
1. <xml> 2. <ToUserName><![CDATA[toUser]]></ToUserName> 3. <FromUserName><![CDATA[fromUser]]></FromUserName> 4. <CreateTime>1348831860</CreateTime> 5. <MsgType><![CDATA[text]]></MsgType> 6. <Content><![CDATA[this is a test]]></Content> 7. <MsgId>1234567890123456</MsgId> 8. </xml >
表 4-2 对所用参数进行了说明,具体如下。
表 4-2 用户向公众号发送文本消息参数说明
参数名称 | 描述 |
MsgType | 消息类型,text |
Content | 文本消息内容 |
文本消息需要继承用户发送消息数据实体基类 RequestBaseMessage,接收文本消息代码如下:
1. ///<summary> 2. ///接收文本消息 3. ///</summary> 4. public class RequestTextMessage: RequestBaseMessage 5. { 6. public class override RequestMsgType MsgType 7. { 8. get { return RequestMsgType.text;} 9. } 10. ///<summary> 11. ///消息内容 12. ///</summary> 13. public string Content{ get; set; } 14. }
当用户向公众号发送图片消息时,微信公众号接收到的 POST 消息的 XML 数据格式如下:
1. <xml> 2. <ToUserName><![CDATA[toUser]]></ToUserName> 3. <FromUserName><![CDATA[fromUser]]></FromUserName> 4. <CreateTime>1348831860</CreateTime> 5. <MsgType><![CDATA[image]]></MsgType> 6. <PicUrl><![CDATA[this is a url]]></PicUrl > 7. <MediaId><![CDATA[media_id]]></MediaId> 8. <MsgId>1234567890123456</MsgId> 9. </xml >
表 4-3 对所用参数进行了说明,具体如下。
表 4-3 用户向公众号发送图片消息参数说明
参数名称 | 描述 |
MsgType | 消息类型,image |
PicUrl | 图片链接(由系统生成) |
MediaId | 图片消息媒体 ID,可以调用多媒体文件下载接口拉取数据 |
图片消息需要继承 RequestBaseMessage,接收图片消息的代码如下:
1. ///<summary> 2. ///接收图片消息 3. ///</summary> 4. public class RequestImageMessage: RequestBaseMessage 5. { 6. public class override RequestMsgType MsgType 7. { 8. get { return RequestMsgType.image;} 9. } 10. ///<summary> 11. ///图片链接 12. ///</summary> 13. public string PicUrl{ get; set; } 14. ///<summary> 15. ///图片消息媒体 ID 16. ///</summary> 17. public string MediaId{ get; set; } 18. }
当用户向公众号发送语音消息时,微信公众号接收到的 POST 消息的 XML 数据格式如下:
1. <xml> 2. <ToUserName><![CDATA[toUser]]></ToUserName> 3. <FromUserName><![CDATA[fromUser]]></FromUserName> 4. <CreateTime>1357290913</CreateTime> 5. <MsgType><![CDATA[voice]]></MsgType> 6. <Format><![CDATA[Format]]></Format> 7. <MediaId><![CDATA[media_id]]></MediaId> 8. <MsgId>1234567890123456</MsgId> 9. </xml >
表 4-4 对所用参数进行了说明,具体如下。
表 4-4 用户向公众号发送语音消息参数说明
参数名称 | 描述 |
MsgType | 语音为 voice |
Format | 语音格式,如 amr、speex 等 |
MediaId | 语音消息媒体 ID,可以调用多媒体文件下载接口拉取数据 |
需要注意的是,开通语音识别后,用户每次发送语音给公众号时,微信会在推送的语音消息 XML 数据包中增加一个 Recognition 字段(注:由于客户端缓存,开发者开启或者关闭语音识别功能,对新关注者立刻生效,对已关注者需要 24 小时生效。开发者可以重新关注此账号进行测试)。开启语音识别后的语音 XML 数据包如下:
1. <xml> 2. <ToUserName><![CDATA[toUser]]></ToUserName> 3. <FromUserName><![CDATA[fromUser]]></FromUserName> 4. <CreateTime>1357290913</CreateTime> 5. <MsgType><![CDATA[voice]]></MsgType> 6. <MediaId><![CDATA[media_id]]></MediaId> 7. <Format><![CDATA[Format]]></Format> 8. <Recognition><![CDATA[腾讯微信团队]]></Recognition> 9. <MsgId>1234567890123456</MsgId> 10. </xml >
多出来的字段中,Format 为语音格式,一般为 amr;Recognition 为语音识别结果,使用 UTF8 编码。
语音消息需要继承 RequestBaseMessage,接收语音消息的代码如下:
1. ///<summary> 2. ///接收语音消息 3. ///</summary> 4. public class RequestVoiceMessage: RequestBaseMessage 5. { 6. public class override RequestMsgType MsgType 7. { 8. get { return RequestMsgType.voice;} 9. } 10. ///<summary> 11. ///语音格式 12. ///</summary> 13. public string Format{ get; set; } 14. ///<summary> 15. ///语音消息媒体 ID 16. ///</summary> 17. public string MediaId{ get; set; } 18. ///<summary> 19. ///语音识别,UTF8 编码 20. ///</summary> 21. public string Recognition{ get; set; } 22. }
当用户向公众号发送视频消息时,微信公众号接收到的 POST 消息的 XML 数据格式如下:
1. <xml> 2. <ToUserName><![CDATA[toUser]]></ToUserName> 3. <FromUserName><![CDATA[fromUser]]></FromUserName> 4. <CreateTime>1357290913</CreateTime> 5. <MsgType><![CDATA[video]]></MsgType> 6. <MediaId><![CDATA[media_id]]></MediaId> 7. <ThumbMediaId><![CDATA[thumb_media_id]]></ ThumbMediaId > 8. <MsgId>1234567890123456</MsgId> 9. </xml >
表 4-5 对所用参数进行了说明,具体如下。
表 4-5 用户向公众号发送视频消息参数说明
参数名称 | 描述 |
MsgType | 视频为 video |
MediaId | 视频消息媒体 ID,可以调用多媒体文件下载接口拉取数据 |
ThumbMediaId | 视频消息缩略图的媒体 ID,可以调用多媒体文件下载接口拉取数据 |
视频消息需要继承 RequestBaseMessage,接收视频消息的代码如下:
1. ///<summary> 2. ///接收视频消息 3. ///<summary> 4. public class RequestVideoMessage: RequestBaseMessage 5. { 6. public class override RequestMsgType MsgType 7. { 8. get { return RequestMsgType.video;} 9. } 10. ///<summary> 11. ///视频消息缩略图 ID 12. ///</summary> 13. public string ThumbMediaId{ get; set; } 14. ///<summary> 15. ///视频消息媒体 ID 16. ///</summary> 17. public string MediaId{ get; set; } 18. }
当用户向公众号发送小视频消息时,微信公众号接收到的 POST 消息的 XML 数据格式如下:
1. <xml> 2. <ToUserName><![CDATA[toUser]]></ToUserName> 3. <FromUserName><![CDATA[fromUser]]></FromUserName> 4. <CreateTime>1357290913</CreateTime> 5. <MsgType><![CDATA[shortvideo]]></MsgType> 6. <MediaId><![CDATA[media_id]]></MediaId> 7. <ThumbMediaId><![CDATA[thumb_media_id]]></ThumbMediaId> 8. <MsgId>1234567890123456</MsgId> 9. </xml >
表 4-6 对所用参数进行了说明,具体如下。
表 4-6 用户向公众号发送小视频消息参数说明
参数名称 | 描述 |
MsgType | 小视频为 shortvideo |
MediaId | 视频消息媒体 ID,可以调用多媒体文件下载接口拉取数据 |
ThumbMediaId | 视频消息缩略图的媒体 ID,可以调用多媒体文件下载接口拉取数据 |
小视频消息需要继承 RequestBaseMessage,接收视频消息的代码如下:
1. ///<summary> 2. ///接收小视频消息 3. ///<summary> 4. public class RequestShortVedioMessage: RequestBaseMessage 5. { 6. public class override RequestMsgType MsgType 7. { 8. get { return RequestMsgType.shortvideo;} 9. } 10. ///<summary> 11. ///视频消息缩略图 ID 12. ///</summary> 13. public string ThumbMediaId{ get; set; } 14. ///<summary> 15. ///视频消息媒体 ID 16. ///</summary> 17. public string MediaId{ get; set; } 18. }
当用户向公众号发送地理位置消息时,微信公众号接收到的 POST 消息的 XML 数据格式如下:
1. <xml> 2. <ToUserName><![CDATA[toUser]]></ToUserName> 3. <FromUserName><![CDATA[fromUser]]></FromUserName> 4. <CreateTime>1351776360</CreateTime> 5. <MsgType><![CDATA[location]]></MsgType> 6. <Location_X>23.134521</Location_X> 7. <Location_Y>113.358803</Location_Y> 8. <Scale>20</Scale> 9. <Label><![CDATA[位置信息]]></Label> 10. <MsgId>1234567890123456</MsgId> 11. </xml >
表 4-7 对所用参数进行了说明,具体如下。
表 4-7 用户向公众号发送地理位置消息参数说明

地理位置消息需要继承 RequestBaseMessage,接收地理位置消息的代码如下:
1. ///<summary> 2. ///接收地理位置消息 3. ///<summary> 4. public class RequestLocationMessage : RequestBaseMessage 5. { 6. public class override RequestMsgType MsgType 7. { 8. get { return RequestMsgType.location;} 9. } 10. ///<summary> 11. ///纬度 12. ///</summary> 13. public string Location_X{ get; set; } 14. ///<summary> 15. ///经度 16. ///</summary> 17. public string Location_Y{ get; set; } 18. ///<summary> 19. ///地图缩放 20. ///</summary> 21. public string Scale{ get; set; } 22. ///<summary> 23. ///地理位置信息 24. ///</summary> 25. public string Label{ get; set; } 26. }
版权保护: 本文由 李斯特 原创,转载请保留链接: https://www.wechatadd.com/artdet/9547
阅读推荐
更多...- 利益,谁都拒绝不了「销售技巧」 2023-03-02
- 草根创业时不我待 2023-10-08
- 初识微信公众平台,获取自定义菜单配置接口 2023-07-15
- 带货本质是什么?常见的带货平台有哪些类型?带货营销概述 2023-08-26
- 微信公众号在创业创新课程中的应用研究 2023-07-14
- 创业风险识别与管理 2023-09-06
- 让你的团队拥有适度的多样性 2023-07-16
- 博恩·崔西:交易结束,但与客户的联系不能断的有效方法 2023-03-24
- 订阅号的内容组织与编辑技巧-好内容是编出来的 2023-07-02
- 业绩增长的规律,你知道吗?为您的生意带来巨大成功 2023-05-19
- SNS营销——戴尔旗舰店在人人网的成功 2022-07-23
- 高绩效销售的习惯 2023-03-04
- 销售绝招:与众不同的开场白 2023-04-01
- 启动的时间和方法,提高销售技巧 2023-04-01
- 公众账号粉丝管理和内容运营的策略与方法,公众账号内容运营的8条军规 2023-07-03
- 创新创业基础知识,创新 2023-09-06
- 创业是个什么鬼? 2023-07-14
- 绕开女性的创业陷阱,如何清晰而有条理地表达 2023-07-16