最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501
当前位置: 首页 - 科技 - 知识百科 - 正文

在小程序中推送模板消息的实现方法

来源:懂视网 责编:小采 时间:2020-11-27 21:53:33
文档

在小程序中推送模板消息的实现方法

在小程序中推送模板消息的实现方法:前段时间剁手了 PS4,在浏览商店时,发现官方商店真的不好用,主要是网络原因,次要是页面设计。所以就想自己做一个游戏查询的小程序,可以关注某个游戏,然后在这个游戏打折的时候发送通知给用户。最后发现有个很大的问题是:小程序没法直接给用户推送消息(
推荐度:
导读在小程序中推送模板消息的实现方法:前段时间剁手了 PS4,在浏览商店时,发现官方商店真的不好用,主要是网络原因,次要是页面设计。所以就想自己做一个游戏查询的小程序,可以关注某个游戏,然后在这个游戏打折的时候发送通知给用户。最后发现有个很大的问题是:小程序没法直接给用户推送消息(

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

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

  • formId:这个可以通过表单的提交来获取,需要在组件中设置属性 report-submit="true" ,这样每次对这个表单的提交一次就会产生一个 formId.
  • prepay_id:这个是支付动作产生的,具体的我也不太清楚,毕竟个人小程序并不能支付.
  • 下面具体来讲讲前后台的实现,前台使用 mpvue,后台使用 java

    前台获取 formId

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

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

    获取一个模板

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

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

    2.选择显示参数

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

    这样就有了一个模板可以用来发消息了,在我的模板中可以看到模板 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 来获取。详情参见: https://developers.weixin.qq.com/miniprogram/dev/api-backend/auth.getAccessToken.html

    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

    总结

    以上所述是小编给大家介绍的在小程序中推送模板消息的实现方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!
    如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

    声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

    文档

    在小程序中推送模板消息的实现方法

    在小程序中推送模板消息的实现方法:前段时间剁手了 PS4,在浏览商店时,发现官方商店真的不好用,主要是网络原因,次要是页面设计。所以就想自己做一个游戏查询的小程序,可以关注某个游戏,然后在这个游戏打折的时候发送通知给用户。最后发现有个很大的问题是:小程序没法直接给用户推送消息(
    推荐度:
    标签: 消息 小程序 推送
    • 热门焦点

    最新推荐

    猜你喜欢

    热门推荐

    专题
    Top