1. 程式人生 > >微信企業號開發九:非同步任務(全員覆蓋成員)

微信企業號開發九:非同步任務(全員覆蓋成員)

       微信非同步任務是在批量更新部門或者人員時使用,向微信伺服器傳送一個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位元組