Java 接入 钉钉API

前言:

      本人在单位做了一个简单的HR招聘管理系统,后续扩展打算将此系统与公司管理系统——钉钉 相结合,于是从钉钉官网的开放API出发,对钉钉的对接有了一个简单的了解。

对接简介

      根据人事的需求场景,本人需要用到钉钉API的功能主要有:

             授权:获取access_token

             信息:员工信息、组织机构信息、入职人员添加

             功能:消息通知、审批

 

钉钉API接入

业务场景一:

将公司钉钉所有员工信息同步到HR招聘管理系统,以组织机构展示花名册,同时在HR招聘管理系统里修改员工信息,修改时与钉钉上的员工信息保持同步,也满足修改组织机构信息,人员部门变更等相关功能。

注:此功能,我在数据库中未存储任何数据,展示钉钉API接口获取的数据,通过钉钉API接口修改数据。

一、获取access_token

1.获取应用的appKey和appSecret

   登录钉钉管理后台,创建应用

    创建成功后,进入应用详情页,找到appKey和appSecret

2.接口获取access_token

注:大部分接口的调用都依赖于access_token,而access_token有效期为7200秒,有效期内重复获取返回相同结果,并自动续期。

       可以将access_token放入缓存,减少接口调用频率。

二、用户信息管理

1.获取用户详情信息

请求说明:

返回说明:

2.获取部门下用户信息

请求说明:

返回说明:

2.创建用户

请求说明:

参数说明:

返回说明:

3.更新用户信息

请求说明:

参数说明:

返回说明:

三、组织机构信息管理

1.获取部门列表

请求说明:

返回说明:

2.获取部门详情

请求说明:

返回说明:

业务场景二:

HR招聘管理系统中,可以以钉钉消息推送的方式提前提醒相应面试官进行准备,面试结束后,也会提醒相关人员进行审核,并会发起相应的审核流程对应聘人员进行审核。

一、消息推送

1.发送工作通知消息

请求说明:

参数说明:

名称类型是否必须示例值描述
agent_idNumber必须1234企业自建应用是微应用agentId,第三方应用是通过获取授权企业的应用信息接口/service/get_agent获取到的agentId
userid_listString可选(userid_list,dept_id_list, to_all_user必须有一个不能为空)zhangsan,lisi接收者的用户userid列表,最大列表长度:20
dept_id_listString可选123,456接收者的部门id列表,最大列表长度:20,  接收者是部门id下(包括子部门下)的所有用户
to_all_userBoolean可选false是否发送给企业全部用户(ISV不能设置true)
msgjson对象必须{"msgtype":"text","text":{"content":"消息内容"}}消息内容,具体见“消息类型与数据格式”。最长不超过2048个字节

 

 

 

 

 

 

 

 

 

 

返回说明:

二、审批

1.发起审批实例

请求说明:

参数说明:

返回说明:

业务场景三

HR招聘管理系统以钉钉方式进行扫码登录(第三方登录),然后以钉钉的角色进行权限管理,

例如:HR主管:可以查看所有信息

           Java主管:可以查看Java面试人员的信息,以及Java试题的维护等相关功能

一、第三方登录

1.获取appId及appSecret

2.构造扫码登录页面

方法一:直接使用钉钉提供的扫码登录页面

方法二:网站将钉钉登录二维码内嵌到自己页面中

3.服务端通过Code获取授权用户的个人信息

上代码

import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiDepartmentListRequest;
import com.dingtalk.api.request.OapiGettokenRequest;
import com.dingtalk.api.request.OapiMessageCorpconversationAsyncsendV2Request;
import com.dingtalk.api.request.OapiUserSimplelistRequest;
import com.dingtalk.api.response.OapiDepartmentListResponse;
import com.dingtalk.api.response.OapiGettokenResponse;
import com.dingtalk.api.response.OapiMessageCorpconversationAsyncsendV2Response;
import com.dingtalk.api.response.OapiUserSimplelistResponse;
import com.taobao.api.ApiException;
import com.xxx.ding.util.LocalCacheClient;

public class DingUtil {
	
	private final static String APPKEY ="";
	
	private final static String APPSECRET="";
	
	private final static Long AGENTID = 0L;
	
