uni-app中实现微信小程序/公众号订阅消息推送功能

请添加图片描述

‍ 热爱摄影的程序员
‍ 喜欢编码的设计师
擅长设计的剪辑师
‍ 一位高冷无情的编码爱好者
大家好,我是全栈 IT 工程师摘星人
欢迎分享 / 收藏 / 赞 / 在看!

开发业务时时常遇到需要向用户发送一些通知,如欠费通知、会员到期通知等等。
这里使用官方提供的 uni-subscribemsg 公共模块实现推送功能
uni-subscribemsg 公共模块可以方便开发者快速接入小程序订阅消息和微信公众号模板消息。

目前 uni-subscribemsg 支持:

  • 微信公众号模板消息
  • 微信小程序订阅消息

uni-subscribemsg 公共模块仅能在云函数/云对象内使用。
uni-subscribemsg 插件市场地址

获取订阅模板

如何申请微信小程序订阅消息

如果觉得模板不好用,可以自己添加提交审核成功后就可以使用。

进入 微信小程序后台 - 点击【订阅消息】- 点击【公共模板库】- 点击【选用】。

uni-app中实现微信小程序/公众号订阅消息推送功能_第1张图片

这里的【模板ID】后面会使用到。

点击详情来到模板详情页面,注意这里的字段对应关系,后面会进行赋值操作。

获取微信公众号模板消息

进入 微信公众号后台 - 点击【模板消息】- 点击【从历史模板库中添加】。

uni-app中实现微信小程序/公众号订阅消息推送功能_第2张图片

配置

uni-subscribemsg 自身没有配置文件,其依赖 uni-open-bridge 的配置。
这里简单列出如何配置使用的步骤,详细内容请点击:官网 uni-open-bridge

下载插件 uni-open-bridge 到项目中

uni-open-bridge 插件市场地址

uni-config-center 的 uni-id 下配置固定凭据

如果没有appid 和 secret ,需要先向微信申请

  • 微信小程序或微信公众号,向微信的公众平台申请 appid 和 secret 固定凭据。
  • 微信 App 或 PC 网页,向微信的开放平台申请 appid 和 secret 固定凭据。

然后在项目的 uniCloud/cloudfunctions/common/uni-config-center/uni-id/config.json 文件中配置

如果不需要定时刷新 access_token、ticket、也不需要通过外部系统访问凭据时可单独引入 uni-open-bridge-common,然后在云函数或云对象中直接调用相关方法

// uni-id-config 中 uni-id 示例代码
// uniCloud/cloudfunctions/common/uni-config-center/uni-id/config.json
{
  "dcloudAppid": "__UNI__xxxxxx", // 在项目的 manifest.json 中
  "mp-weixin": { // 微信小程序
    "tokenExpiresIn": 259200,
    "oauth": {
      "weixin": {
        "appid": "", // 微信公众平台申请的小程序 appid
        "appsecret": "" // 微信公众平台申请的小程序 secret
      }
    }
  },
  "web": {
    "oauth": {
      "weixin-h5": { //微信公众号h5
        "appid": "", // 微信公众平台申请的网页授权 appid
        "appsecret": "" // 微信公众平台申请的网页授权 secret
      }
    }
  }
}
  • 在 weixin-mp、weixin-h5 平台,通过调用 uni-open-bridge-common 的get相关方法可自动从微信服务器获取 access_token、encrypt_key、ticket 时需要用到配置文件中的 appid、appsecret

  • 暂时不需要配置 weixin-web、weixin-app、qq-mp、qq-app,后续支持这些平台时需要再次补充配置,但仍然可通过调用 uni-open-bridge-common 的方法传入设置值

注意:拷贝此文件内容时需要移除 注释。标准 json 不支持注释。在 HBuilderX 中可用多选 // 来批量移除注释。

uni-config-center 下配置 uni-open-bridge

在 uni-config-center 目录下新建子目录 uni-open-bridge, 新增 config.json,配置 dcloudAppid ,详情见下面的示例代码

