feishu-cli-event
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinese飞书实时事件订阅技能(WebSocket)
Feishu Real-time Event Subscription Skill (WebSocket)
通过 子命令族订阅飞书开放平台事件,使用 WebSocket 长连接接收事件并以 NDJSON 输出到 stdout,适合 AI Agent 做 bot 实时响应、群消息监听、审批回调消费等场景。
feishu-cli eventfeishu-cli:如尚未安装,请前往 riba2534/feishu-cli 获取安装方式。发消息? 请使用 feishu-cli-msg 技能。本技能专注于事件订阅(接收应用事件),不负责发送。
Subscribe to Feishu Open Platform events via the 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 eventfeishu-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 exitDifferences 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
| 路径 | 作用 |
|---|---|
| 活跃 consumer 列表(PID/EventKey/启动时间/参数) |
| flock 文件锁;bus.json 读写串行化,fd 关闭自动释放 |
每个 AppID 一个子目录,不同应用互不干扰。 查询会主动剔除已不存活的 PID 条目(kill -9 / 崩溃残留)。bus.json 用 tmp + rename 原子写,防半写。
event status| Path | Purpose |
|---|---|
| List of active consumers (PID/EventKey/start time/parameters) |
| 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. 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.
event status输出协议(NDJSON + ready marker)
Output Protocol (NDJSON + ready marker)
| 流 | 内容 |
|---|---|
| stdout | 每条事件一行 JSON(NDJSON),适合 jq / 脚本管道 |
| stderr | 诊断日志;启动时一行 |
AI Agent 推荐:父进程把 consume 跑后台(),先阻塞 stderr 等到run_in_background=true那一行再开始读 stdout。注意:ready marker 只表示进程初始化完成,WS 握手在后台异步执行;父进程见到 marker 后还需额外等 1-3s 让 WS 握手真正完成,生产环境建议父进程发自检事件 + 等 echo 回环来确认链路通。[event] ready
| Stream | Content |
|---|---|
| stdout | One JSON per event line (NDJSON), suitable for jq / script pipelines |
| stderr | Diagnostic logs; outputs |
AI Agent Recommendation: Run consume in the background with the parent process (), block on stderr until therun_in_background=trueline 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.[event] ready
退出码与退出 reason
Exit Codes and Exit Reasons
| 退出码 | 含义 |
|---|---|
| 0 | 正常退出(达到 |
| 非 0 | startup 失败 / WebSocket 不可恢复错误 / 参数错误 |
stderr 末尾会输出 ,reason 有 4 个:
[event] exited — elapsed=<d> reason=<r>- — 达到
limit--max-events - — 达到
timeout--timeout - — 上下文取消(Ctrl-C / SIGTERM / stdin EOF / 下游 pipe broken)
signal - — WebSocket 连接持续失败
error
| Exit Code | Meaning |
|---|---|
| 0 | Normal exit (reached |
| Non-0 | Startup failure / unrecoverable WebSocket error / parameter error |
The end of stderr will output , where there are 4 reasons:
[event] exited — elapsed=<d> reason=<r>- — reached
limit--max-events - — reached
timeout--timeout - — context canceled (Ctrl-C / SIGTERM / stdin EOF / downstream pipe broken)
signal - — continuous WebSocket connection failure
error
命令速查
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. 停 consumebash
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 consume1. event list
:列出支持的 EventKey
event list1. event list
: List supported EventKeys
event list按 domain 分组展示当前支持的 22+ EventKey(im / contact / calendar / drive / approval / vc)。
bash
undefinedDisplays 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
event schema2. event schema
: View payload schema and scope
event schemabash
feishu-cli event schema im.message.receive_v1
feishu-cli event schema im.message.receive_v1 --json输出 4 部分: / / / / + 可选 。Payload schema 为手工 curated,订阅后实际 payload 以飞书开放平台文档为准。
KeyEvent TypeDomainDescriptionScopesPayload Schema (示例)bash
feishu-cli event schema im.message.receive_v1
feishu-cli event schema im.message.receive_v1 --jsonOutputs 4 parts: / / / / + optional . The payload schema is manually curated; the actual payload after subscription is subject to Feishu Open Platform documentation.
KeyEvent TypeDomainDescriptionScopesPayload Schema (Example)3. event consume
:启动 WebSocket 订阅(阻塞)
event consume3. event consume
: Start WebSocket subscription (blocking)
event consumebash
undefinedbash
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 进程
event status4. event status
: View active local consume processes
event statusbash
feishu-cli event status
feishu-cli event status --json | jq '.consumers[] | .pid'输出: / 路径 / / / / (max-events / timeout / output-dir / jq)。
App IDState filePIDEVENT_KEYUPTIMEEXTRA查询时会主动剔除已不存活的 PID 条目(清理 kill -9 / 崩溃残留的僵尸记录)。
bash
feishu-cli event status
feishu-cli event status --json | jq '.consumers[] | .pid'Outputs: / path / / / / (max-events / timeout / output-dir / jq).
App IDState filePIDEVENT_KEYUPTIMEEXTRADuring query, entries of non-living PIDs will be actively removed (cleaning up zombie records from kill -9 / crashes).
5. event stop
:停止 consume 进程
event stop5. event stop
: Terminate consume processes
event stopbash
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 验证进程已退出; 升级为 SIGKILL,会留下 bus.json 僵尸条目,下次 会自动清理。
--forceevent statusbash
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; upgrades to SIGKILL, which will leave zombie entries in bus.json, and the next will automatically clean them up.
--forceevent statusEventKey 速查(按 domain 分组)
EventKey Quick Reference (Grouped by Domain)
完整列表用 。常用:
feishu-cli event list| Domain | EventKey | 描述 |
|---|---|---|
| im | | 接收消息(用户/群聊发给 Bot) |
| im | | 消息已读回执 |
| im | | 消息被撤回 |
| im | | 消息表情回复添加/删除 |
| im | | 群聊信息更新 |
| im | | 用户进群/离群 |
| im | | Bot 被拉入/移出群 |
| im | | 群聊被解散 |
| contact | | 员工入职/变更/离职 |
| calendar | | 日程变更(创建/更新/删除) |
| calendar | | 日历权限变更 |
| drive | | 文档标题修改 |
| drive | | 文档协作者添加 |
| approval | | 审批实例状态变更 |
| approval | | 审批任务变更 |
| vc | | VC 会议开始/结束 |
EventKey 与 EventType 通常一致;接收到的 payload 里等于header.event_type字段。event_type
Use for the complete list. Common ones:
feishu-cli event list| Domain | EventKey | Description |
|---|---|---|
| im | | Receive messages (sent to Bot by user/group chat) |
| im | | Message read receipt |
| im | | Message recalled |
| im | | Message reaction added/deleted |
| im | | Group chat information updated |
| im | | User joined/left group |
| im | | Bot added/removed from group |
| im | | Group chat disbanded |
| contact | | Employee hired/changed/left |
| calendar | | Calendar event changed (created/updated/deleted) |
| calendar | | Calendar permission changed |
| drive | | Document title modified |
| drive | | Document collaborator added |
| approval | | Approval instance status changed |
| approval | | Approval task changed |
| vc | | VC meeting started/ended |
EventKey and EventType are usually consistent; thein the received payload equals theheader.event_typefield.event_type
权限与开放平台配置
Permissions and Open Platform Configuration
默认 App Token,无需 auth login
auth loginDefault App Token, no auth login
required
auth login事件订阅走 App 身份(app_id + app_secret),不强制 user token。配好 或 / 环境变量即可。
~/.feishu-cli/config.yamlFEISHU_APP_IDFEISHU_APP_SECRETEvent subscription uses App identity (app_id + app_secret), user token is not mandatory. Just configure or set the / environment variables.
~/.feishu-cli/config.yamlFEISHU_APP_IDFEISHU_APP_SECRET飞书开放平台两步配置
Two-step Configuration on Feishu Open Platform
在 open.feishu.cn 你的应用控制台:
- 「事件订阅 - 长连接接收事件」 开启长连接模式(feishu-cli 走 WebSocket,不是 webhook URL 模式)
- 「事件与回调 - 事件订阅」 选中目标 EventType(与 输出的 Event Type 一致)并发布版本
event schema <key> - scope 开通:每个 EventKey 需要的 scope 见 的
event schema <key>字段;在「权限管理」页面开通。Scopes域已加入event推荐列表,可一次性申请 IM/contact/calendar/drive/approval/vc 常用 scope 并集--domain event --recommend
In your application console at open.feishu.cn:
- 「Event Subscription - Receive Events via Long Connection」 Enable long connection mode (feishu-cli uses WebSocket, not webhook URL mode)
- 「Events and Callbacks - Event Subscription」 Select the target EventType (consistent with the Event Type output by ) and publish the version
event schema <key> - Scope activation: The scopes required for each EventKey can be found in the field of
Scopes; activate them on the "Permission Management" page. Theevent schema <key>domain has been added to theeventrecommendation list, allowing one-click application for the union of common scopes for IM/contact/calendar/drive/approval/vc--domain event --recommend
常见错误
Common Errors
| 现象 | 原因 | 解决 |
|---|---|---|
| WS 连接失败,stderr 报 ws error | 长连接模式未开启 | 飞书开放平台开启「事件订阅 - 长连接接收事件」 |
| 启动后看到 ready,但收不到事件 | 目标 EventType 未在「事件订阅」勾选 / 未发版本 | 重新勾选 + 发版 |
| 收到事件但 payload 字段缺失 | App 缺对应 scope(如 | |
| App ID/Secret 错 / 网络不通 / 域名走 lark 但 BaseURL 用了 feishu | 检查 |
| Phenomenon | Cause | Solution |
|---|---|---|
| WS connection failed, stderr reports ws error | Long connection mode not enabled | Enable "Event Subscription - Receive Events via Long Connection" on Feishu Open Platform |
| Ready message appears after startup, but no events are received | Target EventType not checked in "Event Subscription" / version not published | Re-check and publish the version |
| Events are received but payload fields are missing | App lacks corresponding scopes (e.g., | Check Scopes via |
| Incorrect App ID/Secret / network unreachable / using lark domain but BaseURL set to feishu | Check |
AI Agent 后台订阅推荐用法
Recommended Usage for AI Agent Background Subscription
单 EventKey 后台订阅(run_in_background=true
)
run_in_background=trueSingle EventKey Background Subscription (run_in_background=true
)
run_in_background=truepython
undefinedpython
undefined1. 后台启动 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)
undefinedundefined子进程 stdin EOF 协议(非 TTY)
Subprocess stdin EOF Protocol (Non-TTY)
非 TTY 模式下,关闭 stdin 即触发优雅退出(reason=signal)。Python 用 ,处理完后 比 SIGTERM 更稳——consume 会跑完当前事件再退出。
subprocess.Popenstdin=subprocess.PIPEp.stdin.close()In non-TTY mode, closing stdin triggers graceful exit (reason=signal). For Python with , after processing is more stable than SIGTERM—the consume process will finish processing the current event before exiting.
subprocess.Popenstdin=subprocess.PIPEp.stdin.close()限制单跑时长 / 事件数
Limit Single Run Duration / Event Count
调试场景永远先用 ,避免忘了 stop 留下后台进程吃 API quota:
--max-events N --timeout Dsbash
feishu-cli event consume im.message.receive_v1 --max-events 1 --timeout 30sAlways use in debugging scenarios to avoid leaving background processes that consume API quota:
--max-events N --timeout Dsbash
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
undefinedundefined踩坑与注意事项
Pitfalls and Notes
- daemon 进程持久:阻塞运行直到信号/超时/EOF;不会自己退出。AI Agent 后台跑必须配
event consume/--max-events或显式--timeout,否则会留下长跑进程event stop - flock 跨进程互斥:bus.json 读写都走 flock,多个 同时启动注册是安全的;但不要手动编辑 bus.json
event consume - pipe broken 自动退出:下游 jq / tee 关闭 stdout(典型场景:)会触发 SIGPIPE,consume 主动 cancel 退出 reason=signal,不会卡死等 Ctrl-C
event consume ... | head -1 - 不影响 ready marker:ready marker 走真实
--quiet绕过os.Stderr重定向,所以 AI Agent 即使开--quiet父进程仍能等到 ready 行;但其他诊断(包括--quietreason)会被静默[event] exited - AutoReconnect 无限重试:oapi-sdk-go v3 ws.Client 默认 ,断线后无限重试(间隔 2 分钟 + 首次抖动)。长时间断线场景建议用
WithAutoReconnect(true)主动退出,由外层守护进程拉起,比内层无限 retry 更可控--timeout - status 不主动 ping 进程:用
event status探活,对 PID 复用场景理论可能误判(极小概率)。signal(0)也是 syscall.Kill,命中错 PID 会 ESRCH 失败,不会误杀event stop --pid N - 每条事件独立文件:模式下每条事件落盘
--output-dir,短时间高频事件可能创建大量小文件;落盘只为留痕,业务消费仍推荐用 stdout NDJSON<event_id>.json - 只支持点路径:
--jq把每条事件投影到子树后再输出;不命中的事件会被 skip(不输出空行)。复杂过滤永远走 pipe 外部 jq--jq .event.message - 只支持安全相对路径:传
--output-dir、~/events、/tmp/events都会报错;用../events或./eventsevents/today
- Persistent daemon process: runs blocking until signal/timeout/EOF; it will not exit on its own. When running in the background for AI Agent, you must configure
event consume/--max-eventsor explicitly run--timeout, otherwise long-running processes will remain.event stop - flock cross-process mutual exclusion: bus.json read/write operations all use flock, so registering multiple processes simultaneously is safe; do not edit bus.json manually.
event consume - Automatic exit on pipe broken: If downstream jq / tee closes stdout (typical scenario: ), SIGPIPE will be triggered, and consume will actively cancel exit with reason=signal, avoiding being stuck waiting for Ctrl-C.
event consume ... | head -1 - does not affect ready marker: The ready marker uses real
--quietbypassingos.Stderrredirection, so even if--quietis enabled, the parent process can still wait for the ready line; but other diagnostics (including--quietreason) will be suppressed.[event] exited - AutoReconnect infinite retry: oapi-sdk-go v3 ws.Client defaults to , retries infinitely after disconnection (interval 2 minutes + initial jitter). For long-term disconnection scenarios, it is recommended to use
WithAutoReconnect(true)to exit actively and be pulled up by the outer daemon process, which is more controllable than infinite inner retry.--timeout - status does not actively ping processes: uses
event statusto check liveness, which may theoretically misjudge in PID reuse scenarios (very low probability).signal(0)also uses syscall.Kill, which will fail with ESRCH if the wrong PID is hit, avoiding accidental killing.event stop --pid N - Independent file per event: In mode, each event is persisted as
--output-dir, 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.<event_id>.json - only supports dot paths:
--jqprojects 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.--jq .event.message - only supports safe relative paths: Passing
--output-dir,~/events,/tmp/eventswill all report errors; use../eventsor./events.events/today
何时转其他 skill
When to Switch to Other Skills
| 任务 | 路由 |
|---|---|
| 发消息 / 回复 / 卡片 / 通知 | feishu-cli-msg |
| 构造 interactive 卡片 JSON | feishu-cli-card |
| 处理收到的消息事件 → 写多维表格 | feishu-cli-bitable(解析 payload 后调 record 命令) |
| 处理收到的审批事件 → 查审批详情 | feishu-cli-toolkit(approval 子命令) |
| 收到群消息后查群信息/成员 | feishu-cli-chat |
| Webhook URL 模式(HTTP 回调,非长连接) | 不在本技能范围;走飞书开放平台的「请求网址配置」+ 自建 HTTP server |
| 历史消息批量拉取(非实时) | feishu-cli-chat 的 |
| Task | Route |
|---|---|
| Send messages / replies / cards / notifications | feishu-cli-msg |
| Construct interactive card JSON | feishu-cli-card |
| Process received message events → write to multidimensional tables | feishu-cli-bitable (parse payload and call record command) |
| Process received approval events → query approval details | feishu-cli-toolkit (approval subcommand) |
| Query group information/members after receiving group messages | feishu-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) | |
参考
References
- 飞书开放平台事件订阅文档:https://open.feishu.cn/document/server-docs/event-subscription-guide/event-list
- 项目 CHANGELOG:本模块新增详情见仓库
CHANGELOG.md段落event 模块 - 源码:+
cmd/event*.gointernal/event/{bus,keys,runtime}.go
- Feishu Open Platform Event Subscription Documentation: https://open.feishu.cn/document/server-docs/event-subscription-guide/event-list
- Project CHANGELOG: Details of new additions to this module can be found in the section of the repository's
event moduleCHANGELOG.md - Source Code: +
cmd/event*.gointernal/event/{bus,keys,runtime}.go
安全 — event_id 文件名净化
Security — event_id Filename Sanitization
--output-dir<event_id>.jsonsanitizeEventID- 只保留 字符,长度截到 128
[A-Za-z0-9_-] - 、
..、空格、特殊符号都被丢弃/ - 净化后空串 → 跳过 dump(不写空文件名文件)
防御场景:服务端 payload 异常或恶意构造 类 payload 时,writeFile 不会逃出 。
header.event_id = "../etc/passwd"--output-dirWhen is enabled, each event is dumped as . The v1 PR added for defense:
--output-dir<event_id>.jsonsanitizeEventID- Only retains characters, truncates to 128 characters in length
[A-Za-z0-9_-] - ,
.., 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., ), writeFile will not escape from .
header.event_id = "../etc/passwd"--output-dir