序言
由于微信小程序长期订阅的消息模板全部失效以后,对于小程序的消息推送可以改成往公众号推。
这里将介绍如何使用小程序向公众号推送消息,并且消息可以跳转到小程序
准备
1、微信公众平台注册服务号(订阅号是不可以推送的)与小程序,两者都需要认证并且认证主体是一致
2、微信开放平台注册账号(该账号也需要认证),绑定小程序与公众号
3、公众号根据想要的模板消息绑定服务类目,去模板消息中先挑选你的模板消息。(如果是刚注册的公众号还需要去新的功能页面添加模板消息功能,需要微信审核,不过很快)
4、微信公众号绑定小程序
5、小程序与公众号配置服务器的ip地址白名单
整体实现流程
通过在开放平台绑定的公众号与小程序后,我们在调用微信code2Session接口的时候会返回unionid(虽然我们推送用不上哈哈),只要绑定以后,就可以通过小程序的openid调用微信的下发统一消息接口推送消息到公众号去了
实现代码(java)
1、消息推送接口文档
2、小程序access_token获取接口文档
- 需要先获取小程序的access_token
private String getAppletAccessToken() {
// 因为微信有限制次数跟有效期,所以需要存在redis中
String token = redisCache.getCacheObject(CacheConstants.WECHAT_MINI_ACCESS_TOKEN);
// token失效或者为空
if (StringUtils.isEmpty(token)) {
HashMap<String, String> map = new HashMap<>(3);
map.put("appid", weAppAppId); // 小程序appid
map.put("secret", weAppSecret); // 小程序secret
map.put("grant_type", "client_credential");
// 发送Http的post请求
String resp = HttpUtils.sendPostJson(GET_ACCESS_TOKEN_URL, JSON.toJSONString(map), null);
log.info("获取小程序accessToken返回:" + resp);
if (StringUtils.isEmpty(resp) || !resp.contains("access_token")) {
throw new ServiceException("获取小程序accessToken失败");
}
token = JSONObject.parseObject(resp).getString("access_token");
// 设置为1.9h(有效期2h)
redisCache.setCacheObject(CacheConstants.WECHAT_MINI_ACCESS_TOKEN, token,
7100, TimeUnit.SECONDS);
}
return token;
}
- 封装下发消息参数实体(仅参考,照着接口文档封)
/**
* 微信下发统一消息参数
*
* @author quan
* @date 2023/9/15 16:42
*/
@Data
@NoArgsConstructor
public class PushMsgParams {
/**
* 用户openid,可以是小程序的openid,
* 也可以是mp_template_msg.appid对应的公众号的openid
*/
private String touser;
/**
* 公众号模板消息
*/
private MpTemplateMsg mp_template_msg;
public PushMsgParams(String touser) {
this.touser = touser;
}
}
/**
* 小程序模板消息相关的信息,可以参考小程序模板消息接口;
* 有此节点则优先发送小程序模板消息;
* (小程序模板消息已下线,不用传此节点)
*
* @author quan
* @date 2023/9/15 16:48
*/
@Data
public class MpTemplateMsg {
/**
* 公众号appid,要求与小程序有绑定且同主体
*/
private String appid;
/**
* 公众号模板id
*/
private String template_id;
/**
* 公众号模板消息所要跳转的url
*/
private String url;
/**
* 公众号模板消息所要跳转的小程序,
* 小程序的必须与公众号具有绑定关系
*/
private Map<String, String> miniprogram;
/**
* 公众号模板消息的数据
*/
private Map<String, Map<String, String>> data;
/**
* 构建data数据
*/
public void createData(Map<String, String> data) {
if (null == data || data.isEmpty()){
return;
}
Map<String, Map<String, String>> map = new HashMap<>(data.size());
for (Map.Entry<String, String> entry : data.entrySet()) {
Map<String, String> valMap = new HashMap<>(1);
valMap.put("value", entry.getValue());
map.put(entry.getKey(), valMap);
}
this.data = map;
}
}
- 消息推送方法封装
/**
* 下发统一消息接口
*
* @param pushMsgParams 下发参数
* @param data 模板参数
*/
public void sendUniformMessage(PushMsgParams pushMsgParams, Map<String, String> data) {
String accessToken = getAppletAccessToken();
MpTemplateMsg templateMsg = new MpTemplateMsg();
// 公众号appid
templateMsg.setAppid(mpAppId);
// 前面准备的模板消息的id
templateMsg.setTemplate_id(templateId);
// 推送参数,格式为keyword,value。可看下微信提供的demo会清楚点
templateMsg.createData(data);
// 跳转小程序
HashMap<String, String> miniPro = new HashMap<>(2);
miniPro.put("appid", weAppAppId);
miniPro.put("pagepath", "");
templateMsg.setMiniprogram(miniPro);
pushMsgParams.setMp_template_msg(templateMsg);
// 发送Http请求
// SEND_UNIFORM_MESSAGE = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send?access_token="
String resp = HttpUtils.sendPostJson(SEND_UNIFORM_MESSAGE + accessToken, JSON.toJSONString(pushMsgParams), null);
log.info("微信下发统一消息接口返回:{}", resp);
JSONObject result = JSON.parseObject(resp);
if (!"0".equals(result.getString("errcode"))) {
throw new ServiceException("微信消息推送失败," + result.getString("errMsg"));
}
}
- 业务调用推送代码
for (SysUser user : users) {
// 小程序或公众号用户的openid都可以推
PushMsgParams pushMsgParams = new PushMsgParams(user.getOpenid());
HashMap<String, String> data = new HashMap<>(5);
data.put("character_string2", event.getFlightNo());
data.put("thing10", event.getStartPlace());
data.put("thing11", event.getDestPlace());
data.put("time3", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, event.getFlightStartTime()));
data.put("thing9", "请及时处理关注事件");
weChatUtil.sendUniformMessage(pushMsgParams, data);
}
- 推送效果,可直接跳转小程序