// uni-id-config 中 uni-open-bridge 示例代码
// uniCloud/cloudfunctions/common/uni-config-center/uni-open-bridge/config.json
{
  "schedule": {
    "__UNI__xxxxxx": { // dcloudAppid, 需要和 `uni-config-center` uni-id中的配置一致
      "enable": true, // 任务全局开关,优先级最高
      "weixin-mp": { // 平台,目前仅支持 微信小程序、微信 H5,详情参见 https://uniapp.dcloud.net.cn/uniCloud/uni-open-bridge#platform
        "enable": true, // 当前平台任务开关
        "tasks": ["accessToken"] // 要执行的任务,微信小程序支持 accessToken
      },
      "weixin-h5": {
        "enable": false,
        "tasks": ["ticket"] // 支持微信 H5 ticket,因 ticker 依赖微信 H5 accessToken,内部自动先获取 accessToken。此处的 accessToken 和微信小程序的 accessToken 不是一个值
      }
    }
  },
  "ipWhiteList": ["0.0.0.0"] // 用于 URL化后 http 调用的服务器IP白名单,即指定ip的服务器才可以访问URL化后的`uni-open-bridge云对象
}

将插件上传到服务空间

云对象 uni-open-bridge 上传到服务空间后,会每隔一个小时自动运行一次,从微信服务器获取相关凭据并保存到数据库。

在数据库 opendb-open-data 中会看到数据。如开通 Redis 则在 Redis 的 uni-id 分组中查看。

uni-app中实现微信小程序/公众号订阅消息推送功能_第3张图片

如果异常,请在 uniCloud Web 控制台,找到云函数/云对象 uni-open-bridge 检查运行日志。很可能是第一步或第二步的配置出错了。

当然如果不需要定时任务,可以修改云对象 package.json 里的定时任务配置并重新上传。或在 uniCloud web 控制台修改定时任务。一般不推荐修改定时任务设置。

注意:
如需获取微信公众号 H5 平台的 access_token,需要处理服务空间的固定出口 IP 问题。因为需将 IP 白名单填入到微信公众平台,然后才能在从微信服务器拿到该凭据。uniCloud 中默认没有固定 IP,获取固定 IP 需另见文档 固定 IP。

关联依赖

笔者使用云对象操作,新建云对象后,右击【管理公共模块或扩展库依赖】,在弹出的窗口上将【uni-subscribemsg】钩上,点击确定。

uni-app中实现微信小程序/公众号订阅消息推送功能_第4张图片
uni-app中实现微信小程序/公众号订阅消息推送功能_第5张图片

编码部分

可以根据官方提供的 API 实现不同的订阅需求

发送微信小程序订阅消息

订阅消息顾名思义,需要先订阅,才可以发送消息,因此前端需要先让用户订阅。

订阅

调用 uni.requestSubscribeMessage API 即可让用户订阅。

uni.requestSubscribeMessage({
	tmplIds: ["xxx"], // 改成你的小程序订阅消息模板id
	success: () => {
		uni.showToast({
			title: "订阅成功",
			icon: "none"
		})
	}
});

云对象

const dcloudAppid = '__UNI__xxx'
// 引入uni-subscribemsg公共模块
const UniSubscribemsg = require('uni-subscribemsg');
module.exports = {
	_before: function() {},

	/**
	 * 获取openid
	 * @param {Object} code
	 */
	async getOpenid(code) {
		// 初始化实例
		let uniSubscribemsg = new UniSubscribemsg({
			dcloudAppid: dcloudAppid,
			provider: "weixin-mp",
		});
		return await uniSubscribemsg.getOpenid({
			code: code
		})
	},

	/**
	 * 发送订阅消息
	 * @param {Object} obj
	 */
	async sendSubscribeMessage(obj) {

		let {
			touser, // 接收者(用户)的 openid
			template_id, // 所需下发的订阅模板id
			page, // 点击模板卡片后的跳转页面,仅限本小程序内的页面。支持带参数,(示例index?foo=bar)。该字段不填则模板无跳转。
			data, // 模板内容,格式形如 { "key1": { "value": any }, "key2": { "value": any } }
			miniprogram_state, // 跳转小程序类型:developer为开发版;trial为体验版;formal为正式版;默认为正式版
		} = obj;
		// 初始化实例
		let uniSubscribemsg = new UniSubscribemsg({
			dcloudAppid: dcloudAppid,
			provider: "weixin-mp",
		});
		// 发送订阅消息
		let res = await uniSubscribemsg.sendSubscribeMessage({
			touser: touser,
			template_id: template_id,
			page: page, // 小程序页面地址
			miniprogram_state: miniprogram_state, // 跳转小程序类型:developer为开发版;trial为体验版;formal为正式版;默认为正式版
			lang: "zh_CN",
			data: data
		});
		return res;
	},
}

