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. Resource Relationships Important Notes Identity and Token Mapping - means user identity and uses . Calls run as the authorized end user, so permissio…

...'`.\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. Resource Relationships Important Notes Identity and Token Mapping - means user identity and uses . Calls run as the authorized end user, so permissio…

...'`:\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. Resource Relationships Important Notes Identity and Token Mapping - means user identity and uses . Calls run as the authorized end user, so permissio…

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. Resource Relationships Important Notes Identity and Token Mapping - means user identity and uses . Calls run as the authorized end user, so permissio…

```sql\\nselect * from jobs;\\n```'\n```\n\nThis keeps the reply as plain text instead of converting it to a `post`.\n\n### When formatting does not need exact preservation\n\nUse `--markdown`:\n\n```bash\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. Resource Relationships Important Notes Identity and Token Mapping - means user identity and uses . Calls run as the authorized end user, so permissio…

## Follow-up\\n\\n- I reproduced it\\n- I am fixing it'\n```\n\nThis is better for quick readable formatting, but the final payload may still differ from the source text because headings and spacing are normalized before sending.\n\n## Commands\n\n```bash\n# Reply to a message (plain text, --text is recommended for normal replies)\nlark-cli im +messages-reply --message-id om_xxx --text \"Received\"\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. Resource Relationships Important Notes Identity and Token Mapping - means user identity and uses . Calls run as the authorized end user, so permissio…

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 basic Markdown (will be converted to post JSON)\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. Resource Relationships Important Notes Identity and Token Mapping - means user identity and uses . Calls run as the authorized end user, so permissio…

## Reply\\n\\n- item 1\\n- item 2'\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# 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. Resource Relationships Important Notes Identity and Token Mapping - means user identity and uses . Calls run as the authorized end user, so permissio…

## Test\\n\\nhello' --dry-run\n```\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. Best default when you need exact text and formatting preservation |\n| `--markdown \u003cstring>` | One content option | Convenience Markdown input. Internally converted to `post` JSON with Feishu-specific normalization |\n| `--image \u003cpath\\|key>` | One content option | Local image path or `image_key` (`img_xxx`) |\n| `--file \u003cpath\\|key>` | One content option | Local file path or `file_key` (`file_xxx`) |\n| `--video \u003cpath\\|key>` | One content option | Local video path or `file_key`; **must be used together with `--video-cover`** |\n| `--video-cover \u003cpath\\|key>` | **Required with `--video`** | Video cover image path or `image_key` (`img_xxx`) |\n| `--audio \u003cpath\\|key>` | One content option | Local audio path or `file_key` |\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; the same key sends only one reply within 1 hour |\n| `--as \u003cidentity>` | No | Identity type: `bot` only |\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 `--markdown` when you actually need exact plain text. If exact line breaks and spacing 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. Resource Relationships Important Notes Identity and Token Mapping - means user identity and uses . Calls run as the authorized end user, so permissio…

