feishu-cli-event

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

飞书实时事件订阅技能(WebSocket)

Feishu Real-time Event Subscription Skill (WebSocket)

通过
feishu-cli event
子命令族订阅飞书开放平台事件,使用 WebSocket 长连接接收事件并以 NDJSON 输出到 stdout,适合 AI Agent 做 bot 实时响应、群消息监听、审批回调消费等场景。
feishu-cli:如尚未安装,请前往 riba2534/feishu-cli 获取安装方式。
发消息? 请使用 feishu-cli-msg 技能。本技能专注于事件订阅(接收应用事件),不负责发送。
Subscribe to Feishu Open Platform events via the
feishu-cli event
subcommand family. Use WebSocket long connections to receive events and output them to stdout in NDJSON format, suitable for scenarios like AI Agent bot real-time response, group message monitoring, approval callback consumption, etc.
feishu-cli: If not installed yet, please visit riba2534/feishu-cli for installation instructions.
Need to send messages? Please use the feishu-cli-msg skill. This skill focuses on event subscription (receiving app events) and does not handle sending.

核心概念

Core Concepts

进程模型 = 1 个 EventKey 1 个 consume 进程

Process Model = One consume process per EventKey

event consume <EventKey>
   ├─ 启动 WebSocket 长连接(飞书 SDK ws.Client + AutoReconnect)
   ├─ 注册到 bus.json(PID / EventKey / 启动时间 / max-events / timeout)
   ├─ stderr 输出 [event] ready event_key=<key>
   ├─ 接收事件 → 写 stdout(NDJSON,每条一行 JSON)
   ├─ 可选:dump 每条事件为 <event_id>.json 文件
   ├─ 退出条件:--max-events / --timeout / SIGTERM / Ctrl-C / stdin EOF / pipe broken
   └─ 退出时自动 unregister bus.json
与 lark-cli event 的差异:lark-cli 用 Unix domain socket 跑独立 bus 守护进程做事件 fan-out;feishu-cli 简化为「每个 consume 直接连一条 WebSocket」,不做事件分发——足够覆盖 AI Agent 单 EventKey 订阅的主线场景。
event consume <EventKey>
   ├─ Starts WebSocket long connection (Feishu SDK ws.Client + AutoReconnect)
   ├─ Registers to bus.json (PID / EventKey / start time / max-events / timeout)
   ├─ Outputs [event] ready event_key=<key> to stderr
   ├─ Receives events → writes to stdout (NDJSON, one JSON per line)
   ├─ Optional: dumps each event as <event_id>.json file
   ├─ Exit conditions: --max-events / --timeout / SIGTERM / Ctrl-C / stdin EOF / pipe broken
   └─ Automatically unregisters from bus.json on exit
Differences from lark-cli event: lark-cli runs an independent bus daemon via Unix domain socket for event fan-out; feishu-cli simplifies it to "each consume connects directly to a WebSocket" without event distribution—this sufficiently covers the main scenario of AI Agent single EventKey subscription.

状态文件与跨进程互斥

Status Files and Cross-Process Mutual Exclusion

路径作用
~/.feishu-cli/events/<app_id>/bus.json
活跃 consumer 列表(PID/EventKey/启动时间/参数)
~/.feishu-cli/events/<app_id>/bus.lock
flock 文件锁;bus.json 读写串行化,fd 关闭自动释放
每个 AppID 一个子目录,不同应用互不干扰。
event status
查询会主动剔除已不存活的 PID 条目(kill -9 / 崩溃残留)。bus.json 用 tmp + rename 原子写,防半写。
PathPurpose
~/.feishu-cli/events/<app_id>/bus.json
List of active consumers (PID/EventKey/start time/parameters)
~/.feishu-cli/events/<app_id>/bus.lock
flock file lock; serializes bus.json read/write, automatically released when fd is closed
One subdirectory per AppID, different applications do not interfere with each other.
event status
will actively remove entries of non-living PIDs (residues from kill -9 / crashes). bus.json uses tmp + rename for atomic writing to prevent partial writes.

输出协议(NDJSON + ready marker)

Output Protocol (NDJSON + ready marker)

