Skip to content
Development
Skill

/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

From plugin
cli
16k28 skills2 agents
Install
$ npx -y skills add larksuite/cli --skill lark-event --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/lark-event

Context preview

The summary Claude sees to decide when to auto-load this skill.

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

SKILL.md

lark-event.SKILL.md
name: lark-event
version: 1.0.0
description: "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 Lark bots, real-time message processing, long-running subscribers, streaming webhook/push handlers. Supports `--max-events` / `--timeout` bounded runs and a stderr ready-marker contract — designed for AI agents running as subprocesses."
metadata:
  requires:
    bins: ["lark-cli"]
  cliHelp: "lark-cli event --help"

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

# 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

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 i

Read more
Ships withcli

The official Lark/Feishu CLI tool, maintained by the larksuite team — built for humans and AI Agents.

Get the whole plugin

Other skills on cli.