相关文章
模板消息仅用于公众号向用户发送重要的服务通知,只能用于符合其要求的服务场景中,如信用卡刷卡通知,商品购买成功通知等
官方文档:模板消息接口
一、公共类
-
WXConstants.java
/** * 获取access_token接口 * 此处的ACCESS_TOKEN与授权登陆获得的ACCESS_TOKEN不同,有效期为7200s */ public static final String GET_ACCESS_TOKEN = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s"; /** * 设置所属行业接口 */ public static final String SET_INDUSTRY_URL = "https://api.weixin.qq.com/cgi-bin/template/api_set_industry?access_token=%s"; /** * 获得模板ID */ public static final String GET_TEMPLATE_ID = "https://api.weixin.qq.com/cgi-bin/template/api_add_template?access_token=%s"; /** * 发送模板消息 */ public static final String SEND_TEMPLATE_MSG = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s";
-
HttpUtils.java
@Slf4j public class HttpUtils { public static JSONObject sendGetRequest(String requestUrl) { return (JSONObject) sendHttpRequest(requestUrl, "GET", null, null, null, null); } public static JSONObject sendJsonPostRequest(String requestUrl, String data){ return (JSONObject) sendHttpRequest(requestUrl, "POST", "Content-Type", "application/json; charset=UTF-8", data, null); } public static String sendXmlPostRequest(String requestUrl, String xmlInfo){ return (String) sendHttpRequest(requestUrl, "POST", "Content-Type", "text/xml;charset=utf-8", null, xmlInfo); } private static Object sendHttpRequest(String requestUrl, String requestMethod, String requestPropertyKey, String requestPropertyValue, String data, String xmlInfo) { BufferedReader bufferedReader = null; try { URL url = new URL(requestUrl); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setDoOutput(true); conn.setDoInput(true); conn.setUseCaches(false); conn.setRequestMethod(requestMethod); if (StringUtils.isNotBlank(requestPropertyKey) && StringUtils.isNotBlank(requestPropertyValue)) { conn.setRequestProperty(requestPropertyKey, requestPropertyValue); } OutputStream outputStream = conn.getOutputStream(); if (StringUtils.isNotBlank(data) && StringUtils.isBlank(xmlInfo)) { // 在输出流中进行转码 outputStream.write(data.getBytes(StandardCharsets.UTF_8)); outputStream.close(); } if (StringUtils.isNotBlank(xmlInfo) && StringUtils.isBlank(data)) { // 在输出流中进行转码 outputStream.write(xmlInfo.getBytes(StandardCharsets.UTF_8)); outputStream.close(); } InputStream inputStream = conn.getInputStream(); InputStreamReader isr = new InputStreamReader(inputStream); bufferedReader = new BufferedReader(isr); String str; StringBuilder builder = new StringBuilder(); while ((str = bufferedReader.readLine()) != null) { builder.append(str); } conn.disconnect(); if (StringUtils.isNotBlank(xmlInfo) && StringUtils.isBlank(data)) { return builder.toString(); } else { return JSONObject.fromObject(builder.toString()); } } catch (Exception e) { log.error("发送http请求,失败", e); return null; } finally { // 释放资源 try { if(null != bufferedReader) { bufferedReader.close(); } } catch (IOException e) { log.error("释放资源,失败", e); } } } }
-
WXUtils.java
@Slf4j public class WXUtils { private static String appid = "xxxxxxxxxxxx"; private static String appsecret = "xxxxxxxxxxxx"; public static String getAccessToken() { // 使用自己公众号的 AppID、AppSecret String url = String.format(WXConstants.GET_ACCESS_TOKEN, appid, appsecret); JSONObject jsonObject = HttpUtils.sendGetRequest(url); if (jsonObject != null) { log.info("获取access_token,成功,返回信息为【{}】", jsonObject); return (String) jsonObject.get("access_token"); } return null; } }
二、设置所属行业
-
设置行业可在微信公众平台后台完成,每月可修改行业 1 次,帐号仅可使用所属行业中相关的模板
-
参数说明
-
调用接口 (https POST 请求)
https://api.weixin.qq.com/cgi-bin/template/api_set_industry?access_token=ACCESS_TOKEN
-
请求参数
参数 是否必须 说明 access_token 是 接口调用凭证 industry_id1 是 公众号模板消息所属行业编号 industry_id2 是 公众号模板消息所属行业编号 -
行业代码 (其余行业代码详见官方文档)
主行业 副行业 代码 IT科技 互联网/电子商务 1 IT科技 IT软件与服务 2 IT科技 IT硬件与设备 3 IT科技 电子技术 4 IT科技 通信与运营商 5 IT科技 网络游戏 6
-
-
设置所属行业
-
WXUtils.java
@Slf4j public class WXUtils { public static void setIndustry() { Optional.ofNullable(getAccessToken()).ifPresent(accessToken -> { JSONObject industry = new JSONObject(); // IT科技 IT软件与服务 industry.put("industry_id1", 2); // IT科技 IT硬件与设备 industry.put("industry_id2", 3); String url = String.format(WXConstants.SET_INDUSTRY_URL, accessToken); Optional.ofNullable(HttpUtils.sendJsonPostRequest(url, industry.toString())).ifPresent(jsonObject -> { if ((Integer) jsonObject.get("errcode") == 0) { log.info("设置所属行业,成功,返回信息为【{}】", jsonObject); } else { log.error("设置所属行业,失败,返回信息为【{}】", jsonObject); } }); }); } public static void main(String[] args) { setIndustry(); } }
-
测试结果
// 设置所属行业,成功,返回信息为【{"errcode":0,"errmsg":"ok"}】
-
三、获取模板 ID
-
从行业模板库选择模板到帐号后台,我们即可获取到对应的模板 ID,这里我们尝试下调用接口来获取模板 ID
-
路径:功能 --> 模板消息 --> 模板库
-
注意:每调用一次该接口,就等价于在账号后台将模板从【模板库】添加到【我的模板】,同时会生成一个模板 ID
-
-
参数说明
-
调用接口 (https POST 请求)
https://api.weixin.qq.com/cgi-bin/template/api_add_template?access_token=ACCESS_TOKEN
-
请求参数
参数 是否必须 说明 access_token 是 接口调用凭证 template_id_short 是 模板库中模板的编号,有 “TM**” 和 “OPENTMTM**” 等形式 -
返回参数
参数 说明 template_id 模板 ID
-
-
获取模板 ID
-
WXUtils.java
@Slf4j public class WXUtils { public static String getTemplateID(String templateIdShort) { String accessToken = getAccessToken(); if (StringUtils.isNotBlank(accessToken)) { JSONObject template = new JSONObject(); // templateIdShort 为模板库中模板的编号 template.put("template_id_short", templateIdShort); String url = String.format(WXConstants.GET_TEMPLATE_ID, accessToken); JSONObject jsonObject = HttpUtils.sendJsonPostRequest(url, template.toString()); if (jsonObject != null) { if ((Integer) jsonObject.get("errcode") == 0) { log.info("获取模板ID,成功,返回信息为【{}】", jsonObject); return (String) jsonObject.get("template_id"); } else { log.error("获取模板ID,失败,返回信息为【{}】", jsonObject); } } } return null; } public static void main(String[] args) { getTemplateID("TM00201"); } }
-
测试结果
// 获取模板ID,成功,返回信息为【{"errcode":0,"errmsg":"ok","template_id":"ePgZmrXWAwURCFHbr4p01WTI6GMS594f42YRNjXhcZY"}】
-
四、发送模板消息
-
参数说明
-
调用接口 (https POST 请求)
https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN
-
请求参数
参数 是否必须 说明 touser 是 接收者 openid template_id 是 模板 ID url 否 模板跳转链接 (海外帐号没有跳转能力) miniprogram 否 跳小程序所需数据,不需跳小程序可不用传该数据 appid 是 所需跳转到的小程序 appid
(该小程序 appid 必须与发模板消息的公众号是绑定关联关系,暂不支持小游戏)pagepath 否 所需跳转到小程序的具体页面路径,支持带参数,
(示例 index?foo=bar),要求该小程序已发布,暂不支持小游戏data 是 模板数据 color 否 模板内容字体颜色,不填默认为黑色 -
返回参数
参数 说明 msgid 消息 ID
-
-
发送模板消息
-
消息模板
-
SendTemplateMsgData.java
@Data public class SendTemplateMsgData { /** * 接收者openid */ private String touser; /** * 模板ID */ private String template_id; /** * 模板数据 */ private TemplateMsgData data; @Data public class TemplateMsgData { private First first; private Keyword1 keyword1; private Keyword2 keyword2; private Keyword3 keyword3; private Remark remark; } @Data public class First { private String value; public First(String value) { this.value = value; } } @Data public class Keyword1 { private String value; public Keyword1(String value) { this.value = value; } } @Data public class Keyword2 { private String value; public Keyword2(String value) { this.value = value; } } @Data public class Keyword3 { private String value; public Keyword3(String value) { this.value = value; } } @Data public class Remark { private String value; public Remark(String value) { this.value = value; } } }
-
WXUtils.java
@Slf4j public class WXUtils { private static String openid = "xxxxxxxxxxxx"; private static String first = "尊敬的用户,你好"; private static String keyword1 = "1号公寓1001房间"; private static String keyword2 = "电费剩余低于10度,请尽快缴费"; private static String keyword3 = "2018年8月6日 12:12"; private static String remark = "如有疑问,请联系管理员 电话:010-11111111"; public static void sendTemplateMsg(String templateId) { Optional.ofNullable(getAccessToken()).ifPresent(accessToken -> { SendTemplateMsgData sendTemplateMsgData = new SendTemplateMsgData(); sendTemplateMsgData.setTouser(openid); sendTemplateMsgData.setTemplate_id(templateId); SendTemplateMsgData.TemplateMsgData data = new SendTemplateMsgData().new TemplateMsgData(); data.setFirst(new SendTemplateMsgData().new First(first)); data.setKeyword1(new SendTemplateMsgData().new Keyword1(keyword1)); data.setKeyword2(new SendTemplateMsgData().new Keyword2(keyword2)); data.setKeyword3(new SendTemplateMsgData().new Keyword3(keyword3)); data.setRemark(new SendTemplateMsgData().new Remark(remark)); sendTemplateMsgData.setData(data); String url = String.format(WXConstants.SEND_TEMPLATE_MSG, accessToken); Optional.ofNullable(HttpUtils.sendJsonPostRequest(url, JSONObject .fromObject(sendTemplateMsgData).toString())).ifPresent(jsonObject -> { if ((Integer) jsonObject.get("errcode") == 0) { log.info("发送模板消息,成功,返回信息为【{}】", jsonObject); } else { log.error("发送模板消息,失败,返回信息为【{}】", jsonObject); } }); }); } public static void main(String[] args) { sendTemplateMsg("tXXutFOKEAI2sQVnXGK82ZR0KJiU868fEu6EBcQz2hQ"); } }
-
测试结果
-