im (v1) CRITICAL — 开始前 MUST 先用 Read 工具读取 ,其中包含认证、权限处理 Core Concepts - Message : A single message in a chat, identified by (om xxx). Supports types: text, post, image, file, audio, video, sticker, interactive (card), share chat, share user, merge forward, etc. - Chat : A group chat or P2P conversation, identified by (oc xxx). - Thread : A reply thread under a message, identified by (om xxx or omt xxx). - Reaction : An emoji reaction on a message. - Flag : A bookmark on a message or thread. - Feed Shortcut : A chat pinned to the current user's feed sidebar, identified by (an open chat id for CH…

## Result\\n\\n![diagram](img_v3_xxxx)\\n\\nSee above for details.'\n```\n\n## Preserving Formatting\n\nIf the reply contains multiple lines, code blocks, indentation, tabs, or a lot of escaping, prefer `

im (v1) CRITICAL — 开始前 MUST 先用 Read 工具读取 ,其中包含认证、权限处理 Core Concepts - Message : A single message in a chat, identified by (om xxx). Supports types: text, post, image, file, audio, video, sticker, interactive (card), share chat, share user, merge forward, etc. - Chat : A group chat or P2P conversation, identified by (oc xxx). - Thread : A reply thread under a message, identified by (om xxx or omt xxx). - Reaction : An emoji reaction on a message. - Flag : A bookmark on a message or thread. - Feed Shortcut : A chat pinned to the current user's feed sidebar, identified by (an open chat id for CH…

...'` for either `--markdown` or `--text`.\n\n### When formatting must be preserved\n\nUse `--text` plus `

im (v1) CRITICAL — 开始前 MUST 先用 Read 工具读取 ,其中包含认证、权限处理 Core Concepts - Message : A single message in a chat, identified by (om xxx). Supports types: text, post, image, file, audio, video, sticker, interactive (card), share chat, share user, merge forward, etc. - Chat : A group chat or P2P conversation, identified by (oc xxx). - Thread : A reply thread under a message, identified by (om xxx or omt xxx). - Reaction : An emoji reaction on a message. - Flag : A bookmark on a message or thread. - Feed Shortcut : A chat pinned to the current user's feed sidebar, identified by (an open chat id for CH…

...'`:\n\n```bash\nlark-cli im +messages-reply --message-id om_xxx --text

im (v1) CRITICAL — 开始前 MUST 先用 Read 工具读取 ,其中包含认证、权限处理 Core Concepts - Message : A single message in a chat, identified by (om xxx). Supports types: text, post, image, file, audio, video, sticker, interactive (card), share chat, share user, merge forward, etc. - Chat : A group chat or P2P conversation, identified by (oc xxx). - Thread : A reply thread under a message, identified by (om xxx or omt xxx). - Reaction : An emoji reaction on a message. - Flag : A bookmark on a message or thread. - Feed Shortcut : A chat pinned to the current user's feed sidebar, identified by (an open chat id for CH…

Received\\nI will check this today.\\nOwner: alice'\n```\n\n```bash\nlark-cli im +messages-reply --message-id om_xxx --text

im (v1) CRITICAL — 开始前 MUST 先用 Read 工具读取 ,其中包含认证、权限处理 Core Concepts - Message : A single message in a chat, identified by (om xxx). Supports types: text, post, image, file, audio, video, sticker, interactive (card), share chat, share user, merge forward, etc. - Chat : A group chat or P2P conversation, identified by (oc xxx). - Thread : A reply thread under a message, identified by (om xxx or omt xxx). - Reaction : An emoji reaction on a message. - Flag : A bookmark on a message or thread. - Feed Shortcut : A chat pinned to the current user's feed sidebar, identified by (an open chat id for CH…

```sql\\nselect * from jobs;\\n```'\n```\n\nThis keeps the reply as plain text instead of converting it to a `post`.\n\n## Commands\n\n```bash\n# Reply with a formatted update\nlark-cli im +messages-reply --message-id om_xxx --markdown

im (v1) CRITICAL — 开始前 MUST 先用 Read 工具读取 ,其中包含认证、权限处理 Core Concepts - Message : A single message in a chat, identified by (om xxx). Supports types: text, post, image, file, audio, video, sticker, interactive (card), share chat, share user, merge forward, etc. - Chat : A group chat or P2P conversation, identified by (oc xxx). - Thread : A reply thread under a message, identified by (om xxx or omt xxx). - Reaction : An emoji reaction on a message. - Flag : A bookmark on a message or thread. - Feed Shortcut : A chat pinned to the current user's feed sidebar, identified by (an open chat id for CH…

## Reply\\n\\n- item 1\\n- item 2'\n\n# Reply with a plain one-line message\nlark-cli im +messages-reply --message-id om_xxx --text \"Received\"\n\n# Read Markdown from a local file\nlark-cli im +messages-reply --message-id om_xxx --markdown @./reply.md\n\n# Equivalent manual JSON\nlark-cli im +messages-reply --message-id om_xxx --content '{\"text\":\"Received\"}'\n\n# Reply as a bot\nlark-cli im +messages-reply --message-id om_xxx --text \"bot reply\" --as bot\n\n# Reply with preserved multi-line text\nlark-cli im +messages-reply --message-id om_xxx --text

im (v1) CRITICAL — 开始前 MUST 先用 Read 工具读取 ,其中包含认证、权限处理 Core Concepts - Message : A single message in a chat, identified by (om xxx). Supports types: text, post, image, file, audio, video, sticker, interactive (card), share chat, share user, merge forward, etc. - Chat : A group chat or P2P conversation, identified by (oc xxx). - Thread : A reply thread under a message, identified by (om xxx or omt xxx). - Reaction : An emoji reaction on a message. - Flag : A bookmark on a message or thread. - Feed Shortcut : A chat pinned to the current user's feed sidebar, identified by (an open chat id for CH…

Line 1\\nLine 2\\n indented line'\n\n# Reply inside the thread (message appears in the target thread)\nlark-cli im +messages-reply --message-id om_xxx --text \"Let's discuss this\" --reply-in-thread\n\n# Reply with Markdown containing an image (must pre-upload via images.create)\nlark-cli im images create --data '{\"image_type\":\"message\"}' --file ./screenshot.png\n# Use the returned image_key\nlark-cli im +messages-reply --message-id om_xxx --markdown

im (v1) CRITICAL — 开始前 MUST 先用 Read 工具读取 ,其中包含认证、权限处理 Core Concepts - Message : A single message in a chat, identified by (om xxx). Supports types: text, post, image, file, audio, video, sticker, interactive (card), share chat, share user, merge forward, etc. - Chat : A group chat or P2P conversation, identified by (oc xxx). - Thread : A reply thread under a message, identified by (om xxx or omt xxx). - Reaction : An emoji reaction on a message. - Flag : A bookmark on a message or thread. - Feed Shortcut : A chat pinned to the current user's feed sidebar, identified by (an open chat id for CH…

## Screenshot\\n\\n![screenshot](img_v3_xxxx)\\n\\nConfirmed.'\n\n# If you need exact post structure, send JSON directly\nlark-cli im +messages-reply --message-id om_xxx --msg-type post --content '{\"zh_cn\":{\"title\":\"Reply\",\"content\":[[{\"tag\":\"text\",\"text\":\"Detailed content\"}]]}}'\n\n# Reply with a local image (uploaded automatically before sending)\nlark-cli im +messages-reply --message-id om_xxx --image ./photo.png\n\n# Reply with a local file (uploaded automatically before sending)\nlark-cli im +messages-reply --message-id om_xxx --file ./report.pdf\n\n# Reply with a local video (--video-cover is required as the video cover)\nlark-cli im +messages-reply --message-id om_xxx --video ./demo.mp4 --video-cover ./cover.png\n\n# Reply with a voice message\nlark-cli im +messages-reply --message-id om_xxx --audio ./voice.opus\n\n# With an idempotency key\nlark-cli im +messages-reply --message-id om_xxx --text \"Received\" --idempotency-key my-unique-id\n\n# Preview the request without executing it\nlark-cli im +messages-reply --message-id om_xxx --markdown

im (v1) CRITICAL — 开始前 MUST 先用 Read 工具读取 ,其中包含认证、权限处理 Core Concepts - Message : A single message in a chat, identified by (om xxx). Supports types: text, post, image, file, audio, video, sticker, interactive (card), share chat, share user, merge forward, etc. - Chat : A group chat or P2P conversation, identified by (oc xxx). - Thread : A reply thread under a message, identified by (om xxx or omt xxx). - Reaction : An emoji reaction on a message. - Flag : A bookmark on a message or thread. - Feed Shortcut : A chat pinned to the current user's feed sidebar, identified by (an open chat id for CH…

## Test\\n\\nhello' --dry-run\n\n# ===== Interactive Card =====\n# 🚫 STOP — before constructing ANY interactive card JSON, you MUST read\n# card/lark-im-card-create.md and follow its workflow. Do NOT\n# hand-write or copy a card payload. The JSON passed to --content must be\n# the OUTPUT of that workflow. This is non-negotiable.\n\n# Once the workflow has produced the card JSON, reply with it:\nlark-cli im +messages-reply --message-id om_xxx --msg-type interactive --content '\u003ccard_json_from_workflow>'\n```\n\n## Media Input Rules\n\n- Media flags accept an existing key (`img_xxx` / `file_xxx`), an `http://` or `https://` URL, or a local file path.\n- Local paths must be relative to the current working directory and stay within it after resolving `..` and symlinks.\n- Absolute paths such as `/tmp/photo.png` are rejected. Run the command from the file's directory and pass `./photo.png`, or copy the file into the current directory first.\n- `--audio` sends a voice message and accepts only Opus audio (`.opus` or Ogg Opus `.ogg`) for local paths and URLs. For `mp3`, `wav`, or other non-Opus audio, convert to `.opus` before using `--audio`, or use `--file` to send the original audio as an attachment.\n\n## Parameters\n\n| Parameter | Required | Description |\n|------|------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `--message-id \u003cid>` | Yes | ID of the message being replied to (`om_xxx`) |\n| `--msg-type \u003ctype>` | No | Message type (default `text`). If you use `--text` / `--markdown` / media flags, the effective type is inferred automatically. Explicitly setting a conflicting `--msg-type` fails validation |\n| `--content \u003cjson>` | One content option | Exact reply content as JSON. The JSON must match the effective `--msg-type` |\n| `--text \u003cstring>` | One content option | Plain text reply. Use when exact text and formatting preservation matter |\n| `--markdown \u003cstring>` | One content option | Best default for lightweight formatted replies such as headings, lists, links, summaries, and investigation notes. Internally converted to `post` JSON with Feishu-specific normalization |\n| `--image \u003cpath\\|url\\|key>` | One content option | Cwd-relative local image path, URL, or `image_key` (`img_xxx`) |\n| `--file \u003cpath\\|url\\|key>` | One content option | Cwd-relative local file path, URL, or `file_key` (`file_xxx`) |\n| `--video \u003cpath\\|url\\|key>` | One content option | Cwd-relative local video path, URL, or `file_key` (`file_xxx`); **must be used together with `--video-cover`** |\n| `--video-cover \u003cpath\\|url\\|key>` | **Required with `--video`** | Cwd-relative local cover image path, URL, or `image_key` (`img_xxx`) |\n| `--audio \u003cpath\\|url\\|key>` | One content option | Voice-message audio key, URL, or cwd-relative local path. Local paths and URLs must be Opus (`.opus` or Ogg Opus `.ogg`) |\n| `--attachment \u003ckey>` | One content option | Repeatable bare file/folder key (`file_xxx`); merges into the post message's attachment zone. Requires a post message (`--markdown` or `--msg-type post`). Name/size/mime/is_folder are filled by the server from file service metadata, not taken from the client. Use this instead of `--file` when the file should render inside a rich-text message's attachment area |\n| `--reply-in-thread` | No | Reply inside the thread. The reply appears in the target message's thread instead of the main chat stream |\n| `--idempotency-key \u003ckey>` | No | Idempotency key, max 50 characters; the same key sends only one reply within 1 hour |\n| `--as \u003cidentity>` | No | Identity type: `bot` or `user` (default `bot`) |\n| `--dry-run` | No | Print the request only, do not execute it |\n\n> **Mutual exclusivity rule:** `--text`, `--markdown`, `--content`, and `--image`/`--file`/`--video`/`--audio` cannot be used together. Media flags are also mutually exclusive with each other.\n>\n> **Video cover rule:** `--video` **must** be accompanied by `--video-cover`. Omitting `--video-cover` when using `--video` will fail validation. `--video-cover` cannot be used without `--video`.\n\n## Common Mistakes\n\n- Choosing `--text` for headings, lists, links, summaries, or investigation notes. Use `--markdown`.\n- Choosing `--markdown` when you actually need exact plain text. If exact line breaks, spacing, logs, code, or literal Markdown characters matter, use `--text`, usually with `

im (v1) CRITICAL — 开始前 MUST 先用 Read 工具读取 ,其中包含认证、权限处理 Core Concepts - Message : A single message in a chat, identified by (om xxx). Supports types: text, post, image, file, audio, video, sticker, interactive (card), share chat, share user, merge forward, etc. - Chat : A group chat or P2P conversation, identified by (oc xxx). - Thread : A reply thread under a message, identified by (om xxx or omt xxx). - Reaction : An emoji reaction on a message. - Flag : A bookmark on a message or thread. - Feed Shortcut : A chat pinned to the current user's feed sidebar, identified by (an open chat id for CH…

