4-09 6,234 views
微信公众平台开启了开发者自定义菜单及消息处理后,开发者需要写一套后台代码来处理用户发送的消息及一些事件。在这提供一套明文模式包含了文本消息和图文消息回复的后台处理消息代码:
服务器配置的url文件index.php:
- <?php
- /**
- * 微信被动回复消息PHP后台url
- * 2016.4.9 by karlew
- */
- //将weixin替换为公众号后台设置的token
- define("TOKEN", "weixin");
- $wechatObj = new wechatCallbackapi();
- //判断是token验证还是消息或事件推送
- if (isset($_GET['echostr'])) {
- $wechatObj->valid();
- }else{
- $wechatObj->responseMsg();
- }
- class wechatCallbackapi
- {
- //token验证
- public function valid()
- {
- $echoStr = $_GET["echostr"];
- if($this->checkSignature()){
- echo $echoStr;
- exit;
- }
- }
- //签名验证
- private function checkSignature()
- {
- if (!defined("TOKEN")) {
- throw new Exception('TOKEN is not defined!');
- }
- $signature = $_GET["signature"];
- $timestamp = $_GET["timestamp"];
- $nonce = $_GET["nonce"];
- $token = TOKEN;
- $tmpArr = array($token, $timestamp, $nonce);
- // 按官方文档要求,需字典排序
- sort($tmpArr, SORT_STRING);
- $tmpStr = implode( $tmpArr );
- $tmpStr = sha1( $tmpStr );
- if( $tmpStr == $signature ){
- return true;
- }else{
- return false;
- }
- }
- //消息或事件回复
- public function responseMsg()
- {
- $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
- if (!emptyempty($postStr)){
- $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
- $fromUsername = $postObj->FromUserName;
- $toUsername = $postObj->ToUserName;
- $msgType = $postObj->MsgType;
- $time = time();
- //通过MsgType判断消息类型
- //文本消息
- if($msgType=="text"){
- require_once('keyword.php');
- $keyword = trim($postObj->Content);
- $responseArr = keywordResponse($keyword,$fromUsername);
- //回复文本
- if($responseArr['msgType']=="text"){
- if($responseArr['content']!="noreply"){
- textResponse($fromUsername, $toUsername, $time, $responseArr['content'])
- }
- //无匹配关键字的情况
- else{
- echo "";
- exit;
- }
- }
- //图文消息回复
- elseif($responseArr['msgType']=="news"){
- $articleCount = count($responseArr['articles']);
- newsResponse($fromUsername, $toUsername, $time, $articleCount, $responseArr['articles'])
- }
- }
- //语音消息
- elseif($msgType=="voice"){
- $content = "语音消息我们是听不到的哦。\n所以无法回复语音消息,给您造成的不便敬请谅解。";
- textResponse($fromUsername, $toUsername, $time, $content)
- }
- //事件推送
- elseif($msgType=="event"){
- $event = trim($postObj->Event);
- $eventKey = trim($postObj->EventKey);
- //用户关注事件
- if($event=="subscribe"){
- $content = "感谢关注XXXX。";
- textResponse($fromUsername, $toUsername, $time, $content)
- }
- //自定义菜单点击事件
- elseif($event=="CLICK"){
- require_once('click.php');
- $responseArr = eventResponse($eventKey,$fromUsername);
- //文字消息回复
- if($responseArr['msgType']=="text"){
- textResponse($fromUsername, $toUsername, $time, $responseArr['content'])
- }
- //图文消息回复
- elseif($responseArr['msgType']=="news"){
- $articleCount = count($responseArr['articles']);
- newsResponse($fromUsername, $toUsername, $time, $articleCount, $responseArr['articles'])
- }
- }
- //其他事件
- else{
- echo "";
- exit;
- }
- }
- //其他消息
- else{
- echo "";
- exit;
- }
- }
- //如果没有接收到消息
- else {
- echo "";
- exit;
- }
- }
- //文本消息回复
- public function textResponse($fromUsername, $toUsername, $time, $content){
- $textTpl = "<xml>
- <ToUserName><![CDATA[%s]]></ToUserName>
- <FromUserName><![CDATA[%s]]></FromUserName>
- <CreateTime>%s</CreateTime>
- <MsgType><![CDATA[text]]></MsgType>
- <Content><![CDATA[%s]]></Content>
- </xml>";
- $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $content);
- echo $resultStr;
- }
- //回复图文消息
- public function newsResponse($fromUsername, $toUsername, $time, $articleCount, $articlesArr){
- $textTpl = "<xml>
- <ToUserName><![CDATA[%s]]></ToUserName>
- <FromUserName><![CDATA[%s]]></FromUserName>
- <CreateTime>%s</CreateTime>
- <MsgType><![CDATA[news]]></MsgType>
- <ArticleCount>%s</ArticleCount>
- <Articles>%s</Articles>
- </xml>";
- $articlesStr = "";
- for ($i=0; $i < $articleCount; $i++) {
- $articlesStr .= "<item><Title><![CDATA[".$articlesArr[$i]['Title']."]]></Title>";
- $articlesStr .= "<Description><![CDATA[".$articlesArr[$i]['Description']."]]></Description>";
- $articlesStr .= "<PicUrl><![CDATA[".$articlesArr[$i]['PicUrl']."]]></PicUrl>";
- $articlesStr .= "<Url><![CDATA[".$articlesArr[$i]['Url']."]]></Url></item>";
- }
- $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $articleCount, $articlesStr);
- echo $resultStr;
- }
- }
- ?>
文本消息关键字回复处理文件keyword.php:
- <?php
- //文本自动回复,把openid传进来,用于需要记录用户id的业务逻辑
- function keywordResponse($keyword,$openid){
- $msg = array();
- //文本示例 你好
- elseif(strstr($keyword,"你好")){
- $msg['msgType'] = 'text';
- $msg['content'] = "你好,有什么可以帮忙的吗?";
- return $msg;
- }
- //文本示例 谢谢
- elseif(strstr($keyword,"谢谢")){
- $msg['msgType'] = 'text';
- $msg['content'] = "不客气哟~";
- return $msg;
- }
- //图文示例 优惠
- elseif(strstr($keyword,"优惠")||strstr($keyword,"活动")){
- $msg['msgType'] = 'news';
- //有多少条图文,就按格式写多少个数组元素,官方文档规定最多十条图文
- $msg['articles'][0]['Title'] = '优惠活动1';
- $msg['articles'][0]['Description'] = 'XXXXXXXXXXXX大放送';
- $msg['articles'][0]['PicUrl'] = '这里替换为图文消息1图片的url';
- $msg['articles'][0]['Url'] = '替换为用户点击图文1后跳转的url';
- $msg['articles'][1]['Title'] = '优惠活动2';
- $msg['articles'][1]['Description'] = 'XXXXXXXXXXXX回馈用户';
- $msg['articles'][1]['PicUrl'] = '这里替换为图文消息2图片的url';
- $msg['articles'][1]['Url'] = '替换为用户点击图文2后跳转的url';
- return $msg;
- }
- //其他关键字
- else{
- //设置时区
- ini_set('date.timezone','PRC');
- $week = date("w",time());
- $hour = date("H",time());
- //周末
- if($week==0||$week==6){
- $msg['msgType'] = 'text';
- $msg['content'] = "亲亲,周末愉快,今天是休息哒,希望亲有个愉快的周末~\n如果有问题咨询,可以XXXXXX";
- }
- //工作日下班时间
- elseif($hour<9||$hour>=18){
- $msg['msgType'] = 'text';
- $msg['content'] = "今天已经下班咯~如果有问题,请在工作日9点-18点咨询哦~\n如果亲的问题非常紧急,不用担心,可XXXXXXXXX";
- }
- //其他情况不作自动回复
- else{
- $msg['msgType'] = 'text';
- $msg['content'] = "noreply";
- }
- return $msg;
- }
- }
自定义菜单事件回复click.php:
- <?php
- //菜单点击事件回复,把openid传进来,用于需要记录用户id的业务逻辑
- function eventResponse($key,$openid){
- $msg = array();
- //文本回复示例 查看规则
- if($key=="rule"){
- $msg['msgType'] = 'text';
- $msg['content'] = "XXXXX的用户,可兑换我们准备的XXXXX,有效期至XXXXXXXXXX";
- return $msg;
- }
- //文本回复示例 礼品兑换
- elseif($key=="exchange"){
- ...
- //业务逻辑代码
- if(兑换条件判断){
- ...
- //业务逻辑代码
- $msg['msgType'] = 'text';
- $msg['content'] = "兑换成功!领取码为:XXXX,可通过XXXX领取!";
- return $msg;
- }else{
- $msg['msgType'] = 'text';
- $msg['content'] = "您未满足兑换条件,继续XXXXXX吧~";
- return $msg;
- }
- }
- //图文示例 优惠活动
- elseif($key=="raffle"){
- $msg['msgType'] = 'news';
- //有多少条图文,就按格式写多少个数组元素,官方文档规定最多十条图文
- $msg['articles'][0]['Title'] = '优惠活动1';
- $msg['articles'][0]['Description'] = 'XXXXXXXXXXXX大放送';
- $msg['articles'][0]['PicUrl'] = '这里替换为图文消息1图片的url';
- $msg['articles'][0]['Url'] = '替换为用户点击图文1后跳转的url';
- $msg['articles'][1]['Title'] = '优惠活动2';
- $msg['articles'][1]['Description'] = 'XXXXXXXXXXXX回馈用户';
- $msg['articles'][1]['PicUrl'] = '这里替换为图文消息2图片的url';
- $msg['articles'][1]['Url'] = '替换为用户点击图文2后跳转的url';
- return $msg;
- }
- //其它情况不作回复
- else{
- $msg['msgType'] = 'text';
- $msg['content'] = "noreply";
- return $msg;
- }
- }
以上已是完整代码,测试通过,或在下面链接下载源码: