微信接入智能机器人回复消息
1 寻找智能机器人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位,因此要除以1000
this.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":
//TODO
break;
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 {
@Autowired
private 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 测试功能
在自己的接口测试账号上发送消息,查看结果