本节书摘来自华章出版社《微信公众平台开发最佳实践》一 书中的第3章,第3.2节,作者:方倍工作室,更多章节内容可以访问云栖社区“华章计算机”公众号查看。
3.2 发送被动响应消息
微信公众账号能够回复用户发送的六种类型的消息:文本、图片、语音、视频、音乐、图文。其中图文又可分为单图文和多图文。下面将分别介绍这几种消息。
3.2.1 文本消息
微信公众账号向用户回复文本消息的示例如图3-7所示。
微信公众账号回复用户文本消息时的XML数据格式如下所示:
<xml>
<ToUserName><![CDATA[oIDrpjqASyTPnxRmpS9O_
ruZGsfk]]></ToUserName>
<FromUserName><![CDATA[gh_680bdefc8c5d]]></From
UserName>
<CreateTime>1359036631</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[【深圳】天气实况 温度:27℃ 湿度:59% 风速:东北风3级
11月03日 周日 27℃~23℃ 小雨 东北风4-5级 11月04日 周一 26℃~21℃ 阵雨 微风 11月05日 周二 27℃~22℃ 阴 微风]]></Content>
</xml>```
公众账号回复文本消息的参数及描述如表3-7所示。
<div style="text-align: center"><img src="https://yqfile.alicdn.com/c9659db909a7ba92129d4777f39d6df2f81c3d7a.png" width="" height="">
</div>
####3.2.2 图片消息
微信公众账号向用户回复图片消息的示例如图3-8所示。
<div style="text-align: center"><img src="https://yqfile.alicdn.com/cb9bfc166eda2762da2363da62f167f7eb0dbbc6.png" width="" height="">
</div>
微信公众账号回复用户图片消息时的XML数据格式如下所示:
<ToUserName><![CDATA[oDeOAjj54GvEkkgCV2d7QV4-
JLMc]]>
<FromUserName><![CDATA[gh_ba6050bc0be7]]></From
UserName>
<CreateTime>1392133855</CreateTime>
<MsgType><![CDATA[image]]></MsgType>
<Image>
<MediaId><![CDATA[huNJ_LxG8vmFunz2Hjeb73X1IS02pu0jslBK24HAhSqi3bw2ZTCCYwKU2PaIer5n]]></MediaId>
</Image>
`
公众账号回复图片消息的参数及描述如表3-8所示。
3.2.3 语音消息
微信公众账号向用户回复语音消息的示例如图3-9所示。
微信公众账号回复用户语音消息时的XML数据格式如下所示:
<xml>
<ToUserName><![CDATA[oDeOAjj54GvEkkgCV2d7QV4-
JLMc]]></ToUserName>
<FromUserName><![CDATA[gh_ba6050bc0be7]]></From
UserName>
<CreateTime>1392133779</CreateTime>
<MsgType><![CDATA[voice]]></MsgType>
<Voice>
<MediaId><![CDATA[ZKqseDPkTJ4dttQqNm_UPzoIHImELr
otOYjyALGJcdRZ2XcMQ6drvVabf5Dyr_Yx]]></MediaId>
</Voice>
</xml>```
公众账号回复语音消息的参数及描述如表3-9所示。
<div style="text-align: center"><img src="https://yqfile.alicdn.com/a0cd43bc91f6cd4e78fcbf5ef81fbcd9b06bb31e.png" width="" height="">
</div>
####3.2.4 视频消息
微信公众账号向用户回复视频消息的示例如图3-10所示。
<div style="text-align: center"><img src="https://yqfile.alicdn.com/a2a7771f6cdedb4d81d32aaade665791f43c260e.png" width="" height="">
</div>
微信公众账号回复用户视频消息的XML数据格式如下所示:
<ToUserName><![CDATA[oDeOAjj54GvEkkgCV2d7QV4-
JLMc]]>
<FromUserName><![CDATA[gh_ba6050bc0be7]]></From
UserName>
<CreateTime>1392133911</CreateTime>
<MsgType><![CDATA[video]]></MsgType>
<Video>
<MediaId><![CDATA[sFH7kkZ8I-9ioYPWwLzy47pg3AWXMR
4h0cr05asJdS8Pq3TlNTWpukrFjE-iPfgv]]>
<ThumbMediaId><![CDATA[9UMnGcFgaKD1ReW3c3gLerY-
c0zsrZtj0Vd6ZXWDmy9IYLyp-D5_blWTRU0pwihI]]>
<Title><![CDATA[Title]]></Title>
<Description><![CDATA[Description]]></Description>
</Video>
`
公众账号回复视频消息的参数及描述如表3-10所示。
3.2.5 音乐消息
微信公众账号向用户回复音乐消息的示例如图3-11所示。
微信公众账号回复用户音乐消息时的XML数据格式如下所示:
<xml>
<ToUserName><![CDATA[ollB4jqgdO_cRnVXk_wRnSywgtQ8]]></ToUserName>
<FromUserName><![CDATA[gh_b629c48b653e]]></FromUserName>
<CreateTime>1372310544</CreateTime>
<MsgType><![CDATA[music]]></MsgType>
<Music>
<Title><![CDATA[最炫民族风]]></Title>
<Description><![CDATA[凤凰传奇]]></Description>
<MusicUrl><![CDATA[http://zj189.cn/zj/download/music/zxmzf.mp3]]></MusicUrl>
<HQMusicUrl><![CDATA[http://zj189.cn/zj/download/music/zxmzf.mp3]]></HQMusicUrl>
</Music>
</xml>```
公众账号回复音乐消息的参数及描述如表3-11所示。
<div style="text-align: center"><img src="https://yqfile.alicdn.com/2499035eefea1cedb775079681cef1f8221c56db.png" width="" height="">
</div>
####3.2.6 图文消息
图文信息可以分为单图文和多图文,它们实现的代码是一样的,但在显示方式有细微区别。
微信公众账号向用户回复单图文消息的示例如图3-12所示。
<div style="text-align: center"><img src="https://yqfile.alicdn.com/08d3c954c0b3c399f9ceac34004c6d1b550cc976.png" width="" height="">
</div>.
微信公众账号回复用户单图文消息的XML数据格式如下所示:
<ToUserName><![CDATA[oIDrpjqASyTPnxRmpS9O_ruZGsfk]]></ToUserName>
<FromUserName><![CDATA[gh_680bdefc8c5d]]></FromUserName>
<CreateTime>1359011899</CreateTime>
<MsgType><![CDATA[news]]></MsgType>
<Content><![CDATA[]]></Content>
<ArticleCount>1</ArticleCount>
<Articles>
<item>
<Title><![CDATA[[苹果产品信息查询]]></Title>
<Description><![CDATA[序列号:USE IMEI NUMBER
??IMEI号:358031058974471
设备名称:iPhone 5C
设备颜色:
设备容量:
激活状态:已激活
电话支持:未过期[2014-01-13]
硬件保修:未过期[2014-10-14]
生产工厂:中国]]>
</Description>
<PicUrl><![CDATA[http://www.doucube.com/weixin/weather/icon/banner.jpg]]></PicUrl>
<Url><![CDATA[]]></Url>
</item>
</Articles>
`
微信公众账号向用户回复多图文消息的示例如图3-13所示。
微信公众账号回复用户多图文消息时的XML数据格式如下所示:
<xml>
<ToUserName><![CDATA[oIDrpjqASyTPnxRmpS9O_ruZGsfk]]></ToUserName>
<FromUserName><![CDATA[gh_680bdefc8c5d]]></FromUserName>
<CreateTime>1359011829</CreateTime>
<MsgType><![CDATA[news]]></MsgType>
<Content><![CDATA[]]></Content>
<ArticleCount>5</ArticleCount>
<Articles>
<item>
<Title><![CDATA[ 【深圳】实况 温度:6℃ 湿度:62﹪ 风速:东北风2级]]> </Title>
<Description><![CDATA[]]></Description>
<PicUrl><![CDATA[http://www.doucube.com/weixin/weather/icon/banner.jpg]]></PicUrl>
<Url><![CDATA[]]></Url>
</item>
<item>
<Title><![CDATA[建议着厚外套加毛衣等服装。年老体弱者宜着大衣、呢外套加羊毛衫。]]></Title>
<Description><![CDATA[]]></Description>
<PicUrl><![CDATA[http://www.doucube.com/weixin/weather/icon/d00.gif]]></PicUrl>
<Url><![CDATA[]]></Url>
</item>
<item>
<Title><![CDATA[02月12日 周三 10℃~6℃ 阴 微风]]></Title>
<Description><![CDATA[]]></Description>
<PicUrl><![CDATA[http://www.doucube.com/weixin/weather/icon/d00.gif]]></PicUrl>
<Url><![CDATA[]]></Url>
</item>
<item>
<Title><![CDATA[02月13日 周四 11℃~7℃ 小雨 微风]]></Title>
<Description><![CDATA[]]></Description>
<PicUrl><![CDATA[http://www.doucube.com/weixin/weather/icon/d01.gif]]></PicUrl>
<Url><![CDATA[]]></Url>
</item>
<item>
<Title><![CDATA[02月14日 周五 11℃~8℃ 小雨 东北风3-4级]]></Title>
<Description><![CDATA[]]></Description>
<PicUrl><![CDATA[http://www.doucube.com/weixin/weather/icon/d01.gif]]></PicUrl>
<Url><![CDATA[]]></Url>
</item>
</Articles>
</xml>```
公众账号回复图文消息的参数及描述如表3-12所示。
<div style="text-align: center"><img src="https://yqfile.alicdn.com/372c4cc00a3c6ce93de3e25a35d9bf3caa583fca.png" width="" height="">
</div>
在单图文消息中,标题、描述、图片分开显示在各处,图片为大图。在多图文信息中,每条信息将只显示标题内容,描述字段中的内容将不显示,第一条消息标题与图片层叠,显示在上方,从第二条消息开始,对应的图片显示为小图。
####3.2.7 案例
本节将以上六种类型的响应消息通过代码实现,以便读者理解。代码如下所示:
<?php
//
// 响应用户消息
// 微信公众账号响应给用户的不同消息类型
//
define("TOKEN", "weixin");
$wechatObj = new wechatCallbackapiTest();
if (!isset($_GET['echostr'])) {
$wechatObj->responseMsg();
}else{
$wechatObj->valid();
}
class wechatCallbackapiTest
{
public function valid()
{
$echoStr = $_GET["echostr"];
if($this->checkSignature()){
echo $echoStr;
exit;
}
}
private function checkSignature()
{
$signature = $_GET["signature"];
$timestamp = $_GET["timestamp"];
$nonce = $_GET["nonce"];
$token = TOKEN;
$tmpArr = array($token, $timestamp, $nonce);
sort($tmpArr);
$tmpStr = implode($tmpArr);
$tmpStr = sha1($tmpStr);
if($tmpStr == $signature){
return true;
}else{
return false;
}
}
public function responseMsg()
{
$postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
if (!empty($postStr)){
$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
$RX_TYPE = trim($postObj->MsgType);
//用户发送的消息类型判断
switch ($RX_TYPE)
{
case "text":
$result = $this->receiveText($postObj);
break;
case "image":
$result = $this->receiveImage($postObj);
break;
case "voice":
$result = $this->receiveVoice($postObj);
break;
case "video":
$result = $this->receiveVideo($postObj);
break;
default:
$result = "unknow msg type: ".$RX_TYPE;
break;
}
echo $result;
}else {
echo "";
exit;
}
}
private function receiveText($object)
{
$keyword = trim($object->Content);
if($keyword == "文本"){
//回复文本消息
$content = "这是个文本消息";
$result = $this->transmitText($object, $content);
}
else if($keyword == "图文" || $keyword == "单图文"){
//回复单图文消息
$content = array();
$content[] = array("Title"=>"单图文标题",
"Description"=>"单图文内容",
"PicUrl"=>"http://discuz.comli.com/weixin/weather/icon/cartoon.jpg",
"Url" =>"http://m.cnblogs.com/?u= txw1958");
$result = $this->transmitNews($object, $content);
}
else if($keyword == "多图文"){
//回复多图文消息
$content = array();
$content[] = array("Title"=>"多图文1标题", "Description"=>"",
"PicUrl"=>"http://discuz.comli.com/weixin/weather/icon/cartoon.jpg", "Url" =>"http://m.cnblogs.com/?u=txw1958");
$content[] = array("Title"=>"多图文2标题", "Description"=>"", "PicUrl"=>"http://d.hiphotos.bdimg.com/wisegame/pic/item/f3529822720e0cf3ac9f1ada0846f21fbe09aaa3.jpg", "Url" =>"http://m.cnblogs.com/?u=txw1958");
$content[] = array("Title"=>"多图文3标题", "Description"=>"", "PicUrl"=>"http://g.hiphotos.bdimg.com/wisegame/pic/item/18cb0a46f21fbe090d338acc6a600c338644adfd.jpg", "Url" =>"http://m.cnblogs.com/?u=txw1958");
$result = $this->transmitNews($object, $content);
}
else if($keyword == "音乐"){
//回复音乐消息
$content = array("Title"=>"最炫民族风",
"Description"=>"歌手:凤凰传奇",
"MusicUrl"=>"http://121.199.4.61/music/zxmzf.mp3",
"HQMusicUrl"=>"http://121.199.4.61/music/zxmzf.mp3");
$result = $this->transmitMusic($object, $content);
}
return $result;
}
private function receiveImage($object)
{
//回复图片消息
$content = array("MediaId"=>$object->MediaId);
$result = $this->transmitImage($object, $content);;
return $result;
}
private function receiveVoice($object)
{
//回复语音消息
$content = array("MediaId"=>$object->MediaId);
$result = $this->transmitVoice($object, $content);;
return $result;
}
private function receiveVideo($object)
{
//回复视频消息
$content = array("MediaId"=>$object->MediaId, "ThumbMediaId"=> $object->ThumbMediaId, "Title"=>"", "Description"=>"");
$result = $this->transmitVideo($object, $content);;
return $result;
}
/*
* 回复文本消息
*/
private function transmitText($object, $content)
{
$textTpl = "<xml>
%s
%s
%s
text
%s
";
$result = sprintf($textTpl, $object->FromUserName, $object-> ToUserName, time(), $content);
return $result;
}
/*
* 回复图片消息
*/
private function transmitImage($object, $imageArray)
{
$itemTpl = "<Image>
<MediaId><![CDATA[%s]]></MediaId>
";
$item_str = sprintf($itemTpl, $imageArray['MediaId']);
$textTpl = "<xml>
%s
%s
%s
image
$item_str
";
$result = sprintf($textTpl, $object->FromUserName, $object-> ToUserName, time());
return $result;
}
/*
* 回复语音消息
*/
private function transmitVoice($object, $voiceArray)
{
$itemTpl = "<Voice>
<MediaId><![CDATA[%s]]></MediaId>
";
$item_str = sprintf($itemTpl, $voiceArray['MediaId']);
$textTpl = "<xml>
%s
%s
%s
voice
$item_str
";
$result = sprintf($textTpl, $object->FromUserName, $object-> ToUserName, time());
return $result;
}
/*
* 回复视频消息
*/
private function transmitVideo($object, $videoArray)
{
$itemTpl = "<Video>
<MediaId><![CDATA[%s]]></MediaId>
<ThumbMediaId><![CDATA[%s]]></ThumbMediaId>
<Title><![CDATA[%s]]></Title>
<Description><![CDATA[%s]]></Description>
";
$item_str = sprintf($itemTpl, $videoArray['MediaId'], $videoArray
['ThumbMediaId'], $videoArray['Title'], $videoArray['Description']);
$textTpl = "<xml>
%s
%s
%s
video
$item_str
";
$result = sprintf($textTpl, $object->FromUserName, $object-> ToUserName, time());
return $result;
}
/*
* 回复图文消息
*/
private function transmitNews($object, $arr_item)
{
if(!is_array($arr_item))
return;
$itemTpl = " <item>
<Title><![CDATA[%s]]></Title>
<Description><![CDATA[%s]]></Description>
<PicUrl><![CDATA[%s]]></PicUrl>
<Url><![CDATA[%s]]></Url>
</item>
";
$item_str = "";
foreach ($arr_item as $item)
$item_str .= sprintf($itemTpl, $item['Title'], $item ['Description'], $item['PicUrl'], $item['Url']);
$newsTpl = "<xml>
%s
%s
%s
news
]]></Content><br><ArticleCount>%s</ArticleCount><br><Articles><br>$item_str</Articles><br></xml>";</p><pre><code> $result = sprintf($newsTpl, $object->FromUserName, $object-> ToUserName, time(), count($arr_item)); return $result; } /* * 回复音乐消息 */ private function transmitMusic($object, $musicArray) { $itemTpl = "<Music> <Title><![CDATA[%s]]></Title> <Description><![CDATA[%s]]></Description> <MusicUrl><![CDATA[%s]]></MusicUrl> <HQMusicUrl><![CDATA[%s]]></HQMusicUrl></code></pre><p></Music>";</p><pre><code> $item_str = sprintf($itemTpl, $musicArray['Title'], $musicArray ['Description'], $musicArray['MusicUrl'], $musicArray['HQMusicUrl']); $textTpl = "<xml></code></pre><p><ToUserName><![CDATA[%s
%s
%s
music
$item_str
";
$result = sprintf($textTpl, $object->FromUserName, $object-> ToUserName, time());
return $result;
}
}
?>`
在上面的代码中,回复文本、图文(包括单图文和多图文)、音乐三种消息,是使用直接构造响应消息类型实现的,而图片、语音、视频三种消息需要MediaId参数,在这里直接使用用户发送过来的消息中的MediaId,然后组装成响应消息回复