mcpField
L
lark-event

lark-event

larksuite设计与 UI17.9k469.2k 次安装今天更新
代码仓库

关于 lark-event

lark-event 是 Lark CLI 中的 skill,用于订阅飞书事件并以 NDJSON 形式输出到标准输出,供 AI 代理或脚本消费。它提供事件目录查询、字段结构查看和本地事件总线的状态管理。

主要功能

  1. 01事件目录与字段结构查询
  2. 02阻塞式消费事件并输出 NDJSON
  3. 03支持 --jq 过滤与转换事件
  4. 04支持按最大事件数或超时结束运行
  5. 05结构化退出码与 reason 标记

适用场景

  1. 01AI 代理实时接收飞书消息事件
  2. 02脚本按事件数量或时长采集飞书事件
  3. 03用 jq 表达式筛选特定群聊或发送者的消息

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/larksuite/cli --skill lark-event

安装后在 Claude Code 中输入/lark-event确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
lark-event-application.md
lark-event-approval.md
lark-event-im.md
lark-event-minutes.md
lark-event-task.md
lark-event-vc.md
lark-event-whiteboard.md

详细介绍

飞书事件

**前提条件:**请先阅读 ../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)

示例

# Default: stream every event for the key (no filter, no projection)
lark-cli event consume im.message.receive_v1 --as bot

# List every EventKey of one domain (the authoritative, always-current catalog)
lark-cli event list --domain vc --json

# Grab one sample event to inspect payload shape
lark-cli event consume im.message.receive_v1 --max-events 1 --timeout 30s --as bot

# Run for 10 minutes then auto-exit
lark-cli event consume im.message.receive_v1 --timeout 10m --as bot

# Consume multiple EventKeys concurrently (one shape per process, no dispatcher)
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 → 选择有效的键。--domain <d> 可将范围缩小到一个域;可选域为 application、approval、board、card、im、minutes、task、vc。未知域会导致失败,并在提示中列出有效域。
  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 子进程调用方接入)。**有界运行不受此规则影响:设置 --max-events 或 --timeout(> 0)时,会忽略 stdin EOF,且仅在达到自身限制、超时或收到 SIGTERM 时退出。**对于无界运行,< /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(stdin EOF 仅适用于无上限运行)
1stderr 上的 JSON 错误封装消费前设置期间 Lark API 业务失败(例如创建/删除订阅)
2stderr 上的 JSON 错误封装(无 exited 行)验证失败(未知 EventKey、无效的 --param / --jq、已有其他总线连接)
3stderr 上的 JSON 错误封装身份验证失败(缺少令牌、缺少权限范围)
4 / 5stderr 上的 JSON 错误封装网络/内部故障(总线启动、握手、文件 I/O)

启动和运行时故障会在 stderr 上输出结构化 JSON 封装:{"ok":false,"error":{"type","subtype","param","message","hint",...}}(封装也可能包含顶层的 identity / _notice 同级字段)。使用 error.type / error.subtype 进行分支处理(例如,missing_scope 会携带 missing_scopes 列表),通过 error.param 查找有问题的标志,并根据 error.hint 执行恢复操作——不要使用正则表达式匹配消息文本。

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

切勿使用 kill -9

对于 PreConsume 会注册服务端订阅、且在退出时会取消订阅的 EventKey(minutes、vc、board 键),避免对消费进程使用 kill -9:kill -9 会跳过 OAPI 取消订阅,导致服务端订阅泄漏(表现为重启时出现“subscription already exists”、重复投递事件)。订阅是持久关系且无需清理的键(task、approval 键)不会因此泄漏,但对所有键而言,使用 SIGTERM 或关闭 stdin 仍是正确的关闭方式。

一次消费一个 EventKey(多个键 = 多个 Shell)

该命令只接受一个位置参数;不支持 k1,k2 和通配符。监听 N 个键意味着运行 N 个子进程——这是有意设计:

  • 每个进程的 stdout 只有一种结构;AI 无需实现分发逻辑
  • 故障隔离(一个键失败不会影响其他键)
  • 每个键的 --as / --jq / --max-events / --timeout 都可以独立设置

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

根据架构编写 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":"Chat ID, prefixed with oc_"},
  "sender_id":   {"type":"string", "format":"open_id",      "description":"Sender open_id, prefixed with ou_"},
  "create_time": {"type":"string", "format":"timestamp_ms", "description":"Send time as ms-epoch string"}
}

(3) 字段语义 — 查看 format 标签

由 Lark 定义的语义标签(不是 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 对每个事件都报错并静默丢弃该事件——消费者看似仍在运行,却不输出任何内容,stderr 中只埋着一行 WARN。(这是通用行为:任何 jq 运行时错误都会跳过该事件并输出一行 WARN;循环不会中止。)

不要跳过架构检查:使用 jq 投影 event schema --json 时,不要从 properties 中剥除 .description ——该字段会告诉你某个字段是否已解码。请输出完整的属性对象,而不仅仅是键。


补充:--param 的有效参数也在架构中——params 部分列出了 name / type / required / enum / default / description;缺少该部分 = 此 key 不接受任何 --param。

主题索引

主题参考覆盖范围
应用references/lark-event-application.mdApplication EventKey 目录,包括用于自定义机器人菜单推送事件的 application.bot.menu_v6 + 扁平化的 event_key / 操作者字段 + jq 示例
审批references/lark-event-approval.md2 个 Approval EventKey(approval.instance.status_changed_v4、approval.task.status_changed_v4)目录 + 可选/多值 subscription_type 预注册 + 用户授权订阅生命周期 + 扁平输出字段参考
IMreferences/lark-event-im.md12 个 IM EventKey 目录 + 结构说明(扁平与 V2 信封格式)+ im.message.receive_v1 字段注意事项(sender_id 仅为 open_id;.content 是纯文本,interactive 卡片除外)+ 常用 jq 示例(按 chat_type / message_type / sender 筛选);对于 card.action.trigger,另请参阅 ../lark-im/references/lark-im-card-action-reply.md
任务references/lark-event-task.md1 个 Task EventKey(task.task.update_user_access_v2)目录 + 原生 V2 信封格式 + 任务提交类型 + 用户/机器人订阅说明
VCreferences/lark-event-vc.md7 个 VC EventKey 目录(会议生命周期 participant_meeting_started/joined/ended_v1、vc.note.generated_v1、录制 recording_started/transcript_generated/ended_v1)+ 字段参考 + 来源类型语义;实时列表始终以 lark-cli event list --domain vc --json 为准
纪要references/lark-event-minutes.md1 个 Minutes EventKey(minutes.minute.generated_v1)目录 + 字段参考 + 来源类型语义(仅限会议)
白板references/lark-event-whiteboard.md1 个 Board EventKey(board.whiteboard.updated_v1)目录 + 按白板订阅的模型(需要 -p whiteboard_id=<token>)+ 负载字段参考(whiteboard_id / operator_ids 三元 ID)

评论

支持 Markdown