微信异步任务是在批量更新部门或者人员时使用,向微信服务器发送一个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 responseHandler = new ResponseHandler() {
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 responseHandler = new ResponseHandler() {
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
https://qyapi.weixin.qq.com/cgi-bin/batch/replaceuser?access_token=ACCESS_TOKEN
请求包结构体为:
{ "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字节 |