...'`.\n- Assuming `--markdown` supports every Markdown feature. It is converted into a Feishu `post` payload and normalized first.\n- Putting local image paths inside Markdown like `![x](./a.png)`. `--markdown` does not auto-upload those paths.\n- **Using local file paths inside Markdown image syntax** (e.g. `![x](./a.png)`) with `--markdown`. Local paths are not auto-uploaded and will not render as an image. Pre-upload via `images.create` to get an `image_key` instead.\n- Using `--content` without making the JSON match the effective `--msg-type`.\n- Explicitly setting `--msg-type` to something that conflicts with `--text`, `--markdown`, or media flags.\n- Mixing `--text`, `--markdown`, or `--content` with media flags in one command.\n- Using `--attachment` with `--text` or a media flag. The attachment zone only exists on `post` messages — pair `--attachment` with `--markdown` or `--msg-type post`.\n\n## Return Value\n\n```json\n{\n \"message_id\": \"om_xxx\",\n \"chat_id\": \"oc_xxx\",\n \"create_time\": \"1234567890\"\n}\n```\n\n## Usage Scenarios\n\n### Scenario 1: Reply in the main chat stream\n\n```bash\nlark-cli im +messages-reply --message-id om_xxx --text \"OK, I will handle it\"\n```\n\nThe reply appears in the main chat stream and references the target message.\n\n### Scenario 2: Reply inside a thread\n\n```bash\nlark-cli im +messages-reply --message-id om_xxx --text \"Let me take a look at this\" --reply-in-thread\n```\n\nThe reply appears in the target message's thread and does not show up in the main chat stream.\n\n## @Mention Format\n\nThe `\u003cat>` syntax differs by message type. The shortcut only normalizes mentions for `text` and `post`; `interactive` card content is passed through verbatim, so cards must use the card-native syntax below.\n\n### `text`\n\n- `\u003cat user_id=\"ou_xxx\">name\u003c/at>` — the inner text is the mentioned user's display name and is optional (`\u003cat user_id=\"ou_xxx\">\u003c/at>` also works)\n- @all: `\u003cat user_id=\"all\">\u003c/at>`\n\n### `post`\n\n- Inside a `text` or `md` element, the same inline form as `text` works: `\u003cat user_id=\"ou_xxx\">name\u003c/at>`\n- Or use a dedicated `at` element node: `{\"tag\":\"at\",\"user_id\":\"ou_xxx\"}` (use `\"all\"` to mention everyone)\n\n### `interactive` (card)\n\nCard content is **not** normalized — use the card-native `\u003cat>` syntax inside a `lark_md` / `markdown` element:\n\n- single user by open_id: `\u003cat id=ou_xxx>\u003c/at>`\n- multiple users: `\u003cat ids=ou_xxx1,ou_xxx2>\u003c/at>`\n- by email: `\u003cat [email protected]>\u003c/at>`\n\n## Notes\n\n- `--message-id` must be a valid message ID in `om_xxx` format\n- `--content` must be valid JSON\n- When using `--content`, you are responsible for making the JSON structure match the effective `msg_type`\n- `--reply-in-thread` adds `reply_in_thread=true` to the API request\n- `--reply-in-thread` is mainly meaningful in chats that support thread replies\n- `--image`/`--file`/`--video`/`--audio`/`--video-cover` support existing keys, URLs, and cwd-relative local file paths; the shortcut uploads local paths and URLs first, then sends the reply; both the upload and send steps use the same identity (UAT when `--as user`, TAT when `--as bot`)\n- If the provided media value starts with `img_` or `file_`, it is treated as an existing key and used directly\n- `--markdown` always sends `msg_type=post`\n- If you explicitly set `--msg-type` and it conflicts with the chosen content flag, validation fails\n- When using `--video`, `--video-cover` is required as the video cover\n- `--dry-run` uses placeholder image keys for remote Markdown images and placeholder media keys for local uploads\n- Failures return error codes and messages\n- `--as user` uses a user access token (UAT) and requires the `im:message.send_as_user` and `im:message` scopes; the reply is sent as the authorized end user\n- `--as bot` uses a tenant access token (TAT), and requires the `im:message:send_as_bot` scope\n- When using `--markdown` with images, pre-uploading via `images.create` to obtain an `image_key` is recommended for reliability; remote URLs may be auto-resolved at runtime, but if download/upload fails the image is removed with a warning; local paths are not supported\n- **Interactive cards are gated:** you MUST read and follow the [`card/lark-im-card-create.md`](card/lark-im-card-create.md) workflow to produce the card JSON *before* replying. Do not hand-write or copy a card payload — the JSON given to `--msg-type interactive --content` must be the workflow's output. This applies every time, with no exception\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":17470,"content_sha256":"d9a17f506348feccf523646a039cbfe2532f8a45a2ea9854d9aae3eb8c223e84"},{"filename":"references/lark-im-messages-resources-download.md","content":"# im +messages-resources-download\n\n> **Prerequisite:** Read [`../../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) first to understand authentication, global parameters, and safety rules.\n\nDownload an image or file attached to a message. Use the `message_id` and resource key returned by a message-reading command; do not guess or combine identifiers from different messages.\n\n> **Note:** read-only message commands render resource keys in message content, but they do not download binaries automatically. Use this command whenever you need to fetch the actual image/file bytes or save them to a specific path.\n\nShortcut: `lark-cli im +messages-resources-download`.\n\n## Commands\n\n```bash\n# Download an image (save to the current directory)\nlark-cli im +messages-resources-download --message-id om_xxx --file-key img_v3_xxx --type image\n\n# Download a file\nlark-cli im +messages-resources-download --message-id om_xxx --file-key file_v3_xxx --type file\n\n# Specify the output path\nlark-cli im +messages-resources-download --message-id om_xxx --file-key img_v3_xxx --type image --output ./photo.png\n\n# Download as a bot\nlark-cli im +messages-resources-download --message-id om_xxx --file-key img_v3_xxx --type image --as bot\n\n# Preview the request without executing it\nlark-cli im +messages-resources-download --message-id om_xxx --file-key img_v3_xxx --type image --dry-run\n```\n\n## Parameters\n\n| Parameter | Required | Description |\n|------|------|------|\n| `--message-id \u003cid>` | Yes | Message ID (`om_xxx` format) |\n| `--file-key \u003ckey>` | Yes | Resource key (`img_xxx` or `file_xxx`) |\n| `--type \u003ctype>` | Yes | Resource type: `image` or `file` |\n| `--output \u003cpath>` | No | Output path, relative or absolute, that must resolve inside the built-in allowed roots (the working directory, `/tmp`, `~/files`); system and credential directories stay refused. When omitted, the command uses the attachment name when available and otherwise falls back to the resource key |\n| `--as \u003cidentity>` | No | Identity type: `user` (default) or `bot` |\n| `--dry-run` | No | Print the request only, do not execute it |\n\n## Choose `--type`\n\nDifferent resource markers in message content correspond to different `file_key` and `type` values:\n\n| Message Type | Marker in Content | `file_key` Format | `--type` |\n|---------|-------------|---------------|--------|\n| Image | `img_xxx` | `img_xxx` | `image` |\n| File | `file_xxx` | `file_xxx` | `file` |\n| Audio | `file_xxx` | `file_xxx` | `file` |\n| Video | `file_xxx` | `file_xxx` | `file` |\n\nStickers cannot be downloaded with this command.\n\nA folder itself cannot be downloaded: expand it with `lark-cli im files folder --recursive` first (see [lark-im](../SKILL.md)), then download the files it contains.\n\n## Output\n\nOn success, read:\n\n| Field | Meaning |\n|------|---------|\n| `data.saved_path` | Saved local path |\n| `data.size_bytes` | Saved byte count |\n\n## Usage Scenario\n\n### Scenario: Extract and download an image from a message\n\n```bash\n# Step 1: Fetch messages and find one containing an image\nlark-cli im +chat-messages-list --chat-id oc_xxx\n# In the response you see: { \"msg_type\": \"image\", \"content\": \"{\\\"image_key\\\":\\\"img_v3_xxx\\\"}\" }\n\n# Step 2: Download the image\nlark-cli im +messages-resources-download --message-id om_xxx --file-key img_v3_xxx --type image\n```\n\n## Common Errors and Troubleshooting\n\n| Symptom | Root Cause | Solution |\n|---------|---------|---------|\n| Resource does not match the message | `file_key` and `message_id` came from different messages | Read the message again and use its matching identifiers |\n| Permission denied | `im:message:readonly` is not authorized | For user identity, run `lark-cli auth login --scope \"im:message:readonly\"`; for bot identity, grant the scope to the app in the developer console |\n| Attachment unavailable | The message or resource is deleted, hidden, restricted, or inaccessible to the caller | Do not retry unchanged; report the exact CLI error |\n| Retryable network error | The transfer did not complete | Retry the same command |\n\n## References\n\n- [lark-im](../SKILL.md) - all message-related commands\n- [lark-shared](../../lark-shared/SKILL.md) - authentication and global parameters\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":4195,"content_sha256":"409e1d9a166db0adffd8dafa1978b915c266405b5c5d5dc93ed03b778b1b83e1"},{"filename":"references/lark-im-messages-search.md","content":"# im +messages-search\n\n> **Prerequisite:** Read [`../../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) first to understand authentication, global parameters, and safety rules.\n\nSearch Feishu messages across conversations. This shortcut automatically performs a multi-step workflow: search for message IDs, batch fetch message details, then enrich the results with chat context.\n\nBy default each result message also carries a `reactions` block (counts + details from `im.reactions.batch_query`) when the server has reactions for it, and `update_time` for messages that were actually edited. With `--page-all`, every page is enriched; pass `--no-reactions` to skip the extra round-trip. See [message enrichment](lark-im-message-enrichment.md) for the full contract.\n\nThis skill maps to the shortcut: `lark-cli im +messages-search` (internally calls `POST /open-apis/im/v1/messages/search` + batched `GET /open-apis/im/v1/messages/mget`, then batch-fetches chat context).\n\n## Commands\n\n```bash\n# Search by keyword\nlark-cli im +messages-search --query \"project progress\"\n\n# Restrict search to a specific group chat\nlark-cli im +messages-search --query \"weekly report\" --chat-id oc_xxx\n\n# Filter by sender (comma-separated)\nlark-cli im +messages-search --query \"requirement\" --sender ou_xxx,ou_yyy\n\n# Filter by attachment type\nlark-cli im +messages-search --query \"report\" --include-attachment-type file\n\n# Filter by chat type (group / p2p)\nlark-cli im +messages-search --query \"progress\" --chat-type group\n\n# Filter by sender type (user / bot)\nlark-cli im +messages-search --query \"reminder\" --sender-type bot\n\n# Exclude bot senders\nlark-cli im +messages-search --query \"reminder\" --exclude-sender-type bot\n\n# Only messages that @me\nlark-cli im +messages-search --query \"announcement\" --is-at-me\n\n# Only messages that @mention specific users (results also include messages that @all)\nlark-cli im +messages-search --query \"release\" --at-chatter-ids ou_xxx,ou_yyy\n\n# Combined filters + time range\nlark-cli im +messages-search --query \"meeting\" --sender ou_xxx --chat-type group --start \"2026-03-13T00:00:00+08:00\" --end \"2026-03-20T23:59:59+08:00\"\n\n# Specific time range (ISO 8601)\nlark-cli im +messages-search --query \"release\" --start \"2026-03-01T00:00:00+08:00\" --end \"2026-03-10T00:00:00+08:00\"\n\n# Output format options\nlark-cli im +messages-search --query \"test\" --format pretty\nlark-cli im +messages-search --query \"test\" --format table\nlark-cli im +messages-search --query \"test\" --format csv\n\n# Pagination\nlark-cli im +messages-search --query \"test\" --page-token \u003cPAGE_TOKEN>\n\n# Auto-pagination across multiple pages\nlark-cli im +messages-search --query \"test\" --page-all --format json\n\n# Auto-pagination with an explicit page cap\nlark-cli im +messages-search --query \"test\" --page-limit 5 --format json\n\n# Preview the request without executing it\nlark-cli im +messages-search --query \"test\" --dry-run\n```\n\n## Parameters\n\n| Parameter | Required | Description |\n|------|------|------|\n| `--query \u003ctext>` | No | Search keyword (may be empty when used with other filters) |\n| `--chat-id \u003cid>` | No | Restrict to chat IDs, comma-separated (`oc_xxx,oc_yyy`) |\n| `--sender \u003cids>` | No | Sender open_ids, comma-separated (`ou_xxx`) |\n| `--include-attachment-type \u003ctype>` | No | Attachment filter: `file` / `image` / `video` / `link` |\n| `--chat-type \u003ctype>` | No | Chat type: `group` / `p2p` |\n| `--sender-type \u003ctype>` | No | Sender type: `user` / `bot` |\n| `--exclude-sender-type \u003ctype>` | No | Exclude messages from `user` or `bot` senders |\n| `--is-at-me` | No | Only return messages that mention `@me` |\n| `--at-chatter-ids \u003cids>` | No | Filter by @mentioned user open_ids, comma-separated (`ou_xxx,ou_yyy`). Matched results also include messages that `@all` |\n| `--start \u003ctime>` | No | Start time with local timezone offset required (e.g. `2026-03-24T00:00:00+08:00`) |\n| `--end \u003ctime>` | No | End time with local timezone offset required (e.g. `2026-03-25T23:59:59+08:00`) |\n| `--page-size \u003cn>` | No | Page size (default 20, range 1-50) |\n| `--page-token \u003ctoken>` | No | Starting cursor, normally returned by a previous response |\n| `--page-all` | No | Automatically paginate through all result pages (up to 40 pages) |\n| `--page-limit \u003cn>` | No | Max pages to fetch when auto-pagination is enabled (default 20, max 40). Setting it explicitly also enables auto-pagination |\n| `--format \u003cfmt>` | No | Output format: `json` (default) / `pretty` / `table` / `ndjson` / `csv` |\n| `--as \u003cidentity>` | No | Identity type: `user` or `bot` |\n| `--dry-run` | No | Print the request only, do not execute it |\n\n## Core Constraints\n\n### 1. Provide at least one filter whenever possible\n\nAll parameters are optional, but you should usually provide at least one filter (`--query`, `--sender`, `--chat-id`, etc.). Otherwise the search scope may be too broad and return low-signal results.\n\n### 2. Two-step orchestration is automatic\n\nThe shortcut automatically performs:\n\n1. The **search API** returns matching `message_id` values\n2. The **mget API** fetches full message content for those message IDs in batch\n3. Chat context lookup is fetched in batch and attached to each message\n\nThe user does not need to manage the orchestration manually. When search results span multiple pages, the shortcut can also paginate automatically with `--page-all` or `--page-limit`.\n\n### 3. Conversation context is enriched automatically\n\nIn JSON output, each message automatically includes conversation context:\n\n| Field | Description |\n|------|------|\n| `chat_type` | Conversation type: `p2p` / `group` |\n| `chat_name` | Group name (for groups) or the other participant's name (for p2p chats) |\n| `chat_partner` | For p2p only: the other participant's `open_id` and `name` |\n\nIn pretty output, the `chat` column shows the chat name for groups, or `\"p2p\"` for direct messages.\n\nEach message in JSON output contains:\n\n| Field | Description |\n|------|------|\n| `message_id` | Message ID |\n| `msg_type` | Message type: `text`, `image`, `file`, `interactive`, `post`, `audio`, `video`, `system`, etc. |\n| `create_time` | Creation time |\n| `sender` | Sender information (includes `name` for user senders) |\n| `content` | Message content |\n| `chat_id` | ID of the conversation the message belongs to |\n| `deleted` | Whether the message has been recalled (`true` = recalled) |\n| `updated` | Whether the message has been edited after sending |\n| `mentions` | Array of @mentions in the message; each item contains `{id, key, name}`. Present only when the message contains @mentions |\n| `thread_id` | Thread ID (`omt_xxx`) if the message has replies in a thread. Present only when replies exist |\n\n### 4. Pagination behavior\n\n- Default behavior is still **single-page**.\n- `--page-token` is the manual continuation mechanism when you already have a token from a previous response.\n- `--page-all` enables auto-pagination and uses a default cap of **40 pages**.\n- With both flags, auto-pagination starts at `--page-token` and continues from that cursor.\n- `--page-limit \u003cn>` enables auto-pagination with an explicit cap. If you pass `--page-limit` without `--page-all`, auto-pagination is still enabled.\n- When auto-pagination stops because of the configured page cap, the response still includes the last `has_more` / `page_token` so you can continue manually.\n\n### 5. Search results contain follow-up clues\n\nIn JSON output, each message includes `chat_id` and `thread_id` (when present). Use them with other shortcuts for deeper inspection:\n\n```bash\n# View the full message stream for the conversation that contains the search result\nlark-cli im +chat-messages-list --chat-id \u003cchat_id>\n\n# View replies in the thread that contains the search result\nlark-cli im +threads-messages-list --thread \u003cthread_id>\n```\n\n## Resource Rendering\n\nSearch results reuse the same content formatter as other read commands. Image messages are rendered as placeholders such as `![Image](img_xxx)`; `folder` messages in results are expanded one level (see [`lark-im-chat-messages-list`](lark-im-chat-messages-list.md#resource-rendering) for the marker/download contract); resource binaries are **not** downloaded automatically.\n\nUse `im +messages-resources-download` if you need to fetch the underlying image or file bytes from a specific message.\n\n## AI Usage Guidance\n\n### Query boundary for activity review\n\nUse `--query` only for real message keywords. If the user asks for activity review such as \"最近一周我和哪些 Bot 有过交互\" or \"整理我和某人的聊天记录\", and the useful constraints are sender type, chat, person, or time range, keep `--query \"\"` and rely on those filters. Do not put generic instruction words such as \"看看\", \"总结\", \"交互内容\", or \"聊天记录\" into `--query`; those words often over-constrain message search and hide the relevant messages.\n\nThis guidance applies to both user and bot identity. If the user explicitly asks for application/bot identity, run `im +messages-search --as bot`; for named-group history/listing intents where search is not needed, resolving the group with `im +chat-search --as bot` and listing messages with `im +chat-messages-list --as bot --chat-id \u003cchat_id>` is still a good narrower path.\n\n```bash\n# Review recent bot interactions without forcing a keyword\nlark-cli im +messages-search --query \"\" --sender-type bot --start \"\u003cYYYY-MM-DDT00:00:00+08:00>\" --end \"\u003cYYYY-MM-DDT23:59:59+08:00>\" --page-all --format json\n```\n\nReplace the time placeholders at execution time. For example, \"最近一周\" means computing the start date and end date from the current day before running the command; do not copy date literals from this reference into answers for relative requests.\n\nFor activity summaries, validate evidence by message IDs and chat context. The final answer should cite or retain the `message_id`, sender, chat, and create time for each important item. If the row's source data contains concrete `om_...` message IDs or `ou_...` user IDs, treat those IDs as strong recall targets during verification; do not rely only on a high-level keyword match.\n\n### Resolving chat_id from a chat name\n\nWhen the user refers to a chat by name and you need its `chat_id` for the `--chat-id` filter, use [`+chat-search`](lark-im-chat-search.md) first:\n\n```bash\n# Step 1: Find the chat_id by name\nlark-cli im +chat-search --query \"\u003cchat name keyword>\" --format json\n\n# Step 2: Use the chat_id to narrow down message search\nlark-cli im +messages-search --query \"keyword\" --chat-id \u003cchat_id>\n```\n\n**Do not use `im chats search` or `+chat-list` — always use the `+chat-search` shortcut.**\n\n## Work Summary / Report Generation\n\nWhen the user asks you to summarize work, generate a weekly report, or compile activity from chat messages, you should **paginate through all available results** to get a complete picture. A single page is rarely enough for thorough summarization.\n\n### Strategy\n\n1. **Start with targeted filters** — use `--chat-id`, `--sender`, `--start`, `--end` to narrow the scope as much as possible before paginating.\n2. **Prefer auto-pagination** — for report and summary tasks, use `--page-all --format json` by default. If you need a bounded run, use `--page-limit \u003cn> --format json`.\n3. **Accumulate before summarizing** — collect all pages of messages first, then analyze and summarize. Do not summarize after the first page alone — you will miss important context.\n4. **Fall back to `--page-token` when resuming** — if auto-pagination hits the configured page cap and the response still has `has_more=true`, continue from the returned `page_token`.\n5. **Use `--format json`** — JSON output includes `has_more` and `page_token` fields needed for pagination. `pretty` and `table` formats are useful for reading but not for resuming pagination reliably.\n\n### Example: Weekly work summary from a project chat\n\n```bash\n# Preferred: fetch automatically\nlark-cli im +messages-search --query \"\" --chat-id oc_xxx --sender ou_me --start \"2026-03-18T00:00:00+08:00\" --end \"2026-03-25T23:59:59+08:00\" --page-size 50 --page-all --format json\n\n# If you need to cap the run explicitly\nlark-cli im +messages-search --query \"\" --chat-id oc_xxx --sender ou_me --start \"2026-03-18T00:00:00+08:00\" --end \"2026-03-25T23:59:59+08:00\" --page-size 50 --page-limit 5 --format json\n\n# If the bounded run still returns has_more=true, continue manually\nlark-cli im +messages-search --query \"\" --chat-id oc_xxx --sender ou_me --start \"2026-03-18T00:00:00+08:00\" --end \"2026-03-25T23:59:59+08:00\" --page-size 50 --page-token \u003ctoken_from_previous_run> --format json\n```\n\n### Key points\n\n- **Always paginate exhaustively** for summary tasks. A single page of 20-50 messages is usually insufficient for a meaningful work summary.\n- Prefer `--page-all`; use `--page-limit` only when you need to bound runtime or output volume.\n- If the user does not specify a time range, default to the current week (Monday to today) for weekly reports, or ask for clarification.\n- When summarizing, group messages by topic/thread rather than by chronological order for better readability.\n\n## Common Errors and Troubleshooting\n\n| Symptom | Root Cause | Solution |\n|---------|---------|---------|\n| Too few results | The time range is too narrow or the keyword is too specific | Expand the time range and try broader keywords |\n| No results | Missing permission or no match | Confirm `search:message` is authorized and relax the filters |\n| Permission denied | Search scope not authorized | Run `auth login --scope \"search:message\"` |\n\n## References\n\n- [lark-im](../SKILL.md) - all message-related commands\n- [lark-im-threads-messages-list](lark-im-threads-messages-list.md) - inspect thread replies\n- [lark-shared](../../lark-shared/SKILL.md) - authentication and global parameters\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":13788,"content_sha256":"1ea9af6a3483a64afcb4c951ebf78421cb193c5f4e0f0dbf5b29f709a7217d86"},{"filename":"references/lark-im-messages-send.md","content":"# im +messages-send\n\n> **Prerequisite:** Read [`../../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) first to understand authentication, global parameters, and safety rules.\n\nSend a message to a group chat or a direct message conversation. Supports both user identity (`--as user`) and bot identity (`--as bot`).\n\nThis skill maps to the shortcut: `lark-cli im +messages-send` (internally calls `POST /open-apis/im/v1/messages`).\n\n## Safety Constraints\n\nMessages sent by this tool are visible to other people. Before calling it, you **must** confirm with the user:\n\n1. The recipient (which person or which group)\n2. The message content\n3. The sending identity (user or bot)\n\n**Do not** send messages without explicit user approval.\n\nWhen using `--as bot`, the message is sent in the app's name, so make sure the app has already been added to the target chat.\n\nWhen using `--as user`, the message is sent as the authorized end user and requires the `im:message.send_as_user` and `im:message` scopes.\n\n## Choose The Right Content Flag\n\n### Default Selection Rule For Agents\n\n- Prefer `--markdown` for headings, lists, links, summaries, reports, or Markdown-looking content.\n- Use `--text` for exact plain text: logs, code, indentation-sensitive text, or literal Markdown.\n- Use `--content` for exact `post` JSON, titles, multiple locales, cards, or unsupported structures.\n\n| Need | Recommended flag | Why |\n|------|------|------|\n| Send headings, lists, links, summaries, or reports | `--markdown` | Best default for lightweight formatting; converted to Feishu `post` JSON |\n| Send plain text exactly as written | `--text` | Preserves literal text; no Markdown conversion |\n| Precisely control the final payload | `--content` | You provide the exact JSON for `text` / `post` / `interactive` / `share_*` / media payloads |\n| Send image / file / video / audio | `--image` / `--file` / `--video` / `--audio` | Shortcut uploads URLs, or cwd-relative local files automatically |\n| Attach files/folders to a post message's attachment zone | `--attachment` | Repeatable, as bare `file_key` (`file_xxx`); merges into the post content's `files` array. Requires a post message (`--markdown` or `--msg-type post`). Name/metadata are filled by the server, not the client |\n\n### `--text` vs `--markdown`\n\n- Use `--markdown` for lightweight formatted messages.\n- Use `--text` for exact plain text, especially logs, code, indentation, or Markdown characters that should **not** render.\n- Use `--content` when `--markdown` is not enough, especially if you need exact `post` JSON, a title, multiple locales, cards, or unsupported rich structures.\n\n## What `--markdown` Really Does\n\n`--markdown` accepts Markdown-like input and converts it to the Feishu `post` payload required by the message API.\n\nThe shortcut does all of the following before sending:\n\n1. Forces `msg_type=post`\n2. Resolves remote Markdown images like `![x](https://...)` by downloading and uploading them first\n3. Normalizes the Markdown for Feishu post rendering\n4. Wraps the result as:\n\n```json\n{\"zh_cn\":{\"content\":[[{\"tag\":\"md\",\"text\":\"...\"}]]}}\n```\n\nThis makes `--markdown` the simplest path for lightweight formatted messages.\n\n### Markdown Boundaries\n\n- It does **not** promise full CommonMark / GitHub Flavored Markdown support.\n- It always becomes a `post` payload with a single `zh_cn` locale.\n- It does **not** let you set a `post` title. If you need a title, use `--msg-type post --content ...`.\n- Headings are rewritten:\n - `# Title` becomes `#### Title`\n - `##` to `######` are normalized to `#####` when the content contains H1-H3\n- Consecutive headings are separated with blank lines after heading normalization.\n- Block spacing and line breaks may be normalized during conversion.\n- Code blocks are preserved as code blocks.\n- Excess blank lines are compressed.\n- Already-uploaded `img_xxx` image keys are the most reliable Markdown image input.\n- Local paths in Markdown image syntax like `![x](./a.png)` are **not** supported and will not be auto-uploaded.\n- Remote URLs (`https://...`) will be auto-downloaded and uploaded at runtime; if the download or upload fails, the image is removed with a warning.\n\nIf you need a title, multiple locales, cards, unsupported rich structures, or byte-for-byte post JSON control, use `--content` and provide the final JSON yourself.\n\n### Image Constraint for `--markdown`\n\nWhen using `--markdown` with images, prefer pre-uploading via `images.create` and referencing `![alt](img_xxx)` for predictable results. Remote URLs may work but are not guaranteed.\n\n**Steps:**\n\n```bash\n# 1. Upload image to get image_key\nlark-cli im images create --data '{\"image_type\":\"message\"}' --file ./diagram.png\n# Returns: {\"image_key\":\"img_v3_xxxx\"}\n\n# 2. Use image_key in --markdown\nlark-cli im +messages-send --chat-id oc_xxx --markdown

im (v1) CRITICAL — 开始前 MUST 先用 Read 工具读取 ,其中包含认证、权限处理 Core Concepts - Message : A single message in a chat, identified by (om xxx). Supports types: text, post, image, file, audio, video, sticker, interactive (card), share chat, share user, merge forward, etc. - Chat : A group chat or P2P conversation, identified by (oc xxx). - Thread : A reply thread under a message, identified by (om xxx or omt xxx). - Reaction : An emoji reaction on a message. - Flag : A bookmark on a message or thread. - Feed Shortcut : A chat pinned to the current user's feed sidebar, identified by (an open chat id for CH…

## Report\\n\\n![diagram](img_v3_xxxx)\\n\\nSee above for details.'\n```\n\n## Preserving Formatting\n\nIf the message has multiple lines, indentation, code blocks, tabs, or many quotes/backslashes, prefer shell ANSI-C quoting with `

im (v1) CRITICAL — 开始前 MUST 先用 Read 工具读取 ,其中包含认证、权限处理 Core Concepts - Message : A single message in a chat, identified by (om xxx). Supports types: text, post, image, file, audio, video, sticker, interactive (card), share chat, share user, merge forward, etc. - Chat : A group chat or P2P conversation, identified by (oc xxx). - Thread : A reply thread under a message, identified by (om xxx or omt xxx). - Reaction : An emoji reaction on a message. - Flag : A bookmark on a message or thread. - Feed Shortcut : A chat pinned to the current user's feed sidebar, identified by (an open chat id for CH…

...'` for either `--markdown` or `--text`.\n\nThis is especially useful in `zsh` / `bash` because it lets you write `\\n` explicitly instead of relying on the shell to preserve literal newlines.\n\n### When formatting must be preserved\n\nUse `--text` plus `

im (v1) CRITICAL — 开始前 MUST 先用 Read 工具读取 ,其中包含认证、权限处理 Core Concepts - Message : A single message in a chat, identified by (om xxx). Supports types: text, post, image, file, audio, video, sticker, interactive (card), share chat, share user, merge forward, etc. - Chat : A group chat or P2P conversation, identified by (oc xxx). - Thread : A reply thread under a message, identified by (om xxx or omt xxx). - Reaction : An emoji reaction on a message. - Flag : A bookmark on a message or thread. - Feed Shortcut : A chat pinned to the current user's feed sidebar, identified by (an open chat id for CH…

...'`:\n\n```bash\nlark-cli im +messages-send --chat-id oc_xxx --text

im (v1) CRITICAL — 开始前 MUST 先用 Read 工具读取 ,其中包含认证、权限处理 Core Concepts - Message : A single message in a chat, identified by (om xxx). Supports types: text, post, image, file, audio, video, sticker, interactive (card), share chat, share user, merge forward, etc. - Chat : A group chat or P2P conversation, identified by (oc xxx). - Thread : A reply thread under a message, identified by (om xxx or omt xxx). - Reaction : An emoji reaction on a message. - Flag : A bookmark on a message or thread. - Feed Shortcut : A chat pinned to the current user's feed sidebar, identified by (an open chat id for CH…

Build failed\\nBranch: feature/im-docs\\nAction: please check logs'\n```\n\n```bash\nlark-cli im +messages-send --chat-id oc_xxx --text

im (v1) CRITICAL — 开始前 MUST 先用 Read 工具读取 ,其中包含认证、权限处理 Core Concepts - Message : A single message in a chat, identified by (om xxx). Supports types: text, post, image, file, audio, video, sticker, interactive (card), share chat, share user, merge forward, etc. - Chat : A group chat or P2P conversation, identified by (oc xxx). - Thread : A reply thread under a message, identified by (om xxx or omt xxx). - Reaction : An emoji reaction on a message. - Flag : A bookmark on a message or thread. - Feed Shortcut : A chat pinned to the current user's feed sidebar, identified by (an open chat id for CH…

```bash\\nmake test\\nmake lint\\n```'\n```\n\nUse this path when you want the receiver to see the text exactly as entered, not a converted Markdown post.\n\n## Commands\n\n```bash\n# Send a formatted update\nlark-cli im +messages-send --chat-id oc_xxx --markdown

im (v1) CRITICAL — 开始前 MUST 先用 Read 工具读取 ,其中包含认证、权限处理 Core Concepts - Message : A single message in a chat, identified by (om xxx). Supports types: text, post, image, file, audio, video, sticker, interactive (card), share chat, share user, merge forward, etc. - Chat : A group chat or P2P conversation, identified by (oc xxx). - Thread : A reply thread under a message, identified by (om xxx or omt xxx). - Reaction : An emoji reaction on a message. - Flag : A bookmark on a message or thread. - Feed Shortcut : A chat pinned to the current user's feed sidebar, identified by (an open chat id for CH…

## Update\\n\\n- item 1\\n- item 2'\n\n# Send a plain one-line message\nlark-cli im +messages-send --chat-id oc_xxx --text \"Hello\"\n\n# Read Markdown from a local file\nlark-cli im +messages-send --chat-id oc_xxx --markdown @./update.md\n\n# Equivalent manual JSON\nlark-cli im +messages-send --chat-id oc_xxx --content '{\"text\":\"Hello\"}'\n\n# Send to a direct message (pass open_id)\nlark-cli im +messages-send --user-id ou_xxx --text \"Hello\"\n\n# Send multi-line text while preserving formatting\nlark-cli im +messages-send --chat-id oc_xxx --text

im (v1) CRITICAL — 开始前 MUST 先用 Read 工具读取 ,其中包含认证、权限处理 Core Concepts - Message : A single message in a chat, identified by (om xxx). Supports types: text, post, image, file, audio, video, sticker, interactive (card), share chat, share user, merge forward, etc. - Chat : A group chat or P2P conversation, identified by (oc xxx). - Thread : A reply thread under a message, identified by (om xxx or omt xxx). - Reaction : An emoji reaction on a message. - Flag : A bookmark on a message or thread. - Feed Shortcut : A chat pinned to the current user's feed sidebar, identified by (an open chat id for CH…

