07-实战 · 飞书卡片验证与排障
目标:上线前验证“卡片能发、按钮能点、脚本能执行、失败能解释”。飞书卡片系统最怕只测 happy path。
建议按 10 步走,从离线到线上:
| 步骤 | 验证项 | 失败时先看 |
|---|---|---|
| 1 | Python / Node 脚本语法 | 本地错误栈 |
| 2 | 卡片 JSON 可解析 | json.tool / schema 字段 |
| 3 | 卡片大小未超限 | wc -c |
| 4 | dry-run 能生成 state | ~/.openclaw/temp/cards/ |
| 5 | 飞书 token 能获取 | app_id / app_secret / 权限 |
| 6 | CardKit 创建成功 | create card response |
| 7 | IM 发送成功 | receive_id_type / open_id |
| 8 | callback 能进 gateway | gateway 日志 / 反向代理 |
| 9 | handler 单元测试通过 | action value / 白名单 |
| 10 | 合并与回滚 dry-run 通过 | candidates / backup / audit log |
不要跳过 dry-run。它能帮你在不打扰用户的情况下发现 80% 的问题。
推荐验证命令
Section titled “推荐验证命令”# 1. 脚本语法python3 -m py_compile ~/.openclaw/scripts/sunday-memory-digest.pypython3 -m py_compile ~/.openclaw/scripts/memory-merge-weekly.pynode -c ~/.openclaw/extensions/openclaw-lark/src/tools/generic-card-action.js
# 2. 生成卡片但不发送python3 ~/.openclaw/scripts/sunday-memory-digest.py --dry-run > /tmp/weekly-card.out
# 3. 合并 dry-runpython3 ~/.openclaw/scripts/memory-merge-weekly.py --dry-run --tier high
# 4. 回滚 dry-runpython3 ~/.openclaw/scripts/memory-merge-weekly.py --rollback --dry-run --tier high
# 5. gateway 健康检查openclaw gateway statusopenclaw doctor如果你有自己的 verify-weekly-card.sh,建议把这些步骤固化进去,每次改卡片或 handler 后都跑一遍。
模拟 callback
Section titled “模拟 callback”上线前至少模拟这些 case:
| case | 预期 |
|---|---|
合法 memory-merge-high | accepted |
| 未知 action | rejected: unknown_action |
| 缺少 task_id | rejected: invalid_payload |
| task_id 不存在 | rejected: unknown_task |
| 卡片过期 | rejected: expired_card |
| 非管理员点危险动作 | rejected: permission_denied |
| 脚本执行失败 | failed,并写日志 |
| cancel | accepted,但不改长期记忆 |
让 AI 写测试时,不要只测成功路径。
卡片发不出去
Section titled “卡片发不出去”优先检查:
receive_id_type是否和传入 ID 匹配- bot 是否在目标群里
- 权限是否已发布生效
- tenant token 是否过期
- CardKit 创建接口和 IM 发送接口是不是混用了不同 token
卡片能发,但按钮没反应
Section titled “卡片能发,但按钮没反应”优先检查:
- 飞书开放平台是否配置了卡片交互回调
- gateway 是否外网可达
- 反向代理是否把 POST body 原样转发
openclaw-lark是否启用- 官方
feishu插件是否和openclaw-lark同时启用导致冲突
handler 收到事件,但 action 是空
Section titled “handler 收到事件,但 action 是空”通常是按钮 value 格式不对。检查:
value是否是对象,不是字符串- action 字段是否在
value.action - 卡片生成时是否被模板转义成字符串
- 飞书回调事件里 action 路径是否和你的 handler 代码一致
合并成功,但卡片没有刷新
Section titled “合并成功,但卡片没有刷新”先判断“合并失败”还是“刷新失败”:
- 看长期记忆文件是否真的更新
- 看合并脚本审计日志
- 看 CardKit update 接口响应
- 如果只是刷新失败,应该发送兜底报告卡
子 agent 卡片 footer 缺 model/cache/context
Section titled “子 agent 卡片 footer 缺 model/cache/context”这类问题通常不是飞书应用配置,而是插件读取 session 路径的问题。可先看 飞书深度配置 里的 footer metrics 修复说明。
日志位置建议
Section titled “日志位置建议”~/.openclaw/logs/ gateway.log gateway.err.log card-actions.jsonl weekly-memory-digest.log memory-merge-weekly.log~/.openclaw/temp/cards/ weekly-2026-04-24.state.json weekly-2026-04-24.card.json排障时先看 card-actions.jsonl,确认按钮是否进来;再看脚本日志,确认动作是否执行。
- 所有脚本支持
--dry-run - handler 没有
eval、sh -c、执行用户传入命令 - action 白名单覆盖所有按钮
- 危险动作有二次确认或管理员限制
- 卡片 value 包含
task_id和issued_at - 过期卡片不会执行合并 / 回滚
- 合并前会备份长期记忆
- 回滚 dry-run 能显示将删除 / 恢复的内容
- 失败时会写审计日志
- 卡片刷新失败时有兜底消息
用 AI 辅助排障的 prompt
Section titled “用 AI 辅助排障的 prompt”把日志脱敏后再发给 AI:
这是我的 OpenClaw 飞书卡片排障信息,敏感 token 已脱敏。请按“卡片创建、消息发送、callback、handler、脚本执行、卡片刷新”六段分析。要求:1. 先判断失败发生在哪一段。2. 给出最可能的 3 个原因。3. 给出我下一条应该执行的命令。4. 不要要求我提供 appSecret 或完整 token。AI 很适合帮你归类日志,但不要把密钥、完整 open_id、tenant token 直接贴进去。
如果四篇实战都跑通,你已经具备了用 OpenClaw 做“飞书里的 AI 工作流面板”的基础能力。后续可以把同样模式扩展到日报、客服质检、运营审批、告警确认和知识库维护。