# 飞书 Access Token 配置指南 ## 概述 本模块支持两种消息推送方式: 1. **Webhook 方式**(无需 access token) - 推送到群组 - 通过 @user_id 提及群组中的个人 - 简单易用,无需额外配置 2. **开放平台 API 方式**(需要 access token) - 直接推送到个人聊天 - 批量推送到多人 - 需要配置 app_id 和 app_secret ## 为什么需要 Access Token? 飞书的自定义机器人 Webhook 只能推送到群组,如果需要直接推送到个人聊天,就需要使用飞书开放平台 API,这需要: 1. 创建企业自建应用 2. 获取 app_id 和 app_secret 3. 通过这两个参数获取 tenant_access_token 4. 使用 token 调用发送消息 API ## Token 管理机制 本模块实现了完整的 token 管理机制: - **自动获取**:首次使用时自动从飞书 API 获取 token - **数据库存储**:token 保存到 Parse Server 的 Store 表的 config 字段 - **自动刷新**:token 过期前自动刷新(提前 5 分钟) - **缓存优化**:优先从数据库读取,避免频繁请求飞书 API ### 数据库存储格式 Token 保存在 Store 表的 config 字段中,格式如下: ```json { "feishu": { "accessToken": "t-xxx", "expireTime": 1709971200000 } } ``` - `accessToken`: 飞书的 tenant_access_token - `expireTime`: 过期时间戳(毫秒),提前 5 分钟过期 ## 配置步骤 ### 1. 创建企业自建应用 1. 访问 [飞书开放平台](https://open.feishu.cn/) 2. 登录企业管理员账号 3. 进入"开发者后台" → "企业自建应用" 4. 点击"创建企业自建应用" 5. 填写应用信息(名称、描述、图标等) 6. 创建完成后,进入应用详情页 ### 2. 获取 App ID 和 App Secret 在应用详情页的"凭证与基础信息"中,可以看到: - **App ID**:应用的唯一标识(格式:cli_xxx) - **App Secret**:应用的密钥(点击"查看"按钮显示) **重要提示:** - App Secret 只显示一次,请妥善保管 - 如果忘记,可以重置,但会导致旧的 token 失效 ### 3. 配置应用权限 在应用详情页的"权限管理"中,需要开通以下权限: - **im:message** - 获取与发送单聊、群组消息 - **im:message:send_as_bot** - 以应用的身份发消息 配置权限后,需要等待管理员审批(如果你是管理员,可以直接通过)。 ### 4. 配置环境变量 在服务器上配置以下环境变量: ```bash # Linux/Mac export FEISHU_APP_ID="cli_xxx" export FEISHU_APP_SECRET="your_app_secret" # Windows (PowerShell) $env:FEISHU_APP_ID="cli_xxx" $env:FEISHU_APP_SECRET="your_app_secret" # Windows (CMD) set FEISHU_APP_ID=cli_xxx set FEISHU_APP_SECRET=your_app_secret ``` 或者在 `.env` 文件中配置(如果项目使用 dotenv): ```env FEISHU_APP_ID=cli_xxx FEISHU_APP_SECRET=your_app_secret ``` ### 5. 验证配置 启动服务后,调用任意需要 access token 的接口,系统会自动: 1. 从环境变量读取 app_id 和 app_secret 2. 调用飞书 API 获取 tenant_access_token 3. 保存到数据库(Store 表的 config 字段) 4. 返回成功响应 如果配置错误,会返回错误信息: ```json { "success": false, "error": "飞书配置无效:请设置 FEISHU_APP_ID 和 FEISHU_APP_SECRET 环境变量", "timestamp": "2026-03-09T14:00:00.000Z" } ``` ## Token 生命周期 ### Token 有效期 - 飞书的 tenant_access_token 有效期为 **2 小时**(7200 秒) - 本模块会提前 5 分钟刷新 token,避免边界情况 ### Token 刷新流程 ``` 1. 前端请求接口 ↓ 2. 后端检查数据库中的 token ↓ 3. 判断是否过期 ├─ 未过期:直接使用 └─ 已过期: ├─ 调用飞书 API 获取新 token ├─ 保存到数据库 └─ 使用新 token ↓ 4. 调用飞书 API 发送消息 ↓ 5. 返回结果 ``` ### 手动刷新 Token 如果需要手动刷新 token(例如,怀疑 token 失效),可以: 1. 删除数据库中的 token 记录 2. 下次请求时会自动重新获取 或者,可以添加一个管理接口来手动刷新 token(需要自行实现)。 ## 安全建议 1. **保护 App Secret** - 不要在前端代码中暴露 app_secret - 不要提交到 Git 仓库 - 使用环境变量或密钥管理服务 2. **限制应用权限** - 只开通必要的权限 - 定期审查应用权限 3. **监控 Token 使用** - 记录 token 获取和刷新日志 - 监控异常的 token 使用情况 4. **定期轮换密钥** - 定期重置 app_secret - 更新环境变量配置 ## 常见问题 ### Q1: 为什么获取 token 失败? **可能原因:** - app_id 或 app_secret 配置错误 - 应用未启用或已停用 - 网络连接问题 **解决方法:** 1. 检查环境变量配置是否正确 2. 在飞书开放平台检查应用状态 3. 检查服务器网络连接 ### Q2: Token 过期后会自动刷新吗? 是的,本模块会自动检查 token 是否过期,如果过期会自动刷新。 ### Q3: 可以手动指定 token 吗? 不建议。本模块已经实现了完整的 token 管理机制,手动指定 token 可能导致: - Token 过期后无法自动刷新 - 多个服务实例之间 token 不一致 ### Q4: 数据库中的 token 丢失了怎么办? 不用担心,下次请求时会自动重新获取并保存。 ### Q5: 如何查看当前的 token? 可以直接查询 Parse Server 的 Store 表: ```javascript const query = new Parse.Query('Store'); query.equalTo('objectId', 'config'); const store = await query.first({ useMasterKey: true }); const config = store.get('config'); console.log(config.feishu); ``` ## 技术实现 ### Token 管理器 本模块使用单例模式实现了 `TokenManager` 类,负责: - 从飞书 API 获取 token - 保存到数据库 - 从数据库读取 - 检查是否过期 - 自动刷新 ### 配置管理 配置管理模块从环境变量读取 app_id 和 app_secret: ```typescript export function getFeishuConfig(): FeishuConfig { return { app_id: process.env.FEISHU_APP_ID || '', app_secret: process.env.FEISHU_APP_SECRET || '' }; } ``` ### 使用示例 在路由中使用 token: ```typescript import { getTokenManager } from './token-manager'; // 获取 token const tokenManager = getTokenManager(); const accessToken = await tokenManager.getAccessToken(); // 使用 token 调用飞书 API const response = await fetch('https://open.feishu.cn/open-apis/im/v1/messages', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${accessToken}` }, body: JSON.stringify({...}) }); ``` ## 参考资料 - [飞书开放平台 - 获取 tenant_access_token](https://open.feishu.cn/document/server-docs/api-call-guide/calling-process/get-access-token) - [飞书开放平台 - 发送消息](https://open.feishu.cn/document/server-docs/im-v1/message/create) - [飞书开放平台 - 权限说明](https://open.feishu.cn/document/home/introduction-to-scope-and-authorization/list-of-permissions-by-feature)