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

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 ? "订阅成功" : "订阅失败");
相关推荐
李纲明17 小时前
微信小程序次卡跨店对不上账或前台随手改余次:先核流水只增不改与统一日切,再查冲正权限与总部只读
微信小程序·devdiy·核销流水·跨店次卡·日切对账·冲正权限·总部只读
李纲明20 小时前
微信小程序维修拆机后口头加价或未确认就开工:先核验机快照与报价确认,再查补充报价与取机核验
微信小程序·devdiy·维修验机·报价确认·报价快照·补充报价·取机核验
wx1qq1com21 小时前
一桩带几台车:共享租赁桩位配比、取电与结算闭环设计
物联网·微信小程序·小程序
李纲明1 天前
微信小程序场地长租月底对不上或口头占场撞场:先核合约预约与核销流水出账,再查附加费与转租归属
微信小程序·devdiy·场地长租·月结账单·核销流水·附加费·转租归属
2401_879692511 天前
微信小程序照相与摄像功能实现——chooseImage 与 chooseVideo 详解
微信小程序·小程序·notepad++
律宏阔2 天前
微信小程序 + Taro + TDesign 去掉 [&&&],让普通 Tailwind 类接管局部样式
前端·微信小程序·taro
律宏阔2 天前
微信小程序 + Taro + 多语言实现与国际化检查实录
前端·微信小程序·taro
李纲明3 天前
微信小程序 getSystemInfo 提示已废弃、屏幕高度算错胶囊还对不齐?getWindowInfo 和 getDeviceInfo 怎么接才稳
javascript·微信小程序·小程序·小程序开发·devdiy
dreams_dream3 天前
微信小程序-使用npm包
微信小程序·小程序·npm
L1mbo3 天前
Lite模式 缓解微信开发者工具卡顿,附 uni-app 实践方案
前端·微信小程序