FeishuAuthtimeController(飞书集成管理)¶
管理企业域与飞书(Lark)集成的全流程:飞书企业 corpId / AppId / AppSecret / 服务器外网地址的查询与保存;AppId/AppSecret 凭据可达性验证;企业域组织架构与飞书组织架构的双向同步;按软件 + 飞书 AppId 生成飞书免登跳转链接;按软件单独保存飞书应用 AppSecret / AppId。
- 类级基址:
${myapps.context-path.manager:}/api/authtime(完整路径:{manager-context}/api/authtime<相对路径>) - Tag:飞书集成模块(控制器源码未声明类级
@Tag,本文档按所属业务域命名) - 控制器源码:
obpm-manager/src/main/java/cn/myapps/manager/authtime/controller/feishu/FeishuAuthtimeController.java - 公共说明:
- 类继承
BaseAuthTimeController,通过其success(errmsg, data)/error(errcode, errmsg, errors)返回统一Resource(字段errcode/errmsg/data/errors,结构见 ../index.md「统一响应结构」)。 - 多数端点在
try/catch内捕获Exception并e.printStackTrace()后返回errcode=500、errmsg=e.getMessage()、data=null(HTTP 状态码 200);外网验证失败常用errcode=1。 synch2Feishu/synchFromFeishu未捕获异常,方法签名throws Exception,异常向上抛由 Spring 默认异常处理(HTTP 500,无统一Resource体)。- 鉴权说明见 index.md「鉴权说明」(adminToken JWT)。
- 路径变量:
domainid为企业域 id;applicationid为软件 id;appkey/appsecret为飞书应用的 AppId / AppSecret(路径名沿用钉钉命名appkey/appsecret,语义为飞书 AppId/AppSecret);appid为生成跳转链接用的飞书应用 AppId。 - 源码注释中保留了部分钉钉历史命名(如「保存钉钉应用 AppSecret」用作飞书端点的
@Operation summary),本文档摘要按所属业务域调整为飞书语义。
1. 飞书配置¶
按企业域 id 查询飞书集成配置:企业 corpId、AppId/AppSecret、服务器外网地址;同时返回企业域已绑定软件列表(含每个软件的飞书应用 AppSecret/AppKey)。feishuProxyType 为空时返回 "none"。
- 接口类型:REST 资源
- 请求方式:
GET - 请求路径:
/domain/{domainid}/feishu(完整:{manager-context}/api/authtime/domain/{domainid}/feishu) - 鉴权:是(需管理员 adminToken,详见 index.md「鉴权说明」)
- Tag:飞书集成模块
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| domainid | path | string | 是 | 企业域 id |
请求示例¶
响应¶
结构:统一 Resource(见 ../index.md「统一响应结构」)。
data:JSONObject,字段:
| 字段 | 类型 | 说明 |
|---|---|---|
| feishuProxyType | string | 飞书代理类型(域对象为空时返回 none) |
| feishuCorpID | string | 飞书企业 corpId(Tenant Access Key 维度的企业 ID) |
| feishuAppSecret | string | 飞书企业默认 AppSecret |
| feishuAppId | string | 飞书企业默认 AppId(取自 domain.getFeishuAppKey()) |
| feishuServerHost | string | 服务器外网访问地址 |
| apps | array\<JSONObject> | 企业域已绑定软件的飞书应用配置列表 |
apps 元素字段:
| 字段 | 类型 | 说明 |
|---|---|---|
| id | string | 软件 id |
| name | string | 软件名称 |
| description | string | 软件描述 |
| feishuAppSecret | string | 该软件的飞书应用 AppSecret |
| feishuAppKey | string | 该软件的飞书应用 AppId(AppKey) |
成功示例:
{
"errcode": 0,
"errmsg": "ok",
"data": {
"feishuProxyType": "feishu",
"feishuCorpID": "cli_xxxxxxxx",
"feishuAppSecret": "secret-xxx",
"feishuAppId": "app-xxx",
"feishuServerHost": "https://example.com",
"apps": [
{ "id": "__APP01", "name": "协同办公", "description": "", "feishuAppSecret": "secret-xxx", "feishuAppKey": "app-xxx" }
]
},
"errors": null
}
2. 保存飞书配置¶
按企业域 id 保存飞书集成配置(覆盖企业 corpId、AppId/AppSecret、服务器外网地址中**非空且与现状不同**的字段)。任一字段变更即触发 needUpdate=true,调用 doCreateOrUpdate 持久化并清理飞书 secret 缓存;同时构建 FeishuConfig 并写入 DomainVO。
- 接口类型:REST 资源
- 请求方式:
PUT - 请求路径:
/domain/{domainid}/feishu(完整:{manager-context}/api/authtime/domain/{domainid}/feishu) - 鉴权:是
- Tag:飞书集成模块
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| domainid | path | string | 是 | 企业域 id |
| jsonObject | body | JSON | 是 | 配置包体(字段见下) |
请求体¶
JSON 对象(application/json):
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| feishuProxyType | string | 否 | 飞书代理类型,非空且与现状不同才更新 |
| feishuCorpID | string | 否 | 飞书企业 corpId,非空且与现状不同才更新 |
| feishuAppSecret | string | 否 | 飞书企业默认 AppSecret,非空且与现状不同才更新(同步写入 FeishuConfig) |
| feishuAppId | string | 否 | 飞书企业默认 AppId,对应 body 字段名 feishuAppId,非空且与现状不同才更新(同步写入 FeishuConfig 的 feishuAppKey) |
| feishuServerHost | string | 否 | 服务器外网访问地址,非空且与现状不同才更新 |
注:源码注释中保留了
feishuAgentId/ 钉钉扫码登录相关字段,当前实现已注释掉,不参与保存。
请求示例¶
PUT /api/authtime/domain/__P1UD2yVWpnFpUedONr/feishu HTTP/1.1
Content-Type: application/json
{
"feishuProxyType": "feishu",
"feishuCorpID": "cli_xxxxxxxx",
"feishuAppId": "app-xxx",
"feishuAppSecret": "secret-xxx",
"feishuServerHost": "https://example.com"
}
响应¶
结构:统一 Resource。
data:字符串 "保存成功"。
成功示例:
失败示例:3. AppId及AppSecret验证¶
用飞书应用 AppId / AppSecret(路径名沿用 appkey/appsecret)调用 FeishuService.getAccessToken 校验飞书开放平台可达性与应用凭据有效性。getAccessToken 返回非空视为成功,返回 null 视为验证失败(errcode=1)。
- 接口类型:REST 资源
- 请求方式:
GET - 请求路径:
/domain/{domainid}/feishu/appkey/{appkey}/appsecret/{appsecret}(完整:{manager-context}/api/authtime/domain/{domainid}/feishu/appkey/{appkey}/appsecret/{appsecret}) - 鉴权:是
- Tag:飞书集成模块
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| domainid | path | string | 是 | 企业域 id(路径变量,方法签名持有但实际逻辑未直接使用) |
| appkey | path | string | 是 | 飞书应用 AppId(路径名 appkey) |
| appsecret | path | string | 是 | 飞书应用 AppSecret |
注:将 AppSecret 放在 URL 路径中存在泄露风险,建议生产环境配合 HTTPS / 网关日志脱敏使用。
请求示例¶
响应¶
结构:统一 Resource。
data:字符串 "验证成功"。
| 条件 | errcode | errmsg | data |
|---|---|---|---|
getAccessToken 返回 null |
1 | 验证失败 |
null |
| 验证成功 | 0 | ok | 验证成功 |
| 抛异常 | 500 | <异常信息> |
null |
成功示例:
失败示例:4. 同步企业域组织架构到飞书¶
按企业域 id 取出域对象,调用 FeishuService.synch2Feishu 将企业域下的部门 / 用户推送到飞书,返回同步结果。
- 接口类型:REST 资源
- 请求方式:
PUT - 请求路径:
/domain/{domainid}/synch2feishu(完整:{manager-context}/api/authtime/domain/{domainid}/synch2feishu) - 鉴权:是
- Tag:飞书集成模块
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| domainid | path | string | 是 | 企业域 id |
请求示例¶
响应¶
结构:统一 Resource。
data:net.sf.json.JSONObject(由 FeishuService.synch2Feishu 返回,结构由同步逻辑决定)。
注:本端点方法签名
throws Exception,未捕获异常,失败时由 Spring 默认异常处理(HTTP 500,无统一Resource体)。
成功示例:
失败示例:5. 同步飞书组织架构到企业域¶
按企业域 id 取出域对象,调用 FeishuService.synchFromFeishu 将飞书通讯录拉取到企业域(部门 / 用户)。
- 接口类型:REST 资源
- 请求方式:
PUT - 请求路径:
/domain/{domainid}/synchfromfeishu(完整:{manager-context}/api/authtime/domain/{domainid}/synchfromfeishu) - 鉴权:是
- Tag:飞书集成模块
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| domainid | path | string | 是 | 企业域 id |
请求示例¶
响应¶
结构:统一 Resource。
data:net.sf.json.JSONObject(由 FeishuService.synchFromFeishu 返回)。
注:方法名
synchFromDingding(源码命名沿用钉钉模板),实际调用的是synchFromFeishu;方法签名throws Exception,未捕获异常,失败时由 Spring 默认异常处理(HTTP 500,无统一Resource体)。
成功示例:
失败示例:6. 生成跳转链接¶
按企业域 + 软件 + 飞书 AppId 生成飞书免登跳转链接:拼接 https://open.feishu.cn/open-apis/authen/v1/index?redirect_uri=<serverHost>/static/feishu.html?domainid=<domainid>&app_id=<appid>。返回 Map 固定键 "进入系统"。
- 接口类型:REST 资源
- 请求方式:
GET - 请求路径:
/domain/{domainid}/application/{applicationid}/getfeishuurl/appid/{appid}(完整:{manager-context}/api/authtime/domain/{domainid}/application/{applicationid}/getfeishuurl/appid/{appid}) - 鉴权:是
- Tag:飞书集成模块
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| domainid | path | string | 是 | 企业域 id |
| applicationid | path | string | 是 | 软件 id(路径变量,方法签名持有但实际逻辑未直接使用) |
| appid | path | string | 是 | 飞书应用 AppId |
请求示例¶
GET /api/authtime/domain/__P1UD2yVWpnFpUedONr/application/__APP01/getfeishuurl/appid/app-xxx HTTP/1.1
响应¶
结构:统一 Resource。
data:Map<String, String>,键固定为 "进入系统",值为拼好的跳转 URL。
注:源码额外把
uris写入request属性(疑似为视图渲染保留),但作为@RestController端点,最终响应体即上述Resource。
成功示例:
{
"errcode": 0,
"errmsg": "ok",
"data": { "进入系统": "https://open.feishu.cn/open-apis/authen/v1/index?redirect_uri=https://example.com/static/feishu.html?domainid=__P1UD2yVWpnFpUedONr&app_id=app-xxx" },
"errors": null
}
7. 保存飞书应用 AppSecret¶
按企业域 + 软件保存该软件的飞书应用 AppSecret(写入 DomainVO 中按软件 id 维度的 AppSecret 映射),并持久化(doCreateOrUpdate)。
- 接口类型:REST 资源
- 请求方式:
PUT - 请求路径:
/domain/{domainid}/application/{applicationid}/updatefeishuappsecret(完整:{manager-context}/api/authtime/domain/{domainid}/application/{applicationid}/updatefeishuappsecret) - 鉴权:是
- Tag:飞书集成模块
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| domainid | path | string | 是 | 企业域 id |
| applicationid | path | string | 是 | 软件 id |
| appsecret | query | string | 是 | 飞书应用 AppSecret |
请求示例¶
PUT /api/authtime/domain/__P1UD2yVWpnFpUedONr/application/__APP01/updatefeishuappsecret?appsecret=secret-xxx HTTP/1.1
响应¶
结构:统一 Resource。
data:字符串 "保存成功"。
成功示例:
失败示例:8. 保存飞书应用 AppId¶
按企业域 + 软件保存该软件的飞书应用 AppId(写入 DomainVO 中按软件 id 维度的 AppKey 映射),并持久化。
- 接口类型:REST 资源
- 请求方式:
PUT - 请求路径:
/domain/{domainid}/application/{applicationid}/updatefeishuappId(完整:{manager-context}/api/authtime/domain/{domainid}/application/{applicationid}/updatefeishuappId) - 鉴权:是
- Tag:飞书集成模块
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| domainid | path | string | 是 | 企业域 id |
| applicationid | path | string | 是 | 软件 id |
| id | query | string | 是 | 飞书应用 AppId(请求参数名以方法签名 @RequestParam String id 为准;源码 @Parameter(name = "appid") 与之不一致,调用方需按 id 传值) |
注:路径段为
updatefeishuappId(其中I大写);源码@Parameter(name = "appid")仅作 Swagger 文档展示,实际绑定到@RequestParam String id,请求时须用id作为 query 参数名。
请求示例¶
PUT /api/authtime/domain/__P1UD2yVWpnFpUedONr/application/__APP01/updatefeishuappId?id=app-xxx HTTP/1.1
响应¶
结构:统一 Resource。
data:字符串 "保存成功"。
成功示例:
失败示例: