1、图灵官网
http://www.turingapi.com
进入官网后,注册登录账号,然后完成个人认证(需要身份证+人脸的正反照)。认证完成之后应该会有5个免费的机器人,每个机器人自动回复上限是100次(其实是101次),用完之后第二天才能解除限制。
2、图灵API接入文档
接入说明
注册图灵账号
登入网站 http://biz.turingos.cn/login 注册账户
编码方式
UTF-8(调用图灵API的各个环节的编码方式均为UTF-8)
接口地址
http接入: http://api.turingos.cn/turingos/api/v2
https接入:https://api.turingos.cn/turingos/api/v2
若对数据通信有较高的安全要求,建议选择https接入方式来访问图灵服务,由于ssl层验证预计会额外多花费40~50ms。
请求方法
Method: POST
Content-Type: application/json
请求参数
请求示例:
{
"reqType": 0,
"perception": {
"inputText": {
"text": "附近的酒店"
},
"inputImage": {
"url": "imageUrl"
},
"selfInfo": {
"location": {
"city": "北京",
"province": "北京",
"street": "信息路"
}
}
},
"userInfo": {
"apiKey": "",
"userId": ""
}
}
具体的参数说明可以看官方API文档
3、根据请求参数,我们进行参数的封装,然后调用接口
这里我用JavaBean转Json,这里的对象都是用来转Json的,所以就不实现Serializable接口了
TuLingBean
import lombok.Data;
@Data
public class TuLingBean {
/**输入类型:0-文本(默认)、1-图片、2-音频*/
private int reqType = 0;
private Perception perception;
private UserInfo userInfo;
}
Perception
import lombok.Data;
@Data
public class Perception {
private InputText inputText;
}
InputText
import lombok.Data;
@Data
public class InputText {
String text;
}
UserInfo
import lombok.Data;
@Data
public class UserInfo {
/**机器人标识*/
private String apiKey;
/**用户唯一标识*/
private String userId;
}
TuLingAPI
import com.wyz.project.weixin.util.WeixinUtil;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.springframework.stereotype.Service;
@Service
public class TuLingAPI {
/**
* 图灵机器人API
*/
private static final String TuLing_POST_URL="http://openapi.tuling123.com/openapi/api/v2";
private static final String USER_ID = "wyz";
/**
* 对请求参数进行封装
*
* @return
*/
private String request(String text, String apiKey) {
TuLingBean tuLingBean = new TuLingBean();
tuLingBean.setReqType(0);
Perception perception = new Perception();
InputText inputText = new InputText();
inputText.setText(text);
perception.setInputText(inputText);
tuLingBean.setPerception(perception);
UserInfo userInfo = new UserInfo();
userInfo.setApiKey(apiKey);
userInfo.setUserId(USER_ID);
tuLingBean.setUserInfo(userInfo);
//将java对象转成JSON格式
JSONObject jsonObject = JSONObject.fromObject(tuLingBean);
return jsonObject.toString();
}
/**
* 获取响应的结果
* @param jsonObjStr
* @return
*/
private String getResponse(String jsonObjStr) {
JSONObject jsonObject = WeixinUtil.httpRequest(TuLing_POST_URL, "POST", jsonObjStr);
JSONArray jsonArray = (JSONArray) jsonObject.get("results");
JSONObject jsonObject1 = (JSONObject) jsonArray.get(0);
JSONObject object= (JSONObject) jsonObject1.get("values");
String result = object.getString("text");
return result;
}
/**
* 外部调用该方法返回图灵机器人响应的文本
* @param text
* @return
*/
private String sendMessage(String text,String key) {
String jsonObjStr=this.request(text,key);
return this.getResponse(jsonObjStr);
}
/**机器人id*/
private static String[] API_KEY={"1","2","3","4","5"};
//记录当前机器人下标索引key
private static int KEY_INDEX = 0;
//判断所有的机器人key是都全部用完 true都可用,false都不可用
public static boolean TuLing_KEY_FLAG = true;
/**
* 递归方法
* @param text
* @return
*/
public String send(String text) {
if (TuLing_KEY_FLAG = false) {
return "机器人很累啦,明天再来吧";
}
String result = this.sendMessage(text, API_KEY[KEY_INDEX]);
//如果机器人超限制了,就换下一个机器人
if ("请求次数超限制!".equals(result)) {
KEY_INDEX++;
//判断递归是否结束,当机器人API池中已经没有key可用了,递归结束
if (KEY_INDEX >= API_KEY.length) {
//所有的机器人key已经不能用了,就将下标重置为0
KEY_INDEX = 0;
TuLing_KEY_FLAG = false;
return "机器人很累啦,明天再来吧";
}
return this.send(text);
}
return result;
}
}
SpringTask定时任务,每天凌晨恢复机器人的状态
@Component
public class TuLingTask {
@Scheduled(cron = "1-1 0 0 1/1 * ? ")
public void test() {
TuLingAPI.TuLing_KEY_FLAG = true;
}
}
记得在启动类上加注解 @EnableScheduling 开启SpringTask任务
4、返回请求的结果
CoreService
@Service
public class CoreService {
@Resource
private TuLingAPI tuLingAPI;
/**
* 处理微信发来的请求
*
* @param request
* @return
*/
public String processRequest(HttpServletRequest request) {
String respMessage = null;
try {
// 默认返回的文本消息内容
String respContent = "请求处理异常,请稍候尝试!";
// xml请求解析 调用消息工具类MessageUtil解析微信发来的xml格式的消息,解析的结果放在HashMap里;
Map<String, String> requestMap = MessageUtil.parseXml(request);
// 发送方帐号(open_id) 下面三行代码是: 从HashMap中取出消息中的字段;
String fromUserName = requestMap.get("FromUserName");
// 公众帐号
String toUserName = requestMap.get("ToUserName");
// 消息类型
String msgType = requestMap.get("MsgType");
// 回复文本消息 组装要返回的文本消息对象;
TextMessage textMessage = new TextMessage();
textMessage.setToUserName(fromUserName);
textMessage.setFromUserName(toUserName);
textMessage.setCreateTime(new Date().getTime());
textMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_TEXT);
textMessage.setFuncFlag(0);
// 由于href属性值必须用双引号引起,这与字符串本身的双引号冲突,所以要转义
// textMessage.setContent("欢迎访问<a
// href=\"http://www.baidu.com/index.php?tn=site888_pg\">百度</a>!");
// 将文本消息对象转换成xml字符串
respMessage = MessageUtil.textMessageToXml(textMessage);
/**
* 演示了如何接收微信发送的各类型的消息,根据MsgType判断属于哪种类型的消息;
*/
// 接收用户发送的文本消息内容
String content = requestMap.get("Content");
// 创建图文消息
NewsMessage newsMessage = new NewsMessage();
newsMessage.setToUserName(fromUserName);
newsMessage.setFromUserName(toUserName);
newsMessage.setCreateTime(new Date().getTime());
newsMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_NEWS);
newsMessage.setFuncFlag(0);
// 文本消息
if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_TEXT)) {
/*
API的调用在这里
*/
respContent = tuLingAPI.send(content);
}
// 图片消息
else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_IMAGE)) {
respContent = "您发送的是图片消息!";
}
// 地理位置消息
else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LOCATION)) {
respContent = "您发送的是地理位置消息!";
}
// 链接消息
else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LINK)) {
respContent = "您发送的是链接消息!";
}
// 音频消息
else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_VOICE)) {
respContent = "您发送的是音频消息!";
}
// 事件推送
else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_EVENT)) {
// 事件类型
String eventType = requestMap.get("Event");
// 订阅
if (eventType.equals(MessageUtil.EVENT_TYPE_SUBSCRIBE)) {
respContent = "欢迎关注微信公众号";
}
// 取消订阅
else if (eventType.equals(MessageUtil.EVENT_TYPE_UNSUBSCRIBE)) {
// TODO 取消订阅后用户再收不到公众号发送的消息,因此不需要回复消息
}
// 自定义菜单点击事件
else if (eventType.equals(MessageUtil.EVENT_TYPE_CLICK)) {
// 事件KEY值,与创建自定义菜单时指定的KEY值对应
String eventKey = requestMap.get("EventKey");
if (eventKey.equals("11")) {
respContent = "菜单项被点击!";
}
else if (eventKey.equals("70")) {
List<Article> articleList = new ArrayList<Article>();
// 单图文消息
Article article = new Article();
article.setTitle("标题");
article.setDescription("描述内容");
article.setPicUrl(
"图片");
article.setUrl("跳转连接");
articleList.add(article);
// 设置图文消息个数
newsMessage.setArticleCount(articleList.size());
// 设置图文消息
newsMessage.setArticles(articleList);
// 将图文消息对象转换为XML字符串
respMessage = MessageUtil.newsMessageToXml(newsMessage);
return respMessage;
}
}
}
// 组装要返回的文本消息对象;
textMessage.setContent(respContent);
// 调用消息工具类MessageUtil将要返回的文本消息对象TextMessage转化成xml格式的字符串;
respMessage = MessageUtil.textMessageToXml(textMessage);
} catch (Exception e) {
e.printStackTrace();
}
return respMessage;
}
}
5、测试结果
这机器人。。。。。。