微信公众号开发教程[003]-消息管理-接收消息

        当微信用户向公众号发送消息时,微信服务器会向公众号配置的服务器URL地址发送请求,并将相关内容包装成一定格式的xml发送到这个服务器;响应时,这个服务器只要回复特定格式的xml字符串给微信服务器,微信服务器即可向微信用户的客户端转发这条回复消息.(假设公众号开发模式已开启,以后的教程,如果没有特别说明,都是如此).如下图:

微信公众号开发教程[003]-消息管理-接收消息


        例如,文本消息的xml结构如下:

<xml>
	<ToUserName><![CDATA[toUser]]></ToUserName>
	<FromUserName><![CDATA[fromUser]]></FromUserName>
	<CreateTime>1348831860</CreateTime>
	<MsgType><![CDATA[text]]></MsgType>
	<Content><![CDATA[this is a test]]></Content>
	<MsgId>1234567890123456</MsgId>
</xml>

        各参数说明如下:

微信公众号开发教程[003]-消息管理-接收消息


        其他消息类型的xml结构详见微信公众号官方文档.

        微信暂时能转发的消息类型分为:普通消息和事件推送消息.其中普通消息又分为:文本消息,图片消息,语音消息,视频消息,小视频消息,地理位置消息,链接消息;事件推消息又分为:关注/取消关注事件,扫描带参数二维码事件,上报地理位置事件,自定义菜单事件.

        下面偿试接收这些所有消息:

<?php
//文件名: http://szuzsq.tunnel.qydev.com/weixin/index.php

$wechatObj = new wechatCallbackapiTest();
$wechatObj->responseMsg();

class wechatCallbackapiTest {
	public function responseMsg() {
		//注:微信官方demo是使用$GLOBALS,而我使用的是file_get_contents的形式,来获取转发过来的xml内容.具体php配置不同,应采用不同的形式,请大家注意下,不然后可能粉丝收不到你的公众号回复的消息.
		//$str = $GLOBALS["HTTP_RAW_POST_DATA"];
		$str = file_get_contents("php://input");
		if(!isset($str) || empty($str))
			exit("");

		libxml_disable_entity_loader(true);
		$xml = simplexml_load_string($str, 'SimpleXMLElement', LIBXML_NOCDATA);

		switch($xml->MsgType) {
			case "text": {
					$fmt = "<xml>";
					$fmt .= "<ToUserName><![CDATA[%s]]></ToUserName>";
					$fmt .= "<FromUserName><![CDATA[%s]]></FromUserName>";
					$fmt .= "<CreateTime>%s</CreateTime>";
					$fmt .= "<MsgType><![CDATA[%s]]></MsgType>";
					$fmt .= "<Content><![CDATA[%s]]></Content>";
					$fmt .= "</xml>";

					$toUserName = $xml->FromUserName;
					$fromUserName = $xml->ToUserName;
					$createTime = time();
					$msgType = "text";
					$content = "接收方:$xml->ToUserName";
					$content .= "\n发送方:$xml->FromUserName";
					$content .= "\n创建时间:$xml->CreateTime";
					$content .= "\n类型:$xml->MsgType";
					$content .= "\n内容:$xml->Content";
					$content .= "\n消息ID:$xml->MsgId";

					$rs = sprintf($fmt, $toUserName, $fromUserName, $createTime, $msgType, $content);
					echo $rs;
					break;
				}
			case "image": {
					$fmt = "<xml>";
					$fmt .= "<ToUserName><![CDATA[%s]]></ToUserName>";
					$fmt .= "<FromUserName><![CDATA[%s]]></FromUserName>";
					$fmt .= "<CreateTime>%s</CreateTime>";
					$fmt .= "<MsgType><![CDATA[%s]]></MsgType>";
					$fmt .= "<Content><![CDATA[%s]]></Content>";
					$fmt .= "</xml>";

					$toUserName = $xml->FromUserName;
					$fromUserName = $xml->ToUserName;
					$createTime = time();
					$msgType = "text";
					$content = "接收方:$xml->ToUserName";
					$content .= "\n发送方:$xml->FromUserName";
					$content .= "\n创建时间:$xml->CreateTime";
					$content .= "\n类型:$xml->MsgType";
					$content .= "\n图片链接:$xml->PicUrl";
					$content .= "\n图片ID:$xml->MediaId";
					$content .= "\n消息ID:$xml->MsgId";

					$rs = sprintf($fmt, $toUserName, $fromUserName, $createTime, $msgType, $content);
					echo $rs;
					break;
				}
			case "voice": {
					$fmt = "<xml>";
					$fmt .= "<ToUserName><![CDATA[%s]]></ToUserName>";
					$fmt .= "<FromUserName><![CDATA[%s]]></FromUserName>";
					$fmt .= "<CreateTime>%s</CreateTime>";
					$fmt .= "<MsgType><![CDATA[%s]]></MsgType>";
					$fmt .= "<Content><![CDATA[%s]]></Content>";
					$fmt .= "</xml>";

					$toUserName = $xml->FromUserName;
					$fromUserName = $xml->ToUserName;
					$createTime = time();
					$msgType = "text";
					$content = "接收方:$xml->ToUserName";
					$content .= "\n发送方:$xml->FromUserName";
					$content .= "\n创建时间:$xml->CreateTime";
					$content .= "\n类型:$xml->MsgType";
					$content .= "\n语音ID:$xml->MediaID";
					$content .= "\n语音格式:$xml->Format";
					$content .= "\n语音识别结果:$xml->Recognition";
					$content .= "\n消息ID:$xml->MsgId";

					$rs = sprintf($fmt, $toUserName, $fromUserName, $createTime, $msgType, $content);
					echo $rs;
					break;
				}
			case "video": {
					$fmt = "<xml>";
					$fmt .= "<ToUserName><![CDATA[%s]]></ToUserName>";
					$fmt .= "<FromUserName><![CDATA[%s]]></FromUserName>";
					$fmt .= "<CreateTime>%s</CreateTime>";
					$fmt .= "<MsgType><![CDATA[%s]]></MsgType>";
					$fmt .= "<Content><![CDATA[%s]]></Content>";
					$fmt .= "</xml>";

					$toUserName = $xml->FromUserName;
					$fromUserName = $xml->ToUserName;
					$createTime = time();
					$msgType = "text";
					$content = "接收方:$xml->ToUserName";
					$content .= "\n发送方:$xml->FromUserName";
					$content .= "\n创建时间:$xml->CreateTime";
					$content .= "\n类型:$xml->MsgType";
					$content .= "\n视频ID:$xml->MediaId";
					$content .= "\n视频缩略图ID:$xml->ThumbMediaId";
					$content .= "\n消息ID:$xml->MsgId";

					$rs = sprintf($fmt, $toUserName, $fromUserName, $createTime, $msgType, $content);
					echo $rs;
					break;
				}
			case "shortvideo": {
					$fmt = "<xml>";
					$fmt .= "<ToUserName><![CDATA[%s]]></ToUserName>";
					$fmt .= "<FromUserName><![CDATA[%s]]></FromUserName>";
					$fmt .= "<CreateTime>%s</CreateTime>";
					$fmt .= "<MsgType><![CDATA[%s]]></MsgType>";
					$fmt .= "<Content><![CDATA[%s]]></Content>";
					$fmt .= "</xml>";

					$toUserName = $xml->FromUserName;
					$fromUserName = $xml->ToUserName;
					$createTime = time();
					$msgType = "text";
					$content = "接收方:$xml->ToUserName";
					$content .= "\n发送方:$xml->FromUserName";
					$content .= "\n创建时间:$xml->CreateTime";
					$content .= "\n类型:$xml->MsgType";
					$content .= "\n视频ID:$xml->MediaId";
					$content .= "\n视频缩略图ID:$xml->ThumbMediaId";
					$content .= "\n消息ID:$xml->MsgId";

					$rs = sprintf($fmt, $toUserName, $fromUserName, $createTime, $msgType, $content);
					echo $rs;
					break;
				}
			case "location": {
					$fmt = "<xml>";
					$fmt .= "<ToUserName><![CDATA[%s]]></ToUserName>";
					$fmt .= "<FromUserName><![CDATA[%s]]></FromUserName>";
					$fmt .= "<CreateTime>%s</CreateTime>";
					$fmt .= "<MsgType><![CDATA[%s]]></MsgType>";
					$fmt .= "<Content><![CDATA[%s]]></Content>";
					$fmt .= "</xml>";

					$toUserName = $xml->FromUserName;
					$fromUserName = $xml->ToUserName;
					$createTime = time();
					$msgType = "text";
					$content = "接收方:$xml->ToUserName";
					$content .= "\n发送方:$xml->FromUserName";
					$content .= "\n创建时间:$xml->CreateTime";
					$content .= "\n类型:$xml->MsgType";
					$content .= "\n地理位置维度:$xml->Location_X	";
					$content .= "\n地理位置经度:$xml->Location_Y	";
					$content .= "\n地图缩放大小:$xml->Scale";
					$content .= "\n地理位置信息:$xml->Label";
					$content .= "\n消息ID:$xml->MsgId";

					$rs = sprintf($fmt, $toUserName, $fromUserName, $createTime, $msgType, $content);
					echo $rs;
					break;
				}
			case "link": {
					$fmt = "<xml>";
					$fmt .= "<ToUserName><![CDATA[%s]]></ToUserName>";
					$fmt .= "<FromUserName><![CDATA[%s]]></FromUserName>";
					$fmt .= "<CreateTime>%s</CreateTime>";
					$fmt .= "<MsgType><![CDATA[%s]]></MsgType>";
					$fmt .= "<Content><![CDATA[%s]]></Content>";
					$fmt .= "</xml>";

					$toUserName = $xml->FromUserName;
					$fromUserName = $xml->ToUserName;
					$createTime = time();
					$msgType = "text";
					$content = "接收方:$xml->ToUserName";
					$content .= "\n发送方:$xml->FromUserName";
					$content .= "\n创建时间:$xml->CreateTime";
					$content .= "\n类型:$xml->MsgType";
					$content .= "\n消息标题:$xml->Title";
					$content .= "\n消息描述:$xml->Description";
					$content .= "\n消息链接:$xml->Url";
					$content .= "\n消息ID:$xml->MsgId";

					$rs = sprintf($fmt, $toUserName, $fromUserName, $createTime, $msgType, $content);
					echo $rs;
					break;
				}
			case "event": {
					switch($xml->Event) {
						case "subscribe": {
								$fmt = "<xml>";
								$fmt .= "<ToUserName><![CDATA[%s]]></ToUserName>";
								$fmt .= "<FromUserName><![CDATA[%s]]></FromUserName>";
								$fmt .= "<CreateTime>%s</CreateTime>";
								$fmt .= "<MsgType><![CDATA[%s]]></MsgType>";
								$fmt .= "<Content><![CDATA[%s]]></Content>";
								$fmt .= "</xml>";

								$toUserName = $xml->FromUserName;
								$fromUserName = $xml->ToUserName;
								$createTime = time();
								$msgType = "text";
								$content = "接收方:$xml->ToUserName";
								$content .= "\n发送方:$xml->FromUserName";
								$content .= "\n创建时间:$xml->CreateTime";
								$content .= "\n类型:$xml->MsgType";
								$content .= "\n事件类型:$xml->Event";
								//注:只有在用户还未关注公众号但扫描带参数二维码事件时,微信服务器才会带场景值的关注事件.
								//即:普通关注事件只有Event参数.扫描带参数二维码并关注事件还有EventKey,Ticket参数.
								$content .= "\n事件KEY值:$xml->EventKey";
								$content .= "\n二维码的ticket:$xml->Ticket";
								$content .= "\n消息ID:$xml->MsgId";

								$rs = sprintf($fmt, $toUserName, $fromUserName, $createTime, $msgType, $content);
								echo $rs;
								break;
							}
						case "unsubscribe": {
								$fmt = "<xml>";
								$fmt .= "<ToUserName><![CDATA[%s]]></ToUserName>";
								$fmt .= "<FromUserName><![CDATA[%s]]></FromUserName>";
								$fmt .= "<CreateTime>%s</CreateTime>";
								$fmt .= "<MsgType><![CDATA[%s]]></MsgType>";
								$fmt .= "<Content><![CDATA[%s]]></Content>";
								$fmt .= "</xml>";

								$toUserName = $xml->FromUserName;
								$fromUserName = $xml->ToUserName;
								$createTime = time();
								$msgType = "text";
								$content = "接收方:$xml->ToUserName";
								$content .= "\n发送方:$xml->FromUserName";
								$content .= "\n创建时间:$xml->CreateTime";
								$content .= "\n类型:$xml->MsgType";
								$content .= "\n事件类型:$xml->Event";
								$content .= "\n消息ID:$xml->MsgId";

								$rs = sprintf($fmt, $toUserName, $fromUserName, $createTime, $msgType, $content);
								echo $rs;
								break;
							}
						case "SCAN": {
								$fmt = "<xml>";
								$fmt .= "<ToUserName><![CDATA[%s]]></ToUserName>";
								$fmt .= "<FromUserName><![CDATA[%s]]></FromUserName>";
								$fmt .= "<CreateTime>%s</CreateTime>";
								$fmt .= "<MsgType><![CDATA[%s]]></MsgType>";
								$fmt .= "<Content><![CDATA[%s]]></Content>";
								$fmt .= "</xml>";

								$toUserName = $xml->FromUserName;
								$fromUserName = $xml->ToUserName;
								$createTime = time();
								$msgType = "text";
								$content = "接收方:$xml->ToUserName";
								$content .= "\n发送方:$xml->FromUserName";
								$content .= "\n创建时间:$xml->CreateTime";
								$content .= "\n类型:$xml->MsgType";
								$content .= "\n事件类型:$xml->Event";
								$content .= "\n事件KEY值:$xml->EventKey";
								$content .= "\n二维码的ticket:$xml->Ticket";
								$content .= "\n消息ID:$xml->MsgId";

								$rs = sprintf($fmt, $toUserName, $fromUserName, $createTime, $msgType, $content);
								echo $rs;
								break;
							}
						case "LOCATION": {
								$fmt = "<xml>";
								$fmt .= "<ToUserName><![CDATA[%s]]></ToUserName>";
								$fmt .= "<FromUserName><![CDATA[%s]]></FromUserName>";
								$fmt .= "<CreateTime>%s</CreateTime>";
								$fmt .= "<MsgType><![CDATA[%s]]></MsgType>";
								$fmt .= "<Content><![CDATA[%s]]></Content>";
								$fmt .= "</xml>";

								$toUserName = $xml->FromUserName;
								$fromUserName = $xml->ToUserName;
								$createTime = time();
								$msgType = "text";
								$content = "接收方:$xml->ToUserName";
								$content .= "\n发送方:$xml->FromUserName";
								$content .= "\n创建时间:$xml->CreateTime";
								$content .= "\n类型:$xml->MsgType";
								$content .= "\n事件类型:$xml->Event";
								$content .= "\n地理位置纬度:$xml->Latitude";
								$content .= "\n地理位置经度:$xml->Longitude";
								$content .= "\n地理位置精度:$xml->Precision";
								$content .= "\n消息ID:$xml->MsgId";

								$rs = sprintf($fmt, $toUserName, $fromUserName, $createTime, $msgType, $content);
								echo $rs;
								break;
							}
						case "CLICK": {
								$fmt = "<xml>";
								$fmt .= "<ToUserName><![CDATA[%s]]></ToUserName>";
								$fmt .= "<FromUserName><![CDATA[%s]]></FromUserName>";
								$fmt .= "<CreateTime>%s</CreateTime>";
								$fmt .= "<MsgType><![CDATA[%s]]></MsgType>";
								$fmt .= "<Content><![CDATA[%s]]></Content>";
								$fmt .= "</xml>";

								$toUserName = $xml->FromUserName;
								$fromUserName = $xml->ToUserName;
								$createTime = time();
								$msgType = "text";
								$content = "接收方:$xml->ToUserName";
								$content .= "\n发送方:$xml->FromUserName";
								$content .= "\n创建时间:$xml->CreateTime";
								$content .= "\n类型:$xml->MsgType";
								$content .= "\n事件类型:$xml->Event";
								$content .= "\n事件KEY值:$xml->EventKey";
								$content .= "\n消息ID:$xml->MsgId";

								$rs = sprintf($fmt, $toUserName, $fromUserName, $createTime, $msgType, $content);
								echo $rs;
								break;
							}
						case "VIEW": {
								$fmt = "<xml>";
								$fmt .= "<ToUserName><![CDATA[%s]]></ToUserName>";
								$fmt .= "<FromUserName><![CDATA[%s]]></FromUserName>";
								$fmt .= "<CreateTime>%s</CreateTime>";
								$fmt .= "<MsgType><![CDATA[%s]]></MsgType>";
								$fmt .= "<Content><![CDATA[%s]]></Content>";
								$fmt .= "</xml>";

								$toUserName = $xml->FromUserName;
								$fromUserName = $xml->ToUserName;
								$createTime = time();
								$msgType = "text";
								$content = "接收方:$xml->ToUserName";
								$content .= "\n发送方:$xml->FromUserName";
								$content .= "\n创建时间:$xml->CreateTime";
								$content .= "\n类型:$xml->MsgType";
								$content .= "\n事件类型:$xml->Event";
								$content .= "\n事件KEY值:$xml->EventKey";
								$content .= "\n消息ID:$xml->MsgId";

								$rs = sprintf($fmt, $toUserName, $fromUserName, $createTime, $msgType, $content);
								echo $rs;
								break;
							}
					}
					break;
				}
		}
	}
}
?>



