小程序模板網(wǎng)

小程序訂閱消息用戶拒絕/關(guān)閉后,如何引導(dǎo)用戶再開啟?并獲得用戶的操作呢

發(fā)布時(shí)間:2020-05-21 09:33 所屬欄目:小程序開發(fā)教程

前言

有些時(shí)間沒(méi)折騰小程序了,話說(shuō)年前小程序就發(fā)布了消息,于1月10日會(huì)下線模板消息下發(fā)功能,所有的訂閱消息都要用戶手動(dòng)觸發(fā)確認(rèn)同意,這可就太難了,之前的 wx.openSetting 、 wx.getPhoneNumber 、 wx.getUserInfo 等等API的調(diào)整,可把我折騰慘了,這次又來(lái)……

難道直接js調(diào)用,不爽嗎?非要整手動(dòng)確認(rèn),爽是肯定的,但如果從一個(gè)用戶的角度出發(fā),自己啥都沒(méi)干,你就把我信息獲取了、天天給我推一堆垃圾信息,那肯定不爽了,所以從這角度看,微信的調(diào)整也是為了尊重用戶的隱私,畢竟用戶第一嘛

今天主要是想分享一下,今天在處理這個(gè)訂閱消息邏輯時(shí),遇到當(dāng) 用戶拒絕 后,如何重新引導(dǎo)開啟 「訂閱消息」通知的問(wèn)題,并在 開啟后獲取到它的狀態(tài)

如果你處理過(guò)小程序的訂閱消息,應(yīng)該是知道的,在用戶拒絕或關(guān)閉消息總開關(guān)之后,我們引導(dǎo)用戶手動(dòng)開啟「訂閱消息」功能(也就是 openSetting API的調(diào)用回調(diào)里,是拿不到 scope.subscribeMessage 狀態(tài)的),開始我也糾結(jié)了很久,百度、google都用上了,同樣發(fā)現(xiàn)很多的同學(xué)也有遇到這樣的問(wèn)題,而都沒(méi)有找到解決方案,最后在我快要放棄的時(shí)候卻突然靈光一閃,想到了個(gè)辦法,所以抖膽B(tài)B幾句,分析一下:

溫馨提示:書讀的少,卻又喜歡瞎BB幾句,內(nèi)容僅為個(gè)人解決方案的思路,僅供參考,不足之處請(qǐng)見諒,勿噴,謝謝~

授權(quán)API示例

首先來(lái)看下調(diào)用的示例:

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

  }
})

同時(shí)官方也說(shuō)了, success 回調(diào)的模版對(duì)應(yīng)有三種狀態(tài):

  1. accept = 同意
  2. reject = 拒絕
  3. ban = 后臺(tái)封禁

fail 也有對(duì)應(yīng)的狀態(tài)碼,如下:

本次要講的是 errorCode 20004 與 reject 狀態(tài)時(shí),

根據(jù)以往經(jīng)驗(yàn),如果拒絕了,我們肯定是使用直接使用 openSetting ,引導(dǎo)用戶進(jìn)行手動(dòng)開啟授權(quán)(),比如:

//以微信運(yùn)動(dòng)為例
export default class Sign extends wepy.page {
  config = {
    navigationBarBackgroundColor: '#fff',
    navigationBarTitleText: '贏積分',
  };
  components = {
    Toast: Toast,
    Modals: Modals
  };
  methods = {
  };
  data = {
    signHistory: []
  };
  getRunData() {
    wx.getWeRunData({
      success: res => {
        ……處理運(yùn)動(dòng)步數(shù)邏輯
      }
    });
  }
  setAuth() {
    wx.getSetting({
      success: res => {
        //第一步,檢測(cè)是否有授權(quán) - 沒(méi)有授權(quán)
        if (!res.authSetting['scope.werun']) {
          //第二步,開始授權(quán),但這里有一個(gè)坑點(diǎn)(騰訊的bug),之前授權(quán)過(guò)但是是拒絕,所以會(huì)進(jìn)入失敗
          wx.authorize({
            scope: 'scope.werun',
            success: () => {
              this.getRunData();
            },
            fail: () => {
              //第三步,引導(dǎo)用戶,手動(dòng)引導(dǎo)用戶點(diǎn)擊按鈕,去設(shè)置頁(yè)開啟,## Modals是自定義組件
              this.$invoke('Modals', '__modalConfirm__', [
                '檢測(cè)到您沒(méi)有打微信運(yùn)動(dòng)的權(quán)限,是否去設(shè)置?',
                'openSetting',
                //第四步,進(jìn)入設(shè)置頁(yè)的回調(diào) - 成功
                res => {
                  let { authSetting } = res.detail;
                  if (authSetting['scope.werun']) {
                    this.getRunData();
                  } else {
                    this.$invoke('Toast', '__warning__', [
                      `您沒(méi)有同意授權(quán)微信運(yùn)動(dòng),獲取步數(shù)失敗`
                    ]);
                  }
                },
                //第五步,點(diǎn)擊取消按鈕的回調(diào)
                () => {
                  this.$invoke('Toast', '__warning__', [
                    `您已拒絕微信運(yùn)動(dòng)授權(quán),無(wú)法獲取步數(shù)`
                  ]);
                }
              ]);
            }
          });
        } else {
          //第六步,已經(jīng)授權(quán)直接進(jìn)入保存邏輯
          // console.log("授權(quán)了")
          this.getRunData();
        }
      }
    });
  }
}

