跳到主要内容

Feishu / Lark

Hermes Agent 可作为功能完整的 bot 接入 Feishu 和 Lark。接入后,你可以在私聊和群聊中与 agent 对话,在 home chat 中接收 cron 结果,并按标准网关流程收发文本、图片、音频和文件附件。

该集成支持两种连接模式:

  • websocket:推荐;Hermes 主动建立出站连接,无需公网 webhook 端点
  • webhook:适合你已经有可访问的 HTTP 入口,希望由 Feishu/Lark 主动推送事件的场景

Hermes 的行为方式

ContextBehavior
Direct messagesHermes 会回复每一条消息。
Group chats只有在群里显式 @ bot 时 Hermes 才会回复。
Shared group chats默认按用户隔离共享群聊中的会话历史。

该共享群行为由 config.yaml 控制:

group_sessions_per_user: true

如果你明确希望整个群共享一段会话,可改为 false

第 1 步:创建 Feishu / Lark App

推荐:扫码创建(一条命令完成)

hermes gateway setup

选择 Feishu / Lark,然后用 Feishu 或 Lark 手机端扫描二维码。Hermes 会自动创建一个权限配置正确的 bot 应用,并保存凭据。

备选:手动设置

  1. 打开开发者控制台:
  2. 创建新应用
  3. Credentials & Basic Info 中复制 App IDApp Secret
  4. 为应用启用 Bot 能力
  5. 运行 hermes gateway setup,选择 Feishu / Lark 并按提示输入这些凭据
注意

请妥善保管 App Secret。任何获得该密钥的人都可以冒充你的应用。

第 2 步:选择连接模式

推荐:WebSocket 模式

如果 Hermes 运行在你的笔记本、工作站或私有服务器上,建议使用 WebSocket 模式;它无需公网 URL。官方 Lark SDK 会自动维护一条持久出站 WebSocket,并负责重连。

FEISHU_CONNECTION_MODE=websocket

要求: 需安装 websockets Python 包。SDK 会在内部处理连接生命周期、心跳和自动重连。

可选:Webhook 模式

如果你已经拥有可访问的 HTTP 入口,也可以选择 webhook 模式:

FEISHU_CONNECTION_MODE=webhook

此模式下,Hermes 会启动一个 aiohttp HTTP 服务,并在以下路径暴露 Feishu webhook:

/feishu/webhook

可自定义绑定地址与路径:

FEISHU_WEBHOOK_HOST=127.0.0.1   # default: 127.0.0.1
FEISHU_WEBHOOK_PORT=8765 # default: 8765
FEISHU_WEBHOOK_PATH=/feishu/webhook # default: /feishu/webhook

当 Feishu 发送 URL 验证挑战(type: url_verification)时,适配器会自动应答。

第 3 步:配置 Hermes

Option A: Interactive Setup

hermes gateway setup

Option B: Manual Configuration

把以下内容加入 ~/.hermes/.env

FEISHU_APP_ID=cli_xxx
FEISHU_APP_SECRET=secret_xxx
FEISHU_DOMAIN=feishu
FEISHU_CONNECTION_MODE=websocket

# Optional but strongly recommended
FEISHU_ALLOWED_USERS=ou_xxx,ou_yyy
FEISHU_HOME_CHANNEL=oc_xxx

FEISHU_DOMAIN 可取:

  • feishu:中国区 Feishu
  • lark:国际版 Lark

第 4 步:启动网关

hermes gateway

然后从 Feishu/Lark 给 bot 发一条消息,确认连接已生效。

Home Chat

你可以在任意 Feishu/Lark 聊天中使用 /set-home 把它标记为 home channel,用于接收 cron 结果和跨平台通知。

你也可以手动配置:

FEISHU_HOME_CHANNEL=oc_xxx

安全

用户 allowlist

生产环境建议设置 Feishu Open ID allowlist:

FEISHU_ALLOWED_USERS=ou_xxx,ou_yyy

如果不设置,任何能触达 bot 的用户都可能使用它。在群聊中,消息处理前会使用发送者的 open_id 进行校验。

Webhook Encryption Key

在 webhook 模式下,建议设置加密 key,以启用入站 webhook 签名验证:

FEISHU_ENCRYPT_KEY=your-encrypt-key

当设置后,适配器会使用以下算法验证每个 webhook 请求:

SHA256(timestamp + nonce + encrypt_key + body)

Verification Token

还可以额外设置 verification token,校验 webhook payload 中的 token 字段:

