微信公众平台智能回复机器人后台开发
2015-06-04 17:42
555 查看
框架是groovy的框架grails ,但还是用java写的,有些地方跟java还是稍微有一丢丢不一样的,不过不碍事的
下面是各个对象类
class AutoReplyController { static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE"] //输入自己的公众号token private static final TOKEN = "YOUR TOKEN"; //图灵机器人开发key private static final APIKEY = "YOUR APIKEY"; /** * 微信后台主入口,所有的通过微信后台服务器转接到系统的方法全部由此入口登录 * @author slash * @since 2015年6月4日17:38:34 * @return */ def mainPort(){ String methods = request.getMethod(); HashMap<String, String> data = new HashMap<String, String>(); boolean listFlag = false; boolean urlFlag = false; boolean trainFlag = false; boolean planeFlag = false; boolean newsFlag = false; boolean eatFlag = false; StringBuffer replyString = new StringBuffer("<xml>\n"); //验证服务器地址有效性 if(request.getMethod().equals("GET")||request.getMethod().equals("get")){ boolean result = checkSignature(params.signature, params.timestamp, params.nonce, TOKEN); if(result) render params.echostr; } //具体业务主入口 else { try { InputStream inputStream = request.getInputStream(); // 创建saxReader对象 SAXReader reader = new SAXReader(); Document document = reader.read(inputStream); Element element = document.getRootElement(); List<Element> list = element.elements(); Map<String, Object> map = new HashMap<String, Object>(); for (Element e : list) { map.put(e.getName(), e.getText()); } if (map.get("MsgType") != null && map.get("MsgType").equals("text")) { //打通图灵机器人 String massageInfo = URLEncoder.encode(map.get("Content"), "utf-8"); String getURL = "http://www.tuling123.com/openapi/api?key=" + APIKEY + "&info=" + massageInfo; URL getUrl = new URL(getURL); HttpURLConnection connection = (HttpURLConnection) getUrl.openConnection(); connection.connect(); // 取得输入流,并使用Reader读取 BufferedReader bufferedReader = new BufferedReader(new InputStreamReader( connection.getInputStream(), "utf-8")); StringBuffer sb = new StringBuffer(); String line = ""; while ((line = bufferedReader.readLine()) != null) { sb.append(line); } //第一层JSON解析对象 JSONObject dataJson = new JSONObject(sb.toString()); //第二层JSON解析对象 JSONObject listJson Iterator it = dataJson.keys(); //遍历最外层JSON while (it.hasNext()){ String key = String.valueOf(it.next()); String value = (String) dataJson.get(key); //当获取到的key是list,即返回结果为新闻,列车,航班,菜谱 if(key.equals("list")){ listFlag = true; String a = value.substring(1,value.length()-1); listJson = new JSONObject(value.substring(1,value.length()-1)); Iterator listIt = listJson.keys(); //遍历list中的JSON while (it.hasNext()){ String listKey = String.valueOf(listIt.next()); //当获取的list中的key是trainnum时,即返回结果为列车 if(listKey.equals("trainnum")){ trainFlag = true; break; } if(listKey.equals("flight")){ planeFlag = true; break; } if(listKey.equals("article")){ newsFlag = true; break; } if(listKey.equals("name")){ eatFlag = true; break; } } } //当获取到的key是url,即返回结果为链接时 if(key.equals("url")){ urlFlag = true; } } ReplyForImageAndText replyForImageAndText = new ReplyForImageAndText(); replyForImageAndText.toUserName = map.get("FromUserName"); replyForImageAndText.fromUserName = map.get("ToUserName"); replyForImageAndText.msgType = map.get("MsgType"); replyForImageAndText.articleCount = 1; //如果返回结果为列车 if(listFlag && trainFlag){ ImageAndTextDetail imageAndTextDetail = new ImageAndTextDetail(); imageAndTextDetail.description = "车次:"+listJson.get("trainnum")+"; 起始站:"+ listJson.get("start")+"; 终点站:"+listJson.get("terminal")+"; 开车时间:"+ listJson.get("starttime")+"; 到达时间:"+listJson.get("endtime"); imageAndTextDetail.picUrl = listJson.get("icon").toString(); imageAndTextDetail.url = listJson.get("detailurl").toString(); replyString.append("<ToUserName><![CDATA[" + replyForImageAndText.toUserName + "]]></ToUserName>\n"); replyString.append("<FromUserName><![CDATA[" + replyForImageAndText.fromUserName + "]]></FromUserName>\n"); replyString.append("<CreateTime>" + replyForImageAndText.createTime + "</CreateTime>\n"); replyString.append("<MsgType><![CDATA[news]]></MsgType>\n"); replyString.append("<ArticleCount>" + replyForImageAndText.articleCount + "</ArticleCount>\n"); replyString.append("<Articles>\n"); replyString.append("<item>\n"); replyString.append("<Title><![CDATA[" + dataJson.get("text") + "]]></Title>\n"); replyString.append("<Description><![CDATA[" + imageAndTextDetail.description + "]]></Description>\n"); replyString.append("<PicUrl><![CDATA[" + imageAndTextDetail.picUrl + "]]></PicUrl>\n"); replyString.append("<Url><![CDATA[" + imageAndTextDetail.url + "]]></Url>\n"); replyString.append("</item>\n"); replyString.append("</Articles>\n"); replyString.append("</xml>"); } //如果返回结果为航班 else if(listFlag && planeFlag){ ImageAndTextDetail imageAndTextDetail = new ImageAndTextDetail(); imageAndTextDetail.description = "航班次:"+listJson.get("flight")+"; 航班路线:"+ listJson.get("route")+"; 起飞时间:"+ listJson.get("starttime")+"; 到达时间:"+listJson.get("endtime")+"; 航班状态:"+ listJson.get("state"); imageAndTextDetail.picUrl = listJson.get("icon").toString(); imageAndTextDetail.url = listJson.get("detailurl").toString(); replyString.append("<ToUserName><![CDATA[" + replyForImageAndText.toUserName + "]]></ToUserName>\n"); replyString.append("<FromUserName><![CDATA[" + replyForImageAndText.fromUserName + "]]></FromUserName>\n"); replyString.append("<CreateTime>" + replyForImageAndText.createTime + "</CreateTime>\n"); replyString.append("<MsgType><![CDATA[news]]></MsgType>\n"); replyString.append("<ArticleCount>" + replyForImageAndText.articleCount + "</ArticleCount>\n"); replyString.append("<Articles>\n"); replyString.append("<item>\n"); replyString.append("<Title><![CDATA[" + dataJson.get("text") + "]]></Title>\n"); replyString.append("<Description><![CDATA[" + imageAndTextDetail.description + "]]></Description>\n"); replyString.append("<PicUrl><![CDATA[" + imageAndTextDetail.picUrl + "]]></PicUrl>\n"); replyString.append("<Url><![CDATA[" + imageAndTextDetail.url + "]]></Url>\n"); replyString.append("</item>\n"); replyString.append("</Articles>\n"); replyString.append("</xml>"); } //如果返回结果为新闻 else if(listFlag && newsFlag){ ImageAndTextDetail imageAndTextDetail = new ImageAndTextDetail(); imageAndTextDetail.description = "标题:"+listJson.get("article")+"; 来源:"+ listJson.get("source"); imageAndTextDetail.picUrl = listJson.get("icon").toString(); imageAndTextDetail.url = listJson.get("detailurl").toString(); replyString.append("<ToUserName><![CDATA[" + replyForImageAndText.toUserName + "]]></ToUserName>\n"); replyString.append("<FromUserName><![CDATA[" + replyForImageAndText.fromUserName + "]]></FromUserName>\n"); replyString.append("<CreateTime>" + replyForImageAndText.createTime + "</CreateTime>\n"); replyString.append("<MsgType><![CDATA[news]]></MsgType>\n"); replyString.append("<ArticleCount>" + replyForImageAndText.articleCount + "</ArticleCount>\n"); replyString.append("<Articles>\n"); replyString.append("<item>\n"); replyString.append("<Title><![CDATA[" + dataJson.get("text") + "]]></Title>\n"); replyString.append("<Description><![CDATA[" + imageAndTextDetail.description + "]]></Description>\n"); replyString.append("<PicUrl><![CDATA[" + imageAndTextDetail.picUrl + "]]></PicUrl>\n"); replyString.append("<Url><![CDATA[" + imageAndTextDetail.url + "]]></Url>\n"); replyString.append("</item>\n"); replyString.append("</Articles>\n"); replyString.append("</xml>"); } //如果返回结果为菜谱 else if(listFlag && eatFlag){ ImageAndTextDetail imageAndTextDetail = new ImageAndTextDetail(); imageAndTextDetail.description = "菜名:"+listJson.get("name")+"; 详情:"+ listJson.get("info"); imageAndTextDetail.picUrl = listJson.get("icon").toString(); imageAndTextDetail.url = listJson.get("detailurl").toString(); replyString.append("<ToUserName><![CDATA[" + replyForImageAndText.toUserName + "]]></ToUserName>\n"); replyString.append("<FromUserName><![CDATA[" + replyForImageAndText.fromUserName + "]]></FromUserName>\n"); replyString.append("<CreateTime>" + replyForImageAndText.createTime + "</CreateTime>\n"); replyString.append("<MsgType><![CDATA[news]]></MsgType>\n"); replyString.append("<ArticleCount>" + replyForImageAndText.articleCount + "</ArticleCount>\n"); replyString.append("<Articles>\n"); replyString.append("<item>\n"); replyString.append("<Title><![CDATA[" + dataJson.get("text") + "]]></Title>\n"); replyString.append("<Description><![CDATA[" + imageAndTextDetail.description + "]]></Description>\n"); replyString.append("<PicUrl><![CDATA[" + imageAndTextDetail.picUrl + "]]></PicUrl>\n"); replyString.append("<Url><![CDATA[" + imageAndTextDetail.url + "]]></Url>\n"); replyString.append("</item>\n"); replyString.append("</Articles>\n"); replyString.append("</xml>"); } //如果返回结果为链接 else if(urlFlag){ ReplyForUrl replyForUrl = new ReplyForUrl(); replyForUrl.toUserName = map.get("FromUserName"); replyForUrl.fromUserName = map.get("ToUserName"); replyForUrl.msgType = map.get("MsgType"); replyForUrl.msgId = BigInteger.valueOf(Long.valueOf(map.get("MsgId"))); replyForUrl.contentUrl = dataJson.get("text")+",点击查询"; replyString.append("<ToUserName><![CDATA[" + replyForUrl.toUserName + "]]></ToUserName>\n"); replyString.append("<FromUserName><![CDATA[" + replyForUrl.fromUserName + "]]></FromUserName>\n"); replyString.append("<CreateTime>" + replyForUrl.createTime + "</CreateTime>\n"); replyString.append("<MsgType><![CDATA[" + replyForUrl.msgType + "]]></MsgType>\n"); replyString.append("<Content><![CDATA[<a href = '" + dataJson.get("url")+ "'>"+replyForUrl.contentUrl+"</a>]]></Content>\n"); replyString.append("</xml>"); } else { ReplyForText replyForText = new ReplyForText(); replyForText.toUserName = map.get("FromUserName"); replyForText.fromUserName = map.get("ToUserName"); replyForText.msgType = map.get("MsgType"); replyForText.msgId = BigInteger.valueOf(Long.valueOf(map.get("MsgId"))); replyForText.createTime = 15529131405; replyForText.content = dataJson.get("text"); replyString.append("<ToUserName><![CDATA[" + replyForText.toUserName + "]]></ToUserName>\n"); replyString.append("<FromUserName><![CDATA[" + replyForText.fromUserName + "]]></FromUserName>\n"); replyString.append("<CreateTime>" + replyForText.createTime + "</CreateTime>\n"); replyString.append("<MsgType><![CDATA[" + replyForText.msgType + "]]></MsgType>\n"); replyString.append("<Content><![CDATA[" + replyForText.content + "]]></Content>\n"); replyString.append("</xml>"); } } render replyString.toString(); } catch (Exception e) { e.printStackTrace(); } } }
<pre name="code" class="java"> /** * 检查请求是否合法 * @param signature * @param timestamp * @param nonce * @param token * @return * @throws Exception */ private boolean checkSignature(String signature, String timestamp, String nonce, String token) throws Exception{ String[] tmpArr = new String[3]; tmpArr[0] = token; tmpArr[1] = timestamp; tmpArr[2] = nonce; Arrays.sort(tmpArr);//对字符串数组 排序 String tmpStr = getArrayStr(tmpArr); String sha1 = makeSHA1(tmpStr); if(signature.equals(sha1)) return true; return false; } /** * 获得字符串数组的字符串形式 * @param array * @return */ private String getArrayStr(String[] array){ StringBuffer sb = new StringBuffer(); for(int i = 0; i < array.length; i++){ sb.append(array[i]); } return sb.toString(); } /** * 对字符串进行SHA1加密 * @param tmpStr * @return * @throws Exception */ private String makeSHA1(String tmpStr) throws Exception{ MessageDigest md = MessageDigest.getInstance("SHA-1");//获取MessageDigest实例 md.update(tmpStr.getBytes()); byte[] tmpArr = md.digest(); return byteToHex(tmpArr); } /** * 将二进制数据转化为十六进制数据串 * @param arr * @return */ private String byteToHex(byte[] arr){ String hs = ""; String tmp = ""; for(int i = 0; i < arr.length; i++){ tmp = Integer.toHexString(arr[i] & 0xFF); if(tmp.length() < 2){ tmp = "0" + tmp; } hs = hs + tmp; } return hs; }
下面是各个对象类
class ReplyForText { static constraints = { } //发送至 的微信号 String toUserName; //来自于 的微信号 String fromUserName; //回复 创建时间 BigInteger createTime; //消息类别:文字,图文,视频,音频,地理位置 String msgType; //内容 String content; //消息Id BigInteger msgId; }
class ReplyForUrl { static constraints = { } //发送至 的微信号 String toUserName; //来自于 的微信号 String fromUserName; //回复 创建时间 BigInteger createTime; //消息类别:文字,图文,视频,音频,地理位置 String msgType; //内容 String contentUrl; //消息Id BigInteger msgId; }
class ReplyForImageAndText { static constraints = { } //发送至 的微信号 String toUserName; //来自于 的微信号 String fromUserName; //回复 创建时间 BigInteger createTime; //消息类别:文字,图文,视频,音频,地理位置 String msgType; //图文消息个数,限制为10条以内 Integer articleCount; }
class ImageAndTextDetail { static constraints = { } //图文消息标题 String title; //图文消息描述 String description; //图片链接,支持JPG、PNG格式,较好的效果为大图360*200,小图200*200 String picUrl; //点击图文消息跳转链接 String url; }
相关文章推荐
- 微信分享须知
- 从一个小程序明白new和delete的奇特现象
- Android 微信支付body参数不支持中文的问题
- 微信接入自定义开发
- 微信支付商户申请接入信息汇总【接入教程】
- 微信JS-SDK说明文档及常见问题处理
- 用微信分享又用微信支付问题
- 微信开发 没有认证过的服务号怎么办?微信提供了测试号(开通了认证过的服务号的功能)
- 仿微信摇一摇震动
- 用c#开发微信 (12) 微统计 - 阅读分享统计系统 2 业务逻辑实现
- iOS微信接入错误解决。~
- 如何精准化的做微信公众号运营?
- 微信仿制的时候常用的抓包工具
- 类似微信朋友圈动态的数字红点
- Android 基于google Zxing实现二维码、条形码扫描,仿微信二维码扫描效果 (转载)
- 公众微信认证方法与条件
- php微信支付测试开发(流程已通)
- 微信支付调用JSAPI缺少参数:timeStamp
- 微信JS SDK Demo
- PHP JS判断浏览器,微信浏览器