【小程序】使用模板消息发送消息给多个用户
【⼩程序】使⽤模板消息发送消息给多个⽤户
使⽤模板消息发送消息给多个⽤户
⼀、需求背景
  基于的通知渠道,⼩程序为开发者提供了可以⾼效触达⽤户的模板消息能⼒,在⽤户本⼈与⼩程序页⾯有交互⾏为后触发,通过聊天列表中的服务通知可快捷进⼊查看消息,点击查看详情还能跳转到下发消息的⼩程序的指定页⾯。
  ⼩程序允许下发模板消息的条件分为两类:⽀付或者提交表单。通过提交表单来下发模板消息的限制为“允许开发者向⽤户在7天内推送有限条数的模板消息(1次提交表单可下发1条,多次提交下条数独⽴,相互不影响)”。
  然⽽,⽤户1次触发7天内推送1条通知是明显不够⽤的。⽐如,签到功能利⽤模板消息的推送来提醒⽤户每天签到,只能在⽤户前⼀天签到的情况下,获取⼀次推送模板消息的机会,然后⽤于第⼆天向该⽤户发送签到提醒。但是很多情况下,⽤户在某⼀天忘记签到,系统便失去了提醒⽤户的权限,导致和⽤户断开了联系;再⽐如,系统想主动告知⽤户即将做某活动,然⽽由于⼩程序被动触发通知的限制,系统将⽆法主动推送消息。
⼆、如何突破模板消息的推送限制?
  为了突破模板消息的推送限制,实现7天内任性推送,只需收集到⾜够的推送码,即每次提交表单时获取到的formId。⼀个formId代表着开发者有向当前⽤户推送模板消息的⼀次权限。
三、实现
  1.收集推送码。获取多个表单id并保存,便于⼀次性发送给服务器
  // 收集推送码
  Page({
    formSubmit: funcition(e) {//form表单按钮点击调⽤该⽅法
      let formId = e.detail.formId; //获取表单formId
      llectFormIds(formId); //保存推送码
      let type = e.detail.pe; // 根据type执⾏点击事件奥运百米决赛
    },
    collectFormIds: function(formId) { //保存推送码
      let formIds = app.globalData.globalFormIds; // 获取全局推送码数组
      if (!formIds)
        formIds = [];
      let data = {
        formId: formId,
        expire: new Data().getTime() + 60480000 // 7天后的过期时间戳
      }
      formIds.push(data);
      app.globalData.globalFormIds = formIds;
      },
    })
  2.上传推送码。即将推送码发送给服务器然后保存起来(需要上传的数据:formId和openId)
    // 上报推送码
    Page({火炬之光2人物加点
      onLoad: funcition(e) {
      this.uploadFormIds(); //上传推送码
    },
    collectFormIds: function(formId) {
      var formIds = app.globalData.globalFormIds; // 获取全局推送码
      if (formIds.length) {
        formIds = JSON.stringify(formIds); // 转换成JSON字符串
        app.globalData.gloabalFomIds = ''; // 清空当前全局推送码
      }
      wx.request({ // 发送到服务器
        url: 'xxx',
        method: 'POST',
        data: {
          openId: 'openId',//openId为⼩程序的⽤户唯⼀标识,需⾃⾏获取
          formIds: formIds//表单id
        },
        success: function(res) {
          }
        });
      },
    })
  3.服务端-存储推送码(⾼频IO,采⽤Redis来存储推送码。将推送码保存到数据库实现持久化存储,由于formId有七天有效期,所以需要定时清理⽆效推送码)
    /**
    * 收集⽤户推送码
    *
    * @param openId  ⽤户的openid
    * @param formIds  ⽤户的formId
    */
    public void collect(String openId, List<FormTemplateVO> formTemplates) {
      redisTemplate.opsForList().rightPushAll(openId, formIds);
    }
  4.发送模板消息相关接⼝
  需要使⽤的接⼝:
  1>模板消息发送api:POST api.weixin.qq/cgi-bin/message/wxopen/template/send?access_token=ACCESS_TOKEN
  要想使⽤该接⼝发送模板消息,还需要获取
