實戰分享:小程序雲開發玩轉訂閱消息

微信官方為提升小程序模板消息能力的使用體驗,對模板消息的下發條件進行了調整。原有的小程序模板消息接口於 2020 年 1 月 10 日下線,屆時將無法使用舊的小程序模板消息接口發送模板消息,取而代之的是新的一次性訂閱消息和長期訂閱消息。

訂閱消息給小程序開發者帶來了更好的觸達用戶的能力,在具體實施過程中,開發者如何把模板消息換成新的訂閱消息,是否需要購買服務器來實現服務器鑑權,怎樣才能在用戶訂閱之後一段時間後,給用戶發送長期或一次性訂閱消息呢?

小程序·雲開發最近支持了通過雲調用免 access_token 發送訂閱消息,還新增支持了在定時觸發器中實現雲調用,這些能力可以幫助開發者輕鬆玩轉小程序訂閱消息。

我們今天會利用小程序·雲開發進行一個小程序中實現訂閱開課提醒的實戰,幫助大家瞭解如何基於小程序·雲開發快速接入小程序訂閱消息。

實戰分享:小程序雲開發玩轉訂閱消息

整體時序圖

實戰分享:小程序雲開發玩轉訂閱消息

環境準備

  • https://tencentcloudbase.github.io/2019-09-03-wx-dev-guide-register/
  • https://tencentcloudbase.github.io/2019-09-03-wx-dev-guide-service/

獲取訂閱消息模板 ID

在微信小程序管理後臺中,新增一個訂閱消息的模板,這裡我們新增了一個開課提醒的模板。

實戰分享:小程序雲開發玩轉訂閱消息

引導用戶訂閱

微信小程序提供了wx.requestSubscribeMessage 接口來發起申請訂閱權限界面。

實戰分享:小程序雲開發玩轉訂閱消息

在 "訂閱開課提醒" 的按鈕上綁定 tap 事件,事件處理器我們這裡用的 onSubscribe

index.wxml

<button> class="btn"
data-item="{{ item }}"
bindtap="onSubscribe"
hover-class="btn-hover"

>
訂閱開課提醒
/<button>

在 onSubscribe 函數內,我們會調用微信 API wx.requestSubscribeMessage 申請發送訂閱消息權限,當用戶在彈窗同意訂閱之後,我們會收到 success 回調,將訂閱的課程信息調用雲函數 subscribe 存入雲開發數據庫,雲函數 subscribe 的實現在下文會講。

index.js

onSubscribe: function(e) {
// 獲取課程信息
const item = e.currentTarget.dataset.item;
// 調用微信 API 申請發送訂閱消息
wx.requestSubscribeMessage({
// 傳入訂閱消息的模板id,模板 id 可在小程序管理後臺申請
tmplIds: [lessonTmplId],
success(res) {
// 申請訂閱成功
if (res.errMsg === 'requestSubscribeMessage:ok') {
// 這裡將訂閱的課程信息調用雲函數存入雲開發數據
wx.cloud
.callFunction({
name: 'subscribe',
data: {
data: item,
templateId: lessonTmplId,
},
})
.then(() => {
wx.showToast({
title: '訂閱成功',
icon: 'success',
duration: 2000,

});
})
.catch(() => {
wx.showToast({
title: '訂閱失敗',
icon: 'success',
duration: 2000,
});
});
}
},
});
},

將訂閱消息存入雲開發數據庫

接下來我們創建一個雲函數 subscribe ,這個雲函數的作用是將用戶的訂閱信息存入雲開發數據庫的集合 messages 中,等待將來需要通知用戶時進行調用。

在微信開發者工具的雲開發面板中創建數據庫集合 messages

實戰分享:小程序雲開發玩轉訂閱消息

創建一個 subscribe 雲函數,在雲函數中我們將小程序端發送過來的課程訂閱信息,存儲在雲開發數據庫集合中,開發完成後,在微信開發者工具中右鍵上傳並部署雲函數。

cloudfunctions/subscribe/index.js

