设为首页收藏本站

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 242|回复: 1

微信公众平台PHP开发自动回复机器人

[复制链接]
发表于 2014-5-21 22:49:24 | 显示全部楼层 |阅读模式
                                本系列教程以微信公众平台应用妈妈助手(账号mmhelper:发送食物名称或拼音首字母查询孕妇、坐月子、宝宝能不能吃哪些食物。发送自己的位置查询附近的母婴类商家,以及促销、团购等信息。发送与宝宝的合照测试与宝宝的脸部相似度)为例,讲解微信接口开发过程。欢迎大家关注该账号,二维码见底部图。

        使用前提条件:拥有一个公网上的HTTP服务器主机空间,具有创建目录、上传文件等权限。推荐新浪的SAE。http://sae.sina.com.cn/

        首先请注册微信公众平台的账号,注册地址:http://mp.weixin.qq.com/

        本教程主要讲解接口的开发流程。
        事例代码也跑不通。我研究了一番,终于搞定。方法如下:

        一、写好接口程序

        在你的服务器上上传好一个接口程序文件,如http://www.yourdomain.com/weixin.php  内容如下:
  1. <?php
  2. define("TOKEN", "weixin");//自己定义的token 就是个通信的私钥
  3. $wechatObj = new wechatCallbackapiTest();
  4. $wechatObj->valid();
  5. //$wechatObj->responseMsg();
  6. class wechatCallbackapiTest
  7. {
  8.     public function valid()
  9.     {
  10.         $echoStr = $_GET["echostr"];
  11.         if($this->checkSignature()){
  12.             echo $echoStr;
  13.             exit;
  14.         }
  15.     }
  16.     public function responseMsg()
  17.     {
  18.         $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
  19.         if (!empty($postStr)){
  20.             $postObj = simplexml_load_string($postStr, 'SimpleXMLElement',
  21. LIBXML_NOCDATA);
  22.             $fromUsername = $postObj->FromUserName;
  23.             $toUsername = $postObj->ToUserName;
  24.             $keyword = trim($postObj->Content);
  25.             $time = time();
  26.             $textTpl = "<xml>
  27.             <ToUserName><![CDATA[%s]]></ToUserName>
  28.             <FromUserName><![CDATA[%s]]></FromUserName>
  29.             <CreateTime>%s</CreateTime>
  30.             <MsgType><![CDATA[%s]]></MsgType>
  31.             <Content><![CDATA[%s]]></Content>
  32.             <FuncFlag>0<FuncFlag>
  33.             </xml>";
  34.             if(!empty( $keyword ))
  35.             {
  36.                 $msgType = "text";
  37.                 $contentStr = '你好啊,屌丝';
  38.                 $resultStr = sprintf($textTpl, $fromUsername, $toUsername,
  39. $time, $msgType, $contentStr);
  40.                 echo $resultStr;
  41.             }else{
  42.                 echo '咋不说哈呢';
  43.             }
  44.         }else {
  45.             echo '咋不说哈呢';
  46.             exit;
  47.         }
  48.     }

  49.     private function checkSignature()
  50.     {
  51.         $signature = $_GET["signature"];
  52.         $timestamp = $_GET["timestamp"];
  53.         $nonce = $_GET["nonce"];
  54.         $token =TOKEN;
  55.         $tmpArr = array($token, $timestamp, $nonce);
  56.         sort($tmpArr);
  57.         $tmpStr = implode( $tmpArr );
  58.         $tmpStr = sha1( $tmpStr );

  59.         if( $tmpStr == $signature ){
  60.             return true;
  61.         }else{
  62.             return false;
  63.         }
  64.     }
  65. }
  66. ?>
复制代码



        二、配置微信公众平台回复接口
