基于WEB微信通信实现智能聊天机器人


原文: 基于WEB微信通信实现智能聊天机器人
date: 2017-04-10 12:39:04


序言

在QQ群里突然看到一个叫QQ小冰的机器人, 在群里只要@他 就会出来跟你聊天.
可以讲笑话, 查天气等功能, 跟人聊天的语义理解也非常智能. 类似的还有美拍的小冰.
于是去找了相关的机器人, 有微软小冰, 茉莉机器人, 图灵机器人等…
还有些是收费的. 果断跳过

我已经放到github上了: https://github.com/thank037/wechat-robot

关于实现, 发现现有很多机器人都有API, 提供第三方接入.

当然微信和QQ也支持.

通过微信公众号接入机器人或关注机器人好友都可以快速实现与机器人聊天.

对于这种接入, 我还试着去注册了微信公众号. 发现并不是我想要的.

首先, 不想让机器人作为一个公众号, 我希望他的消息出现在好友对话列表, 而非订阅号列表中.

而且要支持群聊!

其次, 我希望能作为一个开发者, 能够自由的为这个机器人写出想要的功能.

参考

看了网上的一些参考后, 不得不说, Python的版本很多, 而且功能普遍要比Java的完善.

Java版本的还有部分bug. 这里我参考了这个版本.

除了修正部分bug之外, 根据自己想法, 又加入了如下:

**开发日志**
修复bug:
    1. 对群聊中的消息判断不准确.(WechatServiceImpl --> handleMsg()) 

新增功能:
    1. 机器人调用变为图灵机器人(原来是茉莉机器人)
    2. 群聊中被@回复消息
    3. 增加给特定用户定时发送问候语
    4. 在定时发送功能中增加金山和茉莉机器人的API调用
        a. 金山API(获取每日一句英语)
        b. 茉莉机器人(获取当天当地天气信息)
    5. 增加Emoji表情, 并随机发送
    6. 程序处理"图灵机器人"消息内容的水印
    7. 增加消息防撤回(识别撤回消息并保存到消息字典)
    8. 增加语义处理(趣味回答, 口头禅等...)
    9. 完善控制台和记录文件的LOGGER日志, 方便日后维护及调试
    10. 调用API异常的处理(例如茉莉机器人的接口有时很不稳定, 为了不影响功能, 增加备用接口处理异常)
TODO:
    1. 增加发送图片和语音的功能.
    2. 如何不依赖手机端, 程序出现异常后重新选择线路
    3. 增强程序稳定性

执行流程

其实这里与机器人的对话并不是难得, 因为已经有现成的API提供

主要是需要研究微信WEB协议与API

       +--------------+     +---------------+   +---------------+
       |              |     |               |   |               |
       |   Get UUID   |     |  Get Contact  |   | Status Notify |
       |              |     |               |   |               |
       +-------+------+     +-------^-------+   +-------^-------+
               |                    |                   |
               |                    +-------+  +--------+
               |                            |  |
       +-------v------+               +-----+--+------+      +--------------+
       |              |               |               |      |              |
       |  Get QRCode  |               |  Weixin Init  +------>  Sync Check  <----+
       |              |               |               |      |              |    |
       +-------+------+               +-------^-------+      +-------+------+    |
               |                              |                      |           |
               |                              |                      +-----------+
               |                              |                      |
       +-------v------+               +-------+--------+     +-------v-------+
       |              | Confirm Login |                |     |               |
+------>    Login     +---------------> New Login Page |     |  Weixin Sync  |
|      |              |               |                |     |               |
|      +------+-------+               +----------------+     +---------------+
|             |
|QRCode Scaned|
+-------------+

API

获取会话ID

Get UUID

URL: https://login.wx.qq.com/jslogin
请求方式: GET
参数: 
    a. appid: wx782c26e4c19acffb(固定字符串)
    b. fun: new(固定值)
    c. lang: zh_CN(固定值)
    d. _: 1491804797(13位毫秒时间戳)
返回数据(String):
window.QRLogin.code = 200; window.QRLogin.uuid = "[UUID]"
状态码code=200表示成功

显示二维码图片

Get QRCode

URL: https://login.weixin.qq.com/qrcode/[UUID] (上一步获取到的返回值window.QRLogin.uuid)
请求方式: GET
返回数据: 二维码

手机端扫描二维码等待确认登录

URL: https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/login
请求方式: GET
参数: 
    a. uuid: [UUID](前面获取到的UUID)
    b. tip: 1 (1-未扫描  0-已扫描)
    d. _: 1491804797(13位毫秒时间戳)
