openclaw-skills/lark-event/SKILL.md
Lark/Feishu real-time event listening / subscribing / consuming: stream events as NDJSON via `lark-cli event consume <EventKey>` (covers IM messages/reactions/chat changes, VC meeting 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.
npx skillsauth add seaworld008/commonly-used-high-value-skills lark-eventInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Prerequisite: Read
../lark-shared/SKILL.mdfirst for authentication,--as user/botswitching,Permission deniedhandling, and safety rules.
| 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 |
| 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 stderr diagnostics. AI should not use this — it silences the ready marker |
| --as user\|bot\|auto | Identity for the session (see lark-shared) |
# Default: stream every event for the key (no filter, no projection)
lark-cli event consume im.message.receive_v1 --as bot
# 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
lark-cli event list --json → pick a legal keylark-cli event schema <key> --json → read resolved_output_schema + jq_root_path to determine field pathslark-cli event consume <key> [--jq '<expr>'] → consumeevent 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.
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:
< <(tail -f /dev/null)--max-events N / --timeout DOn 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) |
| non-0 | Error: ... (no exited line) | Startup / runtime failure (permissions, network, params, config) |
Orchestrators should treat reason: limit/timeout/signal (all exit 0) as "business completion" and non-zero as "failure".
kill -9Avoid kill -9 on consume processes: for EventKeys with a PreConsume hook (those that register server-side subscriptions via OAPI), kill -9 skips the OAPI unsubscribe and leaks server-side subscriptions (symptoms: "subscription already exists" on restart, duplicate event delivery). Prefer SIGTERM or closing stdin.
The command takes exactly one positional argument; k1,k2 and wildcards are unsupported. Listening to N keys means N subprocesses — this is intentional:
--as / --jq / --max-events / --timeout per keyAll N consumers share a single bus daemon (UDS local IPC), so the overhead is small
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
"." → fields are at the top level, write .chat_id".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):
{
"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) 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 | Reference | Coverage |
|------------|------------------------------------------------------------------------------|---|
| IM | references/lark-event-im.md | Catalog of 11 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) |
| VC | references/lark-event-vc.md | Catalog of 2 VC EventKeys (vc.meeting.participant_meeting_ended_v1, vc.note.generated_v1) + field reference + source type semantics (meeting only) |
| Minutes | 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 | 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) |
testing
Orchestrating specialist AI agent teams as a meta-coordinator. Decomposes requests into minimum viable chains, spawns each as an independent session in AUTORUN modes, and drives to final output. Use when a task spans multiple specialist domains, requires parallel agent execution, or needs hub-and-spoke routing across the skill ecosystem.
tools
用于 Next.js App Router 模式开发,包含 RSC、Server Actions 和路由最佳实践。来源:skills.sh 10.2K installs。
tools
Deploy web projects to Netlify using the Netlify CLI (`npx netlify`). Use when the user asks to deploy, host, publish, or link a site/repo on Netlify, including preview and production deploys.
tools
Guides and best practices for working with Neon Serverless Postgres. Covers setup, connection methods, branching, autoscaling, scale-to-zero, read replicas, connection pooling, Neon Auth, and the Neon CLI, MCP server, REST API, TypeScript SDK, and Python SDK. Use when users ask about "Neon setup", "connect to Neon", "Neon project", "DATABASE_URL", "serverless Postgres", "Neon CLI", "neonctl", "Neon MCP", "Neon Auth", "@neondatabase/serverless", "@neondatabase/neon-js", "scale to zero", "Neon autoscaling", "Neon read replica", or "Neon connection pooling".