[填坑手册]小程序新版订阅消息+云开发实战与跳坑
发布于 5 年前 作者 gaoxiulan 3398 次浏览 来自 分享

老版本的订阅消息在2020年1月10日就下线了,相信不少人在接入新版本订阅系统的时候,或多或少会遇到一些问题,这里智库君跟大家介绍下新版订阅的机制和__不需要node/后端的情况下__ 独立完成功能开发。

一、新版订阅的机制

其实开发过程不难,但是要理清楚它里面的机制,智库君还是花了一些时间的,也踩了不少坑

先来看下官方介绍:

  1. 可以设置多个订阅选项
  2. 感叹号里面可以看到详情
  3. 有个默认不被选中的“总是”选项

这些就是新不同的地方,智库君在开发的时候也有很多疑问,点了“总是”再点“取消”按钮会怎样?部分选择订阅会怎样?下面为大家一一梳理

(1)部分选中


比如现在有三个选项 A,B,C,用户**“部分选中”**返回的情况:

这里用真机调试可以看到,有个返回值状态为“reject”。
如果我们反复几点点击同一个订阅后,这些值是如何计算的呢?

举例:

从这里看出,微信系统会自动记录用户点击的次数,并且做累加记录,如果用户只允许2次发送,而开发者发送了3次,最后一次将会被拒绝。

(2)点击“总是保持以上选择,不再询问”的情况

当用户点击“总是”之后,同一个类型的订阅将不再弹出,那如果有多个订阅选项呢?

举例

订阅AAA 三个订阅模板为 X Y Z

订阅BBB 二个订阅模板为 Y W

这时候如果“订阅AAA”按钮选择了“总是”,那么再点击“订阅BBB”按钮,将只会弹出__一个选项“W”__,不会有 “Y” 的模板,因为在之前 “订阅AAA” 按钮中已经包含了。

wx.requestSubscribeMessage({
  tmplIds: ["MECDDOdhbC3SrQmMY5XrfqiIGbMTzpEN8Z7ScXJfcd0", "iSb2NIlNnnO60wlI-8Wx5Pe82jR7TRdwjotSXtM1-ww"],
  success(res) {
    console.log(res);
  }
})

显示内容仅一个选项:

这里需要注意,“总是”选项是全局有效,不区分页面,选中“总是”的 W,X,Y,Z的模板,在全局任意页面中再次调用,再次调用将不再会显示!

返回值无提示用户是否选中“总是”。

(3)用户点击“总是”后,获取状态

wx.getSetting({
  withSubscriptions: true,
  success(res) {
    console.log(res.authSetting)
    // res.authSetting = {
    //   "scope.userInfo": true,
    //   "scope.subscribeMessage": true
    // }
    console.log(res.subscriptionsSetting)
    // res.subscriptionsSetting = {
    //   SYS_MSG_TYPE_INTERACTIVE: 'accept',
    //   SYS_MSG_TYPE_RANK: 'accept',
    //   zun-LzcQyW-edafCVvzPkK4de2Rllr1fFpw2A_x0oXE: 'reject',
    //   ke_OZC_66gZxALLcsuI7ilCJSP2OJ2vWo2ooUPpkWrw: 'ban',
    // }
  }
});

这里可以调用__wx.getSetting__方法,但是需要注意:如果用户第一次选“总是”后点击“取消”按钮或者订阅模板全部是未选中/reject的,那将获取不到状态(这里可能是BUG,期待官方未来修复)。

(4)用户点击“总是”后,让用户手动修改

前面说到用户点击“总是”后,系统将不再弹窗,但是我们可以通过**“wx.openSetting”**引导用户手动修改。

wx.openSetting({
  success(res) {
    console.log(res.authSetting)
    // res.authSetting = {
    //   "scope.userInfo": true,
    //   "scope.userLocation": true
    // }
  }
})


当然用户自己也可以修改

总结

  • 用户点击次数系统会自动累加,直接影响后台发送通知的次数。
  • 用户选择“总是”后,小程序界面不再弹窗,但仍然有回调/callback。
  • 任意订阅模板在用户选中“总是”(包括接受/拒绝2个状态)后,全局有效,就算其他订阅包含“此模板”也不再显示/弹出
  • 当用户选择“总是”中“accept/选中/接受”的状态后,可以在__wx.getSetting__查询到用户是否选择“总是”。
  • 当用户选择“总是”中“reject/未选中/拒绝”的状态后,返回值“无感知”(这里可能是BUG)

二、功能开发

使用微信自带的云开发,可以在没有node/后端开发支持下,完成整个订阅流程的开发。

(1)微信后台设置订阅模板和获取模板ID

1、打开小程序后台,找到订阅消息设置

2、在公共模板库找模板或者自己申请新模板,建议能用现成模板用现成的,因为申请周期可能较长,且容易被拒

3、选好模板后,点击详情

4、查看模板内容和发送DATA的结构

5、复制模板ID

(2)配置云函数



1、新建getOpenId云函数,用于获取用户的openID

// 云函数入口文件
const cloud = require('wx-server-sdk')

cloud.init()

// 云函数入口函数
exports.main = async (event, context) => {
  const wxContext = cloud.getWXContext()

  return {
    event,
    openid: wxContext.OPENID,
    appid: wxContext.APPID,
    unionid: wxContext.UNIONID,
  }
}

2、新建订阅推送通知云函数

// 云函数入口文件

const cloud = require('wx-server-sdk')
cloud.init()

//订阅推送通知
exports.main = async (event, context) => {
  try {
    const result = await cloud.openapi.subscribeMessage.send({
      touser: event.openid, //接收用户的openId
      page: 'pages/my/index', //订阅通知 需要跳转的页面
      data: {   //设置通知的内容
        thing1: {
          value: '小程序订阅填坑'
        },
        thing2: {
          value: '智库方程式'
        },
        thing3: {
          value: '一起学习,一起进步'
        }
      },
      templateId: '5Efr7IqIooYO9nPw047Iggxbm9Ge2Km10GQ4amGOUac' //模板id
    })
    console.log(result)
    return result
  } catch (err) {
    console.log(err)
    return err
  }
}

写完云函数记得__右键部署__下!!!

(3)小程序代码部分

<!------------html ------------->
<button bindtap="getOpenId" type='primary'>获取openId</button>

<view class="subBtn" catch:tap="sub">订阅AAA</view>

<view class="subBtn" catch:tap="send">订阅推送测试</view>

<view class="subBtn" catch:tap="setting">设置“总是”后,跳转修改</view>
//JS 部分
//获取用户的openid
  getOpenId() {
    wx.cloud.callFunction({
      name: "getOpenId"
    }).then(res => {
      let openid = res.result.openid
      console.log("获取openid成功", openid)
    }).catch(res => {
      console.log("获取openid失败", res)
    })
  },
//发送模板消息给指定的openId用户
  send(openid){
      wx.cloud.callFunction({
        name: "sendSub",
        data: {
          openid: openid
        }
      }).then(res => {
        console.log("发送通知成功", res)
      }).catch(res => {
        console.log("发送通知失败", res)
      });
  },
//消息订阅
  sub: function () {
    wx.requestSubscribeMessage({
      tmplIds: ["5Efr7IqIooYO9nPw047Iggxbm9Ge2Km10GQ4amGOUac"],
      success(res) {
        console.log("订阅授权成功:"+res);
      },
      fail(res){
        console.log("订阅授权失败:" + res);
      }
    })
  },
//帮助用户跳转修改订阅状态
  setting:function(){
    wx.openSetting({
      success(res) {
        console.log(res.authSetting)
        // res.authSetting = {
        //   "scope.userInfo": true,
        //   "scope.userLocation": true
        // }
      }
    })
  },

(4)测试流程

点击发送通知后,获得这样的效果:

获得对应返回值:

当errCode为0时,即发送通知成功。
当errCode为43101,说明用户只授权了一次,但是你发送了2次,超过用户授权次数。

三、进阶与思考

1、当你有__多个订阅模板__同时需要用户选择时,你可以通过以下代码记录,用户哪些选了,哪些没选。

wx.requestSubscribeMessage({
  tmplIds: ["5Efr7IqIooYO9nPw047Iggxbm9Ge2Km10GQ4amGOUac", "OBB_Z10eh_Inm9p8EU6Ml_NS_mijXgTz3T07cxgKvX0","5Efr7IqIooYO9nPw047Iggxbm9Ge2Km10GQ4amGOUac"],
  success(res) {
    //console.log(res);
    if (res.errMsg == "requestSubscribeMessage:ok") {
      let acceptArray = [];  //用户授权模板列表
      for (let i = 0; i < tmplIds.length; i++) {
        const element = tmplIds[i];
        if (res[element] == "accept") {
          acceptArray.push(element);
        }
      };
      console.log(acceptArray);
      if (acceptArray.length > 0) {
      //执行下一步函数
      }
    }
  }
})

2、一个关于是否需要记录用户对某个“订阅模板授权的次数”,以控制后台“发送的次数”,智库君在实战中认为,其实没有必要,顶多就是你发送返回一个错误码,微信之所有记录用户授权次数,也是为了保护用户不被骚扰。

3、你只需要记录用户点击了哪些需要授权的模板就行,为了是用户点击订阅后,改变按钮的状态,避免订阅按钮反复弹窗的问题,同时当检测到用户点错“总是”按钮后,可以自动跳转到“设置”界面。

4、这次智库君主要给大家简单介绍了下订阅全流程。后面大家可以根据自己的需要,添加和改进这些代码。比如:

  • 配置云函数中的node函数,实现定时发送
  • 配置云函数中的数据库,实现内容的自定义发送

最后,希望这篇文章能帮助到大家,一起学习,一起进步!

(官方文档地址:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/subscribe-message.html)

往期回顾:

2 回复

非常详细,花了不少功夫整理,加油

大量的订阅消息能否用云函数定时推送?还是用自己的服务器靠谱些?延迟大吗?

回到顶部