小程序 · 订阅消息

1、获取模板 ID
在微信公众平台手动配置获取模板 ID:
登录 获取模板,
一次性订阅:如果没有合适的模板,可以申请添加新模板,审核通过后可使用。
永久订阅:不可以对模版进行修改
在这里插入图片描述

2、获取下发权限
详见小程序端消息订阅接口 wx.requestSubscribeMessage

一次性订阅
在这里插入图片描述

永久订阅
在这里插入图片描述

  // 订阅消息授权
  getMsgInfo() {
    let that = this
    // 这里是获取下发权限地方,根据官方文档,可以根据  wx.getSetting() 的 withSubscriptions   这个参数获取用户是否打开订阅消息总开关。后面我们需要获取用户是否同意总是同意消息推送。所以这里要给它设置为true 。
    wx.getSetting({
      withSubscriptions: true, //  这里设置为true,下面才会返回mainSwitch
      success: function (res) {
        console.log(res)
        // 调起授权界面弹窗
        if (res.subscriptionsSetting.mainSwitch) {
          // 用户打开了订阅消息总开关
          if (!res.subscriptionsSetting.itemSettings) {
            // 当用户没有点击 ’总是保持以上选择,不再询问‘  按钮。那每次执到这都会拉起授权弹窗
            // wx.showModal({
            //   title: '提示',
            //   content: '请授权开通服务通知',
            //   showCancel: true,
            //   success: function (ress) {
            //     if (ress.confirm) {
            wx.requestSubscribeMessage({
              // 调起消息订阅界面
              // 永久 ETkJzRxc-wTKPKJJdeP-_3JvJr_F4aUPp8jVRga_KtA
              // 一次性 rSELfotEiOJ_2GtKYxRHNoKdhnnwEEPt6cqGhsqqZzQ
              tmplIds: ['ETkJzRxc-wTKPKJJdeP-_3JvJr_F4aUPp8jVRga_KtA'],
              success(res) {
                console.log('订阅消息 成功 ')
                console.log(res)
                // 用户同意的消息模板id
                let moIdState = res['ETkJzRxc-wTKPKJJdeP-_3JvJr_F4aUPp8jVRga_KtA']
                // Object res   [TEMPLATE_ID]是动态的键,即模板id,值包括'accept'、'reject'、'ban'。
                // 'accept'表示用户同意订阅该条id对应的模板消息,'reject'表示用户拒绝订阅该条id对应的模板消息,'ban'表示已被后台封禁。

                if (moIdState === 'accept') {
                  // 用户同意总是保持是否推送消息的选择, 这里表示以后不会再拉起推送消息的授权
                  console.log('接受了消息推送')
                } else if (moIdState === 'reject') {
                  console.log('拒绝消息推送')
                } else if (moIdState === 'ban') {
                  console.log('已被后台封禁')
                }
                that.toMsgList()
              },
              fail(er) {
                console.log('订阅消息 失败 ')
                console.log(er)
                if (res.errCode === 20004) {
                  wx.showModal({
                    title: '温馨提示',
                    content: '您已拒绝授权,将无法在微信中收到回复通知!',
                    showCancel: false,
                    success: (res) => {
                      if (res.confirm) {
                        that.toMsgList()
                      }
                    },
                  })
                }
              },
            })
            //     }
            //   },
            // })
          } else {
            // 用户同意总是保持是否推送消息的选择, 这里表示以后不会再拉起推送消息的授权
            let moIdState = res.subscriptionsSetting.itemSettings['ETkJzRxc-wTKPKJJdeP-_3JvJr_F4aUPp8jVRga_KtA'] // 用户同意的消息模板id
            if (moIdState === 'accept') {
              console.log('接受了消息推送')
              that.toMsgList()
            } else if (moIdState === 'reject') {
              console.log('拒绝消息推送')
              wx.showModal({
                title: '提示',
                content: '检测到您没打开消息通知功能权限,是否去设置打开?',
                success(res) {
                  if (res.confirm) {
                    console.log('用户点击确定')
                    wx.openSetting({
                      success: (res) => {
                        console.log(res)
                      },
                    })
                  } else if (res.cancel) {
                    console.log('用户点击取消')
                    // 拒绝跳转
                    that.toMsgList()
                  }
                },
              })
            } else if (moIdState === 'ban') {
              console.log('已被后台封禁')
            }
          }
        } else {
          console.log('订阅消息未开启')
        }
      },
      fail: function (error) {
        console.log(error)
      },
    })
  },

注意事项
1、“总是保持以上选择,不再询问”
如果不勾选,用户每次触发订阅消息功能都会弹出授权窗口。

比如,你现在有两个订阅消息,第一个你勾选了不再询问,第二个没勾选,第二个下次点击还是会提示的,每个订阅消息是独立的。

