2.【小萌伴】机器人陪聊模块分享

小萌伴最初版本只是一个机器人陪聊软件,所以其最初的核心功能就是聊天机器人,这一功能做得很早,代码也写得很简单。

xmb.itlao5.com

聊天机器人用的是第三方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地址:

  1. 聚合数据
  2. showApi
  3. haoService
  4. 图灵机器人


发表评论

必填项已用*标注

+ 58 = 67