const cloud = require('wx-server-sdk');
cloud.init();
const db = cloud.database();
exports.main = async (event, context) => {
try {
const {OPENID} = cloud.getWXContext();
// 在雲開發數據庫中存儲用戶訂閱的課程
const result = await db.collection('messages').add({
data: {
touser: OPENID, // 訂閱者的openid
page: 'index', // 訂閱消息卡片點擊後會打開小程序的哪個頁面
data: event.data, // 訂閱消息的數據
templateId: event.templateId, // 訂閱消息模板ID
done: false, // 消息發送狀態設置為 false
},
});
return result;
} catch (err) {
console.log(err);
return err;
}
};

利用定時觸發器來定期發送訂閱消息

接下來我們需要實現一個定時執行的雲函數send,來檢查數據庫中是否有需要發送給用戶的訂閱消息。如果有需要發送的訂閱消息,會通過雲調用 cloud.openapi.subscribeMessage.send 將訂閱消息發送給用戶。

創建一個名叫 send 的雲函數,首先要配置雲函數,在 config.json 的 permissions 中新增 subscribeMessage.send的雲調用權限,然後新增一個 sendMessagerTimer 的定時觸發器,定時觸發器的語法和 linux 的 crontab 類似,比如,我們配置的 "0 * * * * * *" 代表每分鐘執行一次雲函數。

cloudfunctions/send/config.json

{
"permissions": {
"openapi": ["subscribeMessage.send"]
},
"triggers": [
{
"name": "sendMessagerTimer",
"type": "timer",
"config": "0 * * * * * *"
}
]
}

接下來是實現發送訂閱消息的雲函數,這個雲函數會從雲開發數據庫集合messages中查詢等待發送的消息列表,檢查數據庫中是否有需要發送給用戶的訂閱消息,發送條件可以根據自己的業務實現,比如開課提醒可以根據課程開課日期來檢查是否需要發送訂閱消息,在我們下面的代碼示例裡做了簡化,篩選條件只檢查了狀態為未發送。

查詢到待發送的消息列表之後,我們會循環消息列表,依次發送每條訂閱消息,發送成功後將數據庫中消息的狀態改為已發送。

cloudfunctions/send/index.js

const cloud = require('wx-server-sdk');
exports.main = async (event, context) => {
cloud.init();
const db = cloud.database();
try {
// 從雲開發數據庫中查詢等待發送的消息列表
const messages = await db
.collection('messages')
// 查詢條件這裡做了簡化,只查找了狀態為未發送的消息
// 在真正的生產環境,可以根據開課日期等條件篩選應該發送哪些消息
.where({
done: false,
})
.get();
// 循環消息列表
const sendPromises = messages.data.map(async message => {
try {
// 發送訂閱消息
await cloud.openapi.subscribeMessage.send({
touser: message.touser,
page: message.page,
data: message.data,
templateId: message.templateId,
});
// 發送成功後將消息的狀態改為已發送
return db
.collection('messages')
.doc(message._id)
.update({
data: {
done: true,
},
});
} catch (e) {
return e;

}
});
return Promise.all(sendPromises);
} catch (err) {
console.log(err);
return err;
}
};

最終效果

實戰分享:小程序雲開發玩轉訂閱消息

源代碼

https://github.com/binggg/tcb-subscribe-demo

關於我

 binggg(Booker Zhao) @騰訊 

- 先後就職於迅雷、騰訊等,個人開源項目有 mrn.js 等
- 創辦了迅雷內部組件倉庫 XNPM ,參與幾個迅雷前端開源項目的開發
- 熱衷於優化和提效,是一個奉行“懶惰使人進步”的懶人工程師

社交資料

  • GitHub: https://github.com/binggg
  • 簡書: https://www.jianshu.com/u/60f22559b79f
  • 掘金: https://juejin.im/user/58d31f130ce4630057edb3ba
  • ️‍️ 微博: https://weibo.com/being99
  • 思否: https://segmentfault.com/u/binggg
  • 博客園: https://www.cnblogs.com/binggg/
  • 開源中國: https://my.oschina.net/u/4217267
  • 極術社區: https://aijishu.com/u/binggg
  • 今日頭條: https://www.toutiao.com/c/user/102306299647
  • CSDN: https://blog.csdn.net/weixin_42541867


分享到:


相關文章: