Java企业微信开发_部门和管理账号同步企业微信通讯录

一.获取通讯录密钥

获取方式:

       登录企业微信—>管理工具—>通讯录同步助手—>开启“API接口同步”  ; 开启后,即可看到通讯录密钥,也可设置通讯录API的权限:读取或者编辑通讯录。

获取通讯录密钥的目的:

        通过企业ID(CorpId)和 通讯录密钥可以获取通讯录相关接口的使用凭证(AccessToken)。有了AccessToken,就可以使用通讯录相关接口了。

凭证的获取方式有两种(此处暂时存疑,以待勘误):

通讯录AccessToken:CorpId+通讯录密钥

其他AccessToken:CorpId+应用密钥

 二、创建接口类

public interface QyApiService {

    /**
     * 企业微信全量同步部门
     * @return
     * @throws Exception
     */
    AjaxJson synchronizationDepart() throws Exception;

    /**
     * 企业微信全量覆盖成员
     * @return
     * @throws Exception
     */
    AjaxJson synchronizationUser() throws Exception;

    /**
     * 获取异步任务结果
     * @return
     * @throws Exception
     */
    AjaxJson getQyWeixinResult(HttpServletRequest request) throws Exception;
}

三、创建实现类

@Service
public class QyApiServiceImpl implements QyApiService {

    private static final Logger logger = Logger.getLogger(QyApiServiceImpl.class);

    // 农担非正式员工企业微信ID
    private static final String WECHAT_2_CORP_ID = "ww21f9457079dfbd4b";
    // 农担非正式员工企业微信通讯录管理密钥
    private static final String WECHAT_2_ADDRESSBOOKSECRET ="v3grboxbxFisxLaf6o4mZ4WzWiWtWq83ZoMy1Rur9AM";

    private static final String DEFAULT_USER_AGENT = "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36";

    @Autowired
    private SystemService systemService;


    @Override
    public AjaxJson synchronizationDepart() throws Exception {
        //获取AccessToken
        String accessTokenUrl = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" + WECHAT_2_CORP_ID + "&corpsecret="+WECHAT_2_ADDRESSBOOKSECRET;
        String httpOrgCreateTestRtn = HttpClientUtil.doGet(accessTokenUrl, null);
        JSONObject json = JSONObject.parseObject(httpOrgCreateTestRtn);
        String accessToken = json.get("access_token").toString();

        // 组装部门数据
        List<Map<String, String>> exportData = new ArrayList<Map<String, String>>();
        Map row = new LinkedHashMap<String, String>();
        TSDepart tsDepart = systemService.getEntity(TSDepart.class, "402883d463ba0b070163ba4d8d8100b2");
        row.put("1", tsDepart.getDepartname());
        row.put("2", "1");
        row.put("3", "0");
        row.put("4", "0");
        exportData.add(row);
        List<Map<String, Object>> tsDepartList = systemService.findForJdbc("select * from t_s_depart d where d.orgtype='biz' and d.parentdepartid=? and d.org_type='9' and d.departname!='待占位' order by d.org_code asc", "402883d463ba0b070163ba4d8d8100b2");
        for (Map<String, Object> tsDepartMap : tsDepartList) {
            row = new LinkedHashMap<String, String>();
            String orgCode = tsDepartMap.get("ORG_CODE").toString();
            orgCode = orgCode.substring(2);
            row.put("1", tsDepartMap.get("DEPARTNAME").toString());
            row.put("2", orgCode);
            row.put("3", "1");
            row.put("4", "0");
            exportData.add(row);

            List<Map<String, Object>> tsDepartTwoList = systemService.findForJdbc("select * from t_s_depart d where d.orgtype='biz' and d.parentdepartid=? and d.org_type='11' and d.departname!='待占位' order by d.org_code asc", tsDepartMap.get("ID"));
            for (Map<String, Object> tsDepartTwoMap : tsDepartTwoList) {
                row = new LinkedHashMap<String, String>();
                String orgCodeTwo = tsDepartTwoMap.get("ORG_CODE").toString();
                orgCodeTwo = orgCodeTwo.substring(2);
                row.put("1", tsDepartTwoMap.get("DEPARTNAME").toString());
                row.put("2", orgCodeTwo);
                row.put("3", orgCode);
                row.put("4", "0");
                exportData.add(row);
            }
        }

        LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
        map.put("1", "部门名称");
        map.put("2", "部门ID");
        map.put("3", "父部门ID");
        map.put("4", "排序");
        File file = createCSVFile(exportData, map, "D:/hnndFile");

        // 上传临时素材文件到企业微信
        String media_id = mediaUpload(accessToken,file);

        // 企业微信全量覆盖部门
        String replacepartyUrl = "https://qyapi.weixin.qq.com/cgi-bin/batch/replaceparty?access_token=" + accessToken;
        Map<String, Object> replacepartyMap = new HashMap<>();
        replacepartyMap.put("media_id", media_id);
        Map<String, Object> replacepartyCallbackMap = new HashMap<>();
        replacepartyCallbackMap.put("url", "");
        replacepartyCallbackMap.put("token", "");
        replacepartyCallbackMap.put("encodingaeskey", "");
        replacepartyMap.put("callback", replacepartyCallbackMap);
        String replacepartyJson = JSON.toJSONString(replacepartyMap);
        JSONObject jsonObject = WeiXinUtil.httpRequest(replacepartyUrl, "POST", replacepartyJson);
        logger.info("全量覆盖部门返回值:" + jsonObject.toString());

        AjaxJson ajaxJson= new AjaxJson();
        ajaxJson.setObj(jsonObject);
        return ajaxJson;
    }



    @Override
    public AjaxJson synchronizationUser() throws Exception{
        AjaxJson ajaxJson= new AjaxJson();
        //获取AccessToken
        String accessTokenUrl = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" + WECHAT_2_CORP_ID + "&corpsecret="+WECHAT_2_ADDRESSBOOKSECRET;
        String httpOrgCreateTestRtn = HttpClientUtil.doGet(accessTokenUrl, null);
        JSONObject json = JSONObject.parseObject(httpOrgCreateTestRtn);
        String accessToken = json.get("access_token").toString();

        // 组装用户数据
        List<Map<String, String>> exportData = new ArrayList<Map<String, String>>();
        Map row = new LinkedHashMap<String, String>();
        List<Map<String, Object>> tsUserList = systemService.findForJdbc("select distinct tsbu.id,tsbu.realname,tsbu.username,tsu.mobilephone,tsu.email,tsu.personal_mail,tsbu.departid,tsd.departname,substr(tsd.org_code,3) as org_code, tsbu.userkey,tsu.emp_sex,'' as isleader,0 as sortno,'' as nickname,tsu.family_address,tsu.family_mobile,tsu.job_position from t_s_base_user tsbu left join t_s_user tsu on tsu.id=tsbu.id left join t_s_org_role_user tsoru on tsoru.user_id=tsbu.id left join t_s_role tsr on tsr.id=tsoru.role_id left join t_s_depart tsd on tsd.id=tsbu.departid where tsr.rolecode in ('fgsqdjl','qdjl','fwzxfzr') and tsu.job_position='3' and tsbu.status=1");
        for (Map<String, Object> tsUserMap : tsUserList) {
            row = new LinkedHashMap<String, String>();
            String orgCode ="";
            String roleName="";
            row.put("1", tsUserMap.get("REALNAME").toString());
            row.put("2", tsUserMap.get("USERNAME").toString());
            if(!StringUtil.isNotEmpty(tsUserMap.get("MOBILEPHONE"))){
                logger.info(String.format("姓名:%s,用户名:%s,手机号码为空",tsUserMap.get("REALNAME").toString(),tsUserMap.get("USERNAME").toString()));
            }
            row.put("3", tsUserMap.get("MOBILEPHONE")==null?"":tsUserMap.get("MOBILEPHONE").toString());
            row.put("4", tsUserMap.get("PERSONAL_MAIL")==null?"":tsUserMap.get("PERSONAL_MAIL").toString());
            row.put("5", tsUserMap.get("EMAIL")==null?"":tsUserMap.get("EMAIL").toString());
            List<Map<String, Object>> tsDepartList = systemService.findForJdbc("select tsoru.*,tsd.departname,tsd.org_code,tsr.rolename from t_s_org_role_user tsoru left join t_s_depart tsd on tsd.id=tsoru.org_id left join t_s_role tsr on tsr.id=tsoru.role_id where tsoru.user_id=? ", tsUserMap.get("ID"));
            for (Map<String, Object> tsDepartMap : tsDepartList) {
                orgCode = tsDepartMap.get("ORG_CODE").toString();
                orgCode = orgCode.substring(2);
               if(roleName.length()==0){
                   roleName=roleName+tsDepartMap.get("ROLENAME").toString();
               }else{
                   roleName=roleName+";"+tsDepartMap.get("ROLENAME").toString();
               }
            }
            row.put("6", orgCode);
            row.put("7", roleName);
            String sex=tsUserMap.get("EMP_SEX")==null?"":tsUserMap.get("EMP_SEX").toString();
            if("2".equals(sex)){
                sex="男";
            }else if("3".equals(sex)){
                sex="女";
            }else {
                sex="";
            }
            row.put("8", sex);
            row.put("9", tsUserMap.get("ISLEADER")==null?"":tsUserMap.get("ISLEADER").toString());
            row.put("10",tsUserMap.get("SORTNO")==null?"":tsUserMap.get("SORTNO").toString());
            row.put("11", tsUserMap.get("NICKNAME")==null?"":tsUserMap.get("NICKNAME").toString());
            row.put("12", tsUserMap.get("FAMILY_ADDRESS")==null?"":tsUserMap.get("FAMILY_ADDRESS").toString());
            row.put("13", tsUserMap.get("FAMILY_MOBILE")==null?"":tsUserMap.get("FAMILY_MOBILE").toString());
            String jobPosition=tsUserMap.get("JOB_POSITION")==null?"":tsUserMap.get("JOB_POSITION").toString();
            if("3".equals(jobPosition)){
                jobPosition="0";
            }else {
                jobPosition="1";
            }
            row.put("14", jobPosition);
            row.put("15", "");
            exportData.add(row);
        }
        LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
        map.put("1", "姓名");
        map.put("2", "帐号");
        map.put("3", "手机号");
        map.put("4", "邮箱");
        map.put("5", "企业邮箱");
        map.put("6", "所在部门");
        map.put("7", "职位");
        map.put("8", "性别");
        map.put("9", "是否部门内领导");
        map.put("10", "排序");
        map.put("11", "别名");
        map.put("12", "地址");
        map.put("13", "座机");
        map.put("14", "禁用");
        map.put("15", "禁用项说明:(0-启用;1-禁用)");
        logger.info(String.format("企业微信全量覆盖成员数量:%s",exportData.size()));
        File file = createCSVFile(exportData, map, "D:/hnndFile");

        // 上传临时素材文件到企业微信
        String media_id = mediaUpload(accessToken,file);

        // 企业微信全量覆盖成员
        String replacepartyUrl = "https://qyapi.weixin.qq.com/cgi-bin/batch/replaceuser?access_token=" + accessToken;
        Map<String, Object> replacepartyMap = new HashMap<>();
        replacepartyMap.put("media_id", media_id);
        replacepartyMap.put("to_invite", false);//是否发出邀请
        Map<String, Object> replacepartyCallbackMap = new HashMap<>();
        replacepartyCallbackMap.put("url", "");
        replacepartyCallbackMap.put("token", "");
        replacepartyCallbackMap.put("encodingaeskey", "");
        replacepartyMap.put("callback", replacepartyCallbackMap);
        String replacepartyJson = JSON.toJSONString(replacepartyMap);
        JSONObject jsonObject = WeiXinUtil.httpRequest(replacepartyUrl, "POST", replacepartyJson);
        logger.info("全量覆盖成员返回值:" + jsonObject.toString());

        ajaxJson.setObj(jsonObject);
        return ajaxJson;
    }

