安装方式
命令行安装
在项目根目录执行以下命令,完成 Skill 安装。
npx bzskills add larksuite/cli --skill lark-event Lark/飞书 实时事件监听 / 订阅 / 消费:通过 `lark-cli event consume <EventKey>` 以 NDJSON 格式流式输出事件(涵盖 IM 消息/反应/聊天变更、VC 会议结束、Minutes 纪要生成等)。适用于 Lark 机器人、实时消息处理、长期运行的订阅者、流式 Webhook/Push 处理器。支持 `--max-events` / `--timeout` 限定运行时长,并包含 stderr 就绪标记约定——专为作为子进程运行的 AI 代理设计。
103.3k
下载量
命令行安装
在项目根目录执行以下命令,完成 Skill 安装。
npx bzskills add larksuite/cli --skill lark-event name: lark-event
version: 1.0.0
description: Lark/飞书 实时事件监听 / 订阅 / 消费:通过 `lark-cli event consume <EventKey>` 以 NDJSON 格式流式输出事件(涵盖 IM 消息/反应/聊天变更、VC 会议结束、Minutes 纪要生成等)。适用于 Lark 机器人、实时消息处理、长期运行的订阅者、流式 Webhook/Push 处理器。支持 `--max-events` / `--timeout` 限定运行时长,并包含 stderr 就绪标记约定——专为作为子进程运行的 AI 代理设计。
metadata:
requires:
bins: ["lark-cli"]
cliHelp: "lark-cli event --help"前置条件: 先阅读../lark-shared/SKILL.md了解认证方式、--as user/bot切换、Permission denied处理以及安全规则。
| 命令 | 用途 |
|---|---|
lark-cli event list [--json] | 列出所有可订阅的 EventKey |
lark-cli event schema <EventKey> [--json] | 显示某 EventKey 的参数和输出结构 |
lark-cli event consume <EventKey> [flags] | 阻塞式消费;事件 → stdout NDJSON |
lark-cli event status [--json] [--fail-on-orphan] | 检查本地总线守护进程状态 |
lark-cli event stop [--all] [--force] | 停止总线守护进程 |
| 标志 | 说明 | ||
|---|---|---|---|
--param key=value / -p | 业务参数(可重复;多值用逗号分隔)。未知键会失败,并内联列出有效名称 | ||
--jq <expr> | jq 表达式,用于过滤/转换每个事件;输出为空则跳过该事件 | ||
--max-events N | 收到 N 个事件后退出。默认 0 = 无限制 | ||
--timeout D | 持续 D 时长后退出(例如 30s、2m)。默认 0 = 无超时。--max-events 和 --timeout 谁先触发就生效 | ||
--output-dir <dir> | 将每个事件写入单独文件(仅支持相对路径;防止路径遍历) | ||
--quiet | 抑制 stderr 诊断信息。AI 不应使用此选项——它会抑制就绪标记的输出 | ||
| `--as user\ | bot\ | auto` | 会话身份(参见 lark-shared) |
# 默认:流式接收该键的所有事件(无过滤、无投影)
lark-cli event consume im.message.receive_v1 --as bot
# 抓取一个示例事件以检查载荷形状
lark-cli event consume im.message.receive_v1 --max-events 1 --timeout 30s --as bot
# 运行 10 分钟后自动退出
lark-cli event consume im.message.receive_v1 --timeout 10m --as bot
# 并发消费多个 EventKey(每个进程一个形状,无调度器)
lark-cli event consume im.message.receive_v1 --as bot > receive.ndjson &
lark-cli event consume im.message.reaction.created_v1 --as bot > reaction.ndjson &
wait
lark-cli event list --json → 选择一个合法的键lark-cli event schema <key> --json → 读取 resolved_output_schema + jq_root_path 以确定字段路径lark-cli event consume <key> [--jq '<expr>'] → 开始消费event consume 的 stderr 会输出一行固定文本 [event] ready event_key=<key>。父进程应阻塞等待 stderr 出现该行后,再开始读取 stdout。 不要使用 sleep 回退方案。
event consume 将 stdin 关闭视为关闭信号(专为 AI 子进程调用方设计)。< /dev/null / nohup / systemd 默认的 StandardInput=null 会导致立即优雅退出(stderr 输出 reason: signal)。要保持运行:
< <(tail -f /dev/null)--max-events N / --timeout D退出时,最后一行 stderr 会输出 [event] exited — received N event(s) in Xs (reason: ...)。
| 退出码 | 原因 | 触发条件 |
|---|---|---|
| 0 | reason: limit | 达到 --max-events |
| 0 | reason: timeout | 达到 --timeout |
| 0 | reason: signal | Ctrl+C / SIGTERM / stdin EOF |
| 非0 | Error: ...(无 exited 行) | 启动/运行时失败(权限、网络、参数、配置) |
编排器应将 reason: limit/timeout/signal(均退出码 0)视为"业务完成",而非零视为"失败"。
kill -9避免对消费进程使用 kill -9:对于具有 PreConsume 钩子(通过 OAPI 注册服务端订阅)的 EventKey,kill -9 会跳过 OAPI 取消订阅,导致服务端订阅泄漏(症状:重启时提示"订阅已存在"、重复事件投递)。首选 SIGTERM 或关闭 stdin。
该命令只接受一个位置参数;不支持 k1,k2 和通配符。监听 N 个键需要 N 个子进程——这是有意为之:
--as / --jq / --max-events / --timeout所有 N 个消费者共享同一个总线守护进程(UDS 本地 IPC),因此开销很小。
event schema <key> --json 是编写 --jq 的唯一事实来源。需要关注以下四点:
(1) 字段起始位置——查看 jq_root_path
"." → 字段位于顶层,直接写 .chat_id".event" → 字段位于 V2 信封内部,需写 .event.chat_id(2) 字段列表及类型——查看 resolved_output_schema.properties.<name>
每个字段包含 type / description,部分还有 format。示例片段(来自 event schema im.message.receive_v1 --json):
{
"chat_id": {"type":"string", "format":"chat_id", "description":"会话 ID,前缀为 oc_"},
"sender_id": {"type":"string", "format":"open_id", "description":"发送者 open_id,前缀为 ou_"},
"create_time": {"type":"string", "format":"timestamp_ms", "description":"发送时间,毫秒时间戳字符串"}
}
(3) 字段语义——查看 format 标签
飞书定义的语义标签(不是 JSON Schema 的标准 format)。常见值:open_id / chat_id / message_id / timestamp_ms / email。用途:区分"相同字符串类型但不同含义"的字段,以便通过 API 反向查找或转换格式。
(4) 解码状态——阅读字段的 description
event consume 会运行 Process 钩子,这些钩子可能预先解码某些载荷字段(展平 V2 信封、将 .content 渲染为纯文本等)——行为与原始 OAPI 不同。在编写 jq 之前一定要阅读字段的 description,尤其对于 content / data / body / payload 这类通用字段名。
为什么重要:对已经解码的文本字段盲目使用 fromjson 会导致 jq 在每个事件上出错并静默丢弃事件——消费者看起来仍然存活,但实际没有输出任何内容,仅有一条 WARN 行隐藏在 stderr 中。(这是通用行为:任何 jq 运行时错误都会跳过该事件并输出一行 WARN;循环不会中止。)
不要绕过 schema:当你用 jq 投影 event schema --json 时,不要从 properties 中剥离 .description——正是这个字段告诉你某个字段是否已解码。要转储完整的属性对象,而不仅仅是键名。
---
附注:--param 的有效参数也存在于 schema 中——params 部分列出了 name / type / required / enum / default / description;缺少该部分 = 该键不接受任何 --param。
| 主题 | 参考文档 | 覆盖内容 |
|---|---|---|
| IM | [references/lark-event-im.md](references/lark-event-im.md) | 11 个 IM EventKey 的目录 + 形状说明(扁平 vs V2 信封)+ im.message.receive_v1 字段陷阱(sender_id 仅为 open_id;.content 除 interactive 卡片外均为纯文本)+ 常用 jq 配方(按 chat_type / message_type / sender 过滤) |
| VC | [references/lark-event-vc.md](references/lark-event-vc.md) | 2 个 VC EventKey 的目录(vc.meeting.participant_meeting_ended_v1、vc.note.generated_v1)+ 字段参考 + source type 语义(仅会议) |
| 会议纪要 | [references/lark-event-minutes.md](references/lark-event-minutes.md) | 1 个会议纪要 EventKey 的目录(minutes.minute.generated_v1)+ 字段参考 + source type 语义(仅会议) |