微信接入智能机器人回复消息
1 寻找智能机器人API
此处我使用的是极速数据
七款不错的聊天机器人API推荐
①登录注册之后,直接搜索机器人
②申请数据
③在个人中心,找到自己的appKey
④编写代码,根据接口地址发起对应的HTTP请求即可
2 编写代码,实现与微信对接
①导入依赖
<!--dom4j 解析微信发送的XML数据--><dependency><groupId>dom4j</groupId><artifactId>dom4j</artifactId><version>1.1</version></dependency><!--xstream构建返回的XML--><dependency><groupId>com.thoughtworks.xstream</groupId><artifactId>xstream</artifactId><version>1.4.14</version></dependency><!--发送HTTP请求--><dependency><groupId>com.squareup.okhttp</groupId><artifactId>okhttp</artifactId><version>2.5.0</version></dependency><!--处理json数据--><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.83</version></dependency>
②编写基础类(返回给微信的XML实体类)
BaseXML:
@Data
@AllArgsConstructor
@NoArgsConstructor
public class BaseMessage {@XStreamAlias("ToUserName")private String toUserName;@XStreamAlias("FromUserName")private String fromUserName;@XStreamAlias("CreateTime")private String createTime;@XStreamAlias("MsgType")private String msgType;@XStreamAlias("MsgId")private String msgId;//初始化默认数据public BaseMessage(Map<String, String> requestMap){//开始是请求方,返回数据的时候,就成为了发送方this.toUserName = requestMap.get("FromUserName");this.fromUserName = requestMap.get("ToUserName");//微信中的时间默认是10位数,java的currentTimeMillis是13位,因此要除以1000this.createTime = System.currentTimeMillis() / 1000 + "";this.msgId = requestMap.get("MsgId");}}
TextMessage:
此处只实现了TextMessage(返回文本消息),其他消息,参考该模式实现
【详细文档,参考官网:https://mp.weixin.qq.com/】
@Data
@AllArgsConstructor
@NoArgsConstructor
@XStreamAlias("xml")
public class TextMessage extends BaseMessage{//文本内容@XStreamAlias("Content")private String content;public TextMessage(Map<String, String> requestMap, String content){super(requestMap);//设置消息类型为文本super.setMsgType("text");//设置文本消息this.content = content;}
}
③编写service,解析微信的XML数据,同时给微信返回XML数据
WxService:
@Service
public class WxService {/*** 解析通过dom4j解析XML数据* @param is* @return map*/public Map<String, String> parseRequest(InputStream is){Map<String, String> map = new HashMap<>();SAXReader reader = new SAXReader();try{//读取输入流,获取文档对象Document document = reader.read(is);//根据文档对象获取根节点Element root = document.getRootElement();//获取根节点的所有子节点List<Element> elements = root.elements();for(Element e : elements){map.put(e.getName(), e.getStringValue());}return map;}catch (Exception e){e.printStackTrace();}return null;}/*** 返回的消息* @param requestMap* @return*/public String getResponse(Map<String, String> requestMap){String msgType = requestMap.get("MsgType");//要返回的消息BaseMessage rtnMsg = null;switch (msgType){//根据消息类型,处理不同消息case "text":rtnMsg = dealTextMessage(requestMap);case "image"://TODObreak;case "voice":break;case "video":break;case "shortvideo":break;case "location":break;case "link":break;default:break;}return beanToXML(rtnMsg);}/*** 将消息对象处理为XML数据包* @param msg* @return*/public String beanToXML(BaseMessage msg){if(msg == null){return "";} //公众号返回信息XStream stream = new XStream();//设置需要处理XStreamAlias("xml")注解的类stream.processAnnotations(TextMessage.class);stream.processAnnotations(PicMessage.class);String xml = stream.toXML(msg);return xml;}/*** 处理文本消息* @param requestMap* @return*/public BaseMessage dealTextMessage(Map<String, String> requestMap){String returnMsg = "收到消息!!!";TextMessage tm = new TextMessage(requestMap, returnMsg);return tm;}/*** 智能问答机器人根据内容回复文本* @param requestMap* @return 返回XML格式的数据包*/public String getResponseByAI(Map<String, String> requestMap) throws IOException {String content = requestMap.get("Content");//拼接请求URL[appkey填写自己账号的]String baseUrl = "https://api.jisuapi.com/iqa/query?appkey=8033aa4b1f27e290&question=" + content;Request request = new Request.Builder().url(new URL(baseUrl)).get().build();OkHttpClient client = new OkHttpClient();Call call = client.newCall(request);Response response = call.execute();System.out.println("this is response===================");//注意okHttp的response.body().string()只能使用一次,如果重复使用会报java.lang.IllegalStateException: closed//如果想要得到多次string()结果,只有重新构建response对象String responseStr = response.body().string();JSONObject responseObj = JSONObject.parseObject(responseStr);System.out.println(responseObj);//获取结果Object result = responseObj.get("result");String resultStr = JSON.toJSONString(result);//获取数据对象JSONObject resultObj = JSONObject.parseObject(resultStr);//获取回复的内容String respContent = (String) resultObj.get("content");String type = (String) resultObj.get("type");//构建返回结果String returnMsg = "";if("聊天".equals(type) || "重复".equals(type)){returnMsg = respContent;}TextMessage textMessage = new TextMessage(requestMap, returnMsg);String xml = beanToXML(textMessage);return xml;}
}
④编写controller,提供给微信请求地址
@RestController
public class WxController {@Autowiredprivate WxService wxService;@PostMapping("/wx")public void receiveMsg(HttpServletRequest request, HttpServletResponse response){try {//设置编码,防止乱码request.setCharacterEncoding("utf8");response.setCharacterEncoding("utf8");//获取请求信息ServletInputStream is = request.getInputStream();//处理消息和事件推送Map<String, String> requestMap = wxService.parseRequest(is);System.out.println(requestMap);//准备回复的数据包
// String respXML = wxService.getResponse(requestMap);//测试机器人String respXML = wxService.getResponseByAI(requestMap);System.out.println(respXML);PrintWriter out = response.getWriter();out.print(respXML);out.flush();out.close();} catch (IOException e) {e.printStackTrace();}}
}
提供给微信的请求地址,需要注册自己的开发账号,详情见:
微信接口配置失败、接收微信发送的消息、与微信交互
3 测试功能
在自己的接口测试账号上发送消息,查看结果