微信小程序消息推送

实现步骤:

  1. 申请消息模板
  2. 订阅对应模板消息
  3. 获取用户登入code
  4. 获取用户openId
  5. 获取access_token
  6. 进行消息推送

说明:

code是用户登录凭证(有效期五分钟)。

openid 是小程序用户唯一标识。

access_token是小程序全局唯一后台接口调用凭据。

实现效果:

具体实现:

1.申请消息模板
首先登入微信公众平台,选择自己的小程序,进入到小程序页面。
如图操作:

 

2.订阅对应模板消息
找到申请的模板,复制模板ID,小程序调用wx.requestSubscribeMessage接口订阅模板消息。
如图操作:

3.获取用户登入code
小程序调用wx.login接口获取用户code。
如图操作:


4.获取用户登入code

使用获取到的code调用后端用户授权接口获取用户openid。
官方接口文档:
auth.code2Session | 微信开放文档 (qq.com)
如图操作:

public UserAuthRes userAuth(String code) {
    Map<String, Object> requestParams = new HashMap<>();
    requestParams.put("appid", "wx4a6ad6d7e5e6xxxx"); //小程序appid
    requestParams.put("secret", "eb05b4885d3fbe18d46b1822fca7xxxx"); //小程序secret
    requestParams.put("js_code", code); //用户登入code
    requestParams.put("grant_type", "authorization_code"); //授权类型这里填写authorization_code


    UserAuthRes userAuthRes = restTemplate.getForObject("https://api.weixin.qq.com/sns/jscode2session?" +
            "appid={appid}&secret={secret}&js_code={js_code}&grant_type={grant_type}", UserAuthRes.class, requestParams);
    if (null != userAuthRes) {
        log.info("授权用户信息:{}", userAuthRes);
        //TODO 可以记录用户信息到mysql/redis(openid、session_key、unionid)备注:session_key 有效期为三天
        return userAuthRes;
    } else {
        throw new RuntimeException("用户授权失败");
    }
}

返回值结构:

public class UserAuthRes {
    private String openid; //用户唯一标识openid


    private String session_key; //用户会话密钥session_key


    private String unionid; //用户在开放平台的唯一标识符,若当前小程序已绑定到微信开放平台帐号下会返回


    private String errcode; //错误码


    private String errmsg; //错误信息
}

5.获取access_token
后端调用接口传入appid、secret、grant_type获取access_token。
官方接口文档:
获取接口调用凭据 | 微信开放文档 (qq.com)
如图操作:

public String getUserAccessToken() {

    Map<String, Object> requestParams = new HashMap<>();
    requestParams.put("appid", "wx4a6ad6d7e5e6xxxx"); //小程序appid
    requestParams.put("secret", "eb05b4885d3fbe18d46b1822fca7xxxx"); //小程序secret
    requestParams.put("grant_type", "client_credential"); //授权类型这里填写client_credential

    JSONObject result = restTemplate.getForObject("https://api.weixin.qq.com/cgi-bin/token?grant_type={grant_type}&appid={appid}&secret={secret}", JSONObject.class, requestParams);
    if (null == result) {
        throw new RuntimeException("获取access token失败");
    }
    String accessToken = result.get("access_token").toString();
    if (StringUtils.isNoneBlank(accessToken)) {
        log.info("获取access token成功:{}", accessToken);
        return accessToken;
    } else {
        throw new RuntimeException("获取access token失败");
    }
}

6.进行消息推送
打开要要推送的模板详情,查看模板占位符、后端调用接口传入touser、template_id、data,进行消息推送。注意请求参数data里的属性名一定要与模板占位符保持一致!
官方文档:
subscribeMessage.send | 微信开放文档 (qq.com)
如图操作: 

 

  后端接口:

private void sendMessage() {

    MessageTemplateEntity messageTemplateEntity = new MessageTemplateEntity();
    String time = new SimpleDateFormat("yyyy-mm-dd HH:mm:ss").format(new Date());
    messageTemplateEntity.setMessageData(new MessageValueEntity("项目名称"), new MessageValueEntity(time), new MessageValueEntity("这是描述"));

    Map<String, Object> paramsMap = new HashMap<>();
    paramsMap.put("touser", "wx4a6ad6d7e5e6xxxx"); //用户openid
    paramsMap.put("template_id", "h7eKu5vOSbbObOxg9psqYZ-NiRyiiPi9wMuWqExxxx"); //推送消息模板id
    paramsMap.put("data", messageTemplateEntity); //消息体:{{"thing1":"项目名称"},{"time2":"2022-08-23"},{"thing3":"这是描述"}}
    HttpHeaders headers = new HttpHeaders(); //构建请求头
    headers.setContentType(MediaType.APPLICATION_JSON); //设置内容类型为json
    HttpEntity<Map<String, Object>> request = new HttpEntity<>(paramsMap, headers); //构建http请求实体

    //发送请求路径拼接获取到的access_token
    SendMessageVo sendMessageVo = restTemplate.postForObject("https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" +
            "60_mrPc2IpScFl8b8a9fhsPVw4nbMxxxx...", request, SendMessageVo.class);

    if (null == sendMessageVo) {
        throw new RuntimeException("推送消息失败");
    }

    if (sendMessageVo.getErrcode() != 0) {
        log.error("推送消息失败,原因:{}", sendMessageVo.getErrmsg());
        throw new RuntimeException("推送消息失败");
    }
    log.info("推送消息成功");
}


MessageTemplateEntity实体类结构:

@Data
public class MessageTemplateEntity {

    private MessageValueEntity thing1;

    private MessageValueEntity time2;

    private MessageValueEntity thing3;

    public void setMessageData(MessageValueEntity thing1, MessageValueEntity time2, MessageValueEntity thing3) {
        this.thing1 = thing1;
        this.time2 = time2;
        this.thing3 = thing3;
    }

}


MessageValueEntity实体类结构:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class MessageValueEntity {

    private String value;
}


注意事项:
(1)本篇消息推送教学为一次性订阅消息,也就是订阅一次可以推送一次消息,不订阅推送消息会失败,长期订阅消息如有需要,请去小程序官方申请长期消息模板。
(2)推送消息data属性值格式一定要严格按照官方给的格式,不然会报错,47003错误码说明有某个字段为null或者格式不正确。如果不清楚可以去官方文档查看对应格式。
官方文档:
subscribeMessage.send | 微信开放文档

关于我们:
创作不易,如有问题、疑难杂症,欢迎评论区交流病情(包治百病)。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值