页面

<template>
	<view>
		<u-button @click="getOpenid">获取openid</u-button>
		<u-button @click="sendSubscribeMessage">订阅</u-button>
	</view>
</template>

<script>
	const mjchPush = uniCloud.importObject('mjch-subscribe-push')
	export default {
		data() {
			return {
				code: '',
				form: {
					touser: '', // 接收者(用户)的 openid
					template_id: 'xxx', // 所需下发的订阅模板id
					page: '/pages/index/index', // 点击模板卡片后的跳转页面,仅限本小程序内的页面。支持带参数,(示例index?foo=bar)。该字段不填则模板无跳转。
					data: {
						// 活动名称
						thing11: {
							value: "“舞蹈杯”全国舞蹈大赛"
						},
						// 活动内容
						thing4: {
							value: "点击即可抢红包,最高可得200元红包"
						},
						// 活动开始
						date2: {
							value: "2023-01-01 20:00"
						},
						// 活动截止
						date3: {
							value: "2023-01-31 20:00"
						},
						// 温馨提示
						thing5: {
							value: "活动即将开始,请做好准备"
						}
					}, // 模板内容,格式形如 { "key1": { "value": any }, "key2": { "value": any } }
					miniprogram_state: "developer", // 跳转小程序类型:developer为开发版;trial为体验版;formal为正式版;默认为正式版
				}
			};
		},
		async onLoad() {
			this.login()
		},
		methods: {
			/**
			 * 登录获取code
			 */
			async login() {
				let that = this
				uni.login({
					provider: 'weixin',
					success: function(res) {
						that.code = res.code
					}
				});

			},
			/**
			 * 根据code获取openid
			 */
			async getOpenid() {
				mjchPush.getOpenid(this.code).then(res => {
					const openid = res.openid
					const session_key = res.session_key

					this.form.touser = openid
				}).catch(err => {
					console.log(err);
				})
			},
			/**
			 * 返送订阅消息
			 */
			async sendSubscribeMessage() {
				mjchPush.sendSubscribeMessage(this.form).then(res => {
					console.log('res', res);
				}).catch(err => {
					console.log(err);
				})
			}
		}
	}
</script>

<style lang="scss">

</style>

请求参数:

属性 类型 必填 说明
touser string 接收者(用户)的 openid
template_id string 所需下发的订阅模板id
page string 点击模板卡片后的跳转页面,仅限本小程序内的页面。支持带参数,(示例index?foo=bar)。该字段不填则模板无跳转
miniprogram_state string 跳转小程序类型:developer为开发版;trial为体验版;formal为正式版;默认为正式版
lang string 进入小程序查看”的语言类型,支持zh_CN(简体中文)、en_US(英文)、zh_HK(繁体中文)、zh_TW(繁体中文),默认为
data string 模板内容,格式形如 { “key1”: { “value”: any }, “key2”: { “value”: any } }的object

返回参数:

参数 说明
errCode 为0代表发送成功,其他均为失败,与微信公众号官方返回码一致 微信公众号全局返回码
errMsg 失败后的提示 ,与微信公众号官方错误提示一致

发送微信公众号模板消息

// 引入uni-subscribemsg公共模块
const UniSubscribemsg = require('uni-subscribemsg');
// 初始化实例
let uniSubscribemsg = new UniSubscribemsg({
	dcloudAppid: "你项目的dcloudAppid",
	provider: "weixin-h5", // 注意,这里是weixin-h5
});
// 发送模板消息
let res = await uniSubscribemsg.sendTemplateMessage({
	touser: "用户openid",
	template_id: "消息模板id",
	url: "https://uniapp.dcloud.net.cn", // 用户点击消息后跳转的链接地址
	data: {
		first: {
			value: "您购买的套餐已到期!",
			color: "#666666"
		},
		keyword1: {
			value: "[email protected]",
			color: "#666666"
		},
		keyword2: {
			value: "阿里云空间",
			color: "#666666"
		},
		keyword3: {
			value: "2023-12-21 15:30:20",
			color: "#666666"
		},
		remark: {
			value: "请及时续费",
			color: "#666666"
		}
	}
});