FEISHU_VERIFICATION_TOKEN=your-verification-token

FEISHU_ENCRYPT_KEYFEISHU_VERIFICATION_TOKEN 可以一起使用,形成双重防护。

Group Message Policy

FEISHU_GROUP_POLICY 环境变量控制 Hermes 在群聊中的行为:

FEISHU_GROUP_POLICY=allowlist   # default
ValueBehavior
open对任意群里的任意用户 @ bot 都会响应
allowlist只有 FEISHU_ALLOWED_USERS 中的用户 @ bot 时才响应
disabled完全忽略所有群消息

无论哪种模式,群聊中都必须显式 @ bot(或 @all)后才会处理;私聊不受此限制。

Bot Identity for @Mention Gating

为了在群里精确判断是否 @ 到 bot,适配器需要知道 bot 的身份。你可以显式提供:

FEISHU_BOT_OPEN_ID=ou_xxx
FEISHU_BOT_USER_ID=xxx
FEISHU_BOT_NAME=MyBot

如果都没有设置,适配器会在启动时尝试通过 Application Info API 自动发现 bot 名称。为此,你需要授予 admin:app.info:readonlyapplication:application:self_manage scope。

Interactive Card Actions

当用户点击 bot 发出的交互式卡片按钮时,适配器会把这些动作转换为合成的 /card 命令事件:

  • 按钮点击会变成:/card button {"key": "value", ...}
  • 卡片定义中的 value payload 会以 JSON 形式附带进来
  • 卡片动作会在 15 分钟窗口内去重,防止重复处理

这也是危险命令审批在 Feishu/Lark 中的实现方式:当 agent 需要执行危险命令时,它会发一张带有 Allow Once / Session / Always / Deny 按钮的交互卡片,用户点击按钮后,审批结果就会通过 card action 回调传回 agent。

Required Feishu App Configuration

交互卡片需要在 Feishu 开发者后台完成三项设置,少任何一项都可能在点击按钮时出现 200340 错误:

  1. Event Subscriptions 中订阅 card.action.trigger
  2. App Features > Bot 中启用 Interactive Card
  3. 若使用 webhook 模式,在 Message Card Request URL 中配置与事件 webhook 相同的地址

Document Comment Intelligent Reply

除了聊天外,适配器还支持在 Feishu/Lark 文档评论中对 @mention 作答。当用户在文档评论中 @ bot 时,Hermes 会读取文档内容与评论上下文,并在线程中回复。

它基于 drive.notice.comment_add_v1 事件工作,处理流程包括:

  • 并行拉取文档内容和评论时间线
  • 在单独的评论会话中运行 agent,并只启用 feishu_docfeishu_drive 工具集
  • 把回复按 4000 字符分块,并作为 threaded replies 回发
  • 为每个文档缓存 1 小时的会话上下文,便于后续追问延续上下文

3-Tier Access Control

文档评论回复采用显式授权模式,没有默认 allow-all。权限按以下顺序匹配:

  1. 精确文档规则
  2. 通配符规则
  3. 顶层默认规则

每条规则可以使用两种策略:

  • allowlist:静态用户 / tenant 列表
  • pairing:静态列表 + 运行时批准存储,适合逐步放量

规则文件位于 ~/.hermes/feishu_comment_rules.json,pairing 授权存放于 ~/.hermes/feishu_comment_pairing.json。它们支持基于 mtime 的热加载,无需重启网关。

媒体支持

入站(接收)

适配器会接收并缓存以下媒体:

TypeExtensionsHow it's processed
Images.jpg, .jpeg, .png, .gif, .webp, .bmp通过 Feishu API 下载并缓存
Audio.ogg, .mp3, .wav, .m4a, .aac, .flac, .opus, .webm下载并缓存;小型文本文件会自动抽取内容
Video.mp4, .mov, .avi, .mkv, .webm, .m4v, .3gp下载并缓存为文档
Files.pdf, .doc, .docx, .xls, .xlsx, .ppt, .pptx 等下载并缓存为文档

富文本(post)消息中的内嵌图片和文件附件也会被提取。

出站(发送)

MethodWhat it sends
send文本或 rich post 消息
send_image / send_image_file原生图片消息
send_document文件附件
send_voice音频文件附件
send_video原生视频消息
send_animationGIF 会降级为文件附件

Markdown Rendering and Post Fallback

当出站文本包含 Markdown(标题、加粗、列表、代码块、链接等)时,适配器会优先将其作为 Feishu post 消息发送。若 Feishu API 拒绝该 post payload,适配器会自动回退为纯文本发送,以确保消息一定送达。