效果图,如下:

文本消息

微信公众号开发教程[003]-消息管理-接收消息


图片消息
微信公众号开发教程[003]-消息管理-接收消息


语音消息
微信公众号开发教程[003]-消息管理-接收消息


视频消息
微信公众号开发教程[003]-消息管理-接收消息


小视频消息
微信公众号开发教程[003]-消息管理-接收消息


地理位置消息
微信公众号开发教程[003]-消息管理-接收消息


链接消息

微信公众号开发教程[003]-消息管理-接收消息


关注事件

微信公众号开发教程[003]-消息管理-接收消息


        以下事件暂时没截到效果图.

        微信官方文档里说:"其中,某些事件推送在发生后,是允许开发者回复用户的,某些则不允许,详细说明请见本页末尾的微信推送消息与事件说明。".我没找着那个说明.也不知道是否微信服务器不能接收回复,还是微信服务器接收回复后不会向公众号服务器转发.如果有同学知道,也请告诉我.不过我用微信公众平台接口调试工具,似乎都返回成功,代码应该是没问题了的.

        取消关注事件

        扫描带参数二维码事件

        上报地理位置事件

        自定义菜单事件--点击菜单拉取消息时的事件推送

        自定义菜单事件--点击菜单跳转链接时的事件推送


微信公众平台接口调试工具:   https://mp.weixin.qq.com/debug/

微信公众号开发教程[003]-消息管理-接收消息

上一篇:微信公众号开发教程[006]-PHP使用CURL详解


下一篇:微信智能跑鞋技术解密