skilly.
All skills
Automation · Backend / AGENT SKILL

lark-event

open.feishu.cn
719.3K installs
0

Consume real-time Lark events as NDJSON for bots, subscribers, and streaming handlers.
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.

Low community score

lark-event: This skill has a community score below −5, meaning it has received more downvotes than upvotes. Review its source and assessment before installing. Community votes are not a security review.

BEFORE YOU INSTALL

Understand the trade-offs.

SECURITY REVIEW

Review incomplete

The available checks do not support a complete conclusion. Review the scope before relying on this result.

No reported risk0 reported findingsIncomplete evidence
Scope & how to read this review

Static inspection of the supplied skill source. “Complete” means the selected source and checks completed; it does not cover every downloaded package, external service, or runtime action.

Source coverage
partial
Reviewed
2026-10-07
Reviewed version
sha256:0d43a
Latest catalog version
sha256:0d43a

The reported findings score starts at 100 and subtracts 35 for each critical finding, 20 for high, 9 for medium, and 3 for low, with a floor of 0. It is shown only for complete, current reviews with all finding details. A score of 100 means no findings were reported in the reviewed source.

Severity describes potential impact, not the probability of harm. Review the conditions and evidence for each finding. A scan is not a safety guarantee.

SKILL QUALITY

Limited evidence for a verdict

60/100Provisional source score

The supplied instructions clearly describe event discovery, schema inspection, streaming, and subprocess lifecycle handling. A user can expect detailed guidance for operating an existing lark-cli installation, but setup dependencies and domain references are missing from this bundle. Runtime behavior was not verified.

low confidenceStatic reviewIntegration skill

The reviewer had limited evidence. These scores describe what was available, not a verified measure of reliability.

What works well

  • Explicit ordered workflow and concrete bounded-consumption examples.
  • Detailed readiness, shutdown, exit-code, and structured-error contracts.
  • Useful guidance on schema-based filtering and observable event-loss warnings.

Before you rely on it

  • Supply the shared authentication prerequisite and all linked domain references.
  • Document installation requirements and the compatible CLI release.
  • Add a bounded validation example with expected output and checks for readiness, event shape, warnings, and exit status.
Clear instructionsCan your agent understand the task and expected outcome?4/4

The task, command selection, output format, and agent subprocess expectations are explicit.

EVIDENCE
SKILL.md: "1. `lark-cli event list --json` → pick a legal key."; "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"
Complete workflowAre prerequisites, failure cases, and recovery covered?2/4

Lifecycle and failure handling are detailed, but required authentication guidance is delegated to an unavailable file, and recovery from leaked subscriptions is not concretely described.

EVIDENCE
SKILL.md: "Read [`../lark-shared/SKILL.md`](../lark-shared/SKILL.md) first for authentication, `--as user/bot` switching, `Permission denied` handling, and safety rules."; "`kill -9` skips the OAPI unsubscribe and leaks the server-side subscription"

To improve: Provide the shared prerequisite and explicit recovery steps for orphaned daemons and leaked subscriptions.

Repeatable resultsAre examples and dependencies specific enough to repeat the work?2/4

Concrete commands and deterministic lifecycle details support repeatable use, but the installation baseline and compatible CLI version are unspecified.

EVIDENCE
SKILL.md: "lark-cli event consume im.message.receive_v1 --max-events 1 --timeout 30s --as bot"; "Whichever of `--max-events` / `--timeout` fires first wins"

To improve: Specify how to obtain the CLI, its compatible release range, and the environment and subscription setup needed to reproduce the sample.

Checkable outcomesCan you tell whether the task succeeded?3/4

Observable readiness and completion criteria are concrete enough to check an integration, although no validation transcript or supplied tests corroborate them.

EVIDENCE
SKILL.md: "`event consume`'s stderr emits a fixed line `[event] ready event_key=<key>`."; "On exit, the last stderr line is `[event] exited — received N event(s) in Xs (reason: ...)`."

To improve: Add an end-to-end validation recipe that triggers a known event and checks NDJSON fields, readiness, warnings, completion reason, and exit code.

Supporting filesDo the supplied scripts and references support the workflow?1/4

Supporting references are explicitly required and indexed, but none were supplied, so their coherence and completeness cannot be assessed.

EVIDENCE
SKILL.md: "| 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) |". Evidence from this reference and the other linked files was not available.

To improve: Include all linked references and the shared prerequisite so their commands, schemas, and lifecycle guidance can be compared with SKILL.md.

Review scope & scoring

Scores describe source evidence: 0 absent or contradicted, 1 weak, 2 incomplete, 3 solid, 4 strong. Supporting files are excluded when not applicable. Instruction skills can demonstrate quality through examples and checkable outcomes without executable tests.

Provisional source score
60/100
Files reviewed
1
Source coverage
skill only
Reviewed
2026-10-08
Rubric
2026-09-25-v3
Assessed version
sha256:0d43a
Latest catalog version
sha256:0d43a

Review limitations

  • Source coverage is skill-only; referenced supporting files and CLI implementation were unavailable.
  • This assessment is static and does not establish runtime success or confirm the documented CLI contracts.

This review does not execute the skill or verify runtime results. Install counts and publisher reputation do not increase the score.

The full skill.

Original instructions from the publisher’s SKILL.md

# 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

```bash
# 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 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`):

```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

| 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) |