内容
stdout每条事件一行 JSON(NDJSON),适合 jq / 脚本管道
stderr诊断日志;启动时一行
[event] ready event_key=<key> (init complete; WS handshake in progress)
AI Agent 推荐:父进程把 consume 跑后台(
run_in_background=true
),先阻塞 stderr 等到
[event] ready
那一行再开始读 stdout。注意:ready marker 只表示进程初始化完成,WS 握手在后台异步执行;父进程见到 marker 后还需额外等 1-3s 让 WS 握手真正完成,生产环境建议父进程发自检事件 + 等 echo 回环来确认链路通。
StreamContent
stdoutOne JSON per event line (NDJSON), suitable for jq / script pipelines
stderrDiagnostic logs; outputs
[event] ready event_key=<key> (init complete; WS handshake in progress)
on startup
AI Agent Recommendation: Run consume in the background with the parent process (
run_in_background=true
), block on stderr until the
[event] ready
line appears before starting to read stdout. Note: The ready marker only indicates process initialization is complete, the WS handshake is executed asynchronously in the background; after seeing the marker, the parent process needs an additional 1-3s wait for the WS handshake to truly complete. In production environments, it is recommended that the parent process sends a self-check event + waits for echo loop to confirm the link is connected.

退出码与退出 reason

Exit Codes and Exit Reasons

退出码含义
0正常退出(达到
--max-events
/
--timeout
/ SIGTERM / Ctrl-C / stdin EOF)
非 0startup 失败 / WebSocket 不可恢复错误 / 参数错误
stderr 末尾会输出
[event] exited — elapsed=<d> reason=<r>
,reason 有 4 个:
  • limit
    — 达到
    --max-events
  • timeout
    — 达到
    --timeout
  • signal
    — 上下文取消(Ctrl-C / SIGTERM / stdin EOF / 下游 pipe broken)
  • error
    — WebSocket 连接持续失败
Exit CodeMeaning
0Normal exit (reached
--max-events
/
--timeout
/ SIGTERM / Ctrl-C / stdin EOF)
Non-0Startup failure / unrecoverable WebSocket error / parameter error
The end of stderr will output
[event] exited — elapsed=<d> reason=<r>
, where there are 4 reasons:
  • limit
    — reached
    --max-events
  • timeout
    — reached
    --timeout
  • signal
    — context canceled (Ctrl-C / SIGTERM / stdin EOF / downstream pipe broken)
  • error
    — continuous WebSocket connection failure

命令速查

Quick Command Reference

bash
feishu-cli event list [--json]                       # 1. 列所有支持的 EventKey
feishu-cli event schema <event_key> [--json]         # 2. 看某 key 的 EventType / scope / payload schema
feishu-cli event consume <event_key> [flags]         # 3. 启动订阅(阻塞)
feishu-cli event status [--json]                     # 4. 看本机活跃 consume 进程
feishu-cli event stop {--pid N | --event-key K | --all} [--force] [--json]  # 5. 停 consume
bash
feishu-cli event list [--json]                       # 1. List all supported EventKeys
feishu-cli event schema <event_key> [--json]         # 2. View EventType / scope / payload schema of a key
feishu-cli event consume <event_key> [flags]         # 3. Start subscription (blocking)
feishu-cli event status [--json]                     # 4. View active local consume processes
feishu-cli event stop {--pid N | --event-key K | --all} [--force] [--json]  # 5. Stop consume

1.
event list
:列出支持的 EventKey

1.
event list
: List supported EventKeys

按 domain 分组展示当前支持的 22+ EventKey(im / contact / calendar / drive / approval / vc)。
bash
undefined
Displays over 22 currently supported EventKeys grouped by domain (im / contact / calendar / drive / approval / vc).
bash
undefined

表格视图(默认)

Table view (default)

feishu-cli event list
feishu-cli event list

JSON 输出,jq 提取 IM 域所有 EventKey

JSON output, extract all IM domain EventKeys with jq

feishu-cli event list --json | jq -r '.[] | select(.domain=="im") | .key'

**输出字段**(JSON 模式):`key` / `event_type` / `description` / `domain` / `scopes[]` / `payload_schema`。
feishu-cli event list --json | jq -r '.[] | select(.domain=="im") | .key'

**Output fields** (JSON mode): `key` / `event_type` / `description` / `domain` / `scopes[]` / `payload_schema`.

2.
event schema
:看 payload schema 与 scope

2.
event schema
: View payload schema and scope

