由于微信官方政策调整,模板消息已经升级为“订阅消息”,原来的模板消息需要用户在小程序内产生特定行为(如支付、提交表单)后才能触发,而订阅消息则允许用户主动订阅,之后开发者可以在一定时间内(通常为30天)向用户推送服务通知。

我将为你详细讲解如何使用 “订阅消息” 来实现类似模板消息的功能。


整体流程概览

  1. 获取模板ID:在微信公众平台申请并添加你需要的消息模板。
  2. 获取用户授权:在小程序中引导用户同意订阅,并获取 subscription item(订阅消息凭证)。
  3. 后端服务调用API:你的服务器使用 subscription item 和模板ID,向微信服务器发送请求,推送消息。
  4. 用户接收消息:用户在微信的“服务通知”中收到推送的消息。

详细步骤

第一步:申请订阅消息模板

这是所有工作的前提,你需要先在微信公众平台后台配置好消息模板。

  1. 登录微信公众平台

  2. 进入模板库

    • 在左侧菜单栏找到 「开发」 -> 「开发管理」 -> 「订阅消息」
    • 点击进入,然后点击 「公共模板库」
  3. 选择并添加模板

    • 在模板库中,你可以根据行业和应用场景搜索模板,搜索“订单支付成功”、“物流更新”等。
    • 找到合适的模板后,点击右侧的 「选用」 按钮。
    • 选中模板后,点击页面底部的 「添加」 按钮。
  4. 记录模板ID

    • 添加成功后,模板会出现在你的 「我的模板」 列表中。
    • 复制这个模板的 「模板ID」,这个ID在后续的API调用中会用到。

示例模板结构: 一个模板通常包含一些固定的文本和可替换的关键词(用 包围),一个“订单支付成功”的模板可能如下:

{{thing1.DATA}},您的订单{{number2.DATA}}已支付成功,金额为{{amount3.DATA}}元,{{phrase4.DATA}}。

这里的 thing1, number2, amount3, phrase4 就是模板的关键词,你在发送消息时需要提供对应的值。


第二步:在小程序中获取用户授权

用户必须主动同意订阅,你才能给他发消息,这个过程通常在一个用户触发的操作之后进行,比如点击“订阅通知”按钮。

  1. 前端代码 (WXML): 创建一个按钮来触发订阅请求。

    <!-- pages/index/index.wxml -->
    <button bindtap="requestSubscribe">订阅订单支付通知</button>
  2. 前端代码 (JS): 在页面的 JS 文件中,调用 wx.requestSubscribeMessage API 来请求用户授权。

    // pages/index/index.js
    Page({
      data: {},
      // 请求订阅消息
      requestSubscribeMessage() {
        // 1. 定义你想要订阅的模板ID列表
        const templateIds = ['你的模板ID_1', '你的模板ID_2']; // 可以一次请求多个
        // 2. 调用API请求订阅
        wx.requestSubscribeMessage({
          tmplIds: templateIds,
          success: (res) => {
            console.log('订阅请求成功', res);
            // res 返回一个对象,key 是 tmplId,value 是 'accept' 或 'reject'
            //  { '你的模板ID_1': 'accept', '你的模板ID_2': 'reject' }
            if (res['你的模板ID_1'] === 'accept') {
              wx.showToast({
                title: '订阅成功!',
                icon: 'success'
              });
              // 用户同意后,通常会将这个凭证传给后端保存,以便后续使用
              // 这里为了演示,我们直接调用发送函数
              this.sendSubscriptionMessage();
            } else {
              wx.showToast({
                title: '您拒绝了订阅',
                icon: 'none'
              });
            }
          },
          fail: (err) => {
            console.error('订阅请求失败', err);
            wx.showToast({
              title: '订阅失败',
              icon: 'none'
            });
          }
        });
      },
      // 调用后端API发送订阅消息
      sendSubscriptionMessage() {
        wx.showLoading({
          title: '发送中...',
        });
        // 调用我们自己写的后端接口
        wx.request({
          url: 'https://你的域名.com/api/send-subscribe-message', // 替换成你的后端接口地址
          method: 'POST',
          data: {
            // 这里可以传一些用户信息,比如订单号、用户openid等
            orderNo: 'DD202510270001',
            // 用户openid,通常是从全局变量或登录接口获取
            openid: '用户的openid' 
          },
          success: (res) => {
            wx.hideLoading();
            if (res.data.code === 0) {
              wx.showToast({
                title: '消息发送成功!',
                icon: 'success'
              });
            } else {
              wx.showToast({
                title: res.data.msg || '发送失败',
                icon: 'none'
              });
            }
          },
          fail: (err) => {
            wx.hideLoading();
            console.error('调用后端接口失败', err);
            wx.showToast({
              title: '网络错误',
              icon: 'none'
            });
          }
        });
      }
    });

