小萌伴最初版本只是一个机器人陪聊软件,所以其最初的核心功能就是聊天机器人,这一功能做得很早,代码也写得很简单。
聊天机器人用的是第三方Api,最初是聚合数据,刚开始免费无限次数调用,半年后收费开了一年钻石会员继续无限次数调用,用了一年,会员价翻了几倍;因为聚合数据居然用的是图灵机器人,所以用了图灵机器人的sdk,再后来因为调用限制太低(5000降为了100次/天);于是又用到showApi和haoService,并且开了多个号,加起来够几万次调用,能够满足了几千用户的正常使用。
以下分别是聚合、showApi和haoService的接口调用代码:
/**
* 聚合数据,聊天机器人数据接口
*/
public void robotAsk(NetCallback callback, String info, String userid) {
String url = "http://op.juhe.cn/robot/index";// 请求接口地址
Map params = new HashMap();// 请求参数
params.put("key", APPKEY_ROBOT_JUHE);// 您申请到的本接口专用的APPKEY
params.put("info", info);// 要发送给机器人的内容,不要超过30个字符
params.put("dtype", "json");// 返回的数据的格式,json或xml,默认为json
params.put("loc", "");// 地点,如北京中关村
params.put("lon", "");// 经度,东经116.234632(小数点后保留6位),需要写为116234632
params.put("lat", "");// 纬度,北纬40.234632(小数点后保留6位),需要写为40234632
params.put("userid", userid);// 1~32位,此userid针对您自己的每一个用户,用于上下文的关联
doNet(callback, url, params);
}
/**
* showapi,聊天机器人数据接口
*/
public void robotAsk(NetCallback callback, String info, String userid) {
String url = "http://route.showapi.com/60-27";// 请求接口地址
Map params = new HashMap();// 请求参数
params.put("info", info);// 要发送给机器人的内容,不要超过30个字符
params.put("userid", userid);// 1~32位,此userid针对您自己的每一个用户,用于上下文的关联
params.put("showapi_appid", APPKEY_ROBOT_SHOWAPI);
params.put("showapi_sign", APPKEY_SIGN_SHOWAPI);
params.put("showapi_timestamp", System.currentTimeMillis());
params.put("showapi_sign_method", "md5");
params.put("showapi_res_gzip", "0");
doNet(callback, url, params);
}
/**
* haoservice,聊天机器人数据接口
*/
public void robotAsk(NetCallback callback, String info, String userid) {
String url = "http://apis.haoservice.com/efficient/robot";
Map params = new HashMap();// 请求参数
params.put("key", APPKEY_ROBOT_HAOAPI);// 您申请到的本接口专用的APPKEY
params.put("info", info);// 要发送给机器人的内容,不要超过30个字符
doNet(callback, url, params);
}
这是网络请求回调接口,最初准备返回retCode和retMsg,后来决定从简只返回JSONObject了:
/**
* 回调接口
*/
public interface NetCallback{
public void callback(JSONObject object);
}
这是一个简单的HttpURLConnection网络请求封装,项目开始比较早,什么OKHttp之类的也不太流行,而且应用用到网络请求的地方并不是非常多,集成第三方网络框架过于臃肿了:
/**
* 发起网络请求
* @param callback
* @param url
* @param params
* @param isPost
*/
private void doNet(NetCallback callback, String url, Map params, boolean isPost) {
JSONObject object = null;
try {
String strMethod;
if(isPost) {
trMethod = "POST";
} else {
strMethod = "GET";
}
String result = net(url, params, strMethod);
object = new JSONObject(result);
// if (object.getInt("error_code") == 0) {
// System.out.println(object.get("result"));
// } else {
// System.out.println(object.get("error_code") + ":" + object.get("reason"));
// }
} catch (Exception e) {
// e.printStackTrace();
}
callback.callback(object);
}
/**
*
* @param strUrl
* 请求地址
* @param params
* 请求参数
* @param method
* 请求方法
* @return 网络请求字符串
* @throws Exception
*/
private static String net(String strUrl, Map params, String method) throws Exception {
HttpURLConnection conn = null;
BufferedReader reader = null;
String rs = null;
try {
StringBuffer sb = new StringBuffer();
if (method == null || method.equals("GET")) {
strUrl = strUrl + "?" + urlencode(params);
}
URL url = new URL(strUrl);
conn = (HttpURLConnection) url.openConnection();
if (method == null || method.equals("GET")) {
conn.setRequestMethod("GET");
} else {
conn.setRequestMethod("POST");
conn.setDoOutput(true);
}
conn.setRequestProperty("User-agent", userAgent);
conn.setUseCaches(false);
conn.setConnectTimeout(DEF_CONN_TIMEOUT);
conn.setReadTimeout(DEF_READ_TIMEOUT);
conn.setInstanceFollowRedirects(false);
conn.connect();
if (params != null && method.equals("POST")) {
try {
DataOutputStream out = new DataOutputStream(conn.getOutputStream());
out.writeBytes(urlencode(params));
} catch (Exception e) {
// TODO: handle exception
}
}
InputStream is = conn.getInputStream();
reader = new BufferedReader(new InputStreamReader(is, DEF_CHATSET));
String strRead = null;
while ((strRead = reader.readLine()) != null) {
sb.append(strRead);
}
rs = sb.toString();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
reader.close();
}
if (conn != null) {
conn.disconnect();
}
}
return rs;
}
/**
* 将map型转为请求参数型
*/
private static String urlencode(Map<String, Object> data) {
StringBuilder sb = new StringBuilder();
for (Map.Entry i : data.entrySet()) {
try {
sb.append(i.getKey()).append("=").append(URLEncoder.encode(i.getValue() + "", "UTF-8")).append("&");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
return sb.toString();
}
以上是数据请求这一块,至于界面,则是普通的聊天对话框界面,只是对数据进行了一些过滤与处理,这些后面的文章再说。
简书:ThinkinLiu 博客: IT老五
分享完自己的烂代码,突然感慨着代码居然是自己写的,OMG,也许不同时期有不同时期的想法和见识吧。
发散下:经常听到有同事或朋友维护别人代码时吐槽“这代码太糟了,完全违背了***”、“这完全不合理啊”、“这明显不应该这样写”、“有一点点编程思想的人都不会这样写”......其实所有代码在某一个时期都是有原因的,不管好与坏,也许你的代码在别人眼里也是糟糕的,也许在几年后看自己代码,也觉得不可饶恕;个人认为,会看别人的代码比会写自己的代码更能体现一个人的能力......
以上用到的Api地址:
扫码关注微信公众号--IT老五
微信扫一扫关注公众号,获取更多实用app,订阅地址不定时更新
来自外部的引用