...'`.\n- Assuming `--markdown` supports all Markdown features. It does not; it is converted into a Feishu `post` payload and rewritten first.\n- Putting local image paths inside Markdown like `![x](./a.png)`. `--markdown` does not auto-upload those paths.\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\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 (text / post)\n\n- Recommended format: `\u003cat user_id=\"ou_xxx\">name\u003c/at>`\n- @all: `\u003cat user_id=\"all\">\u003c/at>`\n- The shortcut normalizes common variants like `\u003cat id=...>` and `\u003cat open_id=...>` into `user_id`, but `user_id` remains the recommended documented form\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 local file paths; the shortcut uploads first and then sends the reply\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 bot` uses a tenant access token (TAT), and requires the `im:message:send_as_bot` scope","content_type":"text/markdown; charset=utf-8","language":"markdown","size":10469,"content_sha256":"211bc8f1eb5b23813dcb8fd29c7ce6259152edd1e507c826759d926d6fc5c0b4"},{"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 image or file resources from a message. Resources are identified by the combination of `message_id` + `file_key`, both of which come directly from message content returned by `im +chat-messages-list`.\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\nThis skill maps to the shortcut: `lark-cli im +messages-resources-download` (internally calls `GET /open-apis/im/v1/messages/{message_id}/resources/{file_key}`).\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 paths only; `..` traversal is not allowed; defaults to `file_key` as the file name) |\n| `--as \u003cidentity>` | No | Identity type: `user` (default) or `bot` |\n| `--dry-run` | No | Print the request only, do not execute it |\n\n## `file_key` Sources\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\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| Download failed | `file_key` does not match the `message_id` | Make sure the `file_key` came from that message's content |\n| Hit error code 234002 or 14005 | No permission, **not** missing API scope | no access to this chat or file was deleted — do not retry, return the error to the user |\n| Permission denied | `im:message:readonly` is not authorized | Run `auth login --scope \"im:message:readonly\"` |\n| File too large | Over the 100 MB limit | This is a Feishu API limitation and cannot be bypassed with this endpoint |\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":3679,"content_sha256":"85c439d7fbaf35708fc8fbcfa0e601c7b7acaf6e9f5d0ca23cc40c3476a069a1"},{"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\n> **User identity only** (`--as user`). Bot identity is not supported.\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# 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| `--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 | Pagination token for the next page |\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 (defaults to and only supports `user`) |\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- `--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]`; 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### 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 `im chats 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":11110,"content_sha256":"d00a8604eec0e255e2ebd84b5465cb0b19be1fd6733d4e5735333cb93533d6cc"},{"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. Only supports bot identity.\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 (bot only)\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\n## Choose The Right Content Flag\n\n| Need | Recommended flag | Why |\n|------|------|------|\n| Send plain text exactly as written | `--text` | Wrapped directly to `{\"text\":\"...\"}`; no Markdown conversion |\n| Send simple Markdown and accept Feishu-style rendering | `--markdown` | Automatically converted to `post` JSON |\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 local files automatically |\n\n### `--text` vs `--markdown`\n\n- Use `--text` when the content should stay as plain text, including exact line breaks, indentation, code samples, shell snippets, or Markdown characters that should **not** be reinterpreted.\n- Use `--markdown` when you want basic Markdown-style rendering and you accept that the shortcut will normalize and rewrite parts of the content before sending.\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` is **not** sent as raw Markdown API content.\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 means `--markdown` is convenient, but it is not a full-fidelity Markdown transport.\n\n### Current Markdown Caveats\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- Only `http://...`, `https://...`, or already-uploaded `img_xxx` Markdown images are kept reliably.\n- Local paths in Markdown image syntax like `![x](./a.png)` are **not** auto-uploaded by `--markdown`; they may be stripped during optimization.\n- If remote Markdown image download/upload fails, that image is removed with a warning.\n\nIf any of the above is unacceptable, do **not** use `--markdown`; use `--content` and provide the final JSON yourself.\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. Resource Relationships Important Notes Identity and Token Mapping - means user identity and uses . Calls run as the authorized end user, so permissio…

...'`.\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. Resource Relationships Important Notes Identity and Token Mapping - means user identity and uses . Calls run as the authorized end user, so permissio…

...'`:\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. Resource Relationships Important Notes Identity and Token Mapping - means user identity and uses . Calls run as the authorized end user, so permissio…

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. Resource Relationships Important Notes Identity and Token Mapping - means user identity and uses . Calls run as the authorized end user, so permissio…

```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### When formatting does not need exact preservation\n\nUse `--markdown`:\n\n```bash\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. Resource Relationships Important Notes Identity and Token Mapping - means user identity and uses . Calls run as the authorized end user, so permissio…

## Release Notes\\n\\n- Added send shortcut\\n- Added reply shortcut'\n```\n\nThis is better for lightweight readable formatting, but the final content may not match the source text byte-for-byte because the shortcut normalizes headings and spacing before sending.\n\n## Commands\n\n```bash\n# Send plain text (--text is recommended for normal messages)\nlark-cli im +messages-send --chat-id oc_xxx --text \"Hello\"\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. Resource Relationships Important Notes Identity and Token Mapping - means user identity and uses . Calls run as the authorized end user, so permissio…

Line 1\\nLine 2\\n indented line'\n\n# Send basic Markdown (will be converted to post JSON)\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. Resource Relationships Important Notes Identity and Token Mapping - means user identity and uses . Calls run as the authorized end user, so permissio…

## Update\\n\\n- item 1\\n- item 2'\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 audio\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. Resource Relationships Important Notes Identity and Token Mapping - means user identity and uses . Calls run as the authorized end user, so permissio…

