你知道如何在小程序中推送模板消息?

前段时间剁手了 PS4,在浏览商店时,发现官方商店真的很差用,主要是网络缘由,次要是页面设计。因此就想本身作一个游戏查询的小程序,能够关注某个游戏,而后在这个游戏打折的时候发送通知给用户。最后发现有个很大的问题是:小程序无法直接给用户推送消息(当时还不知道模板消息),服务号才能。而后就用邮箱实现了通知功能,可是邮箱的局限实在是太大了(各大免费邮箱天天的发件数都很小,本身搭建的邮件服务器虽然没有发件限制,可是大几率会被放到垃圾箱)。javascript

而后某天在微信小程序的管理后台发现了模板消息这个东西,查了会资料发现能够经过这个来实现消息推送。要给用户发送模板消息须要formId/prepay_id这样一个东西,这个东西是怎么来的呢?html

  • formId:这个能够经过表单的提交来获取,须要在
    组件中设置属性 report-submit="true",这样每次对这个表单的提交一次就会产生一个 formId.
  • prepay_id:这个是支付动做产生的,具体的我也不太清楚,毕竟我的小程序并不能支付.

下面具体来说讲先后台的实现,前台使用 mpvue,后台使用 javavue

前台获取 formId

既然能够经过 form 的 submit 操做来获取到 formId,那咱们稍微拓展一下,将咱们的小程序页面中全部用户能点击的部分都用 form,button 来包裹一下,这样用户感知不到有表单提交操做,咱们也能获取大量的 formId。java

注意不能用叠加的方式来一次点击获取多个 formId,这样方法已经不行了,获取到的都会是同样的。git

获取一个模板

要发送模板消息,首先要在小程序的管理后台上添加模板,步骤以下:github

1.在模板库中选择一个模板数据库

选择模板

2.选择显示参数npm

选择要显示在消息中的参数,这里选择以下两个参数:json

选择参数

这样就有了一个模板能够用来发消息了,在个人模板中能够看到模板 id,和字段 id小程序

模板id

获取 formId

formId 是经过表单提交来获取到了,为了获取足够多的 formId,能够将可以点击的组件(好比按钮,列表单元..)包裹在 form 中,这样用户在平常使用中就可以收集到足够多的 formId。下面以包裹一个有赞的按钮为例。由于小程序的限制,设置form-type属性的按钮必须为 form 组件的直接子节点,因此并不可以在 form 中使用自定义组件,并将form-type='submit'设置到自定义组件中。

template 部分以下:

<!-- 要获取formId,须要给form设置report-submit="true"的属性,而后在form-type="submit"的按钮上产生点击动做,才会触发表单提交的事件--formSubmit,进而获取到formId -->
<form @submit="formSubmit" report-submit="true" class="bottom">
  <button style="border:0;display:inline-block" plain="true" form-type="submit" @click="back">
    <van-button round type="primary" size="small" @click="back">返回</van-button>
  </button>
  <button style="border:0;display:inline-block" plain="true" form-type="submit" @click="watchGame">
    <van-button round type="danger" size="small">{{watchText}}</van-button>
  </button>
  <button style="border:0;display:inline-block" plain="true" form-type="submit" open-type="share">
    <van-button round type="info" size="small">分享</van-button>
  </button>
</form>
复制代码

style 目的为了去除原生 button 的背景,边框啥的,把 button 当一个 div 来使用,而后在 button 中设置 form-type 和 click 属性,这样既不影响 formId 的属性,也对原有逻辑不产生任何影响。之因此将 click 放在 button 上是由于 button 内部的组件无法获取到点击事件。

formSubmit 代码以下:

formSubmit(e) {
  let item = {
    value: e.mp.detail.formId,
    expireTime: Date.now() + 7 * 24 * 60 * 60 * 1000
  };
  this.globalData.formIdList.push(item);
},
复制代码

该函数是在表单提交时触发,用于获取 formId,将 formId 和这个 formId 的过时时间一块儿存到 globalData 全局数据中。而后找一个时机将这些 formId 发送给服务器保存起来就好了。

这里放上个人作法以供参考。

我是在每次发送 http 请求前检查是否是有 formId 须要发送到服务器,若是有就将这些数据 JSON 序列化后放到一个自定义 header 中,发送出去,具体代码以下(http 请求工具为:flyio):

var Fly = require("flyio/dist/npm/wx");
var fly = new Fly();
//在请求预处理中
fly.interceptors.request.use(request => {
  request.headers["jwt-token"] = wxUtil.getGlobalData("jwt-token");
  //若是有formId就放到header里送过去
  let formIdList = getApp().globalData.formIdList;
  if (formIdList.length > 0) {
    request.headers["formIdList"] = JSON.stringify(formIdList);
    getApp().globalData.formIdList = [];
  }
  if (request.method == "GET") {
    request.params["_t"] = new Date().getTime();
  }
  return request;
});
复制代码

下面将后台的实现,基于 Spring Boot.

后台处理

搜集 formId

首先须要把 formId 收集起来存到数据库,那么就须要检查每一个请求,看 header 中有没有携带 formId,若是有就存到数据库中,注意要和用户对应起来,某个用户点击产生的 formId 只能用于给这个用户推送消息。

由于要将 formId 和用户绑定起来,所以我是在身份认证过滤器中进行的 formId 处理,身份认证成功后,处理 formId。代码以下:

/** * Description: 从请求头中获取formIdList,并插入数据库 * * @param request 请求头 * @return void * @author fanxb * @date 2019/5/6 16:39 */
private void checkFormId(HttpServletRequest request) {
    String str = request.getHeader(Constant.HEADER_FORM_ID);
    if (StringUtil.isEmpty(str)) {
        return;
    }
    List<FormKey> formKeyList = JSON.parseArray(str, FormKey.class);
    //UserContextHolder用户将当前线程和用户绑定起来,方便后面获取用户信息
    int userId = UserContextHolder.get().getUser().getUserId();
    formKeyList.forEach(item -> item.setUserId(userId));
    this.formKeyDao.insertMany(formKeyList);
}
复制代码

发送微信提醒

经过官方文档能够知道发送消息的流程以下:

1 获取 accessToken,调用微信的大多数接口都须要这个东西,这个经过 appId 和 secret 来获取。详情参见:developers.weixin.qq.com/miniprogram…

2 调用微信发送服务通知的接口.这个接口文档在:点击跳转

最终发送的 http 请求是这样的:

url: https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=上面获取的accessToken
method: post

请求体格式为:application/json; charset=utf-8

body:{
  "touser": "用户的openId",
  "template_id": "模板id",
  "page": "点击跳转的小程序url路径",
  "form_id": "收集到的formId",
  "data": {
    "keyword1": {
      "value": "您有一个信息的提示消息"
    },
    "keyword2": {
      "value": "这是消息内容"
    }
  },
  "emphasis_keyword": "keyword1.DATA"
}
复制代码

data 中的数据的按照顺序 keyword1,keyword2 对应于模板中字段的顺序。

结束

工程所有源码在这里:github

PS 这就是那个小程序,欢迎批评指正。

小程序

本文原创发布于:www.tapme.top/blog/detail…

扫码关注微信公众号:FleyX 学习笔记,获取更多干货

相关文章
相关标签/搜索