1 简介
小程序的订阅消息分为两种:一次性订阅和永久订阅。
一次性订阅:订阅一次,可发送一次消息。一次调用最多可订阅3个不同订阅消息。
永久订阅:用户订阅一次后,开发者可长期下发多条消息。目前长期性订阅消息仅向政务民生、医疗、交通、金融、教育等线下公共服务开放。
我们小程序只能申请一次性订阅。
2 微信公众平台开通订阅消息功能并选用模板
1)登录微信公众平台
2)找到订阅消息,开通

3) 申请模板
开通订阅消息功能后,在公共模板库找到需要的模板,选用

4) 我的模板
选用好模板后,在我的慕白就可以看到了

3 小程序端开发
3.1 简介
在小程序端调起订阅消息界面。订阅消息界面,需要在小程序端客户点击或者支付的时候才可以调用
3.2 官方api文档
3.3 调用
在点击或者支付完成的时候,进行调用
下面是一次调用三个模板(一次最多就三个,对于手机系统的版本也有要求,具体看api文档)
ids就是模板id,在刚才申请好的我的模板处复制过来即可。
subscribeMessage () {
var ids = ['xJJaxOXJK6f4mwsECrxgtJbBDFV4tb1WBPyXMJ8UGUw','pT7V6Fbjk-bnIZZraaMTLJsCjLlj9XItGu1QpHk3fAA','IRpjhA858GkWsXdQM1axRLYbRmbOPQ6HOVGu8e3P-oI']
wx.requestSubscribeMessage({
tmplIds: ids,
success(res) {
var acceptIds = []
console.log('subscribeMessage success');
console.log(res);
ids.forEach((item, index) => {
if (res[item] === 'accept') {
acceptIds.push(item)
}
});
if(acceptIds.length > 0){
// 发送请求到后端
}
},
fail(res) {
console.log('subscribeMessage fail');
console.log(res);
}
});
},
返回值
{
"xJJaxOXJK6f4mwsECrxgtJbBDFV4tb1WBPyXMJ8UGUw": "accept",
"errMsg": "requestSubscribeMessage:ok",
"pT7V6Fbjk-bnIZZraaMTLJsCjLlj9XItGu1QpHk3fAA": "accept",
"IRpjhA858GkWsXdQM1axRLYbRmbOPQ6HOVGu8e3P-oI": "accept"
}
accept表示该模板被订阅
3.4 订阅消息弹窗效果

3.5 注意事项
一次性订阅消息,客户统一一次,只能给客户发送一次消息,且有效期是7天
4 服务端发送订阅消息
4.1 官方api文档
4.2 请求参数实体类
public class TemplateDataVo {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public TemplateDataVo() {
}
public TemplateDataVo(String value) {
this.value = value;
}
}
public class WxMssVo {
private String template_id;//模版id
private String page = "pages/index/index";//默认跳到小程序首页
private String touser;//用户openid
private Map<String, TemplateDataVo> data; // 模板参数
private String miniprogram_state; // 跳转小程序类型: developer为开发版;trial为体验版;formal为正式版;默认为正式版
private String lang; // 进入小程序查看”的语言类型,支持zh_CN(简体中文)、en_US(英文)、zh_HK(繁体中文)、zh_TW(繁体中文),默认为zh_CN
public String getMiniprogram_state() {
return miniprogram_state;
}
public void setMiniprogram_state(String miniprogram_state) {
this.miniprogram_state = miniprogram_state;
}
public String getLang() {
return lang;
}
public void setLang(String lang) {
this.lang = lang;
}
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, TemplateDataVo> getData() {
return data;
}
public void setData(Map<String, TemplateDataVo> data) {
this.data = data;
}
public WxMssVo(String touser, String template_id, String page, Map<String, TemplateDataVo> data) {
this.touser = touser;
this.template_id = template_id;
this.page = page;
this.data = data;
}
public WxMssVo() {
}
}
4.3 工具类
public class SendSubMesUtils {
private static RestTemplate restTemplate;
public static final String GYAPP_ID = "xxx";
public static final String GYAPP_SECRET = "yyy";
// 发送消息
public static AjaxResult pushOneUser(String access_token, WxMssVo wxMssVo) throws IntrospectionException, InvocationTargetException, IllegalAccessException {
//如果access_token为空则从新获取
if (StringUtils.isEmpty(access_token)) {
access_token = getAccess_token(GYAPP_ID,GYAPP_SECRET);
}
String url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send" +
"?access_token=" + access_token;
if(restTemplate==null){
restTemplate = new RestTemplate();
}
ResponseEntity<String> responseEntity =
restTemplate.postForEntity(url, wxMssVo, String.class);
String body = responseEntity.getBody();
Map<String, Object> stringObjectMap = MyJsonUtil.String_to_Map(body);
String errcode = MyMapUtils.getString(stringObjectMap, "errcode");
if("0".equals(errcode)){
return AjaxResult.success();
}else{
return AjaxResult.error(errcode);
}
}
/*
* 获取access_token
* appid和appsecret到小程序后台获取,当然也可以让小程序开发人员给你传过来
* */
public static String getAccess_token(String appid,String appsecret) {
String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential" +
"&appid=" + appid + "&secret=" + appsecret;
if (restTemplate == null) {
restTemplate = new RestTemplate();
}
String json = restTemplate.getForObject(url, String.class);
JSONObject myJson = JSONObject.parseObject(json);
return myJson.get("access_token").toString();
}
4.4 测试发送
public static void main(String[] args) throws IntrospectionException, InvocationTargetException, IllegalAccessException {
String dcc_openid = "ok8W55Z38TcO6orXmHNi5PawwNQ8";
String my_openid = "ok8W55c0RK8qXhqHDgE_quOWE7Cg";
//拼接推送的模版
WxMssVo wxMssVo = new WxMssVo();
wxMssVo.setMiniprogram_state("formal");
wxMssVo.setLang("zh_CN");
wxMssVo.setTouser(my_openid);//用户openid
wxMssVo.setTemplate_id("pT7V6Fbjk-bnIZZraaMTLJsCjLlj9XItGu1QpHk3fAA");//模版id
wxMssVo.setPage("pages/paymanage/page/shiftrecordTap/index"); // 跳转页面
Map<String, TemplateDataVo> m = new HashMap<>();
wxMssVo.setData(m);
m.put("thing3", new TemplateDataVo("用车申请"));
m.put("phrase1", new TemplateDataVo("审核通过"));
m.put("time10", new TemplateDataVo("2019-10-01 15:01"));
m.put("thing12", new TemplateDataVo("jcc"));
m.put("character_string11", new TemplateDataVo("1"));
/*String a = pushOneUser(getAccess_token(GYAPP_ID, GYAPP_SECRET)
,wxMssVo );
System.out.println(a);*/
}
1)参数page
点击消息需要跳转到的页面路径
如需要需要传参数,只需要在page后面接上即可。
如传递参数state=1:"pages/bark/index?state=1"
小程序页面端可在onload(options)函数获取:options.state
2)data
模板的参数,对照在微信公众平台申请的模板填入

3)效果