bash
feishu-cli event schema im.message.receive_v1
feishu-cli event schema im.message.receive_v1 --json
输出 4 部分:
Key
/
Event Type
/
Domain
/
Description
/
Scopes
+ 可选
Payload Schema (示例)
。Payload schema 为手工 curated,订阅后实际 payload 以飞书开放平台文档为准。
bash
feishu-cli event schema im.message.receive_v1
feishu-cli event schema im.message.receive_v1 --json
Outputs 4 parts:
Key
/
Event Type
/
Domain
/
Description
/
Scopes
+ optional
Payload Schema (Example)
. The payload schema is manually curated; the actual payload after subscription is subject to Feishu Open Platform documentation.

3.
event consume
:启动 WebSocket 订阅(阻塞)

3.
event consume
: Start WebSocket subscription (blocking)

bash
undefined
bash
undefined

基础订阅,Ctrl-C 退出

Basic subscription, exit with Ctrl-C

feishu-cli event consume im.message.receive_v1
feishu-cli event consume im.message.receive_v1

调试:抓 5 条消息,最多跑 60s

Debug: capture 5 messages, run for maximum 60s

feishu-cli event consume im.message.receive_v1 --max-events 5 --timeout 60s
feishu-cli event consume im.message.receive_v1 --max-events 5 --timeout 60s

落盘 + 静默

Persist to disk + quiet mode

feishu-cli event consume im.message.receive_v1 --output-dir ./events --quiet
feishu-cli event consume im.message.receive_v1 --output-dir ./events --quiet

配合 jq 实时过滤群消息

Real-time filter group messages with jq

feishu-cli event consume im.message.receive_v1 | jq 'select(.event.message.chat_type=="group")'
feishu-cli event consume im.message.receive_v1 | jq 'select(.event.message.chat_type=="group")'

后台并发订阅多个 EventKey(每个 EventKey 一个进程)

Background concurrent subscription to multiple EventKeys (one process per EventKey)

feishu-cli event consume im.message.receive_v1 > receive.ndjson 2> receive.log & feishu-cli event consume im.message.reaction.created_v1 > reaction.ndjson 2> reaction.log & feishu-cli event status

**关键 flag**:

| Flag | 默认 | 说明 |
|---|---|---|
| `--max-events N` | 0(不限制) | 接收 N 条事件后退出,reason=`limit` |
| `--timeout 30s` | 0(不限制) | 运行 D 时长后退出,reason=`timeout` |
| `--jq .event.xxx` | "" | 极简**点路径**过滤,不支持完整 jq 语法(用 pipe 接外部 jq) |
| `--output-dir ./events` | "" | 每条事件额外 dump 为 `<event_id>.json` 落盘(不影响 stdout) |
| `--quiet` | false | 抑制 stderr 诊断;**AI Agent 慎用**——会一起抑制大部分 stderr,但 ready marker 仍走真实 os.Stderr 不受影响 |

**`--jq` 限制**:只识别 `.a.b.c` 形式的 map 取值(如 `.event.message`),不支持 `select` / 数组下标 / 管道。复杂过滤请用 `feishu-cli event consume ... | jq '<expr>'`。

**`--output-dir` 限制**:必须是安全相对路径;不做 `~` 展开,不接受绝对路径或 `..` 路径段。
feishu-cli event consume im.message.receive_v1 > receive.ndjson 2> receive.log & feishu-cli event consume im.message.reaction.created_v1 > reaction.ndjson 2> reaction.log & feishu-cli event status

**Key flags**:

| Flag | Default | Description |
|---|---|---|
| `--max-events N` | 0 (unlimited) | Exit after receiving N events, reason=`limit` |
| `--timeout 30s` | 0 (unlimited) | Exit after running for D duration, reason=`timeout` |
| `--jq .event.xxx` | "" | Minimal **dot-path** filtering, does not support full jq syntax (use pipe with external jq) |
| `--output-dir ./events` | "" | Additionally dump each event as `<event_id>.json` to disk (does not affect stdout) |
| `--quiet` | false | Suppress stderr diagnostics; **use with caution for AI Agent**—most stderr will be suppressed, but the ready marker still uses real os.Stderr and is not affected |

**`--jq` Limitations**: Only recognizes map values in the form of `.a.b.c` (e.g., `.event.message`), does not support `select` / array subscripts / pipes. For complex filtering, use `feishu-cli event consume ... | jq '<expr>'`.

**`--output-dir` Limitations**: Must be a safe relative path; does not expand `~`, does not accept absolute paths or `..` path segments.

4.
event status
:看本机活跃 consume 进程