Processing Status Reactions

在 agent 工作期间,bot 会在你的消息上显示 Typing reaction。回复完成后会清除;如果处理失败,则改为 CrossMark

可通过 FEISHU_REACTIONS=false 关闭。

Burst Protection and Batching

适配器内置了防抖和合并逻辑,以避免短时间内的消息洪峰压垮 agent:

  • 文本消息会按 quiet period 合并成一个批次再送入 agent
  • 多个媒体附件也会按 burst 合并成一个事件
  • 同一聊天内部仍按顺序串行处理,以保持会话连贯性

Rate Limiting (Webhook Mode)

在 webhook 模式下,适配器会按 IP 做限流:

  • Window: 60 秒滑动窗口
  • Limit: 每个 (app_id, path, IP) 组合 120 次请求 / 窗口
  • Tracking cap: 最多跟踪 4096 个 key,避免内存无限增长

超限请求会返回 HTTP 429。

WebSocket Tuning

使用 websocket 模式时,可在 config.yaml 中调整重连和 ping:

platforms:
feishu:
extra:
ws_reconnect_interval: 120
ws_ping_interval: 30

Per-Group Access Control

除了全局 FEISHU_GROUP_POLICY 外,你还可以在 config.yamlgroup_rules 中按群精细配置:

platforms:
feishu:
extra:
default_group_policy: "open"
admins:
- "ou_admin_open_id"
group_rules:
"oc_group_chat_id_1":
policy: "allowlist"
allowlist:
- "ou_user_open_id_1"
"oc_group_chat_id_2":
policy: "admin_only"

支持的策略包括 openallowlistblacklistadmin_onlydisabled

Deduplication

入站消息会基于 message ID 做 24 小时 TTL 去重。去重状态会持久化到 ~/.hermes/feishu_seen_message_ids.json

All Environment Variables

VariableRequiredDefaultDescription
FEISHU_APP_IDFeishu/Lark App ID
FEISHU_APP_SECRETFeishu/Lark App Secret
FEISHU_DOMAINfeishufeishu(中国区)或 lark(国际版)
FEISHU_CONNECTION_MODEwebsocketwebsocketwebhook
FEISHU_ALLOWED_USERS(empty)逗号分隔的 open_id allowlist
FEISHU_HOME_CHANNELcron / 通知输出 chat ID
FEISHU_ENCRYPT_KEY(empty)webhook 签名验证 key
FEISHU_VERIFICATION_TOKEN(empty)webhook payload 验证 token
FEISHU_GROUP_POLICYallowlist群消息策略
FEISHU_BOT_OPEN_ID(empty)bot 的 open_id
FEISHU_BOT_USER_ID(empty)bot 的 user_id
FEISHU_BOT_NAME(empty)bot 显示名称
FEISHU_WEBHOOK_HOST127.0.0.1webhook 绑定地址
FEISHU_WEBHOOK_PORT8765webhook 端口
FEISHU_WEBHOOK_PATH/feishu/webhookwebhook 路径

Troubleshooting

ProblemFix
lark-oapi not installed安装 SDK:pip install lark-oapi
websockets not installed; websocket mode unavailable安装 websockets
aiohttp not installed; webhook mode unavailable安装 aiohttp
FEISHU_APP_ID or FEISHU_APP_SECRET not set设置环境变量或通过 hermes gateway setup 配置
另一个本地实例正在使用同一个 app_id同一个 app_id 同时只能被一个 Hermes 实例使用
群里不回复确认已 @ bot,并检查 FEISHU_GROUP_POLICY 与 allowlist
Webhook rejected: invalid verification token检查 FEISHU_VERIFICATION_TOKEN
Webhook rejected: invalid signature检查 FEISHU_ENCRYPT_KEY
Post 消息被降级成纯文本这是正常回退行为,可查看日志了解具体原因
bot 收不到图片 / 文件给 Feishu app 授予 im:messageim:resource scope
bot 身份自动发现失败授予 admin:app.info:readonly scope,或手动设置 FEISHU_BOT_OPEN_ID / FEISHU_BOT_NAME
点击审批按钮时报 200340在开发者后台启用 Interactive Card 并配置 Card Request URL
Webhook rate limit exceeded同一 IP 在 1 分钟内超过 120 个请求,通常意味着配置错误或发生循环

Toolset

Feishu / Lark 使用 hermes-feishu 平台预设,包含与 Telegram 等消息平台相同的核心工具。