Appearance
飞书
织信支持与飞书进行集成,通过飞书自建应用并完成相关配置,即可在飞书工作台使用织信。
1.注册飞书
首先,需要在 飞书 注册账号创建团队。
2.在飞书开放平台创建企业自建应用
创建完团队后,需要进入 飞书开放平台 创建一个企业自建应用。 然后按照要求填写好应用资料,填写完毕点击「确定创建」
点击刚创建的应用,在「凭证与基础信息」中,将参数 AppID 和 App Secret 记录下来。
3.自建应用设置权限
选择「权限管理」, 开通以下权限:
- 获取用户 user ID
- 获取用户基本信息
- 获取部门基础信息
- 获取部门组织架构信息
在「权限管理」中,将需要设置的权限一一选择,然后点击「批量开通」。如下图所示:
4.获取织信团队ID
打开织信工作台,选择「团队 >> 团队设置」,找到「团队ID」。
5.自建应用安全设置
在「安全设置」中的「重定向 URL」中添加:https://next.informat.cn/web0/feishu/login/{团队ID}
URL最后一个参数是上一步获取的团队ID
6.自建应用启用网页
选择「应用功能 >> 网页」,启用网页,设置桌面端和移动端主页后,点击「保存」。
如需跳转系统工作台应用列表,则设置:
- 桌面端主页:
https://next.informat.cn/web0/feishu/enter/{团队ID}
- 移动端主页:
https://next.informat.cn/web0/feishu/mobile_enter/{团队ID}
如需跳转指定应用首页,则设置:
- 桌面端主页:
https://next.informat.cn/web0/feishu/enter/{团队ID}/{应用ID}
- 移动端主页:
https://next.informat.cn/web0/feishu/mobile_enter/{团队ID}/{应用ID}
链接最后一个参数是上一步得到的团队ID:xqrqdfvte9tnk
7.织信第三方集成飞书
在织信工作台「团队 >> 团队设置」下,找到「第三方集成」,选择「飞书」,点击「启用此功能」,填入第2步保存的飞书AppID 和 App Secret后点击「保存」。
8.织信团队成员设置飞书账号ID
- 8.1 在织信工作台「团队 >> 团队设置」下,找到「成员」,点击「编辑」按钮,打开成员编辑页面。
- 8.2 打开飞书管理后台,在「组织架构 >> 成员与部门」下找到织信成员对应的飞书成员,点击对应成员「姓名」打开成员详情,找到用户ID,并复制。
- 8.3 在8.1打开的编辑成员页面里,「飞书账号ID」,填入8.2得到的飞书用户ID,并保存
9.飞书自建应用发布版本
在飞书开放平台,打开上面建好的自建应用页面。找到「应用发布>> 版本管理与发布」,点击「创建版本」 版本详情页面如下填写: 应用版本号: 1.0.0 更新说明: 初始版本 点击「保存」
然后点击「申请线上发布」。
10.飞书工作台打开织信
在飞书客户端或者移动端,在工作台的列表中,找到上述创建好的自建应用,点击打开,就会免登录跳转到织信的工作台。 如果跳转到织信登录页面,说明当前飞书账号未和织信账号绑定,需要按照第8步流程,给织信团队成员设置飞书账号ID
11.飞书通知
在飞书开放平台,打开自建应用页面。找到「应用功能>> 机器人」,点击「启用机器人」
在「权限管理」中,将以下需要设置的权限一一选择,然后点击「批量开通」。如下图所示:
- im:message
- im:message:send_as_bot
以上设置完成后,发送通时,会将消息同步发送给已绑定的飞书用户
12.飞书扫码登录
- 12.1 在织信工作台「团队 >> 团队设置 >> 登录页面」下,点击「启用团队登录页面」、「启用第三方扫码登录」。
- 12.2 在织信工作台「团队 >> 团队设置 >> 第三方集成」下找到「飞书」,点击「启用登录」,启用
飞书扫码
登录。
需要注意,扫码登录需要给团队成员绑定飞书账号ID
。
13.对接飞书同步组织架构和成员
13.1 概述
在企业内部通常会使用飞书
等即时通讯工具作为日常办公的沟通工具,这类工具通常提供了组织架构管理、用户管理、通知、待办等功能。 下面是对接飞书并同步组织架构和成员到织信的步骤。
13.2 实现步骤
- 同步飞书组织架构前,需要先完成「第三方集成 >> 飞书」的集成。
- 开通通讯录权限,至少包含获取部门基础信息、获取通讯录部门组织架构信息、获取用户基本信息、获取用户userID、获取用户手机号、以应用身份读取通讯录这六个权限。
13.3 实现代码
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;
}