## Test\\n\\nhello' --dry-run\n```\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. Best default for exact text and preserved formatting. Automatically wrapped as `{\"text\":\"...\"}` |\n| `--markdown \u003cstring>` | One content option | Convenience Markdown input. Internally converted to `post` JSON with Feishu-specific normalization; not full Markdown passthrough |\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\\|key>` | One content option | Local image path or `image_key` (`img_xxx`). Local paths are uploaded automatically |\n| `--file \u003cpath\\|key>` | One content option | Local file path or `file_key` (`file_xxx`). Local paths are uploaded automatically |\n| `--video \u003cpath\\|key>` | One content option | Local video path or `file_key`. Local paths are uploaded automatically. **Must be paired with `--video-cover`** |\n| `--video-cover \u003cpath\\|key>` | **Required with `--video`** | Video cover image path or `image_key` (`img_xxx`). Local paths are uploaded automatically |\n| `--audio \u003cpath\\|key>` | One content option | Local audio path or `file_key`. Local paths are uploaded automatically |\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; the same key sends only one message within 1 hour |\n| `--as \u003cidentity>` | No | Identity type: `bot` only |\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 `--markdown` when you actually need exact plain text. If exact line breaks and spacing 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. Resource Relationships Important Notes Identity and Token Mapping - means user identity and uses . Calls run as the authorized end user, so permissio…

