有些時間沒折騰小程序了,話說年前小程序就發佈了消息,於1月10日會下線模板消息下發功能,全部的訂閱消息都要用戶手動觸發確認贊成,這可就太難了,以前的 wx.openSetting
、 wx.getPhoneNumber
、 wx.getUserInfo
等等API的調整,可把我折騰慘了,此次又來……javascript
難道直接js調用,不爽嗎?非要整手動確認,爽是確定的,但若是從一個用戶的角度出發,本身啥都沒幹,你就把我信息獲取了、每天給我推一堆垃圾信息,那確定不爽了,因此從這角度看,微信的調整也是爲了尊重用戶的隱私,畢竟用戶第一嘛css
今天主要是想分享一下,今天在處理這個訂閱消息邏輯時,遇到當用戶拒絕後,如何從新引導開啓 「訂閱消息」通知的問題,並在開啓後獲取到它的狀態html
若是你處理太小程序的訂閱消息,應該是知道的,在用戶拒絕或關閉消息總開關以後,咱們引導用戶手動開啓「訂閱消息」功能(也就是openSetting
API的調用回調裏,是拿不到scope.subscribeMessage
狀態的),開始我也糾結了好久,百度、google都用上了,一樣發現不少的同窗也有遇到這樣的問題,而都沒有找到解決方案,最後在我快要放棄的時候卻忽然靈光一閃,想到了個辦法,因此抖膽BB幾句,分析一下:前端
舒適提示:書讀的少,卻又喜歡瞎BB幾句,內容僅爲我的解決方案的思路,僅供參考,不足之處請見諒,勿噴,謝謝~
首先來看下調用的示例:java
wx.requestSubscribeMessage({ tmplIds: ['模版id'], success (res) { } })
同時官方也說了,success
回調的模版對應有三種狀態:react
fail
也有對應的狀態碼,以下:
算法
本次要講的是errorCode 20004
與 reject
狀態時,typescript
根據以往經驗,若是拒絕了,咱們確定是使用直接使用 openSetting
,引導用戶進行手動開啓受權(),好比:編程
//以微信運動爲例 export default class Sign extends wepy.page { config = { navigationBarBackgroundColor: '#fff', navigationBarTitleText: '贏積分', }; components = { Toast: Toast, Modals: Modals }; methods = { }; data = { signHistory: [] }; getRunData() { wx.getWeRunData({ success: res => { ……處理運動步數邏輯 } }); } setAuth() { wx.getSetting({ success: res => { //第一步,檢測是否有受權 - 沒有受權 if (!res.authSetting['scope.werun']) { //第二步,開始受權,但這裏有一個坑點(騰訊的bug),以前受權過可是是拒絕,因此會進入失敗 wx.authorize({ scope: 'scope.werun', success: () => { this.getRunData(); }, fail: () => { //第三步,引導用戶,手動引導用戶點擊按鈕,去設置頁開啓,## Modals是自定義組件 this.$invoke('Modals', '__modalConfirm__', [ '檢測到您沒有打微信運動的權限,是否去設置?', 'openSetting', //第四步,進入設置頁的回調 - 成功 res => { let { authSetting } = res.detail; if (authSetting['scope.werun']) { this.getRunData(); } else { this.$invoke('Toast', '__warning__', [ `您沒有贊成受權微信運動,獲取步數失敗` ]); } }, //第五步,點擊取消按鈕的回調 () => { this.$invoke('Toast', '__warning__', [ `您已拒絕微信運動受權,沒法獲取步數` ]); } ]); } }); } else { //第六步,已經受權直接進入保存邏輯 // console.log("受權了") this.getRunData(); } } }); } }
上面代碼執行截圖以下:
小程序
上述代碼,this.$invoke('Modals'……)
部分爲自定義彈窗,即引用用戶肯定,去設置頁,
可是 在 openSetting
的回調裏,是沒有 scope.subscribeMessage
這一項的,下面是列出的scope 列表
官方清單(文檔地址):
//提交訂閱消息示例 export default class Sign extends wepy.page { config = { navigationBarBackgroundColor: '#fff', navigationBarTitleText: '贏積分', }; setClock(e) { let that = this; if (wx.requestSubscribeMessage) { wx.requestSubscribeMessage({ tmplIds: [pushReservationTmplIds], success(res) { if (res[pushReservationTmplIds] === 'accept') { //發起請求…… } else if (res[pushReservationTmplIds] === 'reject') { // 用戶歷史操做有設置了拒絕 or 關閉了訂閱消息的主(總)開關,致使沒法推送 that.guideOpenSubscribeMessage(); } else { wx.showToast({ title: '受權訂閱消息有誤', icon: 'none' }); } }, fail(res) { // 20004:用戶關閉了主開關 或在 消息通知 裏 「拒絕接收」操做,沒法進行訂閱,引導開啓 if (res.errCode == 20004) { console.log(res, 'fail:用戶關閉了主開關,沒法進行訂閱,引導開啓---'); } } }); } else { wx.showToast({ title: '請更新您微信版本,來獲取訂閱消息功能', icon: 'none' }); } } guideOpenSubscribeMessage() { //引導用戶,手動引導用戶去設置頁開啓, this.$invoke('Modals', '__modalConfirm__', [ '檢測到您沒有開啓訂閱消息的權限,是否去設置?', 'openSetting', res => { console.log('openSetting的回調數據:', res); //可是這個回調數據裏,並無 「訂閱消息」 相關 open/close 的狀態返回 }, //用戶點擊了取消按鈕 () => { // console.log("取消了") this.$invoke('Toast', '__warning__', [ `您已拒絕訂閱消息受權,沒法預定` ]); } ]); }
上圖爲 openSetting
的回調數據,而網上說回調裏不作任何處理,用戶是否有手動開啓,則讓提示讓他再手動點擊一次業務按鈕,若是有開啓,則回到最初的邏輯,訂閱消息成功,不然則又循環進入 openSetting
設置頁,俗稱「死纏爛打受權法」,這固然不失爲一種方法,但體驗不是最好,
對於追求完美的我來講,不能接受,繼續尋找更好的方案,把官方文檔來回看,終於發現了新大陸,——wx.getSetting
屬性 | 類型 | 說明 | 最低版本 |
---|---|---|---|
authSetting | AuthSetting | 用戶受權結果 | |
subscriptionsSetting | SubscriptionsSetting | 用戶訂閱消息設置,接口參數withSubscriptions值爲true時纔會返回 | 2.10.1 |
文檔有有這麼一個屬性:subscriptionsSetting
,感謝蒼天,終於讓我看到了訂閱消息
相關的東西,
//官方示例 wx.getSetting({ withSubscriptions: true, success (res) { console.log(res.authSetting) // res.authSetting = { // "scope.userInfo": true, // "scope.userLocation": true // } console.log(res.subscriptionsSetting) // res.subscriptionsSetting = { // mainSwitch: true, // 訂閱消息總開關 // itemSettings: { // 每一項開關 // SYS_MSG_TYPE_INTERACTIVE: 'accept', // 小遊戲系統訂閱消息 // SYS_MSG_TYPE_RANK: 'accept' // zun-LzcQyW-edafCVvzPkK4de2Rllr1fFpw2A_x0oXE: 'reject', // 普通一次性訂閱消息 // ke_OZC_66gZxALLcsuI7ilCJSP2OJ2vWo2ooUPpkWrw: 'ban', // } // } } })
在wx.getSetting
的回調裏,有一項 mainSwitch
,還有一項withSubscriptions: true
,最後回調裏還能一項 zun-LzcQyW-edafCVvzPkK4de2Rllr1fFpw2A_x0oXE: 'reject'
,到這裏,但它也只是在getSetting
方法裏啊,跟 openSetting
沒有扯上任何關係,怎麼辦?
其實道理很簡單,但人有時候就是這樣,思惟若是沒有轉換過來,你能夠就會一直槓在那個死衚衕裏出不來,
openSetting
回調裏取不到狀態,那麼咱們是否能夠在它的回調裏,再作一次 getSetting
的調用裏呢?,取getSetting
回調裏的狀態來判斷,剛纔用戶在設置頁的行爲操做,直接看示例吧:
//提交訂閱消息示例 const pushReservationTmplIds = 'PVC_DBcvvdtffd1fO0vdS8YpSe0c7Br3QW54'; export default class Sign extends wepy.page { config = { navigationBarBackgroundColor: '#fff', navigationBarTitleText: '贏積分', }; submitClock() { fetchJson({ type: 'POST', url: '/api/steps/clock', data: { }, success: res => { wx.showToast({ title: '預約成功', icon: 'success', duration: 2000 }); } }); } setClock(e) { let that = this; if (wx.requestSubscribeMessage) { wx.requestSubscribeMessage({ tmplIds: [pushReservationTmplIds], success(res) { if (res[pushReservationTmplIds] === 'accept') { that.submitClock(); } else if (res[pushReservationTmplIds] === 'reject') { // 用戶歷史操做有設置了拒絕 or 關閉了訂閱消息的主(總)開關,致使沒法推送 // console.log(res, '0 拒絕 or 關閉了訂閱消息的主(總)開關---'); that.guideOpenSubscribeMessage(); } else { wx.showToast({ title: '受權訂閱消息有誤', icon: 'none' }); } }, fail(res) { // 20004:用戶關閉了主開關,沒法進行訂閱,引導開啓 if (res.errCode == 20004) { // console.log(res, 'fail:用戶關閉了主開關,沒法進行訂閱,引導開啓---'); that.guideOpenSubscribeMessage(); } } }); } else { wx.showToast({ title: '請更新您微信版本,來獲取訂閱消息功能', icon: 'none' }); } } guidSubscribeMessageAuthAfter() { //引導用戶 開啓訂閱消息 以後,「openSetting」 接口暫時不會返回,用戶手動設置後的狀態,因此採用「getSetting」接口從新進行查詢 wx.getSetting({ withSubscriptions: true, success: res => { let { authSetting = {}, subscriptionsSetting: { mainSwitch = false, itemSettings = {} } = {} } = res; if ( (authSetting['scope.subscribeMessage'] || mainSwitch) && itemSettings[pushReservationTmplIds] === 'accept' ) { this.submitClock(); // console.log('用戶手動開啓贊成了,訂閱消息'); } else { this.$invoke('Toast', '__warning__', [ `您沒有贊成受權訂閱消息,預定領取失敗` ]); } } }); } guideOpenSubscribeMessage() { //引導用戶,手動引導用戶去設置頁開啓, this.$invoke('Modals', '__modalConfirm__', [ '檢測到您沒有開啓訂閱消息的權限,是否去設置?', 'openSetting', //用戶點擊了肯定按鈕,進入設置頁的回調 res => { console.log('openSetting的回調數據:', res); this.guidSubscribeMessageAuthAfter(); }, //用戶點擊了取消按鈕 () => { // console.log("取消了") this.$invoke('Toast', '__warning__', [ `您已拒絕訂閱消息受權,沒法預定領取` ]); } ]); } }
到這裏,wx.requestSubscribeMessage
的問題,也就獲得瞭解決,看到網上有貼子在噴requestSubscribeMessage
API的設計,好比:wx.requestSubscribeMessage的接口參數結構設計反人性,實習生設計的嗎?,其實我也想說這麼龐大的一個生態體系,更新方案就考慮的這麼不全面嗎?仍是說就是這麼反人類? getSetting
裏給requestSubscribeMessage
的相關狀態,openSetting
裏又壓根沒有,而後又把它的引導開啓邏輯UI也放在設置頁裏面,我就鬱悶了,
今天的分享,爲我我的的解決思路方案,若有不足之處,請指出,勿噴~謝謝!!
原文首發於: https://susouth.com