小程序发送一次性订阅模版消息

小程序发送一次性订阅模版消息

PS:注意不是微信公众号发送消息,也不是发送长期订阅消息,因为会调用不同微信接口

在这里插入图片描述

消息类型
1. 一次性订阅消息
        一次性订阅消息用于解决用户使用小程序后,后续服务环节的通知问题。用户自主订阅后,开发者可不限时间地下发一条对应的服务消息;每条消息可单独订阅或退订。

2. 长期订阅消息
        一次性订阅消息可满足小程序的大部分服务场景需求,但线下公共服务领域存在一次性订阅无法满足的场景,如航班延误,需根据航班实时动态来多次发送消息提醒。为便于服务,我们提供了长期性订阅消息,用户订阅一次后,开发者可长期下发多条消息。目前长期性订阅消息仅向政务民生、医疗、交通、金融、教育等线下公共服务开放,后期将逐步支持到其他线下公共服务业务。

3. 设备订阅消息
        设备订阅消息是一种特殊类型的订阅消息,它属于长期订阅消息类型,且需要完成「设备接入」才能使用。设备订阅消息用于在设备触发某些需要人工介入的事件时(例如设备发生故障、设备耗材不足等),向用户发送消息通知。详见设备订阅消息文档

步骤一:获取模板 ID

在微信公众平台手动配置获取模板 ID:登录 https://mp.weixin.qq.com 获取模板,如果没有合适的模板,可以申请添加新模板,审核通过后可使用。

在这里插入图片描述
在这里插入图片描述

步骤二:获取下发权限

一次性订阅消息、长期订阅消息,详见接口 wx.requestSubscribeMessage

设备订阅消息,详见接口 wx.requestSubscribeDeviceMessage

在这里插入图片描述

步骤三:调用接口下发订阅消息

一次性订阅消息、长期订阅消息,详见服务端接口 subscribeMessage.send

设备订阅消息,详见服务端接口 hardwareDevice.send

具体实现,详见。。。

主要代码:

package utils;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.nimbus.common.data.model.api.ApiErrorCode;
import com.nimbus.common.data.model.api.ApiResultDto;
import dto.wechat.MessageInfoDto;
import dto.wechat.WeChatLoginResponseDto;
import dto.wechat.WeChatPhoneResponseDto;
import lombok.var;
import org.apache.commons.lang.StringUtils;
import weaver.general.BaseBean;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * WeChatHelper.
 */
public class WeChatHelper {

    private final static BaseBean log = new BaseBean();
    private final static String APP_ID = "xxx";                                      // APP_ID小程序注册时由微信提供
    private final static String APP_SECRET = "xxx";                    // APP_SECRET小程序注册时由微信提供
    private final static String TEMPLATEID = "xxx";         // 一次性订阅消息模板ID
    private final static String TOKENURL = "https://api.weixin.qq.com/cgi-bin/token";
    private final static String PHONEURL = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=";
    private final static String URL = "https://api.weixin.qq.com/sns/jscode2session";
    private final static String MESSAGEURL = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=";   // 一次性订阅消息URL
    
    /**
     * 获取微信AccessToken
     *
     * @return accessToken
     */
    public static String getAccessToken() {
        Map<String, Object> params = new HashMap<>();
        params.put("grant_type", "client_credential");
        params.put("appid", APP_ID);
        params.put("secret", APP_SECRET);
        JSONObject tokenJson = JSONObject.parseObject(HttpUtil.get(TOKENURL, params));
        String accessToken = (String) tokenJson.get("access_token");
        return accessToken;
    }

