微信公众号开发(3) 您所在的位置:网站首页 自动回复源码 微信公众号开发(3)

微信公众号开发(3)

2023-11-05 07:29| 来源: 网络整理| 查看: 265

一、微信公众号消息 微信公众号消息主要有:文本消息、图片消息、语音消息、视频消息、小视频消息、地理位置消息、链接消息、事件推送。 我们先来实现简单的文本消息。

1、添加微信消息解析

/** * 解析消息内容 * * @param xml * @return */ private WechatMessage parseMessage(String xml) { WechatMessage msg = null; try { XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); XmlPullParser parser = factory.newPullParser(); parser.setInput(new StringReader(xml)); int type = parser.getEventType(); while (type != XmlPullParser.END_DOCUMENT) { String tagName = parser.getName(); switch (type) { case XmlPullParser.START_TAG: if ("xml".equals(tagName)) { msg = new WechatMessage(); } else if ("ToUserName".equals(tagName)) { msg.setTo(parser.nextText()); } else if ("FromUserName".equals(tagName)) { msg.setFrom(parser.nextText()); } else if ("MsgType".equals(tagName)) { msg.setMsgType(parser.nextText()); } else if ("CreateTime".equals(tagName)) { msg.setCreateTime(new Date(Long.parseLong(parser.nextText()) * 1000)); } else if ("Event".equals(tagName)) { msg.setEvent(parser.nextText()); } else if ("EventKey".equals(tagName)) { msg.setEventKey(parser.nextText()); } else if ("MsgId".equals(tagName)) { msg.setMsgId(parser.nextText()); } else if ("Content".equals(tagName)) { msg.setContent(parser.nextText()); } else if ("PicUrl".equals(tagName)) { msg.setPicUrl(parser.nextText()); } else if ("MediaId".equals(tagName)) { msg.setMediaId(parser.nextText()); } else if ("Format".equals(tagName)) { msg.setFormat(parser.nextText()); } else if ("Recognition".equals(tagName)) { msg.setRecognition(parser.nextText()); } else if ("ThumbMediaId".equals(tagName)) { msg.setThumbMediaId(parser.nextText()); } else if ("Location_X".equals(tagName)) { msg.setLocationX(parser.nextText()); } else if ("Location_Y".equals(tagName)) { msg.setLocationY(parser.nextText()); } else if ("Scale".equals(tagName)) { msg.setScale(parser.nextText()); } else if ("Label".equals(tagName)) { msg.setLabel(parser.nextText()); } else if ("Title".equals(tagName)) { msg.setTitle(parser.nextText()); } else if ("Url".equals(tagName)) { msg.setUrl(parser.nextText()); } else if ("Description".equals(tagName)) { msg.setDescription(parser.nextText()); } else if ("Ticket".equals(tagName)) { msg.setTicket(parser.nextText()); } else if ("Latitude".equals(tagName)) { msg.setLatitude(parser.nextText()); } else if ("Longitude".equals(tagName)) { msg.setLongitude(parser.nextText()); } else if ("Precision".equals(tagName)) { msg.setPrecision(parser.nextText()); } break; case XmlPullParser.END_TAG: if ("xml".equals(tagName)) { msg.setRaw(xml); } break; default: break; } type = parser.next(); } } catch (Exception e) { logger.error("parse wechat xml message exception : {}", e); } return msg; }

WechatMessage实体类。 添加消息转换xml方法,因为微信接受的消息格式是xml,所以我们返回给微信的消息需要将String转换为微信可识别的xml,代码如下:

