1 简介

  小程序的订阅消息分为两种:一次性订阅和永久订阅。

  一次性订阅:订阅一次,可发送一次消息。一次调用最多可订阅3个不同订阅消息。

  永久订阅:用户订阅一次后,开发者可长期下发多条消息。目前长期性订阅消息仅向政务民生、医疗、交通、金融、教育等线下公共服务开放。

  我们小程序只能申请一次性订阅。

 

2 微信公众平台开通订阅消息功能并选用模板

1)登录微信公众平台

2)找到订阅消息,开通

  image

 3) 申请模板

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

  image

 4) 我的模板

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

  image

 

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 订阅消息弹窗效果

  3bcadea77ddeaab3f6eb0ade70825a76

 

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

  模板的参数,对照在微信公众平台申请的模板填入

   image

 

3)效果

  image