Feishu Message Sending Skill
Send Feishu messages via feishu-cli, supporting multiple message types and rich message management operations.
Core Concepts
Message Architecture
The
field of Feishu Message API is a
JSON string (not a JSON object). The CLI provides three input methods:
| Input Method | Parameter | Applicable Scenario |
|---|
| Quick Text | | Plain text messages, the simplest option |
| Inline JSON | --content '{"key":"val"}'
or | Simple JSON, can be done in one line |
| JSON File | | Complex messages (cards, rich text, etc.) |
Priority:
>
>
(the former takes precedence when specified simultaneously)
Recipient Types
| --receive-id-type | Description | Example |
|---|
| email | Email address | user@example.com |
| open_id | Open ID | ou_xxx |
| user_id | User ID | xxx |
| union_id | Union ID | on_xxx |
| chat_id | Group Chat ID | oc_xxx |
Message Type Selection
Decision Tree (Automatically selected when Claude doesn't specify type)
Default priority is (card message) with beautiful styling, rich content, and support for colors/multi-columns/buttons, etc.
User Requirement
├─ [Default] Notification/Report/Alert/Any informative message → interactive (card)
├─ Send uploaded image/file/audio/video → image/file/audio/media
├─ Share group chat or user business card → share_chat/share_user
├─ Conversation divider (p2p only) → system
└─ Use text/post only in the following scenarios:
├─ User explicitly requests plain text → text
└─ User explicitly requests rich text → post
Why prioritize cards: text does not support any format rendering, post has limited styling, while cards support colored headers, multi-column fields, buttons, dividers, notes, etc., with visual effects far superior to other types.
Overview of Message Types
| Type | Description | content Format | Size Limit |
|---|
| text | Plain text | | 150 KB |
| post | Rich text | {"zh_cn":{"title":"","content":[[...]]}}
| 150 KB |
| image | Image | | — |
| file | File | {"file_key":"file_v2_xxx"}
| — |
| audio | Voice | {"file_key":"file_v2_xxx"}
| — |
| media | Video | {"file_key":"...","image_key":"..."}
| — |
| sticker | Sticker | {"file_key":"file_v2_xxx"}
| Forward only |
| interactive | Card | Card JSON / template_id / card_id | 30 KB |
| share_chat | Group Chat Card | | — |
| share_user | User Business Card | | — |
| system | System Divider | | P2P only |
Sending Commands
Basic Format
bash
feishu-cli msg send \
--receive-id-type <type> \
--receive-id <id> \
[--msg-type <msg_type>] \
[--text "<text>" | --content '<json>' | --content-file <file.json>]
text Type
bash
# Simplest form (default msg-type is text)
feishu-cli msg send \
--receive-id-type email \
--receive-id user@example.com \
--text "Hello, this is a test message"
Inline syntax supported by text type:
- user:
<at user_id="ou_xxx">Tom</at>
- all users:
Note: text type
does not support rich text styles (bold, italic, underline, strikethrough, hyperlinks, etc. will not be rendered). For formatted layout, use the
type.
post Type (Rich Text)
It is recommended to use the
tag to carry Markdown, with one
tag occupying one paragraph:
bash
cat > /tmp/msg.json << 'EOF'
{
"zh_cn": {
"title": "Project Progress Notification",
"content": [
[{"tag": "md", "text": "**This Week's Progress**\n- Completed Feature A development\n- Fixed 3 Bugs\n- [View Details](https://example.com)"}],
[{"tag": "md", "text": "**Next Week's Plan**\n1. Feature B development\n2. Performance optimization"}]
]
}
}
EOF
feishu-cli msg send \
--receive-id-type email \
--receive-id user@example.com \
--msg-type post \
--content-file /tmp/msg.json
Tag types supported by post:
| tag | Description | Main Attributes |
|---|
| text | Text | text, style (bold/italic/underline/lineThrough) |
| a | Hyperlink | text, href |
| at | @user | user_id, user_name |
| img | Image | image_key, width, height |
| media | Video | file_key, image_key |
| emotion | Emoji | emoji_type |
| hr | Divider | — |
| code_block | Code Block | language, text |
| md | Markdown | text (occupies a single paragraph, recommended) |
interactive Type (Card Message)
There are three ways to send card messages:
Method 1: Complete Card JSON (Recommended, most flexible)
bash
cat > /tmp/card.json << 'EOF'
{
"header": {
"template": "blue",
"title": {"tag": "plain_text", "content": "Task Completion Notification"}
},
"elements": [
{"tag": "markdown", "content": "**Project**: feishu-cli\n**Status**: Completed\n**Responsible Person**: <at id=all></at>"},
{"tag": "hr"},
{"tag": "note", "elements": [{"tag": "plain_text", "content": "Automatically sent by CI/CD"}]}
]
}
EOF
feishu-cli msg send \
--receive-id-type email \
--receive-id user@example.com \
--msg-type interactive \
--content-file /tmp/card.json
Method 2: template_id
bash
cat > /tmp/card.json << 'EOF'
{
"type": "template",
"data": {
"template_id": "AAqk1xxxxxx",
"template_variable": {"name": "Zhang San", "status": "Completed"}
}
}
EOF
feishu-cli msg send \
--receive-id-type email \
--receive-id user@example.com \
--msg-type interactive \
--content-file /tmp/card.json
Method 3: card_id
bash
feishu-cli msg send \
--receive-id-type email \
--receive-id user@example.com \
--msg-type interactive \
--content '{"type":"card","data":{"card_id":"7371713483664506900"}}'
Card JSON Structure (v1 vs v2)
v1 Format (Recommended, good compatibility):
json
{
"header": {"template": "blue", "title": {"tag": "plain_text", "content": "Title"}},
"elements": [...]
}
v2 Format (More components):
json
{
"schema": "2.0",
"header": {"template": "blue", "title": {"tag": "plain_text", "content": "Title"}},
"body": {"direction": "vertical", "elements": [...]}
}
v2 additionally supports advanced components such as table, chart, form_container, column_set (multi-column layout), etc. For simple notifications, v1 is sufficient; use v2 when complex layouts are needed.
Header Color Templates
| Color Value | Color System | Recommended Scenario |
|---|
| blue | Blue | General notifications, information |
| wathet | Light Blue | Lightweight prompts |
| turquoise | Cyan | In-progress status |
| green | Green | Success, completion |
| yellow | Yellow | Notes, reminders |
| orange | Orange | Warnings |
| red | Red | Errors, emergencies |
| carmine | Deep Red | Severe alerts |
| violet | Violet | Special markers |
| purple | Purple | Custom categories |
| indigo | Indigo | Dark theme |
| grey | Grey | Processed, archived |
Semantic Recommendations: Green = Success / Blue = Notification / Orange = Warning / Red = Error / Grey = Processed
Quick Reference for Common Components
Content Components:
| Component | tag | Description |
|---|
| Markdown | | Supports lark_md syntax, most commonly used |
| Divider | | Horizontal divider |
| Note | | Bottom gray small text note |
| Image | | Image display |
Layout Components:
| Component | tag | Description |
|---|
| Text + Attachment | | Text block, can contain fields (multi-column) and extra (right attachment) |
| Multi-column Layout | (v2) | Horizontal column layout |
Interactive Components:
| Component | tag | Description |
|---|
| Button | | Three types: default/primary/danger |
| Dropdown Selection | | Static dropdown menu |
| Date Picker | | Date picker |
| Collapsible Menu | | More operations menu |
Card Markdown Syntax (lark_md)
The
component in cards uses
syntax, which differs from standard Markdown:
markdown
# Supported Syntax
**bold** *italic* ~~strikethrough~~ [link](url) `inline code`

# Unique Syntax
<font color='green'>Green text</font>
<font color='red'>Red text</font>
<font color='grey'>Grey text</font>
<at id=ou_xxx></at>
<at id=all></at>
Note:
in lark_md only supports three colors: green/red/grey.
Common Card Templates
Template 1: Simple Notification Card
json
{
"header": {
"template": "blue",
"title": {"tag": "plain_text", "content": "Notification Title"}
},
"elements": [
{"tag": "markdown", "content": "Notification content, supports **bold** and [links](https://example.com)"},
{"tag": "note", "elements": [{"tag": "plain_text", "content": "From automation tool"}]}
]
}
Template 2: Alert Card (Multi-column + Buttons)
json
{
"header": {
"template": "red",
"title": {"tag": "plain_text", "content": "Alert Notification"}
},
"elements": [
{
"tag": "div",
"fields": [
{"is_short": true, "text": {"tag": "lark_md", "content": "**Service**\napi-gateway"}},
{"is_short": true, "text": {"tag": "lark_md", "content": "**Level**\n<font color='red'>P0</font>"}},
{"is_short": true, "text": {"tag": "lark_md", "content": "**Time**\n2024-01-01 10:00"}},
{"is_short": true, "text": {"tag": "lark_md", "content": "**Impact**\n<font color='red'>Users cannot log in</font>"}}
]
},
{"tag": "hr"},
{
"tag": "action",
"actions": [
{"tag": "button", "text": {"tag": "plain_text", "content": "View Details"}, "type": "primary", "url": "https://example.com/alert/123"},
{"tag": "button", "text": {"tag": "plain_text", "content": "Ignore"}, "type": "default"}
]
}
]
}
Template 3: Progress Report Card
json
{
"header": {
"template": "green",
"title": {"tag": "plain_text", "content": "Build Report"}
},
"elements": [
{"tag": "markdown", "content": "**Project**: feishu-cli\n**Branch**: main\n**Commit**: abc1234"},
{"tag": "hr"},
{"tag": "markdown", "content": "<font color='green'>Tests: 42/42 passed</font>\n<font color='green'>Build: Success</font>\n<font color='grey'>Duration: 3m 25s</font>"},
{"tag": "hr"},
{
"tag": "action",
"actions": [
{"tag": "button", "text": {"tag": "plain_text", "content": "View Logs"}, "type": "default", "url": "https://ci.example.com/build/123"}
]
},
{"tag": "note", "elements": [{"tag": "plain_text", "content": "CI/CD Pipeline #123"}]}
]
}
Template 4: Document Operation Notification
json
{
"header": {
"template": "turquoise",
"title": {"tag": "plain_text", "content": "Document Operation Notification"}
},
"elements": [
{
"tag": "div",
"fields": [
{"is_short": true, "text": {"tag": "lark_md", "content": "**Operation Type**\nCreate Document"}},
{"is_short": true, "text": {"tag": "lark_md", "content": "**Status**\n<font color='green'>Success</font>"}}
]
},
{"tag": "markdown", "content": "**Document Title**: Weekly Report 2024-W01\n**Document Link**: [Click to View](https://xxx.feishu.cn/docx/abc123)"},
{"tag": "note", "elements": [{"tag": "plain_text", "content": "Automatically created by feishu-cli"}]}
]
}
Template 5: Approval Confirmation Card (Multiple Buttons)
json
{
"header": {
"template": "orange",
"title": {"tag": "plain_text", "content": "Approval Request"}
},
"elements": [
{"tag": "markdown", "content": "**Applicant**: Zhang San\n**Application Type**: Server Expansion\n**Description**: Online traffic has increased, need to add 2 servers"},
{"tag": "hr"},
{
"tag": "action",
"actions": [
{"tag": "button", "text": {"tag": "plain_text", "content": "Approve"}, "type": "primary"},
{"tag": "button", "text": {"tag": "plain_text", "content": "Reject"}, "type": "danger"},
{"tag": "button", "text": {"tag": "plain_text", "content": "View Details"}, "type": "default", "url": "https://example.com/approval/456"}
]
}
]
}
Reply to Messages
Reply to specified messages, supporting the same message types and input methods as
.
bash
# Text reply
feishu-cli msg reply <message_id> --text "Received, I will handle it"
# Card reply
feishu-cli msg reply <message_id> --msg-type interactive --content-file /tmp/card.json
# Rich text reply
feishu-cli msg reply <message_id> --msg-type post --content-file /tmp/post.json
| Parameter | Description | Default Value |
|---|
| Message type | |
| / / | Message content (choose one of three) | Required |
Merge Forward
Merge and forward multiple messages to the specified recipient.
bash
feishu-cli msg merge-forward \
--receive-id user@example.com \
--receive-id-type email \
--message-ids om_xxx,om_yyy,om_zzz
| Parameter | Description | Default Value |
|---|
| Recipient ID | Required |
| Recipient type | |
| List of message IDs (comma-separated) | Required |
Reaction Emoji Response
Add/remove/query emoji reactions for messages.
bash
# Add emoji
feishu-cli msg reaction add <message_id> --emoji-type THUMBSUP
# Remove emoji
feishu-cli msg reaction remove <message_id> --reaction-id <REACTION_ID>
# Query emoji list
feishu-cli msg reaction list <message_id> [--emoji-type THUMBSUP] [--page-size 20]
Common emoji-type values:
(Like),
(Smile),
(Laugh),
(Love),
(Plus One),
,
Pin Messages
bash
# Pin message
feishu-cli msg pin <message_id>
# Unpin message
feishu-cli msg unpin <message_id>
# Get list of pinned messages in group
feishu-cli msg pins --chat-id <chat_id> [--start-time <ms_timestamp>] [--end-time <ms_timestamp>]
and
use
millisecond-level timestamps.
Other Message Commands
Get Message Details
bash
feishu-cli msg get <message_id>
feishu-cli msg get om_xxx --output json
Forward Message
bash
feishu-cli msg forward <message_id> \
--receive-id user@example.com \
--receive-id-type email
Delete Message
Only messages sent by the bot itself can be deleted, and deletion is irreversible.
bash
feishu-cli msg delete <message_id>
Get Message List
bash
feishu-cli msg list \
--container-id oc_xxx \
--container-id-type chat \
--page-size 20 \
--sort-type ByCreateTimeDesc
Supported parameters:
,
(second-level timestamp),
.
Get Conversation History
bash
feishu-cli msg history \
--container-id oc_xxx \
--container-id-type chat \
--sort-type ByCreateTimeAsc \
--page-size 50
Query Message Read Users
bash
feishu-cli msg read-users <message_id>
feishu-cli msg read-users om_xxx --user-id-type user_id --page-size 50
Search Group Chats
bash
feishu-cli msg search-chats --query "Project Group"
feishu-cli msg search-chats --page-size 20
Search Messages (Requires User Access Token)
bash
feishu-cli search messages "keyword" \
--user-access-token u-xxx \
--chat-ids oc_xxx \
--message-type file \
--start-time 1704067200
Execution Process
When Claude sends messages, follow these steps:
- Determine Recipient: Default is (email), or obtained from context
- Select Message Type:
- If user explicitly specifies type → use the specified type
- Default to (card message) → select header color and appropriate component layout based on content semantics
- Use / only when user explicitly requests plain text/rich text
- Construct Card Content:
- Select header color based on message semantics (Green=Success, Red=Error, Orange=Warning, Blue=Notification, Grey=Archived)
- Use component to carry main content
- Use + multi-column layout when there are multiple key-value pairs
- Add + when operation links are needed
- Add at the bottom to indicate the source
- Write the JSON to a temporary file and send it using
- Send and Check Result: Execute the command and confirm the returned message_id
Permission Requirements
| Permission | Description |
|---|
| Message read/write |
| Send messages as bot |
| Search group chats |
| Get historical messages |
Notes
| Limit | Description |
|---|
| text size limit | Maximum 150 KB per message |
| card/rich text size limit | Maximum 30 KB per message |
| system message | Only valid in p2p conversations, invalid in group chats |
| sticker message | Only supports forwarding received stickers, does not support uploading custom stickers |
| card button callback | The interaction callback of buttons requires application server support; buttons sent via CLI only support url redirection |
| API rate limit | Returns 429 if requests are too frequent, retry after a few seconds |
| Delete message | Only messages sent by the bot can be deleted |
Error Handling
| Error | Cause | Solution |
|---|
content format of a post type is incorrect
| Incorrect JSON format for post type | Ensure the format is {"zh_cn":{"title":"","content":[[...]]}}
|
| Invalid recipient ID | Check if --receive-id-type and --receive-id match |
| Bot has no permission | Confirm the application has the permission |
| API rate limit exceeded | Retry after a few seconds |
| User does not exist | Check if the email or ID is correct |
| Card JSON exceeds 30 KB | Simplify card content or split into multiple messages |
Reference Documents
references/message_content.md
: Detailed explanation of content JSON structure for each message type
references/card_schema.md
: Complete guide to constructing card messages (components, layout, templates)