微信小程序订阅消息授权弹窗问题整理

news2024/11/28 0:48:09

文档

小程序订阅消息(用户通过弹窗订阅)开发指南 | 微信开放文档

1.报错10004

  1. errCode: 10004
  2. errMsg: "requestSubscribeMessage:fail Invalid template id"

真机调试也不行

wx.requestSubscribeMessage({
        tmplIds: result,
        // 用户同意与否都需要传标识给后端
        success(res) {
}
[{ "templateId": "MvyaI3UcBWMpjFLcM_4_quuSJDftIsgbJ3ykuD", "title": "福利包到账提醒" },
    { "templateId": "sDCqzUaMapgSETh_LHpuf0VuKaLXKMDltrOSlz8YADE", "title": "优惠券过期提醒" },]

原因:tmplIds参数必须是数组

const result = ["MvyaI3UcBWMpjFLcM_4_quuSJDftIsgbJ3ykuD",
      "sDCqzUaMapgSETh_LHpuf0VuKaLXKMDltrOSlz8YADE"]

2.用户第一次拒绝,第二次不掉弹窗直接到success

wx.requestSubscribeMessage接口的success中res参数

我试着加了第三个模板ID:发现第二次弹窗只谈了加的模板id对应的模板title,之前被拒绝过的没有再显示

const result = ["MvyaI3UcBWMpjFLcM_4_quuSJDftIsgbJ3ykuD-bHW4",
      "sDCqzUaMapgSETh_LHpuf0VuKaLXKMDltrOSlz8YADE","PokxmMG5bvk_LK7hrz40qqaliqKzAn6vyKkJPwbN7Sc"]

3.用户选择总是保持以上选择后,点击了拒绝

正常情况下,用户选择了总是保持以上选择后,点击了拒绝,之后就不会再次弹窗,如果下次进入时想要弹窗,需要通过微信小程序wx.openSetting()去引导用户到设置页面主动设置接收订阅消息

主要流程:

  1. 调用后端接口获取需要授权的模板ID;
  2. 通过wx.requestSubscribeMessage调用订阅消息授权弹窗;
  3.  检测到有拒绝授权情况就引导用户去设置页面设置接收订阅消息;
  4. 否则直接调用后端接口将已经同意过的模板进行上报;
/**
 * 根据pushSceneId场景ID获取没有授权的模板
 * @param {*} pushSceneId 
 */
function commSubscribeMessage(pushSceneId) {
  return new Promise((resolve, reject) => {
  // 根据场景ID获取需要订阅消息的模板
  // ajax('get', 'api/wechat/auth/unsubscribe/list', {
  //   pushSceneId
  // }, ({ code, msg, result }) => {
  //   console.log('订阅结果上报', code, result)
  //   // 模板ID不为空才进行授权弹窗
  //   if (code === 0 && result.length > 0) {
  // wx.requestSubscribeMessage调起授权订阅消息弹窗

  // 优惠券
  // const tmplIds = ["MvyaI3UcBWMpjFLcM_4_quuSJDftIsgbJ3ykuD-bHW4",
  //   "sDCqzUaMapgSETh_LHpuf0VuKaLXKMDltrOSlz8YADE"]
  // 活动
  // const tmplIds = ["PokxmMG5bvk_LK7hrz40qqaliqKzAn6vyKkJPwbN7Sc"]
  const tmplIds = ["Uc-DA-Jr3N4ih7d5M3PkPrTFOi6t-AX0MGj4S8hvHqU"]
  // 提单
  // const tmplIds = ["3d6zsNMfQ3Wpgq1V8duO31v9gE8un7Lka_2E17sJZjs"]
 wx.requestSubscribeMessage({
    tmplIds,
    // 用户同意与否都需要传标识给后端
    async success(res) {
      let acceptTmplIds = [];
      let rejectTmplIds = [];
      tmplIds.forEach(item=>{
        if(res[item] === 'accept'){
          acceptTmplIds.push(item);
        }else if( res[item] === 'reject'){
          rejectTmplIds.push(item);
        }
      });
      // 检测到有拒绝授权情况
      if(rejectTmplIds.length > 0){
        console.log("引导用户授权");
        await guideOpenSubscribeMessage(tmplIds,pushSceneId);
        resolve(true);
      }else{
        console.log("用户之前已经同意过授权");
        await agreeSubscribe(tmplIds,pushSceneId);
        resolve(true);
      }
    },
    async fail(res) {
      console.log("用户拒绝授权", res);
      if (res.errCode == 20004) {
        // console.log(res, 'fail:用户关闭了主开关,无法进行订阅,引导开启---');
        await guideOpenSubscribeMessage(tmplIds,pushSceneId);
        resolve(true);
      }
    }
  })
});
}

function guidSubscribeMessageAuthAfter(templateIds) {
  return new Promise((resolve, reject) => {
    //引导用户 开启订阅消息 之后,「openSetting」 接口暂时不会返回,用户手动设置后的状态,所以采用「getSetting」接口重新进行查询
    wx.openSetting({
      success: res => {
      console.log(res, "guidSubscribeMessageAuthAfter");
      }
    })
    resolve(true);
  });
}
function guideOpenSubscribeMessage(templateIds,pushSceneId) {
  return new Promise((resolve, reject) => {
    //引导用户,手动引导用户去设置页开启,
    wx.showModal({
      title: '提示',
      content: '检测到您有未开启的订阅消息权限,是否去设置?',
      showCancel: true,
      confirmText: '确认',
      success: function (res) {
        if (res.confirm) {
          // 新版禁用,需要通过按钮触发
          console.log("去设置授权信息");
          guidSubscribeMessageAuthAfter(templateIds);
          resolve(true);
        } else {
          console.log(`您已拒绝订阅消息授权,无法预约领取`);
          disagreeSubscribe(templateIds,pushSceneId);
          resolve(true);
        }
      }
    })
});
}
function agreeSubscribe(templateIds,pushSceneId) {
  ajax('post', '/api/wechat/auth/subscribe', {
    templateIds,
    pushSceneId,
    allow: 1
  }, res1 => {
    console.log('订阅结果上报', res, res1)
  })
}
function disagreeSubscribe(templateIds,pushSceneId) {
  ajax('post', '/api/wechat/auth/subscribe', {
    templateIds,
    pushSceneId,
    allow: 0
  }, res1 => {
    console.log('用户拒绝授权订阅结果上报', res, res1)
  })
}

使用:

  async goPage(e) {
    // 授权订阅消息弹窗
    await commSubscribeMessage("SC_001");
}

4.不引导用户去设置页面,但是要将用户是否选择过永远选中此项传给后端;且需要传openId和每个模板id都有个是否允许授权订阅的状态

 let openId = wx.getStorageSync('userInfo').openId;

5.弹窗涉及所有成功或失败场景:

  • 1.模板数据超过3个,报错20003
  • 2.用户关闭了总开关(设置里面订阅消息的总开关关闭) 20004
  • 3.之前弹窗过,且选择了拒绝,且选中了永远保持以上选择,只会返回以下信息,不会弹窗

MvyaI3UcBWMpjFLcM_4_quuSJDftIsgbJ3ykuD-bHW4: "reject"
PokxmMG5bvk_LK7hrz40qqaliqKzAn6vyKkJPwbN7Sc: "reject"
Uc-DA-Jr3N4ih7d5M3PkPrTFOi6t-AX0MGj4S8hvHqU: "reject"

  • 4.用户手动在设置页面设置了接收消息,不会弹窗,只会显示一下信息
  1. MvyaI3UcBWMpjFLcM_4_quuSJDftIsgbJ3ykuD-bHW4: "accept"
  2. PokxmMG5bvk_LK7hrz40qqaliqKzAn6vyKkJPwbN7Sc: "accept"
  3. Uc-DA-Jr3N4ih7d5M3PkPrTFOi6t-AX0MGj4S8hvHqU: "accept"
  • 5.所以想在获取用户是否选中了永远保持以上选择需要通过 wx.getSetting 进行获取

6.用户弹窗总流程

1.通过wx.getSetting()判断用户是否选择了"永远保持以上选择",如果选中了,需要通知后端,同时通知后端拒绝或者接受订阅的模板

2.如果用户没有选中,每次都会调用弹窗,调用微信小程序接口wx.requestSubscribeMessage()调起弹窗

7.小程序userId和openId关系

  • userid是用户登录小程序的荷叶的唯一标识
  • openid是小程序账号的唯一标识
  • openid跟手机号没关系的,跟微信号一一对应;
  • 次数限制是订阅一次推一次,看产品意思是userid维度订阅,一天订阅一次是咱们这边业务上的限制,不是微信的限制,微信一天内不限制一次性订阅的次数
  • 还有个场景,如果推送消息也是按userid维度推送,小程序只能登录一个手机号,如果同一个小程序多个手机号登录且订阅授权过,那推送消息的时候,当时小程序登录的只有其中一个手机号,那么其他未登录手机号的订阅消息会在同一个小程序内收到,或者其他手机号在另外的微信上登录,一个userid可能对应多个openid,会在两个小程序上都收到订阅消息
  • 推送消息,使用userid+openid维度进行推送

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1599485.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

天池酒瓶瑕疵检测数据集分析及完整baseline

以下内容为还没思路的小伙伴牵个头提供一个demo,大佬勿喷,线上成绩0.7,留空间给小伙伴们发挥自己的力量 ps:markdown不怎么熟悉,代码中如有明显缩进问题,自行斟酌改正,编辑好几次都改不过来,请原谅.... 数据分析瑕疵大类: 瓶盖瑕疵、标贴瑕疵、喷码瑕疵、瓶身瑕疵、酒液瑕疵瑕…

【canvas】canvas基础使用(九):文本绘制

简言 canvas除了能够绘制图形外,也可以绘制文本。 绘制文本 fillText() 填充文本 CanvasRenderingContext2D 对象的方法 fillText() 是 Canvas 2D API 的一部分,它在指定的坐标上绘制文本字符串,并使用当前的 fillStyle 对其进行填充。存…

ChatGPT深度科研应用、数据分析及机器学习、AI绘图与高效论文撰写教程

原文链接:ChatGPT深度科研应用、数据分析及机器学习、AI绘图与高效论文撰写教程https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247601506&idx2&sn5dae3fdc3e188e81b8a6142c5ab8c994&chksmfa820c85cdf58593356482880998fc6eb98e6889b261bf62…

如何解决DDoS攻击?

DDoS攻击(分布式拒绝服务攻击)是一种恶意利用多台傀儡机协同发起大规模网络流量,旨在压垮目标系统或网络资源,使其无法正常服务的网络攻击手段。由于现代计算机和网络性能的提升,单点发起的DoS攻击已难以奏效&#xff…

基于ssm缪斯乐器购物网站的设计与实现论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本缪斯乐器购物网站就是在这样的大环境下诞生,其可以帮助管理者在短时间内处理完毕庞大的数据信息…

DNF手游攻略:萌新入坑大全!

玩DNF手游国服已经正式定档,离上线已经越来越近了,很多小伙伴对于装备打造以及附魔还不是特别了解。如果你还不知道装备要怎么附魔,不要担心,本篇攻略将为你全面解析全职业过渡和毕业附魔推荐。 ​ 一、物理职业附魔推荐 1. 武器…

知道XRD标准品PDF卡片号,如何直接导出标准物质数据,简单快速一分钟完成(附jade下载安装方法)

知道XRD标准品PDF卡片号,如何直接导出标准物质数据(附jade下载安装方法) 网上找到的方法都是先检索再导出,我的样品根本检索不到,但是根据参考文献知道了自己的pdf卡片号,可通过jade直接导出数据 1.请安装…

【kafka】安装

也是第二次安装,蛮记录一下 1.安装kafka之前需要先完成zookeeper的安装 【zookeeper】安装 2. Apache Kafka官网下载 3. 解压完成后修改server.properties配置文件 修改日志文件存放路径 查看与zookeeper连接的端口是否和zookeeper服务所在的端口一致 &#xf…

在vue中发现一个prop新的写法在官方文档没有,查百度不行,还有什么其他方法排查不

先看图,最近在接手一个同事的代码,发现prop有这样的写法: 我自己查了官网,以及百度都没有找到这种写法。这时我灵机一动,想到一个方法,vscode有内置的typesscript,自然有prop类型推断&#xff0…

【数据结构】树与二叉树、树与森林部分习题以及算法设计例题 2

目录 【数据结构】树与二叉树、树与森林部分习题以及算法设计例题一、交换二叉树每个结点的左右孩子Swap 函数(先序遍历):Swap 函数(中序遍历) 不可行:Swap 函数(后序遍历)&#xff…

Java小白教学—五千字带你了解多线程机制及线程安全问题

基础概念 📖 问题一 : 什么是线程?线程和程序、进程有什么区别? 程序:为实现某种功能,使用计算机语言编写的一系列指令的集合。 指的是静态的代码(例如安装在电脑上的那些文件) 进程&#xff…

由于找不到msvcr120.dll,无法继续执行代码的详细处理方法,教你快修复msvcr120.dll

DLL文件,全称动态链接库文件,在计算机系统中具有重要作用。其中,msvcr120.dll是一个常见的DLL文件,它关联了许多程序和应用的正常运行。本指南将深入解释 msvcr120.dll文件的功能,并阐述如果缺少该文件会引起什么样的问…

C语言案例——输出以下图案(两个对称的星型三角形)

目录 图片代码 图片 代码 #include<stdio.h> int main() {int i,j,k;//先输出上半部图案for(i0;i<3;i){for(j0;j<2-i;j)printf(" ");for(k0;k<2*i;k)printf("*");printf("\n");}//再输出下半部分图案for(i0;i<2;i){for(j0;j&…

WebKit简介及工作流程

文章目录 一、WebKit简介二、WebKit结构三、Webkit工作流程四、WebKit常见问题五、WebKit优点六、相关链接 一、WebKit简介 WebKit是一个开源的浏览器引擎&#xff0c;它的起源可以追溯到2001年&#xff0c;当时苹果公司推出了其首款基于Unix的操作系统Mac OS X。在2002年&…

ST-LINK Utility 4.6.0 下载安装及使用方法介绍

一、介绍 STM32 ST-LINK Utility是针对STM32全系芯片进行编程&#xff08;读、写、擦除、选项字&#xff09;的一款工具。 STM32 ST-LINK Utility软件主要的功能就是量产&#xff08;批量下载代码的工具&#xff09;。它也是比较实用的一个工具&#xff0c;当我们需要查看芯片F…

BackTrader 中文文档(十)

原文&#xff1a;www.backtrader.com/ 用户自定义佣金 原文&#xff1a;www.backtrader.com/docu/user-defined-commissions/commission-schemes-subclassing/ 重塑 CommInfo 对象到实际形式的最重要部分涉及&#xff1a; 保留原始的 CommissionInfo 类和行为 为轻松创建用户定…

Android Material Design学习笔记

Material Design控件学习记录 Toolbar 新建一个工程后&#xff0c;在res/values/themes.xml文件里 <resources xmlns:tools"http://schemas.android.com/tools"><!-- Base application theme. --><style name"Theme.MaterialTest" paren…

【C++航海王:追寻罗杰的编程之路】异常——错误处理方式之一

目录 引言 1 -> C语言传统的处理错误的方式 2 -> C异常概念 3 -> 异常的使用 3.1 -> 异常的抛出和捕获 3.2 -> 异常的重新抛出 3.3 -> 异常规范 4 -> 自定义异常体系 5 -> C标准库的异常体系 6 -> 异常的优缺点 引言 在C编程中&#xff…

《剑指 Offer》专项突破版 - 面试题 110 : 所有路径(C++ 实现)

题目链接&#xff1a;所有路径 题目&#xff1a; 一个有向无环图由 n 个节点&#xff08;标号从 0 到 n - 1&#xff0c;n > 2&#xff09;组成&#xff0c;请找出从节点 0 到节点 n - 1 的所有路径。图用一个数组 graph 表示&#xff0c;数组的 graph[i] 包含所有从节点 …

javaWeb项目-游泳馆管理系统功能介绍

项目关键技术 开发工具&#xff1a;IDEA 、Eclipse 编程语言: Java 数据库: MySQL5.7 框架&#xff1a;ssm、Springboot 前端&#xff1a;Vue、ElementUI 关键技术&#xff1a;springboot、SSM、vue、MYSQL、MAVEN 数据库工具&#xff1a;Navicat、SQLyog 1、SSM框架 开发信息…