前言

在基于 Hermes Agent 开发飞书机器人应用时,交互式卡片是实现人机交互闭环非常核心的能力。通过带按钮的消息卡片,可以实现审批确认、任务触发、事件回调、状态更新等业务场景。

但是原生对接飞书开放平台会踩非常多坑:Token 频繁刷新导致限流、按钮 value JSON转义报错(200671)、回调3秒超时、卡片更新逻辑、权限与事件订阅配置,很多开发者会在这里耗费大量调试时间。

因此我封装了一套生产可用完整飞书交互式卡片 Skill,已经上传到 Gitee & GitHub,Agent 可以直接远程拉取仓库内技能,不用从零编写对接代码。
效果示例

✨ Skill 能力特性

这个 feishu‑interactive‑cards 技能完整覆盖飞书交互式卡片全链路:

  1. 📄 动态构建飞书2.0标准交互式卡片JSON,支持宽屏模式、多主题Header颜色
  2. 🔘 支持单/多按钮、点击确认弹窗,完整处理 card.action.trigger 按钮回调事件
  3. Token缓存预刷新机制:不再每次发送请求都获取token,规避飞书开放平台限流问题
  4. 🔄 支持原地更新已发送卡片,实现状态流转(待处理 → 处理中 → 已完成)
  5. 📋 附带完整错误码故障排查手册、发送校验清单
  6. 🧩 附带可直接运行的Python实现代码,封装好调用方法
  7. 🎯 完整交互闭环:卡片发送 → 用户点击 → 回调接收 → 业务执行 → 卡片状态更新

已验证场景:群聊 chat_id 发送卡片、按钮弹窗确认、客户端Toast反馈、卡片原地更新。

📦 仓库地址

  • Gitee:https://gitee.com/saulCode/lark-skill.git
  • GitHub:https://github.com/bettersoul/hermes-lark-skill-collection.git

仓库目录结构

information/
└── MessageCard/
    └── feishu-interactive-cards  # 消息卡片Skill文件

🚀 使用方法(两种方式)

方式一:AI远程自动拉取(复制整句直接发给你的AI即可,复制即用)

帮我去仓库 https://gitee.com/saulCode/lark-skill.git 读取 information 文件下的 MessageCard 文件夹下的skill,加载消息卡片技能,发一个测试卡片。

如果你用GitHub源,复制这句:
帮我去仓库 https://github.com/bettersoul/hermes-lark-skill-collection.git 读取 information 文件下的 MessageCard 文件夹下的skill,加载消息卡片技能,发一个测试卡片。

Agent 会自动读取远程仓库内的 skill 定义,完成技能加载,直接触发发送测试交互式卡片。

方式二:手动部署

  1. 将仓库克隆到本地,复制 information/MessageCard 下的 skill markdown 文件,放到 Hermes Agent 的技能目录
  2. 修改 Hermes 的飞书配置文件 feishu.yaml,填入你的飞书机器人 app_idapp_secret、默认群聊 chat_id
feishu:
  app_id: "cli_xxxx"
  app_secret: "xxxx"
  default_chat_id: "oc_xxx"
  token_cache_advance: 300
  1. 飞书开放平台关键配置(必须配置,否则按钮点击无响应)
    1. 事件订阅添加事件:card.action.trigger 卡片回传交互
    2. 开启机器人交互式卡片能力开关
    3. 配置回调接收地址(Webhook / WebSocket长连接二选一)

⚠️重要约束:飞书要求回调必须 3秒内返回响应,否则客户端提示交互失败。

  1. 触发测试
  • 自然语言直接对话:发个交互卡片,Agent自动调用技能发送测试卡片
  • 代码调用:使用封装好的 send_interactive_card() 函数,自定义标题、正文、按钮载荷。

💡 核心避坑点(踩过的坑)

  1. 不要每次发送消息都重新获取 Tenant Access Token,要做缓存+提前刷新,高频调用会触发平台限流。
  2. 按钮的 value 字段必须是字符串,不能直接传dict,使用json.dumps()序列化,否则会报 200671 卡片交互异常。
  3. 卡片回调事件 card.action.trigger 必须在飞书平台手动订阅,否则点击按钮没有任何回调。
  4. content 字段传给API的时候,需要整体做JSON字符串序列化,JSON格式错误会报参数错误。

📝 调用示例

resp = send_interactive_card(
    title="🎮 测试交互卡片",
    content="点击下方按钮触发交互逻辑",
    button_text="🔘 点击测试",
    button_action_value={"action": "test_demo", "from": "hermes"},
    chat_id="oc_af5a34fe1fec3c098e0259d96e6cb0XX",
    need_confirm=True,
    confirm_title="确认执行测试?",
    confirm_text="确认后Hermes将在聊天窗口回复消息"
)
msg_id = resp["message_id"] # 拿到message_id,后续用来更新卡片

📚 故障排查清单

错误码

问题

解决方案

99991663

Token过期无效

使用缓存逻辑,强制刷新token

200671

卡片按钮交互报错

button.value 使用json.dumps转为字符串

200340

点击按钮没有回调

平台订阅card.action.trigger事件

99991672

权限不足

授予机器人 im:message 消息发送权限

🎯 交互闭环完整流程

调用send_interactive_card发送卡片 → 获取message_id并存储业务上下文
→ 用户在飞书点击卡片按钮 → 飞书推送card.action.trigger回调
→ 服务3秒内返回响应(Toast提示)
→ Hermes执行业务逻辑
→(可选)PATCH接口原地更新卡片状态

结尾

这个Skill把飞书交互式卡片的底层细节全部封装屏蔽,业务开发只需要关心卡片标题、内容、按钮业务载荷,不用反复对接OpenAPI。
后续会持续迭代,增加更多飞书相关Hermes Skill,欢迎大家Star、Issue反馈问题。


🔗 Gitee仓库:https://gitee.com/saulCode/lark-skill.git
🔗 GitHub仓库:https://github.com/bettersoul/hermes-lark-skill-collection.git


👉直接复制给AI的两条完整提示词

Gitee版本提示词:

帮我去仓库 https://gitee.com/saulCode/lark-skill.git 读取 information 文件下的 MessageCard 文件夹下的skill,加载消息卡片技能,发一个测试卡片。

GitHub版本提示词:

帮我去仓库 https://github.com/bettersoul/hermes-lark-skill-collection.git 读取 information 文件下的 MessageCard 文件夹下的skill,加载消息卡片技能,发一个测试卡片。
Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