# 消息推送

微信云开发资源共享给公众号后,支持公众号在微信云开发资源中使用云函数/云托管服务配置消息推送以接收用户发送给当前公众号的消息及开发者需要的事件推送。

接入微信公众号消息推送服务,在云开发中可以2种方式选择其一:

  1. 云函数接收消息推送
  2. 云托管服务接收消息推送(不适用于微信云托管https://cloud.weixin.qq.com/cloudrun)

# 云函数接收消息推送

需开发者工具版本至少 1.05.2103190

被小程序环境共享的公众号可以使用该小程序的云函数接收消息推送,目前仅支持客服消息推送。

接入步骤如下:

  1. 登录微信云开发控制台中填写配置并上传
  2. 云函数中处理消息

# 第一步:开发者工具云开发控制台中增加配置

前往路径“「公众号网页」-「云开发」-「更多」-「环境共享」-「消息推送」”,选择推送模式为云函数; 添加消息推送配置。消息类型对应收包的 MsgType,事件类型对应收包的 Event,同一个 <消息类型, 事件类型> 二元组只能推到一个环境的一个云函数。例如客服消息文本消息对应的就是消息类型为 text,事件类型为空。具体值请查看各个消息的消息格式。 多个消息类型、事件类型多次添加消息推送配置即可。如有多个小程序授权环境共享,消息推送也支持配置多个小程序的多个环境接收。

注意:如在云函数中配置了某个类型的消息,该类型消息将不再推送至“微信公众平台-开发-基本配置-服务器配置”中配置的域名。

# 第二步:云函数中处理消息

云函数被触发时,其 event 参数即是接口所定义的 JSON 结构的对象(统一 JSON 格式,不支持 XML 格式)。

以文本消息为例,公众号接收到用户发送的消息时,event 结构如下:

{
  "FromUserName": "ohl4L0Rnhq7vmmbT_DaNQa4ePaz0",
  "ToUserName": "wx3d289323f5900f8e",
  "Content": "测试",
  "CreateTime": 1555684067,
  "MsgId": "49d72d67b16d115e7935ac386f2f0fa41535298877_1555684067",
  "MsgType": "text"
}

公众号可被动回复用户消息,一个简单的接收到消息后统一回复 “收到” 的示例如下:

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

cloud.init({
  // API 调用都保持和云函数当前所在环境一致
  env: cloud.DYNAMIC_CURRENT_ENV
})

// 云函数入口函数
exports.main = async (event, context) => {
  console.log(event)
  return {
    ToUserName: event.FromUserName,
    FromUserName: event.ToUserName,
    CreateTime: Date.parse(new Date())/1000,
    MsgType: 'text',
    Content: '收到!'
  }
}

# 云托管接收消息推送 (不适用于微信云托管https://cloud.weixin.qq.com/cloudrun)

被小程序环境共享的公众号可以使用该小程序的云托管服务接收消息推送,只需配置一个云托管服务即可支持所有类型的消息推送。

接入步骤如下:

  1. 登录云开发控制台中填写配置
  2. 云托管服务中处理消息

# 第一步 云开发控制台填写配置

前往路径“「公众号网页」-「云开发」-「更多」-「环境共享」-「消息推送」”,选择推送模式为云托管; 点击确定,选择目标云开发环境、填写对应的云托管服务路径(路径可前往“云托管”-“服务列表”-“路径字段”中复制)、选择推送类型; 配置完成后,该小程序的云托管服务即可接收当前公众号下所有类型消息推送。

# 第二步 云托管服务中处理消息

下面的例子展示在环境共享下公众号如何使用云托管服务实现被动消息回复。

const express = require('express')
const bodyParser = require('body-parser')

const PORT = process.env.PORT || 80
const HOST = '0.0.0.0'

// App
const app = express()

app.use(bodyParser.raw())
app.use(bodyParser.json({}))
app.use(bodyParser.urlencoded({ extended: true }))

app.all('/', async (req, res) => {
  res.send({
    ToUserName: req.body.FromUserName,
    FromUserName: req.body.ToUserName,
    CreateTime: Date.parse(new Date())/1000,
    MsgType: 'text',
    Content: 'Hello!'
  })
});

app.listen(PORT, HOST)
console.log(`Running on http://${HOST}:${PORT}`)