1、订阅消息包括两种
一次性订阅消息
一次性订阅消息用于解决用户使用小程序后,后续服务环节的通知问题。用户自主订阅后,开发者可不限时间地下发一条对应的服务消息;每条消息可单独订阅或退订。
长期订阅消息
一次性订阅消息可满足小程序的大部分服务场景需求,但线下公共服务领域存在一次性订阅无法满足的场景,如航班延误,需根据航班实时动态来多次发送消息提醒。为便于服务,我们提供了长期性订阅消息,用户订阅一次后,开发者可长期下发多条消息。
目前长期性订阅消息仅向政务民生、医疗、交通、金融、教育等线下公共服务开放,后期将逐步支持到其他线下公共服务业务。
2、小程序订阅流程
- 获得用户openID
- 获取access_token
- 消息模板推送
- 获得用户openId
要在微信小程序调用登录开放接口 wx.login() 获取用户登陆凭证code。
GET https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code
2.获取access_token
/** * 获得AccessToken * @return */ @Override public String getAccessToken() { Map<String, String> params = new HashMap<>(); /** * 参数appid,appsecret */ params.put(BimsConstsPark.MINI_PROGRAM_APP_ID, appId); params.put(BimsConstsPark.MINI_PROGRAM_APP_SECRET, appSecret); /** * 先去访问缓存中的access_Token 如果未过期 则不需要去重新获取,过期则需要重新拿 */ String accessValue = redisTemplate.opsForValue().get(BimsConstsPark.MINI_PROGRAM_ACCESS_TOKEN +appId); if(StringUtils.isNotBlank(accessValue)){ return accessValue; } /** * 微信接口获得access_Token */ ResponseEntity<String> responseEntity = restTemplate.getForEntity( "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={APPID}&secret={APPSECRET}", String.class, params); String body = responseEntity.getBody(); /** * 返回json解析 */ JSONObject object = JSON.parseObject(body); //Access_Token String access_Token = object.getString("access_token"); //过期时间 String expires_in = object.getString("expires_in"); //将其存在Redis中 System.out.println("有效时长expires_in:" + expires_in); try { /** * 将拿到的access_Token存入缓存,设置过期时间,如果过期需要重新获取 */ redisTemplate.opsForValue().set(BimsConstsPark.MINI_PROGRAM_ACCESS_TOKEN + appId, access_Token,Long.valueOf(expires_in==null?"0":expires_in), TimeUnit.SECONDS); }catch (Exception e){ return ""; } return access_Token; }
3.模板推送
/** * 小程序通知推送 * @return */ @Override public String pushMsg() { String openid = "oVNCx4tMJHNd5PXEqAfrj0Xz2ezY"; RestTemplate restTemplate = new RestTemplate(); //这里简单起见我们每次都获取最新的access_token(时间开发中,应该在access_token快过期时再重新获取) String url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + getAccessToken(); //拼接推送的模版 WxMssVo wxMssVo = new WxMssVo(); //用户的openid(要发送给那个用户,通常这里应该动态传进来的) wxMssVo.setTouser(openid); //订阅消息模板id wxMssVo.setTemplate_id("AGr87hXpZQHhgGIrmIGLt5tqtzt8yx64kkTJNnN9Uwg"); //消息打开跳转页面 // wxMssVo.setPage(toPage); Map<String, TemplateData> m = new HashMap<>(3); m.put("thing1", new TemplateData("我要举报小明贪污")); m.put("name2", new TemplateData("小红")); m.put("date3", new TemplateData(DateUtil.now())); wxMssVo.setData(m); ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, wxMssVo, String.class); return responseEntity.getBody(); }
通用实体及参数定义
参数定义
yml文件: wx: #小程序appId miniAppId: ***** #小程序AppSecret miniAppSecret: ****** #小程序中定义的模板Id miniTemplateId: ******* #消息打开跳转的地址 miniPage: pages/msg/msg 实体中定义: @Value("${wx.miniAppId}") private String appId; @Value("${wx.miniAppSecret}") private String appSecret; @Value("${wx.miniPage}") private String toPage; @Value("${wx.miniTemplateId}") private String templateId;
通用实体:
WxMssVo: package com.fpi.bims.model.vo.push; import java.util.Map; /** * @program bims-core-master * @description: 小程序推送 * @author: zhengzhang_shan * @create: 2020/12/24 11:05 */ public class WxMssVo { /** * 用户openid */ private String touser; /** * 订阅消息模版id */ private String template_id; /** * 默认跳到小程序首页 */ private String page = "pages/index/index"; /** * 推送文字 */ private Map<String, TemplateData> data; public String getTouser() { return touser; } public void setTouser(String touser) { this.touser = touser; } public String getTemplate_id() { return template_id; } public void setTemplate_id(String template_id) { this.template_id = template_id; } public String getPage() { return page; } public void setPage(String page) { this.page = page; } public Map<String, TemplateData> getData() { return data; } public void setData(Map<String, TemplateData> data) { this.data = data; } } TemplateData: package com.fpi.bims.model.vo.push; /** * @program bims-core-master * @description: 推送数据 * @author: zhengzhang_shan * @create: 2020/12/24 11:06 */ public class TemplateData { private String value; public TemplateData(String value) { this.value = value; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } }
3、创建自己的模板
- 进入小程序公共平台,开通订阅消息,选择通用模板。(官方提供了一些通用的模板),没有合适的可以自己申请
- 模板确定后可以在我的模板中看见自己选择模板信息,需要用到模板id
- 详情可查看需要推送的格式