如果用户勾选了订阅面板中的“总是保持以上选择,不再询问”时,模板消息会被添加到用户的小程序设置页,下次订阅调用 wx.requestSubscribeMessage 则不会出现弹窗,保持之前的选择。

需要通过 wx.getSetting 接口可获取用户对相关模板消息的订阅状态。

用户如果同意订阅这条消息之后,wx.requestSubscribeMessage后台还是会默认调用,只是没有弹出框了。比如你订阅了5次,就发5次,我测试是这样子的。

2、订阅消息目前分为「一次性订阅」和「永久订阅」
一次性订阅消息
用户订阅一次后,开发者可下发一条消息,不限时间。可以多个模版。
若用户勾选了“总是保持以上选择,不再询问”且点击了允许,那么以后都默认同意订阅这条消息。用户不再做多次选择,开发者也避免了更繁琐的提醒。

长期性订阅消息
用户订阅一次后,开发者可长期下发多条消息。
目前长期性订阅消息仅向政务民生、医疗、交通、金融、教育等线下公共服务开放,后期将逐步支持到其他线下公共服务业务。
(长期订阅消息只针对特定行业开放,所以普通开发者并无法使用)

在这里插入图片描述

自定义订阅消息组件

在这里插入图片描述
subscribeAlert.wxml

<!-- components/subscribeAlert/subscribeAlert.wxml -->
<view class="mask" bindtap="isAlert" data-type="1" catchtouchmove="stopEvent" wx:if="{{isShow}}">
  <view class="alert" catchtap="stopEvent">
    <view class="top-img">
      <image src="../../assets/ling.png" mode="aspectFit" />
    </view>
    <view class="title">
      <text>订阅通知</text>
    </view>
    <view class="title-tip">
      <text>订阅后您将获得以下事件状态的通知</text>
    </view>
    <view class="content">
      <view class="list-item" wx:for="{{dataList}}" wx:key="index">
        <view class="item-img">
          <image src="../../assets/choose.png" mode="aspectFit" />
        </view>
        <text>{{item.name}}</text>
      </view>
    </view>
    <view class="bottom">
      <button bindtap="isAlert" data-type="2">取消</button>
      <button class="green" bindtap="subscribeAlert">我要订阅</button>
    </view>
  </view>
</view>

subscribeAlert.js

// components/subscribeAlert/subscribeAlert.js
const app = getApp()
const request = require('../../api/request.js')

