feishu-card(schema 2.0)
關鍵規則
- 所有卡片使用 schema 2.0,元素放在
body.elements[],不是頂層elements[] - 發送卡片必須
--as bot,--msg-type interactive,--content傳 JSON 字串 - 卡片內 @人 用
<at id="ou_xxx">姓名</at>(不是<at user_id>) - JSON 2.0 按鈕不再有
action容器,button 直接放進body.elements,互動用behaviors陣列 - 先發「思考中」卡片拿到
message_id,Claude 回答後 PATCH 原地更新,避免洗版 notetag 在 schema 2.0 中已不支援(報錯 200861),備註改用div + lark_md(<font color=grey>備註文字</font>)- 構建卡片 JSON 必須用 Python heredoc 或寫檔案,禁止用
$(python3 -c "...")——內容含反引號或特殊字元時 bash 會報語法錯誤
頂層結構完整欄位
{
"schema": "2.0",
"config": {
"streaming_mode": false,
"enable_forward": true,
"update_multi": true,
"width_mode": "default"
},
"card_link": {
"url": "https://...",
"pc_url": "https://...",
"ios_url": "https://...",
"android_url": "https://..."
},
"header": { "...": "..." },
"body": {
"direction": "vertical",
"padding": "0px",
"elements": []
}
}
config 欄位
| 欄位 | 類型 | 預設 | 說明 |
|---|---|---|---|
streaming_mode | bool | false | 流式更新態(思考中佔位用) |
enable_forward | bool | true | 允許轉發卡片 |
update_multi | bool | false | JSON 2.0 共享卡片模式(多人同步更新需設 true) |
width_mode | string | default(600px) | compact(400px)/ fill(全寬響應)/ default |
Header 欄位
{
"header": {
"title": {"tag": "plain_text", "content": "標題"},
"subtitle": {"tag": "plain_text", "content": "副標題(可選)"},
"template": "blue",
"icon": {
"tag": "standard_icon",
"token": "robot-outlined",
"color": "blue"
},
"text_tag_list": [
{"tag": "text_tag", "text": {"tag": "plain_text", "content": "New"}, "color": "blue"}
]
}
}
template 顏色:blue / wathet / turquoise / green / yellow / orange / red / carmine / violet / purple / indigo / grey
飛書顏色列舉速查
所有支援顏色列舉的欄位(background_color、text_color、icon color 等)均使用以下格式,不能只寫基礎色名(如 "blue" 單獨使用在某些元件會報錯),需帶層級後綴:
| 色系 | 淺色(背景推薦) | 中色 | 深色(文字推薦) |
|---|---|---|---|
| 藍 blue | blue-50 blue-100 blue-200 | blue-300~blue-500 | blue-600~blue-900 |
| 水藍 wathet | wathet-50 wathet-100 wathet-200 | wathet-300~wathet-500 | wathet-600~wathet-900 |
| 青 turquoise | turquoise-50 turquoise-100 | turquoise-300~turquoise-500 | turquoise-600~turquoise-900 |
| 綠 green | green-50 green-100 green-200 | green-300~green-500 | green-600~green-900 |
| 黃綠 lime | lime-50 lime-100 | lime-300~lime-500 | lime-600~lime-900 |
| 黃 yellow | yellow-50 yellow-100 | yellow-300~yellow-500 | yellow-600~yellow-900 |
| 橙 orange | orange-50 orange-100 | orange-300~orange-500 | orange-600~orange-900 |
| 紅 red | red-50 red-100 | red-300~red-500 | red-600~red-900 |
| 粉紅 carmine | carmine-50 carmine-100 | carmine-300~carmine-500 | carmine-600~carmine-900 |
| 紫 purple | purple-50 purple-100 | purple-300~purple-500 | purple-600~purple-900 |
| 藍紫 violet | violet-50 violet-100 | violet-300~violet-500 | violet-600~violet-900 |
| 靛 indigo | indigo-50 indigo-100 | indigo-300~indigo-500 | indigo-600~indigo-900 |
| 灰 grey | grey-00 grey-50 grey-100 | grey-300~grey-500 | grey-600~grey-1000 |
| 白 | white bg-white | — | — |
常用淺色背景推薦(collapsible_panel、column 背景等):
blue-100 wathet-100 green-100 yellow-100
orange-100 red-100 purple-100 carmine-100
turquoise-100 violet-100 indigo-100 lime-100
元件速查表
| tag | 類型 | 說明 |
|---|---|---|
div | 內容 | 文字區塊(plain_text / lark_md),支援前綴 icon |
markdown | 內容 | 純 Markdown 文字(不支援 @,@用 div+lark_md) |
img | 內容 | 圖片 |
table | 內容 | 資料表格(最多 5 個/卡片,不可巢狀) |
hr | 佈局 | 分隔線 |
note | 佈局 | ❌ schema 2.0 已廢棄,改用 div + lark_md + <font color=grey> |
column_set | 容器 | 多欄佈局 |
collapsible_panel | 容器 | 折疊面板 |
button | 互動 | 按鈕(JSON 2.0 直接放 elements,不用 action 容器) |
input | 互動 | 文字輸入框(須在 form 內使用) |
select_static | 互動 | 靜態下拉選擇器 |
div(文字區塊)
{
"tag": "div",
"text": {
"tag": "lark_md",
"content": "**加粗** _斜體_ `程式碼`",
"text_size": "normal",
"text_color": "default",
"text_align": "left",
"lines": 3
},
"icon": {"tag": "standard_icon", "token": "robot-outlined", "color": "blue"}
}
text.tag:plain_text(純文字)或 lark_md(Markdown + @)
text_size:heading-0 / heading / normal(預設)/ notation / x-small
text_align:left / center / right
img(圖片)
{
"tag": "img",
"img_key": "img_xxx",
"alt": {"tag": "plain_text", "content": "懸停說明"},
"title": {"tag": "plain_text", "content": "圖片標題"},
"scale_type": "crop_center",
"size": "medium",
"corner_radius": "4px",
"preview": true
}
scale_type:crop_center / crop_top / fit_horizontal
size:stretch(全寬)/ large / medium / small / tiny / "300px 200px"(自訂)
JSON 2.0 不支援
stretch_without_padding,全寬效果改用負 margin
column_set(多欄佈局)
{
"tag": "column_set",
"flex_mode": "bisect",
"horizontal_spacing": "medium",
"background_style": "default",
"columns": [
{
"tag": "column",
"width": "weighted",
"weight": 1,
"vertical_align": "top",
"elements": [{"tag": "div", "text": {"tag": "plain_text", "content": "左欄"}}]
},
{
"tag": "column",
"width": "weighted",
"weight": 1,
"elements": [{"tag": "div", "text": {"tag": "plain_text", "content": "右欄"}}]
}
]
}
flex_mode:none(按比例壓縮)/ stretch(窄螢幕縱排)/ flow(自動換行)/ bisect(等寬兩欄)/ trisect(等寬三欄)
horizontal_spacing:small(4px) / medium(8px) / large(12px) / extra_large(16px)
column.width:auto / weighted(配合 weight 1-5)/ "200px"
最大巢狀 5 層,欄內不可放 form 容器和 table
collapsible_panel(折疊面板)
{
"tag": "collapsible_panel",
"expanded": false,
"background_color": "default",
"header": {
"title": {"tag": "plain_text", "content": "點擊展開"},
"background_color": "grey",
"icon": {"tag": "standard_icon", "token": "arrow-down-outlined"},
"icon_expanded_angle": -180
},
"elements": [
{"tag": "div", "text": {"tag": "plain_text", "content": "折疊內容"}}
]
}
table(資料表格)
{
"tag": "table",
"page_size": 5,
"row_height": "low",
"freeze_first_column": false,
"header_style": {
"text_align": "left",
"text_size": "normal",
"background_style": "grey",
"bold": true
},
"columns": [
{"name": "name", "display_name": "姓名", "data_type": "text", "width": "auto"},
{"name": "status", "display_name": "狀態", "data_type": "options", "width": "120px"},
{"name": "count", "display_name": "數量", "data_type": "number",
"format": {"precision": 0, "separator": true}},
{"name": "ts", "display_name": "時間", "data_type": "date",
"format": "YYYY/MM/DD HH:mm"}
],
"rows": [
{"name": "張三", "status": [{"name": "進行中", "color": "blue"}], "count": 42, "ts": 1700000000000}
]
}
data_type:text / lark_md / markdown / options / number / persons / date
row_height:low / middle / high / auto / "48px"(32-124px)
每張卡片最多 5 個 table,不可巢狀
button(JSON 2.0)
{
"tag": "button",
"text": {"tag": "plain_text", "content": "確認"},
"type": "primary",
"size": "medium",
"width": "default",
"disabled": false,
"behaviors": [
{
"type": "callback",
"value": {"action": "confirm", "data": "payload"}
}
],
"confirm": {
"title": {"tag": "plain_text", "content": "二次確認"},
"text": {"tag": "plain_text", "content": "確認執行此操作?"}
}
}
type:default(灰)/ primary(藍)/ danger(紅)/ text / primary_text / danger_text / primary_filled / danger_filled / laser
size:tiny / small / medium / large
behaviors[].type:callback(觸發事件)/ open_url(跳轉連結)
JSON 2.0 變化:不再有
action容器,button 直接放body.elements或column.elements;互動用behaviors替代舊的value
input(文字輸入)
{
"tag": "input",
"name": "field_name",
"placeholder": {"tag": "plain_text", "content": "請輸入..."},
"default_value": "",
"input_type": "text",
"max_length": 200,
"required": false,
"disabled": false,
"label": {"tag": "plain_text", "content": "標籤"},
"label_position": "top",
"width": "fill"
}
input_type:text / multiline_text / password
使用者提交觸發 card.action.trigger 事件,事件含 input_value
@提及語法
| 訊息類型 | @人語法 | @全體 |
|---|---|---|
卡片 interactive lark_md | <at id="ou_xxx">姓名</at> | <at id="all">所有人</at> |
文字 text / post | <at user_id="ou_xxx">姓名</at> | <at user_id="all"></at> |
卡片內 @mention 經驗證可用的元素結構(div + lark_md,不要用裸 markdown tag):
{
"tag": "div",
"text": {
"tag": "lark_md",
"content": "<at id=\"ou_xxx\">姓名</at> 訊息內容"
}
}
Markdown 語法速查(lark_md / markdown tag 內)
文字樣式
**加粗** *斜體* ~~刪除線~~ `行內程式碼`
顏色文字
<font color=red>紅色</font>
<font color=green>綠色</font>
<font color=grey>灰色</font>
<font color=blue>藍色</font>
<font color=orange>橙色</font>
<font color=wathet>水藍</font>
<font color=purple>紫色</font>
完整顏色:red / green / grey / blue / orange / wathet / purple / yellow / turquoise / indigo / violet / lime
標籤 / 數字徽章
<text_tag color='red'>標籤</text_tag>
<number_tag>99</number_tag>
本地化時間
<local_datetime millisecond='1700000000000' format_type='date_num'></local_datetime>
format_type:date_num(2023/11/15)/ date_full(2023年11月15日)/ datetime(含時分秒)
標題 / 列表 / 引用
# H1 ## H2 ### H3 #### H4 ##### H5 ###### H6
- 無序 1. 有序 > 引用
程式碼區塊
```python
print("hello")
```
圖片(Markdown 內)