4.
event status
: View active local consume processes

bash
feishu-cli event status
feishu-cli event status --json | jq '.consumers[] | .pid'
输出:
App ID
/
State file
路径 /
PID
/
EVENT_KEY
/
UPTIME
/
EXTRA
(max-events / timeout / output-dir / jq)。
查询时会主动剔除已不存活的 PID 条目(清理 kill -9 / 崩溃残留的僵尸记录)。
bash
feishu-cli event status
feishu-cli event status --json | jq '.consumers[] | .pid'
Outputs:
App ID
/
State file
path /
PID
/
EVENT_KEY
/
UPTIME
/
EXTRA
(max-events / timeout / output-dir / jq).
During query, entries of non-living PIDs will be actively removed (cleaning up zombie records from kill -9 / crashes).

5.
event stop
:停止 consume 进程

5.
event stop
: Terminate consume processes

bash
feishu-cli event stop --pid 12345                          # 按 PID
feishu-cli event stop --event-key im.message.receive_v1    # 按 EventKey(所有订阅该 key 的进程)
feishu-cli event stop --all                                # 当前 AppID 下全部 consume
feishu-cli event stop --all --force                        # SIGKILL(紧急情况)
默认 SIGTERM 优雅退出(consume 进程会自动 unregister bus.json),等最多 3s 验证进程已退出;
--force
升级为 SIGKILL,会留下 bus.json 僵尸条目,下次
event status
会自动清理。
bash
feishu-cli event stop --pid 12345                          # By PID
feishu-cli event stop --event-key im.message.receive_v1    # By EventKey (all processes subscribing to this key)
feishu-cli event stop --all                                # All consume processes under current AppID
feishu-cli event stop --all --force                        # SIGKILL (emergency situation)
Default uses SIGTERM for graceful exit (consume process will automatically unregister from bus.json), waits up to 3s to verify the process has exited;
--force
upgrades to SIGKILL, which will leave zombie entries in bus.json, and the next
event status
will automatically clean them up.

EventKey 速查(按 domain 分组)

EventKey Quick Reference (Grouped by Domain)

完整列表用
feishu-cli event list
。常用:
DomainEventKey描述
im
im.message.receive_v1
接收消息(用户/群聊发给 Bot)
im
im.message.message_read_v1
消息已读回执
im
im.message.recalled_v1
消息被撤回
im
im.message.reaction.created_v1
/
deleted_v1
消息表情回复添加/删除
im
im.chat.updated_v1
群聊信息更新
im
im.chat.member.user.added_v1
/
deleted_v1
用户进群/离群
im
im.chat.member.bot.added_v1
/
deleted_v1
Bot 被拉入/移出群
im
im.chat.disbanded_v1
群聊被解散
contact
contact.user.created_v3
/
updated_v3
/
deleted_v3
员工入职/变更/离职
calendar
calendar.calendar.event.changed_v4
日程变更(创建/更新/删除)
calendar
calendar.calendar.acl.created_v4
日历权限变更
drive
drive.file.title_updated_v1
文档标题修改
drive
drive.file.permission_member_added_v1
文档协作者添加
approval
approval_instance
审批实例状态变更
approval
approval_task
审批任务变更
vc
vc.meeting.meeting_started_v1
/
meeting_ended_v1
VC 会议开始/结束
EventKey 与 EventType 通常一致;接收到的 payload 里
header.event_type
等于
event_type
字段。
Use
feishu-cli event list
for the complete list. Common ones:
DomainEventKeyDescription
im
im.message.receive_v1
Receive messages (sent to Bot by user/group chat)
im
im.message.message_read_v1
Message read receipt
im
im.message.recalled_v1
Message recalled
im
im.message.reaction.created_v1
/
deleted_v1
Message reaction added/deleted
im
im.chat.updated_v1
Group chat information updated
im
im.chat.member.user.added_v1
/
deleted_v1
User joined/left group
im
im.chat.member.bot.added_v1
/
deleted_v1
Bot added/removed from group
im
im.chat.disbanded_v1
Group chat disbanded
contact
contact.user.created_v3
/
updated_v3
/
deleted_v3
Employee hired/changed/left
calendar
calendar.calendar.event.changed_v4
Calendar event changed (created/updated/deleted)
calendar
calendar.calendar.acl.created_v4
Calendar permission changed
drive
drive.file.title_updated_v1
Document title modified
drive
drive.file.permission_member_added_v1
Document collaborator added
approval
approval_instance
Approval instance status changed
approval
approval_task
Approval task changed
vc
vc.meeting.meeting_started_v1
/
meeting_ended_v1
VC meeting started/ended
EventKey and EventType are usually consistent; the
header.event_type
in the received payload equals the
event_type
field.

