微信开发智能机器人
最近对微信开发比较感兴趣 于是就学了点皮毛 在这里进行记录,如有不足之处还请指出来 大家一起学习。
本篇文章所需要的技术与工具:
需要个人的微信公众帐号(当然企业的权限更多或者服务号)如果没有可以申请,申请地址https://mp.weixin.qq.com/
需要一台服务器或者虚拟机也行 微信开发需要支持外网连接 如果是虚拟机的话 需要用例如花生壳等工具将本地网映射到外网访问,其他方法也行 我这里用的是阿里云服务费 买一个一年的也不贵
开发环境 eclipse maven jdk1.7 tomcat7
申请微信公众帐号:
微信公众帐号支持两种模式:一种是编辑模式,一种是开发模式,编辑模式这里就不说了,主要弄开发模式
在公众号开发阶段微信公众帐号可以申请测试帐号进行测试
进行测试号申请,配置开发环境
介绍完微信公众号接下来就进入编码阶段
项目工程就是普通的maven工程采用的框架就是springmvc
接入微信项目不管是开发环境还是生产环境需要配置一个服务器地址,这个地址1、必须是可以通过外网访问的,2、必须支持get和post请求,这两个请求是不同的方法。
1、填写服务器配置 需要提供一个80端口或者443端口的服务
2、验证服务器地址的有效性
3、依据接口文档实现业务逻辑
get请求:通过检验 signature 对请求进行校验,若校验成功则原样返回 echostr,表示接入成功,否则接入失败
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 @RequestMapping(value="/index", method=RequestMethod.GET) 2 public void wxIndexdoGet(HttpServletRequest request,HttpServletResponse response) throws IOException{ 3 String signature=request.getParameter("signature"); 4 String timestamp=request.getParameter("timestamp"); 5 String nonce=request.getParameter("nonce"); 6 String echostr=request.getParameter("echostr"); 7 PrintWriter out = response.getWriter(); 8 // 通过检验 signature 对请求进行校验,若校验成功则原样返回 echostr,表示接入成功,否则接入失败 9 if (CheckUtil.checkSignature(signature, timestamp, nonce)) { 10 out.print(echostr); 11 } 12 out.close(); 13 out = null; 14 }
post请求是通过获取用户所发信息,和返回给用户信息的一个方法
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 @RequestMapping(value="/index", method=RequestMethod.POST) 2 public void wxIndexdoPost(HttpServletRequest request,HttpServletResponse response) throws Exception{ 3 request.setCharacterEncoding("UTF-8"); 4 response.setCharacterEncoding("UTF-8"); 5 PrintWriter out =response.getWriter(); 6 try { 7 Map<String, String> map = MessageUtil.xmlToMap(request); 8 String fromUserName = map.get("FromUserName"); 9 String toUserName = map.get("ToUserName"); 10 String msgType = map.get("MsgType"); 11 String content = map.get("Content"); 12 String event = map.get("Event"); 13 String fhMessage=""; 14 if(MessageUtil.MESSAGE_TEXT.equals(msgType)){ 15 //调用微信机器人返回信息 16 String tulingMessage = null; 17 String result = MessageUtil.jqr(content, fromUserName.replaceAll("-", "").replaceAll("_", "").substring(0,15), null); 18 WeiXinTlResultModel wxModel = JsonUtils.jsonToPojo(result, WeiXinTlResultModel.class); 19 System.out.println(wxModel.getCode()); 20 if(wxModel.getCode().equals("100000")||wxModel.getCode().equals("200000")){//文本类和连接类 文本消息 21 if(wxModel.getCode().equals("100000")){ 22 tulingMessage=wxModel.getText(); 23 }else if(wxModel.getCode().equals("200000")){ 24 tulingMessage=wxModel.getText()+wxModel.getUrl(); 25 } 26 TextMessage message = new TextMessage(); 27 message.setFromUserName(toUserName); 28 message.setToUserName(fromUserName); 29 message.setMsgType("text"); 30 message.setCreateTime(new Date().getTime()); 31 //message.setContent("您发送的内容是:"+content); 32 message.setContent(tulingMessage); 33 fhMessage=MessageUtil.textMessageToXml(message); 34 }else if(wxModel.getCode().equals("308000")){//集合类 图文消息 35 tulingMessage = wxModel.getList().get(0).getIcon()+wxModel.getList().get(0).getName(); 36 ImagesAndTextMessage itMessage = new ImagesAndTextMessage(); 37 itMessage.setToUserName(fromUserName); 38 itMessage.setFromUserName(toUserName); 39 itMessage.setCreateTime(new Date().getTime()); 40 itMessage.setMsgType("news"); 41 itMessage.setArticleCount("5"); 42 List<ImageItem> item = new ArrayList<ImageItem>(); 43 ImageItem ii = null; 44 for (int i = 0; i < 5; i++) { 45 ii = new ImageItem(); 46 ii.setDescription(wxModel.getList().get(i).getInfo()); 47 ii.setTitle(wxModel.getList().get(i).getName()); 48 ii.setPicUrl(wxModel.getList().get(i).getIcon()); 49 ii.setUrl(wxModel.getList().get(i).getDetailurl()); 50 item.add(ii); 51 } 52 itMessage.setArticles(item); 53 fhMessage = MessageUtil.imagesAndTextToXml(itMessage); 54 System.out.println(fhMessage); 55 } 56 //关注/取消关注事件 57 }else if(MessageUtil.MESSAGE_EVENT.equals(msgType)){ 58 //点击关注 59 if(MessageUtil.MESSAGE_SUBSCRIBE.equals(event)){ 60 TextMessage message = new TextMessage(); 61 message.setFromUserName(toUserName); 62 message.setToUserName(fromUserName); 63 message.setMsgType("text"); 64 message.setCreateTime(new Date().getTime()); 65 message.setContent("感谢您关注骑猪上树,我们会为您带来更好的平台!"); 66 fhMessage=MessageUtil.textMessageToXml(message); 67 //取消关注 68 }else if(MessageUtil.MESSAGE_UNSUBSCRIBE.equals(event)){ 69 TextMessage message = new TextMessage(); 70 message.setFromUserName(toUserName); 71 message.setToUserName(fromUserName); 72 message.setMsgType("text"); 73 message.setCreateTime(new Date().getTime()); 74 message.setContent("感谢您的关注,骑猪上树会让你再回来的!"); 75 fhMessage=MessageUtil.textMessageToXml(message); 76 } 77 } 78 out.print(fhMessage); 79 } catch (DocumentException e) { 80 e.printStackTrace(); 81 }finally{ 82 out.close(); 83 }
校验是否接入成功
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 private static final String token = "ceshi";//换成自己的token 2 public static boolean checkSignature(String signature,String timestamp,String nonce){ 3 String[] arr = new String[]{token,timestamp,nonce}; 4 Arrays.sort(arr); 5 StringBuffer content =new StringBuffer(); 6 for (int i = 0; i < arr.length; i++) { 7 content.append(arr[i]); 8 } 9 MessageDigest md = null; 10 String tmpStr = null; 11 try { 12 md = MessageDigest.getInstance("SHA-1"); 13 byte[] digest = md.digest(content.toString().getBytes()); 14 tmpStr = byteToStr(digest); 15 } catch (NoSuchAlgorithmException e) { 16 // TODO Auto-generated catch block 17 e.printStackTrace(); 18 } 19 content = null; 20 return tmpStr != null ? tmpStr.equals(signature.toUpperCase()): false; 21 } 22 23 /** 24 * 将字节数组转换为十六进制字符串 25 * @param digest 26 * @return 27 */ 28 private static String byteToStr(byte[] digest) { 29 // TODO Auto-generated method stub 30 String strDigest = ""; 31 for(int i = 0; i < digest.length; i++){ 32 strDigest += byteToHexStr(digest[i]); 33 } 34 return strDigest; 35 } 36 37 /** 38 * 将字节转换为十六进制字符串 39 * @param b 40 * @return 41 */ 42 private static String byteToHexStr(byte b) { 43 // TODO Auto-generated method stub 44 char[] Digit = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; 45 char[] tempArr = new char[2]; 46 tempArr[0] = Digit[(b >>> 4) & 0X0F]; 47 tempArr[1] = Digit[b & 0X0F]; 48 49 String s = new String(tempArr); 50 return s; 51 }
在这里就不一一将代码列出来了,文章最后会把代码的github地址贴出来
微信接入成功后,开始实现机器人逻辑
机器人主要是调用第三方api实现图灵机器人(地址:http://www.tuling123.com/)
登陆成功后,添加微信机器人,翻到最下方有一个接入
通过调用此接口实现。传递参数格式是json格式,返回也是json格式。
接下来就是将这个机器人添加到微信公众帐号中去
实现思路:用户通过界面输入任何一串数字,我们将这个数字进行封装成图灵机器人的传递参数,发送给图灵机器人,获取返回参数格式,根据返回信息的格式组装成消息体发送给用户。
实现效果:
代码地址:https://github.com/gitChenchao/weixin.git
大家记得关注我的 微信公众帐号 骑猪上树
最后将代码打包部署到服务器