java微信公众号开发(一)《基础配置对接部分(3)》:事件类消息处理
事件消息处理
事件类消息,我们编写EventManage类进行统一管理:
public class EventManage {
public static final Logger log = LoggerFactory.getLogger(EventManage.class);
@Autowired
private static IWxUserService wxUserService;
public static BaseMessage dealEvent(Map<String, String> mapRequest) {
BaseMessage bm=null;
String event =mapRequest.get("Event");
switch (event){
case "subscribe":
//用户关注
//扫描二位码关注
if (StringUtils.isNotEmpty(mapRequest.get("EventKey"))){
System.out.println("扫描关注公众号");
log.info("扫描关注公众号");
String eventkey =mapRequest.get("EventKey");
String ticket =mapRequest.get("Ticket");
System.out.println("EventKey:"+eventkey);
System.out.println("Ticket:"+ticket);
}
//正常关注
bm=dealSubscribe(mapRequest);
break;
case "unsubscribe":
//用户取消关注
bm=dealUnSubscribe(mapRequest);
break;
case "SCAN":
//用户已关注时的事件推送-扫码
bm=dealScan(mapRequest);
break;
case "LOCATION":
//上报地理位置:对于需要实时获取用户当前地理位置的功能,需要通过次入口将用户位置信息进行处理并使用
bm=dealLocation(mapRequest);
break;
case "CLICK":
//点击菜单拉取消息时的事件推送
bm=dealClick(mapRequest);
break;
case "VIEW":
//点击菜单跳转链接时的事件推送
bm=dealView(mapRequest);
break;
case "TEMPLATESENDJOBFINISH":
//模版消息发送任务完成时的事件推送
bm=dealTemplateSendJobFinish(mapRequest);
break;
default:
break;
}
return bm;
}
}
LOCATION上报地理位置事件
/**
* 处理LOCATION上报地理位置事件
* 用户同意上报地理位置后,每次进入公众号会话时,都会在进入时上报地理位置,或在进入会话后每5秒上报一次地理位置,
* 公众号可以在公众平台网站中修改以上设置。上报地理位置时,微信会将上报地理位置事件推送到开发者填写的URL。
* 推送XML数据包示例:
* <xml>
* <ToUserName><![CDATA[toUser]]></ToUserName>
* <FromUserName><![CDATA[fromUser]]></FromUserName>
* <CreateTime>123456789</CreateTime>
* <MsgType><![CDATA[event]]></MsgType>
* <Event><![CDATA[LOCATION]]></Event>
* <Latitude>23.137466</Latitude>
* <Longitude>113.352425</Longitude>
* <Precision>119.385040</Precision>
* </xml>
* 参数说明:
* 参数 描述
* ToUserName 开发者微信号
* FromUserName 发送方账号(一个OpenID)
* CreateTime 消息创建时间 (整型)
* MsgType 消息类型,event
* Event 事件类型,LOCATION
* Latitude 地理位置纬度
* Longitude 地理位置经度
* Precision 地理位置精度
*/
private static BaseMessage dealLocation(Map<String, String> mapRequest) {
return null;
}
SCAN已关注时的事件推送-扫码事件
/**
* 处理SCAN已关注时的事件推送-扫码事件
* 扫描带参数二维码事件
* 用户扫描带场景值二维码时,可能推送以下两种事件:
* 如果用户还未关注公众号,则用户可以关注公众号,关注后微信会将带场景值关注事件推送给开发者。
* 如果用户已经关注公众号,则微信会将带场景值扫描事件推送给开发者。
* 2. 用户已关注时的事件推送
* 推送XML数据包示例:
* <xml>
* <ToUserName><![CDATA[toUser]]></ToUserName>
* <FromUserName><![CDATA[FromUser]]></FromUserName>
* <CreateTime>123456789</CreateTime>
* <MsgType><![CDATA[event]]></MsgType>
* <Event><![CDATA[SCAN]]></Event>
* <EventKey><![CDATA[SCENE_VALUE]]></EventKey>
* <Ticket><![CDATA[TICKET]]></Ticket>
* </xml>
* 参数说明:
* 参数 描述
* ToUserName 开发者微信号
* FromUserName 发送方账号(一个OpenID)
* CreateTime 消息创建时间 (整型)
* MsgType 消息类型,event
* Event 事件类型,SCAN
* EventKey 事件KEY值,是一个32位无符号整数,即创建二维码时的二维码scene_id
* Ticket 二维码的ticket,可用来换取二维码图片
*/
private static BaseMessage dealScan(Map<String, String> mapRequest) {
return null;
}
subscribe/unsubscribe 关注/取消关注事件
/**
* 处理 subscribe/unsubscribe 关注/取消关注事件
* 用户在关注与取消关注公众号时,微信会把这个事件推送到开发者填写的URL。方便开发者给用户下发欢迎消息或者做账号的解绑。
* 为保护用户数据隐私,开发者收到用户取消关注事件时需要删除该用户的所有信息。
* 微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次。
* 关于重试的消息排重,推荐使用FromUserName + CreateTime 排重。
* 假如服务器无法保证在五秒内处理并回复,可以直接回复空串,微信服务器不会对此作任何处理,并且不会发起重试。
* 推送XML数据包示例:
* <xml>
* <ToUserName><![CDATA[toUser]]></ToUserName>
* <FromUserName><![CDATA[FromUser]]></FromUserName>
* <CreateTime>123456789</CreateTime>
* <MsgType><![CDATA[event]]></MsgType>
* <Event><![CDATA[subscribe]]></Event>
* </xml>
* 参数说明:
* 参数 描述
* ToUserName 开发者微信号
* FromUserName 发送方账号(一个OpenID)
* CreateTime 消息创建时间 (整型)
* MsgType 消息类型,event
* Event 事件类型,subscribe(订阅)、unsubscribe(取消订阅)
*/
private static BaseMessage dealSubscribe(Map<String, String> mapRequest) {
/**
* 处理subscribe关注事件(一):点击关注按钮
* 参数说明:
* 参数 描述
* Event 事件类型:subscribe(订阅)
*/
/**
* 处理subscribe关注事件(二):扫描带参数二维码
* 扫描带参数二维码事件
* 用户扫描带场景值二维码时,可能推送以下两种事件:
* 如果用户还未关注公众号,则用户可以关注公众号,关注后微信会将带场景值“关注事件”推送给开发者。
* 如果用户已经关注公众号,则微信会将带场景值“扫描事件”推送给开发者。
* 1. 用户未关注时,进行关注后的事件推送
* 推送XML数据包示例:
* <xml>
* <ToUserName><![CDATA[toUser]]></ToUserName>
* <FromUserName><![CDATA[FromUser]]></FromUserName>
* <CreateTime>123456789</CreateTime>
* <MsgType><![CDATA[event]]></MsgType>
* <Event><![CDATA[subscribe]]></Event>
* <EventKey><![CDATA[qrscene_123123]]></EventKey>
* <Ticket><![CDATA[TICKET]]></Ticket>
* </xml>
* 参数说明:
* 参数 描述
* ToUserName 开发者微信号
* FromUserName 发送方账号(一个OpenID)
* CreateTime 消息创建时间 (整型)
* MsgType 消息类型,event
* Event 事件类型,subscribe
* EventKey 事件KEY值,qrscene_为前缀,后面为二维码的参数值
* Ticket 二维码的ticket,可用来换取二维码图片
*/
if (mapRequest.containsKey("EventKey")){
//subscribe关注事件(二):扫描带参数二维码
String eventKey =mapRequest.get("EventKey");
System.out.println("用户通过扫描二维码关注了公众号");
}else{
//subscribe关注事件(一):点击关注按钮
System.out.println("用户通过点击关注按钮关注了公众号");
}
BaseMessage baseMessage=null;
//1.根据openid获取用户数据
Map map = ApiUtils.getUserInfo(mapRequest.get("FromUserName"));
System.out.println("获取到的用户数据:");
System.out.println(map);
//将标签列表id转换为用逗号分隔的字符串
JSONArray jan = (JSONArray)map.get("tagid_list");
String tagid ="";
if(jan!=null||jan.size()!=0){
for (int i = 0; i < jan.size(); i++) {
tagid=tagid+jan.get(i).toString()+",";
}
}
map.put("tagid_list",tagid);
//2.封装用户数据
WxUser wxUser = JSON.parseObject(JSON.toJSONString(map), WxUser.class);
if (null==wxUser.getSex()){
String sexData = (String) map.get("sex");
if (StringUtils.isNotEmpty(sexData)){
wxUser.setSex(sexData);
}
}
System.out.println("用户性别:"+wxUser.getSex());
System.out.println("用户数据转化为WxUser数据:");
System.out.println(wxUser);
wxUser.setuSbTime(DateUtils.getNowDate());
//3.保存用户
int i =wxUserService.insertWxUserFromWxSubscribe(wxUser);
//4.回复用户消息
//后台固定回复 采用后台回复模式
String msg ="您已关注公众号,系统授权失败,请联系管理员进行授权!";
if (i>0){
msg ="您好,欢迎关注公众号!了解更多,请点击选择:\n" +
"\t1. <a href=\"weixin://bizmsgmenu?msgmenuid=1&msgmenucontent=公众号简介\">公众号简介</a>介绍\n" +
"\t2. <a href=\"weixin://bizmsgmenu?msgmenuid=1&msgmenucontent=会员简介\">会员简介</a>介绍\n" +
"\t3. <a href=\"weixin://bizmsgmenu?msgmenuid=1&msgmenucontent=关于我们\">关于我们</a>介绍\n" +
"\t4. <a href=\"http://zk.hnjjzl.org.cn/wxPublic/wpp\">注册流程图</a>\n" +
"\t5. <a href=\"http://zk.hnjjzl.org.cn/wxPublic/wce\">注册人员分类说明</a>";
}
//回复空消息 采用微信公众管理平台设置回复模式 --返回空消息
/*if (i>0){
//msg =null;
return null;
}*/
return MessageManage.returnText(mapRequest,msg);
}
private static BaseMessage dealUnSubscribe(Map<String, String> mapRequest) {
/**
* 处理unsubscribe取消关注事件
* 参数说明:
* 参数 描述
* Event 事件类型:unsubscribe(取消订阅)
*/
BaseMessage baseMessage=null;
//更新用户数据,设置取消关注
String openid =mapRequest.get("FromUserName");
WxUser wxUser =new WxUser();
wxUser.setOpenid(openid);
int i =wxUserService.updateWxUserFromWxUnSubscribe(wxUser);
if (i>0){
log.info("用户取消关注,用户状态已更新");
System.out.println("用户取消关注,用户状态已更新");
}else {
log.info("用户取消关注,用户状态更新失败");
System.out.println("用户取消关注,用户状态更新失败");
}
return null;
}
View点击菜单跳转链接时事件
/**
* 处理View点击菜单跳转链接时的事件
* 自定义菜单事件
* 用户点击自定义菜单后,微信会把点击事件推送给开发者,请注意,点击菜单弹出子菜单,不会产生上报。
* 点击菜单跳转链接时的事件推送
* 推送XML数据包示例:
* <xml>
* <ToUserName><![CDATA[toUser]]></ToUserName>
* <FromUserName><![CDATA[FromUser]]></FromUserName>
* <CreateTime>123456789</CreateTime>
* <MsgType><![CDATA[event]]></MsgType>
* <Event><![CDATA[VIEW]]></Event>
* <EventKey><![CDATA[www.qq.com]]></EventKey>
* </xml>
* 参数说明:
* 参数 描述
* ToUserName 开发者微信号
* FromUserName 发送方账号(一个OpenID)
* CreateTime 消息创建时间 (整型)
* MsgType 消息类型,event
* Event 事件类型,VIEW
* EventKey 事件KEY值,设置的跳转URL
* @param mapRequest
* @return
*/
private static BaseMessage dealView(Map<String, String> mapRequest) {
return null;
}
Click点击菜单拉取消息事件
/**
* 处理Click点击菜单拉取消息的事件
* 自定义菜单事件
* 用户点击自定义菜单后,微信会把点击事件推送给开发者,请注意,点击菜单弹出子菜单,不会产生上报。
* 点击菜单拉取消息时的事件推送
* 推送XML数据包示例:
* <xml>
* <ToUserName><![CDATA[toUser]]></ToUserName>
* <FromUserName><![CDATA[FromUser]]></FromUserName>
* <CreateTime>123456789</CreateTime>
* <MsgType><![CDATA[event]]></MsgType>
* <Event><![CDATA[CLICK]]></Event>
* <EventKey><![CDATA[EVENTKEY]]></EventKey>
* </xml>
* 参数说明:
* 参数 描述
* ToUserName 开发者微信号
* FromUserName 发送方账号(一个OpenID)
* CreateTime 消息创建时间 (整型)
* MsgType 消息类型,event
* Event 事件类型,CLICK
* EventKey 事件KEY值,与自定义菜单接口中KEY值对应
* @param mapRequest
* @return
*/
private static BaseMessage dealClick(Map<String, String> mapRequest) {
String eventkey =mapRequest.get("EventKey");
switch (eventkey){
case "1":
break;
case "32":
break;
}
return null;
}
模版消息发送任务完成事件
/**
* 处理模版消息发送任务完成时的事件推送
* 在模版消息发送任务完成后,微信服务器会将是否送达成功作为通知,发送到开发者中心中填写的服务器配置地址中。
* 推送的XML如下:
* 1、送达成功时
* 2、送达由于用户拒收(用户设置拒绝接收公众号消息)而失败时
* 3、送达由于其他原因失败时
* <xml>
* <ToUserName><![CDATA[gh_7f083739789a]]></ToUserName>
* <FromUserName><![CDATA[oia2TjuEGTNoeX76QEjQNrcURxG8]]></FromUserName>
* <CreateTime>1395658920</CreateTime>
* <MsgType><![CDATA[event]]></MsgType>
* <Event><![CDATA[TEMPLATESENDJOBFINISH]]></Event>
* <MsgID>200163836</MsgID>
* <Status><![CDATA[success | failed:user block | failed: system failed]]></Status>
* </xml>
* 参数说明
* 参数 说明
* ToUserName 公众号微信号
* FromUserName 接收模板消息的用户的openid
* CreateTime 创建时间
* MsgType 消息类型是事件
* Event 事件为模板消息发送结束
* MsgID 消息id
* Status success:发送状态为成功, failed:user block:发送状态为用户拒绝接收, failed: system failed:发送状态为发送失败(非用户拒绝)
* @param mapRequest
* @return
*/
private static BaseMessage dealTemplateSendJobFinish(Map<String, String> mapRequest) {
String status =mapRequest.get("Status");
switch (status){
case "success":
break;
case "failed:user block":
break;
case "failed: system failed":
break;
}
return null;
}
下一篇《基础对接部分(4)》