上一篇 小程序發送模板消息的幾種實現主要介紹了實現評論通知功能最重要的一環,這篇文章主要介紹實現該功能的具體實戰。
思路其實很簡單,簡單畫了個流程圖以下:前端
這裏有兩個比較坑的地方,一個是微信自己發送模板消息的限制:git
當用戶在小程序內發生過提交表單行爲且該表單聲明爲要發模板消息的,開發者須要向用戶提供服務時,可容許開發者向用戶在7天內推送有限條數的模板消息(1次提交表單可下發1條,屢次提交下發條數獨立,相互不影響)
另一個就是管理員如何初始化本身的formId的問題,並且自身的formId需求量比較大,讀者評論完以後就要向管理員推送消息。github
因此無奈,增長了一個後臺配置的功能,按期手動觸發去生成本身的FormId「自動不行,只能手動,淚奔中」數據庫
另外補充下,網上說的經過嵌套穿透的方式無限獲取formId的方式已經行不通了,生成出來的formId都是同樣的。小程序
首先咱們須要收集用戶的FormId
,有FormId才能發送對應的模板消息,在表單標籤上加上report-submit
屬性便可。api
<form catchsubmit="formSubmit" report-submit="true">
這樣咱們在提交評論表單的時候會獲取到對應的FormId
, 咱們將這個FormId保存至咱們的雲函數中。微信
//評論提交按鈕部分代碼 console.info(e.detail.formId) if (e.detail != undefined && e.detail.formId != undefined) { var data = { formId: e.detail.formId, author: 0, timestamp: new Date().getTime() } wxApi.insertFormIds(data).then(res => { console.info(res) }) } //調用雲數據庫 function insertFormIds(data) { return db.collection('openid_formids').add({ data: data }) }
這樣管理員在接收到評論以後回覆時就能夠到openid_formids
的集合中找到對應的formId來進行評論回覆的模板消息推送了。async
爲了讓管理員能有更多的FormId
來接收評論通知,所以我在小程序中搭建了個生成FormId的小頁面。函數
這樣偶爾登陸本身的小程序,查看下本身FormId的使用狀況,若沒有了能夠手動生成幾個。優化
固然,這裏會有一個權限問題,理論上這個頁面只有管理員才能夠展現,而其餘人是沒有權限訪問的,所以須要提供個驗證權限的雲函數。
這裏可使用雲函數的環境變量來簡單作個驗證,將你的管理員的openId配置在環境變量中,雲函數驗證下openId是否一致便可。
雲函數代碼以下,這樣代碼中不會存放敏感信息,開源的代碼上傳github
也不會泄露。
/** * 驗證 * @param {} event */ async function checkAuthor(event) { if (event.userInfo.openId == process.env.author) { return true; } return false; }
最後就是發送模板消息的實現了,方法在上一篇說的比較具體了,基於個人博客小程序,使用雲調用是最方便的。
主要邏輯是根據傳入的openId(若是爲空默認取管理員的openId)到雲數據庫中取對應的formId。
而後基於openId和formId發送相應的模板消息,發送後從雲數據庫中移除「發送一次後FormId就已經失效了」
具體代碼實現以下:
/** * 發送通知消息 * @param event */ async function sendTemplateMessage(event) { var touser = ""; var form_id = ""; var openId = event.tOpenId == "" ? process.env.author : event.tOpenId //1.獲取formId var openIdformIds = await db.collection('openid_formids').where({ _openid: openId }).limit(1).get() if (openIdformIds.code) { return; } if (!openIdformIds.data.length) { return; } touser = openIdformIds.data[0]['_openid'] form_id = openIdformIds.data[0]['formId'] //2.取到後從雲數據庫中移除 const removeResult = await db.collection('openid_formids').doc(openIdformIds.data[0]['_id']).remove() console.info(event.nickName + ":" + event.message) //3.發送模板消息 const sendResult = await cloud.openapi.templateMessage.send({ touser: touser, templateId: template, formId: form_id, page: 'pages/detail/detail?blogId=' + event.blogId, data: { keyword1: { value: event.nickName // keyword1 的值 }, keyword2: { value: event.message // keyword2 的值 } }, }) return sendResult }
到這裏,具體實現流程就介紹完了,過程當中仍是會遇到些編碼問題「主要仍是對前端不是很熟悉,基本功問題」
雖然功能基本實現,也已經上線了,但其實仍是有一些細節問題的。
好比通知消息點進去以後應該自動轉到對應的評論區域,formId過時須要定時清理,管理員FormId須要通知管理員等,能夠利用小程序的定時觸發器等功能慢慢優化,後期優化後再來寫文章總結。