微信小程序订阅消息工具封装,兼容一次性订阅和长期订阅

1.流程图

2.详细代码

js 复制代码
/**
 * @description Promise调用安全包装
 * @param {Promise} p
 * @returns {Promise}
 */
const $sync = (p) => p.then((d) => [null, d]).catch((e) => [e]);

/**
 * @name requestSubscribeMessage
 * @description 处理消息订阅,兼容一次性订阅和长期订阅
 * @param {String} templateId 消息模板id
 * @returns {Boolean} 是否订阅成功
 */
export async function requestSubscribeMessage(templateId) {
	// 检查之前是否授权
	const [, settingRes] = await $sync(checkSubscribeMessageAuth(templateId));

	// 之前已授权,返回true,执行业务逻辑
	if (settingRes) return true;

	// 之前未授权,请求授权
	const [, authRes] = await $sync(doRequestSubscribeMessage(templateId));

	// 用户同意授权,返回true,执行业务逻辑
	if (authRes) return true;

	// 用户拒绝授权,显示引导授权弹窗
	const [, guideRes] = await $sync(showAuthGuideModal());

	// 用户确认去修改配置,打开配置页面
	if (guideRes) {
		const [, openSettingRes] = await $sync(openSettingPage(templateId));

		// 用户在设置页面已授权,返回true,执行业务逻辑
		if (openSettingRes) return true;
	}

	// 默认返回false,代表用户未授权或授权失败
	return false;
}

// 检查订阅消息授权状态的函数
function checkSubscribeMessageAuth(templateId) {
	return new Promise((resolve, reject) => {
		wx.getSetting({
			withSubscriptions: true, // 注意:需要此参数来获取订阅消息状态
			success: (res) => {
				// 检查订阅消息设置是否存在
				if (!res.subscriptionsSetting) {
					reject(new Error("无法获取订阅消息设置"));
					return;
				}

				const { mainSwitch, itemSettings = {} } = res.subscriptionsSetting;

				// 首先检查订阅消息总开关是否开启
				if (!mainSwitch) {
					reject(new Error("订阅消息总开关未打开"));
					return;
				}

				// 如果提供了具体模板ID,检查其授权状态
				if (templateId) {
					const templateAuth = itemSettings[templateId];
					if (templateAuth !== "accept") {
						reject(new Error(`模板消息 ${templateId} 未授权`));
						return;
					}
				} else {
					reject(new Error("未提供模板id"));
				}

				// 授权检查通过
				resolve(itemSettings);
			},
			fail: (err) => {
				reject(err);
			},
		});
	});
}

// 请求订阅消息授权
function doRequestSubscribeMessage(templateId) {
	return new Promise((resolve, reject) => {
		wx.requestSubscribeMessage({
			tmplIds: [templateId], // 需要订阅的消息模板ID的数组
			success: (res) => {
				if (res[templateId] === "accept") {
					// 用户同意订阅
					resolve(true);
				} else {
					// 用户拒绝订阅、被后台封禁、因标题同名被后台过滤等
					reject(new Error("用户拒绝订阅"));
				}
			},
			fail: (err) => {
				reject(new Error("调起授权弹窗失败"));
			},
		});
	});
}

// 显示引导授权弹窗
function showAuthGuideModal() {
	return new Promise((resolve, reject) => {
		wx.showModal({
			title: "温馨提示",
			content: "为了您能及时收到重要通知,请开启消息订阅权限。",
			confirmText: "前往开启",
			success: (res) => {
				res.confirm ? resolve(true) : reject(new Error("用户取消"));
			},
			fail: () => {
				reject(new Error("打开引导弹窗失败"));
			},
		});
	});
}

// 打开设置页面
function openSettingPage(templateId) {
	return new Promise((resolve, reject) => {
		wx.openSetting({
			withSubscriptions: true,
			success: (res) => {
				// 用户从设置页面返回,再次检查授权状态
				const mainSwitch = res?.subscriptionsSetting?.mainSwitch || false;
				const itemSettings = res?.subscriptionsSetting?.itemSettings || {};
				if (mainSwitch && itemSettings[templateId] === "accept") {
					resolve(true);
				} else {
					reject(new Error("用户在设置页面未授权"));
				}
			},
			fail: (err) => {
				reject(new Error("打开设置页面失败"));
			},
		});
	});
}

3. 使用方法

js 复制代码
const templateId = "XXXXXX"; // 消息模板id
const result = await requestSubscribeMessage(templateId);
console.log(result ? "订阅成功" : "订阅失败");
相关推荐
说私域1 小时前
O2O行业风口下的运营策略与定制开发AI智能名片S2B2C商城小程序的应用研究
人工智能·小程序
是大刚啊13 小时前
微信小程序原生车牌输入器
微信小程序·小程序·tdesign·车牌号·车牌输入
韩立学长16 小时前
【开题答辩实录分享】以《宠物领养微信小程序》为例进行答辩实录分享
微信小程序·宠物
玖月晴空17 小时前
Uniapp 速查文档
前端·微信小程序·uni-app
2501_9159184118 小时前
App 上架苹果商店全流程详解 从开发者账号申请到开心上架(Appuploader)跨平台免 Mac 上传实战指南
macos·ios·小程序·uni-app·objective-c·cocoa·iphone
说私域19 小时前
定制开发开源AI智能名片S2B2C商城小程序中的羊群效应应用研究
人工智能·小程序
一匹电信狗19 小时前
【C++】红黑树详解(2w字详解)
服务器·c++·算法·leetcode·小程序·stl·visual studio
CsharpDev-奶豆哥20 小时前
微信小程序通过主键ID修改json数据的技术分享
微信小程序·小程序·json
汤姆yu20 小时前
基于微信小程序的防诈骗管理系统
微信小程序·小程序·防诈骗管理
2501_9160074720 小时前
从零开始学习iOS App开发:Xcode、Swift和发布到App Store完整教程
android·学习·ios·小程序·uni-app·iphone·xcode