微信小程序-云开发-给所有用户推送信息_云函数推送消息
目录结构
cloudfunctions/└── pushAllUsers/ ├── index.js // 云函数代码入口 └── package.json // 依赖声明(可选)
-
pushAllUsers/index.js
:云函数核心逻辑。 -
pushAllUsers/package.json
:声明依赖(例如wx-server-sdk
,如果你用的是 CloudBase 自带,则可以省略)。
1. package.json(可选)
如果你的环境需要自行安装 wx-server-sdk
,可以在 cloudfunctions/pushAllUsers/
下建一个 package.json
,示例内容如下:
{ \"name\": \"pushAllUsers\", \"version\": \"1.0.0\", \"description\": \"向 user 集合中所有用户推送消息\", \"main\": \"index.js\", \"dependencies\": { \"wx-server-sdk\": \"^2.6.0\" }}
然后在该目录下执行 npm install
,云开发控制台会自动上传依赖。如果你的环境已经内置 wx-server-sdk
,则可跳过。
2. 云函数入口 index.js
// 云函数入口文件const cloud = require(\'wx-server-sdk\');// 初始化云环境;如果希望使用当前同环境,请用 DYNAMIC_CURRENT_ENVcloud.init({ env: cloud.DYNAMIC_CURRENT_ENV});// 数据库引用const db = cloud.database();// 云函数主入口exports.main = async (event, context) => { // 1. 查询所有用户的 openid // 注意:每次最多可拿 100 条,如果 user 表数据量 > 100,需要做分页(这里示例简单,一次性取完) let allUsers = []; const batchSize = 100; let offset = 0; let hasMore = true; while (hasMore) { const usersRes = await db.collection(\'user\') .skip(offset) .limit(batchSize) .field({ openid: true }) // 只取 openid 字段即可 .get(); if (usersRes.data.length > 0) { allUsers = allUsers.concat(usersRes.data); offset += usersRes.data.length; } if (usersRes.data.length < batchSize) { hasMore = false; } } // 如果没有用户,则直接返回 if (allUsers.length === 0) { return { errCode: 1, errMsg: \'user 集合中没有数据\' }; } // 2. 循环推送消息给每个 openid // 这里示例使用「订阅消息」接口。如果要用模板消息或客服消息,可自行替换为 cloud.openapi.templateMessage.send 或 cloud.openapi.customerServiceMessage.send。 const results = []; for (let i = 0; i < allUsers.length; i++) { const openid = allUsers[i].openid; try { const sendRes = await cloud.openapi.subscribeMessage.send({ touser: openid, // 请将下面的 tplId 换成你自己在小程序后台/开发者工具里配置好的订阅消息模板 ID templateId: \'YOUR_SUBSCRIBE_TEMPLATE_ID\', page: \'pages/index/index\', // 点击消息后的跳转页面(可选) data: { // 这里示例一个简单的模板数据结构,根据你在微信公众平台/小程序后台配置的关键词进行填写 thing1: { value: \'你好,来自推送的提醒\' }, date2: { value: new Date().toLocaleDateString() }, thing3: { value: \'欢迎使用我们的服务\' } }, miniprogramState: \'formal\' // **注意:必须与线上/体验版/开发版一致**,否则推送会失败 }); results.push({ openid, success: true, res: sendRes }); } catch (err) { // 某些用户可能没有订阅授权或者模板 ID 配置错误,都会导致推送失败,记录一下 results.push({ openid, success: false, err: err }); } } // 3. 汇总返回推送结果 return { errCode: 0, errMsg: `尝试推送 ${allUsers.length} 位用户,成功/失败结果请查看 results`, results };};
代码详解
-
初始化云环境
cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV });
这样可以确保云函数运行在与当前环境一致的环境下,直接访问到相同的数据库/存储等。
-
分页获取所有用户
const batchSize = 100;let offset = 0;let hasMore = true;while (hasMore) { const usersRes = await db.collection(\'user\') .skip(offset) .limit(batchSize) .field({ openid: true }) .get(); // ...}
-
小程序数据库单次查询上限为 100 条,如果
user
集合数据量较大,需做分页。示例用skip
+limit
来分批取数据,直到不到 100 条为止。
-
-
调用订阅消息接口
await cloud.openapi.subscribeMessage.send({ touser: openid, templateId: \'YOUR_SUBSCRIBE_TEMPLATE_ID\', page: \'pages/index/index\', data: { … }, miniprogramState: \'formal\'});
-
touser
:要推送的用户openid
。 -
templateId
:在后台申请好的订阅消息模板 ID。 -
page
:点击消息后要打开的小程序页面路径。 -
data
:模板内容字段,字段名要和你在后台配置的关键词 ID 保持一致。 -
miniprogramState
:formal
/trial
/developer
,对应线上/体验/开发版,请填写与当前环境一致的值,否则推送会报错。
-
-
错误处理
-
对于没有订阅该模板、模板 ID 填写错误、用户转发设置拒绝接收等情况,会抛出异常。我们在
catch
中记录失败信息,最终把成功与失败都返回给调用方。
-
-
返回结果
最终返回一个对象,包括:-
errCode
: 0 表示代码正常跑完(即便有个别用户推送失败也算正常),1 表示user
集合中没有数据。 -
errMsg
: 简单说明。 -
results
: 一个数组,每一项对应一个用户的推送结果(success: true/false
、具体报错或返回结果),方便你在前端/管理后台做日志分析。
-
其他注意事项
-
模板消息 vs. 订阅消息
-
上述示例用的是「订阅消息」接口(
cloud.openapi.subscribeMessage.send
)。如果你更早期使用「模板消息」(templateMessage.send
)或「客服消息」,调用方式会略有不同。请根据自己的业务和微信官方文档选择对应接口。 -
订阅消息需用户先主动触发订阅,如在页面里调用
wx.requestSubscribeMessage
获取到tmplId
的同意。如果没有订阅授权,推送时会失败。
-
-
接口限制
-
每次调用
send
接口都会消耗调用次数配额,若用户量非常大,要控制好并发和速度,避免触发限频。同一个openid
一天只能推送一次订阅消息。 -
若需要批量推送给海量用户,建议结合消息队列或分片执行,或者做灰度分批推送。
-
-
环境配置
-
在微信开发者工具或云开发控制台,确认已经开通并配置好「订阅消息」或「模板消息」,将对应模板 ID 填入代码中。
-
miniprogramState
必须与实际环境对应:-
developer
:开发版 -
trial
:体验版 -
formal
:线上版
-
-
-
测试
-
本地用微信开发者工具云函数调试时,需要在真机/模拟器登录存在在
user
集合里的那些openid
,且该用户已经在小程序里订阅了相应模板。 -
调试时推荐先在
user
集合里写一个测试用户,然后只推送给这一个人,确认逻辑正确后再推送所有。
-
这样,一个完整的云函数就完成了。在「云开发 → 函数管理」中新建一个名为 pushAllUsers
的云函数,粘贴上述代码,记得替换 YOUR_SUBSCRIBE_TEMPLATE_ID
为你自己的订阅消息模板 ID。然后在需要推送的地方(比如后台定时触发、手动点击按钮等)调用此云函数即可。