小程序模板消息
有时候我们需要从服务端推送一些消息到用户的手机上,比如在用户购买完以后,我们发个消息告诉他购买成功,商家会尽快发货。如下图所示。
有几个需要注意的:
1.小程序的模板消息是发送到微信的服务通知里面的,而不像公众号的模板消息,是直接依附于公众号的。
2.小程序的消息模板需要下发条件,确切的说,需要是在提交表单完以后得到formid,或者在调起支付后得到prepayId。一个formid可以下发一条消息,一个prepayId可以下发三条消息。而微信公众号的模板消息不需要下发条件。
在小程序中加入模板消息很简单,只需要经过如下几步,现在我们以微信支付成功后的模板消息为例来介绍实现方法。
一.申请消息模板
直接在小程序后台--》模板消息---》添加。就可以选用想要的模板了,还可以在模板里自定义参数。很是方便。以下是我选定交易成功的模板。
二.获取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进行发货通知。