请求参数:

参数 类型 必填 说明
touser String 接收者openid
template_id String 模板ID
url String 模板跳转链接(海外帐号没有跳转能力)
miniprogram Object 跳小程序所需数据,不需跳小程序可不用传该数据
– appid String 所需跳转到的小程序appid(该小程序 appid 必须与发模板消息的公众号是绑定关联关系,暂不支持小游戏)
– pagepath String 所需跳转到小程序的具体页面路径,支持带参数,(示例index?foo=bar),要求该小程序已发布,暂不支持小游戏
data Object 模板数据
color String 模板内容字体颜色,不填默认为黑色
client_msg_id String 防重入id。对于同一个openid + client_msg_id, 只发送一条消息,10分钟有效,超过10分钟不保证效果。若无防重入需求,可不填

返回参数:

参数 说明
errCode 为0代表发送成功,其他均为失败,与微信公众号官方返回码一致 微信公众号全局返回码
errMsg 失败后的提示 ,与微信公众号官方错误提示一致

微信小程序转发公众号模板消息

uni-subscribemsg 版本需 ≥ 1.0.2

// 引入uni-subscribemsg公共模块
const UniSubscribemsg = require('uni-subscribemsg');
// 初始化实例
let uniSubscribemsg = new UniSubscribemsg({
	dcloudAppid: "你项目的dcloudAppid",
	provider: "weixin-mp", // 注意,这里是weixin-mp
});
// 发送模板消息
let res = await uniSubscribemsg.sendTemplateMessage({
	touser: "用户openid",
	template_id: "消息模板id",
	appid: "公众号appid",
	miniprogram: {
		appid: "小程序appid",
		pagepath: "pages/index/index", // 小程序页面
	},
	data: {
		first: {
			value: "您购买的套餐已到期!",
			color: "#666666"
		},
		keyword1: {
			value: "[email protected]",
			color: "#666666"
		},
		keyword2: {
			value: "阿里云空间",
			color: "#666666"
		},
		keyword3: {
			value: "2023-12-21 15:30:20",
			color: "#666666"
		},
		remark: {
			value: "请及时续费",
			color: "#666666"
		}
	}
});

请求参数

参数 类型 必填 说明
touser String 接收者openid(用户在该小程序下对应的openid)
appid String 微信公众号appid(不传会自动从uni-id配置中获取)
miniprogram Object 跳小程序所需数据,不需跳小程序可不用传该数据
appid String 所需跳转到的小程序appid(该小程序 appid 必须与发模板消息的公众号是绑定关联关系,暂不支持小游戏)
pagepath String 所需跳转到小程序的具体页面路径,支持带参数,(示例index?foo=bar),要求该小程序已发布,暂不支持小游戏
data Object 模板数据
color String 模板内容字体颜色,不填默认为黑色

返回参数:

参数 说明
errCode 为0代表发送成功,其他均为失败,与微信公众号官方返回码一致 微信公众号全局返回码
errMsg 失败后的提示 ,与微信公众号官方错误提示一致

注意:公众号和小程序无需绑定在同一个开放平台下,但需要同时满足下面的3个要求。

  1. 公众号必须和小程序是同主体
  2. 小程序关联了公众号
  3. 该用户关注了公众号

检测用户是否关注了公众号

uni-subscribemsg 版本需 ≥ 1.0.1

// 引入uni-subscribemsg公共模块
const UniSubscribemsg = require('uni-subscribemsg');
// 初始化实例
let uniSubscribemsg = new UniSubscribemsg({
	dcloudAppid: "你项目的dcloudAppid",
	provider: "weixin-h5",
});
// 检测用户是否关注了公众号
let res = await uniSubscribemsg.getSubscribeUserInfo({
	openid
});

请求参数:

参数 类型 必填 说明
openid String 用户openid

返回参数:

参数 说明
errCode 为0代表发送成功,其他均为失败,与微信公众号官方返回码一致 微信公众号全局返回码
errMsg 失败后的提示,与微信公众号官方错误提示一致
subscribe true 已关注公众号 false 未关注公众号
result 用户基本信息返回值

你可能感兴趣的:(编程干货,微信小程序,uni-app,小程序)