一.申请微信告警模板
登录微信公众号平台,在服务里面找到模板消息
我们点击从模板库中添加一个模板消息
可以通过关键字搜索告警模板,点击详情可以查看该模板的详情与示例,判断该模板是否试用与我们。
最后找到合适的模板点击添加即可完成模板消息的创建。
二.封装微信推送方法
微信推送中用到了两个微信方法
其一:获取access_token,请求方式未get,接口地址:
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=你的appid&secret=你的secret
其二:推送模板消息接口,请求方式未post,接口地址:
https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=接口1得到的token值
/**
* 微信推送方法封装
* @author HyoJung
* @date 20210714
*/
@Slf4j
public class WeChatUtil {
static HttpClient httpClient=new HttpClient();
static String accessToken="";
/**
* 获取Token
* @return
* @throws Exception
*/
public static WeChatToken getWeChatToken() throws Exception {
String strUrl = String.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s"
, WeChatConstants.WECHAT_SUBSCRIPTION_APP_ID, WeChatConstants.WECHAT_SUBSCRIPTION_APP_SECRET);
String strToken=httpClient.doGet(strUrl);
WeChatToken token = JSON.parseObject(strToken,WeChatToken.class);
accessToken =token.getAccess_token();
return token;
}
/**
* 推送微信消息封装
* @param para 推送参数
* @return
* @throws Exception
*/
public static WeChatResult sendWeChatMessage(WeChatSendParam para) throws Exception {
if(accessToken.length()==0){
getWeChatToken();
}
String strUrl = String.format("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s", accessToken);
Map<String,Object> map=new HashMap<>();
map.put("touser", para.getTouser());
map.put("template_id", para.getTemplate_id());
map.put("url", para.getUrl());
map.put("topcolor", para.getTopcolor());
map.put("data", para.getData());
String result=httpClient.doPost(strUrl,JSON.toJSONString(map));
if(result!=null&&result.length()>0){
WeChatResult weChatResult=JSON.parseObject(result,WeChatResult.class);
return weChatResult;
}else {
return null;
}
}
/**
* 模板报警消息推送
* @param touser 被推送人关注公众号后的标识
* @param alarm 报警内容实体
* @return
*/
public static WeChatResult sendWeChatAlarmMessage(String touser, MessageAlarm alarm) {
try {
//报警标题
WeChatParaData first = new WeChatParaData();
first.setValue(String.format("%s[%s]", alarm.getAlarmType(), alarm.getVehicleName()));
first.setColor("#FF0000");
//告警内容
WeChatParaData content = new WeChatParaData();
content.setValue(alarm.getAlarmContent());
content.setColor("#173177");
//告警时间
WeChatParaData occurtime = new WeChatParaData();
occurtime.setValue(alarm.getDateTime());
occurtime.setColor("#173177");
//备注
WeChatParaData remark = new WeChatParaData();
remark.setValue(alarm.getRemark());
remark.setColor("#173177");
Map<String, WeChatParaData> data = new HashMap<>();
data.put("first", first);
data.put("content", content);
data.put("occurtime", occurtime);
data.put("remark", remark);
WeChatSendParam model = new WeChatSendParam();
model.setTouser(touser);
model.setTemplate_id(WeChatConstants.WECHAT_SUBSCRIPTION_ALARM_TEMPLATE_ID);
model.setUrl("");
model.setTopcolor("#FF0000");
model.setData(data);
WeChatResult weChatResult = WeChatUtil.sendWeChatMessage(model);
if (weChatResult.getErrcode() == WeChatResultCode.access_token_expire.getValue() || weChatResult.getErrcode() == WeChatResultCode.access_token_overtime.getValue()) {
WeChatUtil.getWeChatToken();
weChatResult = WeChatUtil.sendWeChatMessage(model);
}
return weChatResult;
}catch (Exception e) {
log.error(e.getMessage());
return null;
}
}
}
里面有用到一些微信推送的常量,定义在了WeChatConstants
/**
* 微信服务接口常量
* @author lenny
*/
public class WeChatConstants {
private WeChatConstants() {
}
/**
* 微信推送AppID
*/
public static final String WECHAT_SUBSCRIPTION_APP_ID = "xxxxxxxx";
/**
* 微信推送密钥
*/
public static final String WECHAT_SUBSCRIPTION_APP_SECRET = "xxxxxxxxxxxxx";
/**
* 微信推送报警信息模板
*/
public static final String WECHAT_SUBSCRIPTION_ALARM_TEMPLATE_ID = "xxxxxxxxxxxxx";
/**
* 微信推送报警备注(中文)
*/
public static final String WECHAT_SUBSCRIPTION_ALARM_CN_REMARK="请尽快处理!";
/**
* 微信推送报警备注(英文)
*/
public static final String WECHAT_SUBSCRIPTION_ALARM_EN_REMARK="please handle it ASAP!";
}
微信推送结果实体类
/**
* 微信推送结果实体类
* @author Mr.lee
* @date 20210710
*/
@Data
public class WeChatResult {
private int errcode;
private String errmsg;
}
微信Token实体类
/**
* 微信Token实体类
* @author Mr.lee
* @date 20210710
*/
@Data
public class WeChatToken {
private String access_token;
private String expires_in;
}
微信推送参数实体类:
/**
* 微信推送参数实体
* @author Mr.Lee
* @date 20210710
*/
@Data
public class WeChatSendParam {
private String touser;
private String template_id;
private String url;
private String topcolor;
private Map<String,WeChatParaData> data;
}
微信推送内容参数:
/**
* 微信推送内容参数
* @author Mr.Lee
* @date 20210710
*/
@Data
public class WeChatParaData {
private String value;
private String color;
}
入参报警实体类
/**
* 报警入参
* @author Mr.Lee
* @date 20230331
*/
@Data
public class MessageAlarm {
private String vehicleName;
private String assetID;
private String dateTime;
private String lon;
private String lat;
private String alarmType;
private String alarmContent;
private String remark;
}
因为微信接口采用的是Api的方式进行调用的,所以这里贴出了我封装的HttpClient
/**
* http请求封装类
* @author lenny
* @date 20210710
*/
public class HttpClient {
public HttpClient(){
}
private CloseableHttpClient httpClient = HttpClientBuilder.create().build();
@Autowired
private RequestConfig config;
/**
* 不带参数的get请求,如果状态码为200,则返回body,如果不为200,则返回null
*
* @param url
* @return
* @throws Exception
*/
public String doGet(String url) {
try {
// 声明 http get 请求
HttpGet httpGet = new HttpGet(url);
// 装载配置信息
httpGet.setConfig(config);
// 发起请求
CloseableHttpResponse response = this.httpClient.execute(httpGet);
if(response!=null) {
return EntityUtils.toString(response.getEntity(), "UTF-8");
}else {
return null;
}
}catch (Exception e) {
return null;
}
}
/**
* 带参数的get请求,如果状态码为200,则返回body,如果不为200,则返回null
*
* @param url
* @return
* @throws Exception
*/
public String doGet(String url, Map<String, Object> map) throws Exception {
URIBuilder uriBuilder = new URIBuilder(url);
if (map != null) {
// 遍历map,拼接请求参数
for (Map.Entry<String, Object> entry : map.entrySet()) {
uriBuilder.setParameter(entry.getKey(), entry.getValue().toString());
}
}
// 调用不带参数的get请求
return this.doGet(uriBuilder.build().toString());
}
/**
* 不带参数post请求
*
* @param url
* @return
* @throws Exception
*/
public String doPost(String url) throws Exception {
return this.doPost(url, "");
}
/**
* 带Json参数的Post请求
* @param url
* @param jsonParam
* @return
* @throws Exception
*/
public String doPost(String url, String jsonParam) throws Exception{
String result = "";
// 声明httpPost请求
HttpPost httpPost = new HttpPost(url);
// 加入配置信息
httpPost.setConfig(config);
httpPost.setHeader("Content-Type", "application/json");
if(jsonParam.length()>0){
httpPost.setEntity(new StringEntity(jsonParam, ContentType.create("application/json", "utf-8")));
HttpResponse response = httpClient.execute(httpPost);
if (response != null && response.getStatusLine().getStatusCode() == 200) {
result = EntityUtils.toString(response.getEntity());
}
}
return result;
}
}
微信返回结果码: WeChatResultCode
/**
* 微信返回状态值
* @author Mr.Li
* @date 2023-09-06
*/
@Getter
public enum WeChatResultCode {
system_busy(-1,"系统繁忙"),
succeed(0,"请求成功"),
fail(40001,"验证失败"),
illegal_voucher_type(40002,"不合法的凭证类型"),
illegal_openid(40003,"不合法的OpenID"),
illegal_media_file_type(40004,"不合法的媒体文件类型"),
illegal_file_type(40005,"不合法的文件类型"),
illegal_file_size(40006,"不合法的文件大小"),
illegal_media_file_id(40007,"不合法的媒体文件id"),
illegal_message_type(40008,"不合法的消息类型"),
illegal_image_file_size(40009,"不合法的图片文件大小"),
illegal_audio_file_size(40010,"不合法的音频文件大小"),
illegal_video_file_size(40011,"不合法的视频文件大小"),
illegal_thumbnail_file_size(40012,"不合法的缩略图文件大小"),
illegal_app_id(40013,"不合法的APPID"),
missing_access_token(41001,"缺少access_token参数"),
missing_app_id(41002,"缺少appid参数"),
missing_refresh_token(41003,"缺少refresh_token参数"),
missing_secret(41004,"缺少secret参数"),
missing_media_file(41005,"缺少多媒体文件数据"),
access_token_overtime(41006,"access_token超时"),
access_token_expire(42001,"access_token过期"),
need_POST(43002,"需要POST请求"),
need_HTTPS(43003,"需要HTTPS请求"),
media_file_null(44001,"多媒体文件为空"),
post_data_null(44002,"POST的数据包为空"),
text_data_null(44003,"图文消息内容为空"),
media_file_size_exceeds_limit(45001,"多媒体文件大小超过限制"),
message_exceeds_limit(45002,"消息内容超过限制"),
title_exceeds_limit(45003,"标题字段超过限制"),
description_exceeds_limit(45004,"描述字段超过限制"),
link_exceeds_limit(45005,"链接字段超过限制"),
image_link_exceeds_limit(45006,"图片链接字段超过限制"),
audio_playback_time_exceeds_limit(45007,"音频播放时间超过限制"),
text_message_exceeds_limit(45008,"图文消息超过限制"),
interface_call_exceeds_limit(45009,"接口调用超过限制"),
media_data_not_existent(46001,"不存在媒体数据"),
parsing_JSON_error(47001,"解析JSON内容错误"),
unknow(-2, "未知异常");
private final int value;
private final String desc;
WeChatResultCode(int value, String desc) {
this.value = value;
this.desc = desc;
}
public static WeChatResultCode fromValue(int result) {
for (WeChatResultCode mediaEventEnum : values()) {
if (result == mediaEventEnum.getValue()) {
return mediaEventEnum;
}
}
return unknow;
}
}
HttpClient需要以下pom
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3.1</version>
</dependency>
<!-- httpClient文件上传需要 -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
</dependency>
三.其他说明
模板推送一个简单的微信服务号,用户需要关注此服务号才能实现推送模板消息的目的,并且推送方法中touser参数可以在用户关注微信服务号的时候通过前端传给后台并保存在数据库中。