- 微信公眾平臺應用開發實踐
- 閆小坤 周濤
- 1167字
- 2019-01-04 05:28:06
4.5 回復消息
對于每一個POST請求,開發者需要在響應包中返回特定XML結構的響應報文,現在支持回復文本、圖片、圖文、語音、視頻、音樂。需要注意的是,回復圖片等多媒體消息需要預先上傳多媒體文件到微信服務器。
微信服務器在5秒內收不到響應會斷掉鏈接,并且重新發起請求,最多重試3次。所以我們需要有消息的排重機制,防止對同一消息或事件回復多條響應消息。對于有msgid的消息可以使用msgid排重。事件類型消息則可以使用FromUserName+CreateTime排重。
對于有些耗時較多,無法保證在5秒內應答的請求可以直接回復空串,微信服務器不會對此做任何處理,并且不會發起重試。在這種情況下,可以使用客服消息接口進行異步回復,這個將在后面介紹。
4.5.1 回復文本消息
<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>12345678</CreateTime> <MsgType><![CDATA[text]]></MsgType> <Content><![CDATA[你好]]></Content> </xml>
參數說明如表4-15所示。
表4-15 參數說明

const REPLY_TYPE_TEXT = 'text'; /** *生成向用戶發送的文字信息 * @param string $content * @return string xml字符串 */ public function outputText($content) { $textTpl = '<xml> <ToUserName><![CDATA[%s]]></ToUserName> <FromUserName><![CDATA[%s]]></FromUserName> <CreateTime>%s</CreateTime> <MsgType><![CDATA[%s]]></MsgType> <Content><![CDATA[%s]]></Content> </xml>';
$text = sprintf($textTpl, $this->_postData->FromUserName, $this->_postData->ToUserName, time(), self::REPLY_TYPE_TEXT, $content); header('Content-Type: application/xml'); echo $text; }
header函數向客戶端發送原始的HTTP報頭,因為我們要發送的是XML格式的內容,定義Content-Type為application/xml。
4.5.2 回復圖片消息
<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>12345678</CreateTime> <MsgType><![CDATA[image]]></MsgType> <Image> <MediaId><![CDATA[media_id]]></MediaId> </Image> </xml>
參數說明如表4-16所示。
表4-16 參數說明

const REPLY_TYPE_IMAGE='image'; /** *生成向用戶發送的圖片信息 * @param string $media_id * @return string xml字符串 */ public function outputImage($media_id) { $textTpl = '<xml> <ToUserName><![CDATA[%s]]></ToUserName> <FromUserName><![CDATA[%s]]></FromUserName> <CreateTime>%s</CreateTime> <MsgType><![CDATA[%s]]></MsgType> <Image> <MediaId><![CDATA[%s]]></MediaId> </Image> </xml>';
$text = sprintf($textTpl, $this->_postData->FromUserName, $this->_postData->ToUserName, time(), self::REPLY_TYPE_IMAGE, $media_id); header('Content-Type: application/xml'); echo $text; }
注意這里的mediaid是筆者上傳獲取的,而且微信服務器對多媒體只保存3天,所以讀者在實驗這段代碼的時候請自行上傳多媒體文件獲取mediaid。上傳下載多媒體的接口將在后面介紹,如圖4-18所示。

圖4-18
4.5.3 回復語音消息
<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>12345678</CreateTime> <MsgType><![CDATA[voice]]></MsgType> <Voice> <MediaId><![CDATA[media_id]]></MediaId> </Voice> </xml>
參數說明如表4-17所示。
表4-17 參數說明

const REPLY_TYPE_VOICE = 'voice'; /** *生成向用戶發送的語音信息 * @param string $content * @return string xml字符串 */ public function outputVoice($media_id) { $textTpl = '<xml> <ToUserName><![CDATA[%s]]></ToUserName> <FromUserName><![CDATA[%s]]></FromUserName> <CreateTime>%s</CreateTime> <MsgType><![CDATA[%s]]></MsgType> <Voice> <MediaId><![CDATA[%s]]></MediaId> </Voice> </xml>';
$text = sprintf($textTpl, $this->_postData->FromUserName, $this->_postData->ToUserName, time(), self::REPLY_TYPE_VOICE, $media_id); header('Content-Type: application/xml'); echo $text; }
運行結果如圖4-19所示。

圖4-19
4.5.4 回復視頻消息
<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>12345678</CreateTime> <MsgType><![CDATA[video]]></MsgType> <Video> <MediaId><![CDATA[media_id]]></MediaId> <Title><![CDATA[title]]></Title> <Description><![CDATA[description]]></Description> </Video> </xml>
參數說明如表4-18所示。
表4-18 參數說明

const REPLY_TYPE_VIDEO = 'video'; /** *生成向用戶發送的視頻信息 * @param string $content * @return string xml字符串 */ public function outputVideo($videopost) { $textTpl = '<xml> <ToUserName><![CDATA[%s]]></ToUserName> <FromUserName><![CDATA[%s]]></FromUserName> <CreateTime>%s</CreateTime> <MsgType><![CDATA[%s]]></MsgType> <Video> <MediaId><![CDATA[%s]]></MediaId> <Title><![CDATA[%s]]></Title> <Description><![CDATA[%s]]></Description> </Video> </xml>';
$text = sprintf($textTpl, $this->_postData->FromUserName, $this->_postData->ToUserName, time(), self::REPLY_TYPE_VIDEO, $videopost['media_id'], $videopost['title'], $videopost['description']); header('Content-Type: application/xml'); echo $text; } private function testVideo() { $video = array( 'media_id' => 'Dx09rTLDC3nZKTSmfWMHXKxNxb01oTbgqn3yHtLPgTUmDJxSSamGW7uqNGRZp3of', 'title' => '獨墅湖', 'description' => '生活在獨墅湖' ); $this->outputVideo($video); }
運行結果如圖4-20所示。

