云调用subscribeMessage.send出现如下问题如何解决?
一、云调用错误如下:
Error: errCode: -501007 invalid parameters | errMsg: subscribeMessage.send:fail missing wxCloudApiToken
二、附源码:
async function batchSend(event) {
const { messages } = event
console.info({event: JSON.stringify(event)})
console.info('处理订阅消息', messages.length)
// 循环消息列表
const sendPromises = messages.map(async message => {
let { touser, page, data, templateId } = message
// 发送订阅消息
await cloud.openapi.subscribeMessage.send({
touser,
templateId,
page,
data,
})
});
await Promise.all(sendPromises)
}
三、现象描述:
- 直接云端测试云函数5 次, 结果:失败、成功、失败、成功、成功。
- 一旦出错后,会一直报上述错误。需要调用其他云调用成功一次,才可以恢复。恢复后又是间歇性失败。
- 其他云调用,如“cloud.openapi.wxacode.getUnlimited”从不会失败。
总结:这个问题已经追踪了两天了,仍然没有找到必现的规律,失败的概率很大,很容易复现。跟其他人说的miniprogram_statestring参数也无关,因为我一直没有传此参数,默认值为formal。
2 回复
已找到问题:
云调用openapi的触发,必须用云函数触发。如果自己的逻辑是指定条件触发,可以用云函数的定时器触发。
我之前出错是因为:由外部的一套 node服务,用“@cloudbase/node-sdk”包触发的云函数。
我目前的技术架构是:
- 部分逻辑用云函数实现,部分逻辑在一个 node 的服务中实现。
- 模板消息逻辑:触发指定条件后,由云函数批量塞到rocketmq消息队列中。然后在 node 中按一定的速度操作消息队列并发送。(为了削峰填谷并维护模板消息的状态)
- 如果在 node 中用 http 接口发送,需要自己维护 access_token,再加上我做的消息队列服务这块要同时服务很多小程序,会比较复杂。因此把消息内容发回指定的小程序云函数发送,这样就不用维护多套access_token。
结论:
不知道云函数为什么要做这个限制。我目前准备把发送订阅消息,全部在 node 中用 http 接口发送。
大家有什么其他的方案,也可以给我留言。