飞书机器人接入
License 提示
飞书渠道需要 channel.feishu (STANDARD)。如果选 DMZ 中转部署额外需要 deploy.dmz_bridge (ENTERPRISE)。
把一个 Sira 编排器接入飞书 / Lark 自建机器人。员工在飞书内单聊或群聊里 @ 机器人,问答自动走 Sira 编排。
适用场景与限制
| 项 | 支持情况 |
|---|---|
| 飞书自建应用 | ✅ |
| 第三方应用商店应用 | ❌ |
| Webhook-only 群机器人 | ❌(需要"自建机器人",不是"自定义机器人") |
| 单聊 (P2P) | ✅ |
| 群聊 (oc_*) | ✅ |
| @ 机器人触发 | ✅ |
| 流式响应 | ⚠️ 缓冲后单次推送,不做增量编辑(飞书消息编辑接口约 5 次上限) |
| 文本 + Markdown | ✅ |
| 图片入站 | ✅(仅 WebSocket 模式) |
| 文件 / 音频 / 视频入站 | ✅(仅 WebSocket 模式) |
| 图片 / 文件 / 音频 / 视频出站 | ✅ |
| 互动卡片 (Card) | ❌ |
| 消息编辑 / 撤回 / 反应 | ❌ |
| 事件订阅 v2(成员加入、文件、日历等) | ❌(仅订阅 im.message.receive_v1) |
两种连接模式
| 模式 | 何时选 |
|---|---|
| WebSocket | 推荐内网 / 开发环境。Backend 主动外连飞书的长连接,无需公网回调地址。多副本部署会重复连——必须配合 DMZ 中转 |
| Webhook | 推荐生产环境。飞书事件订阅 HTTPS 回调到 Sira。需要公网入口或 DMZ 中转 |
模式在创建 Application 时选择,可后续修改。
第一步:在飞书开放平台创建自建应用
- 打开 飞书开放平台,登录企业管理员账号
- 创建 自建应用 (Internal App / 企业自建)
- 启用 机器人 能力
- 为机器人开通权限:
im:message(接收消息)im:message:send_as_bot(以应用身份发送消息)im:resource(下载图片 / 文件等多媒体;如不需要可跳过)
- 在 凭证与基础信息 页找到:
App ID(cli_xxxxx)App Secret
- 在 事件订阅 页准备:
Verification TokenEncrypt Key(32 位字符串)
第二步:在 Sira 创建 Application
进入 /agent-system/applications,点击 新建应用,选择"飞书"。表单字段:
| 字段 | 必填 | 何时填 | 说明 |
|---|---|---|---|
app_id | ✅ | 都填 | cli_xxxxx |
app_secret | ✅ | 都填(编辑时留空 = 保留旧值) | 飞书凭证 |
connection_mode | ✅ | 都填 | websocket / webhook |
verification_token | ✅(仅 webhook) | webhook | 飞书事件订阅 token |
encrypt_key | ✅(仅 webhook) | webhook | 32 字符加密 key |
deployment | 可选(仅 websocket) | websocket | local / gateway(DMZ 中转) |
绑定一个目标编排器,保存。
第三步:在飞书开放平台填回调地址
仅 webhook 模式需要
WebSocket 模式不需要回调地址——Sira 后端会主动发起 SDK 长连接。
在飞书 事件订阅 → 请求地址:
https://<your-public-host>/api/agent-system/callback/feishu/{application_id}{application_id} 替换为刚创建的 Sira Application ID。
订阅事件:
im.message.receive_v1(必需)
公司内网 + 公网回调
如果 Sira Backend 没有公网,必须启用 DMZ Channel Gateway。把回调地址改为指向 DMZ 节点,DMZ 节点通过反向隧道把请求转发到内网 Sira。
第四步:测试
- 在飞书企业内"添加应用"——确认机器人对该用户可见
- 单聊机器人发一句话:会被路由到绑定的编排器并返回结果
- 群聊里 @ 机器人提问,同样有效
入站消息处理
WebSocket 模式
lark-oapi SDK 在后端进程里开 WebSocket 长连接。每条 im.message.receive_v1 经过:
- 用
message_id去重 - 文本 / Markdown:直接转
ChannelMessage - 图片 / 文件 / 音频 / 视频:调
message_resource接口下载,传到 MinIO,把 presigned URL 注入消息里给 LLM
Webhook 模式
- 收到
url_verification事件 → 直接返回挑战值 - 收到加密回调 → AES 解密
request_body["encrypt"]→ 校验header.signatureHMAC - 仅处理
event_type == "im.message.receive_v1" - 仅
text和post内容类型 会被转发;图片 / 文件 / 音频 / 视频在 webhook 模式下会被忽略并打日志
多媒体入站请用 WebSocket 模式。
出站消息
所有文本回复统一包装为 post 消息:单 [{"tag":"md","text":...}],语言 zh_cn。多媒体走 im.v1.image.create / im.v1.file.create。
流式行为
- 编排器流式输出(chunk 事件)会被累积到内存 buffer
- 直到
finish=True才用message.create一次性发送 - 不做
message.patch增量编辑(飞书有 ~5 次编辑上限,做了反而容易触限失败)
错误反馈
当编排器抛 event=='error',ResponseNormalizer 会把错误转成普通文本帧(剥掉 <!--SANDBOX:...--> 标记),用户看到友好提示而不是无声卡死。
PlatformKey 与跨渠道关联
| Key | 含义 |
|---|---|
feishu | 飞书消息卡片(保留) |
feishu_bot | 飞书机器人(实际走的 key) |
别名:lark → feishu,lark_bot → feishu_bot。员工的飞书 open_id 通过 users.external_ids.feishu_bot 关联到 Sira 用户,与企微 / 微信客服 / Web 等渠道身份打通。
部署多副本注意
WebSocket 模式下,每个进程都会发起一条 SDK 长连接——多副本会让飞书把消息分发给随机一个进程,导致:
- 处理顺序乱
- 个别副本拿不到上下文
解决方案:选 deployment="gateway"——只有 DMZ Bridge 持有那条 WebSocket,多副本通过 Bridge 转发。这需要 deploy.dmz_bridge License。
已知不支持
- 互动卡片:不能渲染按钮 / 表单 / 折叠区
- 消息编辑 / 撤回:编排器中途想修正发出去的消息做不到
- 反应 / 引用 / 表情:未处理
- 事件订阅 v2 完整能力:成员变更、日历、文件、表格等事件全部丢弃
- 音 / 视频转码:直接按
audio/video/stream类型上传原字节 - Webhook 模式下多媒体入站:被丢弃。需要时切换到 WebSocket
相关文档
- Channel Plugin 总览
- 企业微信 AI Bot 配置
- DMZ 中转部署
- 模板变量(在 prompt 中引用
{{platform}}等渠道字段)
