java開發企業微信-------訊息自動推送
阿新 • • 發佈:2019-01-03
要實現企業微信中訊息推送的功能,類似如下這種:
企業微信訊息實體類
package com.ducetech.jeewx.api.wxsendmsg.model; import java.io.Serializable; /** * @ClassName: WeChatMsg * @Description: 企業微信訊息類 * @author * @date * */ public class WeChatMsg implements Serializable { private static final long serialVersionUID = 1L; private String toUser; // 訊息接收人 private String toParty; // 部門ID列表,多個接收者用‘|’分隔,最多支援100個。當touser為@all時忽略本引數 private String toTag; // 標籤ID列表,多個接收者用‘|’分隔,最多支援100個。當touser為@all時忽略本引數 private String msgType; // 訊息型別 private String agentId; // 企業應用的id,整型。可在應用的設定頁面檢視 private String title; // 標題,不超過128個位元組,超過會自動截斷 private String description; // 描述,不超過512個位元組,超過會自動截斷 private String thumbMediaId; // 圖文訊息縮圖的media_id, 可以通過素材管理介面獲得。此處thumb_media_id即上傳介面返回的media_id private String mediaId; // 檔案id,可以呼叫上傳臨時素材介面獲取 private String picUrl; // 圖文訊息的圖片連結,支援JPG、PNG格式,較好的效果為大圖640320,小圖8080。 private String btnTxt; // 按鈕文字,僅在圖文數為1條時才生效。 預設為“閱讀全文”, 不超過4個文字,超過自動截斷。該設定只在企業微信上生效,微工作臺(原企業號)上不生效。 private String author; // 圖文訊息的作者,不超過64個位元組 private String contentSourceUrl;//url(news) 點選後跳轉的連結。 private String content; // 圖文訊息的內容,支援html標籤,不超過666 K個位元組 private String digest; // 圖文訊息的描述,不超過512個位元組,超過會自動截斷 private String safe; // 表示是否是保密訊息,0表示否,1表示是,預設0 public String getToUser() { return toUser; } public void setToUser(String toUser) { this.toUser = toUser; } public String getToParty() { return toParty; } public void setToParty(String toParty) { this.toParty = toParty; } public String getToTag() { return toTag; } public void setToTag(String toTag) { this.toTag = toTag; } public String getMsgType() { return msgType; } public void setMsgType(String msgType) { this.msgType = msgType; } public String getAgentId() { return agentId; } public void setAgentId(String agentId) { this.agentId = agentId; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getThumbMediaId() { return thumbMediaId; } public void setThumbMediaId(String thumbMediaId) { this.thumbMediaId = thumbMediaId; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public String getContentSourceUrl() { return contentSourceUrl; } public void setContentSourceUrl(String contentSourceUrl) { this.contentSourceUrl = contentSourceUrl; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } public String getDigest() { return digest; } public void setDigest(String digest) { this.digest = digest; } public String getSafe() { return safe; } public void setSafe(String safe) { this.safe = safe; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public String getPicUrl() { return picUrl; } public void setPicUrl(String picUrl) { this.picUrl = picUrl; } public String getBtnTxt() { return btnTxt; } public String getMediaId() { return mediaId; } public void setMediaId(String mediaId) { this.mediaId = mediaId; } public void setBtnTxt(String btnTxt) { this.btnTxt = btnTxt; } }
企業微信訊息的方法
package com.ducetech.util; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.ConnectException; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.annotation.PostConstruct; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.ducetech.jeewx.api.core.common.MyX509TrustManager; import com.ducetech.jeewx.api.wxsendmsg.model.WeChatMsg; import com.ducetech.jeewx.constant.WxConstant; import com.ducetech.redis.MyRedisTemplate; @Component public class WXUtils { @Autowired private MyRedisTemplate redisTemplateAutoWired; private static MyRedisTemplate redisTemplate; private static Logger logger = LoggerFactory.getLogger(WXUtils.class); @PostConstruct public void init() { redisTemplate = redisTemplateAutoWired; } /** * 獲取企業微信API返回的JSONObject * @return * @throws IOException */ public static JSONObject getURLJSONObject(String requestUrl, String requestMethod, String outputStr) { JSONObject jsonObject = null; StringBuffer buffer = new StringBuffer(); try { // 建立SSLContext物件,並使用我們指定的信任管理器初始化 TrustManager[] tm = { new MyX509TrustManager() }; SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE"); sslContext.init(null, tm, new java.security.SecureRandom()); // 從上述SSLContext物件中得到SSLSocketFactory物件 SSLSocketFactory ssf = sslContext.getSocketFactory(); //開啟連線 URL url = new URL(requestUrl); HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection(); httpUrlConn.setSSLSocketFactory(ssf); httpUrlConn.setDoOutput(true); httpUrlConn.setDoInput(true); httpUrlConn.setUseCaches(false); // 設定請求方式(GET/POST) httpUrlConn.setRequestMethod(requestMethod.toUpperCase()); if ("GET".equalsIgnoreCase(requestMethod)){ httpUrlConn.connect(); } // 當有資料需要提交時 if (null != outputStr) { OutputStream outputStream = httpUrlConn.getOutputStream(); // 注意編碼格式,防止中文亂碼 outputStream.write(outputStr.getBytes("UTF-8")); outputStream.close(); } // 將返回的輸入流轉換成字串 InputStream inputStream = httpUrlConn.getInputStream(); InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8"); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); String str = null; while ((str = bufferedReader.readLine()) != null) { buffer.append(str); } bufferedReader.close(); inputStreamReader.close(); // 釋放資源 inputStream.close(); inputStream = null; httpUrlConn.disconnect(); jsonObject = JSONObject.parseObject(buffer.toString()); } catch (ConnectException ce) { logger.error("Weixin server connection timed out."); } catch (Exception e) { logger.error("https request error:{}", e); } return jsonObject; } /*public static JSONObject getURLJSONObject(String url) throws IOException { URL u = new URL(url); HttpsURLConnection huconn = (HttpsURLConnection) u.openConnection(); BufferedReader in = null; StringBuilder result = new StringBuilder(); huconn.connect(); in = new BufferedReader(new InputStreamReader(huconn.getInputStream(), "UTF-8")); String line; while ((line = in.readLine()) != null) { result.append(line); } if (in != null) { in.close(); } JSONObject jsonObject = JSONObject.parseObject(result.toString()); return jsonObject; }*/ /** * 獲取AccessToken * @param request * @param response * @return * @throws IOException */ public static String getAccessToken(HttpServletRequest request, HttpServletResponse response) throws IOException { /*String wxAccessToken = (String) redisTemplate.getItem("wxAccessToken"); if (null != wxAccessToken) { return wxAccessToken; // response.getWriter().write(wxAccessToken); } else { String url = WxConstant.GET_ACCESS_TOKEN_URL; JSONObject jsonObject = getURLJSONObject(url, "GET", null); wxAccessToken = jsonObject.getString("access_token"); redisTemplate.setItem("examAccessToken", wxAccessToken); redisTemplate.expire("examAccessToken", 7000); return wxAccessToken; // response.getWriter().write(wxAccessToken); }*/ return getAccessToken(); } /** * 獲取AccessToken * @return * @throws IOException */ public static String getAccessToken() throws IOException { String wxAccessToken = (String) redisTemplate.getItem("examAccessToken"); if (null != wxAccessToken) { return wxAccessToken; // response.getWriter().write(wxAccessToken); } else { String url = WxConstant.GET_ACCESS_TOKEN_URL; JSONObject jsonObject = getURLJSONObject(url, "GET", null); wxAccessToken = jsonObject.getString("access_token"); redisTemplate.setItem("examAccessToken", wxAccessToken); redisTemplate.expire("examAccessToken", 7000); return wxAccessToken; // response.getWriter().write(wxAccessToken); } } /** * 獲取企業微信訊息模板 * @param msg * @return */ public static String getMsgTemplate(WeChatMsg msg) { String msgType = msg.getMsgType(); if("mpnews".equalsIgnoreCase(msgType)) { // 圖文訊息(mpnews) JSONObject msgObj = new JSONObject(); msgObj.put("touser", msg.getToUser());//"touser" : "UserID1|UserID2|UserID3" msgObj.put("toparty", msg.getToParty()); msgObj.put("totag", msg.getToTag()); msgObj.put("msgtype", msgType); msgObj.put("agentid", msg.getAgentId());//(String, Long) JSONObject articles = new JSONObject(); articles.put("title", msg.getTitle()); articles.put("thumb_media_id",msg.getThumbMediaId());//TODO:需要呼叫素材管理的介面 articles.put("author", msg.getAuthor()); articles.put("content_source_url", msg.getContentSourceUrl()); articles.put("content", msg.getContent()); articles.put("digest", msg.getDigest()); msgObj.put("articles", JSON.toJSONString(articles)); msgObj.put("safe", msg.getSafe()); return JSON.toJSONString(msgObj); } if("news".equalsIgnoreCase(msgType)) { // 圖文訊息(news) JSONObject msgObj = new JSONObject(); msgObj.put("touser", msg.getToUser());//"touser" : "UserID1|UserID2|UserID3" msgObj.put("toparty", msg.getToParty()); msgObj.put("totag", msg.getToTag()); msgObj.put("msgtype", msgType); msgObj.put("agentid", msg.getAgentId());//(String, Long) Map<String, List<JSONObject>> articles = new HashMap<>(); List<JSONObject> articleList = new ArrayList<>(); JSONObject article = new JSONObject(); article.put("title", msg.getTitle()); article.put("description",msg.getDescription()); article.put("url", msg.getContentSourceUrl()); article.put("picurl", msg.getPicUrl()); article.put("btntxt", msg.getBtnTxt()); articleList.add(article); /*JSONObject article1 = new JSONObject(); article1.put("title", msg.getTitle()); article1.put("description",msg.getDescription()); article1.put("url", msg.getContentSourceUrl()); article1.put("picurl", msg.getPicUrl()); article1.put("btntxt", msg.getBtnTxt()); articleList.add(article1);*/ articles.put("articles", articleList); msgObj.put("news", articles); return JSON.toJSONString(msgObj); } if("textcard".equalsIgnoreCase(msgType)) { // 文字卡片訊息(textcard) JSONObject msgObj = new JSONObject(); msgObj.put("touser", msg.getToUser());//"touser" : "UserID1|UserID2|UserID3" msgObj.put("toparty", msg.getToParty()); msgObj.put("totag", msg.getToTag()); msgObj.put("msgtype", msgType); msgObj.put("agentid", msg.getAgentId());//(String, Long) JSONObject textcard = new JSONObject(); textcard.put("title", msg.getTitle()); textcard.put("description",msg.getDescription()); textcard.put("url", msg.getContentSourceUrl()); textcard.put("btntxt", msg.getBtnTxt()); msgObj.put("textcard", textcard); return JSON.toJSONString(msgObj); }if("file".equalsIgnoreCase(msgType)) { // 檔案訊息(file) JSONObject msgObj = new JSONObject(); msgObj.put("touser", msg.getToUser());//"touser" : "UserID1|UserID2|UserID3" msgObj.put("toparty", msg.getToParty()); msgObj.put("totag", msg.getToTag()); msgObj.put("msgtype", msgType); msgObj.put("agentid", msg.getAgentId());//(String, Long) JSONObject file = new JSONObject(); file.put("media_id", msg.getMediaId()); msgObj.put("file", file); msgObj.put("safe", msg.getSafe()); return JSON.toJSONString(msgObj); } if("text".equalsIgnoreCase(msgType)) { // 文字訊息(text) JSONObject msgObj = new JSONObject(); msgObj.put("touser", msg.getToUser());//"touser" : "UserID1|UserID2|UserID3" msgObj.put("totag", msg.getToTag()); msgObj.put("msgtype", msgType); msgObj.put("agentid", msg.getAgentId());//(String, Long) JSONObject text = new JSONObject(); text.put("content", msg.getContent()); msgObj.put("text", text); return JSON.toJSONString(msgObj); } return ""; } public static int sendMpNews(WeChatMsg msg, HttpServletRequest request, HttpServletResponse response) throws IOException { // https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=ACCESS_TOKEN /*int result = 0; String msgTemplate = WXUtils.getMsgTemplate(msg); String accessToken = WXUtils.getAccessToken(request, response); String sendMpNewsUrl = WxConstant.POST_MSG + accessToken; JSONObject mpNews = WXUtils.getURLJSONObject(sendMpNewsUrl, "POST", msgTemplate); if (null != mpNews) { result = mpNews.getIntValue("errcode"); }*/ return sendMpNews(msg); } public static int sendMpNews(WeChatMsg msg) throws IOException { // https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=ACCESS_TOKEN int result = 0; String msgTemplate = WXUtils.getMsgTemplate(msg); String accessToken = WXUtils.getAccessToken(); String sendMpNewsUrl = WxConstant.POST_MSG + accessToken; JSONObject mpNews = WXUtils.getURLJSONObject(sendMpNewsUrl, "POST", msgTemplate); if (null != mpNews) { result = mpNews.getIntValue("errcode"); } return result; } }
用到的常量
//獲取AccessToken的url public static final String GET_ACCESS_TOKEN_URL = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" + corpID + "&corpsecret=" + corpSecret; //傳送應用訊息 public static final String POST_MSG = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token="; //傳送訊息 public static final String MSG_URL = "http://********.com:8883/examApp";//合法域名
傳送訊息通知
try {
WeChatMsg msg = new WeChatMsg();
msg.setAgentId(WxConstant.agentId); //企業應用的id
msg.setMsgType("textcard"); //訊息型別 文字
msg.setToUser(wxIds); //訊息接收人
msg.setTitle("線上評估"); //標題
msg.setDescription("您有一條新的評估測試待完成,結束時間為:"+ DateUtil.formatDate(questionBank.getEndDate(),0,10)); //描述
msg.setContentSourceUrl(WxConstant.MSG_URL+"/questions?levelId = "+questionBank.getLevelId()+"&classifyId = "+questionBank.getClassifyId()); //url(news) 點選後跳轉的連結
msg.setBtnTxt("檢視詳情");
WXUtils.sendMpNews(msg);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
以上,搞定了