首頁 > 搜索 > 微信公眾號群發模板消息

微信公眾號群發模板消息

互聯網 2020-09-23 23:37:55

擼了今年阿里、頭條和美團的面試,我有一個重要發現.......>>> hot3.png

1. 需求

最近在做一款拼課類小程序,大概需求就是分享課程頁面給好友,好友參與達到一定數量后則拼課成功。

好友參與後會給分享者發送一條模板消息 參與人數滿足后(拼課成功)會給分享者發送一條模板消息 管理後台可以群發模板消息(給所有用戶發消息)

按理說很平常的需求,微信公眾號裡邊應該很容易實現,但是想在小程序裡邊實現這麼個功能卻有點蛋疼了。

2. 分析

為什麼小程序實現起來比較費勁呢,那就要說下小程序發送模板消息的機制了,先看文檔怎麼說:

划重點,本人、交互,也就是說這個模板消息,必須由用戶手動來觸發,你想後台定時給用戶推個消息,洗洗睡吧你。 再來看下面:

這個重點你們自己划吧,發模板消息必須滿足這兩種情況中的一種,支付就不說了,用戶付款后可以推送幾條消息,重點是這個表單提交。 意思就是我想給用戶發個模板消息,第一要搞個表單,第二要讓用戶來提交這個表單(獲取formId),而且這個模板消息還只能發給提交表單的用戶本人,你想發給別的用戶,呵呵。

 

獻給我們偉大的TX

 

3. 原理

好了,說多了都是氣,既然這樣設計,也是有一定道理,但是道理都是講給守規矩的人聽的,至於不守規矩的,喂!說的就是你。 通過上面的分析我們知道,想發送一個基本的模板消息需要以下步驟:

構建一個form表單 設置表單的report-submit屬性為true(用來獲取formId發送模板消息) 用戶提交表單,把openid和formId一塊提交給後台(其實真正開發中一般不會提交openid,因為在用戶登錄或者訪問小程序時候通常會把openid和當前用戶在資料庫中做個同步) 後台調用POST https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=ACCESS_TOKEN來發送模板消息

模板消息介面 POST https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=ACCESS_TOKEN有這麼幾個參數 :

 

其中touser(openid)和form_id是重點,這兩個參數的結合是用來確認和效驗模板接收者的,因為用戶提交表單微信會生成一個專屬的formId,這個formId標識著用戶的一個操作。所以可以這樣來理解,要想發送一個模板消息給特定用戶,那麼必須要有該用戶的有效formId(7天內有效)和openid,一旦我們有了用戶大量的formId,你說我發個模板消息那還不跟玩的一樣。

 

所以問題就來了

1. 我如何來收集用戶的formId? 這個還沒有什麼特別有效的辦法,因為微信不會給提供相關api,而且只有提交表單才能得到formId,所以只能讓用戶去主動的觸發表單來生成formId,我們要做的就是修改原有的頁面,把頁面上高強度的交互都用form和button組件來替換,只是在外層套一個form組件而已,裡邊用button來觸發操作(記得修改樣式),比如:

 

像這些交互元素都可以外層套上form組件,用戶點擊后觸發表單提交事件,得到formId,我們把formId和用戶openid發送給後台特定介面,後台要做的就是把formId和openid存儲下來,至於存資料庫、文件、緩存、redis都行,主要是要把openid和formId關係對應好,而且每個formId都有一個過期時間。我是用laravel的redis緩存來存儲,畢竟這塊是一個高頻的io操作。具體實現方式在後面。

 

2. 搞了一堆用戶的formId后,我該怎麼來用呢? 其實這個問題是多餘的,就像給你了一個女朋友,你卻不知道該幹啥一樣。當然是上... 前面已經說的很清楚了,想要給目標用戶發模板消息需要formId和openid,當後台有一個發送模板消息事件被觸發時,只需要獲取目標用戶的openid(這個你們自己資料庫肯定有對應的啦),然後根據openid從資料庫(或其他存儲引擎)拉取一個有效的formId,請求POST https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=ACCESS_TOKEN即可,完事了,記得刪掉這個formId奧。

4. 實現

前面扯了一堆概念,下面我們來把這個功能具體的實現一遍吧,我這裡後台用的是php laravel,原理都一樣。

小程序端業務

我這隻寫一個例子,一看就明白

// wxml// reprt-submit屬性記得寫上這裡邊才是我們正常的界面代碼 // js// 這塊都可以封裝的,畢竟很多交互的地方都需要clickFormView(event) {let formId = event.detail.formId;// 忽略開發者工具裡邊的formIdif (formId && formId !== 'the formId is a mock one') {wx.request({method: 'POST',url: '/api/collectFormId', // 該介面只用來收集formIddata: { formId: formId } // 只傳了一個formId,因為openid和當前用戶通常會事先在後台做一個關聯,看具體業務了});}// 然後可以干其他事了,比如跳轉頁面,其他業務邏輯 // TODO}

有些時候用戶操作頻繁,可能會導致伺服器收到大量請求,所以可以優化下,把formId先存到一個全局變數裡邊(數組),當達到一定數量后統一發給後台來保存。這塊可以靈活運用。

服務端實現

服務端的實現也就兩個功能,收集和發送。 假設我們現在有這麼一個類FormIdCollection,可以收集(save)和獲取(get)某個openid的formId,那我們給前台暴露的api只需要簡單的調用下就可以了,至於發消息,也只需要get一個formId,即可。

// 實例化一個對象// $openid為目標用戶openid// $config是一個數組,微信小程序相關配置[app_id, secret]$collection = new FormIdCollection($openid, $config);// 收集一個formId$collecton->save($formId);//獲取一個可用formId$collection->get();// 發送模板消息// $data為模板消息相關參數 template_id等$collecton->send($data);

下面是FormIdCollection類的一個具體實現,基於laravel(說實話,挺好用的),另外引入了一個微信開發包overtrue/wechat(這裡主要是用來發模板消息、有點大材小用了),https://www.easywechat.com/

免責聲明:非本網註明原創的信息,皆為程序自動獲取互聯網,目的在於傳遞更多信息,並不代表本網贊同其觀點和對其真實性負責;如此頁面有侵犯到您的權益,請給站長發送郵件,並提供相關證明(版權證明、身份證正反面、侵權鏈接),站長將在收到郵件12小時內刪除。