跳到主要内容

飞书 / Lark 集成设置

Hermes Agent 与飞书和 Lark 集成,作为功能完整的机器人使用。连接成功后,您可以在私聊或群聊中与该代理交流,通过主聊天接收定时任务结果,并通过常规网关流程发送文本、图片、音频和文件附件。

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

  • websocket — 推荐使用;Hermes 主动发起出站连接,无需公开的 Webhook 端点
  • webhook — 当您希望飞书/Lark 通过 HTTP 向您的网关推送事件时非常有用

Hermes 的行为表现

上下文行为
私聊Hermes 对每条消息都作出响应。
群聊Hermes 仅在被 @ 提及的情况下才响应。
共享群聊默认情况下,共享群聊中的会话历史按用户隔离。

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

group_sessions_per_user: true

仅当您明确希望每个群聊共享一个统一对话时,才将其设置为 false

第一步:创建飞书 / Lark 应用

  1. 打开飞书或 Lark 开发者控制台:
  2. 创建一个新应用。
  3. 凭证与基本信息 中,复制 App IDApp Secret
  4. 为应用启用 机器人 功能。
注意

请妥善保管 App Secret。任何持有该密钥的人都可以冒充您的应用。

第二步:选择连接模式

当 Hermes 运行在您的笔记本电脑、工作站或私有服务器上时,请使用 WebSocket 模式。无需公开 URL。官方 Lark SDK 会自动建立并维护持久的出站 WebSocket 连接,并具备自动重连功能。

FEISHU_CONNECTION_MODE=websocket

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

工作原理: 适配器在后台执行器线程中运行 Lark SDK 的 WebSocket 客户端。入站事件(消息、表情反应、卡片操作)会被分发到主 asyncio 循环中。断开连接后,SDK 将自动尝试重新连接。

可选:Webhook 模式

仅当您已在可访问的 HTTP 端点后运行 Hermes 时,才使用 Webhook 模式。

FEISHU_CONNECTION_MODE=webhook

在 Webhook 模式下,Hermes 启动一个 HTTP 服务器(通过 aiohttp),并在以下地址提供飞书端点:

/feishu/webhook

要求: 必须安装 aiohttp Python 包。

您可以自定义 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

当飞书发送 URL 验证挑战(type: url_verification)时,Webhook 会自动响应,以便您在飞书开发者控制台中完成订阅设置。

第三步:配置 Hermes

选项 A:交互式设置

hermes gateway setup

选择 飞书 / Lark 并填写提示信息。

选项 B:手动配置

将以下内容添加到 ~/.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 表示飞书中国版
  • lark 表示 Lark 国际版

第四步:启动网关

hermes gateway

然后从飞书/Lark 向机器人发送消息,以确认连接已激活。

主聊天(Home Chat)

在飞书/Lark 聊天中使用 /set-home 命令,将该聊天设为主频道,用于接收定时任务结果和跨平台通知。

您也可以预先配置:

FEISHU_HOME_CHANNEL=oc_xxx

安全性

用户白名单

在生产环境中,建议设置飞书 Open ID 白名单:

FEISHU_ALLOWED_USERS=ou_xxx,ou_yyy

如果留空,任何能访问机器人的用户都可能使用它。在群聊中,系统会在处理消息前检查发送者的 open_id 是否在白名单中。

Webhook 加密密钥

在 Webhook 模式下运行时,设置加密密钥以启用对入站 Webhook 数据的有效性签名验证:

FEISHU_ENCRYPT_KEY=your-encrypt-key

该密钥可在您的飞书应用配置的 事件订阅 部分找到。设置后,适配器将使用以下签名算法验证每个 Webhook 请求:

SHA256(timestamp + nonce + encrypt_key + body)

计算出的哈希值将与 x-lark-signature 请求头进行时间安全比较。签名无效或缺失的请求将被拒绝,返回 HTTP 401。

提示

在 WebSocket 模式下,签名验证由 SDK 自行处理,因此 FEISHU_ENCRYPT_KEY 为可选项。但在 Webhook 模式下,强烈建议在生产环境中启用。

验证令牌

额外的身份验证层,用于检查 Webhook 数据中的 token 字段:

