微信公众号开发教程(三)事件推送及关键字回复
作者:陈惠,叩丁狼教育高级讲师。原创文章,转载请注明出处。
我们这次利用上一篇文章学习的知识,来做一点小案例。
先来看看效果:
图片.png
这里的回复实际上分成了两种类型:1.关注时马上回复 2.根据关键字来回复
先说关键字回复,这种实际上我们已经很容易实现了,在上一次我们完成的效果是用户发送什么内容就直接回复相同的内容, 所以关键字的话只需要根据用户发送的内容来做相关的判断即可。
关键字回复
代码:
/**
* 微信消息处理
*/
@RequestMapping(value = "/weChat", method = RequestMethod.POST)
@ResponseBody
public Object handleMessage(@RequestBody InMsgEntity msg) {
//创建消息响应对象
OutMsgEntity out = new OutMsgEntity();
//把原来的发送方设置为接收方
out.setToUserName(msg.getFromUserName());
//把原来的接收方设置为发送方
out.setFromUserName(msg.getToUserName());
//获取接收的消息类型
String msgType = msg.getMsgType();
//设置消息的响应类型
out.setMsgType(msgType);
//设置消息创建时间
out.setCreateTime(new Date().getTime());
//根据类型设置不同的消息数据
if("text".equals(msgType)){
//用户发送的内容
String inContent = msg.getContent();
//公众号回复的内容
String outContent = null;
//关键字判断
if(inContent.contains("开班")){
outContent = "上海Java基础班第05期于2018/05/10开班\n" +
"广州Java基础班第24期于2018/04/02开班";
}else if(inContent.contains("地址")){
outContent = "北京校区:北京昌平区沙河镇万家灯火装饰城2楼8077号\n" +
"广州校区:广州市天河区棠下涌东路大地工业区D栋六楼\n" +
"上海校区:上海市青浦区华新镇华隆路1777号E通世界商务园华新园A座4楼402";
}else{
//用户发什么就回复什么
outContent = inContent;
}
out.setContent(outContent);
}else if("image".equals(msgType)){
out.setMediaId(new String[]{msg.getMediaId()});
}
return out;
}
效果:
图片.png事件推送
我们上次使用到的都是用户发送信息过来,我们才回复的。但是,如果是关注的时候需要马上回复,就要使用到事件消息,实际上,微信已经提供给我们很多的事件。
打开开发文档,选择"消息管理"的"接收事件推送":
图片.png
可以看到,主要有这些事件,我们便可根据不同的事件来做不同的处理:
1 关注/取消关注事件
2 扫描带参数二维码事件
3 上报地理位置事件
4 自定义菜单事件
5 点击菜单拉取消息时的事件推送
6 点击菜单跳转链接时的事件推送
关注时回复
现在我们来使用关注/取消关注事件
用户在关注与取消关注公众号时,微信会把这个事件推送到开发者填写的URL。
方便开发者给用户下发欢迎消息或者做一些帐号的解绑操作。
事件推送的xml参数介绍:
图片.png
事件和消息都是推送到我们的URL上,怎么区分他们也很简单,通过MsgType这个属性,
那么进一步再区分是关注还是取消关注,根据Event属性即可。
所以,我们在原来的InMsgEntity类,再添加一个Event属性。
@Setter
@Getter
@XmlRootElement(name="xml")
@XmlAccessorType(XmlAccessType.FIELD)
public class InMsgEntity {
// 开发者微信号
protected String FromUserName;
// 发送方帐号(一个OpenID)
protected String ToUserName;
// 消息创建时间
protected Long CreateTime;
/**
* 消息类型
* text 文本消息
* image 图片消息
* voice 语音消息
* video 视频消息
* music 音乐消息
* event 事件推送
*/
protected String MsgType;
// 消息id
protected Long MsgId;
// 文本内容
private String Content;
// 图片链接(由系统生成)
private String PicUrl;
// 图片消息媒体id,可以调用多媒体文件下载接口拉取数据
private String MediaId;
/**
* 事件类型
* subscribe(订阅)
* unsubscribe(取消订阅)
* LOCATION(上报地理位置)
* CLICK(点击普通的菜单)
* VIEW(点击跳转链接的菜单)
*/
private String Event;
}
接下来添加我们的业务逻辑:
/**
* 微信消息处理
*/
@RequestMapping(value = "/weChat", method = RequestMethod.POST)
@ResponseBody
public Object handleMessage(@RequestBody InMsgEntity msg) {
//创建消息响应对象
OutMsgEntity out = new OutMsgEntity();
//把原来的发送方设置为接收方
out.setToUserName(msg.getFromUserName());
//把原来的接收方设置为发送方
out.setFromUserName(msg.getToUserName());
//获取接收的消息类型
String msgType = msg.getMsgType();
//设置消息创建时间
out.setCreateTime(new Date().getTime());
//根据类型设置不同的消息数据
if("text".equals(msgType)){
//用户发送的内容
String inContent = msg.getContent();
//公众号回复的内容
String outContent = null;
//关键字判断
if(inContent.contains("开班")){
outContent = "上海Java基础班第05期于2018/05/10开班\n" +
"广州Java基础班第24期于2018/04/02开班";
}else if(inContent.contains("地址")){
outContent = "北京校区:北京昌平区沙河镇万家灯火装饰城2楼8077号\n" +
"广州校区:广州市天河区棠下涌东路大地工业区D栋六楼\n" +
"上海校区:上海市青浦区华新镇华隆路1777号E通世界商务园华新园A座4楼402";
}else{
//用户发什么就回复什么
outContent = inContent;
}
//设置消息的响应类型
out.setMsgType("text");
out.setContent(outContent);
}else if("image".equals(msgType)){
out.setMediaId(new String[]{msg.getMediaId()});
}else if("event".equals(msgType)){
//判断关注事件
if("subscribe".equals(msg.getEvent())){
out.setContent("欢迎关注![愉快]");
//设置消息的响应类型
out.setMsgType("text");
}
}
return out;
}
效果:
为了更好的理解,文章中是直接在代码里判断关键字的,如果我们做的是较完整和正式的应用,应该把关键字相关信息都存储到数据库中,再查找 ,而且也不应该把所有逻辑都放到控制器中判断,更应该抽取到业务层中。
另外,在开发过程中,有的时候测试收不到公众号回复的信息,但是代码debug找不到问题,可以尝试使用微信提供的接口调试工具,选择"消息接口调试",输入相关信息,可以检测是否连上我们的应用,也可以查看我们返回的XML数据包,再与正确的XML数据包做对比,基本可解决大部分的问题。
接口调试地址: https://mp.weixin.qq.com/debug/cgi-bin/apiinfo