圖4-20
4.5.5 回復音樂消息
<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>12345678</CreateTime> <MsgType><![CDATA[music]]></MsgType> <Music> <Title><![CDATA[TITLE]]></Title> <Description><![CDATA[DESCRIPTION]]></Description> <MusicUrl><![CDATA[MUSIC_Url]]></MusicUrl> <HQMusicUrl><![CDATA[HQ_MUSIC_Url]]></HQMusicUrl> <ThumbMediaId><![CDATA[media_id]]></ThumbMediaId> </Music> </xml>
參數說明如表4-19所示。
表4-19 參數說明

const REPLY_TYPE_MUSIC='music'; /** *生成向用戶發送的音樂信息 * @param type $musicpost * @return type * @throws Exception */ public function outputMusic($musicpost){ $textTpl = '<xml> <ToUserName><![CDATA[%s]]></ToUserName> <FromUserName><![CDATA[%s]]></FromUserName> <CreateTime>%s</CreateTime> <MsgType><![CDATA[%s]]></MsgType> <Music>%s</Music> </xml>';
$musicTpl = ' <Title><![CDATA[%s]]></Title> <Description><![CDATA[%s]]></Description> <MusicUrl><![CDATA[%s]]></MusicUrl> <HQMusicUrl><![CDATA[%s]]></HQMusicUrl> '; $music = ''; if (is_array($musicpost)){ $music .= sprintf($musicTpl, $musicpost['title'], $musicpost['description'], $musicpost['musicurl'], $musicpost['hdmusicurl']); }else{ throw new Exception('$posts數據結構錯誤'); }
$text = sprintf($textTpl, $this->_postData->FromUserName, $this->_postData->ToUserName, time(), self::REPLY_TYPE_MUSIC, $music); header('Content-Type: application/xml'); echo $text; } private function testMusic() { $music = array( 'title' => '在春天里', 'description' => '在春天里-汪峰', 'musicurl' => 'http://7xnmen.com1.z0.glb.clouddn.com/musicinspring.wma', 'hdmusicurl' => 'http://7xnmen.com1.z0.glb.clouddn.com/musicinspring.mp3' ); $this->outputMusic($music); }
運行結果如圖4-21所示。

圖4-21
4.5.6 回復圖文消息
<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>12345678</CreateTime> <MsgType><![CDATA[news]]></MsgType> <ArticleCount>2</ArticleCount> <Articles> <item> <Title><![CDATA[title1]]></Title> <Description><![CDATA[description1]]></Description> <PicUrl><![CDATA[picurl]]></PicUrl> <Url><![CDATA[url]]></Url> </item> <item> <Title><![CDATA[title]]></Title> <Description><![CDATA[description]]></Description> <PicUrl><![CDATA[picurl]]></PicUrl> <Url><![CDATA[url]]></Url> </item> </Articles> </xml>
參數說明如表4-20所示。
表4-20 參數說明

const REPLY_TYPE_NEWS = 'news'; /** *生成向用戶發送的圖文信息 * @param arrry $posts文章數組,每一個元素是一個文章數組,索引跟微信官方接口說明一致 * @return string xml字符串 */ public function outputNews($posts = array()) { $textTpl = '<xml> <ToUserName><![CDATA[%s]]></ToUserName> <FromUserName><![CDATA[%s]]></FromUserName> <CreateTime>%s</CreateTime> <MsgType><![CDATA[%s]]></MsgType> <ArticleCount>%d</ArticleCount> <Articles>%s</Articles> </xml>';
$itemTpl = '<item> <Title><![CDATA[%s]]></Title> <Discription><![CDATA[%s]]></Discription> <PicUrl><![CDATA[%s]]></PicUrl> <Url><![CDATA[%s]]></Url> </item>';
$items = ''; foreach ((array)$posts as $p) { if (is_array($p)) $items .= sprintf($itemTpl, $p['title'], $p['discription'], $p['picurl'], $p['url']); else throw new Exception('$posts數據結構錯誤'); }
$text = sprintf($textTpl, $this->_postData->FromUserName, $this->_postData->ToUserName, time(), self::REPLY_TYPE_NEWS, count($posts), $items); header('Content-Type: application/xml'); echo $text; }
private function testNews() { $posts = array( array( 'title' => '世界因你而不同', 'discription' => '最大化你的影響力,這就是你一生的意義。', 'picurl' => 'http://www.hers.cn/uploadfile/2011/1006/20111006022157183.jpg', 'url' => 'http://mp.weixin.qq.com/mp/appmsg/show?__biz=MjM5MDE4Njg2MQ== &appmsgid=10000072&itemidx=1&sign=bea6deb75836dbe1249dcf394e8f3c21#wechat_redirect', ), array( 'title' => '平橫', 'discription' => '心要多靜才能保持如此的平衡', 'picurl' => 'http://news.shangdu.com/304/2009/08/20/images/501_20090820_911.jpg', 'url' => 'http://mp.weixin.qq.com/mp/appmsg/show?__biz=MjM5MDE4Njg2MQ== &appmsgid=10000066&itemidx=1#wechat_redirect', ) ); // outputNews用來返回圖文信息 $xml = $this->outputNews($posts); }
運行結果如圖4-22所示。

圖4-22