...'`.\n- Assuming `--markdown` supports all Markdown features. It does not; it is converted into a Feishu `post` payload and rewritten first.\n- Putting local image paths inside Markdown like `![x](./a.png)`. `--markdown` does not auto-upload those paths.\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\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\"}]]}}` |\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 (see Feishu interactive card documentation) |\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 (text / post)\n\n- Recommended format: `\u003cat user_id=\"ou_xxx\">name\u003c/at>`\n- @all: `\u003cat user_id=\"all\">\u003c/at>`\n- The shortcut normalizes common variants like `\u003cat id=...>` and `\u003cat open_id=...>` into `user_id`, but you should still document examples with `user_id`\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 local file paths; the shortcut uploads first and then sends the message\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 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","content_type":"text/markdown; charset=utf-8","language":"markdown","size":11615,"content_sha256":"de13a42c52568d2f8a0dc14555b5a5412d1a6e8a39b0ca35dc41b86e354b5146"},{"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\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":9941,"content_sha256":"97f0cd3b0d3e672f150314fc7e41534b78244af78eeecd34b00949bb765e1945"},{"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\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 --sort 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# 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# 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| `--sort \u003corder>` | No | Sort order: `asc` (default) / `desc` |\n| `--page-size \u003cn>` | No | Number of items per page (default 50, range 1-500) |\n| `--page-token \u003ctoken>` | No | Pagination token for the next page |\n| `--format \u003cfmt>` | No | Output format: `json` (default) / `pretty` / `table` / `ndjson` / `csv` |\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\n- When the result includes `has_more=true`, use `page_token` to fetch the next page\n- If you need the complete thread, keep paginating; if you only need an overview, the first page is often enough\n\n### 4. Recommended expansion strategy\n\n| Scenario | Recommended Parameters |\n|------|---------|\n| Quickly inspect recent replies | `--sort desc --page-size 10` |\n| Read the full thread in chronological order | `--sort asc --page-size 50`, then paginate as needed |\n| Just confirm whether replies exist | `--sort 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]`; resource binaries are **not** downloaded automatically.\n\nOther resource types (files, audio, video) still need to be downloaded 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":4830,"content_sha256":"820573d2a8e7ce447bdc4189eda6acc635019f50b79a06b61294055f3804a5cc"},{"filename":"skill-report.json","content":"{\n \"schema_version\": \"2.0\",\n \"meta\": {\n \"generated_at\": \"2026-03-31T08:32:52.997Z\",\n \"slug\": \"larksuite-lark-im\",\n \"source_url\": \"https://github.com/larksuite/cli/tree/main/skills/lark-im/\",\n \"source_ref\": \"main\",\n \"model\": \"claude\",\n \"analysis_version\": \"3.0.0\",\n \"source_type\": \"community\",\n \"content_hash\": \"e3183c8acd3dc4b7d83a0d86c2e0d9dfcdbc0abbf3bc65009ab46dcf41e91c5c\",\n \"tree_hash\": \"323e515794c2f718d7aad782d8bc4b7aba741df9a9896f6dfea76ee361af204e\"\n },\n \"skill\": {\n \"name\": \"lark-im\",\n \"description\": \"Lark/Feishu IM integration: Send and receive messages, manage group chats, search message history, and handle file resources through the lark-cli tool.\",\n \"summary\": \"Comprehensive Lark/Feishu instant messaging integration for sending messages, managing chats, searching history, and handling file resources.\",\n \"icon\": \"💬\",\n \"version\": \"1.0.0\",\n \"author\": \"larksuite\",\n \"license\": \"MIT\",\n \"category\": \"communication\",\n \"tags\": [\n \"lark\",\n \"feishu\",\n \"messaging\",\n \"chat\",\n \"communication\"\n ],\n \"supported_tools\": [\n \"claude\",\n \"codex\",\n \"claude-code\"\n ],\n \"risk_factors\": [\n \"external_commands\",\n \"filesystem\",\n \"network\"\n ]\n },\n \"security_audit\": {\n \"risk_level\": \"low\",\n \"is_blocked\": false,\n \"safe_to_publish\": true,\n \"summary\": \"This is a legitimate Lark/Feishu IM integration skill using the lark-cli tool. Static analysis flagged 1397 patterns (external_commands: 1121, filesystem: 68, network: 9), but evaluation confirms these are FALSE POSITIVES. The 'external_commands' are documented CLI usage examples in markdown, 'path traversal' references are relative documentation links, and 'crypto' flags are API token references. The skill requires explicit user confirmation before sending messages and follows proper authentication protocols.\",\n \"risk_factor_evidence\": [\n {\n \"factor\": \"external_commands\",\n \"evidence\": [\n {\n \"file\": \"SKILL.md\",\n \"line_start\": 13,\n \"line_end\": 13\n }\n ]\n },\n {\n \"factor\": \"filesystem\",\n \"evidence\": [\n {\n \"file\": \"references/lark-im-messages-resources-download.md\",\n \"line_start\": 37,\n \"line_end\": 37\n }\n ]\n },\n {\n \"factor\": \"network\",\n \"evidence\": [\n {\n \"file\": \"references/lark-im-messages-send.md\",\n \"line_start\": 43,\n \"line_end\": 43\n }\n ]\n }\n ],\n \"files_scanned\": 13,\n \"total_lines\": 1911,\n \"audit_model\": \"claude\",\n \"audited_at\": \"2026-03-31T08:35:00.000Z\",\n \"medium_findings\": [\n {\n \"title\": \"External Command Execution via CLI Tool\",\n \"description\": \"Skill uses lark-cli binary for all operations. This is declared in metadata requires.bins and is expected for CLI-based skills. Commands are structured with hardcoded arguments, not user input injection. Risk mitigated by CLI tool being pre-approved and commands being template-based.\",\n \"locations\": [\n {\n \"file\": \"SKILL.md\",\n \"line_start\": 7,\n \"line_end\": 8\n }\n ],\n \"confidence\": 0.85,\n \"confidence_reasoning\": \"CLI usage is documented and structured - commands follow predictable patterns with no dynamic user input injection vectors detected\"\n }\n ],\n \"low_findings\": [\n {\n \"title\": \"File Download Capability\",\n \"description\": \"Skill can download files from Lark messages to local filesystem. Output paths are validated to prevent traversal attacks (.. not allowed). User must explicitly specify output path.\",\n \"locations\": [\n {\n \"file\": \"references/lark-im-messages-resources-download.md\",\n \"line_start\": 37,\n \"line_end\": 37\n }\n ],\n \"confidence\": 0.9,\n \"confidence_reasoning\": \"File download feature explicitly documented with path validation rules preventing traversal attacks\"\n },\n {\n \"title\": \"API Endpoint References\",\n \"description\": \"Documentation contains hardcoded Lark/Feishu API URLs. These are expected for API integration skills and point to official endpoints only.\",\n \"locations\": [\n {\n \"file\": \"references/lark-im-messages-send.md\",\n \"line_start\": 7,\n \"line_end\": 7\n }\n ],\n \"confidence\": 0.95,\n \"confidence_reasoning\": \"API URLs are documented endpoints for the official Lark/Feishu platform - standard for integration skills\"\n }\n ],\n \"dangerous_patterns\": []\n },\n \"content\": {\n \"user_title\": \"Send messages and manage Lark/Feishu chats\",\n \"value_statement\": \"Integrate Claude with Lark/Feishu messaging to send messages, manage group chats, search conversation history, and handle file resources. Automate team communication workflows with secure bot or user identity authentication.\",\n \"seo_keywords\": [\n \"Lark IM integration\",\n \"Feishu messaging\",\n \"Claude Code chat\",\n \"Lark bot\",\n \"Feishu API\",\n \"Claude messenger\",\n \"Lark group chat\",\n \"Codex communication\",\n \"team messaging automation\",\n \"Lark CLI tool\"\n ],\n \"actual_capabilities\": [\n \"Send text, markdown, post, image, file, video, and audio messages to Lark/Feishu chats\",\n \"Create, update, and manage group chats with user and bot members\",\n \"Search messages across chats with keyword, sender, and time range filters\",\n \"List messages in chats and threads with pagination support\",\n \"Download images and files from messages to local storage\",\n \"Add reactions to messages and manage emoji responses\",\n \"Pin messages and manage chat member lists\"\n ],\n \"limitations\": [\n \"Requires lark-cli tool to be installed and authenticated with Lark/Feishu\",\n \"Bot identity operations require the bot to be added to target chats\",\n \"User identity operations require explicit user authentication via access tokens\",\n \"Cannot send messages without explicit user confirmation of recipient and content\"\n ],\n \"use_cases\": [\n {\n \"title\": \"Team Communication Automation\",\n \"description\": \"Automate sending project updates, status reports, or alerts to team group chats. Schedule regular messages or trigger notifications based on external events.\",\n \"target_user\": \"Engineering managers and team leads\"\n },\n {\n \"title\": \"Customer Support Integration\",\n \"description\": \"Connect Claude to Lark support channels to respond to customer inquiries, search conversation history for context, and escalate issues by pinging team members.\",\n \"target_user\": \"Customer support teams\"\n },\n {\n \"title\": \"Personal Productivity Assistant\",\n \"description\": \"Use Claude to search your message history, download shared files, organize chat resources, and draft responses for review before sending.\",\n \"target_user\": \"Individual knowledge workers\"\n }\n ],\n \"prompt_templates\": [\n {\n \"title\": \"Beginner: Send a text message\",\n \"prompt\": \"Send a message to the team group chat saying \\\"Meeting starts in 10 minutes in Conference Room A\\\"\"\n },\n {\n \"title\": \"Intermediate: Search message history\",\n \"prompt\": \"Search my messages for any files shared by [user_name] in the last week about the project roadmap\"\n },\n {\n \"title\": \"Advanced: Create and configure a group chat\",\n \"prompt\": \"Create a new private group called \\\"Q2 Planning\\\" with the following team members: [list open_ids], set the description to \\\"Quarterly planning discussions\\\", and make the bot a group manager\"\n },\n {\n \"title\": \"Expert: Download and organize chat resources\",\n \"prompt\": \"Find all images shared in the [chat_name] chat this month, download them to ./downloads/ with organized filenames, and create a summary list of what was downloaded\"\n }\n ],\n \"output_examples\": [\n {\n \"input\": \"Send a message to chat oc_123 saying hello\",\n \"output\": \"Message sent successfully to chat oc_123 (Engineering Team). Message ID: om_abc123. The bot posted: \\\"hello\\\"\"\n },\n {\n \"input\": \"Search for messages containing \\\"budget\\\" from last month\",\n \"output\": \"Found 15 messages matching \\\"budget\\\" across 3 chats. Results include messages from Finance Team chat and Project Alpha chat, with dates ranging from Feb 1-28. Top result: spreadsheet attachment shared by Finance Director on Feb 15.\"\n },\n {\n \"input\": \"Download the image from message om_xyz789\",\n \"output\": \"Downloaded image img_v3_abc123 from message om_xyz789. Saved to: ./img_v3_abc123.png (2.4 MB). File type verified as PNG image.\"\n }\n ],\n \"best_practices\": [\n \"Always confirm message recipient and content with the user before sending any message\",\n \"Use bot identity for automated notifications and user identity for personal assistant tasks\",\n \"Verify chat membership before attempting operations - bots must be added to target chats\",\n \"Handle pagination for large result sets using --page-limit or --page-all flags\",\n \"Use dry-run mode to preview API calls before executing sensitive operations\"\n ],\n \"anti_patterns\": [\n \"Never send messages on behalf of users without explicit confirmation of content and recipient\",\n \"Do not guess user open_ids or chat_ids - always fetch them via the appropriate lookup commands first\",\n \"Avoid sending raw markdown with complex formatting - use --content flag for precise control\",\n \"Do not attempt to download files without user specifying a safe output location\"\n ],\n \"faq\": [\n {\n \"question\": \"What authentication is required to use this skill?\",\n \"answer\": \"You need to authenticate with Lark/Feishu using lark-cli. Run lark-cli auth login first. Bot operations use tenant_access_token; user operations use user_access_token.\"\n },\n {\n \"question\": \"Can this skill send messages as me or as a bot?\",\n \"answer\": \"Both. Use --as user for personal messages (sent as you) or --as bot for automated messages (sent as the app bot). Bot identity requires the bot to be added to target chats.\"\n },\n {\n \"question\": \"How do I find a chat_id or user open_id?\",\n \"answer\": \"Use +chat-search to find groups by name or keyword. Use contact +get-user to look up a user's open_id. The skill cannot operate without these identifiers.\"\n },\n {\n \"question\": \"Why can't the bot resolve sender names in fetched messages?\",\n \"answer\": \"Bot visibility settings may not include the message senders. Check app visibility in Lark Developer Console or use --as user to fetch messages with broader contact access.\"\n },\n {\n \"question\": \"Can this skill download files from any chat?\",\n \"answer\": \"Only chats where the authenticated user or bot has access. The caller must be a chat member. Files must be under 100MB (Lark API limit).\"\n },\n {\n \"question\": \"What message types does this skill support?\",\n \"answer\": \"Text, markdown, post (rich formatted), image, file, video, audio, sticker, interactive cards, share_chat, share_user, and merged forward messages.\"\n }\n ]\n },\n \"file_structure\": [\n {\n \"name\": \"references\",\n \"type\": \"dir\",\n \"path\": \"references\",\n \"children\": [\n {\n \"name\": \"lark-im-chat-create.md\",\n \"type\": \"file\",\n \"path\": \"references/lark-im-chat-create.md\",\n \"lines\": 137\n },\n {\n \"name\": \"lark-im-chat-identity.md\",\n \"type\": \"file\",\n \"path\": \"references/lark-im-chat-identity.md\",\n \"lines\": 56\n },\n {\n \"name\": \"lark-im-chat-messages-list.md\",\n \"type\": \"file\",\n \"path\": \"references/lark-im-chat-messages-list.md\",\n \"lines\": 142\n },\n {\n \"name\": \"lark-im-chat-search.md\",\n \"type\": \"file\",\n \"path\": \"references/lark-im-chat-search.md\",\n \"lines\": 115\n },\n {\n \"name\": \"lark-im-chat-update.md\",\n \"type\": \"file\",\n \"path\": \"references/lark-im-chat-update.md\",\n \"lines\": 85\n },\n {\n \"name\": \"lark-im-messages-mget.md\",\n \"type\": \"file\",\n \"path\": \"references/lark-im-messages-mget.md\",\n \"lines\": 96\n },\n {\n \"name\": \"lark-im-messages-reply.md\",\n \"type\": \"file\",\n \"path\": \"references/lark-im-messages-reply.md\",\n \"lines\": 219\n },\n {\n \"name\": \"lark-im-messages-resources-download.md\",\n \"type\": \"file\",\n \"path\": \"references/lark-im-messages-resources-download.md\",\n \"lines\": 78\n },\n {\n \"name\": \"lark-im-messages-search.md\",\n \"type\": \"file\",\n \"path\": \"references/lark-im-messages-search.md\",\n \"lines\": 214\n },\n {\n \"name\": \"lark-im-messages-send.md\",\n \"type\": \"file\",\n \"path\": \"references/lark-im-messages-send.md\",\n \"lines\": 220\n },\n {\n \"name\": \"lark-im-reactions.md\",\n \"type\": \"file\",\n \"path\": \"references/lark-im-reactions.md\",\n \"lines\": 298\n },\n {\n \"name\": \"lark-im-threads-messages-list.md\",\n \"type\": \"file\",\n \"path\": \"references/lark-im-threads-messages-list.md\",\n \"lines\": 112\n }\n ]\n },\n {\n \"name\": \"SKILL.md\",\n \"type\": \"file\",\n \"path\": \"SKILL.md\",\n \"lines\": 139\n }\n ]\n}\n","content_type":"application/json; charset=utf-8","language":"json","size":13868,"content_sha256":"c60c058927befe828d5f09e63fda22f4e6f61dd4e973b41c8c1d618f93a26d6f"}],"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":"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":"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 with Bot Identity","type":"text"}]},{"type":"paragraph","content":[{"text":"When using bot identity (","type":"text"},{"text":"--as bot","type":"text","marks":[{"type":"code_inline"}]},{"text":") to fetch messages (e.g. ","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":"), sender names may not be resolved (shown as open_id instead of display name). This happens when the bot cannot access the user's contact info.","type":"text"}]},{"type":"paragraph","content":[{"text":"Root cause","type":"text","marks":[{"type":"strong"}]},{"text":": The bot's app visibility settings do not include the message sender, so the contact API returns no name.","type":"text"}]},{"type":"paragraph","content":[{"text":"Solution","type":"text","marks":[{"type":"strong"}]},{"text":": Check the app's visibility settings in the Lark Developer Console — ensure the app's visible range covers the users whose names need to be resolved. Alternatively, use ","type":"text"},{"text":"--as user","type":"text","marks":[{"type":"code_inline"}]},{"text":" to fetch messages with user identity, which typically has broader contact access.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Card Messages (Interactive)","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":"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 with bot identity; bot-only; creates private/public chats, invites users/bots, optionally sets bot manager","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/sort/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 keyword and/or member open_ids (e.g. look up chat_id by group name); user/bot; supports member/type filters, sorting, and pagination","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":"+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-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) with bot identity; bot-only; 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 images/files from a message; user/bot; downloads image/file resources by message-id and file-key to a safe relative output path","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 identity; user-only; 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 with bot identity; bot-only; 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 sort/pagination","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":"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":".","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":"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 must belong to the same tenant for internal chats.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"messages","type":"text"}]},{"type":"bullet_list","content":[{"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: ","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":"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: ","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 in the chat, and can only query read status for messages it sent within the last 7 days.","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":"images","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":"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":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.list","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.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":"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":"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":"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":"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":"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":"hr","attrs":{"markup":"---"}}]},"metadata":{"date":"2026-06-05","name":"lark-im","author":"@skillopedia","source":{"stars":336,"repo_name":"marketplace","origin_url":"https://github.com/aiskillstore/marketplace/blob/HEAD/skills/larksuite/lark-im/SKILL.md","repo_owner":"aiskillstore","body_sha256":"5c4013d3b4769db73b1415d29ba2e09ef8c7607005f54c30fce9a8d2c47a9f63","cluster_key":"f129e1f738e8ae788aae35a997666186a36b4bc102ea9d38cddbeb4516e9388b","clean_bundle":{"format":"clean-skill-bundle-v1","source":"aiskillstore/marketplace/skills/larksuite/lark-im/SKILL.md","attachments":[{"id":"0a815df9-d088-529c-8e86-5366a87e61d8","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/0a815df9-d088-529c-8e86-5366a87e61d8/attachment.md","path":"references/lark-im-chat-create.md","size":6258,"sha256":"74f44c8944ca13e98f9973a66ae68e6cdc38b91b169e276150b90034463e27d2","contentType":"text/markdown; charset=utf-8"},{"id":"466766e4-a7d0-5f83-ba35-3c02d62c3b09","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/466766e4-a7d0-5f83-ba35-3c02d62c3b09/attachment.md","path":"references/lark-im-chat-identity.md","size":3206,"sha256":"5ea2e5bd60f040bd185738a1c84451db2ad7c3ff4345d75923a6b9564cff5804","contentType":"text/markdown; charset=utf-8"},{"id":"83aca6ab-7aea-5e9e-81dc-bc79b9b5e892","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/83aca6ab-7aea-5e9e-81dc-bc79b9b5e892/attachment.md","path":"references/lark-im-chat-messages-list.md","size":7095,"sha256":"6f214169cc56317f3a2acd782b04843c88b5da8fc17dae97ce9e731e9ed42cbb","contentType":"text/markdown; charset=utf-8"},{"id":"318eab0e-eddd-57c2-8d89-3e164ed4c7bb","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/318eab0e-eddd-57c2-8d89-3e164ed4c7bb/attachment.md","path":"references/lark-im-chat-search.md","size":5827,"sha256":"cc19baa260b5963e331c63641477644b3ec159333cdad89db4515938088b5611","contentType":"text/markdown; charset=utf-8"},{"id":"7a9467fc-3027-5a9b-b44d-091e4a370e49","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/7a9467fc-3027-5a9b-b44d-091e4a370e49/attachment.md","path":"references/lark-im-chat-update.md","size":3281,"sha256":"5e27243b3e230711107f1bf05b99fe282e8b23b0aaeb411e27a7fdc66f689f4a","contentType":"text/markdown; charset=utf-8"},{"id":"6cc754de-66c3-5f48-926c-b865f0365f3b","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/6cc754de-66c3-5f48-926c-b865f0365f3b/attachment.md","path":"references/lark-im-messages-mget.md","size":3449,"sha256":"6ee4a509ebe37849fd7b70d0981a9ce5ecb32ee7ca2100561d27dd630402d85f","contentType":"text/markdown; charset=utf-8"},{"id":"0b78bb6d-845f-5ac8-99fb-3d70429d386b","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/0b78bb6d-845f-5ac8-99fb-3d70429d386b/attachment.md","path":"references/lark-im-messages-reply.md","size":10469,"sha256":"211bc8f1eb5b23813dcb8fd29c7ce6259152edd1e507c826759d926d6fc5c0b4","contentType":"text/markdown; charset=utf-8"},{"id":"87328cbb-e535-57d2-8190-05b01ef7d58a","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/87328cbb-e535-57d2-8190-05b01ef7d58a/attachment.md","path":"references/lark-im-messages-resources-download.md","size":3679,"sha256":"85c439d7fbaf35708fc8fbcfa0e601c7b7acaf6e9f5d0ca23cc40c3476a069a1","contentType":"text/markdown; charset=utf-8"},{"id":"442ddd24-fb6b-5df2-95e3-3ff51d29b3f0","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/442ddd24-fb6b-5df2-95e3-3ff51d29b3f0/attachment.md","path":"references/lark-im-messages-search.md","size":11110,"sha256":"d00a8604eec0e255e2ebd84b5465cb0b19be1fd6733d4e5735333cb93533d6cc","contentType":"text/markdown; charset=utf-8"},{"id":"e8341c19-abd8-5b8e-abdb-34dee743b1fd","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/e8341c19-abd8-5b8e-abdb-34dee743b1fd/attachment.md","path":"references/lark-im-messages-send.md","size":11615,"sha256":"de13a42c52568d2f8a0dc14555b5a5412d1a6e8a39b0ca35dc41b86e354b5146","contentType":"text/markdown; charset=utf-8"},{"id":"f35915c1-66aa-5aac-aa3b-b7d7e816cf65","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/f35915c1-66aa-5aac-aa3b-b7d7e816cf65/attachment.md","path":"references/lark-im-reactions.md","size":9941,"sha256":"97f0cd3b0d3e672f150314fc7e41534b78244af78eeecd34b00949bb765e1945","contentType":"text/markdown; charset=utf-8"},{"id":"d1d17350-219f-5915-8b87-7b70e509a482","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/d1d17350-219f-5915-8b87-7b70e509a482/attachment.md","path":"references/lark-im-threads-messages-list.md","size":4830,"sha256":"820573d2a8e7ce447bdc4189eda6acc635019f50b79a06b61294055f3804a5cc","contentType":"text/markdown; charset=utf-8"},{"id":"270617d1-9f99-5802-a700-5c36cd2fb83c","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/270617d1-9f99-5802-a700-5c36cd2fb83c/attachment.json","path":"skill-report.json","size":13868,"sha256":"c60c058927befe828d5f09e63fda22f4e6f61dd4e973b41c8c1d618f93a26d6f","contentType":"application/json; charset=utf-8"}],"bundle_sha256":"69cec414b16ce11b4af5d4ddef8af84faac4fe2c838b236abdc9261ecb767a79","attachment_count":13,"text_attachments":13,"attachment_storage":"skillopedia-attachments-v1","binary_attachments":0,"excluded_attachments":[]},"cluster_size":1,"skill_md_path":"skills/larksuite/lark-im/SKILL.md","import_metadata":{"date":"2026-06-05","author":"@skillopedia","version":"v1","category":"general","category_label":"General"},"exact_dupes_collapsed_into_this":0},"version":"v1","category":"general","metadata":{"cliHelp":"lark-cli im --help","requires":{"bins":["lark-cli"]}},"import_tag":"clean-skills-v1","description":"飞书即时通讯:收发消息和管理群聊。发送和回复消息、搜索聊天记录、管理群聊成员、上传下载图片和文件、管理表情回复。当用户需要发消息、查看或搜索聊天记录、下载聊天中的文件、查看群成员时使用。"}},"renderedAt":1782987729188}

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. Resource Relationships Important Notes Identity and Token Mapping - means user identity and uses . Calls run as the authorized end user, so permissio…