內容概要
本篇文章主要敘述如何在微信公眾帳號上實現“發送模板消息開發”功能。包含json的封裝與解析。
何謂模板消息
為了保證用戶不受到騷擾,在開發者出現需要主動提醒、通知用戶時,才允許開發者在公眾平台網站中模板消息庫中選擇模板,選擇後獲得模板ID,再根據模板ID向用戶主動推送提醒、通知消息。
注意:模板消息只能開發者主動向微信用戶發送,不能有用戶被動發起。
尋找接口(數據源)
開發者需向微信服務器發送post請求,並攜帶根據模板配裝好的一個json包。
請求地址:
https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN
json格式:
參考微信接口文檔https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1433751277&token=&lang=zh_CN
開發步驟
1) 獲取模板ID
2) 構造模版消息體並請求接口
代碼及實現
獲取模板id:
1、具有支付能力的公眾號才可以使用模板消息進行服務。在微信公眾平台的後台,依次進入“功能->添加功能插件->模版消息”,即可申請模版消息。
點擊申請
申請時,選擇2個和自己相關的兩個行業即可。
提交並且申請通過後,可以在模版庫中看到模版消息列表
進入想使用的模板,點擊添加
添加後就存到“我的模板庫”中了(每個賬號可以最多可以添加10個模板到“我的模板庫”中)
查看模版的詳情,可以看到模版id及各項內容參數名。
不同的模版消息的內容結構不一樣。這些id及字段名將在程序中使用到。
注意:如果模板庫中沒有你想使用的模板時,可以在模板庫頁面點擊“幫助我們完善模板庫”創建自己的消息模板,創建消息模板需要申請,審核通過後該模板將被添加到該行業的模板庫中。每個賬號每月只能申請3個模板。
點擊幫助我們完善模板庫
代碼實現(java,建議將代碼復制到Eclipse編輯器,看起來效果就不凌亂了):
1、構造模板體(json包),以交易提醒模板為例,這裡封裝成一個TradingNotice類。構造該類時需傳入接收者微信的openid、模 板id、模板主體顏色、用戶名。代碼中采用LinkedHashMap是為了保證數據是以存入的順序排序,從而保證json格式的結構不被打亂。
import java.util.LinkedHashMap; import java.util.Map; public class TradingNotice { private Map<String,Object> map; private Map<String,Object> data; public TradingNotice(String touser, String template_id, String url, String topcolor,String user) { map=new LinkedHashMap<String, Object>(); data=new LinkedHashMap<String, Object>(); LinkedHashMap<String,String> first = new LinkedHashMap<String,String>(); first.put("value","尊敬的" +user + ":\n\n您尾號為0426的招商銀行卡最近有一筆交易(測試)"); first.put("color","#743A3A"); data.put("first",first); LinkedHashMap<String,String> keyword1 = new LinkedHashMap<String,String>(); keyword1.put("value","YXJ134953845"); keyword1.put("color","#FF0000"); data.put("keyword1",keyword1); LinkedHashMap<String,String> keyword2 = new LinkedHashMap<String,String>(); keyword2.put("value","2014/08/18 13:18"); keyword2.put("color","#C4C400"); data.put("keyword2",keyword2); LinkedHashMap<String,String> keyword3 = new LinkedHashMap<String,String>(); keyword3.put("value","1888888888"); keyword3.put("color","#0000FF"); data.put("keyword3",keyword3); LinkedHashMap<String,String> keyword4 = new LinkedHashMap<String,String>(); keyword4.put("value","消費"); keyword4.put("color","#008000"); data.put("keyword4",keyword4); LinkedHashMap<String,String> keyword5 = new LinkedHashMap<String,String>(); keyword5.put("value","26萬元"); keyword5.put("color","#008000"); data.put("keyword5",keyword5); LinkedHashMap<String,String> remark = new LinkedHashMap<String,String>(); remark.put("value","\n\n截止2014/08/18 13:18您招商信用賬戶可用余額未20000元"); remark.put("color","#000000"); data.put("remark",remark); map.put("touser",touser); map.put("template_id",template_id); map.put("url",url); map.put("topcolor",topcolor); map.put("data",data); } public Map<String,Object> getMap() { return map; } public void setMap(Map<String,Object> map){ this.map = map; } public Map<String,Object> getDate() { return data; } public void setDate(Map<String,Object> date){ this.data =date; } } 2、方法create_TN_Json用來構造json包,方法getUserData用來獲取關注者昵稱,需傳入客戶的openid。方法getUserList用來獲取微信關注者列表,將所有關注者的openid保存在一個ArrayList中。由於獲取關注者列表一次只能獲取1000個微信號,所以當關注者多余1000的時候循環調用方法getUserJson來獲取所有關注者賬號。 獲取關注這列表可參考微信公眾平台接口文檔,地址http://mp.weixin.qq.com/wiki/index.php?title=獲取關注者列表 方法send_Json用來發送模板消息請求,必須采用post請求 import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.HttpURLConnection; import java.net.URL; import java.util.ArrayList; import java.util.Iterator; import wx.sunl.menus.Get_Token; import wx.sunl.template.TradingNotice; import net.sf.json.JSONObject; public class Create_Json { //獲取交易提醒json; public static JSONObjectcreate_TN_Json(String touser,String user){ JSONObjectjsonObject=null; //模板id Stringtemplate_id="15Eox4OfGsjFYaVRwk9Dbos_aaIkzveCkpG3AsnKqLA"; //點擊模板後的鏈接地址 String url="www.baidu.com"; //模板的主題顏色 String topcolor="#008000"; //構造json包 TradingNotice wn = new TradingNotice(touser,template_id,url,topcolor,user); jsonObject=JSONObject.fromObject(wn.getMap()); return jsonObject; } //入口; public static void main(String[] args){ //檢查access_token是否過期,如果過期重新產生 //Get_Token.TwoDate(); //調用getUserList獲取關注者列表 ArrayList<String>users= getUserList(); if(users!=null){ Iterator<String> user = users.iterator(); JSONObject jsonObject1 = null; String open_id = null; String userName = null; while(user.hasNext()){ open_id = user.next(); //調用getUserData獲取關注者昵稱 userName = getUserData(open_id); if(userName!=null){ //創建交易提醒json包; jsonObject1 = Create_Json.create_TN_Json(open_id,userName); //發送交易提醒模板消息; send_Json(jsonObject1.toString(),Get_Token.access_token); } } } } //獲取用戶基本信息(UnionID機制); public static String getUserData(String openid){ StringBuffer bufferRes = new StringBuffer(); String result = null; try { URL realUrl = new URL("https://api.weixin.qq.com/cgi-bin/user/info?access_token=" + Get_Token.access_token +"&openid=" + openid+"&lang=zh_CN"); HttpURLConnection conn = (HttpURLConnection)realUrl.openConnection(); // 請求方式 conn.setDoOutput(true); conn.setDoInput(true); conn.setRequestMethod("GET"); conn.setUseCaches(false); conn.setInstanceFollowRedirects(true); conn.setRequestProperty("Content-Type","application/json"); conn.connect(); // 獲取URLConnection對象對應的輸入流 InputStream in =conn.getInputStream(); BufferedReader read =new BufferedReader(new InputStreamReader(in,"UTF-8")); String valueString =null; while ((valueString=read.readLine())!=null){ bufferRes.append(valueString); } System.out.println(bufferRes); in.close(); if (conn != null){ // 關閉連接 conn.disconnect(); } } catch (Exceptione) { e.printStackTrace(); } //將返回的字符串轉換成json JSONObject jsonObject = JSONObject.fromObject(bufferRes.toString()); //解析json中的數據 String subscribe = jsonObject.get("subscribe").toString(); //等於1表示有關注者,0表示沒有關注者 if("1".equals(subscribe.toString())){ //解析出關注者的昵稱 result = (String)jsonObject.get("nickname"); } return result; } //獲取關注列表; @SuppressWarnings("unchecked") public static ArrayList<String> getUserList() { StringBuffer bufferRes = new StringBuffer(); ArrayList<String> users = null; try { URL realUrl = new URL("https://api.weixin.qq.com/cgi-bin/user/get?access_token=" + Get_Token.access_token); HttpURLConnection conn = (HttpURLConnection)realUrl.openConnection(); // 請求方式 conn.setDoOutput(true); conn.setDoInput(true); conn.setRequestMethod("GET"); conn.setUseCaches(false); conn.setInstanceFollowRedirects(true); conn.setRequestProperty("Content-Type","application/json"); conn.connect(); // 獲取URLConnection對象對應的輸入流 InputStream in =conn.getInputStream(); BufferedReader read =new BufferedReader(new InputStreamReader(in,"UTF-8")); String valueString =null; while ((valueString=read.readLine())!=null){ bufferRes.append(valueString); } System.out.println(bufferRes); in.close(); if (conn !=null){ // 關閉連接 conn.disconnect(); } } catch (Exceptione) { e.printStackTrace(); } //將返回的字符串轉換成json JSONObject jsonObject = JSONObject.fromObject(bufferRes.toString()); //解析json中表示openid的列表 JSONObject data = (JSONObject)jsonObject.get("data"); if(data!=null){ //將openid列表轉化成數組保存 users = newArrayList<String>(data.getJSONArray("openid")); //獲取關注者總數 intcount = Integer.parseInt(jsonObject.get("total").toString()); if(count>1000){ JSONObject object = jsonObject; String next_openid = null; JSONObject ob_data = null; ArrayList<String> ob_user = null; //大於1000需要多次獲取,或許次數為count/1000 for(inti=0;i<count/1000;i++){ //解析出下次獲取的啟示openid next_openid = object.get("next_openid").toString(); object = getUserJson(next_openid); ob_data = (JSONObject)object.get("data"); ob_user = newArrayList<String>(ob_data.getJSONArray("openid")); for(Stringopen_id : ob_user){ //將多次獲取的openid添加到同一個數組 users.add(open_id); } } } } return users; } //連續獲取關注列表; public static JSONObject getUserJson(String next_openid) { StringBuffer bufferRes =new StringBuffer(); try { URL realUrl = new URL("https://api.weixin.qq.com/cgi-bin/user/get?access_token=" + Get_Token.access_token +"&next_openid=" + next_openid); HttpURLConnection conn = (HttpURLConnection)realUrl.openConnection(); // 請求方式 conn.setDoOutput(true); conn.setDoInput(true); conn.setRequestMethod("GET"); conn.setUseCaches(false); conn.setInstanceFollowRedirects(true); conn.setRequestProperty("Content-Type","application/json"); conn.connect(); // 獲取URLConnection對象對應的輸入流 InputStream in =conn.getInputStream(); BufferedReader read =new BufferedReader(new InputStreamReader(in,"UTF-8")); String valueString =null; while ((valueString=read.readLine())!=null){ bufferRes.append(valueString); } System.out.println(bufferRes); in.close(); if (conn !=null){ // 關閉連接 conn.disconnect(); } } catch (Exceptione) { e.printStackTrace(); } JSONObject jsonObject = JSONObject.fromObject(bufferRes); return jsonObject; } //發送模板; public static void send_Json(Stringparams,StringaccessToken){ StringBuffer bufferRes =new StringBuffer(); try { URL realUrl = new URL("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" +accessToken); HttpURLConnection conn = (HttpURLConnection)realUrl.openConnection(); // 請求方式 conn.setDoOutput(true); conn.setDoInput(true); conn.setRequestMethod("POST"); conn.setUseCaches(false); conn.setInstanceFollowRedirects(true); conn.setRequestProperty("Content-Type","application/json"); conn.connect(); // 獲取URLConnection對象對應的輸出流 OutputStreamWriter out =new OutputStreamWriter(conn.getOutputStream(),"UTF-8"); // 發送請求參數 //out.write(URLEncoder.encode(params,"UTF-8")); //發送json包 out.write(params); out.flush(); out.close(); InputStream in =conn.getInputStream(); BufferedReader read =new BufferedReader(new InputStreamReader(in,"UTF-8")); String valueString =null; while ((valueString=read.readLine())!=null){ bufferRes.append(valueString); } //輸出返回的json System.out.println(bufferRes); in.close(); if (conn !=null){ // 關閉連接 conn.disconnect(); } } catch (Exceptione) { e.printStackTrace(); } } } 注意: 創建json包時要根據模板內容構造。 列如:交易提醒創建的json為: {"touser":"", "template_id":"", "url":"", "topcolor":"", "data":{ "first":{"value":"","color":""}, "keyword1":{"value":"","color":""}, "keyword2":{"value":"","color":""}, "keyword3":{"value":"","color":""}, "keyword4":{"value":"","color":""}, "keyword5":{"value":"","color":""}, "remark":{"value":"","color":""}}} 筆試通知提醒創建的json為: {"touser":"", "template_id":"", "url":"", "topcolor":"", "data":{ "first":{"value":"","color":""}, "company":{"value":"","color":""}, "datetime":{"value":"","color":""}, "address":{"value":"","color":""}, "contact":{"value":"","color":""}, "remark":{"value":"","color":""}}}