3.3:公众号接收用户消息类型讲解
进入开发模式后,微信默认能接收文本(text),图片(image),语音(voice),视频(video),地理位置(location),链接(link)六种基本的消息格式。另外还可以接受关注/取消关注事件,自定义菜单事件和扫面带参数二维码事件消息。用户向公众账号发送这些消息,微信服务器将POST消息的XML数据包到开发者填写的URL上。开发者编写代码判断用户发送的消息类型和消息内容,分别给予不同的回复,实现与用户的交互。这一节我们分别讲解六种基本消息和关注\取消关注消息类型的xml数据。而自定义菜单事件和扫描带参数二维码事件消息类型将在后面的章节陆续讲解。
注意:微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次。假如服务器无法保证在五秒内处理并回复,可以直接回复空串,微信服务器不会对此作任何处理,并且不会发起重试。
3.3.1:接收文本消息
用户向微信公众账号发送文本消息示例如图3-6所示。
这里我实现的是用户向公众号发送文本消息时,公众号
返回给用户相同的消息内容。这在接下来的章节中会详
细讲解其实现过程。
用户向公众号发送文本消息时,公众号收到的消息格式
内容如下:
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>1348831860</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[你好]]></Content> 图3-6 用户发送文本消息
<MsgId>1234567890123456</MsgId>
</xml>
用户发送的文本消息的参数及描述如表3-1所示。
表3-1 文本消息参数描述
提示:<![CDATA[文本内容]]>意思是,在标记CDATA下,所有的标记、实体引用都被忽略,CDATA 部分中的所有内容都会被XML解析器忽略,这样的好处是防止用户输入恶意字符。
3.3.2:接收图片消息
用户向公众账号发送图片消息示例如图3-7所示。
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>1348831860</CreateTime>
<MsgType><![CDATA[image]]></MsgType>
<PicUrl><![CDATA[/static/
superplus/img/logo_white_ee663702.png]]></PicUrl>
<MediaId><![CDATA[dIcHbnjEh4cAWDGx5lgFuVNM3Rtze4-
M0D-zPL2B6X9ur_FfmxGc5HWifv35rMrO]]></MediaId>
<MsgId>1234567890123456</MsgId>
</xml>图3-7发送图片消息
用户向公众账号发送图片的XML格式数据参数说明如表3-2所示。
表3.3-2 用户发送图片消息参数说明
3.3.3:接收语音消息
用户向公众账号发送语音消息如图3-8所示。
发送语音消息的XML格式数据包内容如下:
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>1357290913</CreateTime>
<MsgType><![CDATA[voice]]></MsgType>
<MediaId><![CDATA[media_id]]></MediaId>
<Format><![CDATA[Format]]></Format>
<MsgId>1234567890123456</MsgId></xml>
用户发送的语音消息参数说明如表3-3 。
表3-3 语音消息参数说明
语音格式,如amr,speex等
MsgID
消息id,64位整型
3.3.4:接收视频消息
用户向公众账号发送视频消息示例如图3-9所示。、
公众号接收到的视频XML格式数据如下:
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>1357290913</CreateTime>
<MsgType><![CDATA[video]]></MsgType>
<MediaId><![CDATA[media_id]]></MediaId>
<ThumbMediaId><![CDATA[thumb_media_id]]></ThumbMediaId>
<MsgId>1234567890123456</MsgId>
</xml>
用户发送的视频消息参数说明如表3-4 。
表3-4 视频消息参数说明
3.3.5:接收地理位置消息
用户向公众账号发送地理位置消息示例如图3-10所示。
用户发送的地理位置XML格式数据包如下:
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>1351776360</CreateTime>
<MsgType><![CDATA[location]]></MsgType>
<Location_X>33.637337</Location_X>
<Location_Y>117.076050</Location_Y>
<Scale>20</Scale>
<Label><![CDATA[宿州市埇桥区026县道]]></Label>
<MsgId>1234567890123456</MsgId>
</xml>
公众号接收到的地理位置消息参数说明如表3-5所示。
表3-5 地理位置消息参数说明
3.3.6:接收链接消息
用户向公众账号发送链接消息示例如图3-11所示。
公众账号接收到的链接消息XML格式数据包如下:
<xml><ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>1351776360</CreateTime>
<MsgType><![CDATA[link]]></MsgType>
<Title><![CDATA[唯美古风]]></Title>
<Description><![CDATA[爱小说关于亲情,爱情,人生的微故事...]]></Description>
<Url><![CDATA[http://mp./s?__biz=MjM5MDQyOTYyMw==&mid=33574&idx=2&sn=07356371c76317865c9ba15673f13a4c&key=2f5eb01238e84f7e31cda77a6b0b64ee32519848bef3cf77014e01910b7dc1863f56d85d3e298cff01270443fb748b43&ascene=1&uin=OTI2ODE4OTQy&devicetype=webwx&version=70000001&pass_ticket=Hx8vE%2Bp1wOmej1eje%2BOoJJNGsJqr9mH5iiRGIh%2BIFeLP4uxBjR3OEARypaYL9KPH]]></Url>
<MsgId>1234567890123456</MsgId></xml>
链接消息参数说明如表3.3-6所示。
表3-6 链接消息参数说明
消息描述
Url
消息链接
MsgId
消息id,64位整型
3.3.7:关注\取消关注事件消息
用户在关注与取消关注公众号时,微信会把这个事件推送到开发者填写的URL。开发者根据这个事件推送的XML数据包,给用户下发消息。
1,关注事件
用户关注公众号示例如图3-12所示。
用户在关注公众号时的推送XML数据包示例如下:
<xml><ToUserName><![CDATA[gh_7da125b671fc]]></ToUserName>
<FromUserName><![CDATA[o0Ufpty46XrLN4oE3VQ00G8
2K6xA]]></FromUserName>
<CreateTime>123456789</CreateTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[subscribe]]></Event></xml>
推送的XML数据参数说明如表3-7所示。
表3.4-7 事件消息XML数据参数说明
发送方帐号(一个OpenID)
CreateTime
消息创建时间(整型)
MsgType
消息类型,event
Event
事件类型,subscribe(订阅)、unsubscribe(取消订阅)
2,取消关注事件
用户取消关注事件示例如图3-13所示。
取消关注事件的消息推送XML数据格式如下:
<xml><ToUserName><![CDATA[gh_7da125b671fc]]></ToUserName>
<FromUserName><![CDATA[o0Ufpty46XrLN4oE3VQ00G8
2K6xA]]></FromUserName>
<CreateTime>1420343391</CreateTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[unsubscribe]]></Event></xml>
推送的XML数据参数说明见表3.7。
其实用户在取消关注后,即使开发者根据微信推送的XML数据做了相应回复设置,用户也收不到消息了,但是我们可以根绝这个XML数据包获得用户的OpenId和用户取消关注的时间。用微信开发调试工具验证,结果如图3-14所示。
图3-14 取消关注公众号
3.3.8 接收语音识别结果
开通语音识别功能,用户每次发送语音给公众号时,微信会在推送的语音消息XML数据包中,增加一个Recongnition字段。需要注意的是,由于客户端缓存,开发者开启或者关闭语音识别功能,对新关注者立刻生效,对已关注用户需要24小时生效。开发者可以重新关注此帐号进行测试。语音识别示例如图3-15所示。
开启语音识别后的语音XML数据包如下:
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>1357290913</CreateTime>
<MsgType><![CDATA[voice]]></MsgType>
<MediaId><![CDATA[media_id]]></MediaId>
<Format><![CDATA[Format]]></Format>
<Recognition><![CDATA[腾讯微信团队]]></Recognition>
<MsgId>1234567890123456</MsgId>
</xml>
参数说明如表3.3-8所示。
表3-8 语音识别参数说明
3.3.9:代码实现接收消息示例
前面我们对用户向公众账号发送不同消息类型的XML数据包进行了讲解,公众号可以根据用户发送的不同类型的消息形式,分别给予不同的回复。这一小节,就来介绍这是如何用代码实现的。
代码示例如下:
<?php
1.define("TOKEN","weixin");
2.$wechatObj= new wechatCallbackapiTest();
3.if(!isset($_GET['echostr'])) {
4.$wechatObj->responseMsg();
5.}else{
6.$wechatObj->valid();
7.}
8.classwechatCallbackapiTest
9.{
10.public function valid()
11.{
12.$echoStr = $_GET["echostr"];
13.if($this->checkSignature()){
14.echo $echoStr;
15.exit;
16.}
17.}
18.private function checkSignature()
19.{
20.$signature = $_GET["signature"];
21.$timestamp =$_GET["timestamp"];
22.$nonce = $_GET["nonce"];
23.$token = TOKEN;
24.$tmpArr = array($token, $timestamp,$nonce);
25.sort($tmpArr, SORT_STRING);
26.$tmpStr = implode($tmpArr);
27.$tmpStr = sha1($tmpStr);
28.if($tmpStr == $signature){
29.return true;
30.}else{
31.return false;
32.}
33.}
34.public function responseMsg(){
35. $postStr= $GLOBALS["HTTP_RAW_POST_DATA"];
36. $postObj = simplexml_load_string($postStr,'SimpleXMLElement', LIBXML_NOCDATA);
37.$fromUsername =$postObj->FromUserName;
38.$toUsername =$postObj->ToUserName;
39. $type= $postObj->MsgType;
40. $event=$postObj->Event;
41. $rec=$postObj->Recognition;
42. $mid=$postObj->MediaId;
43. $link=$postObj->Url;
44. $latitude = $postObj->Location_X;
45. $longitude= $postObj->Location_Y;
46.$keyword =trim($postObj->Content);
47.$time = time();
48.$textTpl = "<xml>
49. <ToUserName><![CDATA[%s]]></ToUserName>
50. <FromUserName><![CDATA[%s]]></FromUserName>
51. <CreateTime>%s</CreateTime>
52. <MsgType><![CDATA[text]]></MsgType>
53. <Content><![CDATA[%s]]></Content>
54. </xml>";
55. if($keyword!=''){ $contentStr=$keyword;} //判断消息类型
56. elseif($type=="image"){$contentStr="您发送的是图片消息,消息的MediaId是".$mid;}
57. elseif($type=="voice"){$contentStr="您发送的是语音消息,消息的MediaId是".$mid;"内容是".$rec;}
58. elseif($type=="video"){$contentStr="您发送的是视频消息,消息的MediaId是".$mid;}
59. elseif($type=="location"){$contentStr="您发送的是地理位置消息,您的地理位置是:经度".$latitude."维度:".$longitude;}
60. elseif($type=="link"){$contentStr="您发送的是链接消息,消息链接为".$link;}
61.elseif($type=="event"&& $event=="subscribe"){$contentStr="欢迎关注陈小龙的微信公众账号,带你进入奇妙有趣的微信公众号开发之旅";}
62.elseif($type="event"&& $event=="unsubscribe"){$contentStr="期待您再次关注陈小龙微信公众账号。";}
63.else{echo"";}
64. $resultStr = sprintf($textTpl,$fromUsername, $toUsername, $time, $contentStr);
65.echo $resultStr;
66.}
67.}
?>
代码解读如下:
第1-7行:定义TOKEN,实例化类,调用valid验证方法,如果验证成功则调用responseMsg
回复方法。公众号的功能全靠responseMsg方法实现。
第10-33行:验证消息真实性函数。
第35-46行:获得微信服务器POST传输过来的XML数据包并解析获得相应值。包括消息发送方OpenId,接收方账号,消息类型,文本消息内容,地理位置等信息。
第48-54行:创建返回给用户文本消息的XML格式数据包。
第55行:判断如果用户发送的文本消息内容是否为空,如果不为空,则原样返回用户发送来的字符串。
第56-62行:判断用户发送的消息类型,并给出相应的文本消息回复内容。
第64行:格式化组成一个XML数据包,并替换$textTpl中相应的值。根据用户发送的消息
类型,分别给予不同的回复内容。
在responseMsg方法中,获得用户发送的XML消息数据,提取MsgType消息类型进行判断,然后对其进行判断,分别给予不同内容的文本类型的消息回复。