1.调用接口获取企业内部应用的accessToken
官方开发指南:获取企业内部应用的accessToken - 钉钉开放平台 (dingtalk.com)
获取token用的新版sdk(也可以用旧版,官方说不建议)。我旧版和新版一起引了,因为后面的获取部门人员的接口要用旧版sdk。
maven
<!--新版sdk 用来获取token-->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>dingtalk</artifactId>
<version>2.0.18</version>
</dependency>
<!--旧版sdk 获取部门、人员-->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>alibaba-dingtalk-service-sdk</artifactId>
<version>2.0.0</version>
</dependency>
官方有提供示例代码,拿来微调一下就可以用
private static final String APP_KEY = "";
private static final String APP_SECRET = "";
public com.aliyun.dingtalkoauth2_1_0.Client createOauth2Client() throws Exception {
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
config.protocol = "https";
config.regionId = "central";
return new com.aliyun.dingtalkoauth2_1_0.Client(config);
}
public String getAccessToken() throws Exception {
com.aliyun.dingtalkoauth2_1_0.Client client = createOauth2Client();
com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenRequest getAccessTokenRequest = new com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenRequest()
.setAppKey(APP_KEY)
.setAppSecret(APP_SECRET);
try {
GetAccessTokenResponse response = client.getAccessToken(getAccessTokenRequest);
return response.getBody().getAccessToken();
} catch (TeaException err) {
if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
// log
}
} catch (Exception _err) {
TeaException err = new TeaException(_err.getMessage(), _err);
if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
// log
}
}
return null;
}
2.获取部门列表
官方开发指南:获取部门列表 - 钉钉开放平台 (dingtalk.com)
这个接口要用旧版sdk
/**
* 获取钉钉部门列表
* 只支持获取当前部门的下一级部门基础信息,不支持获取当前部门下所有层级子部门。
* @param accessToken token
* @param deptId 父ID 不传默认为根部门,
*/
public List<OapiV2DepartmentListsubResponse.DeptBaseResponse> getDeptList(String accessToken, Long deptId) {
try {
DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/listsub");
OapiV2DepartmentListsubRequest req = new OapiV2DepartmentListsubRequest();
req.setDeptId(deptId);
OapiV2DepartmentListsubResponse rsp = client.execute(req, accessToken);
if (rsp.getErrcode() != 0) {
throw new IllegalStateException(rsp.getErrmsg());
}
return rsp.getResult();
} catch (Exception _err) {
TeaException err = new TeaException(_err.getMessage(), _err);
if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
// log
}
return null;
}
}
上面的接口只支持查询一层部门,如果要获取整棵树,可以递归。
/**
* 递归获取部门列表
* @param accessToken token
* @param deptId 父ID 不传默认为根部门
*/
public List<OapiV2DepartmentListsubResponse.DeptBaseResponse> recursiveGetDeptList(String accessToken, Long deptId) {
List<OapiV2DepartmentListsubResponse.DeptBaseResponse> deptList = getDeptList(accessToken, deptId);
List<OapiV2DepartmentListsubResponse.DeptBaseResponse> deptListNew = new ArrayList<>();
if (deptList != null && deptList.size() > 0) {
deptListNew.addAll(deptList);
for (OapiV2DepartmentListsubResponse.DeptBaseResponse baseResponse : deptList) {
List<OapiV2DepartmentListsubResponse.DeptBaseResponse> subList = recursiveGetDeptList(accessToken, baseResponse.getDeptId());
if (subList != null && subList.size() > 0) {
deptListNew.addAll(subList);
}
}
}
return deptListNew;
}
3.获取部门下的用户详情列表
没有找到直接获取人员列表的接口,只能通过部门来获取人员列表。
官方开发指南:获取部门用户详情 - 钉钉开放平台 (dingtalk.com)
因为要存手机号,所以用的用户详情列表接口。官方还提供了部门用户的简单列表接口:
用官方示例代码调整一下:
/**
* 获取钉钉用户列表
* @param deptId 部门id
* @param accessToken token
* @param nextCursor 分页查询的游标,最开始传0,后续传返回参数中的next_cursor值
* @param size 分页大小 每页大小不能超过100
*/
public OapiV2UserListResponse.PageResult getUsersByDeptId(String accessToken, Long deptId, Long nextCursor, Long size) {
try {
DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/list");
OapiV2UserListRequest req = new OapiV2UserListRequest();
req.setDeptId(deptId);
req.setCursor(nextCursor);
req.setSize(size);
OapiV2UserListResponse rsp = client.execute(req, accessToken);
if (rsp.getErrcode() != 0) {
throw new IllegalStateException(rsp.getErrmsg());
}
return rsp.getResult();
} catch (Exception _err) {
TeaException err = new TeaException(_err.getMessage(), _err);
if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
// log
}
return null;
}
}
上面的接口只能获取最多部门下的100个人,改成循环获取
/**
* 循环获取部门下用户列表
* @param deptId 部门id
* @param accessToken token
* @param nextCursor 分页查询的游标,最开始传0,后续传返回参数中的next_cursor值
* @param size 分页大小 每页大小不能超过100
*/
public List<OapiV2UserListResponse.ListUserResponse> recursiveGetUserList(String accessToken, Long deptId, Long nextCursor, Long size) {
OapiV2UserListResponse.PageResult userPageResult = this.getUsersByDeptId(accessToken, deptId, nextCursor, size);
List<OapiV2UserListResponse.ListUserResponse> listNew = new ArrayList<>();
if (userPageResult != null && userPageResult.getList().size() > 0) {
listNew.addAll(userPageResult.getList());
if (userPageResult.getHasMore() != null && userPageResult.getHasMore()) {
// 下一页
List<OapiV2UserListResponse.ListUserResponse> otherPageList = recursiveGetUserList(accessToken, deptId, userPageResult.getNextCursor(), size);
listNew.addAll(otherPageList);
}
}
return listNew;
}
4.获取报表假期数据
官方教程:获取报表假期数据 - 钉钉开放平台 (dingtalk.com)
/**
* 获取报表假期数据
* @param accessToken token
* @param userId 用户ID
* @param fromDate 开始时间
* @param toDate 结束时间,结束时间减去开始时间必须在31天以内。
* @param leaveNames "年假,病假" 多个用逗号隔开
*/
public OapiAttendanceGetleavetimebynamesResponse.ColumnValListForTopVo getLeaveTimeByUserId(String accessToken, String userId, Date fromDate, Date toDate, String leaveNames) {
try {
DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/attendance/getleavetimebynames");
OapiAttendanceGetleavetimebynamesRequest req = new OapiAttendanceGetleavetimebynamesRequest();
req.setUserid(userId);
req.setFromDate(fromDate);
req.setToDate(toDate);
req.setLeaveNames(leaveNames);
OapiAttendanceGetleavetimebynamesResponse rsp = client.execute(req, accessToken);
if (rsp.getErrcode() != 0) {
throw new IllegalStateException(rsp.getErrmsg());
}
return rsp.getResult();
} catch (ApiException _err) {
TeaException err = new TeaException(_err.getMessage(), _err);
if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
// log
}
return null;
}
}