返回数据(String):
window.code=xxx(408 登陆超时, 201 扫描成功但未确认, 200 确认登录)
由于该请求需要用户在手机端连续做几个操作, 所以代码里要轮询来实现. 直到返回结果为200.
获取到以下URL后需要继续访问当前链接获取wxuin和wxsid
window.redirect_uri="https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket=xxx&uuid=xxx&lang=xxx&scan=xxx";

后续

后面还有一些步骤,麻烦不想写了啊

大致步骤是

  1. 初始化微信, 开启状态通知, 保存个人信息, 登录信息, 并将联系人列表和群组列表保存下来.

  2. 然后选择同步线路, 轮询进行消息检查.

    获取到最新消息后调用机器人API(这里我用的是图灵机器人)获得回答结果.

  3. 然后调用消息发送API, 完成消息发送.

相关的通信过程和API网上有很多. 在开头参考中有推荐

附注

为了方便开发, 加几个附注:

1: 同步状态

在同步消息检查的API中:https://webpush2.weixin.qq.com/cgi-bin/mmwebwx-bin/synccheck

为了模拟实时消息的更新, 在程序中轮询2秒检查一次, 此接口的返回值如下:

window.synccheck={retcode:"xxx",selector:"xxx"}
第一步判断: retcode
    0-正常
    1100-失败/登出微信
第二步判断: selector
    0 正常
    2/6 新的消息
    7 进入/离开聊天界面

所以当selector=2/6时, 我们就可以进行消息处理.

这里selector有个很奇怪的返回值, 就是3!

我翻阅各种API也没找到为什么有时会返回3导致程序死掉

2: 消息账户类型

在发送消息之前, 需要获取同步消息.
URL: https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsync?sid=xxx&skey=xxx&pass_ticket=xxx
返回值包括了消息发送方, 接收方, 消息内容, 消息类型.
消息来源的账号类型大致有这几类:
来自个人: 以@开头
来自群聊: 以@@开头
来自公众号/服务号: 以@开头,VerifyFlag & 8 != 0
来自特殊账号:

// 特殊用户 须过滤
("newsapp", "fmessage", "filehelper", "weibo", "qqmail", "fmessage", "tmessage", "qmessage",
 "qqsync", "floatbottle", "lbsapp", "shakeapp", "medianote", "qqfriend", "readerapp", "blogapp",
 "facebookapp", "masssendapp", "meishiapp", "feedsapp", "voip", "blogappweixin", "weixin", "wxitil",
"brandsessionholder", "weixinreminder", "wxid_novlwrv3lqwv11", "gh_22b87fa7cb3c", "officialaccounts",
"notification_messages", "wxid_novlwrv3lqwv11", "gh_22b87fa7cb3c",  "userexperience_alarm");

3: 消息类型

MsgType 说明
1 文本消息
3 图片消息
34 语音消息
37 VERIFYMSG
40 POSSIBLEFRIEND_MSG
42 共享名片
43 视频通话消息
47 动画表情
48 位置消息
49 分享链接
50 VOIPMSG
51 微信初始化消息
52 VOIPNOTIFY
53 VOIPINVITE
62 小视频
9999 SYSNOTICE
10000 系统消息
10002 撤回消息

图灵机器人

关于图灵机器人的调用, 去官网注册一个就可以. so easy!

效果演示

在调试功能时, 可以加上log, 查看同步连接信息和消息


小豆丁-后台日志

附上几张和机器人的聊天:

小豆丁-聊天截图1
小豆丁-聊天截图2
小豆丁-群聊
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,657评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,889评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,057评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,509评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,562评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,443评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,251评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,129评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,561评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,779评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,902评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,621评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,220评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,838评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,971评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,025评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,843评论 2 354

推荐阅读更多精彩内容

  • 点击查看原文 Web SDK 开发手册 SDK 概述 网易云信 SDK 为 Web 应用提供一个完善的 IM 系统...
    layjoy阅读 13,761评论 0 15
  • 最近的日子又开始过得萎靡。 感觉自己像躺在时间的洪流里,我眼睁睁地看着他在身边流得湍急,但我又好像有点享受它冲刷我...
    糯米糯米小糯米阅读 189评论 0 1
  • 构建版本号时候 iphone预览图只需要5.8寸的和5.5寸的; 5.8寸的里边必须彰显出你在iphoneX上使用...
    曾经像素有点低阅读 30,631评论 0 0
  • 春天里的校园 花圃中的三角梅 横空甩岀一根根长长的钓鱼杆 缀满了红艳艳的花朵 似小喇叭 相间其中的绿叶 摇曳多姿随...
    杖剑走四方阅读 251评论 2 7