小程序模板消息

时间:2024-02-23 12:17:03

转载注明出处:www.xdxxdxxdx.com,或者加入java学习群学习讨论:481845043

有时候我们需要从服务端推送一些消息到用户的手机上,比如在用户购买完以后,我们发个消息告诉他购买成功,商家会尽快发货。如下图所示。

QQ截图20181115135615.jpg

    有几个需要注意的:

    1.小程序的模板消息是发送到微信的服务通知里面的,而不像公众号的模板消息,是直接依附于公众号的。

    2.小程序的消息模板需要下发条件,确切的说,需要是在提交表单完以后得到formid,或者在调起支付后得到prepayId。一个formid可以下发一条消息,一个prepayId可以下发三条消息。而微信公众号的模板消息不需要下发条件。

    在小程序中加入模板消息很简单,只需要经过如下几步,现在我们以微信支付成功后的模板消息为例来介绍实现方法。

一.申请消息模板

    直接在小程序后台--》模板消息---》添加。就可以选用想要的模板了,还可以在模板里自定义参数。很是方便。以下是我选定交易成功的模板。

QQ截图20181115142000.jpg

二.获取formId或者prepayId

    第二步就是获取prepayId,或者如果你是在提交表单以后想要发送模板消息,则需要获取formId。

    要获取formId,首先要在form元素添加report-submit=true属性,如下所示。

<form bindsubmit="submitInfo" report-submit=\'true\' ></form>

    然后在form表单提交事件中获取到formId,如下所示。

