微信公众号实现智能聊天-接入第三方智能机器人平台

    我已将博客放到csdn平台了,后面也是打算在csdn上编写博客,本文在csdn博客的地址:http://blog.csdn.net/wsa518/article/details/51112020

    上一篇博客我介绍了如何申请一个新浪云,并创建一个云应用,应用的开发语言为PHP。这篇博客将详细介绍编码实现微信公众号智能聊天功能。

     大家先打开微信公众号的开发文档:https://mp.weixin.qq.com/wiki,找到“接入指南” 

184641_tSqF_2558743.jpg

将官方的PHP代码文件下载下来:

184541_7FSP_2558743.jpg

解压缩后修改文件名并拷贝到我们的项目(从新浪云svn上Check Out下来的项目)中,如下图所示(这里我删除了“config.yaml”文件和替换了“index.php”文件):

184542_Ywja_2558743.jpg

紧接着修改下代码中的TOKEN值:

184542_uyq0_2558743.jpg

现在我们通过svn将代码提交到新浪云上,去微信公众号后台的“开发” -> “基本配置”中修改下配置:

184543_trEP_2558743.jpg

修改配置中的URL就是新浪云应用的地址,Token就是代码中定义的TOKEN常量,EncodingAESKey随机生成就行了(主要用来加密使用,这篇博客不讲解),点击“提交”按钮,正常情况下应该是配置成功的,如果有人没有配置成功可以尝试网上搜索下解决方案,实在没辙,发邮箱wsa518@yeah.net或者博客私聊我都行:

184543_Oys7_2558743.jpg

好了,和微信对接上后,我们要开始写代码咯:

先创建一个名叫TuringRobot类,用来处理图灵机器人的逻辑,这里我暂时只实现了图灵机器人的文本、链接、新闻和菜谱消息的处理,有兴趣的可以再深入研究下其他类型的回复: 

<?php
/**
 * Created by PhpStorm.
 * User: Ainsworth
 * Date: 16/4/9
 * Time: 下午5:20
 */

define("TURING_API_URL", "http://www.tuling123.com/openapi/api");
define("TURING_API_KEY", "您申请的图灵机器人Api Key");

class TuringRobot
{
   /**
     * 获取图灵机器人的回复
     *
     * @param $content
     * @param $user_id
     * @return string
     */
   public function getInfo($content, $user_id)
    {
       $url = TURING_API_URL . "?key=" . TURING_API_KEY . "&info=" . $content . "&userid=" . $user_id;
       $ch = curl_init();
       curl_setopt($ch, CURLOPT_URL, $url);
       curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
       $output = curl_exec($ch);
       curl_close($ch);
       return json_decode($output, true);
   }

   /**
     * 回复文本消息
     *
     * @param $info
     * @return mixed
     */
   public function textInfo($info)
    {
       return $info["text"];
   }

   /**
     * 回复链接消息
     *
     * @param $info
     * @return string
     */
   public function linkInfo($info)
    {
       return $info["text"] . "\n" . $info["url"];
   }

   /**
     * 回复新闻消息
     *
     * @param $info
     * @return string
     */
   public function newsInfo($info)
    {
       $news = $info["text"] . "\n\n";
       $list = $info["list"];
       foreach ($list as $l) {
            error_log($l["icon"]);
           $news .= $l["article"] . "\n" . $l["detailurl"] . "\n";
       }
       return $news;
   }

   /**
     * 回复菜谱消息
     *
     * @param $info
     * @return array
     */
   public function cookbookInfo($info)
    {
       $new_list = array();
       $list = $info["list"];
       for ($i = 0; $i < count($list); $i++) {
           // 由于微信图文消息最多发8条, 所以这边限制下
           if ($i > 8) break;
           $new_list[$i] = array("title" => $list[$i]["name"],
               "description" => $list[$i]["info"],
               "picurl" => $list[$i]["icon"],
               "url" => $list[$i]["detailurl"]);
       }
        error_log(serialize($new_list));
       return $new_list;
   }

}

接下来我们回到index.php文件中,在wechatCallbackapiTest类中加入文本和图片消息的微信回复格式处理:

/**
 * 回复文本消息模板
 *
 * @param $obj
 * @param $content
 * @return string
 */
private function textTemplate($obj, $content)
{
   $time = time();
   return "<xml>
                <ToUserName><![CDATA[$obj->FromUserName]]></ToUserName>
                <FromUserName><![CDATA[$obj->ToUserName]]></FromUserName>
                <CreateTime>$time</CreateTime>
                <MsgType><![CDATA[text]]></MsgType>
                <Content><![CDATA[$content]]></Content>
            </xml>";
}

/**
 * 回复图文消息模板
 *
 * @param $obj
 * @param $news
 * @return string
 */
