7

【微信服务号开发】02.文字消息和图文消息自动回复实现

作者:stark wang

上一篇 【微信服务号开发】01.接入指南

https://segmentfault.com/a/11...

接收消息

  • 当我们向测试号发送信息的时候,就是微信像这个接口发送一个post请求

当普通微信用户向公众账号发消息时,微信服务器将POST消息的XML数据包到开发者填写的URL上。

我们可以使用以下方式来接收post请求

两种方式,如果一种方式失败,不兼容,可以使用另一种方式
// $postStr = file_get_contents('php://input');
$postStr = $GLOBALS['HTTP_RAW_POST_DATA'];

当然 接收的信息是 以xml格式体现,下面会讲到怎么提取。

记录日志

当我们在本地开发测试的时候,想知道我们发送的什么信息,我们可以在本地记录一下
使用 file_put_contents 这个函数写入日志

if (empty($postStr)) {
    file_put_contents('wx.log','post数据为空'.FILE_APPEND."\n",FILE_APPEND);
}
file_put_contents('wx.log',$postStr,FILE_APPEND);

当用户发送请求后,会在本地生成 wx.log

<xml><ToUserName><![CDATA[gh_f91894e6efcb]]></ToUserName>
<FromUserName><![CDATA[oPs5ouNL-PMrIF5Xjiw7l1fq5r2E]]></FromUserName>
<CreateTime>1512612101</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[老师,我爱你]]></Content>
<MsgId>6496619505755885384</MsgId>
</xml>

此时是xml格式

我们需要把 xml格式转换成对象

$xml = simplexml_load_string($postStr,'SimpleXMLElement',LIBXML_NOCDATA);

自动回复

https://mp.weixin.qq.com/wiki...
接收普通消息

当普通微信用户向公众账号发消息时,微信服务器将POST消息的XML数据包到开发者填写的URL上。

请注意:

1、关于重试的消息排重,推荐使用msgid排重。

2、微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次。假如服务器无法保证在五秒内处理并回复,

可以直接回复空串,微信服务器不会对此作任何处理,并且不会发起重试。详情请见“发送消息-被动回复消息”。

3、如果开发者需要对用户消息在5秒内立即做出回应,即使用“发送消息-被动回复消息”接口向用户被动回复消息时,可以在

公众平台官网的开发者中心处设置消息加密。开启加密后,用户发来的消息和开发者回复的消息都会被加密(但开发者通过客服

接口等API调用形式向用户发送消息,则不受影响)。关于消息加解密的详细说明,请见“发送消息-被动回复消息加解密说明”。

实现向用户自动回复消息

当用户发送消息后,我们接收到消息后,可以根据消息的内容,向用户发送自定义的信息。
必须是xml 格式

文本消息

各消息类型的推送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>

代码实现