设置回复接口,填好URL和Token(url填上面的http://www.yourdomain.com/weixin.php,token必须跟上面程序里面定义的Token一致)

        三、验证接口
用自己的个人微信关注下你的公众账号,给这个账号发一条消息过去,收到原样的消息返回,即验证成功了。

四、开始自定义回复
注释掉$wechatObj->valid(); 这行,同时去掉//$wechatObj->responseMsg();这行的注释。
        你可以修改responseMsg函数里面的代码,根据用户的消息类型('text','image','location')和消息内容来回复用户不同的内容。
消息接口就可以使用了,发个消息试试看吧?

封装weixin.class.php

        由于微信公众平台的通信使用的是特定格式的XML数据,每次接受和回复都要去做一大堆的数据处理。
我们就考虑在这个基础上做一次封装,weixin.class.php,代码如下:
  1. <?php
  2. class Weixin
  3. {
  4.     public $token = '';//token
  5.     public
  6. $debug =  false;//是否debug的状态标示,方便我们在调试的时候记录一些中间数据
  7.     public $setFlag =
  8. false;
  9.     public $msgtype = 'text';   //('text','image','location')
  10.    
  11. public $msg = array();

  12.     public function
  13. __construct($token,$debug)
  14.     {
  15.         $this->token =
  16. $token;
  17.         $this->debug = $debug;
  18.     }<br>    
  19. //获得用户发过来的消息(消息内容和消息类型  )
  20.     public function getMsg()
  21.     {
  22.       
  23. $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
  24.         if ($this->debug)
  25. {
  26.                         $this->write_log($postStr);
  27.       
  28. }
  29.         if (!empty($postStr)) {
  30.             $this->msg =
  31. (array)simplexml_load_string($postStr, 'SimpleXMLElement',
  32. LIBXML_NOCDATA);
  33.             $this->msgtype =
  34. strtolower($this->msg['MsgType']);
  35.         }
  36.     }<br>    
  37. //回复文本消息
  38.     public function makeText($text='')
  39.     {
  40.       
  41. $CreateTime = time();
  42.         $FuncFlag = $this->setFlag ? 1 :
  43. 0;
  44.         $textTpl = "<xml>
  45.            
  46. <ToUserName><![CDATA[{$this->msg['FromUserName']}]]></ToUserName>
  47.            
  48. <FromUserName><![CDATA[{$this->msg['ToUserName']}]]></FromUserName>
  49.            
  50. <CreateTime>{$CreateTime}</CreateTime>
  51.            
  52. <MsgType><![CDATA[text]]></MsgType>
  53.            
  54. <Content><![CDATA[%s]]></Content>
  55.            
  56. <FuncFlag>%s</FuncFlag>
  57.             </xml>";
  58.       
  59. return sprintf($textTpl,$text,$FuncFlag);
  60.     }<br>    
  61. //根据数组参数回复图文消息
  62.     public function makeNews($newsData=array())
  63.    
  64. {
  65.         $CreateTime = time();
  66.         $FuncFlag = $this->setFlag ? 1
  67. : 0;
  68.         $newTplHeader = "<xml>
  69.            
  70. <ToUserName><![CDATA[{$this->msg['FromUserName']}]]></ToUserName>
  71.            
  72. <FromUserName><![CDATA[{$this->msg['ToUserName']}]]></FromUserName>
  73.            
  74. <CreateTime>{$CreateTime}</CreateTime>
  75.            
  76. <MsgType><![CDATA[news]]></MsgType>
  77.            
  78. <Content><![CDATA[%s]]></Content>
  79.            
  80. <ArticleCount>%s</ArticleCount><Articles>";
  81.       
  82. $newTplItem = "<item>
  83.            
  84. <Title><![CDATA[%s]]></Title>
  85.            
  86. <Description><![CDATA[%s]]></Description>
  87.            
  88. <PicUrl><![CDATA[%s]]></PicUrl>
  89.            
  90. <Url><![CDATA[%s]]></Url>
  91.            
  92. </item>";
  93.         $newTplFoot = "</Articles>
  94.            
  95. <FuncFlag>%s</FuncFlag>
  96.             </xml>";
  97.       
  98. $Content = '';
  99.         $itemsCount = count($newsData['items']);
  100.       
  101. $itemsCount = $itemsCount < 10 ? $itemsCount :
  102. 10;//微信公众平台图文回复的消息一次最多10条
  103.         if ($itemsCount) {
  104.             foreach
  105. ($newsData['items'] as $key => $item) {
  106.                 if ($key<=9)
  107. {
  108.                     $Content .=
  109. sprintf($newTplItem,$item['title'],$item['description'],$item['picurl'],$item['url']);
  110.                
  111. }
  112.             }
  113.         }
  114.         $header =
  115. sprintf($newTplHeader,$newsData['content'],$itemsCount);
  116.         $footer =
  117. sprintf($newTplFoot,$FuncFlag);
  118.         return $header . $Content .
  119. $footer;
  120.     }
  121.     public function reply($data)
  122.     {
  123.         if
  124. ($this->debug) {
  125.                   
  126. $this->write_log($data);
  127.         }
  128.         echo $data;
  129.     }
  130.    
  131. public function valid()
  132.     {
  133.         if ($this->checkSignature())
  134. {
  135.             if( $_SERVER['REQUEST_METHOD']=='GET' )
  136.            
  137. {
  138.                 echo $_GET['echostr'];
  139.                
  140. exit;
  141.             }
  142.         }else{
  143.            
  144. write_log('认证失败');
  145.             exit;
  146.         }
  147.     }
  148.     private
  149. function checkSignature()
  150.     {
  151.         $signature =
  152. $_GET["signature"];
  153.         $timestamp = $_GET["timestamp"];
  154.       
  155. $nonce = $_GET["nonce"];

  156.         $tmpArr = array($this->token,
  157. $timestamp, $nonce);
  158.         sort($tmpArr);
  159.         $tmpStr = implode(
  160. $tmpArr );
  161.         $tmpStr = sha1( $tmpStr );

  162.         if( $tmpStr ==
  163. $signature ){
  164.             return true;
  165.         }else{
  166.            
  167. return false;
  168.         }
  169.     }
  170.     private function
  171. write_log($log){<br>       //这里是你记录调试信息的地方  请自行完善  
  172. 以便中间调试<br>    }
  173. }
  174. ?>
复制代码







 楼主| 发表于 2014-5-21 22:49:38 | 显示全部楼层
        调用weixin.class.php

        把你的微信公众平台主接口文件(如前面定义的http://www.yourdomain.com/weixin.php)中,修改代码为:
  1. <?php

  2. include_once('weixin.class.php');//引用刚定义的微信消息处理类<br>define("TOKEN",
  3. "mmhelper");<br>define('DEBUG', true);
  4. $weixin = new
  5. Weixin(TOKEN,DEBUG);//实例化
  6. $weixin->getMsg();
  7. $type =
  8. $weixin->msgtype;//消息类型
  9. $username =
  10. $weixin->msg['FromUserName'];//哪个用户给你发的消息,这个$username是微信加密之后的,但是每个用户都是一一对应的
  11. if
  12. ($type==='text') {
  13.     if ($weixin->msg['Content']=='Hello2BizUser')
  14. {//微信用户第一次关注你的账号的时候,你的公众账号就会受到一条内容为'Hello2BizUser'的消息
  15.         $reply =
  16. $weixin->makeText('欢迎你关注妈妈助手哦,屌丝');
  17.     }else{//这里就是用户输入了文本信息
  18.       
  19. $keyword = $weixin->msg['Content'];   //用户的文本消息内容
  20.                
  21. include_once("chaxun.php");//文本消息 调用查询程序
  22.                 $chaxun= new
  23. chaxun(DEBUG,$keyword,$username);
  24.                 $results['items']
  25. =$chaxun->search();//查询的代码
  26.             
  27.                 $reply =
  28. $weixin->makeNews($results);
  29.     }
  30. }elseif ($type==='location')
  31. {
  32.       //用户发送的是位置信息  稍后的文章中会处理                 
  33. }elseif
  34. ($type==='image') {
  35.       //用户发送的是图片 稍后的文章中会处理
  36. }elseif ($type==='voice')
  37. {   
  38.       //用户发送的是声音 稍后的文章中会处理
  39. }
  40. $weixin->reply($reply);

  41. ?>
复制代码

        查询代码

        还需要将数据库里面的查询结果格式化为特定的形式
  1. <?php
  2. public function search(){
  3.        $record=array();  //定义返回结果的数组
  4.       
  5. $list = $this->search($this->keyword);//普通的根据关键词查询数据库的操作
  6. 代码就不用分享了
  7.     if(is_array($list)&&!empty($list)){               

  8.                foreach($list as $msg){

  9.                 $record[]=array(//以下代码,将数据库中查询返回的数组格式化为微信返回消息能接收的数组形式,即title、description、picurl、url
  10. 详见微信官方的文档描述
  11.                     'title'
  12. =>$msg['title'],
  13.                     'description'
  14. =>$msg['discription'],
  15.                     'picurl' =>
  16. $msg['pic_url'],
  17.                     'url'
  18. =>$msg['url']
  19.                 );
  20.         }
  21.     }
  22.     return
  23. $record;
  24. }
  25. ?>
复制代码



您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|小黑屋|BC Morning Website ( Best Deal Inc. 001 )  

GMT-8, 2025-8-26 13:51 , Processed in 0.014846 second(s), 17 queries .

Supported by Best Deal Online X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表