评论

实战分享: 小程序云开发玩转订阅消息(二)

微信最新推出的小程序订阅消息给小程序开发者带来了更好的触达用户的能力,我们今天会我们会利用小程序·云开发进行一个小程序中实现订阅开课提醒的实战,帮助大家了解如何基于小程序·云开发快速接入小程序订阅消息

这是实战分享: 小程序云开发玩转订阅消息的第二部分

第一部分链接 《实战分享: 小程序云开发玩转订阅消息(一)》

将订阅消息存入云开发数据库

接下来我们创建一个云函数 subscribe ,这个云函数的作用是将用户的订阅信息存入云开发数据库的集合 messages 中,等待将来需要通知用户时进行调用。

在微信开发者工具的云开发面板中创建数据库集合 messages


微信开发者工具新增数据库集合


创建一个 subscribe 云函数,在云函数中我们将小程序端发送过来的课程订阅信息,存储在云开发数据库集合中,开发完成后,在微信开发者工具中右键上传并部署云函数。

cloudfunctions/subscribe/index.js

const cloud = require('wx-server-sdk');
cloud.init();
const db = cloud.database();

exports.main = async (event, context) => {
 try {
   const {OPENID} = cloud.getWXContext();
   // 在云开发数据库中存储用户订阅的课程
   const result = await db.collection('messages').add({
     data: {
       touser: OPENID, // 订阅者的openid
       page: 'index', // 订阅消息卡片点击后会打开小程序的哪个页面
       data: event.data, // 订阅消息的数据
       templateId: event.templateId, // 订阅消息模板ID
       done: false, // 消息发送状态设置为 false
     },
   });
   return result;
 } catch (err) {
   console.log(err);
   return err;
 }
};

利用定时触发器来定期发送订阅消息

接下来我们需要实现一个定时执行的云函数send,来检查数据库中是否有需要发送给用户的订阅消息。如果有需要发送的订阅消息,会通过云调用 cloud.openapi.subscribeMessage.send 将订阅消息发送给用户。

创建一个名叫 send 的云函数,首先要配置云函数,在 config.json 的 permissions 中新增 subscribeMessage.send的云调用权限,然后新增一个 sendMessagerTimer 的定时触发器,定时触发器的语法和 linux 的 crontab 类似,比如,我们配置的 "0 * * * * * *" 代表每分钟执行一次云函数。

cloudfunctions/send/config.json

{
 "permissions": {
   "openapi": ["subscribeMessage.send"]
 },
 "triggers": [
   {
     "name": "sendMessagerTimer",
     "type": "timer",
     "config": "0 * * * * * *"
   }
 ]
}

接下来是实现发送订阅消息的云函数,这个云函数会从云开发数据库集合messages中查询等待发送的消息列表,检查数据库中是否有需要发送给用户的订阅消息,发送条件可以根据自己的业务实现,比如开课提醒可以根据课程开课日期来检查是否需要发送订阅消息,在我们下面的代码示例里做了简化,筛选条件只检查了状态为未发送。

查询到待发送的消息列表之后,我们会循环消息列表,依次发送每条订阅消息,发送成功后将数据库中消息的状态改为已发送。

cloudfunctions/send/index.js

const cloud = require('wx-server-sdk');

exports.main = async (event, context) => {
 cloud.init();
 const db = cloud.database();

 try {
   // 从云开发数据库中查询等待发送的消息列表
   const messages = await db
     .collection('messages')
     // 查询条件这里做了简化,只查找了状态为未发送的消息
     // 在真正的生产环境,可以根据开课日期等条件筛选应该发送哪些消息
     .where({
       done: false,
     })
     .get();

   // 循环消息列表
   const sendPromises = messages.data.map(async message => {
     try {
       // 发送订阅消息
       await cloud.openapi.subscribeMessage.send({
         touser: message.touser,
         page: message.page,
         data: message.data,
         templateId: message.templateId,
       });
       // 发送成功后将消息的状态改为已发送
       return db
         .collection('messages')
         .doc(message._id)
         .update({
           data: {
             done: true,
           },
         });
     } catch (e) {
       return e;
     }
   });

   return Promise.all(sendPromises);
 } catch (err) {
   console.log(err);
   return err;
 }
};

最终效果


开课提醒订阅消息截图


源代码

https://github.com/binggg/tcb-subscribe-demo[3]

参考资料


[1]

注册小程序帐号: https://tencentcloudbase.github.io/2019-09-03-wx-dev-guide-register/

[2]

开通云开发服务: https://tencentcloudbase.github.io/2019-09-03-wx-dev-guide-service/

[3]

https://github.com/binggg/tcb-subscribe-demo: https://github.com/binggg/tcb-subscribe-demo



最后一次编辑于  10-23  
点赞 6
收藏
评论

4 个评论

  • 悟
    11-29

    按照上面的写的,为什么我收不到发送的订阅通知?我用的测试版本,和小程序是不是发布有关系吗?

    11-29
    赞同
    回复 7
    • Booker Zhao(赵兵)
      Booker Zhao(赵兵)
      11-29
      使用了开发版的开发者工具么
      11-29
      回复
    • 悟
      11-29回复Booker Zhao(赵兵)
      使用的这个
      11-29
      回复
    • 悟
      11-29回复Booker Zhao(赵兵)
      是开发版的工具
      11-29
      回复
    • Booker Zhao(赵兵)
      Booker Zhao(赵兵)
      11-29回复
      看看日志,有没有报错啥的
      11-29
      回复
    • 悟
      11-29回复Booker Zhao(赵兵)
      没有任何错误,也能订阅成功,就是没有接到服务通知。
      11-29
      回复
    查看更多(2)
  • Seven Jiao
    Seven Jiao
    11-08

    一直提示Error: errCode: 40037  | errMsg: openapi.subscribeMessage.send:fail invalid template_id hint: [TRdd_05638653] 无效的模板ID,确认模板ID无误。

    11-08
    赞同
    回复
  • 兰永懿
    兰永懿
    11-07


    用这个版本,  稳定版的 定时器 有问题  , 开发板的 小程序功能可以正常使用


    11-07
    赞同
    回复
  • 未来_加油
    未来_加油
    11-07

    老哥,你这样测试成功了,我按照文章说的步骤进行,最后日志打印"errCode":-501007,"errMsg":"subscribeMessage.send:fail Invalid request param",请问一下应该怎样解决

    11-07
    赞同
    回复 2
    • Booker Zhao(赵兵)
      Booker Zhao(赵兵)
      11-07
      你有使用 nightly 开发者工具么
      11-07
      回复
    • 未来_加油
      未来_加油
      11-13回复Booker Zhao(赵兵)
      已更换,谢谢老哥
      11-13
      回复