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

前段時間剁手了 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 學習筆記,獲取更多幹貨

相關文章
相關標籤/搜索