feishu-lark
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseFeishu / Lark Messaging Skill
Feishu / Lark 消息发送技能
You are a messaging specialist for Feishu (飞书, ByteDance's Chinese workplace platform) and Lark (the international version). Your job is to send messages, interactive cards, and marketing content to Feishu/Lark group chats via Custom Bot Webhooks or the App Bot API.
你是Feishu(飞书,字节跳动旗下的中国职场协作平台)和Lark(国际版)的消息发送专家。你的工作是通过自定义Bot Webhook或App Bot API向Feishu/Lark群聊发送消息、互动卡片及营销内容。
Prerequisites
前置条件
Check which credentials are available:
bash
echo "FEISHU_WEBHOOK_URL is ${FEISHU_WEBHOOK_URL:+set}"
echo "FEISHU_WEBHOOK_SECRET is ${FEISHU_WEBHOOK_SECRET:+set}"
echo "FEISHU_APP_ID is ${FEISHU_APP_ID:+set}"
echo "FEISHU_APP_SECRET is ${FEISHU_APP_SECRET:+set}"检查可用的凭证:
bash
echo "FEISHU_WEBHOOK_URL is ${FEISHU_WEBHOOK_URL:+set}"
echo "FEISHU_WEBHOOK_SECRET is ${FEISHU_WEBHOOK_SECRET:+set}"
echo "FEISHU_APP_ID is ${FEISHU_APP_ID:+set}"
echo "FEISHU_APP_SECRET is ${FEISHU_APP_SECRET:+set}"Two Integration Modes
两种集成模式
| Mode | Credentials Required | Capabilities |
|---|---|---|
| Custom Bot Webhook (simple) | | Send text, rich text, interactive cards to a single group |
| App Bot API (full featured) | | Send to any chat, upload images, at-mention users, manage cards, receive events |
If no credentials are set, instruct the user:
Custom Bot Webhook (quickest setup):
- Open a Feishu/Lark group chat
- Click the group name at the top to open Group Settings
- Go to Bots > Add Bot > Custom Bot
- Name the bot and optionally set a Signature Verification secret
- Copy the webhook URL and add to
:.envFEISHU_WEBHOOK_URL=https://open.feishu.cn/open-apis/bot/v2/hook/{webhook_id} FEISHU_WEBHOOK_SECRET=your_secret_here # optional, for signed webhooksApp Bot API (for advanced use):
- Go to Feishu Open Platform or Lark Developer Console
- Create a new app, enable the Bot capability
- Add required permissions:
,im:message:send_as_botim:chat:readonly- Publish and approve the app, then add to
:.envFEISHU_APP_ID=cli_xxxxx FEISHU_APP_SECRET=xxxxx
| 模式 | 所需凭证 | 功能 |
|---|---|---|
| 自定义Bot Webhook(简易版) | | 向单个群组发送文本、富文本、互动卡片 |
| App Bot API(全功能版) | | 向任意聊天发送消息、上传图片、@提及用户、管理卡片、接收事件 |
如果未设置任何凭证,请指导用户完成以下步骤:
自定义Bot Webhook(最快配置):
- 打开Feishu/Lark群聊
- 点击顶部群名称打开群设置
- 进入机器人 > 添加机器人 > 自定义机器人
- 为机器人命名,可选择设置签名验证密钥
- 复制webhook URL并添加到
文件:.envFEISHU_WEBHOOK_URL=https://open.feishu.cn/open-apis/bot/v2/hook/{webhook_id} FEISHU_WEBHOOK_SECRET=your_secret_here # 可选,用于签名webhook请求App Bot API(进阶使用):
- 访问飞书开放平台或Lark开发者控制台
- 创建新应用,启用Bot功能
- 添加所需权限:
、im:message:send_as_botim:chat:readonly- 发布并审核应用,然后将凭证添加到
文件:.envFEISHU_APP_ID=cli_xxxxx FEISHU_APP_SECRET=xxxxx
Webhook URL Formats
Webhook URL格式
- Feishu (China):
https://open.feishu.cn/open-apis/bot/v2/hook/{webhook_id} - Lark (International):
https://open.larksuite.com/open-apis/bot/v2/hook/{webhook_id}
- Feishu(中国区):
https://open.feishu.cn/open-apis/bot/v2/hook/{webhook_id} - Lark(国际版):
https://open.larksuite.com/open-apis/bot/v2/hook/{webhook_id}
API Base URLs
API基础URL
- Feishu (China):
https://open.feishu.cn/open-apis - Lark (International):
https://open.larksuite.com/open-apis
- Feishu(中国区):
https://open.feishu.cn/open-apis - Lark(国际版):
https://open.larksuite.com/open-apis
1. Custom Bot Webhook Messages
1. 自定义Bot Webhook消息
1.1 Plain Text Message
1.1 纯文本消息
bash
curl -s -X POST "${FEISHU_WEBHOOK_URL}" \
-H "Content-Type: application/json" \
-d '{
"msg_type": "text",
"content": {
"text": "Hello from OpenClaudia! This is a test message."
}
}'At-mention everyone in the group:
bash
curl -s -X POST "${FEISHU_WEBHOOK_URL}" \
-H "Content-Type: application/json" \
-d '{
"msg_type": "text",
"content": {
"text": "<at user_id=\"all\">Everyone</at> Important announcement: new release is live!"
}
}'bash
curl -s -X POST "${FEISHU_WEBHOOK_URL}" \
-H "Content-Type: application/json" \
-d '{
"msg_type": "text",
"content": {
"text": "Hello from OpenClaudia! This is a test message."
}
}'@提及群内所有人:
bash
curl -s -X POST "${FEISHU_WEBHOOK_URL}" \
-H "Content-Type: application/json" \
-d '{
"msg_type": "text",
"content": {
"text": "<at user_id=\"all\">Everyone</at> Important announcement: new release is live!"
}
}'1.2 Rich Text Message (Post)
1.2 富文本消息(Post格式)
Rich text supports bold, links, at-mentions, and images in a structured format.
bash
curl -s -X POST "${FEISHU_WEBHOOK_URL}" \
-H "Content-Type: application/json" \
-d '{
"msg_type": "post",
"content": {
"post": {
"zh_cn": {
"title": "产品更新公告",
"content": [
[
{"tag": "text", "text": "我们很高兴地宣布 "},
{"tag": "a", "text": "v2.0 版本", "href": "https://example.com/changelog"},
{"tag": "text", "text": " 已正式发布!"}
],
[
{"tag": "text", "text": "主要更新:"}
],
[
{"tag": "text", "text": "1. 全新用户界面\n2. 性能提升 50%\n3. 支持暗色模式"}
],
[
{"tag": "at", "user_id": "all", "user_name": "所有人"}
]
]
}
}
}
}'English version (for Lark):
bash
curl -s -X POST "${FEISHU_WEBHOOK_URL}" \
-H "Content-Type: application/json" \
-d '{
"msg_type": "post",
"content": {
"post": {
"en_us": {
"title": "Product Update Announcement",
"content": [
[
{"tag": "text", "text": "We are excited to announce that "},
{"tag": "a", "text": "v2.0", "href": "https://example.com/changelog"},
{"tag": "text", "text": " is now live!"}
],
[
{"tag": "text", "text": "Key updates:"}
],
[
{"tag": "text", "text": "1. Brand new UI\n2. 50% performance improvement\n3. Dark mode support"}
],
[
{"tag": "at", "user_id": "all", "user_name": "Everyone"}
]
]
}
}
}
}'富文本支持加粗、链接、@提及和结构化图片。
bash
curl -s -X POST "${FEISHU_WEBHOOK_URL}" \
-H "Content-Type: application/json" \
-d '{
"msg_type": "post",
"content": {
"post": {
"zh_cn": {
"title": "产品更新公告",
"content": [
[
{"tag": "text", "text": "我们很高兴地宣布 "},
{"tag": "a", "text": "v2.0 版本", "href": "https://example.com/changelog"},
{"tag": "text", "text": " 已正式发布!"}
],
[
{"tag": "text", "text": "主要更新:"}
],
[
{"tag": "text", "text": "1. 全新用户界面\n2. 性能提升 50%\n3. 支持暗色模式"}
],
[
{"tag": "at", "user_id": "all", "user_name": "所有人"}
]
]
}
}
}
}'英文版本(适用于Lark):
bash
curl -s -X POST "${FEISHU_WEBHOOK_URL}" \
-H "Content-Type: application/json" \
-d '{
"msg_type": "post",
"content": {
"post": {
"en_us": {
"title": "Product Update Announcement",
"content": [
[
{"tag": "text", "text": "We are excited to announce that "},
{"tag": "a", "text": "v2.0", "href": "https://example.com/changelog"},
{"tag": "text", "text": " is now live!"}
],
[
{"tag": "text", "text": "Key updates:"}
],
[
{"tag": "text", "text": "1. Brand new UI\n2. 50% performance improvement\n3. Dark mode support"}
],
[
{"tag": "at", "user_id": "all", "user_name": "Everyone"}
]
]
}
}
}
}'Rich Text Tag Reference
富文本标签参考
| Tag | Purpose | Attributes |
|---|---|---|
| Plain text | |
| Hyperlink | |
| At-mention | |
| Image (App Bot only) | |
| Video/file (App Bot only) | |
| 标签 | 用途 | 属性 |
|---|---|---|
| 纯文本 | |
| 超链接 | |
| @提及 | |
| 图片(仅App Bot支持) | |
| 视频/文件(仅App Bot支持) | |
1.3 Signed Webhook Requests
1.3 签名Webhook请求
If is set, the webhook requires a signature for verification.
FEISHU_WEBHOOK_SECRETGenerate a signed request:
bash
undefined如果设置了,webhook请求需要携带签名以通过验证。
FEISHU_WEBHOOK_SECRET生成签名请求:
bash
undefinedCalculate timestamp and signature
计算时间戳和签名
TIMESTAMP=$(date +%s)
STRING_TO_SIGN="${TIMESTAMP}\n${FEISHU_WEBHOOK_SECRET}"
SIGN=$(printf '%b' "${STRING_TO_SIGN}" | openssl dgst -sha256 -hmac "" -binary | openssl base64)
TIMESTAMP=$(date +%s)
STRING_TO_SIGN="${TIMESTAMP}\n${FEISHU_WEBHOOK_SECRET}"
SIGN=$(printf '%b' "${STRING_TO_SIGN}" | openssl dgst -sha256 -hmac "" -binary | openssl base64)
For proper HMAC-SHA256 signing:
正确的HMAC-SHA256签名方式:
SIGN=$(echo -ne "${TIMESTAMP}\n${FEISHU_WEBHOOK_SECRET}" | openssl dgst -sha256 -hmac "" -binary | base64)
curl -s -X POST "${FEISHU_WEBHOOK_URL}"
-H "Content-Type: application/json"
-d "{ "timestamp": "${TIMESTAMP}", "sign": "${SIGN}", "msg_type": "text", "content": { "text": "Signed message from OpenClaudia." } }"
-H "Content-Type: application/json"
-d "{ "timestamp": "${TIMESTAMP}", "sign": "${SIGN}", "msg_type": "text", "content": { "text": "Signed message from OpenClaudia." } }"
**Feishu signature algorithm details:**
1. Concatenate `timestamp + "\n" + secret` as the string to sign
2. Compute HMAC-SHA256 with an empty key over that string
3. Base64-encode the result
4. Include both `timestamp` and `sign` in the request JSON body
---SIGN=$(echo -ne "${TIMESTAMP}\n${FEISHU_WEBHOOK_SECRET}" | openssl dgst -sha256 -hmac "" -binary | base64)
curl -s -X POST "${FEISHU_WEBHOOK_URL}"
-H "Content-Type: application/json"
-d "{ "timestamp": "${TIMESTAMP}", "sign": "${SIGN}", "msg_type": "text", "content": { "text": "Signed message from OpenClaudia." } }"
-H "Content-Type: application/json"
-d "{ "timestamp": "${TIMESTAMP}", "sign": "${SIGN}", "msg_type": "text", "content": { "text": "Signed message from OpenClaudia." } }"
**Feishu签名算法细节:**
1. 将`timestamp + "\n" + secret`拼接为待签名字符串
2. 使用空密钥对字符串进行HMAC-SHA256计算
3. 将结果进行Base64编码
4. 在请求JSON体中同时包含`timestamp`和`sign`字段
---2. Interactive Card Messages
2. 互动卡片消息
Interactive cards are the most powerful message format. They support headers, content sections, images, action buttons, and structured layouts.
互动卡片是功能最强大的消息格式,支持标题、内容区块、图片、操作按钮和结构化布局。
2.1 Basic Card Structure
2.1 基础卡片结构
json
{
"msg_type": "interactive",
"card": {
"header": {
"title": {
"tag": "plain_text",
"content": "Card Title Here"
},
"template": "blue"
},
"elements": []
}
}json
{
"msg_type": "interactive",
"card": {
"header": {
"title": {
"tag": "plain_text",
"content": "Card Title Here"
},
"template": "blue"
},
"elements": []
}
}Header Color Templates
标题颜色模板
| Template | Color | Best For |
|---|---|---|
| Blue | General info, updates |
| Green | Success, positive news |
| Red | Urgent, alerts, errors |
| Orange | Warnings, action needed |
| Purple | Events, creative |
| Indigo | Technical, engineering |
| Teal | Growth, marketing |
| Yellow | Highlights, tips |
| Grey | Neutral, low priority |
| Light blue | Default, clean |
| 模板 | 颜色 | 适用场景 |
|---|---|---|
| 蓝色 | 通用信息、更新通知 |
| 绿色 | 成功消息、正面资讯 |
| 红色 | 紧急通知、告警、错误提示 |
| 橙色 | 警告、需操作提醒 |
| 紫色 | 活动通知、创意内容 |
| 靛蓝色 | 技术相关、工程通知 |
| 青绿色 | 增长类、营销内容 |
| 黄色 | 重点高亮、小贴士 |
| 灰色 | 中性内容、低优先级通知 |
| 浅蓝 | 默认样式、简洁内容 |
2.2 Card Elements Reference
2.2 卡片元素参考
Markdown Content Block:
json
{
"tag": "markdown",
"content": "**Bold text** and *italic text*\n[Link text](https://example.com)\nList:\n- Item 1\n- Item 2"
}Divider:
json
{
"tag": "hr"
}Note (small gray footer text):
json
{
"tag": "note",
"elements": [
{"tag": "plain_text", "content": "Sent via OpenClaudia Marketing Toolkit"}
]
}Image Block:
json
{
"tag": "img",
"img_key": "img_v2_xxx",
"alt": {"tag": "plain_text", "content": "Image description"},
"title": {"tag": "plain_text", "content": "Image Title"}
}Action Buttons:
json
{
"tag": "action",
"actions": [
{
"tag": "button",
"text": {"tag": "plain_text", "content": "View Details"},
"type": "primary",
"url": "https://example.com/details"
},
{
"tag": "button",
"text": {"tag": "plain_text", "content": "Dismiss"},
"type": "default"
}
]
}Button types: (blue), (red), (gray)
primarydangerdefaultMulti-column Layout:
json
{
"tag": "column_set",
"flex_mode": "bisect",
"columns": [
{
"tag": "column",
"width": "weighted",
"weight": 1,
"elements": [
{"tag": "markdown", "content": "**Left Column**\nContent here"}
]
},
{
"tag": "column",
"width": "weighted",
"weight": 1,
"elements": [
{"tag": "markdown", "content": "**Right Column**\nContent here"}
]
}
]
}Markdown内容区块:
json
{
"tag": "markdown",
"content": "**Bold text** and *italic text*\n[Link text](https://example.com)\nList:\n- Item 1\n- Item 2"
}分隔线:
json
{
"tag": "hr"
}备注(小字号灰色页脚文本):
json
{
"tag": "note",
"elements": [
{"tag": "plain_text", "content": "Sent via OpenClaudia Marketing Toolkit"}
]
}图片区块:
json
{
"tag": "img",
"img_key": "img_v2_xxx",
"alt": {"tag": "plain_text", "content": "Image description"},
"title": {"tag": "plain_text", "content": "Image Title"}
}操作按钮:
json
{
"tag": "action",
"actions": [
{
"tag": "button",
"text": {"tag": "plain_text", "content": "View Details"},
"type": "primary",
"url": "https://example.com/details"
},
{
"tag": "button",
"text": {"tag": "plain_text", "content": "Dismiss"},
"type": "default"
}
]
}按钮类型: (蓝色)、(红色)、(灰色)
primarydangerdefault多列布局:
json
{
"tag": "column_set",
"flex_mode": "bisect",
"columns": [
{
"tag": "column",
"width": "weighted",
"weight": 1,
"elements": [
{"tag": "markdown", "content": "**Left Column**\nContent here"}
]
},
{
"tag": "column",
"width": "weighted",
"weight": 1,
"elements": [
{"tag": "markdown", "content": "**Right Column**\nContent here"}
]
}
]
}2.3 Full Card Example: Product Announcement
2.3 完整卡片示例:产品发布公告
bash
curl -s -X POST "${FEISHU_WEBHOOK_URL}" \
-H "Content-Type: application/json" \
-d '{
"msg_type": "interactive",
"card": {
"header": {
"title": {
"tag": "plain_text",
"content": "New Feature Launch: AI-Powered Analytics"
},
"template": "turquoise"
},
"elements": [
{
"tag": "markdown",
"content": "We are thrilled to announce our latest feature!\n\n**AI-Powered Analytics** is now available to all Pro and Enterprise users.\n\nKey highlights:\n- **Smart Insights**: Automatic trend detection and anomaly alerts\n- **Natural Language Queries**: Ask questions in plain English\n- **Predictive Forecasting**: 90-day revenue and growth projections\n- **Custom Dashboards**: Drag-and-drop report builder"
},
{
"tag": "hr"
},
{
"tag": "markdown",
"content": "**Availability:** Rolling out now, fully live by end of week\n**Documentation:** [View the guide](https://example.com/docs/analytics)\n**Feedback:** Reply in this thread or submit via [feedback form](https://example.com/feedback)"
},
{
"tag": "action",
"actions": [
{
"tag": "button",
"text": {"tag": "plain_text", "content": "Try It Now"},
"type": "primary",
"url": "https://example.com/analytics"
},
{
"tag": "button",
"text": {"tag": "plain_text", "content": "Read Docs"},
"type": "default",
"url": "https://example.com/docs/analytics"
}
]
},
{
"tag": "note",
"elements": [
{"tag": "plain_text", "content": "Product Team | Released 2025-01-15"}
]
}
]
}
}'bash
curl -s -X POST "${FEISHU_WEBHOOK_URL}" \
-H "Content-Type: application/json" \
-d '{
"msg_type": "interactive",
"card": {
"header": {
"title": {
"tag": "plain_text",
"content": "New Feature Launch: AI-Powered Analytics"
},
"template": "turquoise"
},
"elements": [
{
"tag": "markdown",
"content": "We are thrilled to announce our latest feature!\n\n**AI-Powered Analytics** is now available to all Pro and Enterprise users.\n\nKey highlights:\n- **Smart Insights**: Automatic trend detection and anomaly alerts\n- **Natural Language Queries**: Ask questions in plain English\n- **Predictive Forecasting**: 90-day revenue and growth projections\n- **Custom Dashboards**: Drag-and-drop report builder"
},
{
"tag": "hr"
},
{
"tag": "markdown",
"content": "**Availability:** Rolling out now, fully live by end of week\n**Documentation:** [View the guide](https://example.com/docs/analytics)\n**Feedback:** Reply in this thread or submit via [feedback form](https://example.com/feedback)"
},
{
"tag": "action",
"actions": [
{
"tag": "button",
"text": {"tag": "plain_text", "content": "Try It Now"},
"type": "primary",
"url": "https://example.com/analytics"
},
{
"tag": "button",
"text": {"tag": "plain_text", "content": "Read Docs"},
"type": "default",
"url": "https://example.com/docs/analytics"
}
]
},
{
"tag": "note",
"elements": [
{"tag": "plain_text", "content": "Product Team | Released 2025-01-15"}
]
}
]
}
}'3. App Bot API (Full Featured)
3. App Bot API(全功能版)
The App Bot API requires and . It provides full messaging capabilities including sending to any chat, uploading images, and managing messages.
FEISHU_APP_IDFEISHU_APP_SECRETApp Bot API需要和,提供完整的消息功能,包括向任意聊天发送消息、上传图片和管理消息等。
FEISHU_APP_IDFEISHU_APP_SECRET3.1 Get Tenant Access Token
3.1 获取租户访问令牌
All App Bot API calls require a . Tokens expire after 2 hours.
tenant_access_tokenbash
undefined所有App Bot API调用都需要,令牌有效期为2小时。
tenant_access_tokenbash
undefinedFor Feishu (China)
适用于Feishu(中国区)
FEISHU_API_BASE="https://open.feishu.cn/open-apis"
FEISHU_API_BASE="https://open.feishu.cn/open-apis"
For Lark (International)
适用于Lark(国际版)
FEISHU_API_BASE="https://open.larksuite.com/open-apis"
FEISHU_API_BASE="https://open.larksuite.com/open-apis"
TENANT_TOKEN=$(curl -s -X POST "${FEISHU_API_BASE}/auth/v3/tenant_access_token/internal"
-H "Content-Type: application/json"
-d "{ "app_id": "${FEISHU_APP_ID}", "app_secret": "${FEISHU_APP_SECRET}" }" | python3 -c "import json,sys; print(json.load(sys.stdin).get('tenant_access_token',''))")
-H "Content-Type: application/json"
-d "{ "app_id": "${FEISHU_APP_ID}", "app_secret": "${FEISHU_APP_SECRET}" }" | python3 -c "import json,sys; print(json.load(sys.stdin).get('tenant_access_token',''))")
echo "Token: ${TENANT_TOKEN:0:10}..."
undefinedTENANT_TOKEN=$(curl -s -X POST "${FEISHU_API_BASE}/auth/v3/tenant_access_token/internal"
-H "Content-Type: application/json"
-d "{ "app_id": "${FEISHU_APP_ID}", "app_secret": "${FEISHU_APP_SECRET}" }" | python3 -c "import json,sys; print(json.load(sys.stdin).get('tenant_access_token',''))")
-H "Content-Type: application/json"
-d "{ "app_id": "${FEISHU_APP_ID}", "app_secret": "${FEISHU_APP_SECRET}" }" | python3 -c "import json,sys; print(json.load(sys.stdin).get('tenant_access_token',''))")
echo "Token: ${TENANT_TOKEN:0:10}..."
undefined3.2 List Chats the Bot Belongs To
3.2 列出Bot所在的聊天群组
bash
curl -s "${FEISHU_API_BASE}/im/v1/chats?page_size=20" \
-H "Authorization: Bearer ${TENANT_TOKEN}" | \
python3 -c "
import json, sys
data = json.load(sys.stdin)
for chat in data.get('data', {}).get('items', []):
print(f\"Chat ID: {chat['chat_id']} | Name: {chat.get('name', 'N/A')} | Type: {chat.get('chat_type', 'N/A')}\")
"bash
curl -s "${FEISHU_API_BASE}/im/v1/chats?page_size=20" \
-H "Authorization: Bearer ${TENANT_TOKEN}" | \
python3 -c "
import json, sys
data = json.load(sys.stdin)
for chat in data.get('data', {}).get('items', []):
print(f\"Chat ID: {chat['chat_id']} | 群组名称: {chat.get('name', 'N/A')} | 类型: {chat.get('chat_type', 'N/A')}\")
"3.3 Send Message to a Chat
3.3 向聊天群组发送消息
bash
CHAT_ID="oc_xxxxx" # Replace with actual chat_idbash
CHAT_ID="oc_xxxxx" # 替换为实际的chat_idSend a text message
发送文本消息
curl -s -X POST "${FEISHU_API_BASE}/im/v1/messages?receive_id_type=chat_id"
-H "Authorization: Bearer ${TENANT_TOKEN}"
-H "Content-Type: application/json"
-d "{ "receive_id": "${CHAT_ID}", "msg_type": "text", "content": "{\"text\": \"Hello from the App Bot!\"}" }"
-H "Authorization: Bearer ${TENANT_TOKEN}"
-H "Content-Type: application/json"
-d "{ "receive_id": "${CHAT_ID}", "msg_type": "text", "content": "{\"text\": \"Hello from the App Bot!\"}" }"
**Send a rich text message via the API:**
```bash
curl -s -X POST "${FEISHU_API_BASE}/im/v1/messages?receive_id_type=chat_id" \
-H "Authorization: Bearer ${TENANT_TOKEN}" \
-H "Content-Type: application/json" \
-d "{
\"receive_id\": \"${CHAT_ID}\",
\"msg_type\": \"post\",
\"content\": $(python3 -c "
import json
content = {
'zh_cn': {
'title': 'App Bot 消息',
'content': [
[
{'tag': 'text', 'text': '这是一条通过 App Bot API 发送的 '},
{'tag': 'a', 'text': '富文本消息', 'href': 'https://example.com'},
{'tag': 'text', 'text': '。'}
]
]
}
}
print(json.dumps(json.dumps(content)))
")
}"Send an interactive card via the API:
bash
curl -s -X POST "${FEISHU_API_BASE}/im/v1/messages?receive_id_type=chat_id" \
-H "Authorization: Bearer ${TENANT_TOKEN}" \
-H "Content-Type: application/json" \
-d "{
\"receive_id\": \"${CHAT_ID}\",
\"msg_type\": \"interactive\",
\"content\": $(python3 -c "
import json
card = {
'header': {
'title': {'tag': 'plain_text', 'content': 'Marketing Update'},
'template': 'turquoise'
},
'elements': [
{'tag': 'markdown', 'content': '**Campaign Performance This Week**\n\n- Impressions: **120,450** (+12%)\n- Clicks: **8,320** (+8%)\n- Conversions: **342** (+15%)\n- Cost per Conversion: **\$14.20** (-5%)'},
{'tag': 'hr'},
{'tag': 'action', 'actions': [
{'tag': 'button', 'text': {'tag': 'plain_text', 'content': 'View Full Report'}, 'type': 'primary', 'url': 'https://example.com/report'}
]},
{'tag': 'note', 'elements': [{'tag': 'plain_text', 'content': 'Auto-generated by OpenClaudia Marketing Toolkit'}]}
]
}
print(json.dumps(json.dumps(card)))
")
}"curl -s -X POST "${FEISHU_API_BASE}/im/v1/messages?receive_id_type=chat_id"
-H "Authorization: Bearer ${TENANT_TOKEN}"
-H "Content-Type: application/json"
-d "{ "receive_id": "${CHAT_ID}", "msg_type": "text", "content": "{\"text\": \"Hello from the App Bot!\"}" }"
-H "Authorization: Bearer ${TENANT_TOKEN}"
-H "Content-Type: application/json"
-d "{ "receive_id": "${CHAT_ID}", "msg_type": "text", "content": "{\"text\": \"Hello from the App Bot!\"}" }"
**通过API发送富文本消息:**
```bash
curl -s -X POST "${FEISHU_API_BASE}/im/v1/messages?receive_id_type=chat_id" \
-H "Authorization: Bearer ${TENANT_TOKEN}" \
-H "Content-Type: application/json" \
-d "{
\"receive_id\": \"${CHAT_ID}\",
\"msg_type\": \"post\",
\"content\": $(python3 -c "
import json
content = {
'zh_cn': {
'title': 'App Bot 消息',
'content': [
[
{'tag': 'text', 'text': '这是一条通过 App Bot API 发送的 '},
{'tag': 'a', 'text': '富文本消息', 'href': 'https://example.com'},
{'tag': 'text', 'text': '。'}
]
]
}
}
print(json.dumps(json.dumps(content)))
")
}"通过API发送互动卡片:
bash
curl -s -X POST "${FEISHU_API_BASE}/im/v1/messages?receive_id_type=chat_id" \
-H "Authorization: Bearer ${TENANT_TOKEN}" \
-H "Content-Type: application/json" \
-d "{
\"receive_id\": \"${CHAT_ID}\",
\"msg_type\": \"interactive\",
\"content\": $(python3 -c "
import json
card = {
'header': {
'title': {'tag': 'plain_text', 'content': 'Marketing Update'},
'template': 'turquoise'
},
'elements': [
{'tag': 'markdown', 'content': '**Campaign Performance This Week**\n\n- Impressions: **120,450** (+12%)\n- Clicks: **8,320** (+8%)\n- Conversions: **342** (+15%)\n- Cost per Conversion: **\$14.20** (-5%)'},
{'tag': 'hr'},
{'tag': 'action', 'actions': [
{'tag': 'button', 'text': {'tag': 'plain_text', 'content': 'View Full Report'}, 'type': 'primary', 'url': 'https://example.com/report'}
]},
{'tag': 'note', 'elements': [{'tag': 'plain_text', 'content': 'Auto-generated by OpenClaudia Marketing Toolkit'}]}
]
}
print(json.dumps(json.dumps(card)))
")
}"3.4 Upload an Image
3.4 上传图片
Upload an image to get an for use in cards and rich text messages.
image_keybash
IMAGE_KEY=$(curl -s -X POST "${FEISHU_API_BASE}/im/v1/images" \
-H "Authorization: Bearer ${TENANT_TOKEN}" \
-F "image_type=message" \
-F "image=@/path/to/image.png" | python3 -c "import json,sys; print(json.load(sys.stdin).get('data',{}).get('image_key',''))")
echo "Image key: ${IMAGE_KEY}"上传图片以获取,用于卡片和富文本消息中。
image_keybash
IMAGE_KEY=$(curl -s -X POST "${FEISHU_API_BASE}/im/v1/images" \
-H "Authorization: Bearer ${TENANT_TOKEN}" \
-F "image_type=message" \
-F "image=@/path/to/image.png" | python3 -c "import json,sys; print(json.load(sys.stdin).get('data',{}).get('image_key',''))")
echo "Image key: ${IMAGE_KEY}"3.5 Send to a Specific User (by email or user_id)
3.5 向特定用户发送消息(通过邮箱或user_id)
bash
undefinedbash
undefinedBy email (receive_id_type=email)
通过邮箱(receive_id_type=email)
curl -s -X POST "${FEISHU_API_BASE}/im/v1/messages?receive_id_type=email"
-H "Authorization: Bearer ${TENANT_TOKEN}"
-H "Content-Type: application/json"
-d "{ "receive_id": "user@company.com", "msg_type": "text", "content": "{\"text\": \"Direct message from the marketing bot.\"}" }"
-H "Authorization: Bearer ${TENANT_TOKEN}"
-H "Content-Type: application/json"
-d "{ "receive_id": "user@company.com", "msg_type": "text", "content": "{\"text\": \"Direct message from the marketing bot.\"}" }"
---curl -s -X POST "${FEISHU_API_BASE}/im/v1/messages?receive_id_type=email"
-H "Authorization: Bearer ${TENANT_TOKEN}"
-H "Content-Type: application/json"
-d "{ "receive_id": "user@company.com", "msg_type": "text", "content": "{\"text\": \"Direct message from the marketing bot.\"}" }"
-H "Authorization: Bearer ${TENANT_TOKEN}"
-H "Content-Type: application/json"
-d "{ "receive_id": "user@company.com", "msg_type": "text", "content": "{\"text\": \"Direct message from the marketing bot.\"}" }"
---4. Message Templates
4. 消息模板
4.1 Product Announcement
4.1 产品发布公告
bash
send_product_announcement() {
local TITLE="$1"
local VERSION="$2"
local FEATURES="$3"
local DOCS_URL="$4"
local CTA_URL="$5"
curl -s -X POST "${FEISHU_WEBHOOK_URL}" \
-H "Content-Type: application/json" \
-d "$(python3 -c "
import json
card = {
'msg_type': 'interactive',
'card': {
'header': {
'title': {'tag': 'plain_text', 'content': '${TITLE}'},
'template': 'green'
},
'elements': [
{'tag': 'markdown', 'content': '**Version ${VERSION}** is now available!\n\n${FEATURES}'},
{'tag': 'hr'},
{'tag': 'action', 'actions': [
{'tag': 'button', 'text': {'tag': 'plain_text', 'content': 'Get Started'}, 'type': 'primary', 'url': '${CTA_URL}'},
{'tag': 'button', 'text': {'tag': 'plain_text', 'content': 'Release Notes'}, 'type': 'default', 'url': '${DOCS_URL}'}
]},
{'tag': 'note', 'elements': [{'tag': 'plain_text', 'content': 'Product Team | $(date +%Y-%m-%d)'}]}
]
}
}
print(json.dumps(card))
")"
}bash
send_product_announcement() {
local TITLE="$1"
local VERSION="$2"
local FEATURES="$3"
local DOCS_URL="$4"
local CTA_URL="$5"
curl -s -X POST "${FEISHU_WEBHOOK_URL}" \
-H "Content-Type: application/json" \
-d "$(python3 -c "
import json
card = {
'msg_type': 'interactive',
'card': {
'header': {
'title': {'tag': 'plain_text', 'content': '${TITLE}'},
'template': 'green'
},
'elements': [
{'tag': 'markdown', 'content': '**Version ${VERSION}** is now available!\n\n${FEATURES}'},
{'tag': 'hr'},
{'tag': 'action', 'actions': [
{'tag': 'button', 'text': {'tag': 'plain_text', 'content': 'Get Started'}, 'type': 'primary', 'url': '${CTA_URL}'},
{'tag': 'button', 'text': {'tag': 'plain_text', 'content': 'Release Notes'}, 'type': 'default', 'url': '${DOCS_URL}'}
]},
{'tag': 'note', 'elements': [{'tag': 'plain_text', 'content': 'Product Team | $(date +%Y-%m-%d)'}]}
]
}
}
print(json.dumps(card))
")"
}4.2 Team Update / Weekly Report
4.2 团队更新 / 周报
bash
curl -s -X POST "${FEISHU_WEBHOOK_URL}" \
-H "Content-Type: application/json" \
-d '{
"msg_type": "interactive",
"card": {
"header": {
"title": {"tag": "plain_text", "content": "Weekly Marketing Report - W03 2025"},
"template": "blue"
},
"elements": [
{
"tag": "column_set",
"flex_mode": "bisect",
"columns": [
{
"tag": "column",
"width": "weighted",
"weight": 1,
"elements": [
{"tag": "markdown", "content": "**Traffic**\n\nSessions: **45,230**\nUnique Visitors: **32,100**\nBounce Rate: **42%**"}
]
},
{
"tag": "column",
"width": "weighted",
"weight": 1,
"elements": [
{"tag": "markdown", "content": "**Conversions**\n\nSignups: **580**\nTrials: **120**\nPaid: **34**"}
]
}
]
},
{"tag": "hr"},
{
"tag": "markdown",
"content": "**Top Performing Content:**\n1. \"10 Tips for Better SEO\" - 8,200 views\n2. \"Product Comparison Guide\" - 5,100 views\n3. \"Customer Success Story: Acme Corp\" - 3,800 views\n\n**Action Items:**\n- [ ] Publish Q1 campaign landing page\n- [ ] Review ad spend allocation\n- [ ] Schedule social media posts for next week"
},
{
"tag": "action",
"actions": [
{
"tag": "button",
"text": {"tag": "plain_text", "content": "Full Dashboard"},
"type": "primary",
"url": "https://example.com/dashboard"
}
]
},
{
"tag": "note",
"elements": [
{"tag": "plain_text", "content": "Marketing Team | Auto-generated weekly report"}
]
}
]
}
}'bash
curl -s -X POST "${FEISHU_WEBHOOK_URL}" \
-H "Content-Type: application/json" \
-d '{
"msg_type": "interactive",
"card": {
"header": {
"title": {"tag": "plain_text", "content": "Weekly Marketing Report - W03 2025"},
"template": "blue"
},
"elements": [
{
"tag": "column_set",
"flex_mode": "bisect",
"columns": [
{
"tag": "column",
"width": "weighted",
"weight": 1,
"elements": [
{"tag": "markdown", "content": "**Traffic**\n\nSessions: **45,230**\nUnique Visitors: **32,100**\nBounce Rate: **42%**"}
]
},
{
"tag": "column",
"width": "weighted",
"weight": 1,
"elements": [
{"tag": "markdown", "content": "**Conversions**\n\nSignups: **580**\nTrials: **120**\nPaid: **34**"}
]
}
]
},
{"tag": "hr"},
{
"tag": "markdown",
"content": "**Top Performing Content:**\n1. \"10 Tips for Better SEO\" - 8,200 views\n2. \"Product Comparison Guide\" - 5,100 views\n3. \"Customer Success Story: Acme Corp\" - 3,800 views\n\n**Action Items:**\n- [ ] Publish Q1 campaign landing page\n- [ ] Review ad spend allocation\n- [ ] Schedule social media posts for next week"
},
{
"tag": "action",
"actions": [
{
"tag": "button",
"text": {"tag": "plain_text", "content": "Full Dashboard"},
"type": "primary",
"url": "https://example.com/dashboard"
}
]
},
{
"tag": "note",
"elements": [
{"tag": "plain_text", "content": "Marketing Team | Auto-generated weekly report"}
]
}
]
}
}'4.3 Event Notification
4.3 活动通知
bash
curl -s -X POST "${FEISHU_WEBHOOK_URL}" \
-H "Content-Type: application/json" \
-d '{
"msg_type": "interactive",
"card": {
"header": {
"title": {"tag": "plain_text", "content": "Upcoming Webinar: AI in Marketing"},
"template": "purple"
},
"elements": [
{
"tag": "markdown",
"content": "Join us for an exclusive webinar on leveraging AI for marketing success.\n\n**Date:** Thursday, January 30, 2025\n**Time:** 2:00 PM - 3:30 PM (PST)\n**Speaker:** Jane Smith, VP of Marketing\n**Format:** Live presentation + Q&A\n\n**What you will learn:**\n- How to use AI for content personalization\n- Automating campaign optimization\n- Measuring AI-driven marketing ROI"
},
{"tag": "hr"},
{
"tag": "action",
"actions": [
{
"tag": "button",
"text": {"tag": "plain_text", "content": "Register Now"},
"type": "primary",
"url": "https://example.com/webinar/register"
},
{
"tag": "button",
"text": {"tag": "plain_text", "content": "Add to Calendar"},
"type": "default",
"url": "https://example.com/webinar/calendar"
}
]
},
{
"tag": "note",
"elements": [
{"tag": "plain_text", "content": "Limited to 200 seats | Free for all team members"}
]
}
]
}
}'bash
curl -s -X POST "${FEISHU_WEBHOOK_URL}" \
-H "Content-Type: application/json" \
-d '{
"msg_type": "interactive",
"card": {
"header": {
"title": {"tag": "plain_text", "content": "Upcoming Webinar: AI in Marketing"},
"template": "purple"
},
"elements": [
{
"tag": "markdown",
"content": "Join us for an exclusive webinar on leveraging AI for marketing success.\n\n**Date:** Thursday, January 30, 2025\n**Time:** 2:00 PM - 3:30 PM (PST)\n**Speaker:** Jane Smith, VP of Marketing\n**Format:** Live presentation + Q&A\n\n**What you will learn:**\n- How to use AI for content personalization\n- Automating campaign optimization\n- Measuring AI-driven marketing ROI"
},
{"tag": "hr"},
{
"tag": "action",
"actions": [
{
"tag": "button",
"text": {"tag": "plain_text", "content": "Register Now"},
"type": "primary",
"url": "https://example.com/webinar/register"
},
{
"tag": "button",
"text": {"tag": "plain_text", "content": "Add to Calendar"},
"type": "default",
"url": "https://example.com/webinar/calendar"
}
]
},
{
"tag": "note",
"elements": [
{"tag": "plain_text", "content": "Limited to 200 seats | Free for all team members"}
]
}
]
}
}'4.4 Marketing Campaign Alert
4.4 营销活动告警
bash
curl -s -X POST "${FEISHU_WEBHOOK_URL}" \
-H "Content-Type: application/json" \
-d '{
"msg_type": "interactive",
"card": {
"header": {
"title": {"tag": "plain_text", "content": "Campaign Alert: Budget Threshold Reached"},
"template": "orange"
},
"elements": [
{
"tag": "markdown",
"content": "**Google Ads - Q1 Brand Campaign** has reached **80%** of its monthly budget.\n\n| Metric | Value |\n|--------|-------|\n| Budget | $10,000 |\n| Spent | $8,042 |\n| Remaining | $1,958 |\n| Days Left | 8 |\n| Projected Overspend | $2,100 |\n\n**Recommendation:** Reduce daily bid cap by 15% or pause low-performing ad groups."
},
{
"tag": "action",
"actions": [
{
"tag": "button",
"text": {"tag": "plain_text", "content": "Adjust Budget"},
"type": "danger",
"url": "https://ads.google.com/campaigns"
},
{
"tag": "button",
"text": {"tag": "plain_text", "content": "View Campaign"},
"type": "default",
"url": "https://example.com/campaigns/q1-brand"
}
]
}
]
}
}'bash
curl -s -X POST "${FEISHU_WEBHOOK_URL}" \
-H "Content-Type: application/json" \
-d '{
"msg_type": "interactive",
"card": {
"header": {
"title": {"tag": "plain_text", "content": "Campaign Alert: Budget Threshold Reached"},
"template": "orange"
},
"elements": [
{
"tag": "markdown",
"content": "**Google Ads - Q1 Brand Campaign** has reached **80%** of its monthly budget.\n\n| Metric | Value |\n|--------|-------|\n| Budget | $10,000 |\n| Spent | $8,042 |\n| Remaining | $1,958 |\n| Days Left | 8 |\n| Projected Overspend | $2,100 |\n\n**Recommendation:** Reduce daily bid cap by 15% or pause low-performing ad groups."
},
{
"tag": "action",
"actions": [
{
"tag": "button",
"text": {"tag": "plain_text", "content": "Adjust Budget"},
"type": "danger",
"url": "https://ads.google.com/campaigns"
},
{
"tag": "button",
"text": {"tag": "plain_text", "content": "View Campaign"},
"type": "default",
"url": "https://example.com/campaigns/q1-brand"
}
]
}
]
}
}'5. Helper: Build and Send Cards Programmatically
5. 辅助工具:通过代码构建并发送卡片
For complex or dynamic cards, use Python to construct the JSON payload:
bash
python3 -c "
import json, subprocess, os
webhook_url = os.environ.get('FEISHU_WEBHOOK_URL', '')
if not webhook_url:
print('Error: FEISHU_WEBHOOK_URL not set')
exit(1)对于复杂或动态卡片,使用Python构建JSON请求体:
bash
python3 -c "
import json, subprocess, os
webhook_url = os.environ.get('FEISHU_WEBHOOK_URL', '')
if not webhook_url:
print('Error: FEISHU_WEBHOOK_URL not set')
exit(1)Build card dynamically
动态构建卡片
card = {
'msg_type': 'interactive',
'card': {
'header': {
'title': {'tag': 'plain_text', 'content': 'Dynamic Card Title'},
'template': 'blue'
},
'elements': []
}
}
card = {
'msg_type': 'interactive',
'card': {
'header': {
'title': {'tag': 'plain_text', 'content': 'Dynamic Card Title'},
'template': 'blue'
},
'elements': []
}
}
Add content blocks
添加内容区块
card['card']['elements'].append({
'tag': 'markdown',
'content': 'This card was built programmatically.\n\nKey metrics:\n- Users: 10,000\n- Revenue: $50,000'
})
card['card']['elements'].append({
'tag': 'markdown',
'content': 'This card was built programmatically.\n\nKey metrics:\n- Users: 10,000\n- Revenue: $50,000'
})
Add a divider
添加分隔线
card['card']['elements'].append({'tag': 'hr'})
card['card']['elements'].append({'tag': 'hr'})
Add buttons
添加按钮
card['card']['elements'].append({
'tag': 'action',
'actions': [
{
'tag': 'button',
'text': {'tag': 'plain_text', 'content': 'Learn More'},
'type': 'primary',
'url': 'https://example.com'
}
]
})
card['card']['elements'].append({
'tag': 'action',
'actions': [
{
'tag': 'button',
'text': {'tag': 'plain_text', 'content': 'Learn More'},
'type': 'primary',
'url': 'https://example.com'
}
]
})
Add footer
添加页脚
card['card']['elements'].append({
'tag': 'note',
'elements': [{'tag': 'plain_text', 'content': 'Sent via OpenClaudia'}]
})
payload = json.dumps(card)
result = subprocess.run(
['curl', '-s', '-X', 'POST', webhook_url,
'-H', 'Content-Type: application/json',
'-d', payload],
capture_output=True, text=True
)
print(result.stdout)
"
---card['card']['elements'].append({
'tag': 'note',
'elements': [{'tag': 'plain_text', 'content': 'Sent via OpenClaudia'}]
})
payload = json.dumps(card)
result = subprocess.run(
['curl', '-s', '-X', 'POST', webhook_url,
'-H', 'Content-Type: application/json',
'-d', payload],
capture_output=True, text=True
)
print(result.stdout)
"
---6. Bilingual Support (Chinese + English)
6. 双语支持(中文 + 英文)
When sending messages that need both Chinese and English content, use the rich text format which supports multiple locales. Feishu will display the locale matching the user's language setting.
postbash
curl -s -X POST "${FEISHU_WEBHOOK_URL}" \
-H "Content-Type: application/json" \
-d '{
"msg_type": "post",
"content": {
"post": {
"zh_cn": {
"title": "重要通知:系统维护",
"content": [
[
{"tag": "text", "text": "我们将于 "},
{"tag": "text", "text": "1月25日 22:00-02:00 (北京时间)", "un_escape": true},
{"tag": "text", "text": " 进行系统维护。"}
],
[
{"tag": "text", "text": "维护期间服务将暂时不可用。如有问题请联系 "},
{"tag": "a", "text": "技术支持", "href": "https://example.com/support"},
{"tag": "text", "text": "。"}
]
]
},
"en_us": {
"title": "Important: Scheduled Maintenance",
"content": [
[
{"tag": "text", "text": "We will perform scheduled maintenance on "},
{"tag": "text", "text": "January 25, 10:00 PM - 2:00 AM (CST)"},
{"tag": "text", "text": "."}
],
[
{"tag": "text", "text": "Services will be temporarily unavailable. For questions, contact "},
{"tag": "a", "text": "Support", "href": "https://example.com/support"},
{"tag": "text", "text": "."}
]
]
}
}
}
}'当需要发送中英文双语内容时,使用富文本格式,该格式支持多语言环境。Feishu会根据用户的语言设置显示对应版本的内容。
postbash
curl -s -X POST "${FEISHU_WEBHOOK_URL}" \
-H "Content-Type: application/json" \
-d '{
"msg_type": "post",
"content": {
"post": {
"zh_cn": {
"title": "重要通知:系统维护",
"content": [
[
{"tag": "text", "text": "我们将于 "},
{"tag": "text", "text": "1月25日 22:00-02:00 (北京时间)", "un_escape": true},
{"tag": "text", "text": " 进行系统维护。"}
],
[
{"tag": "text", "text": "维护期间服务将暂时不可用。如有问题请联系 "},
{"tag": "a", "text": "技术支持", "href": "https://example.com/support"},
{"tag": "text", "text": "。"}
]
]
},
"en_us": {
"title": "Important: Scheduled Maintenance",
"content": [
[
{"tag": "text", "text": "We will perform scheduled maintenance on "},
{"tag": "text", "text": "January 25, 10:00 PM - 2:00 AM (CST)"},
{"tag": "text", "text": "."}
],
[
{"tag": "text", "text": "Services will be temporarily unavailable. For questions, contact "},
{"tag": "a", "text": "Support", "href": "https://example.com/support"},
{"tag": "text", "text": "."}
]
]
}
}
}
}'7. Error Handling
7. 错误处理
Webhook Response Codes
Webhook响应码
| Code | StatusMessage | Meaning |
|---|---|---|
| 0 | | Message sent successfully |
| 9499 | | Malformed JSON or missing required fields |
| 19001 | | Invalid msg_type or content format |
| 19002 | | Signature verification failed (check timestamp and secret) |
| 19021 | | Rate limit: max 100 messages per minute per webhook |
| 19024 | | Bot has been removed from the group |
| 代码 | 状态消息 | 含义 |
|---|---|---|
| 0 | | 消息发送成功 |
| 9499 | | JSON格式错误或缺少必填字段 |
| 19001 | | msg_type或内容格式无效 |
| 19002 | | 签名验证失败(检查时间戳和密钥) |
| 19021 | | 触发频率限制:每个webhook每分钟最多发送100条消息 |
| 19024 | | Bot已被移出群组 |
Common Troubleshooting
常见故障排查
Message not delivered:
- Verify the webhook URL is correct and the bot is still in the group
- Check that matches the content structure
msg_type - For signed webhooks, ensure the timestamp is within 1 hour of current time
Card not rendering:
- Validate JSON structure: header and elements are both required
- Button URLs must start with or
http://https:// - Markdown in cards supports a limited subset: bold, italic, links, lists, tables
API token errors:
- Tenant access tokens expire after 2 hours; re-fetch before sending
- Ensure the app has been published and approved in the developer console
- Verify permission is granted
im:message:send_as_bot
消息未送达:
- 验证webhook URL是否正确,且Bot仍在群组中
- 检查是否与内容结构匹配
msg_type - 对于签名webhook,确保时间戳与当前时间差不超过1小时
卡片未正常渲染:
- 验证JSON结构:header和elements字段均为必填项
- 按钮URL必须以或
http://开头https:// - 卡片中的Markdown仅支持有限子集:加粗、斜体、链接、列表、表格
API令牌错误:
- 租户访问令牌有效期为2小时,发送前需重新获取
- 确保应用已在开发者控制台发布并通过审核
- 验证已授予权限
im:message:send_as_bot
Rate Limits
频率限制
| Integration | Limit |
|---|---|
| Custom Bot Webhook | 100 messages/minute per webhook |
| App Bot API (messages) | 50 messages/second per app |
| App Bot API (token refresh) | 500 requests/hour |
| 集成方式 | 限制 |
|---|---|
| 自定义Bot Webhook | 每个webhook每分钟100条消息 |
| App Bot API(消息发送) | 每个应用每秒50条消息 |
| App Bot API(令牌刷新) | 每小时500次请求 |
8. Workflow: Post Marketing Content to Feishu/Lark
8. 工作流:向Feishu/Lark发送营销内容
When the user asks to send marketing content to Feishu or Lark, follow this workflow:
当用户要求向Feishu或Lark发送营销内容时,请遵循以下工作流:
Step 1: Check Credentials
步骤1:检查凭证
Verify that or + are set. If not, guide the user through setup.
FEISHU_WEBHOOK_URLFEISHU_APP_IDFEISHU_APP_SECRET验证或 + 是否已设置。如果未设置,指导用户完成配置。
FEISHU_WEBHOOK_URLFEISHU_APP_IDFEISHU_APP_SECRETStep 2: Determine Message Type
步骤2:确定消息类型
| User Intent | Recommended Format |
|---|---|
| Quick text update | Plain text ( |
| Formatted announcement | Rich text ( |
| Marketing report with metrics | Interactive card with columns |
| Product launch | Interactive card with buttons |
| Event notification | Interactive card with CTA buttons |
| Alert or warning | Interactive card with |
| 用户意图 | 推荐格式 |
|---|---|
| 快速文本更新 | 纯文本( |
| 格式化公告 | 富文本( |
| 带指标的营销报告 | 带多列布局的互动卡片 |
| 产品发布 | 带按钮的互动卡片 |
| 活动通知 | 带CTA按钮的互动卡片 |
| 告警或警告 | 红色/橙色标题的互动卡片 |
Step 3: Compose the Message
步骤3:撰写消息
- Use the appropriate template from section 4
- Adapt content to the user's requirements
- For bilingual groups, provide both and
zh_cncontenten_us
- 使用第4节中的对应模板
- 根据用户需求调整内容
- 对于双语群组,同时提供和
zh_cn版本内容en_us
Step 4: Preview and Confirm
步骤4:预览并确认
Show the user the full JSON payload before sending. Explain what the message will look like.
Never auto-send without explicit user confirmation.
在发送前向用户展示完整的JSON请求体,说明消息的显示效果。
未经用户明确确认,请勿自动发送消息。
Step 5: Send
步骤5:发送消息
Execute the curl command and report the response.
执行curl命令并反馈响应结果。
Step 6: Verify
步骤6:验证结果
Check the response code. If , the message was delivered. If there is an error, troubleshoot using the error table above.
code: 0检查响应码。如果,则消息已送达。如果出现错误,使用上述错误表进行排查。
code: 09. Advanced: Message Card JSON Schema Quick Reference
9. 进阶:消息卡片JSON Schema快速参考
{
"msg_type": "interactive",
"card": {
"header": { // Required
"title": {
"tag": "plain_text",
"content": "string"
},
"template": "blue|green|red|..." // Header color
},
"elements": [ // Required, array of blocks
{"tag": "markdown", "content": "..."}, // Rich content
{"tag": "hr"}, // Divider line
{"tag": "img", "img_key": "...", "alt": {...}}, // Image
{ // Multi-column layout
"tag": "column_set",
"flex_mode": "bisect|trisect|...",
"columns": [
{"tag": "column", "width": "weighted", "weight": 1, "elements": [...]}
]
},
{ // Action buttons
"tag": "action",
"actions": [
{"tag": "button", "text": {...}, "type": "primary|danger|default", "url": "..."}
]
},
{ // Footer note
"tag": "note",
"elements": [{"tag": "plain_text", "content": "..."}]
}
]
}
}{
"msg_type": "interactive",
"card": {
"header": { // 必填
"title": {
"tag": "plain_text",
"content": "string"
},
"template": "blue|green|red|..." // 标题颜色
},
"elements": [ // 必填,区块数组
{"tag": "markdown", "content": "..."}, // 富内容
{"tag": "hr"}, // 分隔线
{"tag": "img", "img_key": "...", "alt": {...}}, // 图片
{ // 多列布局
"tag": "column_set",
"flex_mode": "bisect|trisect|...",
"columns": [
{"tag": "column", "width": "weighted", "weight": 1, "elements": [...]}
]
},
{ // 操作按钮
"tag": "action",
"actions": [
{"tag": "button", "text": {...}, "type": "primary|danger|default", "url": "..."}
]
},
{ // 页脚备注
"tag": "note",
"elements": [{"tag": "plain_text", "content": "..."}]
}
]
}
}Tips
小贴士
- Start with webhooks. Custom Bot Webhooks require zero code infrastructure and can be set up in under a minute.
- Use interactive cards for anything beyond simple text. They are more readable and actionable.
- Include action buttons in every marketing card. Drive recipients to a landing page, dashboard, or sign-up form.
- Leverage bilingual support if your team uses both Feishu and Lark, or has members in China and internationally.
- Respect rate limits. For bulk messaging (e.g., sending to multiple groups), add a 1-second delay between requests.
- Test in a private group first before sending to large team channels.
- Keep card content concise. Cards have a maximum content size of approximately 30KB. For very long reports, link to an external page.
- Use the Feishu Message Card Builder for visual card design: https://open.feishu.cn/tool/cardbuilder (Feishu) or https://open.larksuite.com/tool/cardbuilder (Lark).
- 从webhook开始:自定义Bot Webhook无需代码基础设施,可在1分钟内完成配置。
- 使用互动卡片:除简单文本外,优先使用互动卡片,可读性和可操作性更强。
- 添加操作按钮:在所有营销卡片中加入按钮,引导接收者访问落地页、仪表盘或注册表单。
- 利用双语支持:如果团队同时使用Feishu和Lark,或成员分布在中国和海外,请提供双语内容。
- 遵守频率限制:批量发送消息(如向多个群组发送)时,在请求之间添加1秒延迟。
- 先在私有群组测试:向大型团队频道发送前,先在私有群组测试效果。
- 保持卡片内容简洁:卡片最大内容约为30KB,对于超长报告,请链接到外部页面。
- 使用Feishu消息卡片构建器:可视化设计卡片:https://open.feishu.cn/tool/cardbuilder(Feishu)或https://open.larksuite.com/tool/cardbuilder(Lark)。