FEISHU_VERIFICATION_TOKEN=your-verification-token

该令牌同样可在飞书应用的 事件订阅 部分找到。设置后,每个入站 Webhook 数据包必须在其 header 对象中包含匹配的 token。令牌不匹配的请求将被拒绝,返回 HTTP 401。

FEISHU_ENCRYPT_KEYFEISHU_VERIFICATION_TOKEN 可同时使用,实现纵深防御。

群聊消息策略

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

FEISHU_GROUP_POLICY=allowlist   # default
行为
openHermes 会响应任何群组中任何用户的 @提及。
allowlistHermes 仅响应在 FEISHU_ALLOWED_USERS 列表中列出的用户的 @提及。
disabledHermes 完全忽略所有群组消息。

在所有模式下,机器人必须在群组中被显式 @提及(或 @所有人)后,消息才会被处理。私信消息则绕过此限制。

@提及门控的机器人身份

为了在群组中精确检测 @提及,适配器需要知道机器人的身份。该身份可以显式提供:

FEISHU_BOT_OPEN_ID=ou_xxx
FEISHU_BOT_USER_ID=xxx
FEISHU_BOT_NAME=MyBot

如果以上均未设置,适配器将在启动时通过 Application Info API 尝试自动发现机器人名称。为此,需授予 admin:app.info:readonlyapplication:application:self_manage 权限范围。

交互式卡片操作

当用户点击由机器人发送的交互式卡片上的按钮或进行其他交互时,适配器会将这些操作作为合成的 /card 命令事件进行路由:

  • 按钮点击变为:/card button {"key": "value", ...}
  • 卡片定义中的操作 value 负载会以 JSON 格式包含在内。
  • 卡片操作在 15 分钟窗口内去重,以防止重复处理。

卡片操作事件以 MessageType.COMMAND 类型分发,因此会通过正常的命令处理流程。

要使用此功能,请在飞书应用的事件订阅中启用 交互式卡片 事件(card.action.trigger)。

媒体支持

入站(接收)

适配器会接收并缓存来自用户的以下媒体类型:

类型扩展名处理方式
图片.jpg, .jpeg, .png, .gif, .webp, .bmp通过飞书 API 下载并本地缓存
音频.ogg, .mp3, .wav, .m4a, .aac, .flac, .opus, .webm下载并缓存;小尺寸文本文件会自动提取
视频.mp4, .mov, .avi, .mkv, .webm, .m4v, .3gp下载并缓存为文档
文件.pdf, .doc, .docx, .xls, .xlsx, .ppt, .pptx 等下载并缓存为文档

来自富文本(帖子)消息的媒体内容,包括内联图片和文件附件,也会被提取并缓存。

对于小尺寸的文本类文档(.txt, .md),文件内容会自动注入到消息文本中,使代理可以直接读取,无需调用工具。

出站(发送)

方法发送内容
send文本或富文本帖子消息(根据 Markdown 内容自动检测)
send_image / send_image_file将图片上传至飞书,然后以原生图片气泡形式发送(可选标题)
send_document将文件上传至飞书 API,然后作为文件附件发送
send_voice将音频文件作为飞书文件附件上传
send_video上传视频并以原生媒体消息形式发送
send_animationGIF 会被降级为文件附件(飞书无原生 GIF 气泡)

文件上传路由基于扩展名自动完成:

  • .ogg, .opus → 作为 opus 音频上传
  • .mp4, .mov, .avi, .m4v → 作为 mp4 媒体上传
  • .pdf, .doc(x), .xls(x), .ppt(x) → 以对应文档类型上传
  • 其他所有类型 → 作为通用流文件上传

Markdown 渲染与帖子回退

当出站文本包含 Markdown 格式(标题、粗体、列表、代码块、链接等)时,适配器会自动将其作为飞书 帖子 消息发送,并嵌入 md 标签,而非纯文本。这可在飞书客户端中实现富文本渲染。

如果飞书 API 拒绝帖子负载(例如因不支持某些 Markdown 构造),适配器会自动回退为发送纯文本并移除 Markdown 格式。这种两阶段回退机制确保消息始终能送达。

