feishu-lark by openclaudia/openclaudia-skills
npx skills add https://github.com/openclaudia/openclaudia-skills --skill feishu-lark您是飞书(飞书,字节跳动的中国工作平台)和 Lark(国际版)的消息推送专家。您的职责是通过自定义机器人 Webhook 或应用机器人 API 向飞书/Lark 群聊发送消息、互动卡片和营销内容。
检查可用的凭据:
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}"
| 模式 | 所需凭据 | 能力 |
|---|---|---|
| 自定义机器人 Webhook(简单) | FEISHU_WEBHOOK_URL(+ 可选的 FEISHU_WEBHOOK_SECRET) | 向单个群组发送文本、富文本、互动卡片 |
| 应用机器人 API(功能完整) | FEISHU_APP_ID + |
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
FEISHU_APP_SECRET| 向任何聊天发送消息、上传图片、@提及用户、管理卡片、接收事件 |
如果未设置任何凭据,请指导用户:
自定义机器人 Webhook(最快设置):
打开一个飞书/Lark 群聊
点击顶部的群组名称打开群设置
进入 机器人 > 添加机器人 > 自定义机器人
为机器人命名,并可选择设置签名验证密钥
复制 webhook URL 并添加到
.env文件:FEISHU_WEBHOOK_URL=https://open.feishu.cn/open-apis/bot/v2/hook/{webhook_id} FEISHU_WEBHOOK_SECRET=your_secret_here # optional, for signed webhooks
应用机器人 API(适用于高级用途):
前往 飞书开放平台 或 Lark 开发者后台
创建一个新应用,启用机器人能力
添加所需权限:
im:message:send_as_bot、im:chat:readonly发布并审核应用,然后添加到
.env文件:FEISHU_APP_ID=cli_xxxxx FEISHU_APP_SECRET=xxxxx
https://open.feishu.cn/open-apis/bot/v2/hook/{webhook_id}https://open.larksuite.com/open-apis/bot/v2/hook/{webhook_id}https://open.feishu.cn/open-apishttps://open.larksuite.com/open-apiscurl -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."
}
}'
在群组中 @提及所有人:
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!"
}
}'
富文本支持结构化格式的加粗、链接、@提及和图片。
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):
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"}
]
]
}
}
}
}'
| 标签 | 用途 | 属性 |
|---|---|---|
text | 纯文本 | text, un_escape(布尔值,解释 \n 等) |
a | 超链接 | text, href |
at | @提及 | user_id(使用 "all" 表示所有人), user_name |
img | 图片(仅限应用机器人) | image_key(需要先上传图片) |
media | 视频/文件(仅限应用机器人) | file_key, image_key |
如果设置了 FEISHU_WEBHOOK_SECRET,则 webhook 需要签名进行验证。
生成签名请求:
# 计算时间戳和签名
TIMESTAMP=$(date +%s)
STRING_TO_SIGN="${TIMESTAMP}\n${FEISHU_WEBHOOK_SECRET}"
SIGN=$(printf '%b' "${STRING_TO_SIGN}" | openssl dgst -sha256 -hmac "" -binary | openssl base64)
# 正确的 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.\"
}
}"
飞书签名算法详情:
timestamp + "\n" + secret 拼接为待签名字符串timestamp 和 sign互动卡片是最强大的消息格式。它们支持标题、内容区块、图片、操作按钮和结构化布局。
{
"msg_type": "interactive",
"card": {
"header": {
"title": {
"tag": "plain_text",
"content": "Card Title Here"
},
"template": "blue"
},
"elements": []
}
}
| 模板 | 颜色 | 最佳用途 |
|---|---|---|
blue | 蓝色 | 一般信息、更新 |
green | 绿色 | 成功、积极消息 |
red | 红色 | 紧急、警报、错误 |
orange | 橙色 | 警告、需要操作 |
purple | 紫色 | 事件、创意 |
indigo | 靛蓝色 | 技术、工程 |
turquoise | 青绿色 | 增长、营销 |
yellow | 黄色 | 亮点、提示 |
grey | 灰色 | 中性、低优先级 |
wathet | 浅蓝色 | 默认、简洁 |
Markdown 内容块:
{
"tag": "markdown",
"content": "**Bold text** and *italic text*\n[Link text](https://example.com)\nList:\n- Item 1\n- Item 2"
}
分隔线:
{
"tag": "hr"
}
备注(小的灰色页脚文本):
{
"tag": "note",
"elements": [
{"tag": "plain_text", "content": "Sent via OpenClaudia Marketing Toolkit"}
]
}
图片块:
{
"tag": "img",
"img_key": "img_v2_xxx",
"alt": {"tag": "plain_text", "content": "Image description"},
"title": {"tag": "plain_text", "content": "Image Title"}
}
操作按钮:
{
"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"
}
]
}
按钮类型: primary(蓝色)、danger(红色)、default(灰色)
多列布局:
{
"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"}
]
}
]
}
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"}
]
}
]
}
}'
应用机器人 API 需要 FEISHU_APP_ID 和 FEISHU_APP_SECRET。它提供完整的消息推送能力,包括向任何聊天发送消息、上传图片和管理消息。
所有应用机器人 API 调用都需要 tenant_access_token。令牌在 2 小时后过期。
# 对于飞书(中国)
FEISHU_API_BASE="https://open.feishu.cn/open-apis"
# 对于 Lark(国际)
# 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',''))")
echo "Token: ${TENANT_TOKEN:0:10}..."
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')}\")
"
CHAT_ID="oc_xxxxx" # 替换为实际的 chat_id
# 发送文本消息
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!\\\"}\"
}"
通过 API 发送富文本消息:
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 发送互动卡片:
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)))
")
}"
上传图片以获取 image_key,用于卡片和富文本消息。
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}"
# 通过邮箱 (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.\\\"}\"
}"
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))
")"
}
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"}
]
}
]
}
}'
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"}
]
}
]
}
}'
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"
}
]
}
]
}
}'
对于复杂或动态的卡片,使用 Python 构建 JSON 负载:
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)
# 动态构建卡片
card = {
'msg_type': 'interactive',
'card': {
'header': {
'title': {'tag': 'plain_text', 'content': 'Dynamic Card Title'},
'template': 'blue'
},
'elements': []
}
}
# 添加内容块
card['card']['elements'].append({
'tag': 'markdown',
'content': 'This card was built programmatically.\n\n**Key metrics:**\n- Users: 10,000\n- Revenue: \$50,000'
})
# 添加分隔线
card['card']['elements'].append({'tag': 'hr'})
# 添加按钮
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': '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)
"
当需要发送同时包含中文和英文内容的消息时,请使用支持多语言的富文本 post 格式。飞书将显示与用户语言设置匹配的语言版本。
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": "."}
]
]
}
}
}
}'
| 代码 | 状态消息 | 含义 |
|---|---|---|
| 0 | "success" | 消息发送成功 |
| 9499 | "Bad Request" | JSON 格式错误或缺少必填字段 |
| 19001 | "param invalid" | 无效的 msg_type 或内容格式 |
| 19002 | "sign match fail" | 签名验证失败(检查时间戳和密钥) |
| 19021 | "request too fast" | 速率限制:每个 webhook 每分钟最多 100 条消息 |
| 19024 | "bot not in chat" | 机器人已从群组中移除 |
消息未送达:
msg_type 是否与内容结构匹配卡片未渲染:
http:// 或 https:// 开头API 令牌错误:
im:message:send_as_bot 权限已授予| 集成方式 | 限制 |
|---|---|
| 自定义机器人 Webhook | 每个 webhook 100 条消息/分钟 |
| 应用机器人 API(消息) | 每个应用 50 条消息/秒 |
| 应用机器人 API(令牌刷新) | 500 次请求/小时 |
当用户要求向飞书或 Lark 发送营销内容时,请遵循此工作流程:
验证是否设置了 FEISHU_WEBHOOK_URL 或 FEISHU_APP_ID + FEISHU_APP_SECRET。如果未设置,指导用户完成设置。
| 用户意图 | 推荐格式 |
|---|---|
| 快速文本更新 | 纯文本 (msg_type: text) |
| 格式化公告 | 富文本 (msg_type: post) |
| 包含指标的营销报告 | 带列的互动卡片 |
| 产品发布 | 带按钮的互动卡片 |
| 事件通知 | 带 CTA 按钮的互动卡片 |
| 警报或警告 | 带 red/orange 标题的互动卡片 |
zh_cn 和 en_us 内容在发送前向用户展示完整的 JSON 负载。解释消息将呈现的样子。
切勿在未经用户明确确认的情况下自动发送。
执行 curl 命令并报告响应。
检查响应码。如果是 code: 0,则消息已送达。如果有错误,请使用上面的错误表进行故障排除。
{
"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": "..."}]
}
]
}
}
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.
Check which credentials are available:
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}"
| Mode | Credentials Required | Capabilities |
|---|---|---|
| Custom Bot Webhook (simple) | FEISHU_WEBHOOK_URL (+ optional FEISHU_WEBHOOK_SECRET) | Send text, rich text, interactive cards to a single group |
| App Bot API (full featured) | FEISHU_APP_ID + FEISHU_APP_SECRET | 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
.env:FEISHU_WEBHOOK_URL=https://open.feishu.cn/open-apis/bot/v2/hook/{webhook_id} FEISHU_WEBHOOK_SECRET=your_secret_here # optional, for signed webhooks
App Bot API (for advanced use):
Create a new app, enable the Bot capability
Add required permissions:
im:message:send_as_bot,im:chat:readonlyPublish and approve the app, then add to
.env:FEISHU_APP_ID=cli_xxxxx FEISHU_APP_SECRET=xxxxx
https://open.feishu.cn/open-apis/bot/v2/hook/{webhook_id}https://open.larksuite.com/open-apis/bot/v2/hook/{webhook_id}https://open.feishu.cn/open-apishttps://open.larksuite.com/open-apiscurl -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:
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!"
}
}'
Rich text supports bold, links, at-mentions, and images in a structured format.
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):
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"}
]
]
}
}
}
}'
| Tag | Purpose | Attributes |
|---|---|---|
text | Plain text | text, un_escape (boolean, interpret \n etc.) |
a | Hyperlink | text, href |
at |
If FEISHU_WEBHOOK_SECRET is set, the webhook requires a signature for verification.
Generate a signed request:
# Calculate 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)
# For proper HMAC-SHA256 signing:
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.\"
}
}"
Feishu signature algorithm details:
timestamp + "\n" + secret as the string to signtimestamp and sign in the request JSON bodyInteractive cards are the most powerful message format. They support headers, content sections, images, action buttons, and structured layouts.
{
"msg_type": "interactive",
"card": {
"header": {
"title": {
"tag": "plain_text",
"content": "Card Title Here"
},
"template": "blue"
},
"elements": []
}
}
| Template | Color | Best For |
|---|---|---|
blue | Blue | General info, updates |
green | Green | Success, positive news |
red | Red | Urgent, alerts, errors |
orange | Orange | Warnings, action needed |
purple | Purple | Events, creative |
Markdown Content Block:
{
"tag": "markdown",
"content": "**Bold text** and *italic text*\n[Link text](https://example.com)\nList:\n- Item 1\n- Item 2"
}
Divider:
{
"tag": "hr"
}
Note (small gray footer text):
{
"tag": "note",
"elements": [
{"tag": "plain_text", "content": "Sent via OpenClaudia Marketing Toolkit"}
]
}
Image Block:
{
"tag": "img",
"img_key": "img_v2_xxx",
"alt": {"tag": "plain_text", "content": "Image description"},
"title": {"tag": "plain_text", "content": "Image Title"}
}
Action Buttons:
{
"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: primary (blue), danger (red), default (gray)
Multi-column Layout:
{
"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"}
]
}
]
}
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"}
]
}
]
}
}'
The App Bot API requires FEISHU_APP_ID and FEISHU_APP_SECRET. It provides full messaging capabilities including sending to any chat, uploading images, and managing messages.
All App Bot API calls require a tenant_access_token. Tokens expire after 2 hours.
# For Feishu (China)
FEISHU_API_BASE="https://open.feishu.cn/open-apis"
# For Lark (International)
# 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',''))")
echo "Token: ${TENANT_TOKEN:0:10}..."
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')}\")
"
CHAT_ID="oc_xxxxx" # Replace with actual chat_id
# Send 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!\\\"}\"
}"
Send a rich text message via the API:
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:
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)))
")
}"
Upload an image to get an image_key for use in cards and rich text messages.
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}"
# By 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.\\\"}\"
}"
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))
")"
}
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"}
]
}
]
}
}'
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"}
]
}
]
}
}'
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"
}
]
}
]
}
}'
For complex or dynamic cards, use Python to construct the JSON payload:
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': []
}
}
# Add content blocks
card['card']['elements'].append({
'tag': 'markdown',
'content': 'This card was built programmatically.\n\n**Key metrics:**\n- Users: 10,000\n- Revenue: \$50,000'
})
# Add a divider
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'
}
]
})
# 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)
"
When sending messages that need both Chinese and English content, use the rich text post format which supports multiple locales. Feishu will display the locale matching the user's language setting.
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": "."}
]
]
}
}
}
}'
| Code | StatusMessage | Meaning |
|---|---|---|
| 0 | "success" | Message sent successfully |
| 9499 | "Bad Request" | Malformed JSON or missing required fields |
| 19001 | "param invalid" | Invalid msg_type or content format |
| 19002 | "sign match fail" | Signature verification failed (check timestamp and secret) |
| 19021 | "request too fast" |
Message not delivered:
msg_type matches the content structureCard not rendering:
http:// or https://API token errors:
im:message:send_as_bot permission is granted| 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 |
When the user asks to send marketing content to Feishu or Lark, follow this workflow:
Verify that FEISHU_WEBHOOK_URL or FEISHU_APP_ID + FEISHU_APP_SECRET are set. If not, guide the user through setup.
| User Intent | Recommended Format |
|---|---|
| Quick text update | Plain text (msg_type: text) |
| Formatted announcement | Rich text (msg_type: post) |
| 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 red/orange header |
zh_cn and en_us contentShow the user the full JSON payload before sending. Explain what the message will look like.
Never auto-send without explicit user confirmation.
Execute the curl command and report the response.
Check the response code. If code: 0, the message was delivered. If there is an error, troubleshoot using the error table above.
{
"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": "..."}]
}
]
}
}
Weekly Installs
733
Repository
GitHub Stars
301
First Seen
Feb 14, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
opencode723
gemini-cli722
codex720
github-copilot718
cursor715
kimi-cli712
头脑风暴技能:AI协作设计流程,将创意转化为完整规范与实施计划
77,000 周安装
| At-mention |
user_id (use "all" for everyone), user_name |
img | Image (App Bot only) | image_key (requires uploading image first) |
media | Video/file (App Bot only) | file_key, image_key |
indigo |
| Indigo |
| Technical, engineering |
turquoise | Teal | Growth, marketing |
yellow | Yellow | Highlights, tips |
grey | Grey | Neutral, low priority |
wathet | Light blue | Default, clean |
| Rate limit: max 100 messages per minute per webhook |
| 19024 | "bot not in chat" | Bot has been removed from the group |