上面代碼執(zhí)行截圖如下:

上述代碼, this.$invoke('Modals'……) 部分為自定義彈窗,即引用用戶確定,去設(shè)置頁(yè),

requestSubscribeMessage 問(wèn)題點(diǎn)

但是 在 openSetting 的回調(diào)里,是沒(méi)有 scope.subscribeMessage 這一項(xiàng)的,下面是列出的 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') {
            //發(fā)起請(qǐng)求……
          } else if (res[pushReservationTmplIds] === 'reject') {
            // 用戶歷史操作有設(shè)置了拒絕 or 關(guān)閉了訂閱消息的主(總)開關(guān),導(dǎo)致無(wú)法推送
            that.guideOpenSubscribeMessage();
          } else {
            wx.showToast({
              title: '授權(quán)訂閱消息有誤',
              icon: 'none'
            });
          }
        },
        fail(res) {

          // 20004:用戶關(guān)閉了主開關(guān) 或在 消息通知 里 “拒絕接收”操作,無(wú)法進(jìn)行訂閱,引導(dǎo)開啟
          if (res.errCode == 20004) {
            console.log(res, 'fail:用戶關(guān)閉了主開關(guān),無(wú)法進(jìn)行訂閱,引導(dǎo)開啟---');
          }
        }
      });
    } else {
      wx.showToast({
        title: '請(qǐng)更新您微信版本,來(lái)獲取訂閱消息功能',
        icon: 'none'
      });
    }
  }
  guideOpenSubscribeMessage() {
    //引導(dǎo)用戶,手動(dòng)引導(dǎo)用戶去設(shè)置頁(yè)開啟,
    this.$invoke('Modals', '__modalConfirm__', [
      '檢測(cè)到您沒(méi)有開啟訂閱消息的權(quán)限,是否去設(shè)置?',
      'openSetting',
      res => {
        console.log('openSetting的回調(diào)數(shù)據(jù):', res);
        //但是這個(gè)回調(diào)數(shù)據(jù)里,并沒(méi)有 「訂閱消息」 相關(guān) open/close 的狀態(tài)返回

      },
      //用戶點(diǎn)擊了取消按鈕
      () => {
        // console.log("取消了")
        this.$invoke('Toast', '__warning__', [
          `您已拒絕訂閱消息授權(quán),無(wú)法預(yù)約`
        ]);
      }
    ]);
}

上圖為 openSetting 的回調(diào)數(shù)據(jù),而網(wǎng)上說(shuō)回調(diào)里不做任何處理,用戶是否有手動(dòng)開啟,則讓提示讓他再手動(dòng)點(diǎn)擊一次業(yè)務(wù)按鈕,如果有開啟,則回到最初的邏輯,訂閱消息成功,否則則又循環(huán)進(jìn)入 openSetting 設(shè)置頁(yè),俗稱“死纏爛打授權(quán)法”,這當(dāng)然不失為一種方法,但體驗(yàn)不是最好,

對(duì)于追求完美的我來(lái)說(shuō),不能接受,繼續(xù)尋找更好的方案,把官方文檔來(lái)回看,終于發(fā)現(xiàn)了新大陸,—— wx.getSetting

文檔有有這么一個(gè)屬性: subscriptionsSetting ,感謝蒼天,終于讓我看到了 訂閱消息 相關(guān)的東西,

//官方示例
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, // 訂閱消息總開關(guān)
    //   itemSettings: {   // 每一項(xiàng)開關(guān)
    //     SYS_MSG_TYPE_INTERACTIVE: 'accept', // 小游戲系統(tǒng)訂閱消息
    //     SYS_MSG_TYPE_RANK: 'accept'
    //     zun-LzcQyW-edafCVvzPkK4de2Rllr1fFpw2A_x0oXE: 'reject', // 普通一次性訂閱消息
    //     ke_OZC_66gZxALLcsuI7ilCJSP2OJ2vWo2ooUPpkWrw: 'ban',
    //   }
    // }
  }
})

