微信公众平台的应用设想(智能客服)

微信 是最近很流行的短信替代服务, 微信公众平台 是微信的第三方开发接口,我之前并不关注,一个朋友想用这个公共平台来替代之前的手机App(物联网数据采集),我应邀对其进行技术评估。本博客准备写一个系列,每篇文章一个应用,并给出3个问题的答案: 做什么?怎么做?技术难点在什么地方?本文给出一个最简单直接的应用:智能客服。

做什么

本质上这是个问答机器人,用户提问,客服回答。类似于10086短信服务平台那样,用户给出规则的问题,平台引导用户进行下一步选择,一步一步的帮助客户找到答案,或给出服务。

怎么做

用户关注客服的首次引导

actor 用户
用户 -> 微信平台 : 关注(智能客服)
activate 微信平台
微信平台 -> 智能客服: 订阅事件(用户ID)
activate 智能客服
智能客服 -> 微信平台: 欢迎文本消息
deactivate 智能客服
微信平台 -> 用户: 欢迎文本消息
deactivate 微信平台

在欢迎消息中,可以给出一个菜单项,引导用户进行如何使用本应用,以及系统将如何回答。例如:

欢迎使用本智能客服服务,请选择你的服务类别: A 电话服务 B 互联网接入服务 C 我想看一个随机笑话

后面的使用举例:

actor 用户
用户 -> 智能客服 : "A"
activate 智能客服
智能客服 -> 用户: "A1 电话申请 A2 电话注销 A3 电话功能介绍"
deactivate 智能客服
用户 -> 智能客服 : "A1"
activate 智能客服
智能客服 -> 用户 : "请使用微信菜单发送你的位置信息"
用户 -> 智能客服 : 位置信息
智能客服 -> 用户 : "尊敬的XX区用户您好,请拨打分局电话XXXXXXX继续申请"
deactivate 智能客服

值得注意的是,上图忽略了微信平台的存在,在实现中,微信平台相当于一个透明的中间桥梁:

actor 用户
用户 -> 微信平台 : sendTo(智能客服, "A")
activate 微信平台
微信平台 -> 智能客服 : messageFrom(用户ID, "A")
activate 智能客服
智能客服 -> 微信平台: "A1 电话申请 A2 电话注销 A3 电话功能介绍"
deactivate 智能客服
微信平台 -> 用户: messageFrom(智能客服, "A1 电话申请 A2 电话注销 A3 电话功能介绍")
deactivate 微信平台
用户 -> 微信平台 : sendTo(智能客服, "A1")
activate 微信平台
微信平台 -> 智能客服 : messageFrom(用户ID, "A1")
activate 智能客服
智能客服 -> 微信平台 : "请使用微信菜单发送你家的位置"
微信平台 -> 用户: messageFrom(智能客服, "请使用微信菜单发送你家的位置")
deactivate 微信平台
用户 -> 微信平台: sendTo(智能客服, 位置信息)
activate 微信平台
微信平台 -> 智能客服: messageFrom(用户ID, 位置信息)
智能客服 -> 微信平台 : "尊敬的XX区用户您好,请拨打分局电话XXXXXXX继续申请"
deactivate 智能客服
微信平台 -> 用户: messageFrom(智能客服, "尊敬的XX区用户您好,请拨打分局电话XXXXXXX继续申请")
deactivate 微信平台

今后其他的例子如无必要,都会省略微信平台,采用上面那个简化的图。

技术难点

纯粹没有状态的问答最容易实现,只要做一个模式匹配表就可以了。麻烦在于两次或多次提问具有上下文相关性。例如上面用户分别发送A1和位置信息是相关的,位置信息单独发送没有意义,而必须和上文申请电话联系起来才有意义。为此服务器必须对给定用户维护一个会话状态,并设定一个超时时间,超时后该用户的会话状态清除。好在同一个用户在一个时间点上只需要一个状态即可,开销不会太大。平台应可以区分无状态的提问和有状态的提问,并且互相不干扰。例如在上面的例子中用户可以在申请电话的两个消息(“A1”和坐标)之间发送”A3”(或者”C”)来做一个无状态的提问,智能客服服务器回答后,只要后面发送的坐标没有超时,则从技术上可以认为还是合法的,与A1有关。

关于状态本身的实现,由于微信平台的限制,我能想到的只能通过用户ID和超时来标识,无法采用类似cookie等技术。