后端实现小程序订阅消息(Java向)

访问微信公众平台查看所需配置

必需:开发的APPID、开发的secret以及订阅消息的模板ID,模板可以选择微信提供的,也可以自己申请自己需求对应模板

image-20240228170929716

由前端获取用户订阅信息

参考[订阅消息](消息相关 / 订阅消息 / 发送订阅消息 (qq.com))的前端配置

获取AccessToken

  1. 什么是AccessToken

access_token是小程序全局唯一后台接口调用凭据,调用绝大多数后台接口时都需使用。开发者可以通过getAccessToken 接口获取并进行妥善保存为了 accesesoken 的安全性,后端API不能直接在小程序内通过 w.request 调用,即 api.weixin.qq.com不能被配置为服务器域名,开发者应在后端服务器使用 getAccessToken获取 access_token,并调用相关APl

  1. 其实通俗的讲,access_token就是小程序官方给我们提供的一个凭证,你要调用小程序官方的接口,就必须先拿到access_token
1
2
3
4
5
6
7
8
9
public String getAccessToken(){
RestTemplate restTemplate=new RestTemplate();
ResponseEntity<String> responseEntity=restTemplate.getForEntity(
"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+ WxLoginConstants.APPID +"&secret="+WxLoginConstants.SECRET,String.class);
String body = responseEntity.getBody();
JSONObject object=JSONObject.parseObject(body);
String access_Token = object.getString("access_token");
return access_Token;
}

设置模板&发送信息

模板设置

参数类别 参数说明 参数值限制 说明
thing.DATA 事物 20个以内字符 可汉字、数字、字母或符号组合
number.DATA 数字 32位以内数字 只能数字,可带小数
letter.DATA 字母 32位以内字母 只能字母
symbol.DATA 符号 5位以内符号 只能符号
character_string.DATA 字符串 32位以内数字、字母或符号 可数字、字母或符号组合
time.DATA 时间 24小时制时间格式(支持+年月日),支持填时间段,两个时间点之间用“~”符号连接 例如:15:01,或:2019年10月1日 15:01
date.DATA 日期 年月日格式(支持+24小时制时间),支持填时间段,两个时间点之间用“~”符号连接 例如:2019年10月1日,或:2019年10月1日 15:01
amount.DATA 金额 1个币种符号+10位以内纯数字,可带小数,结尾可带“元” 可带小数
phone_number.DATA 电话 17位以内,数字、符号 电话号码,例:+86-0766-66888866
car_number.DATA 车牌 8位以内,第一位与最后一位可为汉字,其余为字母或数字 车牌号码:粤A8Z888挂
name.DATA 姓名 10个以内纯汉字或20个以内纯字母或符号 中文名10个汉字内;纯英文名20个字母内;中文和字母混合按中文名算,10个字内
phrase.DATA 汉字 5个以内汉字 5个以内纯汉字,例如:配送中
enum.DATA 枚举值 只能上传枚举值范围内的字段值 调用接口获取参考枚举值

每个模板都是不一样的例如:

image-20240229131325703

则我们的发送数据格式是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"touser": "OPENID",
"template_id": "TEMPLATE_ID",
"page": "index",
"miniprogram_state":"developer",
"lang":"zh_CN",
"data": {
"phrase1":{
"value":"审核结果内容"
},
"thing13":{
"value":"审核意见内容"
}
}
}

发送消息

实体类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Data
public class WxSubMessageVo {

@Excel(name="用户openId")
private String touser;

@Excel(name="消息模板Id")
private String template_id;

@Excel(name="用户点击消息后跳转到小程序指定的页面路径")
private String page;

@Excel(name="跳转小程序类型:developer为开发版;trial为体验版;formal为正式版;默认为正式版")
private String miniprogram_state = "developer";

@Excel(name="语言默认 zh_CN")
private String lang = "zh_CN";

@Excel(name="发送消息")
private JSONObject data;

}

完整代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
/**
* 推送
* @param userid
* @param status
* @return
*/
@GetMapping("/getmessage")
public AjaxResult getmessage(@RequestParam Long userid,@RequestParam int status){
UserBroker one = iUserBrokerService.getById(userid);
if(one!=null){
//判断此用户是否订阅
if(Objects.equals(one.getIsSubscription(), "accept") && one.getWeChatNum()!=null){
return AjaxResult.success(push(one.getWeChatNum(),status));
}
}
return AjaxResult.success();
}

//获取AccessToken
public String getAccessToken(){
RestTemplate restTemplate=new RestTemplate();
ResponseEntity<String> responseEntity=restTemplate.getForEntity(
"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+ WxLoginConstants.APPID +"&secret="+WxLoginConstants.SECRET,String.class);
String body = responseEntity.getBody();
JSONObject object=JSONObject.parseObject(body);
String access_Token = object.getString("access_token");
return access_Token;
}
//推送
public String push(String openid,int status){
RestTemplate restTemplate=new RestTemplate();
String url="https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token="+getAccessToken();
WxSubMessageVo wxMssVo = new WxSubMessageVo();
wxMssVo.setTouser(openid);//用户的openid(要发送给那个用户,通常这里应该动态传进来的)
wxMssVo.setTemplate_id("Wrk0WD7Y1H1lKdRc0H4tOe5xeDcVZpSj88GuK3is8xY");//订阅消息模板id
wxMssVo.setPage("pages/index/index");
wxMssVo.setMiniprogram_state("developer");

JSONObject send = new JSONObject();

JSONObject topic =new JSONObject();
JSONObject data=new JSONObject();
if(status==0){
data.put("value","认证通过");
topic.put("value","您提交的经纪人认证已通过");
send.put("phrase1", data);
send.put("thing13", topic);
}else {
data.put("value","认证失败");
topic.put("value","您提交的经纪人认证未通过,请点击查看");
send.put("phrase1", data);
send.put("thing13", topic);
}

wxMssVo.setData(send);

//发送post请求发送消息
ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, wxMssVo, String.class);
return responseEntity.getBody();
}