在 wx.getSetting 的回調(diào)里,有一項(xiàng) mainSwitch ,還有一項(xiàng) withSubscriptions: true ,最后回調(diào)里還能一項(xiàng) zun-LzcQyW-edafCVvzPkK4de2Rllr1fFpw2A_x0oXE: 'reject' ,到這里,但它也只是在 getSetting 方法里啊,跟 openSetting 沒(méi)有扯上任何關(guān)系,怎么辦?

其實(shí)道理很簡(jiǎn)單,但人有時(shí)候就是這樣,思維如果沒(méi)有轉(zhuǎn)換過(guò)來(lái),你可以就會(huì)一直杠在那個(gè)死胡同里出不來(lái),

openSetting 回調(diào)里取不到狀態(tài), 那么我們是否可以在它的回調(diào)里,再做一次 getSetting 的調(diào)用里呢? ,取 getSetting 回調(diào)里的狀態(tài)來(lái)判斷,剛才用戶在設(shè)置頁(yè)的行為操作,直接看示例吧:

//提交訂閱消息示例

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: '預(yù)定成功',
          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') {
            // 用戶歷史操作有設(shè)置了拒絕 or 關(guān)閉了訂閱消息的主(總)開關(guān),導(dǎo)致無(wú)法推送
            // console.log(res, '0 拒絕 or 關(guān)閉了訂閱消息的主(總)開關(guān)---');
            that.guideOpenSubscribeMessage();
          } else {
            wx.showToast({
              title: '授權(quán)訂閱消息有誤',
              icon: 'none'
            });
          }
        },
        fail(res) {
          // 20004:用戶關(guān)閉了主開關(guān),無(wú)法進(jìn)行訂閱,引導(dǎo)開啟
          if (res.errCode == 20004) {
            // console.log(res, 'fail:用戶關(guān)閉了主開關(guān),無(wú)法進(jìn)行訂閱,引導(dǎo)開啟---');
            that.guideOpenSubscribeMessage();
          }
        }
      });
    } else {
      wx.showToast({
        title: '請(qǐng)更新您微信版本,來(lái)獲取訂閱消息功能',
        icon: 'none'
      });
    }
  }
  guidSubscribeMessageAuthAfter() {
    //引導(dǎo)用戶 開啟訂閱消息 之后,「openSetting」 接口暫時(shí)不會(huì)返回,用戶手動(dòng)設(shè)置后的狀態(tài),所以采用「getSetting」接口重新進(jìn)行查詢
    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('用戶手動(dòng)開啟同意了,訂閱消息');
        } else {
          this.$invoke('Toast', '__warning__', [
            `您沒(méi)有同意授權(quán)訂閱消息,預(yù)約領(lǐng)取失敗`
          ]);
        }
      }
    });
  }
  guideOpenSubscribeMessage() {
    //引導(dǎo)用戶,手動(dòng)引導(dǎo)用戶去設(shè)置頁(yè)開啟,
    this.$invoke('Modals', '__modalConfirm__', [
      '檢測(cè)到您沒(méi)有開啟訂閱消息的權(quán)限,是否去設(shè)置?',
      'openSetting',
      //用戶點(diǎn)擊了確定按鈕,進(jìn)入設(shè)置頁(yè)的回調(diào)
      res => {
        console.log('openSetting的回調(diào)數(shù)據(jù):', res);
        this.guidSubscribeMessageAuthAfter();
      },
      //用戶點(diǎn)擊了取消按鈕
      () => {
        // console.log("取消了")
        this.$invoke('Toast', '__warning__', [
          `您已拒絕訂閱消息授權(quán),無(wú)法預(yù)約領(lǐng)取`
        ]);
      }
    ]);
  }
}

結(jié)尾

到這里, wx.requestSubscribeMessage 的問(wèn)題,也就得到了解決,看到網(wǎng)上有貼子在噴 requestSubscribeMessage API的設(shè)計(jì),比如: wx.requestSubscribeMessage的接口參數(shù)結(jié)構(gòu)設(shè)計(jì)反人性,實(shí)習(xí)生設(shè)計(jì)的嗎? ,其實(shí)我也想說(shuō)這么龐大的一個(gè)生態(tài)體系,更新方案就考慮的這么不全面嗎?還是說(shuō)就是這么反人類? getSetting 里給 requestSubscribeMessage 的相關(guān)狀態(tài), openSetting 里又壓根沒(méi)有,然后又把它的引導(dǎo)開啟邏輯UI也放在設(shè)置頁(yè)里面,我就郁悶了,

今天的分享,為我個(gè)人的解決思路方案,如有不足之處,請(qǐng)指出,勿噴~謝謝?。?/p>


易優(yōu)小程序(企業(yè)版)+靈活api+前后代碼開源 碼云倉(cāng)庫(kù):starfork
本文地址:http://22321a.com/wxmini/doc/course/25240.html 復(fù)制鏈接 如需定制請(qǐng)聯(lián)系易優(yōu)客服咨詢:800182392 點(diǎn)擊咨詢
QQ在線咨詢