private function newsTemplate($obj, $news)
{
   $time = time();
   $num = count($news);
   $textTpl = "<xml>
                    <ToUserName><![CDATA[$obj->FromUserName]]></ToUserName>
                    <FromUserName><![CDATA[$obj->ToUserName]]></FromUserName>
                    <CreateTime>$time</CreateTime>
                    <MsgType><![CDATA[news]]></MsgType>
                    <ArticleCount>$num</ArticleCount>
                    <Articles>";
   foreach ($news as $new) {
       $textTpl .= $this->transmitNewItem($new["title"], $new["description"], $new["picurl"], $new["url"]);
   }
   $textTpl .= "</Articles></xml>";
   return $textTpl;
}

private function transmitNewItem($title, $description, $picurl, $url)
{
   return "<item>
                <Title><![CDATA[$title]]></Title>
                <Description><![CDATA[$description]]></Description>
                <PicUrl><![CDATA[$picurl]]></PicUrl>
                <Url><![CDATA[$url]]></Url>
            </item>";
}

写好后,加入一个处理文本消息的函数(即我们在微信公众号里发送聊天的文本内容,根据发送过来的内容做一些处理):

/**
 * 接受文本消息并处理
 *
 * @param $obj
 * @return string
 */
private function receiveText($obj)
{
   $content = $obj->Content;

   // 图灵机器人消息处理
   $robot = new TuringRobot();
   $info = $robot->getInfo($content, $obj->FromUserName);
   switch ($info["code"]) {
       case 100000:   // 文本类
           return $this->textTemplate($obj, $robot->textInfo($info));
       case 200000:   // 链接类
           return $this->textTemplate($obj, $robot->linkInfo($info));
       case 302000:   // 新闻类
           return $this->textTemplate($obj, $robot->newsInfo($info));
       case 308000:   // 菜谱类
           return $this->newsTemplate($obj, $robot->cookbookInfo($info));
       case 313000:   // 儿歌类(儿童版)
       case 314000:   // 诗歌类(儿童版)
       default:
           return "亲,你能说的再简单点吗?我有点理解不过来啦!";
   }
}

在responseMsg函数中调用(这里我删除了一些暂时不使用的代码,大家按照我写的来即可),这里我也只处理了文本消息,如果你对公众号发送图片或者语音什么的,我这边默认是统一回复“亲,你说的是啥,我只能理解文字啊!”:

public function responseMsg()
{
   //get post data, May be due to the different environments
   $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];

   //extract post data
   if (!empty($postStr)) {
       /* libxml_disable_entity_loader is to prevent XML eXternal Entity Injection,
           the best way is to check the validity of xml by yourself */
       libxml_disable_entity_loader(true);
       $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);

       $result = '';
       switch ($postObj->MsgType) {
           case 'event':
               // 关注后自动回复
               if ($postObj->Event == 'subscribe') {
                   $result = $this->textTemplate($postObj, 'hi,你怎么才关注我,我都等你一万年了!');
               }
               break;
           case 'text':   // 文本消息
               $result = $this->receiveText($postObj);
               break;
           case 'image':   // 图片消息
           case 'voice':   // 语言消息
           case 'video':   // 视频消息
           case 'shortvideo':   // 小视频消息
           case 'link':   // 链接消息
           default:
               $result = $this->textTemplate($postObj, '亲,你说的是啥,我只能理解文字啊!');
               break;
       }

       echo $result;
   } else {
       echo '';
       exit;
   }
}


最后,把index.php头部位置的代码改下:

$wechatObj = new wechatCallbackapiTest();
$wechatObj->valid();

改为:

$wechat = new wechatCallbackapiTest();
if (isset($_GET["echostr"])) {
   $wechat->valid();
} else {
   $wechat->responseMsg();
}

还有别忘了引入TuringRobot.php哦!

include 'TuringRobot.php';

将所有的代码提交至新浪云上,回到微信公众平台点击“启用”: 

190226_exGk_2558743.png

下面我们来测试一下:

185236_Vlll_2558743.jpg

185236_uPvT_2558743.jpg

185237_RLCp_2558743.jpg

185238_Igmd_2558743.jpg

185238_vRhz_2558743.jpg

185239_xdiR_2558743.jpg

193504_ewrU_2558743.jpg

193505_7JiL_2558743.jpg

最后的最后呢,我放上我的公众号二维码,大家可以测试看看!(最后我建议如果公众号已经在运营阶段,最好是开发的时候本地测试,可以去看我的这篇博客:http://my.oschina.net/wanggong/blog/648671

185455_zVOW_2558743.jpg

转载于:https://my.oschina.net/wanggong/blog/655891

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值