随着微信使用越来越广泛,因其也产生了许多二次开发的小功能,今天要介绍的就是微信服务号的中的消息模板推送。
添加模板消息方式如上面,如果不满足可以添加自定义的,但是需要审核,周期为7到15天。消息模板内容一般如下:
我们需要用到的是模板Id,显示内容,first、keyword1、keyword2、keyword3、keyword4、remark我们传过来的值。
如果想要使用模板推送消息,我们首先得获取到access_token凭证,该凭证有效期为2个小时。我们可以获取的时候存起来,这里我是使用redis存储。
具体获取方式如下代码:
public static AccessToken getAccessToken() throws Exception {
//获取凭证地址
String accessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=SECRET";
CloseableHttpClient httpCilent = HttpClients.createDefault();
HttpGet httpGet = new HttpGet(accessTokenUrl);
try {
CloseableHttpResponse response = httpCilent.execute(httpGet);
System.out.println("code===="+response.getStatusLine().getStatusCode());
if (response.getStatusLine().getStatusCode() == 200) {
String entity = EntityUtils.toString(response.getEntity());
System.out.println("entity===="+entity);
AccessToken accessToken = JSONObject.parseObject(entity, AccessToken.class);
return accessToken;
}else {
logger.error("获取access_token发送get请求获取到的状态为:"+response.getStatusLine().getStatusCode());
return null;
}
} catch (IOException e) {
logger.error("获取access_token出错",e);
throw new Exception("获取access_token出错",e);
}finally {
try {
httpCilent.close();
} catch (IOException e) {
logger.error("关闭请求连接失败",e);
throw new Exception("关闭请求连接失败",e);
}
}
}
View Code
public class AccessToken {
// 获取到的凭证
private String access_token;
// 凭证有效时间,单位:秒
private Integer expires_in;
public String getAccess_token() {
return access_token;
}
public void setAccess_token(String access_token) {
this.access_token = access_token;
}
public Integer getExpires_in() {
return expires_in;
}
public void setExpires_in(Integer expires_in) {
this.expires_in = expires_in;
}
}
View Code
这里需要注意的是,微信获取access_token的接口有多种,这里我们使用的是这个接口:https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=SECRET
使用的get请求,其会返回一个json字符串:{"access_token":"xxx","expires_in":7200}的结果。其中还有一步很重要,就是需要设置ip白名单,如果不设置获取不到access_token。
获取到access_token后,还需要填充内容,具体的封装方式如下:
public class WechatTemplateMsg {
//发送人的openid
private String touser;
//消息模板Id
private String template_id;
//模板跳转链接
private String url;
//data数据
private TreeMap<String, TreeMap<String, String>> data;
//设置参数值,color可为空
public static TreeMap<String,String> init(String value,String color){
TreeMap<String, String> params = new TreeMap<String, String>();
params.put("value", value);
params.put("color", color);
return params;
}
public String getTouser() {
return touser;
}
public void setTouser(String touser) {
this.touser = touser;
}
public String getTemplate_id() {
return template_id;
}
public void setTemplate_id(String template_id) {
this.template_id = template_id;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public TreeMap<String, TreeMap<String, String>> getData() {
return data;
}
public void setData(TreeMap<String, TreeMap<String, String>> data) {
this.data = data;
}
}
View Code
public String leaderSendTemplate(String openid,String repairDate,String repairInfoCount,String resultCount) {
//封装信息
TreeMap<String, TreeMap<String, String>> params = new TreeMap<>();
params.put("first",WechatTemplateMsg.init("","#000000"));
//报表时间
params.put("keyword1",WechatTemplateMsg.init(repairDate,"#000000"));
//报修数量
params.put("keyword2",WechatTemplateMsg.init(repairInfoCount,"#000000"));
//维修完成数量
params.put("keyword3",WechatTemplateMsg.init(resultCount,"#000000"));
//内容
params.put("remark",WechatTemplateMsg.init("","#173177"));
ResourceBundle resource = ResourceBundle.getBundle("properties/pay");
String template_id =resource.getString("Leader_ID");//模板Id
String leaderUrl =resource.getString("leaderUrl");//转跳地址
WechatTemplateMsg templateMsg = new WechatTemplateMsg();
templateMsg.setTouser(openid);//报修人OpenId
templateMsg.setTemplate_id(template_id);
templateMsg.setUrl(leaderUrl);//跳转地址
templateMsg.setData(params);//参数
return JsonUtil.toJsonString(templateMsg);
}
View Code
这样我们就可以获取到String的date了,其中date的数据格式如下:
{"touser":"openid","template_id":"模板id","url":"需要转跳地址","data":{"first":{"color":"#000000","value":"您好,存在新 的待维修单,请查看!"},"keyword1":{"color":"#000000","value":"一体机1"},"keyword2":{"color":"#000000","value":"2019-01-28 10:00"},"keyword3":{"color":"#000000","value":"地址"},"keyword4":{"color":"#000000","value":"无"},"remark":{"color":"#173177","value":"感谢您的使用"}}}
我们就可以使用access_token或date发送消息了,具体如下:
public static String sendDate(String access_token,String data) throws Exception {
String sendUrl = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESSTOKEN";
sendUrl = sendUrl.replace("ACCESSTOKEN",access_token);
logger.info("sendUrl"+sendUrl);
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost(sendUrl);
try {
//转换参数
StringEntity dateSet = new StringEntity(data, ContentType.APPLICATION_JSON);
// 设置post求情参数
httpPost.setEntity(dateSet);
HttpResponse httpResponse = httpClient.execute(httpPost);
if (httpResponse.getStatusLine().getStatusCode() == 200) {
//发送成功
String entity = EntityUtils.toString(httpResponse.getEntity());
logger.info("返回结果:"+entity);
//返回结果
ResultTemplateDate resultTemplateDate = JSONObject.parseObject(entity, ResultTemplateDate.class);
return resultTemplateDate.getErrcode();
}else {
logger.error("StatusCode:"+httpResponse.getStatusLine().getStatusCode());
}
} catch (IOException e) {
logger.info("发送消息失败",e);
throw new Exception("发送消息失败",e);
}finally {
try {
httpClient.close();
} catch (IOException e) {
logger.error("关闭HttpClients异常");
throw new Exception("关闭HttpClients异常",e);
}
}
return "-1";
}
View Code
这样就发送成功了,返回成的结果为:{"errcode":0,"errmsg":"ok","msgid":655130036042940416}。
以下为一些工具类:
public class ResultTemplateDate {
//返回消息代码:0:成功
/*
* 常见错误状态码: 40001:不合法的调用凭证 、40003:不合法的OpenID
* 40030:不合法的refresh_token、
* 40036:不合法的template_id长度、40037:不合法的template_id
* 41009: 缺失openid参数
**/
private String errcode;
//返回信息:“ok”:成功
private String errmsg;
public String getErrcode() {
return errcode;
}
public void setErrcode(String errcode) {
this.errcode = errcode;
}
public String getErrmsg() {
return errmsg;
}
public void setErrmsg(String errmsg) {
this.errmsg = errmsg;
}
}
View Code
// 将对象转成String
public static String toJsonString(Object obj) {
if (obj == null) {
return "{}";
}
if (obj instanceof String) {
if (StringUtils.isEmpty(obj.toString())) {
return "{}";
}
}
String json = "";
try {
if (gson != null) {
json = gson.toJson(obj);
}
} catch (Exception e) {
return "{}";
}
return json;
}
View Code
在这过程中也遇到一些问题,其中最难的是遇到{"errcode":48001,"errmsg":"api unauthorized hint: [L5EA1a05308051!]"}这个错误,一开始以为没有微信没有认证,但去看了以及认证了,也有该接口权限,一直再找问题出现在哪。最后发现是调用错接口了。
这是第一次开发这个功能,如果不正确的地方,请指正,谢谢!