微信小程序订阅消息推送

一、创建消息模板

在微信公众平台-小程序里,选择订阅消息,简单起见,可以从公共模板库选择一个合适的(如公共模板库没有合适的,则可以自己创建,但是需要审核)。
在这里插入图片描述

二、获取模板消息的参数

点击模板消息详情查看模板消息参数。
在这里插入图片描述

三、获取openId

先拿到用户的openId(如已获取,则跳过)。

3.1 前端从小程序获取登录凭证code

前端先从小程序端拿到用户code,然后将code传给后端进行解析。
官方文档:https://developers.weixin.qq.com/miniprogram/dev/api/open-api/login/wx.login.html
在这里插入图片描述
示例代码:

wx.login({
  success (res) {
    if (res.code) {
      //发起网络请求
      wx.request({
        url: 'https://example.com/onLogin',
        data: {
          code: res.code
        }
      })
    } else {
      console.log('登录失败!' + res.errMsg)
    }
  }
})

3.2 后端解析code,拿到openId

官方文档:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/login/auth.code2Session.html
登录凭证校验。通过 wx.login 接口获得临时登录凭证 code 后传到开发者服务器调用此接口完成登录流程。
请求地址:

GET https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code

在这里插入图片描述
Java代码如下:

/**
  * 解析code,获取openId
  * @param appId 小程序的appId
  * @param appSecret 小程序的appSecret 
  * @param code 前端传过来的code
  * @return WechatAppToken
  */
public WechatAppToken getOpenIdInMiniApp(String appId, String appSecret, String code) {
    if (code.isEmpty()) {
        System.out.println("code不能为空");
    }
	private RestTemplate restTemplate = new RestTemplate();
    String requestUrl = UriComponentsBuilder.fromHttpUrl(
            "https://api.weixin.qq.com/sns/jscode2session")
            .queryParam("appid", appId)
            .queryParam("secret", appSecret)
            .queryParam("js_code", code)
            .queryParam("grant_type", "authorization_code")
            .build().encode().toUriString();
    try {
        WechatAppToken result = restTemplate.getForObject(requestUrl, WechatAppToken.class);
        System.out.println("wxchat Result:{}" + result);
        if (result == null || result.errcode != null) {
            System.out.println("getUnionIdInMiniApp error");
            // 抛个异常
        }
        return result;
    } catch (RestClientResponseException ex) {
        System.out.println("getUnionIdInMiniApp error");
    }
}

其中,WechatAppToken是根据小程序接口返回值建的一个类:

@Data
public class WechatAppToken {
    public Integer errcode;
    public String errmsg;
    public String openid;
    public String sessionKey;
    public String unionId;
}

四、获取access_token

官方文档:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/access-token/auth.getAccessToken.html
获取小程序全局唯一后台接口调用凭据(access_token)。调用绝大多数后台接口时都需使用 access_token,开发者需要进行妥善保存。
请求地址:

GET https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

在这里插入图片描述

Java代码如下:

/**
 * 缓存的access_token
 */
private static String accessToken;
/**
 * access_token的失效时间
 */
private static long expiresTime;

public String getAccessToken() {
    // 判断accessToken是否已经过期,如果过期需要重新获取
    if (accessToken == null || expiresTime < System.currentTimeMillis()) {
        RestTemplate restTemplate = new RestTemplate();
        Map<String, String> params = new HashMap<>(2);
        params.put("APPID", "小程序的APPID");
        params.put("APPSECRET", "小程序的APPSECRET");
        ResponseEntity<String> responseEntity = restTemplate.getForEntity(
                "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={APPID}&secret={APPSECRET}", String.class, params);
        String body = responseEntity.getBody();
        JSONObject object = JSON.parseObject(body);
        Integer errcode = object.getInteger("errcode");
        if (errcode != null && errcode != 0) {
            String errmsg = object.getString("errmsg");
            System.out.println("请求accessToken失败,返回码:" + errcode + ",错误信息:" + errmsg);
            // 抛个异常
        }
        // 缓存accessToken
        accessToken = object.getString("access_token");
        // 设置accessToken的失效时间
        long expires_in = object.getLong("expires_in");
        // 失效时间 = 当前时间 + 有效期(提前一分钟,也可不提前,这里只是稳妥一下)
        expiresTime = System.currentTimeMillis() + (expires_in - 60) * 1000;
    }
    return accessToken;
}

五、发送消息

官方文档:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.send.html
发送订阅消息。
请求地址:

POST https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=ACCESS_TOKEN

在这里插入图片描述

需要注意的是,该接口是有次数限制的。
开通支付能力的是3kw/日,没开通的是1kw/日。

Java代码:

/**
 * 发送视频完成模板消息
 * @param openid 用户的openid
 * @return 结果。发送成功,返回值实例:{"errcode":0,"errmsg":"ok","msgid":11111}
 */
public String sendVlogCompleteTemplateMsg(String openid) {
    RestTemplate restTemplate = new RestTemplate();
    //发送订阅消息的url,官网地址:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.send.html
    String url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + getAccessToken();
    //拼接推送的模版
    WxMsgDto wxMsgDto = new WxMsgDto();
    //用户的openid(要发送给的那个用户)
    wxMsgDto.setTouser(openid);
    //订阅消息模板id
    wxMsgDto.setTemplate_id("小程序中选择的模板的模板id");
    //点击消息跳转的页面
    wxMsgDto.setPage("pages/index/index");

    Map<String, WxTemplateDataDto> map = new HashMap<>(5);
    //根据从小程序中的模板获取的参数,进行赋值
    map.put("thing5", new WxTemplateDataDto("西湖"));
    map.put("thing6", new WxTemplateDataDto("断桥景点"));
    map.put("time7", new WxTemplateDataDto("2022-01-13 02:31:36"));
    map.put("time4", new WxTemplateDataDto("2022-01-13 02:31:36"));
    map.put("thing3", new WxTemplateDataDto("您的视频已生成,赶紧去查看吧~"));
    wxMsgDto.setData(map);
    ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, wxMsgDto, String.class);
    return responseEntity.getBody();
}

其中WxMsgDto 类代码如下:

@Data
public class WxMsgDto {

    /**
     * 接收者(用户)的 openid
     */
    private String touser;

    /**
     * 所需下发的订阅模板id
     */
    private String template_id;

    /**
     * 点击模板卡片后的跳转页面,仅限本小程序内的页面
     */
    private String page = "pages/index/index";
    /**
     * 模板内容,格式形如 { "key1": { "value": any }, "key2": { "value": any } }
     */
    private Map<String, WxTemplateDataDto> data;
}

WxTemplateDataDto 代码如下:

@Data
@AllArgsConstructor
public class WxTemplateDataDto {

    private String value;
}

成品图

通过上述步骤,若发送消息返回值成功,则小程序会通过微信的服务通知 发送一条消息至指定用户,效果如下:
在这里插入图片描述

  • 6
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值