	//获取token
	public static String getToken (){
		Object object = LocalCacheClient.get("access_token");
		if(object != null){
			return object.toString();
		}
		DefaultDingTalkClient client = new     
        DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
		OapiGettokenRequest request = new OapiGettokenRequest();
		request.setAppkey(APPKEY);
		request.setAppsecret(APPSECRET);
		request.setHttpMethod("GET");
		try {
			OapiGettokenResponse response = client.execute(request);
			LocalCacheClient.set("access_token", response.getAccessToken(),7200*1000);
			return response.getAccessToken();
		} catch (ApiException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	//获取部门列表
	public static Object getDepartment(){
		DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/department/list");
		OapiDepartmentListRequest request = new OapiDepartmentListRequest();
		//获取根部门下所有部门列表  根部门的部门id为1
		request.setId("1");
		request.setHttpMethod("GET");
		
		try {
			OapiDepartmentListResponse response = client.execute(request, DingUtil.getToken());
			return response;
		} catch (ApiException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	//获取部门下的所有用户列表
	public static Object getDepartmentUser(Long departmentId){
		DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/user/simplelist");
		OapiUserSimplelistRequest request = new OapiUserSimplelistRequest();
		request.setDepartmentId(departmentId);
		request.setOffset(0L);
		request.setSize(10L);
		request.setHttpMethod("GET");

		try {
			OapiUserSimplelistResponse response = client.execute(request, DingUtil.getToken());
			return response;
		} catch (ApiException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	
	//给用户推送消息(文字消息)
	public static Object pushUser(String userIds,String content){
		DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2");

		OapiMessageCorpconversationAsyncsendV2Request request = new OapiMessageCorpconversationAsyncsendV2Request();
		request.setUseridList(userIds);
		request.setAgentId(AGENTID);
		request.setToAllUser(false);

		OapiMessageCorpconversationAsyncsendV2Request.Msg msg = new OapiMessageCorpconversationAsyncsendV2Request.Msg();
		msg.setMsgtype("text");
		msg.setText(new OapiMessageCorpconversationAsyncsendV2Request.Text());
		msg.getText().setContent(content);
		request.setMsg(msg);

		try {
			OapiMessageCorpconversationAsyncsendV2Response response = client.execute(request,DingUtil.getToken());
		return response;
		} catch (ApiException e) {
			e.printStackTrace();
		}
		return null;
	}
}

LocalCacheClient 类

package com.xxx.ding.util;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
 

public class LocalCacheClient {
    // 缓存map
    private static Map<String, Object> cacheMap = new HashMap<String, Object>();
    // 缓存有效期map
    private static Map<String, Long> expireTimeMap = new HashMap<String, Long>();
 
 
    /**
     * 获取指定的value,如果key不存在或者已过期,则返回null
     * @param key
     * @return
     */
    public static Object get(String key) {
        if (!cacheMap.containsKey(key)) {
            return null;
        }
        if (expireTimeMap.containsKey(key)) {
            if (expireTimeMap.get(key) < System.currentTimeMillis()) { // 缓存失效,已过期
                return null;
            }
        }
        return cacheMap.get(key);
    }
 
    /**
     * @param key
     * @param <T>
     * @return
     */
    public static <T> T getT(String key) {
        Object obj = get(key);
        return obj == null ? null : (T) obj;
    }
 
    /**
     * 设置value(不过期)
     * @param key
     * @param value
     */
    public static void set(String key, Object value) {
        cacheMap.put(key, value);
    }
 
    /**
     * 设置value
     * @param key
     * @param value
     * @param millSeconds 过期时间(毫秒)
     */
    public static void set(final String key, Object value, int millSeconds) {
        final long expireTime = System.currentTimeMillis() + millSeconds;
        cacheMap.put(key, value);
        expireTimeMap.put(key, expireTime);
        if (cacheMap.size() > 2) { // 清除过期数据
            new Thread(new Runnable() {
                public void run() {
                    // 此处若使用foreach进行循环遍历,删除过期数据,会抛出java.util.ConcurrentModificationException异常
                    Iterator<Map.Entry<String, Object>> iterator = cacheMap.entrySet().iterator();
                    while (iterator.hasNext()) {
                        Map.Entry<String, Object> entry = iterator.next();
                        if (expireTimeMap.containsKey(entry.getKey())) {
                            long expireTime = expireTimeMap.get(key);
                            if (System.currentTimeMillis() > expireTime) {
                                iterator.remove();
                                expireTimeMap.remove(entry.getKey());
                            }
                        }
                    }
                }
            }).start();
        }
    }
 
    /**
     * key是否存在
     * @param key
     * @return
     */
    public static boolean isExist(String key) {
        return cacheMap.containsKey(key);
    }
    
}

代码说明

 

首先 下载钉钉的jar包,导入项目中。(可以自行根据API文档通过httpclient进行接口调用,然后自己获取返回信息进行序列化)

其次 完善必备参数APPKEY、APPSECRET、AGENTID

最后 token要进行缓存 不要每次调用 有限制(存入本地缓存即可,此项目中LocalCacheClient类作为缓存处理,项目中如果有redis等存储数据库也可以使用)

 

流程梳理 由于钉钉并没有直接获取所有用户信息的接口,所以需要通过接口获取全部部门信息,

               然后再调用接口获取该部门下所有的用户信息,最后可以根据用户id进行消息推送

             (消息推送的种类很多,不在此一一列举,API文档中有详细说明)

  • 29
    点赞
  • 141
    收藏
    觉得还不错? 一键收藏
  • 25
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值