Appearance
对接飞书同步组织架构和成员
概述
在企业内部通常会使用飞书
等即时通讯工具作为日常办公的沟通工具,这类工具通常提供了组织架构管理、用户管理、通知、待办等功能。 下面是对接飞书并同步组织架构和成员到织信的步骤。
实现步骤
- 同步飞书组织架构前,需要先完成「第三方集成 >> 飞书」的集成。
- 开通通讯录权限,至少包含获取部门基础信息、获取通讯录部门组织架构信息、获取用户基本信息、获取用户userID、获取用户手机号、以应用身份读取通讯录这六个权限。
实现代码
javascript
const defaultRole='normal';//授权给新用户的团队角色
const defaultPassword='123456';//新用户设置的密码,用户名为手机号
const syncMembers=true;//是否同步成员
export function syncDepartments() {
syncDepartmentList('0', 10, null);
console.log('syncDepartments finished');
}
function syncDepartmentList(parentId, pageSize, pageToken) {
var url=`https://open.feishu.cn/open-apis/contact/v3/departments/${parentId}/children?department_id_type=department_id&fetch_child=false&page_size=${pageSize}&user_id_type=user_id`;
if(pageToken){
url=url+'&page_token='+pageToken;
}
const resp = httpGet(url);
const result = JSON.parse(resp.body());
console.log('body',resp.body());
if(result.data.items){
result.data.items.forEach(item=>{
var dept=informat.dept.getDept(item.department_id);
if (dept==null) {
console.log('新增部门',item);
console.log('parentId',parentId)
informat.dept.addDept({
'id': item.department_id,
'name': item.name,
'remark': item.name,
'parentId': item.parent_department_id === '0' ? null : parentId
});
}else{
console.log('编辑部门',item);
informat.dept.updateDept({
'id': item.department_id,
'name': item.name
});
}
syncDepartmentList(item.department_id, pageSize, null);
});
}
var hasMore=result.data.has_more;
if(hasMore){
syncDepartmentList(parentId, pageSize, result.data.page_token);
}
//同步成员
if(syncMembers){
syncMemberList(parentId, pageSize, null)
}
}
//
function syncMemberList(departmentId, pageSize, pageToken) {
var url=`https://open.feishu.cn/open-apis/contact/v3/users/find_by_department?department_id_type=department_id&department_id=${departmentId}&page_size=${pageSize}&user_id_type=user_id`;
if(pageToken){
url=url+'&page_token='+pageToken;
}
const resp = httpGet(url);
const result = JSON.parse(resp.body());
console.log('body',resp.body());
if(result.data.items){
result.data.items.forEach(item=>{
var memberList=informat.company.queryCompanyMemberList({
pageIndex:1,
pageSize:1,
filter:{
conditionList:[{
"fieldId":"feishuUserId",
"opt":"eq",
"value":item.user_id
}]
}
});
var departmentList=item.department_ids;
if(memberList.length==0){//新增
var accountId=addAccount(item);
var roleList=defaultRole==null?[]:[defaultRole];
console.log('新增团队成员',item, departmentId);
informat.company.addCompanyMember(accountId, departmentList, roleList);
informat.company.updateCompanyMember({
id: accountId,
feishuUserId: item.user_id,
});
}else{//编辑
var member=memberList[0];
console.log('编辑团队成员', member.id);
informat.company.updateCompanyMember({
id: member.id,
departmentList: departmentList,
});
}
});
}
var hasMore=result.data.has_more;
if(hasMore){
syncMemberList(departmentId, pageSize, result.data.page_token);
}
}
function addAccount(item){
var mobile=item.mobile;
if(mobile==null){
throw new Error('员工手机号不能为空,请开放查看手机权限');
}
if(mobile.length==14){
mobile=mobile.substr(3);
}
var accountList=informat.system.queryAccountList({
pageIndex: 1,
pageSize: 1,
filter: {
conditionList: [
{
fieldId: 'mobileNo',
opt: 'eq',
value: mobile
}
]
}
});
var accountId=null;
if(accountList.length==0){//账号不存在
console.log('新增账号',item);
accountId=informat.system.addAccount({
oid: item.user_id,
name: item.name,
avatar: 'pic15.png',
userName: mobile,
mobileNo: mobile,
email: item.email,
password: defaultPassword
});
}else{
var oldAccount=accountList[0];
accountId=oldAccount.id;
console.log('编辑账号',item);
informat.system.updateAccount({
id: oldAccount.id,
name: item.name,
userName: mobile,
mobileNo: mobile
});
}
return accountId;
}
function httpGet(url){
var feishuAccessToken=informat.app.feishuAccessToken();
var resp=informat.http.request({
headers: {
"Authorization": "Bearer " + feishuAccessToken
},
method: "GET",
timeout: 30000,
url: url
});
if (200 != resp.statusCode()) {
console.log('url',url)
console.log('resp statusCode',resp.statusCode());
console.log('resp body',resp.body())
throw new Error('发起http请求失败,请联系开发人员');
}
return resp;
}