第三步:后端服务调用API发送消息

这是核心步骤,你的服务器需要使用微信提供的 subscribeMessage.send API 来实际推送消息。

API信息

  • 请求地址https://api.weixin.qq.com/cgi-bin/subscribe/send?access_token=ACCESS_TOKEN
  • 请求方式POST
  • 请求头Content-Type: application/json

准备工作: 你的后端需要能够获取到 access_tokenaccess_token 是调用微信接口的全局凭证,有效期为2小时,需要缓存并定时刷新。

  • 获取 access_token 的API:https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

请求体示例 (JSON)

{
  "touser": "用户的openid",
  "template_id": "你的模板ID",
  "data": {
    "thing1": {
      "value": "微信小店"
    },
    "number2": {
      "value": "123456789"
    },
    "amount3": {
      "value": "128.00"
    },
    "phrase4": {
      "value": "欢迎再次光临"
    }
  }
}

参数说明

  • touser:接收消息用户的 openid
  • template_id:你在第一步申请到的模板ID。
  • data:一个对象,键是模板中的关键词(如 thing1),值是一个包含 value 属性的对象,value 就是你想替换上去的具体内容。

后端代码示例 (Node.js/Express)

// 引入依赖
const axios = require('axios');
const crypto = require('crypto');
// 微信小程序的 AppID 和 AppSecret
const APP_ID = '你的小程序AppID';
const APP_SECRET = '你的小程序AppSecret';
// 用于存储 access_token
let accessToken = '';
let tokenExpireTime = 0;
// 获取 access_token 的函数
async function getAccessToken() {
  const currentTime = Date.now();
  // token 存在且未过期,直接返回
  if (accessToken && currentTime < tokenExpireTime) {
    return accessToken;
  }
  console.log('正在获取新的 access_token...');
  try {
    const response = await axios.get('https://api.weixin.qq.com/cgi-bin/token', {
      params: {
        grant_type: 'client_credential',
        appid: APP_ID,
        secret: APP_SECRET
      }
    });
    accessToken = response.data.access_token;
    tokenExpireTime = currentTime + (response.data.expires_in - 300) * 1000; // 提前5分钟刷新
    return accessToken;
  } catch (error) {
    console.error('获取 access_token 失败', error);
    throw error;
  }
}
// 发送订阅消息的接口
router.post('/api/send-subscribe-message', async (req, res) => {
  try {
    const { orderNo, openid } = req.body; // 从请求体中获取数据
    if (!openid || !orderNo) {
      return res.json({ code: -1, msg: '参数错误' });
    }
    // 1. 获取 access_token
    const token = await getAccessToken();
    // 2. 准备发送消息的数据
    const templateId = '你的模板ID'; // 从配置或数据库中获取
    const messageData = {
      touser: openid,
      template_id: templateId,
      data: {
        thing1: { value: "微信小店" },
        number2: { value: orderNo },
        amount3: { value: "128.00" },
        phrase4: { value: "欢迎再次光临" }
      }
    };
    // 3. 调用微信 API 发送消息
    const apiResponse = await axios.post(
      `https://api.weixin.qq.com/cgi-bin/subscribe/send?access_token=${token}`,
      messageData
    );
    // 4. 处理微信 API 的返回结果
    if (apiResponse.data.errcode === 0) {
      res.json({ code: 0, msg: '消息发送成功' });
    } else {
      console.error('微信API返回错误', apiResponse.data);
      res.json({ code: apiResponse.data.errcode, msg: apiResponse.data.errmsg });
    }
  } catch (error) {
    console.error('发送订阅消息时发生错误', error);
    res.status(500).json({ code: -1, msg: '服务器内部错误' });
  }
});

总结与注意事项

  1. 订阅消息 vs 模板消息:请务必使用最新的 订阅消息 API,旧的模板消息接口已基本废弃。
  2. 用户主动:订阅消息的核心是 用户授权,你不能在用户不知情的情况下给他发消息。wx.requestSubscribeMessage 是获取授权的标准方式。
  3. 凭证时效性wx.requestSubscribeMessage 返回的 subscription item 是有时效性的(通常为30天),你的后端需要妥善存储它,并在发送消息时使用。
  4. access_token 管理:后端的 access_token 必须缓存,避免频繁请求导致微信API调用次数超限或被封禁。
  5. 内容合规:发送的消息内容必须符合微信平台规范,不能包含敏感、营销或诱导性词语,否则会被拦截或处罚。
  6. 错误处理:后端代码需要充分处理各种错误情况,如 access_token 失效、用户拒绝订阅、模板ID错误等,并给出明确的返回信息。

遵循以上步骤,你就可以成功地在你的微信小程序中集成订阅消息功能了。