微信小程序订阅

摘要

1.基于promise封装微信小程序订阅

2.解决由于微信基础库版本低下的兼容

3.解决“总是保持以上选择,不再询问”的取消状态

主要运用API:

requestSubscribeMessage
getSetting
openSetting

主要功能:

用户强制订阅,无论怎么取消都能订阅,总代码在下方,具体流程思路有耐心可以往下看...,可以拷贝直接用。引入即可,当然我比较菜,大家可以再改改。

总代码

/**
* @desc 小程序订阅功能
* @param {Array} tmplIds 订阅列表
* @returns {Promise} 返回promise
*/ // 永久关闭订阅则代表点击了我不在接受此消息,再次订阅是无法弹起授权窗口的。普通关闭时可以再次弹起授权窗口。 export const Subscribe = (tmplIds = []) => {
return new Promise((resolve, reject) => {
// 判断是否为微信小程序,不是的不做订阅进行跳过
let isWx = false;
// #ifdef MP-WEIXIN
isWx = true;
// #endif
if (!isWx) resolve(1);
console.log('进来了哟')
// 判断基本库是否在2.8.3,低于的暂时不做订阅进行跳过
const versionCan = compareVersion("2.8.3");
if (versionCan === -1) resolve(1);
// 主流程
requestSubscribe(tmplIds, resolve, reject)
}) }
// 申请订阅功能
function requestSubscribe(tmplIds, resolve, reject) {
uni.requestSubscribeMessage({
tmplIds,
success: async res => {
// 检查订阅数量
let checkSubscribeBool = await checkSubscribeAll(tmplIds, res);
if (checkSubscribeBool) {
// 用户完成订阅
console.log("[用户完成订阅]")
resolve(1);
} else {
// 跳去检查永久关闭订阅还是普通关闭订阅
guidSubscribeMessageAuthAfter(tmplIds, resolve, reject);
}
},
fail: res => {
console.log(res, "订阅,失败");
if (res.errCode == 20004) {
// console.log(res, 'fail:用户关闭了主开关,无法进行订阅,引导开启---');
guideOpenSubscribeMessage(tmplIds, resolve, reject);
}
return
}
})
} // 计算用户订阅消息的数量
function checkSubscribeAll(tmplIds, res) {
// 将accept的生成一个数组,判断申请的订阅消息是不是已经订阅消息的子集
let arr = [];
for (const key of Object.keys(res)) {
if (res[key] === 'accept') {
arr.push(key);
}
}
if (arr.length == tmplIds.length) {
console.log('订阅完毕')
return true
} else {
console.log('没订阅或者少订阅')
return false
} } // 检查用户是否授权完毕(检查时永久关闭还是普通关闭)
function guidSubscribeMessageAuthAfter(tmplIds, resolve, reject) {
uni.getSetting({
withSubscriptions: true,
success: async res => {
let {
authSetting = {},
subscriptionsSetting: { mainSwitch = false, itemSettings = {} } = {}
} = res;
if (Object.keys(itemSettings).length == 0) { // 这种情况是普通关闭
uni.showModal({
title: "温馨提示",
content: "同意订阅才能及时获知完成进度领取优惠",
confirmText: "重新订阅",
cancelText: "我再看看",
success: res => {
if (res.confirm) {
// 重新调起授权订阅
requestSubscribe(tmplIds, resolve, reject);
} else if (res.cancel) {
//没成功订阅,返回reject
reject(2);
}
}
});
} else { // 这种是订阅成功或永久关闭
let checkSubscribeBool = await checkSubscribeAll(tmplIds, itemSettings);
if (
authSetting["scope.subscribeMessage"] ||
(mainSwitch && checkSubscribeBool)
) {
//成功
console.log("用户手动开启同意了,订阅消息");
resolve(1);
} else {
//失败,永久关闭
guideOpenSubscribeMessage(tmplIds, resolve, reject);
}
}
}
});
} //引导用户重新授权(永久关闭的方法)
function guideOpenSubscribeMessage(tmplIds, resolve, reject) {
// console.log(resolve, reject, 'rescovavasr1')
uni.showModal({
title: "温馨提示",
content: "检测到您没有开启全部订阅消息的权限,是否去设置?",
success: res => { if (res.confirm) {
uni.openSetting({
success: res => {
// 在检查是否全部订阅完毕
guidSubscribeMessageAuthAfter(tmplIds, resolve, reject);
}
});
} else if (res.cancel) {
// console.log(resolve, reject, 'rescovavasr2')
uni.showModal({
title: "温馨提示",
content: "同意订阅才能及时获知完成进度领取优惠",
showCancel: false,
confirmText: "我知道了"
});
reject(2);
}
}
});
} // 比较版本号
function compareVersion(v2) {
let { SDKVersion: v1 } = uni.getSystemInfoSync();
v1 = v1.split(".");
v2 = v2.split(".");
const len = Math.max(v1.length, v2.length); while (v1.length < len) {
v1.push("0");
}
while (v2.length < len) {
v2.push("0");
} for (let i = 0; i < len; i++) {
const num1 = parseInt(v1[i]);
const num2 = parseInt(v2[i]); if (num1 > num2) {
return 1;
} else if (num1 < num2) {
return -1;
}
} return 0;
}

思路流程解析

这是第一步,封装promise,返回订阅成功和订阅失败的回调。以及判断版本号是否低于2.8.3,低于2.8.3是只能使用一个模板id的,可以考虑做兼容。这边内部原因就跳过不做订阅。然后走入主流程requestSubscribe(tmplIds, resolve, reject),带入模板id和俩个回调

   return new Promise((resolve, reject) => {
// 判断是否为微信小程序,不是的不做订阅进行跳过
let isWx = false;
// #ifdef MP-WEIXIN
isWx = true;
// #endif
if (!isWx) resolve(1);
console.log('进来了哟')
// 判断基本库是否在2.8.3,低于的暂时不做订阅进行跳过
const versionCan = compareVersion("2.8.3");
if (versionCan === -1) resolve(1);
// 主流程
requestSubscribe(tmplIds, resolve, reject)
})

这是第二步,订阅api。api走通就success,报错走fail。 主要看success,返回一个res,大家可以打印看看,里面就一个对象,键是id,订阅成功的值是accept,执行一波判断数量函数,符合长度说明用户全部订阅,就放行。

当然点击了“总是保持以上选择,不再询问”也是走到这里面,然后值都是订阅失败的。这里走去检查看看是否点击了“总是保持以上选择,不再询问”。

// 申请订阅功能
function requestSubscribe(tmplIds, resolve, reject) {
uni.requestSubscribeMessage({
tmplIds,
success: async res => {
// 检查订阅数量
let checkSubscribeBool = await checkSubscribeAll(tmplIds, res);
if (checkSubscribeBool) {
// 用户完成订阅
console.log("[用户完成订阅]")
resolve(1);
} else {
// 跳去检查永久关闭订阅还是普通关闭订阅
guidSubscribeMessageAuthAfter(tmplIds, resolve, reject);
}
},
fail: res => {
console.log(res, "订阅,失败");
if (res.errCode == 20004) {
// console.log(res, 'fail:用户关闭了主开关,无法进行订阅,引导开启---');
guideOpenSubscribeMessage(tmplIds, resolve, reject);
}
return
}
})
}

第三步 getsettingApi,检查用户是否点击了“总是保持以上选择,不再询问”,判断的条件就是返回的res有没有itemSettings,当然大家可以找俩种情况比对一下就知道了,永久关闭的是有的那个对象的,普通关闭是没有的。

判断这个目的,是可以直接在调起订阅界面。可以引导用户重新点击。当然如果调不起就走guideOpenSubscribeMessage函数。

// 检查用户是否授权完毕(检查时永久关闭还是普通关闭)
function guidSubscribeMessageAuthAfter(tmplIds, resolve, reject) {
uni.getSetting({
withSubscriptions: true,
success: async res => {
let {
authSetting = {},
subscriptionsSetting: { mainSwitch = false, itemSettings = {} } = {}
} = res;
if (Object.keys(itemSettings).length == 0) { // 这种情况是普通关闭
uni.showModal({
title: "温馨提示",
content: "同意订阅才能及时获知完成进度领取优惠",
confirmText: "重新订阅",
cancelText: "我再看看",
success: res => {
if (res.confirm) {
// 重新调起授权订阅
requestSubscribe(tmplIds, resolve, reject);
} else if (res.cancel) {
//没成功订阅,返回reject
reject(2);
}
}
});
} else { // 这种是订阅成功或永久关闭
let checkSubscribeBool = await checkSubscribeAll(tmplIds, itemSettings);
if (
authSetting["scope.subscribeMessage"] ||
(mainSwitch && checkSubscribeBool)
) {
//成功
console.log("用户手动开启同意了,订阅消息");
resolve(1);
} else {
//失败,永久关闭
guideOpenSubscribeMessage(tmplIds, resolve, reject);
}
}
}
});
}

第四步,用户永久关闭了订阅,我们可以用openSetting打开。这时候订阅消息是会出来没订阅的模板的。重新引导...这样就结束了这个封装啦!

//引导用户重新授权(永久关闭的方法)
function guideOpenSubscribeMessage(tmplIds, resolve, reject) {
// console.log(resolve, reject, 'rescovavasr1')
uni.showModal({
title: "温馨提示",
content: "检测到您没有开启全部订阅消息的权限,是否去设置?",
success: res => { if (res.confirm) {
uni.openSetting({
success: res => {
// 在检查是否全部订阅完毕
guidSubscribeMessageAuthAfter(tmplIds, resolve, reject);
}
});
} else if (res.cancel) {
// console.log(resolve, reject, 'rescovavasr2')
uni.showModal({
title: "温馨提示",
content: "同意订阅才能及时获知完成进度领取优惠",
showCancel: false,
confirmText: "我知道了"
});
reject(2);
}
}
});
}
 
 
 

大家觉得有什么奇怪的,欢迎和我讨论

 

