微信小程序:订阅消息

2021-08-28  本文已影响0人  我的小小笔尖
1. 什么是小程序订阅消息

用户在小程序页面点击按钮,确认订阅消息,小程序可以按照消息模板格式在后续的任意时间发送消息给用户。

小程序订阅消息分两种:
一种是一次性订阅,一般都可以使用该服务,缺点就是用户订阅一次,小程序才能发送一次消息。
另一种是长期订阅,比较难,需要申请,只针对特定几个行业或分类的小程序。

2. 实现步骤(示例:一次性订阅)

1)在官网的小程序管理页面申请订阅消息
你会得到:模板ID,详细内容数据格等信息。

2)page.wxml 做个按钮,让用户订阅消息

<button type="primary" bindtap="onSubscribe">订阅次日训练通知</button>

3)page.js 中调用 wx.requestSubscribeMessage 获取用户订阅

  onSubscribe: function (e) {
    var that = this
    let page = this.data.page
    let noticeData = {"thing1": {"value": this.data.noticeTitle},"thing2": {"value": this.data.noticeContent}}
    let templateId = '......' // 敏感信息省略,请用自己的模板ID
    wx.requestSubscribeMessage({
      tmplIds: [templateId],
      success (res) {
        // 申请订阅成功,将订阅信息调用云函数存入云开发数据
        if (res.errMsg === 'requestSubscribeMessage:ok') {
          // res[templateId]: 'accept'、'reject'、'ban'、'filter'
          if(res[templateId] == 'accept') {            
            that.saveSubscribeInfo(page, noticeData, templateId)
          }
        }
      }
    })
  },

注意 noticeData 的数据格式

4)再将用户订阅的信息保存到云数据库中

  // 保存订阅信息
  saveSubscribeInfo(page, noticeData, templateId) {   
    // 调用云函数
    wx.cloud.callFunction({
      name: 'v4_subscriber',
      data: {
        action: 'saveSubscribeInfo',
        page: page,
        data: noticeData,
        templateId: templateId,
      },
      success: res => {
        console.warn('[云函数] [v4_subsriber] saveSubscribeInfo 调用成功:', res)
        wx.showToast({
          icon: 'none',
          title: '订阅成功',
        })
      },
      fail: err => {
        console.error('[云函数] [v4_subsriber] saveSubscribeInfo 调用失败:', err)
      },
      complete: () => {
      }
    })
  },

云函数中的保存订阅消息代码

async function saveSubscribeInfo(openid, event) {
  try {
    return await db.collection('v4_trainingnotice').add({
      data: {
        touser: openid,                   // 发送对象
        page: event.page,                 // 订阅消息卡片点击后会打开小程序的哪个页面
        data: event.data,                 // 订阅消息的数据
        templateId: event.templateId,     // 订阅消息模板ID
        done: false,                      // 消息发送状态设置为 false-未发送,true-已发送
        createDate: new Date(),           // 创建时间
      }
    })
  } catch (e) {
    console.error(e)
  }
}

5)再创建一个send云函数
功能:从云数据库中获取待发送的消息,逐个发送给订阅消息的用户

// 云函数入口文件
const cloud = require('wx-server-sdk')

cloud.init({
  traceUser: true,
  env: '......' // 敏感信息省略,请用自己的云环境
})

const db = cloud.database()
const _ = db.command

// 云函数入口函数
exports.main = async (event, context) => {
  try {
    // 从云开发数据库中查询等待发送的消息列表
    const messages = await db
      .collection('v4_trainingnotice')
      // 查询条件这里做了简化,只查找了状态为未发送的消息
      .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('v4_trainingnotice')
          .doc(message._id)
          .update({
            data: {
              done: true,
              updateDate: new Date(),
            },
          });
      } catch (e) {
        return e;
      }
    });

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

6)send云函数自己怎么自动执行呢?答案:定义触发器
云函数的 config.json 文件中定义触发器

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

代码表示再每天的21点30分0秒,调用send云函数。
用户就可以收到订阅的消息啦!

结束

上一篇下一篇

猜你喜欢

热点阅读