Skip to content

微信小程序订阅消息

1. 什么是订阅消息

订阅消息是微信小程序向用户推送通知的方式,分为:

  • 一次性订阅:用户授权后只能发送一次
  • 长期订阅:可多次发送(需特殊类目资质)

2. 配置

yaml
wechat:
  program:
    # 小程序AppID - 在微信公众平台(https://mp.weixin.qq.com)注册小程序后获取
    appid: YOUR_APPID
    # 小程序AppSecret - 在微信公众平台(https://mp.weixin.qq.com)注册小程序后获取
    appSecret: secret: YOUR_SECRET

3. 初始化服务

java
@Service
public class WxSubscribeMsgService {

    @Value("${wechat.program.appid:}")
    private String appId;

    @Value("${wechat.program.secret:}")
    private String appSecret;

    private WxMaService wxMaService;

    @PostConstruct
    public void init() {
        WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl();
        config.setAppid(appId);
        config.setSecret(appSecret);

        wxMaService = new WxMaServiceImpl();
        wxMaService.setWxMaConfig(config);
    }
}

4. 发送订阅消息

4.1 构建消息命令

java
@Data
public class SendSubscribeMsgCommand {

    @NotBlank
    private String openid;

    @NotBlank
    private String templateId;

    @NotNull
    private List<MsgData> data;

    private String page;
}

@Data
@AllArgsConstructor
public class MsgData {
    private String key;   // 模板字段名
    private String value; // 字段值
}

4.2 发送方法

java
@Service
@RequiredArgsConstructor
public class WxSubscribeMsgService {

    private final WxMaService wxMaService;

    public void sendSubscribeMsg(SendSubscribeMsgCommand command) throws WxErrorException {
        // 构建订阅消息
        WxMaSubscribeMessage message = WxMaSubscribeMessage.builder()
                .toUser(command.getOpenid())
                .templateId(command.getTemplateId())
                .data(command.getData())
                .page(command.getPage())
                .build();

        // 调用接口发送
        wxMaService.getSubscribeService().sendSubscribeMsg(message);
    }
}

5. 业务场景示例

5.1 订单状态通知

java
@Service
@RequiredArgsConstructor
public class OrderNotifyService {

    private final IWxSubscribeMsgService wxSubscribeMsgService;
    private final IDroneOrderService orderService;

    private static final String ORDER_TEMPLATE_ID = "YOUR_ORDER_TEMPLATE_ID";

    public void sendOrderStatusNotice(Long orderId, String openid) {
        DroneOrder order = orderService.getOrderById(orderId);

        // 构建消息数据
        List<MsgData> data = new ArrayList<>();
        data.add(new MsgData("thing11", order.getTitle()));           // 订单标题
        data.add(new MsgData("phrase10", order.getStatusDesc()));     // 状态描述

        SendSubscribeMsgCommand command = new SendSubscribeMsgCommand(
                openid,
                ORDER_TEMPLATE_ID,
                data,
                "/pages/order/detail?id=" + orderId
        );

        wxSubscribeMsgService.sendSubscribeMsg(command);
    }
}

5.2 提现通知

java
@Service
@RequiredArgsConstructor
public class WithdrawalNotifyService {

    private final IWxSubscribeMsgService wxSubscribeMsgService;
    private final IDroneAccountLogService accountLogService;

    private static final String WITHDRAWAL_TEMPLATE_ID = "YOUR_WITHDRAWAL_TEMPLATE_ID";

    public void sendWithdrawalNotice(Long accountLogId) {
        DroneAccountLog log = accountLogService.getById(accountLogId);

        List<MsgData> data = new ArrayList<>();
        data.add(new MsgData("amount2", log.getAmount() + "元"));  // 提现金额
        data.add(new MsgData("phrase3", "待确认"));                // 状态

        SendSubscribeMsgCommand command = new SendSubscribeMsgCommand(
                log.getOpenid(),
                WITHDRAWAL_TEMPLATE_ID,
                data,
                "/pages/wallet/detail?id=" + accountLogId
        );

        wxSubscribeMsgService.sendSubscribeMsg(command);
    }
}

6. 模板占位符说明

占位符类型说明
thing文本最多20个字符
number数字最多32位数字
amount金额格式如 "100.00"
phrase关键词已配置的关键词
time时间格式如 "2024-01-01 12:00:00"

示例:"thing11" 表示第一个文本字段

7. 调用时机

┌─────────────┐    ┌─────────────┐    ┌─────────────┐
│  用户下单    │ -> │ 发送订阅消息 │ -> │ 用户收到通知 │
└─────────────┘    └─────────────┘    └─────────────┘

                                               v
┌─────────────┐    ┌─────────────┐    ┌─────────────┐
│  支付成功    │ -> │ 发送订阅消息 │ -> │ 用户收到通知 │
└─────────────┘    └─────────────┘    └─────────────┘

                                               v
┌─────────────┐    ┌─────────────┐    ┌─────────────┐
│  订单完成    │ -> │ 发送订阅消息 │ -> │ 用户收到通知 │
└─────────────┘    └─────────────┘    └─────────────┘

8. 依赖

xml
<dependency>
    <groupId>com.github.binarywang</groupId>
    <artifactId>weixin-java-miniapp</artifactId>
    <version>4.5.0</version>
</dependency>

9. 注意事项

问题原因解决方案
用户收不到消息未订阅引导用户点击订阅按钮
模板ID错误在小程序后台查找微信公众平台 -> 订阅消息 -> 模板库
字段格式错误占位符不匹配对照模板修改字段名
access_token过期自动刷新SDK自动处理