    /**
     * 上传临时素材文件到企业微信
     * @param accessToken
     * @param file
     * @return
     * @throws IOException
     */
    private String mediaUpload(String accessToken,File file) throws IOException {
        String media_id = "";
        String url = "https://qyapi.weixin.qq.com/cgi-bin/media/upload?access_token=" + accessToken + "&type=file";
        String result = uploadMedia(url, file, null);
        logger.info("上传临时素材返回值:" + result);
        Map resultMap = (Map) JSON.parse(result);
        if (resultMap.containsKey("errcode") && !"0".equals(resultMap.get("errcode").toString())) {
            logger.info("上传临时素材failed:" + result);
        } else {
            media_id = resultMap.get("media_id").toString();
        }
        return media_id;
    }

    @Override
    public AjaxJson getQyWeixinResult(HttpServletRequest request) throws Exception {
        String jobid=request.getParameter("jobid");
        //获取AccessToken
        String accessTokenUrl = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" + WECHAT_2_CORP_ID + "&corpsecret="+WECHAT_2_ADDRESSBOOKSECRET;
        String httpOrgCreateTestRtn = HttpClientUtil.doGet(accessTokenUrl, null);
        JSONObject json = JSONObject.parseObject(httpOrgCreateTestRtn);
        String accessToken = json.get("access_token").toString();

        String getresultUrl = "https://qyapi.weixin.qq.com/cgi-bin/batch/getresult?access_token=" + accessToken + "&jobid="+jobid;
        JSONObject jsonObject = WeiXinUtil.httpRequest(getresultUrl, "GET", null);
        logger.info("获取异步任务结果:" + jsonObject.toString());

        AjaxJson ajaxJson= new AjaxJson();
        ajaxJson.setObj(jsonObject);
        return ajaxJson;
    }

