云计算开发者社区

用新浪微博连接

一步搞定

查看: 42326|回复: 54

[php征文]100行代码教你做微信聊天机器人   [复制链接]

Rank: 1

发表于 2012-12-4 14:50:17 |显示全部楼层
本帖最后由 CZQ_Plus 于 2012-12-10 15:48 编辑

大家可以加我测试帐号"magictalk"测试,是一个类似小黄鸡的应用吧,能实现基础问答


首先要去微信公众平台申请一个帐号

http://mp.weixin.qq.com/

申请一个SAE应用
我的是http://weixintalk.sinaapp.com

设置微信接口地址
微信平台->设置->回复设置->自定义回复->调用公众平台消息接口>>
url写这个url,token随便定一个"helloczq"

开启SAE服务
由于我们需要教机器人一些日常用语,所以我们必须要一个存储他们的空间,这里暂时使用SAE的kvdb服务,请先到sae开启。

定义规则
我们先给他定义一个简单的规则,比如
求助是
help
教他学东西是
"_" + 问题 + ":" + 回答
比如:_hi:hello,就是回复hello给hi
如果一样东西有很多人教他,机器人应该优先回复旧的东西。

聊天代码
规则定好了,我们先写一个聊天的类
class talk {
    public function reply($str) {
      $kv = new SaeKV ();
      $kv->init ();      //用户输入帮助语句,可以自定义帮助语法
      if ($str == 'help' || $str == '求助'){
        return "要教我读书,请英文下划线开头,接着问题,接着英文冒号,接着回答";
      }      //下划线开头的教学模式
      if (substr($str, 0,1) == '_'){
        //教
        $pos = strpos($str, ':');
        if ($pos > -1){            //问题
            $q = substr($str, 1,$pos - 1);            //答案
            $a = substr($str, $pos + 1);
            //加入知识库
            $ret = $kv->get('know_' . md5($q));            if ($ret === false || !is_array($ret))
              $ret = array();
            $ret[] = $a;
            $kv->set('know_' . md5($q), $ret);
            return "known::" . $q . '/' . $a ;
        }
      }
      $ret = $kv->get('know_' . md5($str));//查询数据库,寻找问题答案
      if ($ret === false || !is_array($ret) || count($ret) == 0){
        return '我什么都不知道,输入"help"求助';
      }else{
        //随机一个
        while(count($ret) > 1){
            $re = array_shift($ret);
            if (rand(0, 1) == 0)
              return $re;
        }
        return array_shift($ret);
      }
    }
这个类会自动回复,教学,大家可以简单测试一下

接入微信
其实就是把上面那个类和官方的php代码拼起来...
以下是全部代码,包括验证部分
<?php
define ( "TOKEN", "helloczq" );
$wechatObj = new wechat ();
$wechatObj->valid ();
$wechatObj->responseMsg ();
class wechat {
    public function valid() {
      $echoStr = $_GET ["echostr"];
      if (! $this->checkSignature ())
        exit ();
    }
    public function responseMsg() {
      $postStr = $GLOBALS ["HTTP_RAW_POST_DATA"];
      if (! empty ( $postStr )) {
        $postObj = simplexml_load_string ( $postStr, 'SimpleXMLElement', LIBXML_NOCDATA );
        $fromUsername = $postObj->FromUserName;
        $toUsername = $postObj->ToUserName;
        $content = trim ( $postObj->Content );
        $time = time ();
        $talk = new talk();
        $textTpl = "<xml>
                    <ToUserName><![CDATA[%s]]></ToUserName>
                    <FromUserName><![CDATA[%s]]></FromUserName>
                    <CreateTime>%s</CreateTime>
                    <MsgType><![CDATA[%s]]></MsgType>
                    <Content><![CDATA[%s]]></Content>
                    <FuncFlag>0</FuncFlag>
                    </xml>";
        $msgType = "text";
        $contentStr = $talk->reply($content);
        $resultStr = sprintf ( $textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr );
        echo $resultStr;

      } else {echo $_GET ["echostr"];
        exit ();
      }
    }
    private function checkSignature() {
      $signature = $_GET ["signature"];
      $timestamp = $_GET ["timestamp"];
      $nonce = $_GET ["nonce"];
      $token = TOKEN;
      $tmpArr = array (
            $token,
            $timestamp,
            $nonce 
      );
      sort ( $tmpArr );
      $tmpStr = implode ( $tmpArr );
      $tmpStr = sha1 ( $tmpStr );
      
      if ($tmpStr == $signature) {
        return true;
      } else {
        return false;
      }
    }
}
class talk {
    public function reply($str) {
      $kv = new SaeKV ();
      $kv->init ();
      if ($str == 'help' || $str == '求助'){
        return "要教我读书,请英文下划线开头,接着问题,接着英文冒号,接着回答";
      }
      if (substr($str, 0,1) == '_'){
        $pos = strpos($str, ':');
        if ($pos > -1){
            $q = substr($str, 1,$pos - 1);
            $a = substr($str, $pos + 1);
            $ret = $kv->get('know_' . md5($q));
            if ($ret === false || !is_array($ret))
              $ret = array();
            $ret[] = $a;
            $kv->set('know_' . md5($q), $ret);
            return "known::" . $q . '/' . $a ;
        }
      }
      $ret = $kv->get('know_' . md5($str));
      if ($ret === false || !is_array($ret) || count($ret) == 0){
        return '我什么都不知道,输入"help"求助';
      }else{
        //随机一个
        while(count($ret) > 1){
            $re = array_shift($ret);
            if (rand(0, 1) == 0)
              return $re;
        }
        return array_shift($ret);
      }
    }
}
?>
附件: 你需要登录才可以下载或查看附件。没有帐号?立即注册

使用道具 举报

Rank: 1

发表于 2012-12-5 13:07:29 |显示全部楼层
谢谢 楼主!!我赶紧试试

使用道具 举报

Rank: 1

发表于 2012-12-5 14:06:20 |显示全部楼层
  不会

使用道具 举报

Rank: 1

发表于 2012-12-9 17:04:53 |显示全部楼层
小小的问一下这个怎么改成用mysql数据的?

使用道具 举报

技术主管

灵感电台主播

Rank: 11Rank: 11Rank: 11Rank: 11

发表于 2012-12-11 10:23:03 |显示全部楼层
本帖最后由 灵感水手 于 2013-1-3 12:43 编辑


这两天改进了一下,结合搜索和新浪分词服务自已完善了对话功能,还可以自主学习哦。。。


使用道具 举报

Rank: 1

发表于 2012-12-11 15:22:59 |显示全部楼层
本帖最后由 此号北岛 于 2012-12-11 16:05 编辑

尝试一下。

使用道具 举报

Rank: 4

发表于 2012-12-12 10:42:59 |显示全部楼层
这个好,学起来,数据库没什么
高手在民间  热忱于SAE  群号286758243

使用道具 举报

Rank: 4

发表于 2012-12-12 10:43:59 |显示全部楼层
左氏家谱网 发表于 2012-12-9 17:04
小小的问一下这个怎么改成用mysql数据的?

你可以把数据写在一个xml里面,也可以写在一个txt中
高手在民间  热忱于SAE  群号286758243

使用道具 举报

Rank: 4

发表于 2012-12-12 10:50:24 |显示全部楼层
聊天的类,貌似少一个大括号
高手在民间  热忱于SAE  群号286758243

使用道具 举报

Rank: 1

发表于 2012-12-12 11:59:34 |显示全部楼层
o看见的人 发表于 2012-12-12 10:43
你可以把数据写在一个xml里面,也可以写在一个txt中

怎么改,可以教下我吗?我QQ305612992

使用道具 举报

Rank: 1

发表于 2012-12-13 01:41:55 |显示全部楼层
为嘛老是没有token验证响应啊

使用道具 举报

Rank: 7Rank: 7Rank: 7

发表于 2012-12-15 21:59:56 来自手机 |显示全部楼层
markmarkmark

使用道具 举报

Rank: 1

发表于 2012-12-16 22:47:11 |显示全部楼层
为什么完全没有反应?

使用道具 举报

Rank: 1

发表于 2012-12-17 03:09:57 |显示全部楼层
不支持模糊查询····初学php   希望能看到改进版

使用道具 举报

Rank: 1

发表于 2012-12-17 03:22:12 |显示全部楼层
本帖最后由 戒自己 于 2012-12-17 09:00 编辑

··sae 不支持simsimi....      远程调用simsimi api已经搞定  
对分词和模糊查询比较感兴趣  望指点

