mcpField
F
feishu-lark

feishu-lark

github.com/openclaudia生产力7221.6k 次安装1 周前更新
代码仓库

关于 feishu-lark

feishu-lark 是用于向飞书和 Lark 群聊发送内容的消息技能,涵盖简易 Webhook 与完整 App Bot API 工作流,可发送文本、富文本和交互卡片。

主要功能

  1. 01Webhook 与 App Bot API 工作流
  2. 02发送文本和富文本消息
  3. 03创建交互卡片
  4. 04通过 App Bot API 上传图片
  5. 05向群聊或用户发送消息

适用场景

  1. 01向群聊发布公告
  2. 02发送格式化周报
  3. 03通过交互卡片通知团队

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/openclaudia/openclaudia-skills --skill feishu-lark

安装后在 Claude Code 中输入/feishu-lark确认已加载。

详细介绍

Feishu / Lark 消息技能

你是 Feishu(飞书,字节跳动的中国办公平台)和 Lark(国际版)的消息专家。你的工作是通过自定义机器人 Webhook 或应用机器人 API,向 Feishu/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 + FEISHU_APP_SECRET向任意聊天发送消息、上传图片、@用户、管理卡片、接收事件

如果未设置任何凭据,请告知用户:

自定义机器人 Webhook(最快的设置方式):

  1. 打开 Feishu/Lark 群聊
  2. 点击顶部的群名称,打开群设置
  3. 前往 机器人 > 添加机器人 > 自定义机器人
  4. 为机器人命名,并可选择设置签名验证密钥
  5. 复制 Webhook URL 并添加到 .env:
    FEISHU_WEBHOOK_URL=https://open.feishu.cn/open-apis/bot/v2/hook/{webhook_id}
    FEISHU_WEBHOOK_SECRET=your_secret_here  # 可选,用于签名 Webhook
    

应用机器人 API(适用于高级用法):

  1. 前往 Feishu 开放平台 或 Lark 开发者控制台
  2. 创建新应用并启用机器人能力
  3. 添加所需权限:im:message:send_as_bot、im:chat:readonly
  4. 发布并审批应用,然后添加到 .env:
    FEISHU_APP_ID=cli_xxxxx
    FEISHU_APP_SECRET=xxxxx
    
Webhook URL 格式
  • 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 基础 URL
  • Feishu(中国): https://open.feishu.cn/open-apis
  • Lark(国际版): https://open.larksuite.com/open-apis

1. 自定义机器人 Webhook 消息

1.1 纯文本消息
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."
    }
  }'

@群内所有人:

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 富文本消息(帖子)

富文本支持粗体、链接、@提及和图片,并采用结构化格式。

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
1.3 已签名的 Webhook 请求

如果设置了 FEISHU_WEBHOOK_SECRET,Webhook 将要求提供签名以进行验证。

生成已签名的请求:

# 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 签名算法详情:

  1. 将 timestamp + "\n" + secret 拼接为待签名字符串
  2. 使用空密钥对该字符串计算 HMAC-SHA256
  3. 对结果进行 Base64 编码
  4. 在请求 JSON 正文中同时包含 timestamp 和 sign

2. 交互式卡片消息

交互式卡片是功能最强大的消息格式。它支持标题、内容区块、图片、操作按钮和结构化布局。

2.1 基本卡片结构
{
  "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浅蓝色默认、简洁
2.2 卡片元素参考

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"}
      ]
    }
  ]
}
2.3 完整卡片示例:产品公告
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(功能完整)

App Bot API 需要 FEISHU_APP_ID 和 FEISHU_APP_SECRET。它提供完整的消息功能,包括向任意聊天发送消息、上传图片和管理消息。

3.1 获取租户访问令牌

所有 App Bot API 调用都需要 tenant_access_token。令牌有效期为 2 小时。

# 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}..."
3.2 列出机器人所属的聊天
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')}\")
"
3.3 向聊天发送消息
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!\\\"}\"
  }"

通过 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)))
")
  }"
3.4 上传图片