    /**
     * 小程序发送一次性订阅消息
     *
     * @param openId
     * @param infoDto
     */
    public static void pushMiniProgramMessage(String openId, MessageInfoDto infoDto) {
        log.writeLog("pushMiniProgramMessage start...");
        String accessToken = WeChatHelper.getAccessToken();
        if (StringUtils.isEmpty(openId) || StringUtils.isEmpty(accessToken)) {
            log.writeLog("openid not exists", ApiErrorCode.FORBIDDEN.getMessage());
        }
        // 请求体,根据模版内容动态调整
        JSONObject requestParams = new JSONObject();
        requestParams.put("touser", openId);                // 接收订阅消息的用户openid
        requestParams.put("template_id", TEMPLATEID);       // 订阅消息模板ID
//        requestParams.put("miniprogram_state", "developer");  // 测试
        String nodename = "流程已到达\"" + infoDto.getNodename() + "\"节点";
        requestParams.put("data", new JSONObject()
                .fluentPut("thing1", new JSONObject().fluentPut("value", nodename))
                .fluentPut("thing16", new JSONObject().fluentPut("value", infoDto.getRequestname()))
                .fluentPut("thing14", new JSONObject().fluentPut("value", infoDto.getUsername()))
                .fluentPut("time15", new JSONObject().fluentPut("value", infoDto.getReceivedatetime()))
        );
        log.writeLog("requestParams: " + requestParams.toJSONString());
        String result = HttpUtil.post(MESSAGEURL + accessToken, requestParams.toJSONString());
        log.writeLog("push message result: " + result);
        log.writeLog("pushMiniProgramMessage end...");
    }
}

常见报错:

{"errcode":47003,"errmsg":"argument invalid! data.time15.value invalid rid: 6476a7e2-2a81a2c2-351ce8fc"} -- 参数封装不匹配,某个字段值类型不对,比如name.DATA、thing.DATA、time.DATA,详见https://www.cnblogs.com/wdw31210/p/14544272.html


{'errcode': 43101, 'errmsg': 'user refuse to accept the msg} -- 需要用户授权,步骤二
 
{"errcode":40013,"errmsg":"invalid appid rid: 647706e9-37d064ee-024cd024"} -- 接口URL和参数不匹配
### UniApp 中开发支持订阅消息小程序 #### 实现一次性订阅消息功能 在UniApp中实现小程序一次性订阅消息主要涉及前端页面设计以及与微信服务器端交互逻辑。对于一次性订阅消息而言,用户每次触发特定事件时都需要重新获取授权。 为了实现在UniApp中的集成,需遵循如下要点: - **准备阶段** 确保项目已配置好`app.json`文件内的`permission`字段,声明应用所需的权限[^1]。具体来说,在此场景下应加入`scope.writeMessage`来表明应用程序会请求写入推送通知的能力。 ```json { "permission": { "scope.writeMessage": {} } } ``` - **界面构建** 创建用于展示给用户的提示框或其他形式的通知组件,告知其即将发起的消息订阅操作并引导完成确认流程。这一步骤通常通过调用微信提供的API接口`wx.requestSubscribeMessage()`来进行实际的订阅动作。 当用户同意接收某类别的信息后,该方法返回的结果对象里包含了对应模板ID的状态码;开发者可以根据这些反馈调整后续处理策略或记录必要的状态数据以便将来验证。 ```javascript // 调用 wx.requestSubscribeMessage 方法进行一次性订阅 const res = await uni.requestSubscribeMessage({ tmplIds: ['your_template_id'] }); if (res.errMsg === 'requestSubscribeMessage:ok') { console.log('User agreed to subscribe'); } else { console.error('Failed to request subscription', res); } ``` 需要注意的是,上述代码片段里的`tmplIds`参数应当替换为正式环境中由微信公众平台分配的具体模版编号。 - **后台对接** 一旦成功收集到了用户的许可,则可以利用HTTP POST等方式把相关信息同步至自己的服务端保存起来。这部分工作可能涉及到加密传输、身份认证等多个方面,务必参照官方文档指导实施安全措施以保护敏感资料的安全性和隐私权。 最后提醒一点,虽然当前版本只允许部分行业领域使用永久性的订阅模式,但对于大多数应用场景来讲,合理运用临时性质的信息传递机制同样能够满足日常运营需求的同时也符合政策规定的要求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员码小跳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值