未检测到 Markdown 的纯文本消息将以简单的 text 消息类型发送。

ACK Emoji 反馈

当适配器接收到入站消息时,会立即添加 ✅(OK)emoji 反馈,以表明消息已被接收并正在处理。这为代理完成响应前提供了视觉反馈。

该反馈是持久的——在响应发送后,该 emoji 仍保留在消息上,作为接收凭证。

用户对机器人消息的 emoji 反馈也会被追踪。如果用户在机器人发送的消息上添加或移除 emoji 反馈,该操作会被路由为合成文本事件(reaction:added:EMOJI_TYPEreaction:removed:EMOJI_TYPE),以便代理能够响应用户反馈。

突发保护与批量处理

适配器包含对快速消息洪流的去抖处理,以避免过度压垮代理:

文本批量处理

当用户在短时间内连续发送多条文本消息时,这些消息将在分发前合并为单个事件:

设置环境变量默认值
静默期HERMES_FEISHU_TEXT_BATCH_DELAY_SECONDS0.6s
每批最大消息数HERMES_FEISHU_TEXT_BATCH_MAX_MESSAGES8
每批最大字符数HERMES_FEISHU_TEXT_BATCH_MAX_CHARS4000

媒体批量处理

快速连续发送多个媒体附件(例如拖拽多个图片)会被合并为单个事件:

设置环境变量默认值
静默期HERMES_FEISHU_MEDIA_BATCH_DELAY_SECONDS0.8s

按聊天序列化

同一聊天内的消息按顺序处理(一次一个),以保持对话连贯性。每个聊天拥有独立的锁,因此不同聊天的消息可并发处理。

速率限制(Webhook 模式)

在 webhook 模式下,适配器会针对每个 IP 地址实施速率限制,以防止滥用:

  • 窗口:60 秒滑动窗口
  • 限制:每个窗口内,针对 (app_id, path, IP) 三元组最多 120 个请求
  • 追踪上限:最多追踪 4096 个唯一键(防止内存无限制增长)

超过限制的请求将返回 HTTP 429(请求过多)。

Webhook 异常追踪

适配器会追踪每个 IP 地址连续的错误响应。若同一 IP 地址在 6 小时窗口内连续出现 25 次错误,将记录一条警告。这有助于检测配置错误的客户端或探测行为。

额外的 webhook 保护措施:

  • 请求体大小限制:最大 1 MB
  • 请求体读取超时:30 秒
  • Content-Type 强制校验:仅接受 application/json

WebSocket 调优

使用 websocket 模式时,可自定义重连和心跳行为:

platforms:
feishu:
extra:
ws_reconnect_interval: 120 # Seconds between reconnect attempts (default: 120)
ws_ping_interval: 30 # Seconds between WebSocket pings (optional; SDK default if unset)
设置配置键默认值描述
重连间隔ws_reconnect_interval120s重连尝试之间的等待时间
心跳间隔ws_ping_interval(SDK 默认值)WebSocket 心跳保活消息的频率

按群组访问控制

除了全局的 FEISHU_GROUP_POLICY,还可以通过 config.yaml 中的 group_rules 设置每个群组聊天的细粒度规则:

platforms:
feishu:
extra:
default_group_policy: "open" # Default for groups not in group_rules
admins: # Users who can manage bot settings
- "ou_admin_open_id"
group_rules:
"oc_group_chat_id_1":
policy: "allowlist" # open | allowlist | blacklist | admin_only | disabled
allowlist:
- "ou_user_open_id_1"
- "ou_user_open_id_2"
"oc_group_chat_id_2":
policy: "admin_only"
"oc_group_chat_id_3":
policy: "blacklist"
blacklist:
- "ou_blocked_user"
策略描述
open群组内任何人均可使用机器人
allowlist仅群组 allowlist 中的用户可使用机器人
blacklist除群组 blacklist 中的用户外,其他人均可使用机器人
admin_only仅全局 admins 列表中的用户可在该群组使用机器人
disabled机器人忽略该群组的所有消息

未在 group_rules 中列出的群组将回退到 default_group_policy(默认值为 FEISHU_GROUP_POLICY 的值)。

去重机制

