隨着微信使用越來越廣泛,因其也產生了許多二次開發的小功能,今天要介紹的就是微信服務號的中的消息模板推送。

添加模板消息方式如上面,如果不滿足可以添加自定義的,但是需要審核,周期為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); } } }
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; } }
這里需要注意的是,微信獲取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; } }
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); }
這樣我們就可以獲取到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"; }
這樣就發送成功了,返回成的結果為:{"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; } }
// 將對象轉成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; }
在這過程中也遇到一些問題,其中最難的是遇到{"errcode":48001,"errmsg":"api unauthorized hint: [L5EA1a05308051!]"}這個錯誤,一開始以為沒有微信沒有認證,但去看了以及認證了,也有該接口權限,一直再找問題出現在哪。最后發現是調用錯接口了。
這是第一次開發這個功能,如果不正確的地方,請指正,謝謝!