    /**
     * 上传临时素材
     *
     * @param url  图片上传地址
     * @param file 需要上传的文件
     * @return ApiResult
     * @throws IOException
     */
    public String uploadMedia(String url, File file, String params) throws IOException {
        URL urlGet = new URL(url);
        HttpURLConnection conn = (HttpURLConnection) urlGet.openConnection();
        conn.setDoOutput(true);
        conn.setDoInput(true);
        conn.setUseCaches(false);
        conn.setRequestMethod("POST");
        conn.setRequestProperty("connection", "Keep-Alive");
        conn.setRequestProperty("user-agent", DEFAULT_USER_AGENT);
        conn.setRequestProperty("Charsert", "UTF-8");
        // 定义数据分隔线
        String BOUNDARY = "----WebKitFormBoundaryiDGnV9zdZA1eM1yL";
        conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);

        OutputStream out = new DataOutputStream(conn.getOutputStream());
        // 定义最后数据分隔线
        StringBuilder mediaData = new StringBuilder();
        mediaData.append("--").append(BOUNDARY).append("\r\n");
        mediaData.append("Content-Disposition: form-data;name=\"media\";filename=\"" + file.getName() + "\"\r\n");
        mediaData.append("Content-Type:application/octet-stream\r\n\r\n");
        byte[] mediaDatas = mediaData.toString().getBytes();
        out.write(mediaDatas);
        DataInputStream fs = new DataInputStream(new FileInputStream(file));
        int bytes = 0;
        byte[] bufferOut = new byte[1024];
        while ((bytes = fs.read(bufferOut)) != -1) {
            out.write(bufferOut, 0, bytes);
        }
        IOUtils.closeQuietly(fs);
        // 多个文件时,二个文件之间加入这个
        out.write("\r\n".getBytes());
        if (StringUtils.isNotEmpty(params)) {
            StringBuilder paramData = new StringBuilder();
            paramData.append("--").append(BOUNDARY).append("\r\n");
            paramData.append("Content-Disposition: form-data;name=\"description\";");
            byte[] paramDatas = paramData.toString().getBytes();
            out.write(paramDatas);
            out.write(params.getBytes(Charsets.UTF_8));
        }
        byte[] end_data = ("\r\n--" + BOUNDARY + "--\r\n").getBytes();
        out.write(end_data);
        out.flush();
        IOUtils.closeQuietly(out);