入站消息通过消息 ID 进行去重,TTL 为 24 小时。去重状态在重启之间持久化保存至 ~/.hermes/feishu_seen_message_ids.json

设置环境变量默认值
缓存大小HERMES_FEISHU_DEDUP_CACHE_SIZE2048 条记录

所有环境变量

变量是否必需默认值描述
FEISHU_APP_ID飞书/飞书 Lark 应用 ID
FEISHU_APP_SECRET飞书/飞书 Lark 应用密钥
FEISHU_DOMAINfeishufeishu(中国区)或 lark(国际区)
FEISHU_CONNECTION_MODEwebsocketwebsocketwebhook
FEISHU_ALLOWED_USERS(空)以逗号分隔的 open_id 列表,用于用户白名单
FEISHU_HOME_CHANNEL用于 cron/通知输出的聊天 ID
FEISHU_ENCRYPT_KEY(空)用于 webhook 签名验证的加密密钥
FEISHU_VERIFICATION_TOKEN(空)用于 webhook 负载认证的验证令牌
FEISHU_GROUP_POLICYallowlist群组消息策略:openallowlistdisabled
FEISHU_BOT_OPEN_ID(空)机器人的 open_id(用于 @提及检测)
FEISHU_BOT_USER_ID(空)机器人的 user_id(用于 @提及检测)
FEISHU_BOT_NAME(空)机器人的显示名称(用于 @提及检测)
FEISHU_WEBHOOK_HOST127.0.0.1Webhook 服务器绑定地址
FEISHU_WEBHOOK_PORT8765Webhook 服务器端口
FEISHU_WEBHOOK_PATH/feishu/webhookWebhook 端点路径
HERMES_FEISHU_DEDUP_CACHE_SIZE2048最多追踪的去重消息 ID 数量
HERMES_FEISHU_TEXT_BATCH_DELAY_SECONDS0.6文本突发去抖静默期
HERMES_FEISHU_TEXT_BATCH_MAX_MESSAGES8每次文本批次合并的最大消息数
HERMES_FEISHU_TEXT_BATCH_MAX_CHARS4000每次文本批次合并的最大字符数
HERMES_FEISHU_MEDIA_BATCH_DELAY_SECONDS0.8媒体突发去抖静默期

WebSocket 和按群组 ACL 设置通过 config.yaml 中的 platforms.feishu.extra 配置(详见上方 WebSocket 调优按群组访问控制)。

故障排除

问题解决方案
lark-oapi 未安装安装 SDK:pip install lark-oapi
websockets 未安装;WebSocket 模式不可用安装 websockets:pip install websockets
aiohttp 未安装;Webhook 模式不可用安装 aiohttp:pip install aiohttp
FEISHU_APP_ID 或 FEISHU_APP_SECRET 未设置设置两个环境变量,或通过 hermes gateway setup 进行配置
另一个本地 Hermes 网关正在使用此 Feishu app_id同一 app_id 同一时间只能被一个 Hermes 实例使用。请先停止其他网关。
机器人在群组中无响应确保机器人被 @ 提及,检查 FEISHU_GROUP_POLICY,若策略为 allowlist,请确认发送者在 FEISHU_ALLOWED_USERS 列表中
Webhook 被拒绝:无效的验证令牌确保 FEISHU_VERIFICATION_TOKEN 与 Feishu 应用的事件订阅配置中的令牌一致
Webhook 被拒绝:无效的签名确保 FEISHU_ENCRYPT_KEY 与 Feishu 应用配置中的加密密钥一致
发送的消息显示为纯文本Feishu API 拒绝了发送负载;这是正常的降级行为。请检查日志以获取详细信息。
机器人未收到图片/文件为您的 Feishu 应用授予 im:messageim:resource 权限范围
机器人身份无法自动检测授予 admin:app.info:readonly 权限范围,或手动设置 FEISHU_BOT_OPEN_ID / FEISHU_BOT_NAME
Webhook 请求频率超出限制同一 IP 地址每分钟请求超过 120 次。这通常是配置错误或循环导致的。

工具集

飞书 / Lark 使用 hermes-feishu 平台预设,包含与 Telegram 及其他基于网关的消息平台相同的通用工具。