目录
一、前言
本文介绍如何通过配置微信小程序一次性订阅功能,并通过后端服务Java推送消息,实现一次性订阅推送
二、小程序配置
2.1配置公共模版
在小程序管理后台,点击基础功能→订阅消息→公共模板库→一次性订阅,挑选时候的模板库,点击选用

在模版中选择你需要的字段,最多可选择5个,不存在的字段支持申请,需要小程序审核通过才可使用。基本上模板中的字段可以满足大部分人的要求

模板选择好以后,可以在我的模版中看到,模板ID需要后续推送时使用,点击详情

详情中可查看具体参数名,记住参数字段名称,后续推送消息时使用

三、Java调用微信小程序接口推送消息
3.1获取access_token
可查看微信小程序官方文档,寻找调用接口,链接如下:获取接口调用凭据 | 微信开放文档
其中入参appid和secret可在小程序管理后台寻找,grant_type固定填写为client_credential
import com.alibaba.fastjson.JSONObject;
import com.dhc.ilead.bpm.utils.HttpClientUtils;
import com.dhc.ilead.zzkj.swc.wx.dto.WxAccessTokenVO;
import java.util.HashMap;
import java.util.Map;
/**
* @author : xxx
* @date : 2024/11/13 11:41
* @description : WxMessageUtil
*/
public class WxMessageUtil {
private static final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token";
/*
* 获取access_token
*/
public static WxAccessTokenVO getAccess_token(String appid, String secret) {
WxAccessTokenVO wxAccessTokenVO = new WxAccessTokenVO();
//获取access_token
Map<String, String> paramMap = new HashMap();
paramMap.put("appid", appid);
paramMap.put("secret", secret);
paramMap.put("grant_type", "client_credential");
try {
JSONObject result = JSONObject.parseObject(HttpClientUtils.doGet(ACCESS_TOKEN_URL, paramMap).getContent());
if(result != null){
wxAccessTokenVO.setAccessToken(result.getString("access_token"));
wxAccessTokenVO.setExpiresIn(result.getLong("expires_in"));
wxAccessTokenVO.setErrCode(result.getLong("errcode"));
}
} catch (Exception e) {
e.printStackTrace();
}
return wxAccessTokenVO;
}
}
access_token过期时间最长7200s,所以需要缓存access_token定期刷新,此处利用redis做缓存处理,并根据返回的过期时间提前5分钟设置为redis的过期时间
public void sendMessageToWx(String openid, SwcPortReportingInfoDTO param){
//redis中获取access_token
String accessToken = stringRedisTemplate.opsForValue().get("wxAccessToken");
if ( accessToken == null){
log.info("开始存入redis数据");
//调用小程序接口获取access_token,并存入redis
WxAccessTokenVO wxAccessTokenVO = WxMessageUtil.getAccess_token(appid, secret);
stringRedisTemplate.opsForValue().set("wxAccessToken",wxAccessTokenVO.getAccessToken(),wxAccessTokenVO.getExpiresIn()-300, TimeUnit.SECONDS);
accessToken = wxAccessTokenVO.getAccessToken().trim();
}
log.info("获取accessToken为:"+accessToken);
}
3.2推送订阅信息
调用微信小程序订阅消息接口,官方文档链接如下:发送订阅消息 | 微信开放文档
入参按照接口文档方式传递,touser为你需要推送的微信用户的openid,template_id为前文提到的模版id,page为点击模板卡片后的跳转页面,仅限本小程序内的页面(小程序开发提供),miniprogram_state为小程序类型,lang为进入小程序查看”的语言类型
public void sendMessageToWx(String openid, SwcPortReportingInfoDTO param){
//redis中获取access_token
String accessToken = stringRedisTemplate.opsForValue().get("wxAccessToken");
if ( accessToken == null){
log.info("开始存入redis数据");
//调用小程序接口获取access_token,并存入redis
WxAccessTokenVO wxAccessTokenVO = WxMessageUtil.getAccess_token(appid, secret);
stringRedisTemplate.opsForValue().set("wxAccessToken",wxAccessTokenVO.getAccessToken(),wxAccessTokenVO.getExpiresIn()-300, TimeUnit.SECONDS);
accessToken = wxAccessTokenVO.getAccessToken().trim();
}
log.info("获取accessToken为:"+accessToken);
//发送信息至客户
RestTemplate restTemplate = new RestTemplate();
//获取接口入参
WxMessageDto wxMessageDto = new WxMessageDto();
wxMessageDto.setTouser(openid);
wxMessageDto.setTemplate_id(templateid);
wxMessageDto.setMiniprogram_state(miniprogramstate);
wxMessageDto.setLang(lang);
wxMessageDto.setPage(page);
Map<String, WxMessageValueDto> wxMssVo = new HashMap<>(4);
if (StringUtils.equals(SwcConstant.PORT_REPORT_APPROVED,param.getReportingPortStatus())){
wxMssVo.put("phrase1", new WxMessageValueDto("通过")); //审核结果
wxMssVo.put("thing51", new WxMessageValueDto("无")); //驳回原因
}else {
wxMssVo.put("phrase1", new WxMessageValueDto("不通过")); //审核结果
wxMssVo.put("thing51", new WxMessageValueDto((StringUtils.isNotBlank(param.getRefuseReason()) && param.getRefuseReason().length() > 20) ? param.getRefuseReason().substring(0,17)+"...":param.getRefuseReason())); //驳回原因
}
wxMssVo.put("date3", new WxMessageValueDto(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(LocalDateTime.now()))); //审核时间
String reportType = "xxx申请1";
if (param.getReportingPortType() != null &&SwcConstant.PORT_REPORT_UNLOAD.equals(param.getReportingPortType())){
reportType = "xxx申请2";
}
wxMssVo.put("thing15", new WxMessageValueDto("申请内容xxx")); //申请项目
wxMssVo.put("thing16", new WxMessageValueDto(param.getShipName() + reportType)); //申请内容
wxMessageDto.setData(wxMssVo);
log.info("小程序推送信息:"+wxMessageDto.toString());
try {
ResponseEntity<String> responseEntity =
restTemplate.postForEntity(SEND_MESSAGE_URL+accessToken, wxMessageDto, String.class);
log.info(responseEntity.getBody());
} catch (Exception e) {
e.printStackTrace();
}
}
3.3VO类代码
@Data
public class WxMessageDto {
private String touser;//用户openid
private String template_id;//订阅消息模版id
private String miniprogram_state;//跳转小程序类型
private String lang;//语言类型
private String page = "pages/login";//默认跳到小程序首页
private Map<String, WxMessageValueDto> data;//推送文字
}
@Data
@AllArgsConstructor
public class WxMessageValueDto {
private String value;
}
@Data
public class WxAccessTokenVO {
private String accessToken;
private Long expiresIn;
private Long errCode;
}
3.4注意事项
推送消息时,模版里的字段都有长度限制,所以发送消息时需注意消息的长度,超长字段需要做处理,否则会发送失败,长度限制见下图

3.5发送前提
因为是一次性订阅消息推送,所以推送时需要小程序开发订阅消息的弹窗,用户允许以后才能推送
四、总结
微信小程序一次性订阅消息推送可在用户点击订阅消息以后,由服务端推送消息。但每订阅一次只支持推送一条消息,如需多次推送用户必须多次点击订阅弹窗。小程序本身支持永久订阅但限制很多,所以针对简单的消息推送场景本文方可适用。
1万+

被折叠的 条评论
为什么被折叠?



