使用springboot开发微信智能聊天小机器人(基于图灵问答api接口)
2018-01-05 15:56
1091 查看
废话不多说,也不介绍一下什么背景之类的。。。直接开始。。。。。
首先,我们需要注册一个微信公众号。。类型的话无所谓,订阅号就可以了。(个人只能注册订阅号)
然后进入公众号后台,启用服务器配置。。
启用服务器配置时,微信会向你填写的服务器地址去发送一天get请求进行验证。。验证规则见下:
代码见下:
上面是微信官方的说法。我们理解一下,简单来说,就是用户发送消息给我们公众号,公众号也就是微信后台,在接收到这个消息时,会将这条消息的内容、发送人、时间等一些参数封装成xml格式,然后再转发给我们的服务器。我们的服务器接收到这个请求时,需要作出对应的回复,再讲回复封装成xml转发给微信后台。。。微信后台收到我们服务器发送的xml之后,然后再将数据发送给用户。。这就是用户与公众号之间的一次消息传递过程。。。
消息传递的过程很简单,,,,,我们唯一要关心的点就是,对于用户的输入,我们该反馈什么样的结果给与用户。。。。。这也是我们服务器主要做的事情。。。。
微信支持的消息有六种,,这里我们只做回复文本消息。。。
回复文本消息,我们的核心就是调用图灵的问答api接口。。将用户发送的消息作为请求参数,我们去请求图灵机器人的问答系统开放接口,获取回复后,我们将回复的内容再经过转换发送给用户,这就实现了机器人聊天的功能了。。。。
代码见下:
用户发送消息之后,微信服务器会将此消息以post的请求方式、xml的数据格式转发给我们服务器。服务器收到此消息,也要返回一条对应的xml格式数据回复给微信服务器
@ResponseBody
@PostMapping("/")
public String doPost(HttpServletRequest request){
/*
在收到微信服务器的请求之后,我们需要做如下几件事!
1、解析微信发送的请求数据(将xml转换成map,获取消息发送人、消息接收人、时间、内容)
2、发送请求给图灵的接口,获取返回值,并解析提取回复内容
3、将回复内容和第一步解析到的消息发送人封装成xml格式,再返回给微信服务器
*/
return coreService.process(request);
}
调用图灵api接口时,我们先需要注册一个图灵的账号。。然后添加一个机器人(小云机器人是我已经添加好的)
然后点击设置,进入机器人管理页面。。。里面有api接入的说明,我们需要下面的两个参数
即下面:
public class BaseCommon {
/**
* 图灵机器人的配置参数
*/
public static final String TL_ROBOT_API_URL="http://www.tuling123.com/openapi/api";
public static final String TL_ROBOT_API_KEY="xxxxxxxxxxxx";//这里填写你自己的
}
调用图灵机器人的代码见下:
有一点需要说明一下。。由于人的问答具有连贯性,,所以我们在调用图灵的问答接口时,需要设置userid这个参数。。
在我的代码里,userid使用的是用户的openid。。。
Springboot开发微信公众号智能机器人(基于图灵api)
上面讲述的不够细。。比如微信发送的xml数据格式,,有哪些属性。。我们返回的xml要包含哪些属性。。。请求图灵机器人的格式要求、图灵机器人回复的json格式。。。。这个项目里面有大量的数据格式转换。。。建议下载我的代码,然后对照微信的公众号开发文档和图灵的api接入文档对比着看。。这样比较好。。。。。。
附一张我项目的结构图(这个项目作为一个springboot的项目,还是比较简单的。。。新手可以拿来熟悉springboot):
最后,,附一下我开发的微信公众号智能问答小机器人的微信号,欢迎大家前去骚扰。。
首先,我们需要注册一个微信公众号。。类型的话无所谓,订阅号就可以了。(个人只能注册订阅号)
然后进入公众号后台,启用服务器配置。。
启用服务器配置时,微信会向你填写的服务器地址去发送一天get请求进行验证。。验证规则见下:
代码见下:
/** * 确认请求来自微信服务器 * @param signature 微信加密签名 * @param timestamp 时间戳 * @param nonce 随机数 * @param echostr 随机字符串 */ @ResponseBody @GetMapping("/") public String doGet(String signature,String timestamp,String nonce,String echostr){ if(SignUtil.checkSignature(signature,timestamp,nonce)){ return echostr; } return null; }校验代码:
package com.yunhui.wx.util; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; /** * @Author: Yun * @Description: 检验signature工具类 * @Date: Crea 4000 ted in 2017-11-29 9:49 */ public class SignUtil { /** * 与微信后台配置的Token要一致 */ private static String token = "souvcweixin"; /** * 方法名:checkSignature</br> * 详述:验证签名</br> * @param signature * @param timestamp * @param nonce * @return * @throws */ public static boolean checkSignature(String signature, String timestamp,String nonce) { // 1.将token、timestamp、nonce三个参数进行字典序排序 String[] arr = new String[] { token, timestamp, nonce }; Arrays.sort(arr); // 2. 将三个参数字符串拼接成一个字符串进行sha1加密 StringBuilder content = new StringBuilder(); for (int i = 0; i < arr.length; i++) { content.append(arr[i]); } MessageDigest md; String tmpStr = null; try { md = MessageDigest.getInstance("SHA-1"); // 将三个参数字符串拼接成一个字符串进行sha1加密 byte[] digest = md.digest(content.toString().getBytes()); tmpStr = byteToStr(digest); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } // 3.将sha1加密后的字符串可与signature对比,标识该请求来源于微信 return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false; } /** * 方法名:byteToStr</br> * 详述:将字节数组转换为十六进制字符串</br> * 开发人员:souvc </br> * 创建时间:2015-9-29 </br> * @param byteArray * @return * @throws */ private static String byteToStr(byte[] byteArray) { String strDigest = ""; for (int i = 0; i < byteArray.length; i++) { strDigest += byteToHexStr(byteArray[i]); } return strDigest; } /** * 方法名:byteToHexStr</br> * 详述:将字节转换为十六进制字符串</br> * @param mByte * @return * @throws */ private static String byteToHexStr(byte mByte) { char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A','B', 'C', 'D', 'E', 'F' }; char[] tempArr = new char[2]; tempArr[0] = Digit[(mByte >>> 4) & 0X0F]; tempArr[1] = Digit[mByte & 0X0F]; String s = new String(tempArr); return s; } }如果你微信公众号后台配置无误,而且你的服务器后台也没有啥问题的。。到此,微信与你的服务器已经对接上了。。在这里,顺便讲一下公众号(微信后台)、用户、我们的服务器这三者之间是如何传递消息的。
上面是微信官方的说法。我们理解一下,简单来说,就是用户发送消息给我们公众号,公众号也就是微信后台,在接收到这个消息时,会将这条消息的内容、发送人、时间等一些参数封装成xml格式,然后再转发给我们的服务器。我们的服务器接收到这个请求时,需要作出对应的回复,再讲回复封装成xml转发给微信后台。。。微信后台收到我们服务器发送的xml之后,然后再将数据发送给用户。。这就是用户与公众号之间的一次消息传递过程。。。
消息传递的过程很简单,,,,,我们唯一要关心的点就是,对于用户的输入,我们该反馈什么样的结果给与用户。。。。。这也是我们服务器主要做的事情。。。。
微信支持的消息有六种,,这里我们只做回复文本消息。。。
回复文本消息,我们的核心就是调用图灵的问答api接口。。将用户发送的消息作为请求参数,我们去请求图灵机器人的问答系统开放接口,获取回复后,我们将回复的内容再经过转换发送给用户,这就实现了机器人聊天的功能了。。。。
代码见下:
用户发送消息之后,微信服务器会将此消息以post的请求方式、xml的数据格式转发给我们服务器。服务器收到此消息,也要返回一条对应的xml格式数据回复给微信服务器
@ResponseBody
@PostMapping("/")
public String doPost(HttpServletRequest request){
/*
在收到微信服务器的请求之后,我们需要做如下几件事!
1、解析微信发送的请求数据(将xml转换成map,获取消息发送人、消息接收人、时间、内容)
2、发送请求给图灵的接口,获取返回值,并解析提取回复内容
3、将回复内容和第一步解析到的消息发送人封装成xml格式,再返回给微信服务器
*/
return coreService.process(request);
}
package com.yunhui.wx.service; import com.yunhui.wx.bean.response.TextRespMessage; import com.yunhui.wx.robot.service.*; import com.yunhui.wx.util.MessageUtils; import org.springframework.stereotype.Service; import javax.servlet.http.HttpServletRequest; import java.util.Date; import java.util.Map; /** * @Author: Yun * @Description: * @Date: Created in 2017-11-29 14:24 */ @Service public class CoreService { public String process(HttpServletRequest request){ // xml格式的消息数据 String respXml = null; // 默认返回的文本消息内容 String respContent = "未知的消息类型!"; try { // 调用parseXml方法解析请求消息 Map<String, String> requestMap = MessageUtils.parseXml(request); // 发送方帐号 String fromUserName = requestMap.get("FromUserName"); // 开发者微信号 String toUserName = requestMap.get("ToUserName"); // 消息类型 String msgType = requestMap.get("MsgType"); // 消息内容 String info=requestMap.get("Content"); // 回复文本消息 TextRespMessage textMessage = new TextRespMessage(); textMessage.setToUserName(fromUserName); textMessage.setFromUserName(toUserName); textMessage.setCreateTime(System.currentTimeMillis()); textMessage.setMsgType(MessageUtils.RESP_MESSAGE_TYPE_TEXT); // 文本消息 if (msgType.equals(MessageUtils.REQ_MESSAGE_TYPE_TEXT)) { //如果用户发送的是文本消息,则调用图灵机器人的接口,获取回复内容并返回给微信服务器 respContent=TlRobotService.getTextResponse(fromUserName,info); } // 图片消息 else if (msgType.equals(MessageUtils.REQ_MESSAGE_TYPE_IMAGE)) { respContent = "您发送的是图片消息,小云还不知道怎么回答嘛。。。"; } // 语音消息 else if (msgType.equals(MessageUtils.REQ_MESSAGE_TYPE_VOICE)) { respContent = "您发送的是语音消息,小云还不知道怎么回答嘛。。。"; } // 视频消息 else if (msgType.equals(MessageUtils.REQ_MESSAGE_TYPE_VIDEO)) { respContent = "您发送的是视频消息,小云还不知道怎么回答嘛。。。"; } // 视频消息 else if (msgType.equals(MessageUtils.REQ_MESSAGE_TYPE_SHORTVIDEO)) { respContent = "您发送的是小视频消息,小云还不知道怎么回答嘛。。。"; } // 地理位置消息 else if (msgType.equals(MessageUtils.REQ_MESSAGE_TYPE_LOCATION)) { respContent = "您发送的是地理位置消息,小云还不知道怎么回答嘛。。。"; } // 链接消息 else if (msgType.equals(MessageUtils.REQ_MESSAGE_TYPE_LINK)) { respContent = "您发送的是链接消息,小云还不知道怎么回答嘛。。。"; } // 事件推送 else if (msgType.equals(MessageUtils.REQ_MESSAGE_TYPE_EVENT)) { // 事件类型 String eventType = requestMap.get("Event"); // 关注 if (eventType.equals(MessageUtils.EVENT_TYPE_SUBSCRIBE)) { respContent = "欢迎关注机器人小云。。。。"; } // 取消关注 else if (eventType.equals(MessageUtils.EVENT_TYPE_UNSUBSCRIBE)) { // TODO 取消订阅后用户不会再收到公众账号发送的消息,因此不需要回复 } // 扫描带参数二维码 else if (eventType.equals(MessageUtils.EVENT_TYPE_SCAN)) { // TODO 处理扫描带参数二维码事件 } // 上报地理位置 else if (eventType.equals(MessageUtils.EVENT_TYPE_LOCATION)) { // TODO 处理上报地理位置事件 } // 自定义菜单 else if (eventType.equals(MessageUtils.EVENT_TYPE_CLICK)) { // TODO 处理菜单点击事件 } } // 设置文本消息的内容 textMessage.setContent(respContent); // 将文本消息对象转换成xml respXml = MessageUtils.messageToXml(textMessage); } catch (Exception e) { e.printStackTrace(); } return respXml; } }
调用图灵api接口时,我们先需要注册一个图灵的账号。。然后添加一个机器人(小云机器人是我已经添加好的)
然后点击设置,进入机器人管理页面。。。里面有api接入的说明,我们需要下面的两个参数
即下面:
public class BaseCommon {
/**
* 图灵机器人的配置参数
*/
public static final String TL_ROBOT_API_URL="http://www.tuling123.com/openapi/api";
public static final String TL_ROBOT_API_KEY="xxxxxxxxxxxx";//这里填写你自己的
}
调用图灵机器人的代码见下:
有一点需要说明一下。。由于人的问答具有连贯性,,所以我们在调用图灵的问答接口时,需要设置userid这个参数。。
在我的代码里,userid使用的是用户的openid。。。
package com.yunhui.wx.robot.service; import com.fasterxml.jackson.databind.ObjectMapper; import com.yunhui.wx.robot.bean.request.BaseReqMessage; import com.yunhui.wx.robot.bean.response.BaseRespMessage; import com.yunhui.wx.robot.bean.response.RobotResponTypeEnum; import com.yunhui.wx.robot.common.BaseCommon; import com.yunhui.wx.robot.util.HttpRequestUtil; /** * @Author: Yun * @Description: 图灵机器人的服务类 * @Date: Created in 2017-11-30 10:51 */ public class TlRobotService { /** * 调用图灵的问答API,并返回文本响应值 * @param userid * @param info * @return */ public static String getTextResponse(String userid,String info){ //封装请求参数对象 BaseReqMessage reqMessage=new BaseReqMessage(); reqMessage.setKey(BaseCommon.TL_ROBOT_API_KEY); reqMessage.setInfo(info); reqMessage.setUserid(userid); //转换为json ObjectMapper mapper=new ObjectMapper(); try { String json=mapper.writeValueAsString(reqMessage); String result=HttpRequestUtil.doPost(BaseCommon.TL_ROBOT_API_URL,json,"UTF-8"); BaseRespMessage respMessage=mapper.readValue(result,BaseRespMessage.class); RobotResponTypeEnum robotResponTypeEnum=RobotResponTypeEnum.getRobotResponseType(respMessage.getCode(),respMessage.getText()); return robotResponTypeEnum.getText(); } catch (Exception e) { e.printStackTrace(); } return null; } }由于篇幅限制,这里是不可能将所有的代码都展示出来了。。完整的项目源码在这。。。
Springboot开发微信公众号智能机器人(基于图灵api)
上面讲述的不够细。。比如微信发送的xml数据格式,,有哪些属性。。我们返回的xml要包含哪些属性。。。请求图灵机器人的格式要求、图灵机器人回复的json格式。。。。这个项目里面有大量的数据格式转换。。。建议下载我的代码,然后对照微信的公众号开发文档和图灵的api接入文档对比着看。。这样比较好。。。。。。
附一张我项目的结构图(这个项目作为一个springboot的项目,还是比较简单的。。。新手可以拿来熟悉springboot):
最后,,附一下我开发的微信公众号智能问答小机器人的微信号,欢迎大家前去骚扰。。
相关文章推荐
- 微信开发——基于springboot接入微信公众号(ngrok内网穿透技术)
- [置顶] 使用IDEA基于springboot开发ssm框架(undertow代替tomcat以及其他功能)
- 仿微信/QQ 开发基于XMPP的iPhone/iOS聊天客户端(一)好友资料
- 使用图灵机器人快速开发智能聊天机器人
- 【迷你微信】基于MINA、Hibernate、Spring、Protobuf的即时聊天系统:6.技术简介之Protobuf
- 仿微信/QQ 开发基于XMPP的iPhone/iOS聊天客户端(二)修改密码
- JEECG - 基于代码生成器的J2EE智能开发框架 续二: 代码生成器使用规则
- 【迷你微信】基于MINA、Hibernate、Spring、Protobuf的即时聊天系统:10.项目介绍之架构(2)
- 基于微信硬件公众平台的智能控制开发流程
- 【迷你微信】基于MINA、Hibernate、Spring、Protobuf的即时聊天系统:3.技术简介之MinaFilter——LoggingFilter (转)
- 源码推荐(10.13):基于UICollectionView的美图浏览器,基于XMPP 模仿微信开发的聊天软件
- 使用Spring 2.5 和 Hibernate 3.2 开发MVC Web程序(基于annotation特性)
- 【迷你微信】基于MINA、Hibernate、Spring、Protobuf的即时聊天系统:11.定制化Log输出
- 【迷你微信】基于MINA、Hibernate、Spring、Protobuf的即时聊天系统:7.项目介绍之架构(1)
- 如果是作为客户端的HTTP+JSON接口工程,没有JSP等view视图的情况下,使用Jersery框架开发绝对是第一选择。而在基于Spring3 MVC的架构下,对HTTP+JSON的返回类型也有很好
- 使用Spring 2.5 和 Hibernate 3.2 开发MVC Web程序(基于annotation特性)
- 【迷你微信】基于MINA、Hibernate、Spring、Protobuf的即时聊天系统:8.自定义传输协议
- 基于Spring MVC+Spring JPA技术使用Spring全注解实战开发大型商业ERP项目
- 【迷你微信】基于MINA、Hibernate、Spring、Protobuf的即时聊天系统:9.观察者模式