        // 定义BufferedReader输入流来读取URL的响应
        InputStream in = conn.getInputStream();
        BufferedReader read = new BufferedReader(new InputStreamReader(in, Charsets.UTF_8));
        String valueString = null;
        StringBuffer bufferRes = null;
        bufferRes = new StringBuffer();
        while ((valueString = read.readLine()) != null) {
            bufferRes.append(valueString);
        }
        IOUtils.closeQuietly(in);
        // 关闭连接
        if (conn != null) {
            conn.disconnect();
        }
        return bufferRes.toString();
    }

    /**
     * 导出为CVS文件
     *
     * @param exportData 需要导出的数据
     * @param titleMap   与数据相对应的标题
     * @param outPutPath 导出目录
     */
    public static File createCSVFile(List<Map<String, String>> exportData, LinkedHashMap<String, String> titleMap, String outPutPath) {
        File csvFile = null;
        BufferedWriter csvFileOutputStream = null;
        try {
            File f = new File(outPutPath);
            if (!f.exists()) {
                f.mkdirs();
            }
            csvFile = File.createTempFile("temp", ".csv", new File(outPutPath));
            // GB2312使正确读取分隔符","
            csvFileOutputStream = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(csvFile), "UTF-8"),
                    1024);
            // 写入文件头部标题
            for (Iterator propertyIterator = titleMap.entrySet().iterator(); propertyIterator.hasNext(); ) {
                java.util.Map.Entry propertyEntry = (java.util.Map.Entry) propertyIterator.next();
                csvFileOutputStream.write("\"" + propertyEntry.getValue().toString() + "\"");
                if (propertyIterator.hasNext()) {
                    csvFileOutputStream.write(",");
                }
            }
            csvFileOutputStream.newLine();
            // 写入文件内容
            for (Iterator iterator = exportData.iterator(); iterator.hasNext(); ) {
                Map row = (Map) iterator.next();
                for (Iterator propertyIterator = titleMap.entrySet().iterator(); propertyIterator.hasNext(); ) {
                    java.util.Map.Entry propertyEntry = (java.util.Map.Entry) propertyIterator.next();
                    csvFileOutputStream.write("\""
                            + row.get(propertyEntry.getKey().toString()).toString() + "\"");
                    if (propertyIterator.hasNext()) {
                        csvFileOutputStream.write(",");
                    }
                }
                if (iterator.hasNext()) {
                    csvFileOutputStream.newLine();
                }
            }
            csvFileOutputStream.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                csvFileOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return csvFile;
    }

}

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
您好!关于Java企业微信开发,有以下几个方面的内容可以探讨: 1. 企业微信开发平台:企业微信提供了开放的API开发者可以通过该平台进行接口调用和应用开发。您可以在企业微信开发者文档中找到相关的API文档和示例代码。 2. Java SDK:为了方便Java开发者使用企业微信API,可以使用第三方的Java SDK,如WeChatWork-Java-SDK或者企业微信官方提供的Java SDK。这些SDK封装了企业微信API的调用方法,提供了便捷的接口和功能。 3. 接口调用:使用Java SDK或直接发送HTTP请求进行接口调用。企业微信API提供了丰富的接口,包括发送消息、获取通讯录管理应用等。您可以根据需求选择相应的接口,并按照文档提供的参数和格式进行调用。 4. 消息推送:企业微信提供了企业内部消息推送的功能,可以通过发送消息给指定用户或群聊来实现。您可以使用Java SDK提供的方法来发送不同类型的消息,如文本消息、图片消息、图文消息等。 5. 应用开发企业微信支持应用开发,您可以根据自己的需求开发定制化的应用。例如,可以开发审批系统、打卡系统、会议预订系统等。使用Java开发企业微信应用,可以利用企业微信提供的API和SDK来实现各种功能。 以上是关于Java企业微信开发的一些基本信息,希望对您有所帮助。如果有具体的问题或者需要进一步了解,请随时提问!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

西米先生「软件工程师」

您的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值