Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.anyline.feishu.util.FeishuUtil Maven / Gradle / Ivy
/*
* Copyright 2006-2023 www.anyline.org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.anyline.feishu.util;
import com.lark.oapi.Client;
import org.anyline.adapter.KeyAdapter;
import org.anyline.entity.DataRow;
import org.anyline.entity.DataSet;
import org.anyline.feishu.entity.Department;
import org.anyline.feishu.entity.User;
import org.anyline.net.HttpUtil;
import org.anyline.util.AnylineConfig;
import org.anyline.util.BasicUtil;
import org.anyline.util.BeanUtil;
import org.anyline.util.DateUtil;
import org.apache.http.entity.StringEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
public class FeishuUtil {
private static final Logger log = LoggerFactory.getLogger(FeishuUtil.class);
private static Hashtable instances = new Hashtable();
private FeishuConfig config = null;
private Client client;
private String tenant_access_token = null;
private Long tenant_access_token_time = null;
static {
Hashtable configs = FeishuConfig.getInstances();
for(String key:configs.keySet()){
instances.put(key, getInstance(key));
}
}
public FeishuUtil(){
}
public FeishuUtil(FeishuConfig config){
this.config = config;
client = Client.newBuilder(config.APP_ID, config.APP_SECRET).build();
}
public static Hashtable getInstances(){
return instances;
}
public Client client(){
return client;
}
public void client(Client client){
this.client = client;
}
public static FeishuUtil getInstance(){
return getInstance(FeishuConfig.DEFAULT_INSTANCE_KEY);
}
public static FeishuUtil getInstance(String key){
if(BasicUtil.isEmpty(key)){
key = FeishuConfig.DEFAULT_INSTANCE_KEY;
}
FeishuUtil util = instances.get(key);
if(null == util){
FeishuConfig config = FeishuConfig.getInstance(key);
if(null != config) {
util = new FeishuUtil(config);
instances.put(key, util);
}
}
return util;
}
public static FeishuUtil reg(String key, DataRow config){
FeishuConfig conf = FeishuConfig.register(key, config);
FeishuUtil util = new FeishuUtil(conf);
instances.put(key, util);
return util;
}
public static FeishuUtil reg(String key, String id, String secret){
FeishuConfig conf = FeishuConfig.register(key, id, secret);
FeishuUtil util = new FeishuUtil(conf);
instances.put(key, util);
return util;
}
public static FeishuUtil reg(String key, String id, String secret, String redirect){
FeishuConfig conf = FeishuConfig.register(key, id, secret, redirect);
FeishuUtil util = new FeishuUtil(conf);
instances.put(key, util);
return util;
}
public FeishuConfig config(){
return config;
}
public String tenant_access_token(){
if(null == tenant_access_token || (System.currentTimeMillis()-tenant_access_token_time)/1000 >7000){
flushToken();
}
return tenant_access_token;
}
/**
*
* @param code 用户授权确认后重定向中的code
* @return DataRow
*/
public DataRow access_token(String code){
DataRow token = null;
String url = "https://open.feishu.cn/open-apis/authen/v1/oidc/access_token";
Map header = new Hashtable<>();
header.put("Content-Type","application/json; charset=utf-8");
header.put("Authorization", "Bearer " + tenant_access_token());
Map params = new HashMap<>();
params.put("grant_type", "authorization_code");
params.put("code", code);
String json = BeanUtil.map2json(params);
String body = HttpUtil.post(header, url, new StringEntity(json, "UTF-8")).getText();
log.info("[get feishu access token][body:{}]", body);
DataRow row = DataRow.parseJson(KeyAdapter.KEY_CASE.SRC, body);
token = row.getRow("data");
return token;
}
public User user(String code){
User user = user(access_token(code));
return user;
}
public User user(DataRow token){
User user = new User();
String url = "https://open.feishu.cn/open-apis/authen/v1/user_info";
Map header = new Hashtable<>();
header.put("Content-Type","application/json; charset=utf-8");
header.put("Authorization", "Bearer " + token.getString("access_token"));
String body = HttpUtil.get(header, url).getText();
log.info("[get feishu user info][body:{}]", body);
DataRow row = DataRow.parseJson(KeyAdapter.KEY_CASE.SRC, body);
DataRow data = row.getRow("data");
user = info(data);
return user;
}
public static User info(DataRow data){
User user = new User();
user.setName(data.getString("name"));
user.setEnName(data.getString("en_name"));
if(data.isNotEmpty("avatar")){
//批量获取用户列表
DataRow avators = data.getRow("avatar");
if(null != avators){
user.setAvatarBig(data.getString("AVATAR_640"));
user.setAvatarUrl(data.getString("AVATAR_ORIGIN"));
user.setAvatarThumb(data.getString("AVATAR_72"));
user.setAvatarMiddle(data.getString("AVATAR_240"));
}
}else {
//用户登录获取信息
user.setAvatarBig(data.getString("avatar_big"));
user.setAvatarUrl(data.getString("avatar_url"));
user.setAvatarThumb(data.getString("avatar_thumb"));
user.setAvatarMiddle(data.getString("avatar_middle"));
}
if(data.isNotEmpty("status")){
DataRow status = data.getRow("status");
if(null != status){
user.setActivateStatus(status.getBoolean("is_activated", null)); //激活
user.setFrozenStatus(status.getBoolean("is_frozen", null)); //冻结
user.setResignStatus(status.getBoolean("is_resigned", null)); //离职
}
}
Long joinTime = data.getLong("join_time", 0);
if(joinTime > 0){
Date date = DateUtil.parse(joinTime*1000);
user.setJoinTime(date);
user.setJoinYmd(DateUtil.format(date, "yyyy-MM-dd"));
}
user.setNickname(data.getString("nickname"));
List depts = (List)data.getList("department_ids");
user.setDepartmentIds(depts);
user.setLeaderId(data.getString("leader_user_id"));
user.setJobTitle(data.getString("job_title"));
user.setWorkStation(data.getString("work_station"));
user.setOpenid(data.getString("open_id"));
user.setUnionid(data.getString("union_id"));
user.setEmail(data.getString("email"));
user.setMobile(data.getString("mobile"));
user.setEnterpriseEmail(data.getString("enterprise_email"));
user.setEmployeeNo(data.getString("employee_no"));
user.setId(data.getString("user_id"));
user.setTenantKey(data.getString("tenant_key"));
return user;
}
/**
* 所有可访问用户
* @return List
*/
public List users(){
List users = new ArrayList<>();
String url ="https://open.feishu.cn/open-apis/contact/v3/scopes";
Map header = new HashMap<>();
header.put("Authorization", "Bearer " + tenant_access_token());
String body = HttpUtil.get(header, url).getText();
DataRow row = DataRow.parseJson(body);
List ids = (List)row.getRow("data").getList("user_ids");
if(null != ids) {
List> pages = BeanUtil.page(ids, 50);
for (List page : pages) {
users.addAll(users(page));
}
}
return users;
}
public List users(List ids){
List users = new ArrayList<>();
Map header = new HashMap<>();
header.put("Authorization", "Bearer " + tenant_access_token());
Map params = new HashMap<>();
params.put("user_ids", ids);
String url = "https://open.feishu.cn/open-apis/contact/v3/users/batch";
String body = HttpUtil.get(header, url, "UTF-8", params).getText();
DataRow row = DataRow.parseJson(body);
DataSet items = row.getRow("data").getSet("items");
if(null != items) {
for (DataRow item : items) {
users.add(info(item));
}
}
return users;
}
public List users(Department department){
List users = new ArrayList<>();
Map header = new HashMap<>();
header.put("Authorization", "Bearer " + tenant_access_token());
Map params = new HashMap<>();
params.put("department_id", "0");
params.put("page_size", 50);
if(null != department){
String id = department.getCode();
String openid = department.getOpenid();
if(BasicUtil.isNotEmpty(id)){
params.put("department_id_type", "department_id");
params.put("department_id", id);
}else if(BasicUtil.isNotEmpty(openid)){
params.put("department_id_type", "open_department_id");
params.put("department_id", openid);
}
}
String url = "https://open.feishu.cn/open-apis/contact/v3/users/find_by_department";
while (true) {
String body = HttpUtil.get(header, url, "UTF-8", params).getText();
DataRow row = DataRow.parseJson(body);
DataRow data = row.getRow("data");
if(null != data) {
DataSet items = data.getSet("items");
if (null != items) {
for (DataRow item : items) {
users.add(info(item));
}
}
params.put("page_token", data.getString("page_token"));
if(!data.getBoolean("has_more", false)){
break;
}
}else{
break;
}
}
return users;
}
public List departments() {
return departments("0");
}
/**
* 所有可访问部门
* @return List
*/
public List departments(String parent) {
List departments = new ArrayList<>();
String url = "https://open.feishu.cn/open-apis/contact/v3/departments/"+parent+"/children";
Map header = new HashMap<>();
header.put("Authorization", "Bearer " + tenant_access_token());
Map params = new HashMap<>();
params.put("page_size", 50);
while (true) {
String body = HttpUtil.get(header, url, "UTF-8", params).getText();
DataRow row = DataRow.parseJson(body);
if (row.getInt("CODE", -1) == 0) {
DataRow data = row.getRow("data");
if(null != data) {
DataSet items = data.getItems();
if (null != items) {
for (DataRow item : items) {
Department department = new Department();
department.setCode(item.getString("department_id"));
department.setName(item.getString("name"));
department.setOpenid(item.getString("open_department_id"));
department.setParentCode(item.getString("parent_department_id"));
DataSet leaders = item.getSet("leaders");
if (null != leaders) {
for (DataRow leader : leaders) {
if (leader.getInt("leaderType", 0) == 1) {//主负责人
department.setLeaderCode(leader.getString("leaderID"));
}
}
}
departments.add(department);
}
}
if(!data.getBoolean("has_more")){
break;
}
params.put("page_token", data.getString("page_token"));
}else{
break;
}
} else {
log.warn("[departments][response:{}]", body);
break;
}
}
return departments;
}
private void flushToken(){
String url = "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal/";
Map header = new Hashtable<>();
header.put("Content-Type","application/json; charset=utf-8");
Map params = new HashMap<>();
params.put("app_id", config.APP_ID);
params.put("app_secret", config.APP_SECRET);
try {
String json = BeanUtil.map2json(params);
String body = HttpUtil.post(header, url, new StringEntity(json, "UTF-8")).getText();
DataRow row = DataRow.parseJson(body);
if("0".equals(row.getString("code"))){
tenant_access_token = row.getString("tenant_access_token");
tenant_access_token_time = System.currentTimeMillis();
}else {
log.warn("[flush token][response:{}]", body);
}
}catch (Exception e){
e.printStackTrace();
}
}
/**
* 创建用户登录连接
* @param callback 回调地址(可以从url获取access_token)
* @param scope scope
* @param state state
* @return String
*/
public String createAuthUrl(String callback, String scope, String state){
StringBuilder builder = new StringBuilder();
//https://open.feishu.cn/open-apis/authen/v1/authorize?app_id=cli_a69b4944f47b100e&redirect_uri=https%3A%2F%2Ffs.deepbit.cn&scope=contact:contact%20bitable:app:readonly&state=213
builder.append("https://open.feishu.cn/open-apis/authen/v1/authorize?app_id=").append(config.APP_ID);
if(BasicUtil.isEmpty(callback)){
callback = config.OAUTH_REDIRECT_URL;
}
builder.append("&redirect_uri=").append(HttpUtil.encode(callback, false, true));
//参考https://open.feishu.cn/document/server-docs/application-scope/scope-list
builder.append("&scope=").append(scope);
if(BasicUtil.isNotEmpty(state)) {
builder.append("&state=").append(state);
}
return builder.toString();
}
public String createAuthUrl(String callback, String state){
return createAuthUrl(callback, "contact:contact.base:readonly", state);
}
public String createAuthUrl(String state){
return createAuthUrl(config.OAUTH_REDIRECT_URL, state);
}
}