Skip to content
cccskills
FreePublished on GitHub

lark-event

Receive live Lark/Feishu updates for messages, approvals, tasks, meetings, and more. Stream them as NDJSON, one JSON record per line, with filtering and time or event limits for bots and automated event processing.

OriginalShow the original 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.

See how to install

Good for

  • Receiving new messages for bot processing
  • Monitoring approval and task updates
  • Receiving meeting lifecycle and minutes events
  • Collecting sample events within a time or count limit

Files included (8)

  • SKILL.md11.2 KB
  • references/lark-event-application.md1.3 KB
  • references/lark-event-approval.md8.8 KB
  • references/lark-event-im.md4.5 KB
  • references/lark-event-minutes.md2.3 KB
  • references/lark-event-task.md2.6 KB
  • references/lark-event-vc.md5.0 KB
  • references/lark-event-whiteboard.md3.6 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

Lark Events

Prerequisite: Read ../lark-shared/SKILL.md first for authentication, --as user/bot switching, Permission denied handling, and safety rules.

Core commands

CommandPurpose
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

FlagDescription
--param key=value / -pBusiness 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 NExit after N events. Default 0 = unlimited
--timeout DExit 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)
--quietSuppress 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|autoIdentity 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 codereasonTrigger
0reason: limit--max-events reached
0reason: timeout--timeout reached
0reason: signalCtrl+C / SIGTERM / stdin EOF (stdin EOF applies to unbounded runs only)
1JSON error envelope on stderrLark API business failure during pre-consume setup (for example subscription create/delete)
2JSON error envelope on stderr (no exited line)Validation failure (unknown EventKey, bad --param / --jq, another bus already connected)
3JSON error envelope on stderrAuth failure (missing token, missing scopes)
4 / 5JSON error envelope on stderrNetwork / 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):

{
  "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 index

TopicReferenceCoverage
Applicationreferences/lark-event-application.mdCatalog of Application EventKeys, including application.bot.menu_v6 for custom bot menu push events + flattened event_key / operator fields + jq recipe
Approvalreferences/lark-event-approval.mdCatalog 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
IMreferences/lark-event-im.mdCatalog 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
Taskreferences/lark-event-task.mdCatalog of 1 Task EventKey (task.task.update_user_access_v2) + Native V2 envelope shape + task commit types + user/bot subscription notes
VCreferences/lark-event-vc.mdCatalog 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
Minutesreferences/lark-event-minutes.mdCatalog of 1 Minutes EventKey (minutes.minute.generated_v1) + field reference + source type semantics (meeting only)
Whiteboardreferences/lark-event-whiteboard.mdCatalog 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)

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

lark-approval

FreeSummary

Find and process approval requests in 飞书, including approving, rejecting, transferring, or returning them. Review forms and progress, search existing approval forms and workflows, and submit native requests such as leave or expense claims.

  • Review pending and completed approval requests
  • Approve, reject, or return a request
  • Find an existing form and submit leave or expense claims
larksuite/cli17.7KUpdated Oct 16, 2026

lark-apps

FreeSummary

Build, publish, and manage apps on 妙搭(Spark/Miaoda) through local development or cloud AI sessions. Create page designs, manage data and permissions, inspect logs and usage, and configure automated triggers.

  • Build and publish a business app
  • Create landing pages and interactive prototypes
  • Inspect production logs and usage
larksuite/cli17.7KUpdated Oct 16, 2026

lark-attendance

FreeSummary

Retrieve your own attendance clock records from 飞书 through lark-cli. The skill fills in fixed query parameters and uses read-only attendance access to look up the records you want to check.

  • Checking your own attendance clock records
  • Reviewing recorded clock-ins and clock-outs
  • Asking an agent to retrieve attendance records
larksuite/cli17.7KUpdated Oct 16, 2026

lark-base

FreeSummary

Build and manage business tables in Feishu Base, including fields, records, views, and data queries. Create forms and dashboards, configure automated workflows, organize BaseApp pages and components, and manage role-based access permissions.

  • Create business tables and update records
  • Filter and summarize table data
  • Create information collection forms
larksuite/cli17.7KUpdated Oct 16, 2026

lark-calendar

FreeSummary

Manage events, attendees, and meeting rooms in 飞书. Check shared availability, get meeting time suggestions that account for working hours and breaks, and create or update events with room reservations.

  • Review today's events or search upcoming meetings
  • Find suitable meeting times for several people
  • Book a room with a calendar event
larksuite/cli17.7KUpdated Oct 16, 2026

lark-contact

FreeSummary

Finds Lark contacts by name or email and retrieves open_id, an identifier used in later actions. It also looks up profile details, personal status, and signatures, and searches for bots or agents visible to the current user.

  • Identifying a colleague before messaging or scheduling
  • Looking up a profile from a known open_id
  • Checking colleagues’ personal status and signatures
larksuite/cli17.7KUpdated Oct 16, 2026

See all skills by larksuite

Report a problem with this skill