返回全部 Skills

lark-event

开发工具 官方认证

Lark/飞书 实时事件监听 / 订阅 / 消费:通过 `lark-cli event consume <EventKey>` 以 NDJSON 格式流式输出事件(涵盖 IM 消息/反应/聊天变更、VC 会议结束、Minutes 纪要生成等)。适用于 Lark 机器人、实时消息处理、长期运行的订阅者、流式 Webhook/Push 处理器。支持 `--max-events` / `--timeout` 限定运行时长,并包含 stderr 就绪标记约定——专为作为子进程运行的 AI 代理设计。

103.3k

下载量

AI SkillHub 能力展示图

安装方式

命令行安装

在项目根目录执行以下命令,完成 Skill 安装。

npx bzskills add larksuite/cli --skill lark-event

skill.md

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 事件

前置条件: 先阅读 ../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 时长后退出(例如 30s2m)。默认 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

调用流程

  1. lark-cli event list --json → 选择一个合法的键
  2. lark-cli event schema <key> --json → 读取 resolved_output_schema + jq_root_path 以确定字段路径
  3. lark-cli event consume <key> [--jq '<expr>'] → 开始消费

子进程契约

就绪标记

event consume 的 stderr 会输出一行固定文本 [event] ready event_key=<key>父进程应阻塞等待 stderr 出现该行后,再开始读取 stdout。 不要使用 sleep 回退方案。

stdin EOF = 优雅退出

event consume 将 stdin 关闭视为关闭信号(专为 AI 子进程调用方设计)。< /dev/null / nohup / systemd 默认的 StandardInput=null 会导致立即优雅退出(stderr 输出 reason: signal)。要保持运行:

  • 喂给 stdin 一个不会 EOF 的源:< <(tail -f /dev/null)
  • 或者使用有界运行:--max-events N / --timeout D

退出码及原因

退出时,最后一行 stderr 会输出 [event] exited — received N event(s) in Xs (reason: ...)

退出码原因触发条件
0reason: limit达到 --max-events
0reason: timeout达到 --timeout
0reason: signalCtrl+C / SIGTERM / stdin EOF
非0Error: ...(无 exited 行)启动/运行时失败(权限、网络、参数、配置)

编排器应将 reason: limit/timeout/signal(均退出码 0)视为"业务完成",而非零视为"失败"。

切勿使用 kill -9

避免对消费进程使用 kill -9:对于具有 PreConsume 钩子(通过 OAPI 注册服务端订阅)的 EventKey,kill -9 会跳过 OAPI 取消订阅,导致服务端订阅泄漏(症状:重启时提示"订阅已存在"、重复事件投递)。首选 SIGTERM 或关闭 stdin。

一个消费进程对应一个 EventKey(多键 = 多 shell)

该命令只接受一个位置参数;不支持 k1,k2 和通配符。监听 N 个键需要 N 个子进程——这是有意为之

  • 每个进程 stdout 输出单一形状;AI 不需要实现调度逻辑
  • 故障隔离(一个键失败不影响其他键)
  • 每个键可独立设置 --as / --jq / --max-events / --timeout

所有 N 个消费者共享同一个总线守护进程(UDS 本地 IPC),因此开销很小。

通过 schema 编写 jq

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;.contentinteractive 卡片外均为纯文本)+ 常用 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_v1vc.note.generated_v1)+ 字段参考 + source type 语义(仅会议)
会议纪要[references/lark-event-minutes.md](references/lark-event-minutes.md)1 个会议纪要 EventKey 的目录(minutes.minute.generated_v1)+ 字段参考 + source type 语义(仅会议)