Component({
  /**
   * 组件的属性列表
   */
  properties: {},

  /**
   * 组件的初始数据
   */
  data: {
    isShow: false,
    isTo: false, //是否有后续操作
    state: false, //拒绝后是否需要弹窗
    ids: '', //模版id
    dataList: [
      {
        name: '诉求处理状态更新通知',
      },
      {
        name: '关注事件办结通知',
      },
      {
        name: '社区通知公告的推送',
      },
    ],
  },
  created: function () {
    this.getIds()
  },
  /**
   * 组件的方法列表
   */
  methods: {
    // 之后去做的事情
    toSubscribe() {
      console.log('toSubscribe')
      this.triggerEvent('toSubscribe')
    },
    // 阻止冒泡 阻止滑动
    stopEvent() {
      console.log('stopEvent')
      return true
    },
    isShowSubscribe() {
      // position fixed
      this.triggerEvent('showSubscribe')
    },

    // 控制定位
    isAlert(e) {
      // 点击取消
      if (e.target) {
        e = e.target.dataset.type
      }
      console.log('isAlert', e)

      // 父组件定位
      if (e == 1) {
        this.isShowSubscribe()
      }
      // 弹窗的取消按钮
      if (e == 2) {
        this.isShowSubscribe()
        if (this.data.isTo) {
          this.toSubscribe()
        }
        this.postChanel()
      }

      this.setData({
        isShow: !this.data.isShow,
      })
    },
    // 订阅消息授权
    getSubscribeInfo(isTo) {
      let that = this
      // 这里是获取下发权限地方,根据官方文档,可以根据  wx.getSetting() 的 withSubscriptions   这个参数获取用户是否打开订阅消息总开关。后面我们需要获取用户是否同意总是同意消息推送。所以这里要给它设置为true 。
      if (isTo) {
        this.setData({
          isTo: isTo,
        })
      }
      wx.getSetting({
        withSubscriptions: true, //  这里设置为true,下面才会返回mainSwitch
        success: function (res) {
          console.log(res)
          // 调起授权界面弹窗
          if (res.subscriptionsSetting.mainSwitch) {
            // 用户打开了订阅消息总开关
            if (!res.subscriptionsSetting.itemSettings) {
              // 当用户没有点击 ’总是保持以上选择,不再询问‘  按钮。那每次执到这都会拉起授权弹窗
              // wx.showModal({
              //   title: '提示',
              //   content: '请授权开通服务通知',
              //   showCancel: true,
              //   success: function (ress) {
              //     if (ress.confirm) {
              // type 1 组件显示/隐藏
              if (that.data.state) {
                that.isAlert(1)
              } else {
                if (that.data.isTo) that.toSubscribe()
              }
              //     }
              //   },
              // })
            } else {
              // 用户同意总是保持是否推送消息的选择, 这里表示以后不会再拉起推送消息的授权
              let moIdState = res.subscriptionsSetting.itemSettings[that.data.ids] // 用户同意的消息模板id
              if (moIdState === 'accept') {
                console.log('接受了消息推送')
                that.toSubscribe()
              } else if (moIdState === 'reject') {
                console.log('拒绝消息推送')
                wx.showModal({
                  title: '提示',
                  content: '检测到您没打开消息通知功能权限,是否去设置打开?',
                  success(res) {
                    if (res.confirm) {
                      console.log('用户点击确定')
                      wx.openSetting({
                        success: (res) => {
                          console.log(res)
                        },
                      })
                    } else if (res.cancel) {
                      console.log('用户点击取消')
                      // 拒绝跳转
                      that.toSubscribe()
                    }
                  },
                })
              } else if (moIdState === 'ban') {
                console.log('已被后台封禁')
              }
            }
          } else {
            console.log('订阅消息未开启')
          }
        },
        fail: function (error) {
          console.log(error)
        },
      })
    },
    subscribeAlert() {
      let that = this
      that.isAlert(1)
      let ids = this.data.ids
      wx.requestSubscribeMessage({
        // 调起消息订阅界面
        // 永久 ETkJzRxc-wTKPKJJdeP-_3JvJr_F4aUPp8jVRga_KtA
        // 一次性 rSELfotEiOJ_2GtKYxRHNoKdhnnwEEPt6cqGhsqqZzQ
        tmplIds: [ids],
        success(res) {
          console.log('订阅消息 成功 ')
          console.log(res)
          // 用户同意的消息模板id
          let moIdState = res[ids]
          // Object res   [TEMPLATE_ID]是动态的键,即模板id,值包括'accept'、'reject'、'ban'。
          // 'accept'表示用户同意订阅该条id对应的模板消息,'reject'表示用户拒绝订阅该条id对应的模板消息,'ban'表示已被后台封禁。

          if (moIdState === 'accept') {
            // 用户同意总是保持是否推送消息的选择, 这里表示以后不会再拉起推送消息的授权
            console.log('接受了消息推送')
          } else if (moIdState === 'reject') {
            console.log('拒绝消息推送')
            that.postChanel()
          } else if (moIdState === 'ban') {
            console.log('已被后台封禁')
          }
          that.toSubscribe()
        },
        fail(er) {
          console.log('订阅消息 失败 ')
          console.log(er)
          if (er.errCode === 20004) {
            wx.showModal({
              title: '温馨提示',
              content: '您已拒绝授权,将无法在微信中收到回复通知!',
              showCancel: false,
              success: (res) => {
                if (res.confirm) {
                  that.toSubscribe()
                }
              },
            })
          }
        },
      })
    },
    // 获取模版ids
    getIds() {
      request
        .get('wxapp/getTemplateId', {}, {})
        .then((res) => {
          if (res.retcode == 0) {
            this.setData({
              ids: res.templateId,
              // 获取是否订阅提示
              state: res.state,
              // state: true,
            })
          }
        })
        .catch((e) => {
          console.log('获取数据失败', e)
          wx.showToast({
            title: e,
            icon: 'none',
          })
        })
    },
    // 选择取消
    postChanel() {
      request
        .get('wxapp/rejectSubscribe', {}, {})
        .then((res) => {
          if (res.retcode == 0) {
            this.setData({
              state: false,
            })
            console.log('postChanel', this.data.state)
          }
        })
        .catch((e) => {
          console.log('获取数据失败', e)
          wx.showToast({
            title: e,
            icon: 'none',
          })
        })
    },
  },
})

subscribeAlert.less