权限与开放平台配置

Permissions and Open Platform Configuration

默认 App Token,无需
auth login

Default App Token, no
auth login
required

事件订阅走 App 身份(app_id + app_secret),不强制 user token。配好
~/.feishu-cli/config.yaml
FEISHU_APP_ID
/
FEISHU_APP_SECRET
环境变量即可。
Event subscription uses App identity (app_id + app_secret), user token is not mandatory. Just configure
~/.feishu-cli/config.yaml
or set the
FEISHU_APP_ID
/
FEISHU_APP_SECRET
environment variables.

飞书开放平台两步配置

Two-step Configuration on Feishu Open Platform

open.feishu.cn 你的应用控制台:
  1. 「事件订阅 - 长连接接收事件」 开启长连接模式(feishu-cli 走 WebSocket,不是 webhook URL 模式)
  2. 「事件与回调 - 事件订阅」 选中目标 EventType(与
    event schema <key>
    输出的 Event Type 一致)并发布版本
  3. scope 开通:每个 EventKey 需要的 scope 见
    event schema <key>
    Scopes
    字段;在「权限管理」页面开通。
    event
    域已加入
    --domain event --recommend
    推荐列表,可一次性申请 IM/contact/calendar/drive/approval/vc 常用 scope 并集
In your application console at open.feishu.cn:
  1. 「Event Subscription - Receive Events via Long Connection」 Enable long connection mode (feishu-cli uses WebSocket, not webhook URL mode)
  2. 「Events and Callbacks - Event Subscription」 Select the target EventType (consistent with the Event Type output by
    event schema <key>
    ) and publish the version
  3. Scope activation: The scopes required for each EventKey can be found in the
    Scopes
    field of
    event schema <key>
    ; activate them on the "Permission Management" page. The
    event
    domain has been added to the
    --domain event --recommend
    recommendation list, allowing one-click application for the union of common scopes for IM/contact/calendar/drive/approval/vc

常见错误

Common Errors