表格(最多 5 行資料)
| 欄1 | 欄2 |
|-----|-----|
| A | B |
連結
[文字](https://url) [電話](tel://13800138000)
分隔線 / 換行
--- 或 <hr>
<br/> 或 兩次回車(段落換行)
Emoji
⚠️ 嚴格規則
- 只能使用官方列表中的 key,未收錄的 key(如
:WAITING:、:PROCESSING:)會渲染成純文字,禁止使用。 - key 大小寫必須與官方完全一致(如
Fire不是FIRE,Trophy不是TROPHY,Shrug不是SHRUG)。 <text_tag>內部不渲染:KEY:,須改用 Unicode emoji(如✅)。:KEY:僅在lark_md一般文字區域生效。
發版通知常用
:DONE: :OK: :THUMBSUP: :APPLAUSE:
:PARTY: :FIREWORKS: :MUSCLE: :THANKS:
:Trophy: :Fire: :Hundred: :CheckMark:
工作 & 狀態
:LGTM: :OnIt: :OneSecond: :Get:
:ERROR: :CrossMark: :Pin: :Alarm:
:Loudspeaker: :OKR: :Yes: :No:
:HEADSET: :Typing: :MeMeMe: :Sigh:
:Lemon: :AWESOMEN: :VRHeadset: :YouAreTheBest:
:SALUTE: :HIGHFIVE: :FISTBUMP: :FINGERHEART:
:WAVE: :ThumbsDown:
表情 - 正面
:SMILE: :LAUGH: :LOL: :LOVE:
:WINK: :PROUD: :WITTY: :JOYFUL:
:WOW: :BLUSH: :HUG: :BeamingFace:
:Delighted: :ThanksFace: :SaluteFace: :PRAISE:
:CLAP: :JIAYI: :FACEPALM: :YEAH:
表情 - 負面 / 搞怪
:CRY: :SOB: :ANGRY: :SHOCKED:
:Shrug: :THINKING: :DIZZY: :SLEEP:
:YAWN: :SICK: :SWEAT: :EMBARRASSED:
:SKULL: :RAINBOWPUKE: :PUKE: :ClownFace:
:ColdSweat: :SMUG: :SILENT: :TERROR:
:PETRIFIED: :BETRAYED: :WRONGED:
慶祝 & 節日
:PARTY: :FIREWORKS: :REDPACKET: :FORTUNE:
:FIRECRACKER: :XmasTree: :XmasHat: :Snowman:
:Pumpkin: :Mooncake: :MoonRabbit: :Partying:
:StickyRiceBalls: :JubilantRabbit: :LUCK:
:FullMoonFace: :GoGoGo: :HappyDragon:
物品 & 食物
:ROSE: :HEART: :BEER: :CAKE:
:GIFT: :BOMB: :Fire: :Trophy:
:Coffee: :BubbleTea: :Drumstick: :Pepper:
:CUCUMBER: :CANDIEDHAWS: :Soccer: :Basketball:
:Music: :CLEAVER: :EatingFood: :LIPS:
狀態指示(勿頻繁使用,僅狀態場景)
:GeneralDoNotDisturb: :GeneralInMeetingBusy:
:StatusReading: :GeneralWorkFromHome:
:GeneralBusinessTrip: :StatusInFlight:
:GeneralSun: :GeneralMoonRest:
:StatusFlashOfInspiration: :Status_PrivateMessage:
:GeneralTravellingCar: :StatusBus:
Unicode Emoji(標題、text_tag 內、header subtitle 中使用)
🎉 ✅ ❌ ⚠️ 🚀 📦 💬 ⏳ 🔔 📝 🛠️ 🔍 👋 🎯 💡 🌟
👥 📅 🤖 🏆 🔥 💯 📣 🎁 ☕ 🍺
推薦風格:標題用 Unicode emoji 增強視覺,狀態/回饋用飛書
:DONE::LGTM:等專屬語法
發送 / 回覆 / 更新
發送到群組(新訊息)
CARD=$(python3 -c "
import json
card = {
'schema': '2.0',
'header': {'title': {'tag': 'plain_text', 'content': '標題'}, 'template': 'blue'},
'body': {'elements': [{'tag': 'markdown', 'content': '內容'}]}
}
print(json.dumps(card))
")
lark-cli im +messages-send \
--chat-id oc_xxx \
--msg-type interactive \
--content "$CARD" \
--as bot
回覆指定訊息(取得 message_id 供後續更新)
MSG_ID=$(lark-cli im +messages-reply \
--message-id om_xxx \
--msg-type interactive \
--content "$CARD" \
--as bot \
--jq '.data.message_id')
回覆到 thread(不出現在主聊天流程)
lark-cli im +messages-reply \
--message-id om_xxx \
--msg-type interactive \
--content "$CARD" \
--reply-in-thread \
--as bot
防重複發送(1小時內相同 key 只發一次)
lark-cli im +messages-send \
--chat-id oc_xxx \
--msg-type interactive \
--content "$CARD" \
--idempotency-key "deploy-654.0-notify" \
--as bot
原地更新卡片(PATCH)
PAYLOAD=$(jq -n --argjson card "$CARD" '{"msg_type":"interactive","content":($card|tojson)}')
lark-cli api PATCH "/open-apis/im/v1/messages/${MSG_ID}" \
--data "$PAYLOAD" \
--as bot
卡片範本
思考中(流式態,先發佔位)
make_thinking_card() {
local name="$1" question="$2"
jq -n --arg name "$name" --arg q "$question"
…
[truncated for translation]