ACCESS_TOKEN 即接⼝调⽤凭证
2>
接⼝调⽤凭证
api:
GET api.weixin.qq/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET 获取接⼝调⽤凭证需要appid和secret
孝敬父母的小故事appid:⼩程序唯⼀标识
secret:⼩程序唯⼀凭证密钥
appid和secret获取⽅式请查看:
5.推送模板消息。发送消息给⽤户
templateId消息模板id:⾃⾏登录获取
以下两个⽅法只是部分代码,调⽤sendTemplateMessage⽅法即可发送消息
  /**
  * 发送模板消息
  *
  * @param accessToken 接⼝调⽤凭证
  * @param touser 接收者(⽤户)的 openid
  * @param templateId 所需下发的模板消息的id
  * @param page 点击模板卡⽚后的跳转页⾯,仅限本⼩程序内的页⾯。⽀持带参数,(⽰例index?foo=bar)。该字段不填则模板⽆跳转
  * @param formId 表单提交场景下,为 submit 事件带上的 formId;⽀付场景下,为本次⽀付的 prepay_id
  * @param data 模板内容,不填则下发空模板。具体格式请参考⽰例。
  * @param emphasisKeyword 模板需要放⼤的关键词,不填则默认⽆放⼤
  */
  public WxResSendTemplateMessage sendTemplateMessage(String accessToken, String touser, String templateId,
String page, String formId, Map<String, Object> data, String       emphasisKeyword) {
    /**
    * data⽰例:
    *
    * "data": {
先富带动后富    * "keyword1": { "value": title, "color": "#173177" },
    * "keyword2": { "value": gettime() }
    * }
    * emphasisKeyword⽰例:
    * "emphasis_keyword": "keyword1.DATA"
    *
草莓酱的做法
    */
    /** 结果 */
    String result = "";
    /** 获取输出流 */
    OutputStreamWriter os = null;
    /** 获取输⼊流 */
    BufferedReader in = null;
    /** 请求地址 */
    String urlPath = "api.weixin.qq/cgi-bin/message/wxopen/template/send?access_token=" + accessToken;
    /** 需要传递的数据 */
    Map<String, Object> messageData = new HashMap<>();气质高冷名字女
    messageData.put("touser", touser);//接收者(⽤户)的 openid
    messageData.put("template_id", templateId);//所需下发的模板消息的id
    messageData.put("page", page);//点击模板卡⽚后的跳转页⾯,仅限本⼩程序内的页⾯。⽀持带参数,(⽰例index?
foo=bar)。该字段不填则模板⽆跳转
    messageData.put("form_id", formId);//表单提交场景下,为 submit 事件带上的 formId;⽀付场景下,为本次⽀付的
prepay_id
    messageData.put("data", data);//模板内容,不填则下发空模板。具体格式请参考⽰例。
    messageData.put("emphasis_keyword", emphasisKeyword);//模板需要放⼤的关键词,不填则默认⽆放⼤
    try {
      /** 获得url对象 */
      URL url = new URL(urlPath);
      /** 打开连接 */
      HttpURLConnection conn = (HttpURLConnection) url.openConnection();
      /** 设置通⽤的请求属性 */
      conn.setRequestProperty("accept", "*/*");
      conn.setRequestProperty("connection", "Keep-Alive");
      conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
      conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
      /** 设置请求⽅式 */
      conn.setRequestMethod(Http.HttpMethod.POST.name());
      /** 设置允许读写出数据,默认可以读不可写 */
      conn.setDoOutput(true);
      conn.setDoInput(true);
      /** 获取输出流 */
      os = new OutputStream(), "UTF-8");
      /** 发送请求参数 */
      os.JsonString(messageData));
      /** 输出缓存流 */
      os.flush();
      /** 获取输⼊流 */
      in = new BufferedReader(new InputStream()));
      /** 接收⾏数据 */
      String line;
      /** 读取数据 */
      while((line = in.readLine()) != null) {
        result += line;
      }
    } catch(Exception e) {
      e.printStackTrace();
    } finally {/** 释放输⼊输出流并关闭 */
    try {
      if(os != null) {
        os.close();
      }
      if(in != null) {
        in.close();
      }
     } catch (Exception e) {
       e.printStackTrace();
     }
    }
    (">>>模板消息发送>>>result={}>>>", result);
    return (WxResSendTemplateMessage) JsonMapper.fromJsonString(result, WxResSendTemplateMessage.class);  }

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。