java实现微信小程序订阅通知

最近遇到一个需求,需要推送微信小程序订阅消息,下面分享一下实现步骤以及过程中踩到的坑。 

首先是发送订阅消息的api和所需要的一些参数

POST https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=ACCESS_TOKEN 
  1. access_token: 接口调用凭证,具体获取方式可参照获取接口调用凭据 | 微信开放文档
  2. template_id:订阅模版id,需要在发开者页面进行配置
  3. touser:接收者的open_id,获取方式可参考上一篇分享Java实现微信小程序登录_java微信小程序登录_DearMrWhite的博客-CSDN博客
  4. data:模版内容(此处会有一些坑,下面会具体讲解)
  5. miniprogram_state:调整小程序类型,developer为开发版;trial为体验版;formal为正式版;默认为正式版

接下来是具体实现:

/**
 * 发送订阅请求
 */
public boolean sendSubscriptionMessage(String accessToken, String openId, String programState) {
    return sendSubscribeMessage(accessToken, openId, programState, formatData());
}

/**
 * 拼接请求参数data
 */
private JSONObject formatData() {
    JSONObject data = new JSONObject();

    data.put("thing4", createJsonObj("测试thing4"));
    data.put("thing2", createJsonObj("测试thing2"));
    data.put("date5", createJsonObj("2023年09月18日 14:00"));
    data.put("thing6", createJsonObj("测试thing6"));
    data.put("name1", createJsonObj("测试姓名"));

    return data;
}

private JSONObject createJsonObj(String value) {
    JSONObject obj = new JSONObject();
    obj.put("value", value);
    return obj;
}

/**
 * 发送订阅请求
 */
private boolean sendSubscribeMessage(String accessToken, String toUser, String programState, JSONObject data) {
    String subscribeUrl = buildWeChatSubscribeUrl(accessToken);

    HttpEntity<String> entity = setSubscribeRequestEntity(toUser, programState, data);

    ResponseEntity<String> response;
    try {
        response = restTemplate.postForEntity(subscribeUrl, entity, String.class);
    } catch (RestClientException e) {
        log.error("微信订阅消息推送失败:", e);
        return false;
    }

    Integer responseCode = JSONObject.parseObject(response.getBody()).getInteger("errcode");

    if (responseCode != 0) {
        log.error("微信订阅消息推送失败, 错误代码:{}, 消息体:{}", responseCode, entity);
        return false;
    }
    return true;
}

/**
 * 构建消息推送的url
 */
private String buildWeChatSubscribeUrl(String accessToken) {
    return UriComponentsBuilder.fromHttpUrl(wxConfig.getSubscribeApiUrl())
            .queryParam("access_token", accessToken)
            .toUriString();
}

/**
 * 设置消息订阅请求参数
 */
private HttpEntity<String> setSubscribeRequestEntity(String toUser, String programState, JSONObject data) {
    JSONObject body = new JSONObject();
    body.put("touser", toUser);
    body.put("template_id", wxConfig.getSubscribeTemplateId());
    body.put("data", data);
    body.put("miniprogram_state", programState);

    HttpHeaders header = new HttpHeaders();
    header.add("Content-Type", "application/json;charset=UTF-8");

    return new HttpEntity<>(body.toString(), header);
}

第一个需要特别注意的是在封装请求参数data的时候,一定要注意模版字段类型和对应的数据格式要求。比如,name字段的要求是10个以内纯汉字或20个以内纯字母或符号。因为我当时需要推送的内容是小程序端页面表格填写的,但是名称字段没有做格式限制,导致这个字段在测试的时候输入了数字内容,发送通知的时候就会报错。所以一定要仔细阅读微信开发者文档,并结合自身项目的实际需求来开发。

第二个是切勿“滥用”access_token,这里的“滥用”是指获取access_token的入口不唯一。小程序的access_token有效期为7200秒,所以可以考虑将其放入缓存并定期刷新,而不是哪里需要哪里重新获取,这样很有可能导致第一次获取的access_token,因为不知道哪个地方又获取了一次,导致access_token失效。

好了,今天的分享就到这里啦,祝大家编码愉快~

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值