   谢谢


使用道具 举报

Rank: 6Rank: 6

发表于 2012-12-17 08:44:02 |显示全部楼层
灵感水手 发表于 2012-12-11 10:23
这两天改进了一下,结合搜索和新浪分词服务自已完善了对话功能,还可以自主学习哦。。。
另外一个服务器速 ...

我对其中的自我学习感兴趣。如何利用分词服务提高智能程度呢

使用道具 举报

技术主管

灵感电台主播

Rank: 11Rank: 11Rank: 11Rank: 11

发表于 2012-12-25 17:08:16 |显示全部楼层
第七星尘 发表于 2012-12-17 08:44
我对其中的自我学习感兴趣。如何利用分词服务提高智能程度呢

把源码都贴这里了:
http://cloudbbs.org/forum.php?mo ... &extra=page%3D1

使用道具 举报

Rank: 7Rank: 7Rank: 7

发表于 2012-12-31 03:29:45 来自手机 |显示全部楼层
戒自己 发表于 2012-12-17 03:22
··sae 不支持simsimi....      远程调用simsimi api已经搞定  
对分词和模糊查询比较感兴趣  望指点


simsimi远程api是把函数独立到其它空间,然后get获取关键词进行查询然后返回么?

使用道具 举报

Rank: 1

发表于 2013-1-8 08:16:19 |显示全部楼层
这个有意思……不过人家官方认证的都给发这个平台貌似^

使用道具 举报

Rank: 1

发表于 2013-1-22 03:56:51 |显示全部楼层
记录。。

使用道具 举报

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

Archiver|云计算开发者社区 ( 京ICP证000007-137 )

GMT+8, 2018-7-21 19:53 , Processed in 0.237171 second(s), Total 13, Slave 12 queries .

Powered by Discuz! X2

© 2001-2011 Comsenz Inc.

回顶部