.mask {
  width: 100%;
  min-height: 100%;
  background: rgba(0, 0, 0, 0.5);
  overflow: hidden;
  .alert {
    width: 562rpx;
    height: 569rpx;
    background: #ffffff;
    border-radius: 36rpx;
    border: 1rpx solid #ffffff;
    // filter: blur(8.489425981873111px);
    margin: 200rpx auto 0;
    image {
      width: 100%;
      height: 100%;
      float: left;
    }
    .top-img {
      width: 148rpx;
      height: 148rpx;
      margin: -74rpx auto 0;
    }
    .title {
      font-size: 36rpx;
      font-family: PingFangSC-Medium, PingFang SC;
      font-weight: 500;
      color: #000000;
      line-height: 34rpx;
      text-align: center;
      margin-top: 24rpx;
    }
    .title-tip {
      font-size: 28rpx;
      font-family: PingFangSC-Regular, PingFang SC;
      font-weight: 400;
      color: #5e6166;
      line-height: 38rpx;
      text-align: center;
      margin-top: 24rpx;
    }
    .content {
      width: 463rpx;
      height: 168rpx;
      padding: 20rpx;
      background: rgba(220, 226, 230, 0.15);
      border-radius: 8rpx;
      margin: 24rpx auto 0;
      .list-item {
        line-height: 58rpx;
        .item-img {
          width: 30rpx;
          height: 30rpx;
          margin: 14rpx 24rpx 14rpx 11rpx;
          float: left;
        }
        text {
          font-size: 28rpx;
          font-family: PingFangSC-Medium, PingFang SC;
          font-weight: 500;
          color: #5e6166;
        }
      }
    }
    .bottom {
      display: flex;
      margin-top: 24rpx;
      button {
        width: 222rpx;
        height: 90rpx;
        background: #f1f2f3;
        border-radius: 45rpx;
        font-size: 34rpx;
        font-family: PingFangSC-Regular, PingFang SC;
        font-weight: 400;
        color: #000000;
      }
      .green {
        background: #04b971;
        color: #ffffff;
      }
    }
  }
}

调用
home.json

{
  "usingComponents": {
	"subscribeAlert":"../../components/subscribeAlert/subscribeAlert"
  }
}

home.wxml

<!-- 订阅消息 -->
<subscribeAlert id="subscribeAlert" class="{{isShowSubscribe?'subscribeAlert':''}}" bind:showSubscribe="showSubscribe" bind:toSubscribe="clickInvite"></subscribeAlert>

home.js

  data: {
    isShowSubscribe: false,
  },
  // 显示订阅消息弹窗
  showSubscribe(e) {
    // if (this.data.isShowSubscribe) {
    //   const child = this.selectComponent('.subscribeAlert')
    //   child.postChanel()
    // }
    this.setData({
      isShowSubscribe: !this.data.isShowSubscribe,
    })
  },
  // 订阅消息
  getSubscribe(e) {
    // 点击取消
    if (e.target) {
      e = e.target.dataset.type
    }
    // 调用子组件方法
    const child = this.selectComponent('#subscribeAlert')
    child.getSubscribeInfo(e)
  },
    /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    this.getSubscribe(false)
  },

错误解决:

1.错误信息:

errMsg:“requestSubscribeMessage:fail can only be invoked by user TAP
gesture.”

解决:bindtap点击才行、不能延迟调用

2.错误信息:

errMsg:“requestSubscribeMessage:fail 开发者工具暂时不支持此 API 调试,请使用真机进行开发”

解决:真机调试才行

3.错误信息:

errCode: 20001 errMsg: “requestSubscribeMessage:fail No template data return, verify the template id exist”

解决:确认模板ID是订阅消息的模板ID且正确。

4.错误信息:

errCode:20003 errMsg:“requestSubscribeMessage:fail:Templates count out of max bounds”

解决:模版数量超出,最多3个

5.错误信息:

requestSubscribeMessage:fail last call has not ended

解决:如果申请的是“一次性订阅”,一次触发只有一次推送消息机会,所以我们会在其他页面点击事件去调用requestSubscribeMessage,获取更多次的推送消息机会。但是每个手机获取是有上限的,大概几十个吧。然后只有用掉推送消息次数,才能重新成功调用,否则会出现以上问题。

6.错误信息:

requestSubscribeMessage:fail can only be invoked by user TAP gesture

解决:表单提交,在高版本微信是没有问题的,但是在低版本无法调用订阅消息,低版本订阅消息api必须在点击事件中触发,需将form提交改为bindtap提交,一般可做成显示一个弹框友好的提示用户,然后再让用户点击按钮去手动触发订阅

注意-坑:

1.bindtap点击才可以调起

2.真机调试才行(–2020/01/03:貌似微信开发者工具也可以调用了)

3.不能延迟去调用wx.requestSubscribeMessage,如先调用其他接口请求成功再去它、使用定时器延迟调用

参考:
小程序订阅消息
小程序端消息订阅接口 wx.requestSubscribeMessage
小程序模板消息能力调整通知
针对新手很容易出现理解误区的微信小程序订阅消息模块
微信小程序订阅消息授权选择总是接收订阅消息,成功发送订阅消息一次过后,后续发送都返回43101错误?

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值