前些时间,微信公众平台开放了更多的api,但是只适用于服务号。对于订阅号来说,还是很少的接口可用。
上一节中,只解决了一种类型的消息,就是事件消息。包括关注和取消关注。服务号还增加了自定义菜单事件和上报地理位置事件。
在这一讲中主要介绍一下被动回复消息,就是接收到用户上行的消息,所做出的回复。消息类型主要包括文本消息,图片消息,语音消息,视频消息,图文消息等。还有一类消息是公众号主动推送的消息,但是接口只适用于服务号。
基于回复消息,我们还可以定制自定义回复,就是基于用户的消息,及时,友好的发生相关信息。下一节中会介绍。
对于每种消息类型,我们都有一个相应的类来处理。在这一节中,只介绍回复消息。
在这一节中,我们对用户消息的处理,类似与“echo”功能,即用户输入什么,我们会返回什么。这样代码简单,而且容易说明。
上一节中讲到,根据微信推送的消息类型,我们会有不同的类来具体处理。我们先看下文本消息,文本消息是用TextMsg类来处理的。
public function processMsg($postObj) { $fromUsername = $postObj->FromUserName; $toUsername = $postObj->ToUserName; $content = trim($postObj->Content); $time = time(); if(!empty( $content )) { $this->responseMsg($postObj, $content); } } /** * responseMsg * 回复文本消息的发送 * * @param mixed $postObj 微信推送的消息结构体 * @param mixed $msg 回复消息内容 * @access public * @return void */ public function responseMsg($postObj, $msg) { $textTpl = "<xml> <ToUserName><![CDATA[%s]] > </ToUserName> <FromUserName><![CDATA[%s]] > </FromUserName> <CreateTime>%s</CreateTime> <MsgType><![CDATA[%s]] > </MsgType> <Content><![CDATA[%s]] > </Content> <FuncFlag>0</FuncFlag> </xml>"; $resultStr = sprintf($textTpl, $postObj->FromUserName, $postObj->ToUserName, time(), self::MESSAGE_TYPE, $msg); echo $resultStr; }
processMsg主要处理接收到的消息,responseMsg是具体的回复消息。postObj是微信推送来的消息体,每个消息类型都不一样。具体的属性可以参考文档。textTpl也一样,也是微信给我们定义好的,只要把相应的参数设置正确就可以。
以此类推,其他的消息类型也是如此,除了图文消息。用户不可能发送图文消息,但是我们能回复。
/** * responseMsg * 回复图文消息 * * @param mixed $postObj * @param array $news $news = array( * 'articleCount' => '', * 'news' => array( * 'title' => '', * 'description' => '', * 'picUrl' => '', * 'url' => '' * ), * array( * ... * ), * .... * ) * @access public * @return void */ public function responseMsg($postObj, array $news) { if (!$news['articleCount'] || !is_array($news['news'])) { throw new InvalidArgumentException('Invalid news'); } $textTpl = "<xml> <ToUserName><![CDATA[%s]] > </ToUserName> <FromUserName><![CDATA[%s]] > </FromUserName> <CreateTime>%s</CreateTime> <MsgType><![CDATA[%s]] > </MsgType> <ArticleCount>%s</ArticleCount> <Articles>"; $str = sprintf($textTpl, $postObj->FromUserName, $postObj->ToUserName, time(), self::MESSAGE_TYPE, $news['articleCount']); foreach ($news['news'] as $new) { $newTpl = "<item> <Title><![CDATA[%s]] > </Title> <Description><![CDATA[%s]] > </Description> <PicUrl><![CDATA[%s]] > </PicUrl> <Url><![CDATA[%s]] > </Url> </item>"; $newStr = sprintf($newTpl, $new['title'], $new['description'], $new['picUrl'], $new['url']); $str .= $newStr; } $str .= "</Articles></xml>"; echo $str; }
图文消息相对来说比较复杂,可以同时发送多条图文。 articleCount表示共发送多少条图文,news数组中定义了具体的消息。其中,picUrl是图文消息的封面,必须是公网能访问到的url就可以。url指的用户点击消息后,跳转到的地址。这里图文数量,微信也做了限制,不能超过10条。
测试代码如下:
$newsMsg = MsgController::factory(MsgController::MESSAGE_TYPE_NEWS); $news = array(); $news['articleCount'] = 1; $new = array(); $new['title'] = '测试图文消息'; $new['description'] = '这是一个测试'; $new['picUrl'] = 'http://p.qpic.cn/ecc_merchant/0/P_idc1321596_1382500696281/0'; $new['url'] = 'http://www.google.com'; $news['news'][] = $new; $newsMsg->responseMsg($postObj, $news);
可以在任何一个processMsg 中,加上测试代码就可以。
======================