package com.kindess.util;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* @author kindess
* @date Created in 2019/8/6 0006
* @description 模板消息推送工具类
*/
@Slf4j
@Transactional(rollbackFor = Exception.class)
public class TemplatePushUtil {
/**
* APPID
*/
public static final String APPID = "你的APPID";
/**
* APPSECRET
*/
public static final String APPSECRET = "你的APPSECRET";
/**
* 全局token
*/
public static final String ACCESS_TOKEN = "access_token";
/**
* 获取access_token的接口地址(GET) 限2000(次/天)
*/
public static final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + APPID + "&secret=" + APPSECRET;
/**
* 调用微信服务器IP
*/
public static final String GET_CALLBACK_IP_URL = "https://api.weixin.qq.com/cgi-bin/getcallbackip?access_token=ACCESS_TOKEN";
/**
* 课程进度提醒 模板ID
*/
public static final String courseTemplateId = "模板ID";
/**
* 发送模板消息
*
* @param openIds
* @param templateId
* @param detailUrl
* @param first
* @param keyword1
* @param keyword2
* @param keyword3
* @param remark
* @return json
*/
public synchronized String sendTemplateMessages(List<String> openIds, String templateId, String detailUrl, String first, String keyword1, String keyword2, String keyword3, String remark) {
//获取AccessToken
String accessToken = TemplatePushUtil.getRedisAccessToken();
String url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken;
String jsonStr = "";
try {
for (String openId : openIds) {
String json = "{\"data\":{\"first\":{\"color\":\"#173177\",\"value\":\"" + first + "\"},\"keyword1\":{\"color\":\"#173177\",\"value\":\"" + keyword1
+ "\"},\"keyword2\":{\"color\":\"#173177\",\"value\":\"" + keyword2 + "\"},\"keyword3\":{\"color\":\"#173177\",\"value\":\"" + keyword3
+ "\"},\"remark\":{\"color\":\"#173177\",\"value\":\"" + remark
+ "\"}},\"template_id\":\"" + templateId + "\",\"touser\":\"" + openId + "\",\"url\":\"" + detailUrl + "\"}";
jsonStr = HttpClientUtil.doPostJson(url, json);
}
log.info("sendTemplateMessages ok");
} catch (Exception e) {
e.printStackTrace();
log.error("sendTemplateMessages error {}:", e.getMessage());
}
return jsonStr;
}
/**
* 获取全局access_token
* 通过调用httpclient发送http请求(get方式)
*/
public static synchronized String getAccessToken() {
String result = HttpClientUtil.doGet(ACCESS_TOKEN_URL);
JSONObject resultJson = JSON.parseObject(result);
if (null != resultJson.get(ACCESS_TOKEN) && StringUtils.isNotEmpty(resultJson.get(ACCESS_TOKEN).toString())) {
log.info("accessToken:" + resultJson.get(ACCESS_TOKEN).toString());
return resultJson.get(ACCESS_TOKEN).toString();
} else {
log.info("errcode:" + resultJson.get("errcode").toString() + "--- errmsg:" + resultJson.get("errmsg").toString());
return null;
}
}
/**
* 从redis缓存拿取access_token
*/
public static String getRedisAccessToken() {
RedisUtil redisUtil = new RedisUtil();
String accessToken = "";
try {
//从redis拿取accessToken
if (redisUtil.exists(ACCESS_TOKEN)) {
if (StringUtils.isNotEmpty(redisUtil.get(ACCESS_TOKEN))) {
accessToken = redisUtil.get(ACCESS_TOKEN);
}
}
//如果没有,则重新发出请求拿取accessToken,并重新赋值
if (StringUtils.isEmpty(accessToken)) {
redisUtil.set(ACCESS_TOKEN, getAccessToken());
accessToken = redisUtil.get(ACCESS_TOKEN);
}
} catch (Exception e) {
log.error("redis缓存拿取access_token失败");
e.printStackTrace();
}
return accessToken;
}
/**
* access_token失效处理
* 目的:调用没有限制的接口去验证token的有效性,无效则重新获取,
* 1,调用微信服务器IP的接口
* 2,有效不处理
* 3,无效,则重新获取access_token,并刷新redis中access_token的值
*/
public static void doAccessTokenInvalid() {
RedisUtil redisUtil = new RedisUtil();
String accessToken = "";
try {
if (redisUtil.exists(ACCESS_TOKEN)) {
if (StringUtils.isNotEmpty(redisUtil.get(ACCESS_TOKEN))) {
accessToken = redisUtil.get(ACCESS_TOKEN);
}
}
log.info("调用微信服务器IP的接口");
if (StringUtils.isNotEmpty(accessToken)) {
String getcallbackipUrl = GET_CALLBACK_IP_URL.replace("ACCESS_TOKEN", accessToken);
String result = HttpClientUtil.doGet(getcallbackipUrl);
JSONObject resultJson = JSON.parseObject(result);
if (null != resultJson.get("errcode") && StringUtils.isNotEmpty(resultJson.get("errcode").toString())) {
//无效,则重新获取access_token
log.error("access_token无效了,重新获取.");
accessToken = getAccessToken();
redisUtil.set(ACCESS_TOKEN, accessToken);
} else {
log.info("access_token有效");
}
} else {
log.error("access_token为空,重新获取.");
accessToken = getAccessToken();
redisUtil.set(ACCESS_TOKEN, accessToken);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}