微信小程序订阅的更多相关文章

  1. 微信小程序订阅消息,我踩过的坑都在这里了!

    旧的模板消息将在 2020 年 1 月 10 号全面下架,也就是今天,不过貌似现在还可以用!!!我已经改好了,只不过还没有上线,准备坚持到最后一天! 0.订阅消息 简单介绍一下订阅消息的特点: 用户授 ...

  2. 微信小程序订阅消息

    概述 消息能力是小程序能力中的重要组成,我们为开发者提供了订阅消息能力,以便实现服务的闭环和更优的体验. 订阅消息推送位置:服务通知 订阅消息下发条件:用户自主订阅 订阅消息卡片跳转能力:点击查看详情 ...

  3. 微信小程序订阅消息调研

    相关资料 背景:微信模板消息已正式下架,改为订阅消息,详情如下: 服务变更通知 订阅消息:订阅消息相关内容如下: 订阅消息 接口设计 获取接口访问凭证 :根据appId和secret获取接口访问凭证a ...

  4. 微信小程序、应用号、订阅号、服务号、企业号小总结

    微信小程序是现在微信推出的一个新的项目,但是很多人都不是很清楚微信小程序是怎么一回事,不明白到底怎样分别微信小程序和别的公众号.订阅号等的区别,那么让小编来给你介绍一下. 微信小程序目前是内侧阶段,是 ...

  5. 微信小程序如何发送订阅消息,正确姿势来了,建议收藏!

    小程序订阅消息公测已经有些日子,今天以世界上最好的语言(PHP)为例,说一下如何发送订阅消息. 1.订阅消息 其实如果用过模板消息的话,改用订阅消息挺简单的,看一下官方文档稍加摸索就能使用. 但是对于 ...

  6. 微信小程序的模板消息与小程序订阅消息

    小程序订阅消息 功能介绍 消息能力是小程序能力中的重要组成,我们为开发者提供了订阅消息能力,以便实现服务的闭环和更优的体验. 订阅消息推送位置:服务通知 订阅消息下发条件:用户自主订阅 订阅消息卡片跳 ...

  7. .netcore 3.1 C# 微信小程序发送订阅消息

    一.appsettings.json定义小程序配置信息 "WX": { "AppId": "wx88822730803edd44", &qu ...

  8. 来自于微信小程序的一封简讯

    9月21晚间,微信向部分公众号发出公众平台-微信应用号(小程序)的内测邀请,向来较为低调的微信在这一晚没人再忽视它了. 来自个人博客:Damonare的个人博客 一夜之间火了的微信应用号你真的知道吗? ...

  9. 张小龙宣布微信小程序1月9日发布,并回答了大家最关心的8个问题

    2016 年 12 月 28 日,张小龙在微信公开课 PRO 版的会场上,宣布了微信小程序的正式发布时间. 微信小程序将于 2017 年 1 月 9 号正式上线. 同时他解释称,小程序就像PC时代的网 ...

随机推荐

  1. 图论--最短路--Floyd(含路径输出)

    #include<bits/stdc++.h> using namespace std; #define INF 0x3f3f3f3f #define maxn 1005 int D[ma ...

  2. LCA 学习总结

    怎么说,LCA裸题直接套板子,大家都会做,这样的题没必要看,剩下的题发先LCA只是一个工具就像是搜索一样,只是一个工具而不是一种算法,所以借助这套工具在其图论问题如最长路,数据结构等问题上再去发挥作用 ...

  3. c++ concurrency

    c++的并发涉及到这么几个东西: std::thread std::mutex std::lock_guard std::lock 参考资料: http://en.cppreference.com/w ...

  4. awk调用date命令

    创建文件date.awk: $ == { cmd = "\"" while (cmd | getline line) { print line } close(cmd) ...

  5. 使用Proteus模拟操作HDG12864F-1液晶屏

    在Proteus中模拟了89C52操作HDG12864F-1液晶屏,原理图如下: 一.HDG12864F-1官网信息 该液晶屏是Hantronix的产品,官网上搜索出这个型号是系列型号中的一种,各种型 ...

  6. 使用Pandas读取CSV文件

    使用Pandas读取CSV文件 import pandas as pd csv_data = pd.read_csv('birth_weight.csv') # 读取训练数据 print(csv_da ...

  7. u-boot 源码分析(1) 启动过程分析

    u-boot 源码分析(1) 启动过程分析 文章目录 u-boot 源码分析(1) 启动过程分析 前言 配置 源码结构 api arch board common cmd drivers fs Kbu ...

  8. Java Stream 流如何进行合并操作

    1. 前言 Java Stream Api 提供了很多有用的 Api 让我们很方便将集合或者多个同类型的元素转换为流进行操作.今天我们来看看如何合并 Stream 流. 2. Stream 流的合并 ...

  9. 日志系列1——slf4j日志框架原理

    目录 1.前言 2.日志门面 3.日志库 4.日志适配器 5.日志库的选用 6.logback.xml 配置文件 1.前言 ​ 说到日志工具,日常工作或学习中肯定听过这些名词:log4j.logbac ...

  10. 在一段字符串中的指定位置插入html标签,实现内容修改留痕

    客户需求:实现内容修改留痕,并且鼠标移动到元素时,显示修改人和修改时间. (其实呢本人觉得这个如果是静态的页面,或者是后端拼接好的html,都很好实现,如果让前端动态实现就......) 前端实现的方 ...