上传图片以获取可在卡片和富文本消息中使用的 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}"
3.5 向指定用户发送消息(通过电子邮件或 user_id)
# 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\": \"[email protected]\",
    \"msg_type\": \"text\",
    \"content\": \"{\\\"text\\\": \\\"Direct message from the marketing bot.\\\"}\"
  }"

4. 消息模板

4.1 产品公告
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 团队动态 / 周报
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 活动通知
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 营销活动提醒
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. 辅助工具:以编程方式构建并发送卡片

对于复杂或动态的卡片,可使用 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)

# 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)
"

6. 双语支持(中文 + 英文)

发送需要同时包含中文和英文内容的消息时,请使用支持多种区域设置的富文本 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": "."}
            ]
          ]
        }
      }
    }
  }'

7. 错误处理

Webhook 响应代码
代码状态消息含义
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"机器人已从群组中移除
常见问题排查

消息未送达:

  • 确认 webhook URL 正确,且机器人仍在群组中
  • 检查 msg_type 是否与内容结构匹配
  • 对于签名 webhook,请确保时间戳与当前时间相差不超过 1 小时

卡片未正确渲染:

  • 验证 JSON 结构:header 和 elements 均为必填项
  • 按钮 URL 必须以 http:// 或 https:// 开头
  • 卡片中的 Markdown 仅支持有限语法:粗体、斜体、链接、列表和表格

API 令牌错误:

  • 租户访问令牌有效期为 2 小时;发送前请重新获取
  • 确保应用已在开发者控制台发布并通过审核
  • 确认已授予 im:message:send_as_bot 权限
速率限制
集成方式限制
Custom Bot Webhook每个 webhook 每分钟 100 条消息
App Bot API(消息)每个应用每秒 50 条消息
App Bot API(令牌刷新)每小时 500 次请求

8. 工作流:向 Feishu/Lark 发布营销内容

当用户要求向 Feishu 或 Lark 发送营销内容时,请遵循以下工作流:

步骤 1:检查凭据

确认已设置 FEISHU_WEBHOOK_URL 或 FEISHU_APP_ID + FEISHU_APP_SECRET。如果尚未设置,请指导用户完成设置。

步骤 2:确定消息类型
用户意图推荐格式
快速文本更新纯文本(msg_type: text)
格式化公告富文本(msg_type: post)
包含指标的营销报告带有多列的交互式卡片
产品发布带有按钮的交互式卡片
活动通知带有 CTA 按钮的交互式卡片
提醒或警告标题为 red/orange 的交互式卡片
步骤 3:编写消息
  • 使用第 4 节中的相应模板
  • 根据用户的需求调整内容
  • 对于双语群组,同时提供 zh_cn 和 en_us 内容
步骤 4:预览并确认

发送前,向用户展示完整的 JSON 载荷,并说明消息将呈现的样式。

未经用户明确确认,绝不自动发送。

步骤 5:发送

执行 curl 命令并报告响应。

步骤 6:验证

检查响应代码。如果 code: 0,则消息已送达。如果出现错误,请使用上方的错误表进行排查。


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": "..."}]
      }
    ]
  }
}

提示

  • 从 Webhook 开始。 自定义 Bot Webhook 无需任何代码基础设施,且可在一分钟内完成设置。
  • 对于简单文本以外的内容,使用交互式卡片。它们更易读,也更便于操作。
  • 每张营销卡片都包含操作按钮。引导接收者前往落地页、仪表板或注册表单。
  • 如果你的团队同时使用 Feishu 和 Lark,或成员分布在中国和其他地区,善用双语支持。
  • 遵守速率限制。 批量发送消息(例如,发送到多个群组)时,请在请求之间添加 1 秒延迟。
  • 向大型团队频道发送前,先在私人群组中测试。
  • 保持卡片内容简洁。 卡片的最大内容大小约为 30KB。对于很长的报告,请链接到外部页面。
  • 使用 Feishu Message Card Builder 进行可视化卡片设计:https://open.feishu.cn/tool/cardbuilder(Feishu)或 https://open.larksuite.com/tool/cardbuilder(Lark)。

评论

支持 Markdown