// 当用户回复一些信息的时候,我们需要向用户回复一些特定的内容
// replyMsg 函数是处理 xml 格式,把需要的数据重新组装
function replyMsg($content){
    global $xml;
    $str = sprintf('<xml>
 <ToUserName><![CDATA[%s]]></ToUserName>
 <FromUserName><![CDATA[%s]]></FromUserName>
 <CreateTime>%d</CreateTime>
 <MsgType><![CDATA[text]]></MsgType>
 <Content><![CDATA[%s]]></Content>
 <MsgId>1234567890123456</MsgId>
 </xml>',$xml->FromUserName,$xml->ToUserName,time(),$content);
 echo $str;
}


if (!empty($xml->Content)) {
    replyMsg('hi 你想干嘛?');
}

输出的信息

  • 当微信向url请求post 数据,然后返回以下信息,微信接收这些信息后,会处理,给你回复。
<xml>
 <ToUserName><![CDATA[oPs5ouLW3qg7P6CLj-jS7M1XVtSw]]></ToUserName>
 <FromUserName><![CDATA[gh_f91894e6efcb]]></FromUserName>
 <CreateTime>1512615523</CreateTime>
 <MsgType><![CDATA[text]]></MsgType>
 <Content><![CDATA[hi 你想干嘛?]]></Content>
 <MsgId>1234567890123456</MsgId>
 </xml>

回复图文消息

xml 格式

<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>

php代码函数实现

function replyArticle($data){
    global $xml;
    $article = '<ArticleCount>'.count($data).'</ArticleCount>';
    $article .= '<Articles>';
    foreach ($data as $value) {
       $article .= sprintf('<item><Title><![CDATA[%s]]></Title>',$value['title']);
       $article .= sprintf('<Description><![CDATA[%s]]></Description>',$value['desc']);
       $article .= sprintf('<PicUrl><![CDATA[%s]]></PicUrl>',$value['picurl']);
       $article .= sprintf('<Url><![CDATA[%s]]></Url></item>',$value['url']);
    }
    $article .= '</Articles>';

    $str = sprintf('<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%d</CreateTime>
<MsgType><![CDATA[news]]></MsgType>%s</xml>',$xml->FromUserName,$xml->ToUserName,time(),$article);
file_put_contents('wx.log',$str."\n\n",FILE_APPEND);
echo $str;
}

测试图文消息

// 测试图文消息
if (!empty($xml->Content)) {
    $data = [
        [
        'title' => '安琪拉',
        'url' => 'http://stark.wang',
        'picurl' => 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1513221767&di=112afbccd30f26c20392a7dfff06926a&imgtype=jpg&er=1&src=http%3A%2F%2Fqtimg.bdstatic.com%2Fhiapk%2Fgame%2F201707%2F04%2F595af6d2285d9.jpg',
        'desc' => 'hi 安琪拉!!!'
        ],
        [
        'title' => '李白,今朝有酒今朝醉',
        'url' => 'http://stark.wang',
        'picurl' => 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1512627415601&di=a48be9abc9661620472cf49c9388f221&imgtype=0&src=http%3A%2F%2Fi1.17173cdn.com%2F2fhnvk%2FYWxqaGBf%2Fcms3%2FXivJLTbldqzvDcv.jpg',
        'desc' => '今朝有酒今朝醉,李白就是一个诗人'
        ],
        [
        'title' => '钟馗',
        'url' => 'http://stark.wang',
        'picurl' => 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1513222223&di=40ac217b31655f2dee782c8be7c67aa4&imgtype=jpg&er=1&src=http%3A%2F%2Fzhidao.3533.com%2Fuploads%2Fanswer%2F20160324%2F34c6cc35fe42f302e4c96b9984f55c5e.jpg',
        'desc' => '哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈'
        ],
];

    replyArticle($data);
}

日志

<xml>
<ToUserName><![CDATA[oPs5ouMEk9AZ6Oj1rWUX8sj0DJUs]]></ToUserName>
<FromUserName><![CDATA[gh_f91894e6efcb]]></FromUserName>
<CreateTime>1512617634</CreateTime>
<MsgType><![CDATA[news]]></MsgType><ArticleCount>3</ArticleCount><Articles><item><Title><![CDATA[安琪拉]]></Title><Description><![CDATA[hi 安琪拉!!!]]></Description><PicUrl><![CDATA[https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1513221767&di=112afbccd30f26c20392a7dfff06926a&imgtype=jpg&er=1&src=http%3A%2F%2Fqtimg.bdstatic.com%2Fhiapk%2Fgame%2F201707%2F04%2F595af6d2285d9.jpg]]></PicUrl><Url><![CDATA[http://stark.wang]]></Url></item><item><Title><![CDATA[李白,今朝有酒今朝醉]]></Title><Description><![CDATA[今朝有酒今朝醉,李白就是一个诗人]]></Description><PicUrl><![CDATA[https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1512627415601&di=a48be9abc9661620472cf49c9388f221&imgtype=0&src=http%3A%2F%2Fi1.17173cdn.com%2F2fhnvk%2FYWxqaGBf%2Fcms3%2FXivJLTbldqzvDcv.jpg]]></PicUrl><Url><![CDATA[http://stark.wang]]></Url></item><item><Title><![CDATA[钟馗]]></Title><Description><![CDATA[哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈]]></Description><PicUrl><![CDATA[https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1513222223&di=40ac217b31655f2dee782c8be7c67aa4&imgtype=jpg&er=1&src=http%3A%2F%2Fzhidao.3533.com%2Fuploads%2Fanswer%2F20160324%2F34c6cc35fe42f302e4c96b9984f55c5e.jpg]]></PicUrl><Url><![CDATA[http://stark.wang]]></Url></item></Articles></xml>

手机界面

图文回复消息ok


西树先森
7.1k 声望926 粉丝

从事开发多年,前端、后端(go、Python、php)、服务架构都有涉猎,经历过大公司、创业公司,擅长前端及公司技术选型。