@Data public class WechatMessage { private String to; // appid private String from; // openid private Date createTime; private String msgType; private String raw; private String msgId; private String Content; private String picUrl; private String MediaId; private String format; private String recognition; private String thumbMediaId; private String locationX; private String locationY; private String scale; private String label; private String title; private String url; private String description; /** * subscribe, unsubscribe, SCAN, LOCATION, CLICK, VIEW, */ private String event; private String eventKey; private String ticket; private String latitude; private String longitude; private String precision; /** * 转换xml * @return {String} */ public String toXml() { int nowTime = (int)(System.currentTimeMillis() / 1000); StringBuilder sb = new StringBuilder(); sb.append("\n"); sb.append("\n"); sb.append("\n"); sb.append("").append(nowTime).append("\n"); sb.append("\n"); if (StringUtils.isNotBlank(this.Content) && WeChatMsgType.REQ_MESSAGE_TYPE_TEXT.equals(this.msgType)) { sb.append("\n"); }else if(StringUtils.isNotBlank(this.Content) && WeChatMsgType.REQ_MESSAGE_TYPE_IMAGE.equals(this.msgType)){ sb.append("0"); }else if(WeChatMsgType.REQ_MESSAGE_TYPE_TRANSFRE.equals(this.msgType)){ } sb.append(""); return sb.toString(); } }

如上代码完全可以copy。

2、添加微信消息类型常量类

/** * 消息类型 * */ public class WeChatMsgType { // 请求消息类型:文本 public static final String REQ_MESSAGE_TYPE_TEXT = "text"; // 请求消息类型:图片 public static final String REQ_MESSAGE_TYPE_IMAGE = "image"; // 请求消息类型:语音 public static final String REQ_MESSAGE_TYPE_VOICE = "voice"; // 请求消息类型:视频 public static final String REQ_MESSAGE_TYPE_VIDEO = "video"; // 请求消息类型:小视频 public static final String REQ_MESSAGE_TYPE_SHORTVIDEO = "shortvideo"; // 请求消息类型:地理位置 public static final String REQ_MESSAGE_TYPE_LOCATION = "location"; // 请求消息类型:链接 public static final String REQ_MESSAGE_TYPE_LINK = "link"; // 客服消息 public static final String REQ_MESSAGE_TYPE_TRANSFRE = "transfer_customer_service"; // 请求消息类型:事件推送 public static final String REQ_MESSAGE_TYPE_EVENT = "event"; // 事件类型:subscribe(关注) public static final String EVENT_TYPE_SUBSCRIBE = "subscribe"; // 事件类型:unsubscribe(取消关注) public static final String EVENT_TYPE_UNSUBSCRIBE = "unsubscribe"; // 事件类型:SCAN(用户已关注时的扫描带参数二维码) public static final String EVENT_TYPE_SCAN = "SCAN"; // 事件类型:LOCATION(上报地理位置) public static final String EVENT_TYPE_LOCATION = "LOCATION"; // 事件类型:CLICK(点击菜单拉取消息) public static final String EVENT_TYPE_CLICK = "CLICK"; // 事件类型:VIEW(点击菜单跳转链接) public static final String EVENT_TYPE_VIEW = "VIEW"; // 响应消息类型:文本 public static final Integer RESP_MESSAGE_TYPE_TEXT = 1; // 响应消息类型:图片 public static final Integer RESP_MESSAGE_TYPE_IMAGE = 2; // 响应消息类型:语音 public static final String RESP_MESSAGE_TYPE_VOICE = "voice"; // 响应消息类型:视频 public static final String RESP_MESSAGE_TYPE_VIDEO = "video"; // 响应消息类型:音乐 public static final String RESP_MESSAGE_TYPE_MUSIC = "music"; // 响应消息类型:图文 public static final String RESP_MESSAGE_TYPE_NEWS = "news"; }

3、添加微信关键词回复配置表 因为一般业务需求会根据用户发送的关键词来做指定回复,并且这个回复可能经常改动,所以做成可配置的数据表

/** * @description WechatKeyWord 微信关键词回复配置表 */ @Data @Entity @Table(name = "xs_wechat_keyword") public class WechatKeyword { @Id @Column(name = "f_wechat_keyword_id", unique = true, nullable = false, length = 32) @GenericGenerator(name = "system-uuid", strategy = "uuid") @GeneratedValue(generator = "system-uuid") private String id; @Column(name = "f_keyword") private String keyword; @Column(name = "f_name") private String name; /** * 消息类型 1:文本 2:图片 */ @Column(name = "f_type") private Integer type; @Column(name = "f_content") private String content; @Column(name = "f_update_time") private Date updateTime; @Transient public void applyDefaultValue() { if(getUpdateTime() == null){ setUpdateTime(new Timestamp(System.currentTimeMillis())); } } }

4、实现自动回复功能 需要一些工具类和常量我们已经准备就绪,现在我们来实现消息接收与回复。为了看起来方便,我将一些在本章节未涉及到的功能代码先删除掉。 controller接口,需要注意的一点是,接受微信推送消息的路由必需和之前写的用作微信托管验证接口的路由相同,但是这里是POST请求,所以在这两个接口加上@GetMapping和@PostMapping注解,具体代码如下:

/** * 接收微信推送的消息 * @param xml * @return */ @PostMapping(value = "/index", produces="application/json;charset=UTF-8") @ResponseBody public String receiveWechatMessage(@RequestBody String xml) { logger.info("/wechatmp/index post data:{}", xml); String result = wechatHandleService.handleReceiveMessage(xml); if(StringUtils.isBlank(result)){ result = WechatConstant.SUCCESS; } return result; }

service层的代码如下,主要是将微信传过来解析为对象,然后根据用户发送的关键词,查询我们做好的关键词回复内容,然后转成xml返回给微信。

@Transactional public String handleReceiveMessage(String xml) { String response = null; try { String result = null; WechatMessage msg = parseMessage(xml); try { if (msg != null) { String msgType = msg.getMsgType(); if (WeChatMsgType.REQ_MESSAGE_TYPE_TEXT.equals(msgType)) { // 文本消息 msg = handleTextMessage(msg); result = msg.getContent(); } } } catch (Exception e) { logger.error("--handleReceiveMessage 处理微信消息异常: ", e); return WechatConstant.SUCCESS; } if (msg != null && StringUtils.isNotBlank(result)) { msg.setContent(result); response = msg.toXml(); logger.info("wx response xml:{}", response); } } catch (Exception ex) { logger.error("--handleReceiveMessage 解析微信消息异常: ", ex); return WechatConstant.SUCCESS; } return response; } /** * 文本消息 * @param msg * @return */ private WechatMessage handleTextMessage(WechatMessage msg) { String result = null; String keyword = msg.getContent(); try { WechatKeyword wechatKeyword = wechatKeywordService.findByKeyword(keyword); if(wechatKeyword != null){ result = wechatKeyword.getContent(); if(WeChatMsgType.RESP_MESSAGE_TYPE_TEXT.equals(wechatKeyword.getType())){ //文本消息 msg.setMsgType(WeChatMsgType.REQ_MESSAGE_TYPE_TEXT); } } }catch (Exception e){ logger.error("查询微信自动回复消息异常:{}", e); } if (result == null) { result = wechatMsgService.findByCode(WechatMsgTypes.DEFAULT_RESPONSE); msg.setMsgType(WeChatMsgType.REQ_MESSAGE_TYPE_TEXT); } msg.setContent(result); logger.info("wx handleTextMessage result:{}", result); return msg; }

如上,即已经实现的简单的关键词自动回复消息功能。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有