现象原因解决
WS 连接失败,stderr 报 ws error长连接模式未开启飞书开放平台开启「事件订阅 - 长连接接收事件」
启动后看到 ready,但收不到事件目标 EventType 未在「事件订阅」勾选 / 未发版本重新勾选 + 发版
收到事件但 payload 字段缺失App 缺对应 scope(如
im:message.p2p_msg:readonly
event schema <key>
看 Scopes,去权限管理页开通后重新订阅
event consume
立即退出 reason=error
App ID/Secret 错 / 网络不通 / 域名走 lark 但 BaseURL 用了 feishu检查
config.yaml
lark
国际版需
--base-url https://open.larksuite.com
或对应配置
PhenomenonCauseSolution
WS connection failed, stderr reports ws errorLong connection mode not enabledEnable "Event Subscription - Receive Events via Long Connection" on Feishu Open Platform
Ready message appears after startup, but no events are receivedTarget EventType not checked in "Event Subscription" / version not publishedRe-check and publish the version
Events are received but payload fields are missingApp lacks corresponding scopes (e.g.,
im:message.p2p_msg:readonly
)
Check Scopes via
event schema <key>
, activate on the permission management page and re-subscribe
event consume
exits immediately with reason=error
Incorrect App ID/Secret / network unreachable / using lark domain but BaseURL set to feishuCheck
config.yaml
; for lark international version, use
--base-url https://open.larksuite.com
or corresponding configuration

AI Agent 后台订阅推荐用法

Recommended Usage for AI Agent Background Subscription

单 EventKey 后台订阅(
run_in_background=true

Single EventKey Background Subscription (
run_in_background=true
)

python
undefined
python
undefined

1. 后台启动 consume,stderr/stdout 各 redirect

1. Start consume in background, redirect stderr/stdout respectively

task = Bash( command='feishu-cli event consume im.message.receive_v1 --output-dir ./events 2> consume.log', run_in_background=True, )
task = Bash( command='feishu-cli event consume im.message.receive_v1 --output-dir ./events 2> consume.log', run_in_background=True, )

2. tail consume.log 阻塞等 "[event] ready event_key=im.message.receive_v1"

2. Tail consume.log and block until "[event] ready event_key=im.message.receive_v1"

3. 额外 sleep 1-3s 让 WS 握手完成

3. Additional sleep 1-3s to complete WS handshake

4. 业务逻辑:tail stdout / 读 ./events/*.json 处理新事件

4. Business logic: tail stdout / read ./events/*.json to process new events

5. 退出:feishu-cli event stop --event-key im.message.receive_v1

5. Exit: feishu-cli event stop --event-key im.message.receive_v1

或父进程 kill 后台 Bash task(SIGTERM 触发 graceful shutdown + unregister)

Or kill the background Bash task from parent process (SIGTERM triggers graceful shutdown + unregister)

undefined
undefined

子进程 stdin EOF 协议(非 TTY)

Subprocess stdin EOF Protocol (Non-TTY)

非 TTY 模式下,关闭 stdin 即触发优雅退出(reason=signal)。Python
subprocess.Popen
stdin=subprocess.PIPE
,处理完后
p.stdin.close()
比 SIGTERM 更稳——consume 会跑完当前事件再退出。
In non-TTY mode, closing stdin triggers graceful exit (reason=signal). For Python
subprocess.Popen
with
stdin=subprocess.PIPE
,
p.stdin.close()
after processing is more stable than SIGTERM—the consume process will finish processing the current event before exiting.

限制单跑时长 / 事件数

Limit Single Run Duration / Event Count

调试场景永远先用
--max-events N --timeout Ds
,避免忘了 stop 留下后台进程吃 API quota:
bash
feishu-cli event consume im.message.receive_v1 --max-events 1 --timeout 30s
Always use
--max-events N --timeout Ds
in debugging scenarios to avoid leaving background processes that consume API quota:
bash
feishu-cli event consume im.message.receive_v1 --max-events 1 --timeout 30s

抓 1 条事件 demo / 30 秒超时双保险

Capture 1 event demo / 30-second timeout double insurance

undefined
undefined

踩坑与注意事项

Pitfalls and Notes

  • daemon 进程持久
    event consume
    阻塞运行直到信号/超时/EOF;不会自己退出。AI Agent 后台跑必须配
    --max-events
    /
    --timeout
    或显式
    event stop
    ,否则会留下长跑进程
  • flock 跨进程互斥:bus.json 读写都走 flock,多个
    event consume
    同时启动注册是安全的;但不要手动编辑 bus.json
  • pipe broken 自动退出:下游 jq / tee 关闭 stdout(典型场景:
    event consume ... | head -1
    )会触发 SIGPIPE,consume 主动 cancel 退出 reason=signal,不会卡死等 Ctrl-C
  • --quiet
    不影响 ready marker
    :ready marker 走真实
    os.Stderr
    绕过
    --quiet
    重定向,所以 AI Agent 即使开
    --quiet
    父进程仍能等到 ready 行;但其他诊断(包括
    [event] exited
    reason)会被静默
  • AutoReconnect 无限重试:oapi-sdk-go v3 ws.Client 默认
    WithAutoReconnect(true)
    ,断线后无限重试(间隔 2 分钟 + 首次抖动)。长时间断线场景建议用
    --timeout
    主动退出,由外层守护进程拉起,比内层无限 retry 更可控
  • status 不主动 ping 进程
    event status
    signal(0)
    探活,对 PID 复用场景理论可能误判(极小概率)。
    event stop --pid N
    也是 syscall.Kill,命中错 PID 会 ESRCH 失败,不会误杀
  • 每条事件独立文件
    --output-dir
    模式下每条事件落盘
    <event_id>.json
    短时间高频事件可能创建大量小文件;落盘只为留痕,业务消费仍推荐用 stdout NDJSON
  • --jq
    只支持点路径
    --jq .event.message
    把每条事件投影到子树后再输出;不命中的事件会被 skip(不输出空行)。复杂过滤永远走 pipe 外部 jq
  • --output-dir
    只支持安全相对路径
    :传
    ~/events
    /tmp/events
    ../events
    都会报错;用
    ./events
    events/today
  • Persistent daemon process:
    event consume
    runs blocking until signal/timeout/EOF; it will not exit on its own. When running in the background for AI Agent, you must configure
    --max-events
    /
    --timeout
    or explicitly run
    event stop
    , otherwise long-running processes will remain.
  • flock cross-process mutual exclusion: bus.json read/write operations all use flock, so registering multiple
    event consume
    processes simultaneously is safe; do not edit bus.json manually.
  • Automatic exit on pipe broken: If downstream jq / tee closes stdout (typical scenario:
    event consume ... | head -1
    ), SIGPIPE will be triggered, and consume will actively cancel exit with reason=signal, avoiding being stuck waiting for Ctrl-C.
  • --quiet
    does not affect ready marker
    : The ready marker uses real
    os.Stderr
    bypassing
    --quiet
    redirection, so even if
    --quiet
    is enabled, the parent process can still wait for the ready line; but other diagnostics (including
    [event] exited
    reason) will be suppressed.
  • AutoReconnect infinite retry: oapi-sdk-go v3 ws.Client defaults to
    WithAutoReconnect(true)
    , retries infinitely after disconnection (interval 2 minutes + initial jitter). For long-term disconnection scenarios, it is recommended to use
    --timeout
    to exit actively and be pulled up by the outer daemon process, which is more controllable than infinite inner retry.
  • status does not actively ping processes:
    event status
    uses
    signal(0)
    to check liveness, which may theoretically misjudge in PID reuse scenarios (very low probability).
    event stop --pid N
    also uses syscall.Kill, which will fail with ESRCH if the wrong PID is hit, avoiding accidental killing.
  • Independent file per event: In
    --output-dir
    mode, each event is persisted as
    <event_id>.json
    , a large number of small files may be created for high-frequency events in a short time; persistence is only for traceability, it is recommended to use stdout NDJSON for business consumption.
  • --jq
    only supports dot paths
    :
    --jq .event.message
    projects each event to the subtree before output; events that do not match will be skipped (no empty lines output). Always use pipe with external jq for complex filtering.
  • --output-dir
    only supports safe relative paths
    : Passing
    ~/events
    ,
    /tmp/events
    ,
    ../events
    will all report errors; use
    ./events
    or
    events/today
    .

何时转其他 skill

When to Switch to Other Skills

任务路由
消息 / 回复 / 卡片 / 通知feishu-cli-msg
构造 interactive 卡片 JSONfeishu-cli-card
处理收到的消息事件 → 写多维表格feishu-cli-bitable(解析 payload 后调 record 命令)
处理收到的审批事件 → 查审批详情feishu-cli-toolkit(approval 子命令)
收到群消息后查群信息/成员feishu-cli-chat
Webhook URL 模式(HTTP 回调,非长连接)不在本技能范围;走飞书开放平台的「请求网址配置」+ 自建 HTTP server
历史消息批量拉取(非实时)feishu-cli-chat
msg history
/
msg list
TaskRoute
Send messages / replies / cards / notificationsfeishu-cli-msg
Construct interactive card JSONfeishu-cli-card
Process received message events → write to multidimensional tablesfeishu-cli-bitable (parse payload and call record command)
Process received approval events → query approval detailsfeishu-cli-toolkit (approval subcommand)
Query group information/members after receiving group messagesfeishu-cli-chat
Webhook URL mode (HTTP callback, non-long connection)Not within the scope of this skill; use "Request URL Configuration" on Feishu Open Platform + self-built HTTP server
Batch pull historical messages (non-real-time)
msg history
/
msg list
from feishu-cli-chat

参考

References

安全 — event_id 文件名净化

Security — event_id Filename Sanitization

--output-dir
启用时每条事件 dump 为
<event_id>.json
。v1 PR 加
sanitizeEventID
防御:
  • 只保留
    [A-Za-z0-9_-]
    字符,长度截到 128
  • ..
    /
    、空格、特殊符号都被丢弃
  • 净化后空串 → 跳过 dump(不写空文件名文件)
防御场景:服务端 payload 异常或恶意构造
header.event_id = "../etc/passwd"
类 payload 时,writeFile 不会逃出
--output-dir
When
--output-dir
is enabled, each event is dumped as
<event_id>.json
. The v1 PR added
sanitizeEventID
for defense:
  • Only retains
    [A-Za-z0-9_-]
    characters, truncates to 128 characters in length
  • ..
    ,
    /
    , spaces, and special symbols are discarded
  • If sanitization results in an empty string → skip dumping (do not write a file with empty filename)
Defense scenario: When the server payload is abnormal or maliciously constructed (e.g.,
header.event_id = "../etc/passwd"
), writeFile will not escape from
--output-dir
.