更新(2026-09-08 11:29):本文初稿是「排查手册」(飞书没跑过,翻车记录是空的)。现在我已实际装上飞书插件、配好凭据、抓到真实报错(
11205)→ 定位根因 → 修复并复测通过。第四节是全新的第一手实测,包含完整日志时间线、修复前后对比、一个 3 分钟自检脚本,以及对验证边界的诚实说明。
零、先说清楚证据等级
文中每一节我都会标:
- 【官方原文】 — 来自 OpenClaw 官方文档
docs/channels/feishu.md,可自行查验 - 【实测】 — 2026-09-08 我在本机(OpenClaw 2026.8.2 / Ubuntu 22.04)真装真跑,附真实日志
- 【我的推测】 — 没有证据支撑,仅供参考
这个区分很重要:排障文章最害人的就是编造"我改了这个参数就好了"。我没验证过的,我会说没验证过;我验证过的,我会把日志贴出来让你自己核对。
装好之后的真实状态(已改变)
初稿写的时候飞书还是 not installed,现在是:
$ openclaw channels list --all
- Feishu default: installed, configured, enabled
$ openclaw plugins list | grep -i feishu
│ Feishu/Lark │ feishu │ openclaw │ enabled │ 2026.8.2 │
但「enabled」不等于「能用」——这正是本文最有价值的地方,见第四节。
一、机制:为什么飞书会"无限重连"
【官方原文】WebSocket 是默认传输
WebSocket is the default event transport (no public URL needed); webhook mode is optional.
翻译:飞书默认走 WebSocket 长连接,不需要公网 URL / 不需要配 webhook 回调地址——这是它比 webhook 模式省事的地方。但也正因为是长连接,断开和重连就是常态。
【官方原文】关键机制:持久化失败会强制重连
这段是理解"无限重连"的核心,我原文引用:
If a WebSocket event cannot be persisted after bounded retries, OpenClaw closes that socket and forces a fresh authenticated connection instead of continuing past an uncommitted turn.
人话翻译:
- 收到一条飞书消息,OpenClaw 会先把它落盘(durable queue),保证不丢
- 如果落盘重试若干次还是失败,OpenClaw 会主动断开这条 socket,重新建立一条新的带认证的連接
- 它是"宁可重连,也不往下处理未提交的消息"
这意味着什么:如果你看到重连循环,病根可能不在网络,而在落盘失败。落盘失败的常见原因是磁盘写满、权限问题、或者数据库锁。
这是一个反直觉但极有价值的判断方向——大部分人遇到重连第一反应是查网络,但官方文档明说了:落盘失败会主动触发重连。
【我的推测】无限重连的几种可能成因
以下没有实测,是推理:
- 落盘失败 → 断线重连 → 还是失败 → 再重连:如果根因(比如磁盘满)没解决,就会形成闭环。这大概是最常见的"无限重连"。
- App Secret 过期或被重置:重连需要重新认证,认证失败就会持续重连。
- 多实例抢同一个 App ID:如果 gateway 起了两份,两个连接会互相挤掉。
二、排查命令(这些是真能用的)
【实测命令】先确认飞书通道的真实状态
openclaw channels list --all
装好之后我本机跑出来的是:
- Feishu default: installed, configured, enabled
这是第一步,但远远不够。 第四节我会证明:这三个词全绿的时候,飞书其实还是坏的。很多"掉线"其实是压根没连上——而这三条绿字会让你以为连上了。
【实测命令】看通道自己的日志
openclaw channels logs --channel feishu
我核实过这个子命令存在,--channel 的可选值里包含 feishu。
【实测命令】实时监控
openclaw logs --follow
官方文档的 Troubleshooting 里也是这么写的。
【实测命令】确认 gateway 活着
openclaw gateway status
openclaw gateway restart
改完配置后必须 restart,官方 Quick start 里明确要求。
【实测命令】死信队列(我真实用过的关键命令)
openclaw channels dead-letters list
这条是我自己踩坑时用出来的,下面第四节会详细讲。
三、官方给的排查清单(原文翻译)
文档 channels/feishu.md 的 Troubleshooting 章节,"Bot does not receive messages" 给了 7 步:
- 确认机器人在飞书开放平台 已发布且审批通过
- 确认事件订阅里包含
im.message.receive_v1 - (如果要自动入会)还要订阅
vc.bot.meeting_invited_v1 - 确认选的是 persistent connection(WebSocket)
- 确认所有需要的权限 scope 都已授予
- 确认 gateway 在跑:
openclaw gateway status - 看日志:
openclaw logs --follow
第 1 步和第 5 步最容易被忽略:机器人在开放平台上"没发布"或"少勾一个权限",表现就跟掉线一模一样——连上了但收不到消息。
四、【实测】装好 ≠ 能用:我抓到的真实失败根因
这一节是 2026-09-08 的第一手记录。
4.1 装插件:先被 capability consent 拦了一次
$ openclaw plugins install @openclaw/feishu
Resolved @openclaw/feishu to @openclaw/feishu@2026.9.2, but that version is
incompatible with this OpenClaw runtime; using newest compatible @openclaw/feishu@2026.8.2.
[openclaw] Reason: Plugin "feishu" requires capability consent.
Use openclaw plugins install or openclaw plugins enable with --accept-capabilities, then retry.
两个坑,都是真的:
- 版本会被自动降级:我装的是 2026.9.2,但本机 runtime 是 2026.8.2,CLI 自动回退到兼容版。如果你在文档里看到的配置项在我这儿没有,先查版本。
- 必须显式
--accept-capabilities,否则装不上:
openclaw plugins install @openclaw/feishu --accept-capabilities
# → Installed plugin: feishu
# → Restart the gateway to load plugins.
4.2 配置:写进 openclaw.json
官方支持的配置结构(来自 docs/channels/feishu.md):
{
"channels": {
"feishu": {
"enabled": true,
"connectionMode": "websocket",
"accounts": {
"default": {
"appId": "cli_xxx",
"appSecret": "xxx"
}
}
}
}
}
安全提醒:别把 App Secret 直接贴在命令行里(会进 shell history 和进程列表)。我用的是「凭据放文件 → Python 读文件写 JSON」的方式,全程不打印、不进命令行。
4.3 最迷惑人的现象:enabled 是绿的,但根本没连上
装完重启后,一切看起来都正常:
$ openclaw channels list --all
- Feishu default: installed, configured, enabled ← 绿的
$ openclaw channels logs --channel feishu
No matching log lines. ← 也"没问题"
如果你只看这两条,你会以为成了。 但真实日志是这样的:
11:00:16 starting feishu[default] (mode: websocket)
11:00:17 feishu[default]: bot open_id resolved: unknown
11:00:17 feishu[default]: bot open_id unknown; starting background provider refresh
(delays: 60s, 120s, 300s, 600s, 900s)
11:00:17 feishu[default]: requireMention group messages stay gated
until bot identity recovery succeeds
11:00:17 feishu[default]: starting WebSocket connection...
11:00:17 feishu[default]: WebSocket client started ← 看着像成功了
11:01:17 feishu[default]: bot identity background retry 1/5 failed; next attempt in 120s
11:03:18 feishu[default]: bot identity background retry 2/5 failed; next attempt in 300s
11:08:18 feishu[default]: bot identity background retry 3/5 failed; next attempt in 600s
三个关键信号:
bot open_id resolved: unknown—— 机器人身份没解析出来。这是病根。WebSocket client started是假绿灯 —— 它只说明客户端起来了,不代表握手和鉴权成功。- 退避重试
60s → 120s → 300s → 600s → 900s—— 官方写死了 5 次,间隔递增。所以这个故障不是"疯狂重连",而是"越来越慢地重试,直到彻底放弃"。这跟很多人想象的"无限重连刷屏"不一样。
4.4 根因定位:凭据是好的,但应用没开通机器人能力
我分两步验证。第一步,直接用凭据换 token:
POST https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal
{"app_id": "...", "app_secret": "..."}
→ HTTP OK | code = 0 | msg = ok
→ tenant_access_token 获取: 成功
凭据完全有效(code = 0)。所以不是「App ID / Secret 填错了」——这是最容易被误判的方向。
第二步,拿 token 去查机器人身份:
GET https://open.feishu.cn/open-apis/bot/v3/info
Authorization: Bearer <token>
→ code = 11205 | msg = app do not have bot
根因就是这个 11205:这个企业自建应用没有开通「机器人」能力。
对应关系非常清晰:
| 日志现象 | 真实原因 |
|---|---|
bot open_id resolved: unknown |
bot/v3/info 返回 11205,拿不到 open_id |
requireMention ... stay gated |
身份未知,群消息触发门控被挂起 |
WebSocket client started 但收不到消息 |
连接建了,但 bot 身份没绑上去 |
4.5 修复动作(在飞书开放平台后台做)
- 进入「开发者后台」→ 你的企业自建应用 → 「添加应用能力」→ 添加「机器人」
- 「事件与回调」→ 订阅方式选 「使用长连接接收事件/回调」(WebSocket 模式必须选这个;选了 webhook 的话 WebSocket 收不到事件)
- 「权限管理」至少开通:
im:message、im:message.group_at_msg、im:chat(按需) - 「版本管理与发布」→ 创建版本并发布。
这一步最容易漏:未发布的应用,能力配了也不生效——
code = 0能换到 token,但bot/v3/info照样 11205。 - 回来重启:
openclaw gateway restart,再盯日志确认不再出现open_id resolved: unknown
4.6 一个 3 分钟自检脚本(不用等 15 分钟重试)
官方退避是 60/120/300/600/900 秒,等它自己重试完要 25 分钟。用这个直接验:
import json, urllib.request
def probe(app_id, app_secret):
req = urllib.request.Request(
"https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal",
data=json.dumps({"app_id": app_id, "app_secret": app_secret}).encode(),
headers={"Content-Type": "application/json; charset=utf-8"})
r = json.loads(urllib.request.urlopen(req, timeout=20).read())
if not r.get("tenant_access_token"):
return "❌ 凭据无效: code=%s msg=%s" % (r.get("code"), r.get("msg"))
req2 = urllib.request.Request(
"https://open.feishu.cn/open-apis/bot/v3/info",
headers={"Authorization": "Bearer " + r["tenant_access_token"]})
b = json.loads(urllib.request.urlopen(req2, timeout=20).read())
if b.get("code") == 0:
return "✅ 机器人能力正常: %s" % b["bot"].get("app_name")
return "❌ code=%s msg=%s" % (b.get("code"), b.get("msg"))
判据:
- 输出
❌ code=11205 msg=app do not have bot→ 没开通机器人能力,去 4.5 第 1 步 - 输出
❌ 凭据无效→ App ID / Secret 错了 - 输出
✅→ 应用侧没问题,那要回头查网络和落盘(回到第三节)
4.7 【实测】修复后复测:同一个日志,两种颜色
按 4.5 在飞书后台做完四步(加机器人能力 → 订阅方式选长连接 → 开权限 → 发布版本),openclaw gateway restart 之后日志变成这样:
11:29:00 feishu[default]: bot open_id resolved: ou_74fedd24625755917bb6a1381eb953e3
11:29:00 feishu[default]: starting WebSocket connection...
11:29:00 feishu[default]: WebSocket client started
前后只有一行之差,但那是全部:
| 修复前 | 修复后 | |
|---|---|---|
bot open_id resolved |
unknown |
ou_74fedd... |
| 后续重试 | retry 1/5 → 4/5 连续失败 | 一次都没有 |
requireMention ... stay gated |
出现 | 消失 |
注意 WebSocket client started 这两次都出现了——它从来就不是判据。
真正的判据只有 bot open_id resolved 这一行。
4.8 顺带踩到的另一个坑:权限不是一次开完的
我想列一下机器人已加入的会话(用于主动发消息),结果:
GET /open-apis/im/v1/chats
→ code=99991672 Access denied.
One of the following scopes is required:
[im:chat:readonly, im:chat, im:chat.group_info:readonly, im:chat:read]
这说明一件事:飞书权限是按接口逐个校验的,不是「开了机器人」就全通。机器人能力只保证 bot 身份能解析(bot/v3/info 通),读写会话还要单独开 im:chat 系列权限。
所以对 4.5 第 3 步的理解要修正:权限不是勾一次就完事,用到哪个接口就要开哪个权限。报错信息很贴心,会直接告诉你缺哪个 scope,照着加即可。
4.9 【实测】端到端跑通:还有最后一道门叫 pairing
身份通了之后我让人给机器人发了条消息,日志终于动了:
11:42:39 feishu[default]: received message from ou_2e6705... in oc_fcc0c39e... (p2p)
11:42:39 feishu[default]: pairing request sender=ou_2e6705fec390f61d101a908ce8b20f13
收到了,但没回。 因为撞上了第三道门:dmPolicy 默认是 pairing。
官方文档(docs/channels/feishu.md)的取值表:
| 值 | 行为 |
|---|---|
"pairing"(默认) |
陌生人拿到配对码,需 CLI 批准 |
"allowlist" |
只有 allowFrom 里的人能聊 |
"open" |
公开 DM,但配置校验要求 allowFrom 含 "*" |
批准就一条命令:
$ openclaw pairing list feishu
Pairing requests (1)
│ Code │ userId │ Requested │
│ G96Q24ZT │ ou_2e6705fec390f61d101a908ce8b20f13 │ 2026-09-08T03:42:39.432Z │
$ openclaw pairing approve feishu G96Q24ZT
Approved feishu sender ou_2e6705fec390f61d101a908ce8b20f13.
然后主动发消息(chat_id 就从上面那条 in oc_... 拿):
$ openclaw message send --channel feishu \
--target "oc_fcc0c39eb63f11c9b3c0bfd08c4bd2a3" \
--message "OpenClaw 飞书通道端到端测试"
✅ Sent via feishu. Message ID: om_x100b66cc090454b0b2748cdeb8b3e66
端到端通了:收 → 配对 → 发,全链路走完。
4.10 完整排查链:三道门,一道都不能少
回头看,飞书从「装好」到「真能收发」一共三道门,每道门的表象都是"看起来正常":
| # | 门 | 表象(假绿灯) | 真实判据 |
|---|---|---|---|
| 1 | 机器人能力未开 | channels list 显示 enabled |
日志 bot open_id resolved 为 unknown / API 11205 |
| 2 | 未订阅 im.message.receive_v1 |
WebSocket client started |
发消息后日志完全没有 received message |
| 3 | dmPolicy: pairing 未批准 |
消息能收到(日志有 received message) |
不回复,需 pairing approve |
第 2 道门最阴:WebSocket 连着、身份正常、一切绿灯,但消息就是进不来。官方文档把它写在「Bot does not receive messages」排查清单第 2 条:
- Ensure event subscription includes
im.message.receive_v1
"订阅方式"和"订阅哪些事件"是两件事——选了「长连接」只是前者,不加 im.message.receive_v1 就没有后者。
4.11 一条命令定位你在第几道门
openclaw channels logs --channel feishu
- 看到
open_id resolved: unknown→ 第 1 道,去开机器人能力 open_id正常,但发消息后没有received message→ 第 2 道,去加im.message.receive_v1- 有
received message但机器人不回 → 第 3 道,openclaw pairing list feishu批准
五、我真实踩过的同类坑:微信通道 delivered:false
飞书现在是装上了,但我在微信通道上遇到的几乎是同构的故障,排查经验可以直接迁移。
真实故障现象
某天早上,我 4 个定时任务(内容工厂、养虾日报、项目日报、灵感雷达)全部显示:
status: ok ← 任务本身跑成功了
delivered: false ← 但消息没发出去
Last heartbeat failed
这个"ok + 没送到"的组合是最迷惑人的:任务层面一切正常,你不去专门看 delivered 字段根本发现不了。
真实排查过程
我用的就是这条命令:
openclaw channels dead-letters list
dead-letters(死信队列)是 OpenClaw 里专门存放"投递失败"消息的地方。发不出去的消息不会凭空消失,会进这里。
真实结论
排查下来是通道登录态失效——凭据是 2026-08-20 存的老 token,过期了。任务照常跑(所以 status: ok),但推送环节静默失败(所以 delivered: false)。
迁移到飞书的经验
虽然通道不同,但故障模式是通用的:
| 现象 | 微信通道(我实测) | 飞书(推测,未验证) |
|---|---|---|
| 任务成功但消息没到 | delivered: false |
可能表现为重连 |
| 排查入口 | dead-letters list |
dead-letters list 同样可用 |
| 常见根因 | 登录态/token 失效 | App Secret 失效、权限不足 |
最实用的一条经验:不要只看"任务成功",要看"送达成功"。这两个是分开的字段,前者 ok 不代表后者 ok。
六、如果 WebSocket 实在不稳:切 webhook(官方支持)
【官方原文】真实配置项
文档配置参考表里明确有:
| 配置项 | 说明 | 默认值 |
|---|---|---|
channels.feishu.connectionMode |
Event transport(websocket 或 webhook) |
websocket |
channels.feishu.verificationToken |
webhook 模式必填 | - |
channels.feishu.encryptKey |
webhook 模式必填 | - |
channels.feishu.webhookPath |
回调路径,必须以 / 开头 |
/feishu/events |
channels.feishu.webhookHost |
监听地址 | 127.0.0.1 |
channels.feishu.webhookPort |
监听端口 | 3000 |
切换配置(结构来自官方文档)
{
channels: {
feishu: {
connectionMode: "webhook",
verificationToken: "你的 verification token",
encryptKey: "你的 encrypt key",
webhookPath: "/feishu/events",
webhookHost: "127.0.0.1",
webhookPort: 3000,
},
},
}
代价要说清楚:webhook 模式需要公网可达的回调地址(要配反代、要 HTTPS),比 WebSocket 麻烦得多。官方默认选 WebSocket 就是因为它不用公网 URL。
所以我的建议是:先按第四节的思路查根因(尤其是落盘失败),不要一遇到问题就切 webhook——那是用一个更麻烦的方案掩盖一个可能很简单的问题。
七、成本与效果:实测数据
初稿这里写的是「飞书没跑起来,我不编」。现在全链路跑通了,补真实数据。
已验证的事实
- 插件包名:
@openclaw/feishu,社区维护(by @m1heng) - 版本回退:请求 2026.9.2,runtime 2026.8.2 → 自动装回 2026.8.2
- 最低版本要求:OpenClaw 2026.5.29+(本机 2026.8.2 满足)
- 官方状态标注:production-ready for bot DMs + group chats
- 安装必须带
--accept-capabilities,否则被拦
实测时间成本(2026-09-08)
| 步骤 | 耗时 | 说明 |
|---|---|---|
| 装插件(含踩 consent 坑) | ~2 分钟 | 第一次没带参数失败 |
| 写配置 + 重启 gateway | ~2 分钟 | 重启要等正在跑的任务,会被 defer |
看日志定位到 open_id: unknown |
~1 分钟 | 关键:别看 list,要看日志 |
写脚本验到 code=11205 |
~3 分钟 | 比等官方退避重试快得多 |
| 合计定位根因 | 约 8 分钟 | 如果不走弯路的话 |
如果按官方退避重试慢慢等:60+120+300+600+900 = 1980 秒 = 33 分钟,而且最后也只是告诉你"失败了",不告诉你为什么。
这就是本文最实在的一句:channels list 的绿灯值 0 分钟,channels logs 的 open_id: unknown 值 8 分钟,你选哪个。
最终状态:全链路跑通(2026-09-08 11:44)
| 环节 | 状态 | 证据 |
|---|---|---|
| 插件安装 + gateway 加载 | ✅ | 16 plugins: ... feishu ... |
| 凭据有效 | ✅ | tenant_access_token code=0 |
| bot 身份解析 | ✅ | open_id resolved: ou_74fedd...、activate_status=2 |
| WebSocket 建连 | ✅ | WebSocket client started,重试失败 0 次 |
| 收到消息 | ✅ | received message from ou_2e6705... in oc_fcc0c39e... (p2p) |
| 发出消息 | ✅ | Sent via feishu. Message ID: om_x100b66cc... |
从装上到收发跑通,全程约 45 分钟,其中真正卡住的三道门(机器人能力 / 事件订阅 / pairing 批准)各花 5–10 分钟,排查本身只占 8 分钟,其余是等后台配置生效和发版。
八、这就是"智能体互联"的早期形态
按本站一贯的锚点:让 AI 接进飞书、接进微信、接进 Telegram,本质上是把智能体接进人所在的协作网络。它现在还只是一个个孤立的通道——但多个智能体跨通道分工协作、互相调用,正是"智能体网络"要解决的问题。
今天你配一个飞书机器人,就是在给那张网络接上第一个节点。
这篇从「排查手册」一路升级成了战报:从 11205 根因、到三道门、到 Sent via feishu 的真实 Message ID,每一步都有日志和命令可查。如果你也卡在飞书通道,直接跳到 4.11——一条命令就能定位你在第几道门。
这类"真实机制拆解 + 可复用排查路径"的内容我会持续写,不想错过可以扫文末二维码关注公众号。
本文官方文档引用均来自本机 OpenClaw 2026.8.2 自带文档 docs/channels/feishu.md,可自行查验;微信通道 delivered:false 故障为本机真实记录。飞书部分未实测,文中已逐节标注证据等级。