Line 1\\nLine 2\\n indented line'\n\n# Send Markdown with an image (must pre-upload via images.create)\nlark-cli im images create --data '{\"image_type\":\"message\"}' --file ./screenshot.png\n# Use the returned image_key in the markdown content\nlark-cli im +messages-send --chat-id oc_xxx --markdown

im (v1) CRITICAL — 开始前 MUST 先用 Read 工具读取 ,其中包含认证、权限处理 Core Concepts - Message : A single message in a chat, identified by (om xxx). Supports types: text, post, image, file, audio, video, sticker, interactive (card), share chat, share user, merge forward, etc. - Chat : A group chat or P2P conversation, identified by (oc xxx). - Thread : A reply thread under a message, identified by (om xxx or omt xxx). - Reaction : An emoji reaction on a message. - Flag : A bookmark on a message or thread. - Feed Shortcut : A chat pinned to the current user's feed sidebar, identified by (an open chat id for CH…

## Status\\n\\n![screenshot](img_v3_xxxx)\\n\\nDone.'\n\n# If you need exact post structure, send JSON directly\nlark-cli im +messages-send --chat-id oc_xxx --msg-type post --content '{\"zh_cn\":{\"title\":\"Title\",\"content\":[[{\"tag\":\"text\",\"text\":\"Body\"}]]}}'\n\n# Send a local image (uploaded automatically before sending)\nlark-cli im +messages-send --chat-id oc_xxx --image ./photo.png\n\n# Or send directly with an existing image_key\nlark-cli im +messages-send --chat-id oc_xxx --image img_xxx\n\n# Send a local file (uploaded automatically before sending)\nlark-cli im +messages-send --chat-id oc_xxx --file ./report.pdf\n\n# Send a video (--video-cover is required as the cover)\nlark-cli im +messages-send --chat-id oc_xxx --video ./demo.mp4 --video-cover ./cover.png\nlark-cli im +messages-send --chat-id oc_xxx --video ./demo.mp4 --video-cover img_xxx\n\n# Send a voice message\nlark-cli im +messages-send --chat-id oc_xxx --audio ./voice.opus\n\n# Use an idempotency key (same key sends only once within 1 hour)\nlark-cli im +messages-send --chat-id oc_xxx --text \"Hello\" --idempotency-key my-unique-id\n\n# Preview the request without executing it\nlark-cli im +messages-send --chat-id oc_xxx --markdown

im (v1) CRITICAL — 开始前 MUST 先用 Read 工具读取 ,其中包含认证、权限处理 Core Concepts - Message : A single message in a chat, identified by (om xxx). Supports types: text, post, image, file, audio, video, sticker, interactive (card), share chat, share user, merge forward, etc. - Chat : A group chat or P2P conversation, identified by (oc xxx). - Thread : A reply thread under a message, identified by (om xxx or omt xxx). - Reaction : An emoji reaction on a message. - Flag : A bookmark on a message or thread. - Feed Shortcut : A chat pinned to the current user's feed sidebar, identified by (an open chat id for CH…

## Test\\n\\nhello' --dry-run\n\n# ===== Interactive Card =====\n# 🚫 STOP — before constructing ANY interactive card JSON, you MUST read\n# card/lark-im-card-create.md and follow its workflow. Do NOT\n# hand-write or copy a card payload from the examples below. The JSON passed\n# to --content must be the OUTPUT of that workflow. This is non-negotiable.\n\n# Once the workflow has produced the card JSON, send it:\nlark-cli im +messages-send --chat-id oc_xxx --msg-type interactive --content '\u003ccard_json_from_workflow>'\n```\n\n## Media Input Rules\n\n- Media flags accept an existing key (`img_xxx` / `file_xxx`), an `http://` or `https://` URL, or a local file path.\n- Local paths must be relative to the current working directory and stay within it after resolving `..` and symlinks.\n- Absolute paths such as `/tmp/photo.png` are rejected. Run the command from the file's directory and pass `./photo.png`, or copy the file into the current directory first.\n- `--audio` sends a voice message and accepts only Opus audio (`.opus` or Ogg Opus `.ogg`) for local paths and URLs. For `mp3`, `wav`, or other non-Opus audio, convert to `.opus` before using `--audio`, or use `--file` to send the original audio as an attachment.\n\n## Parameters\n\n| Parameter | Required | Description |\n|------|------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `--chat-id \u003cid>` | One of two | Group chat ID (`oc_xxx`) |\n| `--user-id \u003cid>` | One of two | User open_id (`ou_xxx`) for direct messages |\n| `--text \u003cstring>` | One content option | Plain text message. Use when exact text and formatting preservation matter. Automatically wrapped as `{\"text\":\"...\"}` |\n| `--markdown \u003cstring>` | One content option | Best default for lightweight formatted messages such as headings, lists, links, summaries, and reports. Internally converted to `post` JSON with Feishu-specific normalization |\n| `--content \u003cjson>` | One content option | Exact message content JSON string; use this when you need full control over `msg_type` and payload. The JSON must match the effective `--msg-type` |\n| `--image \u003cpath\\|url\\|key>` | One content option | Cwd-relative local image path, URL, or `image_key` (`img_xxx`). Local paths and URLs are uploaded automatically |\n| `--file \u003cpath\\|url\\|key>` | One content option | Cwd-relative local file path, URL, or `file_key` (`file_xxx`). Local paths and URLs are uploaded automatically |\n| `--video \u003cpath\\|url\\|key>` | One content option | Cwd-relative local video path, URL, or `file_key` (`file_xxx`). Local paths and URLs are uploaded automatically. **Must be paired with `--video-cover`** |\n| `--video-cover \u003cpath\\|url\\|key>` | **Required with `--video`** | Cwd-relative local cover image path, URL, or `image_key` (`img_xxx`). Local paths and URLs are uploaded automatically |\n| `--audio \u003cpath\\|url\\|key>` | One content option | Voice-message audio key, URL, or cwd-relative local path. Local paths and URLs must be Opus (`.opus` or Ogg Opus `.ogg`) |\n| `--attachment \u003ckey>` | One content option | Repeatable bare file/folder key (`file_xxx`); merges into the post message's attachment zone. Requires a post message (`--markdown` or `--msg-type post`). Name/size/mime/is_folder are filled by the server from file service metadata, not taken from the client. Use this instead of `--file` when the file should render inside a rich-text message's attachment area |\n| `--msg-type \u003ctype>` | No | Message type (default `text`). If you use `--text` / `--markdown` / media flags, the effective type is inferred automatically. Explicitly setting a conflicting `--msg-type` fails validation |\n| `--idempotency-key \u003ckey>` | No | Idempotency key, max 50 characters; the same key sends only one message within 1 hour |\n| `--as \u003cidentity>` | No | Identity type: `bot` or `user` (default `bot`) |\n| `--dry-run` | No | Print the request only, do not execute it |\n\n> **Mutual exclusivity rule:** `--text`, `--markdown`, `--content`, and `--image`/`--file`/`--video`/`--audio` cannot be used together. Media flags are also mutually exclusive with each other. `--attachment` cannot be combined with a `--content` that already contains a `files` array (the attachment zone is declared either via `--content` or via `--attachment`, not both).\n>\n> **Video cover rule:** `--video` **must** be accompanied by `--video-cover`. Omitting `--video-cover` when using `--video` will fail validation. `--video-cover` cannot be used without `--video`.\n\n## Common Mistakes\n\n- Choosing `--text` for headings, lists, links, summaries, or reports. Use `--markdown`.\n- Choosing `--markdown` when you actually need exact plain text. If exact line breaks, spacing, logs, code, or literal Markdown characters matter, use `--text`, usually with `

im (v1) CRITICAL — 开始前 MUST 先用 Read 工具读取 ,其中包含认证、权限处理 Core Concepts - Message : A single message in a chat, identified by (om xxx). Supports types: text, post, image, file, audio, video, sticker, interactive (card), share chat, share user, merge forward, etc. - Chat : A group chat or P2P conversation, identified by (oc xxx). - Thread : A reply thread under a message, identified by (om xxx or omt xxx). - Reaction : An emoji reaction on a message. - Flag : A bookmark on a message or thread. - Feed Shortcut : A chat pinned to the current user's feed sidebar, identified by (an open chat id for CH…

...'`.\n- Assuming `--markdown` supports every Markdown feature. It is converted into a Feishu `post` payload and normalized first.\n- Putting local image paths inside Markdown like `![x](./a.png)`. `--markdown` does not auto-upload those paths.\n- **Using local file paths inside Markdown image syntax** (e.g. `![x](./a.png)`) with `--markdown`. Local paths are not auto-uploaded and will not render as an image. Pre-upload via `images.create` to get an `image_key` instead.\n- Using `--content` without making the JSON match the effective `--msg-type`.\n- Explicitly setting `--msg-type` to something that conflicts with `--text`, `--markdown`, or media flags.\n- Mixing `--text`, `--markdown`, or `--content` with media flags in one command.\n- Using `--attachment` with `--text` or a media flag. The attachment zone only exists on `post` messages — pair `--attachment` with `--markdown` or `--msg-type post`.\n- Using `--file` when the file should sit inside a rich-text message's attachment area. `--file` sends a standalone `file`-type message; use `--attachment` (with `--markdown` or post `--content`) to attach files/folders inside a post message.\n\n## `content` Format Reference\n\n| `msg_type` | Example `content` |\n|----------|-------------|\n| `text` | `{\"text\":\"Hello \u003cat user_id=\\\"ou_xxx\\\">name\u003c/at>\"}` |\n| `post` | `{\"zh_cn\":{\"title\":\"Title\",\"content\":[[{\"tag\":\"text\",\"text\":\"Body\"}]]},\"files\":[{\"key\":\"file_xxx\"}]}` — the top-level `files` array is the attachment zone; each entry carries a file/folder `key` (name/metadata are backfilled by the server from file service metadata — a client-supplied `name` has no effect) |\n| `image` | `{\"image_key\":\"img_xxx\"}` |\n| `file` | `{\"file_key\":\"file_xxx\"}` |\n| `audio` | `{\"file_key\":\"file_xxx\"}` |\n| `media` | `{\"file_key\":\"file_xxx\",\"image_key\":\"img_xxx\"}` (video; `image_key` is the cover from `--video-cover` — **required**) |\n| `share_chat` | `{\"chat_id\":\"oc_xxx\"}` |\n| `share_user` | `{\"user_id\":\"ou_xxx\"}` |\n| `interactive` | Card JSON — **MUST** be produced by the [`card/lark-im-card-create.md`](card/lark-im-card-create.md) workflow. Read it before writing any card; never hand-craft the JSON here |\n\n> **`post` vs `interactive`:** `post` is a static rich-text message (title, paragraphs, @mentions, links, inline images) — content is fixed once sent. `interactive` is a card with structured layout and UI components (buttons, forms, selects, date pickers, charts) — content can be updated after sending and supports user-action callbacks. Use `post` for read-only content; use `interactive` when the message needs user interaction or dynamic updates.\n\n`interactive` cards support callback events (`card.action.trigger`) — see [`lark-im-card-action-reply.md`](lark-im-card-action-reply.md).\n\n## Return Value\n\n```json\n{\n \"message_id\": \"om_xxx\",\n \"chat_id\": \"oc_xxx\",\n \"create_time\": \"1234567890\"\n}\n```\n\n## @Mention Format\n\nThe `\u003cat>` syntax differs by message type. The shortcut only normalizes mentions for `text` and `post`; `interactive` card content is passed through verbatim, so cards must use the card-native syntax below.\n\n### `text`\n\n- `\u003cat user_id=\"ou_xxx\">name\u003c/at>` — the inner text is the mentioned user's display name and is optional (`\u003cat user_id=\"ou_xxx\">\u003c/at>` also works)\n- @all: `\u003cat user_id=\"all\">\u003c/at>`\n\n### `post`\n\n- Inside a `text` or `md` element, the same inline form as `text` works: `\u003cat user_id=\"ou_xxx\">name\u003c/at>`\n- Or use a dedicated `at` element node: `{\"tag\":\"at\",\"user_id\":\"ou_xxx\"}` (use `\"all\"` to mention everyone)\n\n### `interactive` (card)\n\nCard content is **not** normalized — use the card-native `\u003cat>` syntax inside a `lark_md` / `markdown` element:\n\n- single user by open_id: `\u003cat id=ou_xxx>\u003c/at>`\n- multiple users: `\u003cat ids=ou_xxx1,ou_xxx2>\u003c/at>`\n- by email: `\u003cat [email protected]>\u003c/at>`\n\n## Notes\n\n- `--chat-id` and `--user-id` are mutually exclusive; you must provide exactly one\n- `--content` must be valid JSON\n- When using `--content`, you are responsible for making the JSON structure match the effective `msg_type`\n- `--image`/`--file`/`--video`/`--audio` support existing keys, URLs, and cwd-relative local file paths; the shortcut uploads local paths and URLs first, then sends the message; both the upload and send steps use the same identity (UAT when `--as user`, TAT when `--as bot`)\n- If the provided media value starts with `img_` or `file_`, it is treated as an existing key and used directly\n- `--markdown` always sends `msg_type=post`, even if you do not explicitly set `--msg-type post`\n- If you explicitly set `--msg-type` and it conflicts with the chosen content flag, validation fails\n- When using `--video`, `--video-cover` is required as the video cover\n- `--dry-run` uses placeholder image keys for remote Markdown images and placeholder media keys for local uploads\n- Failures return an error code and message\n- `--as user` uses a user access token (UAT) and requires the `im:message.send_as_user` and `im:message` scopes; the message is sent as the authorized end user\n- `--as bot` uses a tenant access token (TAT) and requires the `im:message:send_as_bot` scope\n- When sending as a bot, the app must already be in the target group or already have a direct-message relationship with the target user\n- When using `--markdown` with images, pre-uploading via `images.create` to obtain an `image_key` is recommended for reliability; remote URLs may be auto-resolved at runtime, but if download/upload fails the image is removed with a warning; local paths are not supported\n- **Interactive cards are gated:** you MUST read and follow the [`card/lark-im-card-create.md`](card/lark-im-card-create.md) workflow to produce the card JSON *before* sending. Do not hand-write or copy a card payload — the JSON given to `--msg-type interactive --content` must be the workflow's output. This applies every time, with no exception\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":19799,"content_sha256":"8f9bedb2e4b9f9fd016fd94bc57f0d82a3f66d2b167767b6f8fad10028e9cb11"},{"filename":"references/lark-im-reactions.md","content":"# im reactions\n\n> **Prerequisite:** Read [`../../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) first to understand authentication, global parameters, and safety rules.\n\n> **Heads-up — don't reach for `batch_query` by default.** The four message-pulling shortcuts (`+messages-mget`, `+chat-messages-list`, `+messages-search`, `+threads-messages-list`) already call `im.reactions.batch_query` automatically and attach the result as a `reactions` block on each message (replies inside `thread_replies` included). Use those shortcuts for any \"read reactions of messages I'm already pulling\" task. Reach for the raw `batch_query` API only when you have a standalone `message_id` outside that pull flow. See the main [message enrichment](lark-im-message-enrichment.md) for the contract.\n\nThis reference is the shared annotation target for the IM reaction APIs:\n\n- `im.reactions.create`\n- `im.reactions.list`\n- `im.reactions.delete`\n- `im.reactions.batch_query`\n\nIt focuses on:\n\n- What each reaction method does\n- The request/response shape you need when calling the raw API commands\n- The complete `emoji_type` list used in reaction payloads and filters\n\n> **Important:** These raw API commands accept structured input through `--params '\u003cjson>'` and `--data '\u003cjson>'`. They do not expose typed flags such as `--message-id` or `--reaction-type` directly.\n\n## Command Overview\n\n| Method | HTTP | Path | Purpose |\n|---|---|---|---|\n| `im.reactions.create` | `POST` | `/open-apis/im/v1/messages/{message_id}/reactions` | Add a reaction to one message |\n| `im.reactions.list` | `GET` | `/open-apis/im/v1/messages/{message_id}/reactions` | List reaction records on one message |\n| `im.reactions.delete` | `DELETE` | `/open-apis/im/v1/messages/{message_id}/reactions/{reaction_id}` | Delete one specific reaction record |\n| `im.reactions.batch_query` | `POST` | `/open-apis/im/v1/messages/reactions/batch_query` | Query reactions for multiple messages in one request |\n\n## Common Notes\n\n- `message_id` is always an IM message ID such as `om_xxx`\n- `reaction_id` is the unique record ID returned after a reaction is added\n- `reaction_type.emoji_type` is the enum-like emoji identifier used by both write and read APIs\n- Reaction APIs return **reaction records**, not only aggregated counts\n- When the operator is a human user, the returned ID type may depend on `user_id_type`\n\n## Inspect Schema\n\n```bash\nlark-cli schema im.reactions\nlark-cli schema im.reactions.create --format pretty\nlark-cli schema im.reactions.list --format pretty\nlark-cli schema im.reactions.delete --format pretty\n```\n\nIf your local build has already exposed the batch API in `schema`, also check:\n\n```bash\nlark-cli schema im.reactions.batch_query --format pretty\n```\n\n## create\n\nAdd a reaction to one message.\n\n```bash\nlark-cli im reactions create \\\n --params '{\"message_id\":\"om_xxx\"}' \\\n --data '{\"reaction_type\":{\"emoji_type\":\"SMILE\"}}'\n```\n\n### Request\n\n- `--params.message_id`: required message ID\n- `--data.reaction_type.emoji_type`: required emoji type\n\n### Response\n\n```json\n{\n \"reaction_id\": \"ZCaCIjUBVVWSrm5L-3ZTw_xxx\",\n \"operator\": {\n \"operator_id\": \"ou_xxx\",\n \"operator_type\": \"user\"\n },\n \"action_time\": \"1663054162546\",\n \"reaction_type\": {\n \"emoji_type\": \"SMILE\"\n }\n}\n```\n\n## list\n\nList reaction records on one message.\n\n```bash\nlark-cli im reactions list --params '{\"message_id\":\"om_xxx\"}'\nlark-cli im reactions list --params '{\"message_id\":\"om_xxx\",\"reaction_type\":\"SMILE\"}'\nlark-cli im reactions list --params '{\"message_id\":\"om_xxx\",\"page_size\":50}'\nlark-cli im reactions list --params '{\"message_id\":\"om_xxx\",\"page_token\":\"\u003cPAGE_TOKEN>\"}'\nlark-cli im reactions list --params '{\"message_id\":\"om_xxx\",\"user_id_type\":\"open_id\"}'\n```\n\n### Request Parameters (`--params`)\n\n| Parameter | Required | Description |\n|---|---|---|\n| `message_id` | Yes | Message ID (`om_xxx`) |\n| `reaction_type` | No | Filter by one emoji type such as `SMILE` or `LAUGH` |\n| `page_size` | No | Number of records per page. Default is 20 |\n| `page_token` | No | Pagination token from the previous page |\n| `user_id_type` | No | Returned operator ID type when `operator_type=user`: `open_id`, `union_id`, or `user_id` |\n\n### Response Shape\n\n```json\n{\n \"items\": [\n {\n \"reaction_id\": \"ZCaCIjUBVVWSrm5L-3ZTw_xxx\",\n \"operator\": {\n \"operator_id\": \"ou_xxx\",\n \"operator_type\": \"user\"\n },\n \"action_time\": \"1663054162546\",\n \"reaction_type\": {\n \"emoji_type\": \"SMILE\"\n }\n }\n ],\n \"has_more\": true,\n \"page_token\": \"YhljsPiGfUgnVAg9urvRFd-BvSqRLxxxx\"\n}\n```\n\n### Top-Level Fields\n\n| Field | Type | Meaning |\n|---|---|---|\n| `items` | `array\u003cobject>` | Reaction records for the current page |\n| `has_more` | `boolean` | Whether more pages are available |\n| `page_token` | `string` | Token for the next page when `has_more=true` |\n\n### `items[]` Fields\n\n| Field | Type | Meaning |\n|---|---|---|\n| `reaction_id` | `string` | Unique ID of this reaction record |\n| `operator` | `object` | Identity of the user or app that added the reaction |\n| `action_time` | `string` | Unix timestamp in milliseconds |\n| `reaction_type` | `object` | Reaction payload. The key field is `emoji_type` |\n\n### `operator` Fields\n\n| Field | Type | Meaning |\n|---|---|---|\n| `operator.operator_id` | `string` | Operator ID. If `operator_type=user`, the returned ID type follows `user_id_type`; if `operator_type=app`, this is the app ID |\n| `operator.operator_type` | `string` | `user` or `app` |\n\n## delete\n\nDelete one specific reaction record from one message.\n\n```bash\nlark-cli im reactions delete \\\n --params '{\"message_id\":\"om_xxx\",\"reaction_id\":\"ZCaCIjUBVVWSrm5L-3ZTw_xxx\"}'\n```\n\n### Request\n\n- `--params.message_id`: required message ID\n- `--params.reaction_id`: required reaction record ID\n\n### Response\n\nThe response shape is similar to `create`, and usually echoes:\n\n- `reaction_id`\n- `operator`\n- `action_time`\n- `reaction_type.emoji_type`\n\n## batch_query\n\nQuery reactions for multiple messages in one request.\n\n```bash\nlark-cli im reactions batch_query \\\n --params '{\"user_id_type\":\"open_id\"}' \\\n --data '{\n \"queries\":[\n {\"message_id\":\"om_xxx\"},\n {\"message_id\":\"om_yyy\",\"page_token\":\"\u003cPAGE_TOKEN>\"}\n ],\n \"page_size_per_message\":10,\n \"reaction_type\":\"LAUGH\"\n }'\n```\n\n### Request\n\n#### `--params`\n\n| Parameter | Required | Description |\n|---|---|---|\n| `user_id_type` | No | Returned user ID type in operator info: `open_id`, `union_id`, or `user_id` |\n\n#### `--data`\n\n| Field | Required | Description |\n|---|---|---|\n| `queries` | Yes | Array of target messages |\n| `queries[].message_id` | No | Message ID to query |\n| `queries[].page_token` | No | Continuation token for that message |\n| `page_size_per_message` | No | Max reactions returned per message |\n| `reaction_type` | No | Filter by one emoji type |\n\n### Response\n\nThe meta definition contains three top-level result groups:\n\n| Field | Meaning |\n|---|---|\n| `success_msg_reaction_details` | Per-message reaction detail records |\n| `success_msg_reaction_counts` | Per-message aggregated reaction counts |\n| `fail_msg_reaction_details` | Query failures for individual messages |\n\n#### `success_msg_reaction_details`\n\nEach `message_reaction_items[]` element includes:\n\n- `reaction_id`\n- `operator`\n- `action_time`\n- `emoji_type`\n\n#### `success_msg_reaction_counts`\n\nEach aggregated count record includes:\n\n- `message_id`\n- `reaction_count[].reaction_type`\n- `reaction_count[].count`\n\n#### `fail_msg_reaction_details`\n\nEach failed message record includes:\n\n- `message_id`\n- `fail_reason`\n\nSupported `fail_reason` values from meta:\n\n- `invalid`\n- `invalid_page_token`\n- `no_permission`\n\n## `emoji_type` Field\n\nReaction emoji identifiers are used in slightly different field names across the APIs:\n\n- `im.reactions.create`: request and response use `reaction_type.emoji_type`\n- `im.reactions.list`: request filter uses `reaction_type`, response uses `reaction_type.emoji_type`\n- `im.reactions.delete`: response uses `reaction_type.emoji_type`\n- `im.reactions.batch_query`: request filter uses top-level `reaction_type`, detail results use `message_reaction_items[].emoji_type`, aggregated results use `reaction_count[].reaction_type`\n\n## Complete `emoji_type` List\n\nThe following list is synchronized from the official Feishu reaction emoji documentation:\n\n- Source page: `https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message-reaction/emojis-introduce`\n- Markdown source: `https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message-reaction/emojis-introduce.md`\n\nCurrent count in the fetched source: `185`.\n\n```text\nOK, THUMBSUP, THANKS, MUSCLE, FINGERHEART, APPLAUSE, FISTBUMP, JIAYI\nDONE, SMILE, BLUSH, LAUGH, SMIRK, LOL, FACEPALM, LOVE\nWINK, PROUD, WITTY, SMART, SCOWL, THINKING, SOB, CRY\nERROR, NOSEPICK, HAUGHTY, SLAP, SPITBLOOD, TOASTED, GLANCE, DULL\nINNOCENTSMILE, JOYFUL, WOW, TRICK, YEAH, ENOUGH, TEARS, EMBARRASSED\nKISS, SMOOCH, DROOL, OBSESSED, MONEY, TEASE, SHOWOFF, COMFORT\nCLAP, PRAISE, STRIVE, XBLUSH, SILENT, WAVE, WHAT, FROWN\nSHY, DIZZY, LOOKDOWN, CHUCKLE, WAIL, CRAZY, WHIMPER, HUG\nBLUBBER, WRONGED, HUSKY, SHHH, SMUG, ANGRY, HAMMER, SHOCKED\nTERROR, PETRIFIED, SKULL, SWEAT, SPEECHLESS, SLEEP, DROWSY, YAWN\nSICK, PUKE, BETRAYED, HEADSET, EatingFood, MeMeMe, Sigh, Typing\nLemon, Get, LGTM, OnIt, OneSecond, VRHeadset, YouAreTheBest, SALUTE\nSHAKE, HIGHFIVE, UPPERLEFT, ThumbsDown, SLIGHT, TONGUE, EYESCLOSED, RoarForYou\nCALF, BEAR, BULL, RAINBOWPUKE, ROSE, HEART, PARTY, LIPS\nBEER, CAKE, GIFT, CUCUMBER, Drumstick, Pepper, CANDIEDHAWS, BubbleTea\nCoffee, Yes, No, OKR, CheckMark, CrossMark, MinusOne, Hundred\nAWESOMEN, Pin, Alarm, Loudspeaker, Trophy, Fire, BOMB, Music\nXmasTree, Snowman, XmasHat, FIREWORKS, 2022, REDPACKET, FORTUNE, LUCK\nFIRECRACKER, StickyRiceBalls, HEARTBROKEN, POOP, StatusFlashOfInspiration, 18X, CLEAVER, Soccer\nBasketball, GeneralDoNotDisturb, Status_PrivateMessage, GeneralInMeetingBusy, StatusReading, StatusInFlight, GeneralBusinessTrip, GeneralWorkFromHome\nStatusEnjoyLife, GeneralTravellingCar, StatusBus, GeneralSun, GeneralMoonRest, MoonRabbit, Mooncake, JubilantRabbit\nTV, Movie, Pumpkin, BeamingFace, Delighted, ColdSweat, FullMoonFace, Partying\nGoGoGo, ThanksFace, SaluteFace, Shrug, ClownFace, HappyDragon\n```\n\n## References\n\n- [lark-im](../SKILL.md) - all IM commands\n- [lark-shared](../../lark-shared/SKILL.md) - authentication and global parameters\n- Official emoji doc: `https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message-reaction/emojis-introduce`\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":10559,"content_sha256":"8234d2335997e19123545ba22dce7e7aebba1d49b855e145b0adba1abb11bfa3"},{"filename":"references/lark-im-threads-messages-list.md","content":"# im +threads-messages-list\n\n> **Prerequisite:** Read [`../../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) first to understand authentication, global parameters, and safety rules.\n\nFetch the reply message list inside a thread. When `im +chat-messages-list` returns messages that include a `thread_id` field, use this command to inspect all replies in that thread.\n\nBy default each reply also carries a `reactions` block (counts + details from `im.reactions.batch_query`) when the server has reactions for it, and `update_time` for messages that were actually edited. Pass `--no-reactions` to skip the extra round-trip. Pass `--download-resources` to additionally download message resources (image/file/audio/video/media + post-embedded, excluding stickers) into `./lark-im-resources/` and attach a `resources` block — off by default, no extra requests when omitted. See [message enrichment](lark-im-message-enrichment.md) for the full contract.\n\nThis skill maps to the shortcut: `lark-cli im +threads-messages-list` (internally calls `GET /open-apis/im/v1/messages` with `container_id_type=thread` to fetch thread messages).\n\n## Commands\n\n```bash\n# Get thread replies (ascending by time by default, table output)\nlark-cli im +threads-messages-list --thread omt_xxx\n\n# Reverse chronological order (latest first)\nlark-cli im +threads-messages-list --thread omt_xxx --order desc\n\n# Control page size\nlark-cli im +threads-messages-list --thread omt_xxx --page-size 20\n\n# Pagination\nlark-cli im +threads-messages-list --thread omt_xxx --page-token \u003cPAGE_TOKEN>\n\n# Fetch multiple pages automatically, up to 10 pages by default\nlark-cli im +threads-messages-list --thread omt_xxx --page-all\n\n# Output format options\nlark-cli im +threads-messages-list --thread omt_xxx --format pretty\nlark-cli im +threads-messages-list --thread omt_xxx --format table\nlark-cli im +threads-messages-list --thread omt_xxx --format csv\n\n# Read thread context as compact Markdown\nlark-cli im +threads-messages-list --thread omt_xxx --concise\n\n# View as a bot\nlark-cli im +threads-messages-list --thread omt_xxx --as bot\n\n# Preview the request without executing it\nlark-cli im +threads-messages-list --thread omt_xxx --dry-run\n```\n\n## Parameters\n\n| Parameter | Required | Description |\n|------|------|------|\n| `--thread \u003cid>` | Yes | Thread ID (`om_xxx` or `omt_xxx` format) |\n| `--no-reactions` | No | Skip auto-fetching the `reactions` block |\n| `--download-resources` | No | Download message resources (image/file/audio/video/media + post-embedded, excluding stickers) into `./lark-im-resources/` and attach a `resources` block. Off by default |\n| `--order \u003corder>` | No | Sort order: `asc` (default) / `desc` |\n| `--page-size \u003cn>` | No | Number of items per page (default 50, range 1-50) |\n| `--page-token \u003ctoken>` | No | Starting cursor, normally returned by a previous response |\n| `--page-all` | No | Automatically fetch and merge subsequent pages; capped by `--page-limit` |\n| `--page-limit \u003cn>` | No | Maximum pages fetched by `--page-all` (default 10, range 1-1000) |\n| `--format \u003cfmt>` | No | Output format: `json` (default) / `pretty` / `table` / `ndjson` / `csv` |\n| `--concise` | No | Render compact Markdown for thread context |\n| `--as \u003cidentity>` | No | Identity type: `user` (default) / `bot` |\n| `--dry-run` | No | Print the request only, do not execute it |\n\n## Core Constraints\n\n### 1. Source of `thread_id`\n\n`thread_id` (`omt_xxx` or `om_xxx`) comes from the `thread_id` field in results returned by `im +chat-messages-list` or `im +messages-search`. Do not guess a thread ID. Fetch messages first and use the returned value.\n\n### 2. No time filtering support\n\nThread messages do not support `start_time` / `end_time` filtering because of Feishu API limitations. Use pagination and sort order to control the scope.\n\n### 3. Pagination (`has_more` / `page_token`)\n\nDefault is one page. With `--page-all`, `--page-token` sets the starting cursor; if `meta.pagination.complete=false`, resume from `meta.pagination.next_token` or raise `--page-limit`.\n\n### 4. Recommended expansion strategy\n\n| Scenario | Recommended Parameters |\n|------|---------|\n| Quickly inspect recent replies | `--order desc --page-size 10` |\n| Read the full thread in chronological order | `--order asc --page-size 50`, then paginate as needed |\n| Just confirm whether replies exist | `--order desc --page-size 1` |\n\n## Usage Scenarios\n\n### Scenario 1: Expand a thread discovered in group messages\n\n```bash\n# Step 1: Fetch group messages and find one that contains thread_id\nlark-cli im +chat-messages-list --chat-id oc_xxx\n\n# Step 2: Extract thread_id from the JSON output and fetch thread replies\nlark-cli im +threads-messages-list --thread omt_xxx\n```\n\n### Scenario 2: Paginate through a long thread\n\n```bash\n# First page\nlark-cli im +threads-messages-list --thread omt_xxx\n\n# If has_more=true is returned, continue with page_token\nlark-cli im +threads-messages-list --thread omt_xxx --page-token \u003cPAGE_TOKEN>\n```\n\n## Resource Rendering\n\nThread replies are rendered into human-readable text. Image messages appear as placeholders such as `![Image](img_xxx)`; `folder` replies are expanded one level (children rendered inside a `\u003cfolder ...>` tag); by default resource binaries are **not** downloaded.\n\nPass `--download-resources` to download every eligible resource (image/file/audio/video/media + post-embedded, excluding stickers) into `./lark-im-resources/` in one pass and attach a `resources` block to each reply (see [message enrichment](lark-im-message-enrichment.md#resource-auto-download---download-resources-opt-in)). Otherwise download individual resources manually through `im +messages-resources-download` (see [lark-im-messages-resources-download](lark-im-messages-resources-download.md)).\n\n## Common Errors and Troubleshooting\n\n| Symptom | Root Cause | Solution |\n|---------|---------|---------|\n| \"Invalid thread ID format\" | `thread_id` does not start with `om_` or `omt_` | Use a valid `om_xxx` or `omt_xxx` value |\n| Empty thread result | Wrong thread_id or no replies in the thread | Confirm the thread_id came from `im +chat-messages-list` output |\n| Permission denied | The user is not authorized or is not a conversation member | Make sure OAuth authorization is complete and the identity is a chat member |\n\n## References\n\n- [lark-im](../SKILL.md) - all message-related commands\n- [lark-im-chat-messages-list](lark-im-chat-messages-list.md) - fetch conversation messages (source of `thread_id`)\n- [lark-shared](../../lark-shared/SKILL.md) - authentication and global parameters\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":6576,"content_sha256":"830c3642db3668e7bd6379ce26c1476d45cc47cdb15864130b84ff60e86aa3a2"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"im (v1)","type":"text"}]},{"type":"paragraph","content":[{"text":"CRITICAL — 开始前 MUST 先用 Read 工具读取 ","type":"text","marks":[{"type":"strong"}]},{"text":"../lark-shared/SKILL.md","type":"text","marks":[{"type":"link","attrs":{"href":"../lark-shared/SKILL.md","title":null}},{"type":"code_inline"},{"type":"strong"}]},{"text":",其中包含认证、权限处理","type":"text","marks":[{"type":"strong"}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Core Concepts","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Message","type":"text","marks":[{"type":"strong"}]},{"text":": A single message in a chat, identified by ","type":"text"},{"text":"message_id","type":"text","marks":[{"type":"code_inline"}]},{"text":" (om_xxx). Supports types: text, post, image, file, audio, video, sticker, interactive (card), share_chat, share_user, merge_forward, etc.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Chat","type":"text","marks":[{"type":"strong"}]},{"text":": A group chat or P2P conversation, identified by ","type":"text"},{"text":"chat_id","type":"text","marks":[{"type":"code_inline"}]},{"text":" (oc_xxx).","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Thread","type":"text","marks":[{"type":"strong"}]},{"text":": A reply thread under a message, identified by ","type":"text"},{"text":"thread_id","type":"text","marks":[{"type":"code_inline"}]},{"text":" (om_xxx or omt_xxx).","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Reaction","type":"text","marks":[{"type":"strong"}]},{"text":": An emoji reaction on a message.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Flag","type":"text","marks":[{"type":"strong"}]},{"text":": A bookmark on a message or thread.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Feed Shortcut","type":"text","marks":[{"type":"strong"}]},{"text":": A chat pinned to the current user's feed sidebar, identified by ","type":"text"},{"text":"feed_card_id","type":"text","marks":[{"type":"code_inline"}]},{"text":" (an ","type":"text"},{"text":"oc_xxx","type":"text","marks":[{"type":"code_inline"}]},{"text":" open_chat_id for CHAT type).","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Feed Group","type":"text","marks":[{"type":"strong"}]},{"text":": A tag that groups feed cards in the feed list, identified by ","type":"text"},{"text":"feed_group_id","type":"text","marks":[{"type":"code_inline"}]},{"text":" (ofg_xxx). Members are feed cards, each identified by ","type":"text"},{"text":"feed_id","type":"text","marks":[{"type":"code_inline"}]},{"text":" + ","type":"text"},{"text":"feed_type","type":"text","marks":[{"type":"code_inline"}]},{"text":". Two types: ","type":"text"},{"text":"normal","type":"text","marks":[{"type":"code_inline"}]},{"text":" (members managed explicitly) and ","type":"text"},{"text":"rule","type":"text","marks":[{"type":"code_inline"}]},{"text":" (members auto-derived from rules).","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Resource Relationships","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"Chat (oc_xxx)\n├── Message (om_xxx)\n│ ├── Thread (reply thread)\n│ ├── Reaction (emoji)\n│ └── Resource (image / file / video / audio)\n└── Member (user / bot)","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Important Notes","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"AppLink and Share Links","type":"text"}]},{"type":"paragraph","content":[{"text":"Prefer CLI-returned links: use ","type":"text"},{"text":"chat_app_link","type":"text","marks":[{"type":"code_inline"}]},{"text":" to open joined conversations, ","type":"text"},{"text":"message_app_link","type":"text","marks":[{"type":"code_inline"}]},{"text":" to open messages, and ","type":"text"},{"text":"share_link","type":"text","marks":[{"type":"code_inline"}]},{"text":" to invite others to groups. If manually building a joined-conversation AppLink, use ","type":"text"},{"text":"https://\u003capplink_host>/client/chat/open?openChatId=\u003coc_xxx>","type":"text","marks":[{"type":"code_inline"}]},{"text":", never ","type":"text"},{"text":"chatId=\u003coc_xxx>","type":"text","marks":[{"type":"code_inline"}]},{"text":" or ","type":"text"},{"text":"lark://...chat_id=\u003coc_xxx>","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Identity and Token Mapping","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"--as user","type":"text","marks":[{"type":"code_inline"}]},{"text":" means ","type":"text"},{"text":"user identity","type":"text","marks":[{"type":"strong"}]},{"text":" and uses ","type":"text"},{"text":"user_access_token","type":"text","marks":[{"type":"code_inline"}]},{"text":". Calls run as the authorized end user, so permissions depend on both the app scopes and that user's own access to the target chat/message/resource.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"--as bot","type":"text","marks":[{"type":"code_inline"}]},{"text":" means ","type":"text"},{"text":"bot identity","type":"text","marks":[{"type":"strong"}]},{"text":" and uses ","type":"text"},{"text":"tenant_access_token","type":"text","marks":[{"type":"code_inline"}]},{"text":". Calls run as the app bot, so behavior depends on the bot's membership, app visibility, availability range, and bot-specific scopes.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"If an IM API says it supports both ","type":"text"},{"text":"user","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"bot","type":"text","marks":[{"type":"code_inline"}]},{"text":", the token type changes who the operator is. The same API can succeed with one identity and fail with the other because owner/admin status, chat membership, tenant boundary, or app availability are checked against the current caller.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Sender Name Resolution","type":"text"}]},{"type":"paragraph","content":[{"text":"When fetching messages (","type":"text"},{"text":"+chat-messages-list","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"+threads-messages-list","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"+messages-mget","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"+messages-search","type":"text","marks":[{"type":"code_inline"}]},{"text":"), the CLI shows a display name for both user and bot senders:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Server-provided name","type":"text","marks":[{"type":"strong"}]},{"text":": the read APIs return ","type":"text"},{"text":"sender_name","type":"text","marks":[{"type":"code_inline"}]},{"text":" (plus the full-i18n ","type":"text"},{"text":"sender_i18n_names","type":"text","marks":[{"type":"code_inline"}]},{"text":" map) on each message ","type":"text"},{"text":"sender","type":"text","marks":[{"type":"code_inline"}]},{"text":"; the CLI surfaces it as the sender's ","type":"text"},{"text":"name","type":"text","marks":[{"type":"code_inline"}]},{"text":" for users and bots alike. No name lookup and no extra permission are needed — ","type":"text"},{"text":"no contact scope","type":"text","marks":[{"type":"strong"}]},{"text":" and no ","type":"text"},{"text":"application:bot.basic_info:read","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Fallback to id","type":"text","marks":[{"type":"strong"}]},{"text":": when the server does not provide a name, the sender is shown by its id and the command still exits 0. There is no contact-directory fallback.","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"The raw ","type":"text"},{"text":"sender_name","type":"text","marks":[{"type":"code_inline"}]},{"text":" is not duplicated in output (its value is in ","type":"text"},{"text":"name","type":"text","marks":[{"type":"code_inline"}]},{"text":"); the full ","type":"text"},{"text":"sender_i18n_names","type":"text","marks":[{"type":"code_inline"}]},{"text":" map (all locales) is preserved for consumers that need a specific language, alongside an optional ","type":"text"},{"text":"open_bot_id","type":"text","marks":[{"type":"code_inline"}]},{"text":" (","type":"text"},{"text":"ou_","type":"text","marks":[{"type":"code_inline"}]},{"text":") for bot senders aligned with the message-receive event channel. System messages (","type":"text"},{"text":"msg_type: system","type":"text","marks":[{"type":"code_inline"}]},{"text":") have no sender name — that is normal, not an error.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Default message enrichment (reactions / update_time)","type":"text"}]},{"type":"paragraph","content":[{"text":"The four message-pulling shortcuts (","type":"text"},{"text":"+messages-mget","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"+chat-messages-list","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"+messages-search","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"+threads-messages-list","type":"text","marks":[{"type":"code_inline"}]},{"text":") automatically attach a ","type":"text"},{"text":"reactions","type":"text","marks":[{"type":"code_inline"}]},{"text":" block and (for edited messages) ","type":"text"},{"text":"update_time","type":"text","marks":[{"type":"code_inline"}]},{"text":" to each returned message — no separate ","type":"text"},{"text":"im.reactions.batch_query","type":"text","marks":[{"type":"code_inline"}]},{"text":" call is needed. Pass ","type":"text"},{"text":"--no-reactions","type":"text","marks":[{"type":"code_inline"}]},{"text":" to opt out. For the full contract (output shape, the ","type":"text"},{"text":"im:message.reactions:read","type":"text","marks":[{"type":"code_inline"}]},{"text":" scope requirement, and the \"missing field ≠ fetch failure\" data rules), read ","type":"text"},{"text":"references/lark-im-message-enrichment.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/lark-im-message-enrichment.md","title":null}},{"type":"code_inline"}]},{"text":".","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Compact message output (","type":"text"},{"text":"--concise","type":"text","marks":[{"type":"code_inline"}]},{"text":")","type":"text"}]},{"type":"paragraph","content":[{"text":"Some message-listing shortcuts support ","type":"text"},{"text":"--concise","type":"text","marks":[{"type":"code_inline"}]},{"text":" for compact Markdown output. Use it when the user asks for concise output or a smaller result/file; check ","type":"text"},{"text":"--help","type":"text","marks":[{"type":"code_inline"}]},{"text":" for availability and do not combine it with an explicit ","type":"text"},{"text":"--format","type":"text","marks":[{"type":"code_inline"}]},{"text":", an enabled ","type":"text"},{"text":"--json","type":"text","marks":[{"type":"code_inline"}]},{"text":", or a non-empty ","type":"text"},{"text":"--jq","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Opt-in resource auto-download (","type":"text"},{"text":"--download-resources","type":"text","marks":[{"type":"code_inline"}]},{"text":")","type":"text"}]},{"type":"paragraph","content":[{"text":"+chat-messages-list","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"+messages-mget","type":"text","marks":[{"type":"code_inline"}]},{"text":", and ","type":"text"},{"text":"+threads-messages-list","type":"text","marks":[{"type":"code_inline"}]},{"text":" accept ","type":"text"},{"text":"--download-resources","type":"text","marks":[{"type":"code_inline"}]},{"text":" to save eligible attachments into ","type":"text"},{"text":"./lark-im-resources/","type":"text","marks":[{"type":"code_inline"}]},{"text":" and add a ","type":"text"},{"text":"resources","type":"text","marks":[{"type":"code_inline"}]},{"text":" array to each message. It is off by default; stickers are not downloadable. A failed attachment is reported on that resource without aborting the message pull. Use ","type":"text"},{"text":"+messages-resources-download","type":"text","marks":[{"type":"link","attrs":{"href":"references/lark-im-messages-resources-download.md","title":null}},{"type":"code_inline"}]},{"text":" for one attachment. See ","type":"text"},{"text":"references/lark-im-message-enrichment.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/lark-im-message-enrichment.md","title":null}},{"type":"code_inline"}]},{"text":" for the output contract.","type":"text"}]},{"type":"paragraph","content":[{"text":"Folder resources","type":"text","marks":[{"type":"strong"}]},{"text":" are containers, not files — a folder ","type":"text"},{"text":"file_key","type":"text","marks":[{"type":"code_inline"}]},{"text":" cannot be downloaded directly. Expand it first with ","type":"text"},{"text":"lark-cli im files folder --recursive --file-key \u003cfolder_key> --srctype message --srcid \u003cmessage_id>","type":"text","marks":[{"type":"code_inline"}]},{"text":", then download the files inside with ","type":"text"},{"text":"+messages-resources-download","type":"text","marks":[{"type":"link","attrs":{"href":"references/lark-im-messages-resources-download.md","title":null}},{"type":"code_inline"}]},{"text":".","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Card Messages (Interactive)","type":"text"}]},{"type":"paragraph","content":[{"text":"Before sending, replying with, or updating any ","type":"text","marks":[{"type":"strong"}]},{"text":"interactive","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":" card (","type":"text","marks":[{"type":"strong"}]},{"text":"+messages-send","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":" / ","type":"text","marks":[{"type":"strong"}]},{"text":"+messages-reply","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":" / ","type":"text","marks":[{"type":"strong"}]},{"text":"messages.patch","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":"), you MUST read ","type":"text","marks":[{"type":"strong"}]},{"text":"references/card/lark-im-card-create.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/card/lark-im-card-create.md","title":null}},{"type":"code_inline"},{"type":"strong"}]},{"text":" and follow its workflow.","type":"text","marks":[{"type":"strong"}]},{"text":" The card JSON passed to ","type":"text"},{"text":"--msg-type interactive --content","type":"text","marks":[{"type":"code_inline"}]},{"text":" (send/reply) or ","type":"text"},{"text":"messages.patch --data","type":"text","marks":[{"type":"code_inline"}]},{"text":" (update) must be the output of that workflow — never hand-write or copy a card payload.","type":"text"}]},{"type":"paragraph","content":[{"text":"Card messages (","type":"text"},{"text":"interactive","type":"text","marks":[{"type":"code_inline"}]},{"text":" type) are not yet supported for compact conversion in event subscriptions. The raw event data will be returned instead, with a hint printed to stderr.","type":"text"}]},{"type":"paragraph","content":[{"text":"interactive","type":"text","marks":[{"type":"code_inline"}]},{"text":" cards support callback events (","type":"text"},{"text":"card.action.trigger","type":"text","marks":[{"type":"code_inline"}]},{"text":") — see ","type":"text"},{"text":"references/lark-im-card-action-reply.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/lark-im-card-action-reply.md","title":null}},{"type":"code_inline"}]},{"text":".","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Audio Messages","type":"text"}]},{"type":"paragraph","content":[{"text":"--audio","type":"text","marks":[{"type":"code_inline"}]},{"text":" sends a voice message and supports only Opus audio files, for example ","type":"text"},{"text":".opus","type":"text","marks":[{"type":"code_inline"}]},{"text":" files or Ogg Opus (","type":"text"},{"text":".ogg","type":"text","marks":[{"type":"code_inline"}]},{"text":") files. For ","type":"text"},{"text":"mp3","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"wav","type":"text","marks":[{"type":"code_inline"}]},{"text":", or other non-Opus audio, either convert to ","type":"text"},{"text":".opus","type":"text","marks":[{"type":"code_inline"}]},{"text":" first and keep using ","type":"text"},{"text":"--audio","type":"text","marks":[{"type":"code_inline"}]},{"text":", or send the original file as an attachment with ","type":"text"},{"text":"--file","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Sending Doc Content as a Message","type":"text"}]},{"type":"paragraph","content":[{"text":"When sending content fetched from a Lark doc as a message, fetch the doc with --doc-format im-markdown, then send it as a message using the --markdown format. The fetched content is already in markdown; in any content-forwarding scenario, keep the fetched original text and send it in the --markdown format. Note: if the doc contains a cite tag with type=\"user\", keep it as-is and do not strip the tag.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Flag Types","type":"text"}]},{"type":"paragraph","content":[{"text":"Flags support two layers:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Message-layer flag","type":"text","marks":[{"type":"strong"}]},{"text":": ","type":"text"},{"text":"(ItemTypeDefault, FlagTypeMessage)","type":"text","marks":[{"type":"code_inline"}]},{"text":" — regular message bookmark","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Feed-layer flag","type":"text","marks":[{"type":"strong"}]},{"text":": ","type":"text"},{"text":"(ItemTypeThread/ItemTypeMsgThread, FlagTypeFeed)","type":"text","marks":[{"type":"code_inline"}]},{"text":" — thread as feed-layer bookmark","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Item types for feed-layer flags:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"ItemTypeThread","type":"text","marks":[{"type":"strong"}]},{"text":" (4) = thread in a topic-style chat","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"ItemTypeMsgThread","type":"text","marks":[{"type":"strong"}]},{"text":" (11) = thread in a regular chat","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Feed Shortcut","type":"text"}]},{"type":"paragraph","content":[{"text":"Feed shortcuts add chats to the current user's feed sidebar. They are distinct from flags:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Flag","type":"text","marks":[{"type":"strong"}]},{"text":" = bookmark on a message/thread, scoped to the user's bookmark list.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Feed shortcut","type":"text","marks":[{"type":"strong"}]},{"text":" = entry in the user's feed sidebar (currently only chats).","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Key limits:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Only ","type":"text"},{"text":"CHAT-type","type":"text","marks":[{"type":"strong"}]},{"text":" (","type":"text"},{"text":"feed_card_id","type":"text","marks":[{"type":"code_inline"}]},{"text":" is ","type":"text"},{"text":"oc_xxx","type":"text","marks":[{"type":"code_inline"}]},{"text":") is exposed via OpenAPI; doc/app/subscription shortcuts exist internally but are not yet whitelisted.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"All three operations (create/remove/list) are ","type":"text"},{"text":"user-identity only","type":"text","marks":[{"type":"strong"}]},{"text":" — they sign with ","type":"text"},{"text":"user_access_token","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Batch size is ","type":"text"},{"text":"10 per call","type":"text","marks":[{"type":"strong"}]},{"text":" for create/remove; list is a one-page wrapper with opaque ","type":"text"},{"text":"page_token","type":"text","marks":[{"type":"code_inline"}]},{"text":" pagination.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Shortcuts(推荐优先使用)","type":"text"}]},{"type":"paragraph","content":[{"text":"Shortcut 是对常用操作的高级封装(","type":"text"},{"text":"lark-cli im +\u003cverb> [flags]","type":"text","marks":[{"type":"code_inline"}]},{"text":")。有 Shortcut 的操作优先使用。","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Shortcut","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"说明","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"+chat-create","type":"text","marks":[{"type":"link","attrs":{"href":"references/lark-im-chat-create.md","title":null}},{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Create a group chat or topic chat; user/bot; --chat-mode group","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"+chat-list","type":"text","marks":[{"type":"link","attrs":{"href":"references/lark-im-chat-list.md","title":null}},{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"List chats the current user/bot is a member of; defaults to groups; pass --types=p2p,group to include p2p single chats (user-only); user/bot; supports sorting, auto-pagination, --exclude-muted (user-only)","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"+chat-members-list","type":"text","marks":[{"type":"link","attrs":{"href":"references/lark-im-chat-members-list.md","title":null}},{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"List members of a chat; returns separate users[] / bots[] buckets; callable as user or bot; --member-types filters which kinds to return; --page-all pagination; surfaces truncations[] when the server caps a bucket","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"+chat-messages-list","type":"text","marks":[{"type":"link","attrs":{"href":"references/lark-im-chat-messages-list.md","title":null}},{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"List messages in a chat or P2P conversation; user/bot; accepts --chat-id or --user-id, resolves P2P chat_id, supports time range, --order asc/desc sorting, auto-pagination","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"+chat-search","type":"text","marks":[{"type":"link","attrs":{"href":"references/lark-im-chat-search.md","title":null}},{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Search visible group chats by --query keyword and/or --member-ids; user/bot; e.g. look up chat_id by group name; supports type filters, sorting, auto-pagination, and --exclude-muted (user identity only)","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"+chat-update","type":"text","marks":[{"type":"link","attrs":{"href":"references/lark-im-chat-update.md","title":null}},{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Update group chat name or description; user/bot; updates a chat's name or description","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"+message-read-users","type":"text","marks":[{"type":"link","attrs":{"href":"references/lark-im-message-read-status.md","title":null}},{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"List users who read one message; user/bot; identity-specific scopes; supports bounded auto-pagination","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"+messages-edit","type":"text","marks":[{"type":"link","attrs":{"href":"references/lark-im-messages-edit.md","title":null}},{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Edit a message's content (text/post, including the attachment zone); bot-only (user identity is rejected by the server); PUT /open-apis/im/v1/messages/:message_id","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"+messages-mget","type":"text","marks":[{"type":"link","attrs":{"href":"references/lark-im-messages-mget.md","title":null}},{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Batch get messages by IDs; user/bot; fetches up to 50 om_ message IDs, formats sender names, expands thread replies","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"+messages-read-status","type":"text","marks":[{"type":"link","attrs":{"href":"references/lark-im-message-read-status.md","title":null}},{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Batch query whether the current user read 1–50 messages; user-only; returns readable items and invalid message IDs","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"+messages-reply","type":"text","marks":[{"type":"link","attrs":{"href":"references/lark-im-messages-reply.md","title":null}},{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Reply to a message (supports thread replies); user/bot; supports text/markdown/post/media replies, reply-in-thread, idempotency key","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"+messages-resources-download","type":"text","marks":[{"type":"link","attrs":{"href":"references/lark-im-messages-resources-download.md","title":null}},{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Download an image/file from a message; folders are not directly downloadable — expand with ","type":"text"},{"text":"im files folder --recursive","type":"text","marks":[{"type":"code_inline"}]},{"text":" first, then download the files inside; user/bot","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"+messages-search","type":"text","marks":[{"type":"link","attrs":{"href":"references/lark-im-messages-search.md","title":null}},{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Search messages across chats (supports keyword, sender, time range filters) with user or bot identity; filters by chat/sender/attachment/time, supports auto-pagination via ","type":"text"},{"text":"--page-all","type":"text","marks":[{"type":"code_inline"}]},{"text":" / ","type":"text"},{"text":"--page-limit","type":"text","marks":[{"type":"code_inline"}]},{"text":", enriches results via batched mget and chats batch_query","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"+messages-send","type":"text","marks":[{"type":"link","attrs":{"href":"references/lark-im-messages-send.md","title":null}},{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Send a message to a chat or direct message; user/bot; sends to chat-id or user-id with text/markdown/post/media, supports idempotency key","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"+threads-messages-list","type":"text","marks":[{"type":"link","attrs":{"href":"references/lark-im-threads-messages-list.md","title":null}},{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"List messages in a thread; user/bot; accepts om_/omt_ input, resolves message IDs to thread_id, supports --order asc/desc sorting, auto-pagination","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"+flag-create","type":"text","marks":[{"type":"link","attrs":{"href":"references/lark-im-flag-create.md","title":null}},{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Create a bookmark on a message; user-only; defaults to message-layer flag; use --flag-type feed for feed-layer flag (item_type auto-detected from chat mode)","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"+flag-cancel","type":"text","marks":[{"type":"link","attrs":{"href":"references/lark-im-flag-cancel.md","title":null}},{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Cancel (remove) a bookmark. When no --flag-type is given, best-effort double-cancel: removes message layer and (when chat_type is determinable) feed layer","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"+flag-list","type":"text","marks":[{"type":"link","attrs":{"href":"references/lark-im-flag-list.md","title":null}},{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"List bookmarks; user-only; auto-enriches feed-type thread entries with message content; ","type":"text"},{"text":"--page-all","type":"text","marks":[{"type":"code_inline"}]},{"text":" is capped by ","type":"text"},{"text":"--page-limit","type":"text","marks":[{"type":"code_inline"}]},{"text":" (default 20, max 1000), and ","type":"text"},{"text":"has_more=true","type":"text","marks":[{"type":"code_inline"}]},{"text":" means the result is incomplete","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"+feed-shortcut-create","type":"text","marks":[{"type":"link","attrs":{"href":"references/lark-im-feed-shortcut-create.md","title":null}},{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Add chats to the user's feed shortcuts; user-only; oc_xxx chat IDs only; batch up to 10 per call; ","type":"text"},{"text":"--head","type":"text","marks":[{"type":"code_inline"}]},{"text":"/","type":"text"},{"text":"--tail","type":"text","marks":[{"type":"code_inline"}]},{"text":" controls insertion order; partial failures return an ","type":"text"},{"text":"ok:false","type":"text","marks":[{"type":"code_inline"}]},{"text":" ledger","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"+feed-shortcut-remove","type":"text","marks":[{"type":"link","attrs":{"href":"references/lark-im-feed-shortcut-remove.md","title":null}},{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Remove chats from the user's feed shortcuts; user-only; batch up to 10 per call; removing an absent shortcut is idempotent success; real per-item failures return an ","type":"text"},{"text":"ok:false","type":"text","marks":[{"type":"code_inline"}]},{"text":" ledger","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"+feed-shortcut-list","type":"text","marks":[{"type":"link","attrs":{"href":"references/lark-im-feed-shortcut-list.md","title":null}},{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"List one page of the user's feed shortcuts; user-only; omit ","type":"text"},{"text":"--page-token","type":"text","marks":[{"type":"code_inline"}]},{"text":" for the first page; default output enriches CHAT entries under ","type":"text"},{"text":"detail","type":"text","marks":[{"type":"code_inline"}]},{"text":"; pass ","type":"text"},{"text":"--no-detail","type":"text","marks":[{"type":"code_inline"}]},{"text":" to skip the extra lookup and ","type":"text"},{"text":"im:chat:read","type":"text","marks":[{"type":"code_inline"}]},{"text":" scope","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"+feed-group-list","type":"text","marks":[{"type":"link","attrs":{"href":"references/lark-im-feed-group-list.md","title":null}},{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"List the caller's feed groups (tags); user-only; supports ","type":"text"},{"text":"--page-all","type":"text","marks":[{"type":"code_inline"}]},{"text":" auto-pagination","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"+feed-group-list-item","type":"text","marks":[{"type":"link","attrs":{"href":"references/lark-im-feed-group-list-item.md","title":null}},{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"List feed cards in a feed group (tag); user-only; enriches each item with chat_name resolved from feed_id; supports --page-all auto-pagination","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"+feed-group-query-item","type":"text","marks":[{"type":"link","attrs":{"href":"references/lark-im-feed-group-query-item.md","title":null}},{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Look up specific feed cards in a feed group (tag) by ID; user-only; enriches each item with chat_name resolved from feed_id","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"API Resources","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"lark-cli schema im.\u003cresource>.\u003cmethod> # 调用 API 前必须先查看参数结构\nlark-cli im \u003cresource> \u003cmethod> [flags] # 调用 API","type":"text"}]},{"type":"blockquote","content":[{"type":"paragraph","content":[{"text":"重要","type":"text","marks":[{"type":"strong"}]},{"text":":使用原生 API 时,必须先运行 ","type":"text"},{"text":"schema","type":"text","marks":[{"type":"code_inline"}]},{"text":" 查看 ","type":"text"},{"text":"--data","type":"text","marks":[{"type":"code_inline"}]},{"text":" / ","type":"text"},{"text":"--params","type":"text","marks":[{"type":"code_inline"}]},{"text":" 参数结构,不要猜测字段格式。","type":"text"}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"chats","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"create","type":"text","marks":[{"type":"code_inline"}]},{"text":" — 创建群。Identity: ","type":"text"},{"text":"bot","type":"text","marks":[{"type":"code_inline"}]},{"text":" only (","type":"text"},{"text":"tenant_access_token","type":"text","marks":[{"type":"code_inline"}]},{"text":").","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"get","type":"text","marks":[{"type":"code_inline"}]},{"text":" — 获取群信息。Identity: supports ","type":"text"},{"text":"user","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"bot","type":"text","marks":[{"type":"code_inline"}]},{"text":"; the caller must be in the target chat to get full details, and must belong to the same tenant for internal chats.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"link","type":"text","marks":[{"type":"code_inline"}]},{"text":" — 获取群分享链接。Identity: supports ","type":"text"},{"text":"user","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"bot","type":"text","marks":[{"type":"code_inline"}]},{"text":"; the caller must be in the target chat, must be an owner or admin when chat sharing is restricted to owners/admins, and must belong to the same tenant for internal chats.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"update","type":"text","marks":[{"type":"code_inline"}]},{"text":" — 更新群信息。Identity: supports ","type":"text"},{"text":"user","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"bot","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"chat.members","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"create","type":"text","marks":[{"type":"code_inline"}]},{"text":" — 将用户或机器人拉入群聊。Identity: supports ","type":"text"},{"text":"user","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"bot","type":"text","marks":[{"type":"code_inline"}]},{"text":"; the caller must be in the target chat; for ","type":"text"},{"text":"bot","type":"text","marks":[{"type":"code_inline"}]},{"text":" calls, added users must be within the app's availability; for internal chats the operator must belong to the same tenant; if only owners/admins can add members, the caller must be an owner/admin, or a chat-creator bot with ","type":"text"},{"text":"im:chat:operate_as_owner","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"delete","type":"text","marks":[{"type":"code_inline"}]},{"text":" — 将用户或机器人移出群聊。Identity: supports ","type":"text"},{"text":"user","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"bot","type":"text","marks":[{"type":"code_inline"}]},{"text":"; only group owner, admin, or creator bot can remove others; max 50 users or 5 bots per request.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"chat.user_setting","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"batch_query","type":"text","marks":[{"type":"code_inline"}]},{"text":" — 批量查询当前用户在群内的个人偏好设置 (e.g. ","type":"text"},{"text":"is_muted","type":"text","marks":[{"type":"code_inline"}]},{"text":" mutes normal messages, ","type":"text"},{"text":"is_mute_at_all","type":"text","marks":[{"type":"code_inline"}]},{"text":" mutes @all messages); up to 10 chats per request. Identity: ","type":"text"},{"text":"user","type":"text","marks":[{"type":"code_inline"}]},{"text":" only (","type":"text"},{"text":"user_access_token","type":"text","marks":[{"type":"code_inline"}]},{"text":"); the caller must be in each target chat.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"batch_update","type":"text","marks":[{"type":"code_inline"}]},{"text":" — 批量更新当前用户在群内的个人偏好设置 (e.g. ","type":"text"},{"text":"is_muted","type":"text","marks":[{"type":"code_inline"}]},{"text":" mutes normal messages, ","type":"text"},{"text":"is_mute_at_all","type":"text","marks":[{"type":"code_inline"}]},{"text":" mutes @all messages); up to 10 chats per request. Identity: ","type":"text"},{"text":"user","type":"text","marks":[{"type":"code_inline"}]},{"text":" only (","type":"text"},{"text":"user_access_token","type":"text","marks":[{"type":"code_inline"}]},{"text":"); the caller must be in each target chat.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"chat.nickname","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"get","type":"text","marks":[{"type":"code_inline"}]},{"text":" — 获取自己的群昵称。Get your own nickname in the chat (self-only). Identity: ","type":"text"},{"text":"user","type":"text","marks":[{"type":"code_inline"}]},{"text":" only (","type":"text"},{"text":"user_access_token","type":"text","marks":[{"type":"code_inline"}]},{"text":"); returns an empty string when no nickname is set.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"update","type":"text","marks":[{"type":"code_inline"}]},{"text":" — 设置自己的群昵称。Set or update your own nickname in the chat (self-only). Identity: ","type":"text"},{"text":"user","type":"text","marks":[{"type":"code_inline"}]},{"text":" only (","type":"text"},{"text":"user_access_token","type":"text","marks":[{"type":"code_inline"}]},{"text":"); ","type":"text"},{"text":"nickname","type":"text","marks":[{"type":"code_inline"}]},{"text":" must be a non-empty string (max 300 bytes). Use DELETE to clear it.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"delete","type":"text","marks":[{"type":"code_inline"}]},{"text":" — 清空自己的群昵称。Clear your own nickname in the chat (self-only). Identity: ","type":"text"},{"text":"user","type":"text","marks":[{"type":"code_inline"}]},{"text":" only (","type":"text"},{"text":"user_access_token","type":"text","marks":[{"type":"code_inline"}]},{"text":").","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"chat.join_requests","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"list","type":"text","marks":[{"type":"code_inline"}]},{"text":" — 列出群的待审批入群申请(仅群主/管理员,user_access_token)。List pending join requests for a chat. Identity: ","type":"text"},{"text":"user","type":"text","marks":[{"type":"code_inline"}]},{"text":" only (","type":"text"},{"text":"user_access_token","type":"text","marks":[{"type":"code_inline"}]},{"text":"); the caller must be the chat owner or an admin. Paginated (","type":"text"},{"text":"page_size","type":"text","marks":[{"type":"code_inline"}]},{"text":" 1-100); stop on ","type":"text"},{"text":"has_more == false","type":"text","marks":[{"type":"code_inline"}]},{"text":" — ","type":"text"},{"text":"page_token","type":"text","marks":[{"type":"code_inline"}]},{"text":" is returned even on the last page, so paging while it is present never terminates.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"handle","type":"text","marks":[{"type":"code_inline"}]},{"text":" — 批量审批入群申请(approve/reject,仅群主/管理员,user_access_token)。Approve or reject pending join requests in bulk (1-50 items, processed in order). Identity: ","type":"text"},{"text":"user","type":"text","marks":[{"type":"code_inline"}]},{"text":" only (","type":"text"},{"text":"user_access_token","type":"text","marks":[{"type":"code_inline"}]},{"text":"); the caller must be the chat owner or an admin. ","type":"text"},{"text":"results[]","type":"text","marks":[{"type":"code_inline"}]},{"text":" mirrors ","type":"text"},{"text":"items[]","type":"text","marks":[{"type":"code_inline"}]},{"text":" in count and order — check each ","type":"text"},{"text":"result","type":"text","marks":[{"type":"code_inline"}]},{"text":" (","type":"text"},{"text":"success","type":"text","marks":[{"type":"code_inline"}]},{"text":" / ","type":"text"},{"text":"failed","type":"text","marks":[{"type":"code_inline"}]},{"text":" / ","type":"text"},{"text":"already_handled","type":"text","marks":[{"type":"code_inline"}]},{"text":"); exit 0 does not mean every item succeeded.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"chat.managers","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"add_managers","type":"text","marks":[{"type":"code_inline"}]},{"text":" — 指定群管理员。Identity: supports ","type":"text"},{"text":"user","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"bot","type":"text","marks":[{"type":"code_inline"}]},{"text":"; only the group owner can add managers; max 10 managers per chat (20 for super-large chats), and at most 5 bots per request.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"delete_managers","type":"text","marks":[{"type":"code_inline"}]},{"text":" — 删除群管理员。Identity: supports ","type":"text"},{"text":"user","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"bot","type":"text","marks":[{"type":"code_inline"}]},{"text":"; only the group owner can remove managers; max 50 users or 5 bots per request.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"chat.moderation","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"get","type":"text","marks":[{"type":"code_inline"}]},{"text":" — 获取群成员发言权限。Identity: supports ","type":"text"},{"text":"user","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"bot","type":"text","marks":[{"type":"code_inline"}]},{"text":"; the caller must be in the target chat and belong to the same tenant.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"update","type":"text","marks":[{"type":"code_inline"}]},{"text":" — 更新群发言权限。Identity: supports ","type":"text"},{"text":"user","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"bot","type":"text","marks":[{"type":"code_inline"}]},{"text":"; only the group owner (or creator bot with ","type":"text"},{"text":"im:chat:operate_as_owner","type":"text","marks":[{"type":"code_inline"}]},{"text":") can update; the caller must be in the chat.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"messages","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"read_status","type":"text","marks":[{"type":"code_inline"}]},{"text":" — 批量查询当前用户对消息的已读状态。Identity: ","type":"text"},{"text":"user","type":"text","marks":[{"type":"code_inline"}]},{"text":" only (","type":"text"},{"text":"user_access_token","type":"text","marks":[{"type":"code_inline"}]},{"text":"); accepts up to 50 message IDs and returns readable items plus invalid message IDs.","type":"text"},{"text":"Must-read","type":"text","marks":[{"type":"link","attrs":{"href":"references/lark-im-message-read-status.md","title":null}}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"delete","type":"text","marks":[{"type":"code_inline"}]},{"text":" — 撤回消息。Identity: supports ","type":"text"},{"text":"user","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"bot","type":"text","marks":[{"type":"code_inline"}]},{"text":"; for ","type":"text"},{"text":"bot","type":"text","marks":[{"type":"code_inline"}]},{"text":" calls, the bot must be in the chat to revoke group messages; to revoke another user's group message, the bot must be the owner, an admin, or the creator; for user P2P recalls, the target user must be within the bot's availability.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"forward","type":"text","marks":[{"type":"code_inline"}]},{"text":" — 转发消息。Identity: supports ","type":"text"},{"text":"user","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"bot","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"merge_forward","type":"text","marks":[{"type":"code_inline"}]},{"text":" — 合并转发消息。Identity: ","type":"text"},{"text":"bot","type":"text","marks":[{"type":"code_inline"}]},{"text":" only (","type":"text"},{"text":"tenant_access_token","type":"text","marks":[{"type":"code_inline"}]},{"text":").","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"read_users","type":"text","marks":[{"type":"code_inline"}]},{"text":" — 查询消息已读信息。Identity: supports ","type":"text"},{"text":"user","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"bot","type":"text","marks":[{"type":"code_inline"}]},{"text":"; the caller must still be in the chat. A user can query messages they sent within the last 7 days, while a bot can query only messages sent by that bot within the last 7 days.","type":"text"},{"text":"Must-read","type":"text","marks":[{"type":"link","attrs":{"href":"references/lark-im-message-read-status.md","title":null}}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"patch","type":"text","marks":[{"type":"code_inline"}]},{"text":" — 更新已发送的消息卡片。Update an interactive message card sent by the app. Identity: supports ","type":"text"},{"text":"user","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"bot","type":"text","marks":[{"type":"code_inline"}]},{"text":"; the message must have been sent within the last 14 days, and ","type":"text"},{"text":"content","type":"text","marks":[{"type":"code_inline"}]},{"text":" must be a JSON-serialized string no larger than 30 KB.","type":"text"},{"text":"Must-read","type":"text","marks":[{"type":"link","attrs":{"href":"references/card/lark-im-card-create.md","title":null}}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"urgent_app","type":"text","marks":[{"type":"code_inline"}]},{"text":" — 发送应用内加急。Identity: ","type":"text"},{"text":"bot","type":"text","marks":[{"type":"code_inline"}]},{"text":" only (","type":"text"},{"text":"tenant_access_token","type":"text","marks":[{"type":"code_inline"}]},{"text":"); the bot must be the message sender and must be in the conversation that contains the message.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"urgent_phone","type":"text","marks":[{"type":"code_inline"}]},{"text":" — 发送电话加急。Identity: ","type":"text"},{"text":"bot","type":"text","marks":[{"type":"code_inline"}]},{"text":" only (","type":"text"},{"text":"tenant_access_token","type":"text","marks":[{"type":"code_inline"}]},{"text":"); the bot must be the message sender and must be in the conversation that contains the message.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"urgent_sms","type":"text","marks":[{"type":"code_inline"}]},{"text":" — 发送短信加急。Identity: ","type":"text"},{"text":"bot","type":"text","marks":[{"type":"code_inline"}]},{"text":" only (","type":"text"},{"text":"tenant_access_token","type":"text","marks":[{"type":"code_inline"}]},{"text":"); the bot must be the message sender and must be in the conversation that contains the message.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"reactions","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"batch_query","type":"text","marks":[{"type":"code_inline"}]},{"text":" — 批量获取消息表情。Identity: supports ","type":"text"},{"text":"user","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"bot","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"},{"text":"Must-read","type":"text","marks":[{"type":"link","attrs":{"href":"references/lark-im-reactions.md","title":null}}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"create","type":"text","marks":[{"type":"code_inline"}]},{"text":" — 添加消息表情回复。Identity: supports ","type":"text"},{"text":"user","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"bot","type":"text","marks":[{"type":"code_inline"}]},{"text":"; the caller must be in the conversation that contains the message.","type":"text"},{"text":"Must-read","type":"text","marks":[{"type":"link","attrs":{"href":"references/lark-im-reactions.md","title":null}}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"delete","type":"text","marks":[{"type":"code_inline"}]},{"text":" — 删除消息表情回复。Identity: supports ","type":"text"},{"text":"user","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"bot","type":"text","marks":[{"type":"code_inline"}]},{"text":"; the caller must be in the conversation that contains the message, and can only delete reactions added by itself.","type":"text"},{"text":"Must-read","type":"text","marks":[{"type":"link","attrs":{"href":"references/lark-im-reactions.md","title":null}}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"list","type":"text","marks":[{"type":"code_inline"}]},{"text":" — 获取消息表情回复。Identity: supports ","type":"text"},{"text":"user","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"bot","type":"text","marks":[{"type":"code_inline"}]},{"text":"; the caller must be in the conversation that contains the message.","type":"text"},{"text":"Must-read","type":"text","marks":[{"type":"link","attrs":{"href":"references/lark-im-reactions.md","title":null}}]}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"threads","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"forward","type":"text","marks":[{"type":"code_inline"}]},{"text":" — 转发话题。Identity: supports ","type":"text"},{"text":"user","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"bot","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"images","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"create","type":"text","marks":[{"type":"code_inline"}]},{"text":" — 上传图片。Identity: supports ","type":"text"},{"text":"user","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"bot","type":"text","marks":[{"type":"code_inline"}]},{"text":"; user identity requires ","type":"text"},{"text":"im:resource","type":"text","marks":[{"type":"code_inline"}]},{"text":" scope on the UAT.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"files","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"create","type":"text","marks":[{"type":"code_inline"}]},{"text":" — 上传文件。Identity: supports ","type":"text"},{"text":"user","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"bot","type":"text","marks":[{"type":"code_inline"}]},{"text":"; user identity requires ","type":"text"},{"text":"im:resource","type":"text","marks":[{"type":"code_inline"}]},{"text":" scope on the UAT.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"pins","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"create","type":"text","marks":[{"type":"code_inline"}]},{"text":" — Pin 消息。Identity: supports ","type":"text"},{"text":"user","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"bot","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"delete","type":"text","marks":[{"type":"code_inline"}]},{"text":" — 移除 Pin 消息。Identity: supports ","type":"text"},{"text":"user","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"bot","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"list","type":"text","marks":[{"type":"code_inline"}]},{"text":" — 获取群内 Pin 消息。Identity: supports ","type":"text"},{"text":"user","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"bot","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"feed.groups","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"batch_add_item","type":"text","marks":[{"type":"code_inline"}]},{"text":" — Batch add feed cards to a feed group. Identity: ","type":"text"},{"text":"user","type":"text","marks":[{"type":"code_inline"}]},{"text":" only (","type":"text"},{"text":"user_access_token","type":"text","marks":[{"type":"code_inline"}]},{"text":").","type":"text"},{"text":"Must-read","type":"text","marks":[{"type":"link","attrs":{"href":"references/lark-im-feed-groups.md","title":null}}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"batch_query","type":"text","marks":[{"type":"code_inline"}]},{"text":" — Batch query feed groups. Identity: ","type":"text"},{"text":"user","type":"text","marks":[{"type":"code_inline"}]},{"text":" only (","type":"text"},{"text":"user_access_token","type":"text","marks":[{"type":"code_inline"}]},{"text":").","type":"text"},{"text":"Must-read","type":"text","marks":[{"type":"link","attrs":{"href":"references/lark-im-feed-groups.md","title":null}}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"batch_remove_item","type":"text","marks":[{"type":"code_inline"}]},{"text":" — Batch remove feed cards from a feed group. Identity: ","type":"text"},{"text":"user","type":"text","marks":[{"type":"code_inline"}]},{"text":" only (","type":"text"},{"text":"user_access_token","type":"text","marks":[{"type":"code_inline"}]},{"text":").","type":"text"},{"text":"Must-read","type":"text","marks":[{"type":"link","attrs":{"href":"references/lark-im-feed-groups.md","title":null}}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"create","type":"text","marks":[{"type":"code_inline"}]},{"text":" — Create a feed group. Identity: ","type":"text"},{"text":"user","type":"text","marks":[{"type":"code_inline"}]},{"text":" only (","type":"text"},{"text":"user_access_token","type":"text","marks":[{"type":"code_inline"}]},{"text":").","type":"text"},{"text":"Must-read","type":"text","marks":[{"type":"link","attrs":{"href":"references/lark-im-feed-groups.md","title":null}}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"delete","type":"text","marks":[{"type":"code_inline"}]},{"text":" — Delete a feed group. Identity: ","type":"text"},{"text":"user","type":"text","marks":[{"type":"code_inline"}]},{"text":" only (","type":"text"},{"text":"user_access_token","type":"text","marks":[{"type":"code_inline"}]},{"text":").","type":"text"},{"text":"Must-read","type":"text","marks":[{"type":"link","attrs":{"href":"references/lark-im-feed-groups.md","title":null}}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"update","type":"text","marks":[{"type":"code_inline"}]},{"text":" — Update a feed group. Identity: ","type":"text"},{"text":"user","type":"text","marks":[{"type":"code_inline"}]},{"text":" only (","type":"text"},{"text":"user_access_token","type":"text","marks":[{"type":"code_inline"}]},{"text":").","type":"text"},{"text":"Must-read","type":"text","marks":[{"type":"link","attrs":{"href":"references/lark-im-feed-groups.md","title":null}}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"权限表","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"方法","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"所需 scope","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"chats.create","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"im:chat:create","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"chats.get","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"im:chat:read","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"chats.link","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"im:chat:read","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"chats.update","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"im:chat:update","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"chat.members.create","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"im:chat.members:write_only","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"chat.members.delete","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"im:chat.members:write_only","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"chat.members.get","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"im:chat.members:read","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"+chat-members-list","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"im:chat.members:read","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"chat.user_setting.batch_query","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"im:chat.user_setting:read","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"chat.user_setting.batch_update","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"im:chat.user_setting:write","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"chat.managers.add_managers","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"im:chat.managers:write_only","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"chat.managers.delete_managers","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"im:chat.managers:write_only","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"chat.moderation.get","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"im:chat.moderation:read","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"chat.moderation.update","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"im:chat:moderation:write_only","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"chat.join_requests.list","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"im:chat.membership_application:read","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"chat.join_requests.handle","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"im:chat.membership_application:write","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"+messages-read-status","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"user: ","type":"text"},{"text":"im:message:readonly","type":"text","marks":[{"type":"code_inline"}]},{"text":" (recommended), ","type":"text"},{"text":"im:message","type":"text","marks":[{"type":"code_inline"}]},{"text":", or ","type":"text"},{"text":"im:message:get_as_user","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"+message-read-users","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"user: ","type":"text"},{"text":"im:message:readonly","type":"text","marks":[{"type":"code_inline"}]},{"text":" (recommended), ","type":"text"},{"text":"im:message","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"im:message:basic","type":"text","marks":[{"type":"code_inline"}]},{"text":", or ","type":"text"},{"text":"im:message:get_as_user","type":"text","marks":[{"type":"code_inline"}]},{"text":"; bot: ","type":"text"},{"text":"im:message:readonly","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"messages.read_status","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"im:message:readonly","type":"text","marks":[{"type":"code_inline"}]},{"text":" (recommended), ","type":"text"},{"text":"im:message","type":"text","marks":[{"type":"code_inline"}]},{"text":", or ","type":"text"},{"text":"im:message:get_as_user","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"messages.delete","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"im:message:recall","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"messages.forward","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"im:message","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"messages.merge_forward","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"im:message","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"messages.read_users","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"user: ","type":"text"},{"text":"im:message:readonly","type":"text","marks":[{"type":"code_inline"}]},{"text":" (recommended), ","type":"text"},{"text":"im:message","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"im:message:basic","type":"text","marks":[{"type":"code_inline"}]},{"text":", or ","type":"text"},{"text":"im:message:get_as_user","type":"text","marks":[{"type":"code_inline"}]},{"text":"; bot: ","type":"text"},{"text":"im:message:readonly","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"messages.patch","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"im:message:update","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"messages.urgent_app","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"im:message.urgent","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"messages.urgent_phone","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"im:message.urgent:phone","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"messages.urgent_sms","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"im:message.urgent:sms","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"reactions.batch_query","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"im:message.reactions:read","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"reactions.create","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"im:message.reactions:write_only","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"reactions.delete","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"im:message.reactions:write_only","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"reactions.list","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"im:message.reactions:read","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"threads.forward","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"im:message","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"images.create","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"im:resource","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"files.create","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"im:resource","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"pins.create","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"im:message.pins:write_only","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"pins.delete","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"im:message.pins:write_only","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"pins.list","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"im:message.pins:read","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"feed.groups.batch_add_item","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"im:feed_group_v1:write","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"feed.groups.batch_query","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"im:feed_group_v1:read","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"feed.groups.batch_remove_item","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"im:feed_group_v1:write","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"feed.groups.create","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"im:feed_group_v1:write","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"feed.groups.delete","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"im:feed_group_v1:write","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"feed.groups.update","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"im:feed_group_v1:write","type":"text","marks":[{"type":"code_inline"}]}]}]}]}]}]},"metadata":{"date":"2026-11-02","name":"lark-im","author":"@skillopedia","source":{"stars":17934,"repo_name":"cli","origin_url":"https://github.com/larksuite/cli/blob/HEAD/skills/lark-im/SKILL.md","repo_owner":"larksuite","body_sha256":"b880737bd5a6cfebf38a33493f3f37c492133d12e673016097a12a04dd7d2f9c","cluster_key":"ee7accd97a6812e1331233b59d4eb55003fb798435c3fa38ee3cb6e792fcb079","clean_bundle":{"format":"clean-skill-bundle-v1","source":"larksuite/cli/skills/lark-im/SKILL.md","text_bytes":292431,"source_commit":"f31194b461afbd75479d12850b0f9cb9427cb762","skills_sh_rank":133,"attachment_count":60,"text_attachments":60,"attachment_storage":"skill_attachments","binary_attachments":0},"cluster_size":1,"skill_md_path":"skills/lark-im/SKILL.md","import_metadata":{"date":"2026-11-02","author":"@skillopedia","version":"1.0.0","category":"integrations-apis","category_label":"Integrations"},"exact_dupes_collapsed_into_this":0},"version":"1.0.0","category":"integrations-apis","metadata":{"cliHelp":"lark-cli im --help","requires":{"bins":["lark-cli"]}},"import_tag":"skills-sh-top20k-2026-11","description":"飞书即时通讯:收发消息和管理群聊。发送和回复消息、搜索聊天记录、管理群聊成员、上传下载图片和文件、管理表情回复、发送应用内/短信/电话加急、发送和处理交互卡片(Interactive Card)、监听卡片按钮回调(card.action.trigger)。当用户需要发消息、查看或搜索聊天记录、下载聊天中的文件、查看群成员、搜索群、创建群聊或话题群、管理标记数据、管理 Feed 置顶(添加/移除/查询置顶会话)、管理标签数据、处理卡片回调时使用。"}},"renderedAt":1793666654362}

im (v1) CRITICAL — 开始前 MUST 先用 Read 工具读取 ,其中包含认证、权限处理 Core Concepts - Message : A single message in a chat, identified by (om xxx). Supports types: text, post, image, file, audio, video, sticker, interactive (card), share chat, share user, merge forward, etc. - Chat : A group chat or P2P conversation, identified by (oc xxx). - Thread : A reply thread under a message, identified by (om xxx or omt xxx). - Reaction : An emoji reaction on a message. - Flag : A bookmark on a message or thread. - Feed Shortcut : A chat pinned to the current user's feed sidebar, identified by (an open chat id for CH…