微信企業號開發九:非同步任務(全員覆蓋成員)
微信非同步任務是在批量更新部門或者人員時使用,向微信伺服器傳送一個CSV的檔案,微信伺服器會根據CSV檔案進行更新,下面是批量更新人員的模板。注意程式碼中CSV換行使用\n
全員覆蓋成員時,建議先進行覆蓋部門,然後再全員覆蓋人員,以免部門不存在造成異常
微信執行步驟:
1、生成一個CSV格式的檔案流,上傳到微信伺服器得到media_id,注意換行使用\n
2、利用media_id傳送訊息,通知微信伺服器執行非同步任務,得到jobid
3、利用jobid獲得非同步執行結果
---------------------------------------------------------------------------------------------------------------
上傳csv檔案
---------------------------------------------------------------------------------------------------------------
/** * 上傳csv檔案到騰訊伺服器 * @param content cvs檔案內容 * @return * @throws Exception */ public JSONObject sendCVSFile( String content) throws Exception { String result = null; String token=getTokenFromWx(); System.out.println("token:"+token); /** * 第一部分 */ URL urlObj = new URL("https://qyapi.weixin.qq.com/cgi-bin/media/upload?access_token="+ token + "&type=file"); HttpURLConnection con = (HttpURLConnection) urlObj.openConnection(); con.setRequestMethod("POST"); // 以Post方式提交表單,預設get方式 con.setDoInput(true); con.setDoOutput(true); con.setUseCaches(false); // post方式不能使用快取 // 設定請求頭資訊 con.setRequestProperty("Connection", "Keep-Alive"); con.setRequestProperty("Charset", "UTF-8"); // 設定邊界 String BOUNDARY = "----------" + System.currentTimeMillis(); con.setRequestProperty("Content-Type", "multipart/form-data; boundary="+ BOUNDARY); // 請求正文資訊 // 第一部分: StringBuilder sb = new StringBuilder(); sb.append("--"); // 必須多兩道線 sb.append(BOUNDARY); sb.append("\r\n"); sb.append("Content-Disposition: form-data;name=\"media\";filename=\""+ "info.csv" + "\"\r\n"); sb.append("Content-Type:application/octet-stream\r\n\r\n"); byte[] head = sb.toString().getBytes("utf-8"); // 獲得輸出流 OutputStream out = new DataOutputStream(con.getOutputStream()); // 輸出表頭 out.write(head); // 檔案正文部分 // 把檔案已流檔案的方式 推入到url中 DataInputStream in = new DataInputStream(new ByteArrayInputStream(content.getBytes())); int bytes = 0; byte[] bufferOut = new byte[1024]; while ((bytes = in.read(bufferOut)) != -1) { out.write(bufferOut, 0, bytes); } in.close(); // 結尾部分 byte[] foot = ("\r\n--" + BOUNDARY + "--\r\n").getBytes("utf-8");// 定義最後資料分隔線 out.write(foot); out.flush(); out.close(); StringBuffer buffer = new StringBuffer(); BufferedReader reader = null; try { // 定義BufferedReader輸入流來讀取URL的響應 reader = new BufferedReader(new InputStreamReader(con.getInputStream())); String line = null; while ((line = reader.readLine()) != null) { //System.out.println(line); buffer.append(line); } if(result==null){ result = buffer.toString(); } } catch (IOException e) { System.out.println("傳送POST請求出現異常!" + e); e.printStackTrace(); throw new IOException("資料讀取異常"); } finally { if(reader!=null){ reader.close(); } } JSONObject jsonObj =JSONObject.fromObject(result); return jsonObj; }
---------------------------------------------------------------------------------------------------------------
利用midea_id執行非同步任務
---------------------------------------------------------------------------------------------------------------
/** * 執行非同步任務 * @param mediaId 上傳的CVS檔案 * @param url 微信服務地址"https://qyapi.weixin.qq.com/cgi-bin/batch/replaceuser?access_token="+token; * @return */ public boolean sendCVSData(String mediaId,String url){ String jsonContext="{"+ "\"media_id\":\""+mediaId+"\","+ "\"callback\":"+ "{"+ "\"url\": \""+MessageUtil.webUrl+"/addressBookGetJbidServlet"+"\","+ "\"token\": \""+MessageUtil.RESP_MESSAGE_TOKEN+"\","+ "\"encodingaeskey\": \""+MessageUtil.RESP_MESSAGE_ENCODINGAESKEY+"\""+ "}"+ "}"; //傳送訊息 //訊息json格式 boolean flag=false; try { CloseableHttpClient httpclient = HttpClients.createDefault(); HttpPost httpPost= new HttpPost(url); //傳送json格式的資料 StringEntity myEntity = new StringEntity(jsonContext, ContentType.create("text/plain", "UTF-8")); httpPost.setEntity(myEntity); // Create a custom response handler ResponseHandler<JSONObject> responseHandler = new ResponseHandler<JSONObject>() { public JSONObject handleResponse( final HttpResponse response) throws ClientProtocolException, IOException { int status = response.getStatusLine().getStatusCode(); if (status >= 200 && status < 300) { HttpEntity entity = response.getEntity(); if(null!=entity){ String result= EntityUtils.toString(entity); //根據字串生成JSON物件 JSONObject resultObj = JSONObject.fromObject(result); return resultObj; }else{ return null; } } else { throw new ClientProtocolException("Unexpected response status: " + status); } } }; //返回的json物件 JSONObject responseBody = httpclient.execute(httpPost, responseHandler); System.out.println(responseBody); int result= (Integer) responseBody.get("errcode"); if(0==result){ flag=true; }else{ flag=false; } httpclient.close(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); return false; } return true; }
---------------------------------------------------------------------------------------------------------------
利用jobid獲得非同步執行結果
---------------------------------------------------------------------------------------------------------------
/**
* 獲得非同步任務結果
*/
public JSONObject getResultByjobid(String jobid){
//訊息json格式
//獲得token
String token=getTokenFromWx();
try {
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpPost httpPost= new HttpPost("https://qyapi.weixin.qq.com/cgi-bin/batch/getresult?access_token="+token+"&jobid="+jobid);
// Create a custom response handler
ResponseHandler<JSONObject> responseHandler = new ResponseHandler<JSONObject>() {
public JSONObject handleResponse(
final HttpResponse response) throws ClientProtocolException, IOException {
int status = response.getStatusLine().getStatusCode();
if (status >= 200 && status < 300) {
HttpEntity entity = response.getEntity();
if(null!=entity){
String result= EntityUtils.toString(entity);
//根據字串生成JSON物件
JSONObject resultObj = JSONObject.fromObject(result);
return resultObj;
}else{
return null;
}
} else {
throw new ClientProtocolException("Unexpected response status: " + status);
}
}
};
//返回的json物件
JSONObject responseBody = httpclient.execute(httpPost, responseHandler);
System.out.println(responseBody.toString());
return responseBody;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
全量覆蓋成員
- 介面說明
本介面以userid為主鍵,全量覆蓋企業號通訊錄成員,任務完成後企業號通訊錄成員與提交的檔案完全保持一致。請先下載CSV檔案(下載全量覆蓋成員模版),根據需求填寫檔案內容。
注意事項:
1.模板中的部門需填寫部門ID,多個部門用分號分隔,部門ID必須為數字
2.檔案中存在、通訊錄中也存在的成員,完全以檔案為準
3.檔案中存在、通訊錄中不存在的成員,執行新增操作
4.通訊錄中存在、檔案中不存在的成員,執行刪除操作。出於安全考慮,如果:
a) 需要刪除的成員多於50人,且多於現有人數的20%以上
b) 需要刪除的成員少於50人,且多於現有人數的80%以上
系統將中止匯入並返回相應的錯誤碼
5.成員欄位更新規則:檔案中有指定的欄位,以指定的欄位值為準;檔案中沒指定的欄位,不更新
- 請求說明
Https請求方式: POST
請求包結構體為:
{ "media_id":"xxxxxx", "callback": { "url": "xxx", "token": "xxx", "encodingaeskey": "xxx" } }
- 引數說明
引數 | 是否必須 | 描述 |
---|---|---|
media_id | 是 | 上傳的csv檔案的media_id |
callback | 否 | 回撥資訊。如填寫該項則任務完成後,通過callback推送事件給企業。具體請參考應用回撥模式中的相應選項 |
url | 否 | 企業應用接收企業號推送請求的訪問協議和地址,支援http或https協議 |
token | 否 | 用於生成簽名 |
encodingaeskey | 否 | 用於訊息體的加密,是AES金鑰的Base64編碼 |
- 許可權說明
管理組須擁有根部門的管理許可權。
- 返回結果
{ "errcode": 0, "errmsg": "ok", "jobid": "xxxxx" }
引數 | 說明 |
---|---|
errcode | 返回碼 |
errmsg | 對返回碼的文字描述內容 |
jobid | 非同步任務id,最大長度為64位元組 |