OpenClaudia/openclaudia-skills/skills/feishu-lark/SKILL.md
feishu-lark
Use it for engineering and marketing tasks; the detail page covers purpose, installation, and practical steps.
- Source repository stars
- 662
- Declared platforms
- 0
- Static risk flags
- 3
- Last source update
- 2026-08-24
- Source checked
- 2026-08-25
Decision brief
What it does: where it fits
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.
Not for
- Tasks that require unconfirmed production actions or broad system permissions.
- Environments where the pinned source and install steps cannot be inspected.
Compatibility matrix
Platform support, with evidence labels
| Platform | Status | Evidence | What to check |
|---|---|---|---|
| Codex | Not declared | No explicit evidence | Portability before use |
| Claude Code | Not declared | No explicit evidence | Portability before use |
| Cursor | Not declared | No explicit evidence | Portability before use |
| Gemini CLI | Not declared | No explicit evidence | Portability before use |
Installation
Inspect first. Install second.
The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.
npx skills add https://github.com/OpenClaudia/openclaudia-skills --skill "skills/feishu-lark"Inspect the Agent Skill "feishu-lark" from https://github.com/OpenClaudia/openclaudia-skills/blob/6b91665a5ab7d36599a605df17dae3e27d5ab242/skills/feishu-lark/SKILL.md at commit 6b91665a5ab7d36599a605df17dae3e27d5ab242. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.
Workflow
What the source asks the agent to do
- 01
8. Workflow: Post Marketing Content to Feishu/Lark
When the user asks to send marketing content to Feishu or Lark, follow this workflow:
Use the appropriate template from section 4Adapt content to the user's requirementsFor bilingual groups, provide both zhcn and enus content - 02
Step 1: Check Credentials
Verify that FEISHUWEBHOOKURL or FEISHUAPPID + FEISHUAPPSECRET are set. If not, guide the user through setup.
Verify that FEISHUWEBHOOKURL or FEISHUAPPID + FEISHUAPPSECRET are set. If not, guide the user through setup. - 03
Step 2: Determine Message Type
Review the “Step 2: Determine Message Type” section in the pinned source before continuing.
Review and apply the “Step 2: Determine Message Type” source section. - 04
Step 3: Compose the Message
Use the appropriate template from section 4
Use the appropriate template from section 4Adapt content to the user's requirementsFor bilingual groups, provide both zhcn and enus content - 05
Step 4: Preview and Confirm
Show the user the full JSON payload before sending. Explain what the message will look like.
Show the user the full JSON payload before sending. Explain what the message will look like.Never auto-send without explicit user confirmation.
Permission review
Static risk signals and limitations
Sends data out
The documentation includes sending, uploading, or posting data to a remote service.
curl -s -X POST "${FEISHU_WEBHOOK_URL}" \Network access
The documentation includes network, browsing, or remote request actions.
curl -s -X POST "${FEISHU_WEBHOOK_URL}" \Sends data out
The documentation includes sending, uploading, or posting data to a remote service.
curl -s -X POST "${FEISHU_WEBHOOK_URL}" \Network access
The documentation includes network, browsing, or remote request actions.
curl -s -X POST "${FEISHU_WEBHOOK_URL}" \Runs scripts
The documentation asks the agent to run terminal commands or scripts.
python3 -c "Runs scripts
The documentation asks the agent to run terminal commands or scripts.
python3 -c "Evidence record
Why each signal appears
| Signal | Value | Evidence type | Meaning |
|---|---|---|---|
| Quality score | 90/100 | Computed | Documentation, specificity, maintenance, and trust rules |
| Repository stars | 662 | Source | Repository attention, not individual Skill quality |
| Compatibility | 0 platforms | Source | Declared in the catalog source record |
| Usage guide | automated source guide | Editorial | Generated or reviewed according to the visible evidence level |
Pinned source
Provenance and original SKILL.md
- Repository
- OpenClaudia/openclaudia-skills
- Skill path
- skills/feishu-lark/SKILL.md
- Commit
- 6b91665a5ab7d36599a605df17dae3e27d5ab242
- License
- MIT
- Collected
- 2026-08-25
- Default branch
- main
View the original SKILL.md
Feishu / Lark Messaging Skill
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.
Prerequisites
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}"
Two Integration Modes
| 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 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_bot,im:chat:readonly- Publish and approve the app, then add to
.env:FEISHU_APP_ID=cli_xxxxx FEISHU_APP_SECRET=xxxxx
Webhook URL Formats
- 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}
API Base URLs
- Feishu (China):
https://open.feishu.cn/open-apis - Lark (International):
https://open.larksuite.com/open-apis
1. Custom Bot Webhook Messages
1.1 Plain Text Message
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:
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)
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"}
]
]
}
}
}
}'
Rich Text Tag Reference
| Tag | Purpose | Attributes |
|---|---|---|
text | Plain text | text, un_escape (boolean, interpret \n etc.) |
a | Hyperlink | text, href |
at | 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 |
1.3 Signed Webhook Requests
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:
- Concatenate
timestamp + "\n" + secretas the string to sign - Compute HMAC-SHA256 with an empty key over that string
- Base64-encode the result
- Include both
timestampandsignin the request JSON body
2. Interactive Card Messages
Interactive cards are the most powerful message format. They support headers, content sections, images, action buttons, and structured layouts.
2.1 Basic Card Structure
{
"msg_type": "interactive",
"card": {
"header": {
"title": {
"tag": "plain_text",
"content": "Card Title Here"
},
"template": "blue"
},
"elements": []
}
}
Header Color Templates
| 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 |
indigo | Indigo | Technical, engineering |
turquoise | Teal | Growth, marketing |
yellow | Yellow | Highlights, tips |
grey | Grey | Neutral, low priority |
wathet | Light blue | Default, clean |
2.2 Card Elements Reference
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"}
]
}
]
}
2.3 Full Card Example: Product Announcement
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)
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.
3.1 Get Tenant Access Token
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}..."
3.2 List Chats the Bot Belongs To
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 Send Message to a Chat
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)))
")
}"
3.4 Upload an Image
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}"
3.5 Send to a Specific User (by email or 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. Message Templates
4.1 Product Announcement
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
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
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
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
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)
"
6. Bilingual Support (Chinese + English)
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": "."}
]
]
}
}
}
}'
7. Error Handling
Webhook Response Codes
| 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" | Rate limit: max 100 messages per minute per webhook |
| 19024 | "bot not in chat" | Bot has been removed from the group |
Common Troubleshooting
Message not delivered:
- Verify the webhook URL is correct and the bot is still in the group
- Check that
msg_typematches the content structure - 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
http://orhttps:// - 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
im:message:send_as_botpermission is granted
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 |
8. Workflow: Post Marketing Content to Feishu/Lark
When the user asks to send marketing content to Feishu or Lark, follow this workflow:
Step 1: Check Credentials
Verify that FEISHU_WEBHOOK_URL or FEISHU_APP_ID + FEISHU_APP_SECRET are set. If not, guide the user through setup.
Step 2: Determine Message Type
| 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 |
Step 3: Compose the Message
- Use the appropriate template from section 4
- Adapt content to the user's requirements
- For bilingual groups, provide both
zh_cnanden_uscontent
Step 4: Preview and Confirm
Show the user the full JSON payload before sending. Explain what the message will look like.
Never auto-send without explicit user confirmation.
Step 5: Send
Execute the curl command and report the response.
Step 6: Verify
Check the response code. If code: 0, the message was delivered. If there is an error, troubleshoot using the error table above.
9. Advanced: Message Card JSON Schema Quick Reference
{
"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": "..."}]
}
]
}
}
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).
Frequently asked questions
What to verify before installation and use
What does the feishu-lark source document cover?
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.
How do I install feishu-lark?
The source record exposes this install command: npx skills add https://github.com/OpenClaudia/openclaudia-skills --skill "skills/feishu-lark". Inspect the command and pinned source before running it.
Which permission-related actions were detected?
Static rules flagged send-data, network, exec-script in the source; the page lists the matching lines and excerpts.
Alternatives
Compare before choosing
alirezarezvani/claude-skills
app-store-optimization
App Store Optimization (ASO) toolkit for researching keywords, analyzing competitor rankings, generating metadata suggestions, and improving app visibility on Apple App Store and Google Play Store. Use when the user asks about ASO, app store rankings, app metadata, app titles and descriptions, app store listings, app visibility, or mobile app marketing on iOS or Android. Supports keyword research and scoring, competitor keyword analysis, metadata optimization, A/B test planning, launch checklist
indranilbanerjee/contentforge
cf-variants
Generate 3-10 scored A/B test variations of a single content element — headline, hook, CTA, intro, or conclusion — each rated across 6 quality dimensions and ranked by your optimization goal (clicks, engagement, conversions, or readability), with top-3 recommendations and A/B test setup guidance (sample size, duration, success metric). Triggers on "/contentforge:cf-variants", "give me headline alternatives", "A/B test options for this CTA", "which hook is stronger", "write 5 versions of this int
SerendipityOneInc/ZooData-Skills
zoodata
API endpoint reference for the ZooData data platform: the 12 commerce endpoints plus 10 keyword-intelligence endpoints (categories, markets, products, competitors, realtime ASIN, AI review analysis, raw reviews, price band, brand, history, and the keyword detail/trend/extends/search/ market-profile/product-traffic/competitor-keywords/traffic-profile/ traffic-timeline family) — their inputs/outputs, parameter quirks, Quick Start (auth, base URL), how credits are tracked (meta.creditsConsumed), an
MoizIbnYousaf/marketing-cli
higgsfield-generate
Use when the user wants to generate an image or video via Higgsfield AI. Covers 30+ models: Soul V2, Seedance 2.0, Kling 3.0, Veo 3.1, GPT Image 2, Nano Banana 2. Also covers Marketing Studio — branded ad video/image with avatars and products. Use whenever: "generate an image", "make a video", "animate this photo", "image-to-video", "img2vid", "edit this image with AI", "produce a clip", "create an ad", "make a UGC video", "marketing video", "brand video", "TV spot", "import product from URL", "