小程序訂閱消息用戶拒絕/關閉後,如何引導用戶再開啓?並得到用戶的操做呢?

前言

有些時間沒折騰小程序了,話說年前小程序就發佈了消息,於1月10日會下線模板消息下發功能,全部的訂閱消息都要用戶手動觸發確認贊成,這可就太難了,以前的 wx.openSettingwx.getPhoneNumberwx.getUserInfo等等API的調整,可把我折騰慘了,此次又來……javascript

難道直接js調用,不爽嗎?非要整手動確認,爽是確定的,但若是從一個用戶的角度出發,本身啥都沒幹,你就把我信息獲取了、每天給我推一堆垃圾信息,那確定不爽了,因此從這角度看,微信的調整也是爲了尊重用戶的隱私,畢竟用戶第一嘛css

今天主要是想分享一下,今天在處理這個訂閱消息邏輯時,遇到當用戶拒絕後,如何從新引導開啓 「訂閱消息」通知的問題,並在開啓後獲取到它的狀態html

若是你處理太小程序的訂閱消息,應該是知道的,在用戶拒絕或關閉消息總開關以後,咱們引導用戶手動開啓「訂閱消息」功能(也就是openSettingAPI的調用回調裏,是拿不到scope.subscribeMessage狀態的),開始我也糾結了好久,百度、google都用上了,一樣發現不少的同窗也有遇到這樣的問題,而都沒有找到解決方案,最後在我快要放棄的時候卻忽然靈光一閃,想到了個辦法,因此抖膽BB幾句,分析一下:前端

舒適提示:書讀的少,卻又喜歡瞎BB幾句,內容僅爲我的解決方案的思路,僅供參考,不足之處請見諒,勿噴,謝謝~

受權API示例

首先來看下調用的示例:java

wx.requestSubscribeMessage({
  tmplIds: ['模版id'],
  success (res) {

  }
})

同時官方也說了,success 回調的模版對應有三種狀態:react

  1. accept = 贊成
  2. reject = 拒絕
  3. ban = 後臺封禁

fail 也有對應的狀態碼,以下:
image.png算法

本次要講的是errorCode 20004reject狀態時,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'……)部分爲自定義彈窗,即引用用戶肯定,去設置頁,

requestSubscribeMessage 問題點

可是 在 openSetting的回調裏,是沒有 scope.subscribeMessage這一項的,下面是列出的scope 列表官方清單(文檔地址):

image.png

//提交訂閱消息示例


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的問題,也就獲得瞭解決,看到網上有貼子在噴requestSubscribeMessageAPI的設計,好比:wx.requestSubscribeMessage的接口參數結構設計反人性,實習生設計的嗎?,其實我也想說這麼龐大的一個生態體系,更新方案就考慮的這麼不全面嗎?仍是說就是這麼反人類? getSetting裏給requestSubscribeMessage的相關狀態,openSetting裏又壓根沒有,而後又把它的引導開啓邏輯UI也放在設置頁裏面,我就鬱悶了,

今天的分享,爲我我的的解決思路方案,若有不足之處,請指出,勿噴~謝謝!!

推薦閱讀:

原文首發於: https://susouth.com
相關文章
相關標籤/搜索