lark-event

Lark/Feishu real-time event listening / subscribing / consuming: stream events as NDJSON via `lark-cli event consume <EventKey>` (covers IM messages/reactions/chat changes, Approval status changes, Task updates, VC meeting started/joined/ended, Minutes generated, Whiteboard updated, etc.). Use for L

By larksuite · 435,862 installs

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

Source repository · Upstream listing

Lark Events Prerequisite: Read [ ../lark shared/SKILL.md ](../lark shared/SKILL.md) first for authentication, as user/bot switching, Permission denied handling, and safety rules. Core commands Command Purpose lark cli event list [ json] List all subscribable EventKeys lark cli event schema <EventKey [ json] Show an EventKey's params and output schema lark cli event consume <EventKey [flags] Blocking consume; events → stdout NDJSON lark cli event status [ json] [ fail on orphan] Inspect the local bus daemon status lark cli event stop [ all] [ force] Stop the bus daemon Common flags Flag Description param key=value / p Business params (repeatable; comma separated for multi value). Unknown keys fail with valid names listed inline jq <expr jq expression to filter / transform each event; empty output skips the event max events N Exit after N events. Default 0 = unlimited timeout D Exit after duration D (e.g. 30s , 2m ). Default 0 = no timeout. Whichever of max events / timeout fires first wins output dir <dir Write each event as a file (relative paths only; prevents traversal) quiet Suppress ready/exit markers and per event stderr diagnostics, including drop warnings. This can hide event loss. AI should not use this — it removes readiness and integrity signals as user\ bot\ auto Identity for the session (see lark shared) Examples Call flow 1. lark cli event list json → pick a legal key. domain <d narrows to one domain; the domains are application , approval , board , card , im , minutes , task , vc . An unknown domain fails with the valid set listed in the hint. 2. lark cli event schema <key json → read resolved output schema + jq root path to determine field paths 3. lark cli event consume <key [ jq '<expr '] → consume Subprocess contract Ready marker event consume 's stderr emits a fixed line [event] ready event key=<key . Parent processes should block on stderr until this line appears, then start reading stdout. Do not fall back to sleep . stdin EOF = graceful exit event consume treats stdin close as a shutdown signal (wired for AI subprocess callers). Bounded runs are exempt: when max events or timeout is set ( 0), stdin EOF is ignored and the run exits only via its own bound, timeout, or SIGTERM. For unbounded runs, < /dev/null / nohup / systemd's default StandardInput=null will cause an immediate graceful exit (stderr reason: signal ). To keep an unbounded run alive: Feed stdin a source that never EOFs: < <(tail f /dev/null) Or run bounded: max events N / timeout D Exit codes & reason On exit, the last stderr line is [event] exited — received N event(s) in Xs (reason: ...) . exit code reason Trigger 0 reason: limit max events reached 0 reason: timeout timeout reached 0 reason: signal Ctrl+C / SIGTERM / stdin EOF (stdin EOF applies to unbounded runs only) 1 JSON error envelope on stderr Lark API business failure during pre consume setup (for example subscription create/delete) 2 JSON error envelope on stderr (no exited line) Validation failure (unknown EventKey, bad param / jq , another bus already connected) 3 JSON error envelope on stderr Auth failure (missing token, missing scopes) 4 / 5 JSON error envelope on stderr Network / internal failure (bus startup, handshake, file I/O) Startup and runtime failures emit a structured JSON envelope on stderr: {"ok":false,"error":{"type","subtype","param","message","hint",...}} (the envelope may also carry top level identity / notice siblings). Parse error.type / error.subtype to branch (e.g. missing scope carries a missing scopes list), error.param to find the offending flag, and error.hint for the recovery action — do not regex match message text. Orchestrators should treat reason: limit/timeout/signal (all exit 0) as "business completion" and non zero as "failure". Never kill 9 Avoid kill 9 on consume processes for EventKeys whose PreConsume registers a server side subscription and unsubscribes on exit (minutes, vc, board keys): kill 9 skips the OAPI unsubscribe and leaks the server side subscription (symptoms: "subscription already exists" on restart, duplicate event delivery). Keys whose subscription is a durable relation with no cleanup (task, approval keys) do not leak this way, but SIGTERM or closing stdin remains the right shutdown for every key. One consume, one EventKey (multi key = multi shell) The command takes exactly one positional argument; k1,k2 and wildcards are unsupported. Listening to N keys means N subprocesses — this is intentional : One shape per process stdout; no dispatcher logic required in the AI Fault isolation (one key failing doesn't affect others) Independent as / jq / max events / timeout per key All N consumers share a single bus daemon (UDS local IPC), so the overhead is small Writing jq via schema event schema <key json is the source of truth for writing jq . Four things to look at: (1) Where fields start — see jq root path Value "." → fields are at the top level, write .chat id Value ".event" → fields are inside a V2 envelope, write .event.chat id (2) Field list and types — see resolved output schema.properties.<name Each field carries type / description , and some also have format . Snippet (from event schema im.message.receive v1 json ): (3) Field semantics — see the format tag Lark defined semantic tags ( not JSON Schema's standard format ). Common values: open id / chat id / message id / timestamp ms / email . Purpose: distinguish "same string type, different meanings" fields so you can reverse lookup via API or convert formats. (4) Decoded state — read the field's description event consume runs Process hooks that may pre decode some payload fields (flattening V2 envelopes, rendering .content to plain text, etc.) — behavior differs from raw OAPI. Always read the field's description before writing jq , especially for generic field names like content / data / body / payload . Why it matters : blindly applying fromjson to an already decoded text field makes jq error on every event and silently drop it — the consumer looks alive but emits nothing, with only a single WARN line buried on stderr. (This is the general behavior: any jq runtime error skips the event with a one line WARN; the loop does not abort.) Don't shortcut the schema : when projecting event schema json with jq, do not strip .description from properties — that's the field that tells you whether a field is already decoded. Dump the full property objects, not just keys. Aside : param 's valid parameters also live in the schema — the params section lists name / type / required / enum / default / description ; section missing = this key accepts no param . Topic index Topic Reference Coverage Application [ references/lark event application.md ](references/lark event application.md) Catalog of Application EventKeys, including application.bot.menu v6 for custom bot menu push events + flattened event key / operator fields + jq recipe Approval [ references/lark event approval.md ](references/lark event approval.md) Catalog of 2 Approval EventKeys ( approval.instance.status changed v4 , approval.task.status changed v4 ) + optional/multi subscription type pre registration + user auth subscription lifecycle + flat output field reference IM [ references/lark event im.md ](references/lark event im.md) Catalog of 12 IM EventKeys + shape notes (flat vs V2 envelope) + im.message.receive v1 field gotchas ( sender id is open id only; .content is plain text except for interactive cards) + common jq recipes (filter by chat type / message type / sender); for card.action.trigger see also [ ../lark im/references/lark im card action reply.md ](../lark im/references/lark im card action reply.md) Task [ references/lark event task.md ](references/lark event task.md) Catalog of 1 Task EventKey ( task.task.update user access v2 ) + Native V2 envelope shape + task commit types + user/bot subscription notes VC [ references/lark event vc.md ](references/lark event vc.md) Catalog of 7 VC EventKeys (meeting lifecycle participant meeting started/joined/ended v1 , vc.note.generated v1 , recording recording started/transcript generated/ended v1 ) + field reference + source type semantics; the live list is always lark cli event list domain vc json Minutes [ references/lark event minutes.md ](references/lark event minutes.md) Catalog of 1 Minutes EventKey ( minutes.minute.generated v1 ) + field reference + source type semantics (meeting only) Whiteboard [ references/lark event whiteboard.md ](references/lark event whiteboard.md) Catalog of 1 Board EventKey ( board.whiteboard.updated v1 ) + per whiteboard subscription model (requires p whiteboard id=<token ) + payload field reference (whiteboard id / operator ids triple id)