submitInfo: function (e) {
  console.log(\'GG 敌方军团已同意投降 4票赞成 0票反对\')
  console.log(e.detail.formId);
},

    至于获取prepayId,需要涉及到微信支付接口,会有专门文章来介绍,这边就不再赘述了。

三.调用sendTemplateMessage接口下发消息

    1.首先,我们写一个模块类,让各页面来调用,主要就是调用服务端发送模板消息的方法。

    模块类:templateMethod.js

const app = getApp();
const templateId = {
  tradeTplId: \'UNgCJILBU6UIkrUEwoxyJDpN_SffcEhrfXlBlcsF0ww\',
}
 
const template = function (name) {
  return templateId[name];
}
 
const send = function (SESSION, templateId, xcxOpenId, emphasisKeyword, page, prepayId, msgData, color) {
  const _this = this;
  wx.request({
    method: \'POST\',
    url: app.domain + app.api.xcxTempleSendReq,
    header: {
      \'content-type\': app.globalData.postHeader,
      \'Cookie\'\'JSESSIONID=\' + SESSION + \';SESSION=\' + SESSION
    },
    data: {
      page: page,
      templateId: templateId,
      xcxOpenId: xcxOpenId,
      emphasisKeyword: emphasisKeyword,
      prepayId: prepayId,
      msgData: msgData,
      color: color
    },
    success: function (res) {
      console.log(res);
    },
    fail: function (res) {
      console.log(res)
    }
  })
}
 
module.exports = {
  send: send,
  template: template
}

    其实就是将sendTemplateMessage接口需要的各参数传递给服务端,让服务端去调用sendTemplateMessage接口。其中xcxTempleSendReq所对应的服务端代码如下。

    public String xcxTempleSend() {
        HttpServletRequest req = ServletActionContext.getRequest();
        String openId = req.getParameter("xcxOpenId");
        String templateId = req.getParameter("templateId");
        String page = req.getParameter("page");
        String sceneID = req.getParameter("prepayId");
        String msgData = req.getParameter("msgData");
        String color = req.getParameter("color");
        String emphasisKeyword = req.getParameter("emphasisKeyword");
        String result = wxService.xcxSendTemplate(openId, templateId, page,
                sceneID, msgData, color, emphasisKeyword);
        OutPutMsg.outPutMsg(result.toString());
        return null;
    }

xcxSendTemplate的代码如下:

public String xcxSendTemplate(String openId, String templateId,
            String page, String sceneID, String msgData, String color,
            String emphasisKeyword) {
        System.err.println("发送订单消息模板");
        String access_token = "";
        if (redisDao.get("xcx_access_token") != null) {
            access_token = redisDao.get("xcx_access_token");
        else {
            String tokenStr = CommonUtil
                    .getTokenByUrl(ConfigUtil.XCX_TOKEN_URL);
            JSONObject tokeJson = JSONObject.fromObject(tokenStr);
            access_token = tokeJson.getString("access_token");
        }
        String template = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token="
                + access_token + "&type=wx_card";
        Map<String, String> pmMap = new HashMap<String, String>();
        pmMap.put("touser", openId);
        pmMap.put("template_id", templateId);
        pmMap.put("page", page);
        System.err.println(page);
        pmMap.put("form_id", sceneID);
        pmMap.put("data""msgData");
        pmMap.put("emphasis_keyword", emphasisKeyword);
        pmMap.put("color", color);
        String pmStr = JSON.toJSONString(pmMap).replaceAll("\"msgData\"",
                msgData);
        String sendResult = CommonUtil.httpsRequest(template, "POST", pmStr);
        System.err.println(sendResult);
        return sendResult;
    }

    我们这边的策略是从redis中去获取小程序的access_token。然后组装各参数,最后调用sendTemplateMessage接口以发送消息。

    最后再看看页面如何调用模块类的方法来发送消息的吧。

    首先,引入模块类

const templateMethod = require(app.resource.util.templateMethod);

    然后,封装好参数,直接调用templateMethod 暴露出来的send方法,如下:

 templateMethod.send(_this.data.userInfo.SESSION, templateMethod.template(\'tradeTplId\'), _this.data.userInfo.wechatUser.xcxOpenId, \'keyword3.DATA\', pageUrl, payJson.package.split(\'=\')[1], _this.generateMsgData(), \'\');

其中templateMethod.template(\'tradeTplId\')同样是调用templateMethod 的template方法获取该交易成功模板的模板Id.emphasisKeyword 表示的是强调突出的参数,这边是keyword3.DATA,也就是第三个参数,表示支付金额。这个参数将会被放大放在显眼位置,如文章刚开始的图片所示。pageUrl是用户点击该模板消息通知需要跳转的页面。这边我们传递的参数是用户订单列表页。payJson.package.split(\'=\')[1]是获取到了prepayId,_this.generateMsgData()是组装模板内容的方法。其具体的实现如下。

  generateMsgData: function () {
    const _this = this;
    const tips = \'本次支付采用微信支付方式并在小程序《逸品生活NNWN》上进行支付-点击打开小程序,查看订单!\';
    const note = \'仅作通知提醒使用,不成为支付或报销之依据!\';
    const msgData = {};
    msgData.keyword1 = {
      value: _this.data.orderIdArray.join(\'、\'),
      color: \'#173177\'
    }
    msgData.keyword2 = {
      value: _this.data.subject,
      color: \'#173177\'
    }
    msgData.keyword3 = {
      value: _this.data.total,
      color: \'#173177\'
    }
    msgData.keyword4 = {
      value: tips,
      color: \'#173177\'
    }
    msgData.keyword5 = {
      value: note,
      color: \'#173177\'
    }
 
    return JSON.stringify(msgData)
  }

    自此,整个模板消息发送的要点都讲完了。

    PS:

    1.本文讲的方法对很多地方做了一些封装,所以看起来感觉很麻烦。比如采用redis存储access_token;在小程序端封装templateMethod模块方法,给其他页面调用;还有就是封装generateMsgData()方法来组装模板内容。读者只需要知道大概的流程就可以,至于如何去传参,是在客户端封装参数还是在服务端封装参数,可以自行决定。

    2.获取到prepayId后,我们可将其存储起来,跟客户或者订单相关联,当订单发货的时候,再次使用这个prepayId进行发货通知。