feishu-cli-msg
npx skills add https://github.com/riba2534/feishu-cli --skill feishu-cli-msg
Agent 安装分布
Skill 文档
é£ä¹¦æ¶æ¯åéæè½
éè¿ feishu-cli åéé£ä¹¦æ¶æ¯ï¼æ¯æå¤ç§æ¶æ¯ç±»åå丰å¯çæ¶æ¯ç®¡çæä½ã
æ ¸å¿æ¦å¿µ
æ¶æ¯æ¶æ
é£ä¹¦æ¶æ¯ API ç content åæ®µæ¯ä¸ä¸ª JSON å符串ï¼ä¸æ¯ JSON 对象ï¼ãCLI æä¾ä¸ç§è¾å
¥æ¹å¼ï¼
| è¾å ¥æ¹å¼ | åæ° | éç¨åºæ¯ |
|---|---|---|
| å¿«æ·ææ¬ | --text "å
容" |
çº¯ææ¬æ¶æ¯ï¼æç®å |
| å è JSON | --content '{"key":"val"}' æ -c |
ç®å JSONï¼ä¸è¡æå® |
| JSON æä»¶ | --content-file file.json |
å¤ææ¶æ¯ï¼å¡çã坿æ¬çï¼ |
ä¼å
级ï¼--text > --content > --content-fileï¼åæ¶æå®æ¶åè
ä¼å
ï¼
æ¥æ¶è ç±»å
| –receive-id-type | 说æ | ç¤ºä¾ |
|---|---|---|
| é®ç®±å°å | user@example.com | |
| open_id | Open ID | ou_xxx |
| user_id | User ID | xxx |
| union_id | Union ID | on_xxx |
| chat_id | 群è ID | oc_xxx |
æ¶æ¯ç±»åéæ©
å³çæ ï¼Claude æªæå®ç±»åæ¶èªå¨éæ©ï¼
é»è®¤ä¼å
ä½¿ç¨ interactiveï¼å¡çæ¶æ¯ï¼ï¼æ ·å¼ç¾è§ãå
容丰å¯ãæ¯æé¢è²/å¤å/æé®çã
ç¨æ·éæ±
ââ ãé»è®¤ãéç¥/æ¥å/åè¦/ä»»ä½æä¿¡æ¯éçæ¶æ¯ â interactiveï¼å¡çï¼
ââ åéå·²ä¸ä¼ çå¾ç/æä»¶/é³è§é¢ â image/file/audio/media
ââ å享群èæç¨æ·åç â share_chat/share_user
ââ ä¼è¯åå²çº¿ï¼ä»
p2pï¼ â system
ââ ä»
以ä¸åºæ¯æç¨ text/postï¼
ââ ç¨æ·æç¡®è¦æ±åçº¯ææ¬ â text
ââ ç¨æ·æç¡®è¦æ±åå¯ææ¬ â post
为ä»ä¹ä¼å å¡çï¼text 䏿¯æä»»ä½æ ¼å¼æ¸²æï¼post æ ·å¼æéï¼å¡çæ¯æå½©è² headerãå¤å fieldsãæé®ãåå²çº¿ã夿³¨çï¼è§è§ææè¿ä¼äºå ¶ä»ç±»åã
æ¶æ¯ç±»åä¸è§
| ç±»å | 说æ | content æ ¼å¼ | 大å°éå¶ |
|---|---|---|---|
| text | çº¯ææ¬ | {"text":"å
容"} |
150 KB |
| post | å¯ææ¬ | {"zh_cn":{"title":"","content":[[...]]}} |
150 KB |
| image | å¾ç | {"image_key":"img_xxx"} |
â |
| file | æä»¶ | {"file_key":"file_v2_xxx"} |
â |
| audio | è¯é³ | {"file_key":"file_v2_xxx"} |
â |
| media | è§é¢ | {"file_key":"...","image_key":"..."} |
â |
| sticker | 表æ å | {"file_key":"file_v2_xxx"} |
ä» è½¬å |
| interactive | å¡ç | Card JSON / template_id / card_id | 30 KB |
| share_chat | 群åç | {"chat_id":"oc_xxx"} |
â |
| share_user | 个人åç | {"user_id":"ou_xxx"} |
â |
| system | ç³»ç»åå²çº¿ | {"type":"divider",...} |
ä» p2p |
åéå½ä»¤
åºç¡æ ¼å¼
feishu-cli msg send \
--receive-id-type <type> \
--receive-id <id> \
[--msg-type <msg_type>] \
[--text "<text>" | --content '<json>' | --content-file <file.json>]
text ç±»å
# æç®å½¢å¼ï¼é»è®¤ msg-type 为 textï¼
feishu-cli msg send \
--receive-id-type email \
--receive-id user@example.com \
--text "ä½ å¥½ï¼è¿æ¯ä¸æ¡æµè¯æ¶æ¯"
text ç±»åæ¯æçå èè¯æ³ï¼
@ç¨æ·ï¼<at user_id="ou_xxx">Tom</at>@ææäººï¼<at user_id="all"></at>
注æï¼text ç±»å䏿¯æå¯ææ¬æ ·å¼ï¼å ç²ãæä½ãä¸å线ãå é¤çº¿ãè¶
龿¥çåä¸ä¼æ¸²æï¼ãå¦éæ ¼å¼æçï¼è¯·ä½¿ç¨ post ç±»åã
post ç±»åï¼å¯ææ¬ï¼
æ¨èä½¿ç¨ md æ ç¾æ¿è½½ Markdownï¼ä¸ä¸ª md æ ç¾ç¬å ä¸ä¸ªæ®µè½ï¼
cat > /tmp/msg.json << 'EOF'
{
"zh_cn": {
"title": "项ç®è¿å±éç¥",
"content": [
[{"tag": "md", "text": "**æ¬å¨è¿å±**\n- 宿åè½ A å¼å\n- ä¿®å¤ 3 个 Bug\n- [æ¥ç详æ
](https://example.com)"}],
[{"tag": "md", "text": "**ä¸å¨è®¡å**\n1. åè½ B å¼å\n2. æ§è½ä¼å"}]
]
}
}
EOF
feishu-cli msg send \
--receive-id-type email \
--receive-id user@example.com \
--msg-type post \
--content-file /tmp/msg.json
post æ¯æç tag ç±»åï¼
| tag | 说æ | 主è¦å±æ§ |
|---|---|---|
| text | ææ¬ | text, styleï¼bold/italic/underline/lineThroughï¼ |
| a | è¶ é¾æ¥ | text, href |
| at | @ç¨æ· | user_id, user_name |
| img | å¾ç | image_key, width, height |
| media | è§é¢ | file_key, image_key |
| emotion | 表æ | emoji_type |
| hr | åå²çº¿ | â |
| code_block | 代ç å | language, text |
| md | Markdown | textï¼ç¬å 段è½ï¼æ¨è使ç¨ï¼ |
interactive ç±»åï¼å¡çæ¶æ¯ï¼
å¡çæ¶æ¯æä¸ç§åéæ¹å¼ï¼
æ¹å¼ä¸ï¼å®æ´ Card JSONï¼æ¨èï¼æçµæ´»ï¼
cat > /tmp/card.json << 'EOF'
{
"header": {
"template": "blue",
"title": {"tag": "plain_text", "content": "ä»»å¡å®æéç¥"}
},
"elements": [
{"tag": "markdown", "content": "**项ç®**: feishu-cli\n**ç¶æ**: 已宿\n**è´è´£äºº**: <at id=all></at>"},
{"tag": "hr"},
{"tag": "note", "elements": [{"tag": "plain_text", "content": "ç± CI/CD èªå¨åé"}]}
]
}
EOF
feishu-cli msg send \
--receive-id-type email \
--receive-id user@example.com \
--msg-type interactive \
--content-file /tmp/card.json
æ¹å¼äºï¼template_id
cat > /tmp/card.json << 'EOF'
{
"type": "template",
"data": {
"template_id": "AAqk1xxxxxx",
"template_variable": {"name": "å¼ ä¸", "status": "已宿"}
}
}
EOF
feishu-cli msg send \
--receive-id-type email \
--receive-id user@example.com \
--msg-type interactive \
--content-file /tmp/card.json
æ¹å¼ä¸ï¼card_id
feishu-cli msg send \
--receive-id-type email \
--receive-id user@example.com \
--msg-type interactive \
--content '{"type":"card","data":{"card_id":"7371713483664506900"}}'
Card JSON ç»æï¼v1 vs v2ï¼
v1 æ ¼å¼ï¼æ¨èï¼å ¼å®¹æ§å¥½ï¼ï¼
{
"header": {"template": "blue", "title": {"tag": "plain_text", "content": "æ é¢"}},
"elements": [...]
}
v2 æ ¼å¼ï¼æ´å¤ç»ä»¶ï¼ï¼
{
"schema": "2.0",
"header": {"template": "blue", "title": {"tag": "plain_text", "content": "æ é¢"}},
"body": {"direction": "vertical", "elements": [...]}
}
v2 é¢å¤æ¯æï¼tableï¼è¡¨æ ¼ï¼ãchartï¼å¾è¡¨ï¼ãform_containerï¼è¡¨åï¼ãcolumn_setï¼å¤åå¸å±ï¼çé«çº§ç»ä»¶ã对äºç®åéç¥ï¼v1 è¶³å¤ï¼éè¦å¤æå¸å±æ¶ç¨ v2ã
header é¢è²æ¨¡æ¿
| é¢è²å¼ | è²ç³» | æ¨èåºæ¯ |
|---|---|---|
| blue | èè² | éç¨éç¥ãä¿¡æ¯ |
| wathet | æµ è | è½»éæç¤º |
| turquoise | éè² | è¿è¡ä¸ç¶æ |
| green | ç»¿è² | æåã宿 |
| yellow | é»è² | 注æãæé |
| orange | æ©è² | è¦å |
| red | çº¢è² | é误ãç´§æ¥ |
| carmine | 深红 | 严éåè¦ |
| violet | ç´«ç½å ° | ç¹æ®æ è®° |
| purple | ç´«è² | èªå®ä¹åç±» |
| indigo | éè | æ·±è²ä¸»é¢ |
| grey | ç°è² | å·²å¤çã彿¡£ |
è¯ä¹åæ¨èï¼ç»¿=æå / è=éç¥ / æ©=è¦å / 红=é误 / ç°=å·²å¤ç
常ç¨ç»ä»¶éæ¥
å 容ç»ä»¶ï¼
| ç»ä»¶ | tag | 说æ |
|---|---|---|
| Markdown | markdown |
æ¯æ lark_md è¯æ³ï¼æå¸¸ç¨ |
| åå²çº¿ | hr |
æ°´å¹³åå²çº¿ |
| 夿³¨ | note |
åºé¨ç°è²å°å夿³¨ |
| å¾ç | img |
å¾çå±ç¤º |
å¸å±ç»ä»¶ï¼
| ç»ä»¶ | tag | 说æ |
|---|---|---|
| ææ¬+éå | div |
ææ¬åï¼å¯å« fieldsï¼å¤åï¼å extraï¼å³ä¾§éå ï¼ |
| å¤åå¸å± | column_setï¼v2ï¼ |
横ååæ å¸å± |
交äºç»ä»¶ï¼
| ç»ä»¶ | tag | 说æ |
|---|---|---|
| æé® | button |
default/primary/danger ä¸ç§ç±»å |
| 䏿鿩 | select_static |
éæä¸æèå |
| æ¥æéæ© | date_picker |
æ¥æéæ©å¨ |
| æå èå | overflow |
æ´å¤æä½èå |
å¡ç Markdown è¯æ³ï¼lark_mdï¼
å¡çå
markdown ç»ä»¶ä½¿ç¨ lark_md è¯æ³ï¼ä¸æ å Markdown æå·®å¼ï¼
# æ¯æçè¯æ³
**å ç²** *æä½* ~~å é¤çº¿~~ [龿¥](url) `è¡å
代ç `

# ç¹æè¯æ³
<font color='green'>ç»¿è²æå</font>
<font color='red'>çº¢è²æå</font>
<font color='grey'>ç°è²æå</font>
<at id=ou_xxx></at>
<at id=all></at>
注æï¼lark_md ç <font color> ä»
æ¯æ green/red/grey ä¸ç§é¢è²ã
常ç¨å¡ç模æ¿
æ¨¡æ¿ 1ï¼ç®åéç¥å¡ç
{
"header": {
"template": "blue",
"title": {"tag": "plain_text", "content": "éç¥æ é¢"}
},
"elements": [
{"tag": "markdown", "content": "éç¥å
å®¹ï¼æ¯æ **å ç²** å [龿¥](https://example.com)"},
{"tag": "note", "elements": [{"tag": "plain_text", "content": "æ¥èªèªå¨åå·¥å
·"}]}
]
}
æ¨¡æ¿ 2ï¼åè¦å¡çï¼å¤å + æé®ï¼
{
"header": {
"template": "red",
"title": {"tag": "plain_text", "content": "åè¦éç¥"}
},
"elements": [
{
"tag": "div",
"fields": [
{"is_short": true, "text": {"tag": "lark_md", "content": "**æå¡**\napi-gateway"}},
{"is_short": true, "text": {"tag": "lark_md", "content": "**级å«**\n<font color='red'>P0</font>"}},
{"is_short": true, "text": {"tag": "lark_md", "content": "**æ¶é´**\n2024-01-01 10:00"}},
{"is_short": true, "text": {"tag": "lark_md", "content": "**å½±å**\n<font color='red'>ç¨æ·æ æ³ç»å½</font>"}}
]
},
{"tag": "hr"},
{
"tag": "action",
"actions": [
{"tag": "button", "text": {"tag": "plain_text", "content": "æ¥ç详æ
"}, "type": "primary", "url": "https://example.com/alert/123"},
{"tag": "button", "text": {"tag": "plain_text", "content": "忽ç¥"}, "type": "default"}
]
}
]
}
æ¨¡æ¿ 3ï¼è¿åº¦æ¥åå¡ç
{
"header": {
"template": "green",
"title": {"tag": "plain_text", "content": "æå»ºæ¥å"}
},
"elements": [
{"tag": "markdown", "content": "**项ç®**: feishu-cli\n**忝**: main\n**æäº¤**: abc1234"},
{"tag": "hr"},
{"tag": "markdown", "content": "<font color='green'>Tests: 42/42 passed</font>\n<font color='green'>Build: Success</font>\n<font color='grey'>Duration: 3m 25s</font>"},
{"tag": "hr"},
{
"tag": "action",
"actions": [
{"tag": "button", "text": {"tag": "plain_text", "content": "æ¥çæ¥å¿"}, "type": "default", "url": "https://ci.example.com/build/123"}
]
},
{"tag": "note", "elements": [{"tag": "plain_text", "content": "CI/CD Pipeline #123"}]}
]
}
æ¨¡æ¿ 4ï¼ææ¡£æä½éç¥
{
"header": {
"template": "turquoise",
"title": {"tag": "plain_text", "content": "ææ¡£æä½éç¥"}
},
"elements": [
{
"tag": "div",
"fields": [
{"is_short": true, "text": {"tag": "lark_md", "content": "**æä½ç±»å**\nåå»ºææ¡£"}},
{"is_short": true, "text": {"tag": "lark_md", "content": "**ç¶æ**\n<font color='green'>æå</font>"}}
]
},
{"tag": "markdown", "content": "**ææ¡£æ é¢**: 卿¥ 2024-W01\n**ææ¡£é¾æ¥**: [ç¹å»æ¥ç](https://xxx.feishu.cn/docx/abc123)"},
{"tag": "note", "elements": [{"tag": "plain_text", "content": "ç± feishu-cli èªå¨å建"}]}
]
}
æ¨¡æ¿ 5ï¼å®¡æ¹ç¡®è®¤å¡çï¼å¤æé®ï¼
{
"header": {
"template": "orange",
"title": {"tag": "plain_text", "content": "审æ¹è¯·æ±"}
},
"elements": [
{"tag": "markdown", "content": "**ç³è¯·äºº**: å¼ ä¸\n**ç³è¯·ç±»å**: æå¡å¨æ©å®¹\n**说æ**: çº¿ä¸æµéå¢é¿ï¼éè¦å¢å 2 å°æå¡å¨"},
{"tag": "hr"},
{
"tag": "action",
"actions": [
{"tag": "button", "text": {"tag": "plain_text", "content": "æ¹å"}, "type": "primary"},
{"tag": "button", "text": {"tag": "plain_text", "content": "æç»"}, "type": "danger"},
{"tag": "button", "text": {"tag": "plain_text", "content": "æ¥ç详æ
"}, "type": "default", "url": "https://example.com/approval/456"}
]
}
]
}
å ¶ä»æ¶æ¯å½ä»¤
è·åæ¶æ¯è¯¦æ
feishu-cli msg get <message_id>
feishu-cli msg get om_xxx --output json
è½¬åæ¶æ¯
feishu-cli msg forward <message_id> \
--receive-id user@example.com \
--receive-id-type email
å 餿¶æ¯
ä» è½å 餿ºå¨äººèªå·±åéçæ¶æ¯ï¼ä¸å¯æ¢å¤ã
feishu-cli msg delete <message_id>
è·åæ¶æ¯å表
feishu-cli msg list \
--container-id oc_xxx \
--container-id-type chat \
--page-size 20 \
--sort-type ByCreateTimeDesc
æ¯æåæ°ï¼--start-timeã--end-timeï¼ç§çº§æ¶é´æ³ï¼ã--page-tokenã
è·åä¼è¯åå²
feishu-cli msg history \
--container-id oc_xxx \
--container-id-type chat \
--sort-type ByCreateTimeAsc \
--page-size 50
æ¥è¯¢æ¶æ¯å·²è¯»ç¨æ·
feishu-cli msg read-users <message_id>
feishu-cli msg read-users om_xxx --user-id-type user_id --page-size 50
æç´¢ç¾¤è
feishu-cli msg search-chats --query "项ç®ç¾¤"
feishu-cli msg search-chats --page-size 20
æç´¢æ¶æ¯ï¼é User Access Tokenï¼
feishu-cli search messages "å
³é®è¯" \
--user-access-token u-xxx \
--chat-ids oc_xxx \
--message-type file \
--start-time 1704067200
æ§è¡æµç¨
Claude åéæ¶æ¯æ¶æä»¥ä¸æµç¨æä½ï¼
- ç¡®å®æ¥æ¶è
ï¼é»è®¤
user@example.comï¼emailï¼ï¼æä»ä¸ä¸æè·å - éæ©æ¶æ¯ç±»åï¼
- ç¨æ·æç¡®æå®ç±»å â ä½¿ç¨æå®ç±»å
- é»è®¤ä½¿ç¨
interactiveï¼å¡çæ¶æ¯ï¼ â æ ¹æ®å 容è¯ä¹éæ© header é¢è²ååéçç»ä»¶å¸å± - ä»
å¨ç¨æ·æç¡®è¦æ±çº¯ææ¬/å¯ææ¬æ¶ â 使ç¨
text/post
- æé å¡çå
容ï¼
- æ ¹æ®æ¶æ¯è¯ä¹éæ© header é¢è²ï¼ç»¿=æåã红=éè¯¯ãæ©=è¦åãè=éç¥ãç°=彿¡£ï¼
- 使ç¨
markdownç»ä»¶æ¿è½½ä¸»è¦å 容 - æå¤ä¸ªé®å¼å¯¹æ¶ä½¿ç¨
div+fieldså¤åå¸å± - éè¦æä½é¾æ¥æ¶æ·»å
action+button - åºé¨æ·»å
note夿³¨æ¥æº - å° JSON åå
¥ä¸´æ¶æä»¶åç¨
--content-fileåé
- åéå¹¶æ£æ¥ç»æï¼æ§è¡å½ä»¤ï¼ç¡®è®¤è¿å message_id
æéè¦æ±
| æé | 说æ |
|---|---|
im:message |
æ¶æ¯è¯»å |
im:message:send_as_bot |
以æºå¨äººèº«ä»½åéæ¶æ¯ |
im:chat:readonly |
æç´¢ç¾¤è |
im:message:readonly |
è·åå岿¶æ¯ |
注æäºé¡¹
| éå¶ | 说æ |
|---|---|
| text 大å°éå¶ | åæ¡æå¤§ 150 KB |
| å¡ç/坿æ¬å¤§å°éå¶ | åæ¡æå¤§ 30 KB |
| system æ¶æ¯ | ä» p2p ä¼è¯ææï¼ç¾¤èæ æ |
| sticker æ¶æ¯ | ä» æ¯æè½¬åæ¶å°ç表æ å ï¼ä¸æ¯æèªè¡ä¸ä¼ |
| å¡çæé®åè° | æé®ç交äºåè°éåºç¨æå¡ç«¯æ¯æï¼CLI åéçæé®ä» url è·³è½¬ææ |
| API é¢çéå¶ | 请æ±è¿å¿«è¿å 429ï¼çå¾ å ç§åéè¯ |
| å 餿¶æ¯ | ä» è½å 餿ºå¨äººåéçæ¶æ¯ |
é误å¤ç
| é误 | åå | è§£å³ |
|---|---|---|
content format of a post type is incorrect |
post ç±»å JSON æ ¼å¼é误 | ç¡®ä¿æ ¼å¼ä¸º {"zh_cn":{"title":"","content":[[...]]}} |
invalid receive_id |
æ¥æ¶è ID æ æ | æ£æ¥ –receive-id-type å –receive-id æ¯å¦å¹é |
bot has no permission |
æºå¨äººæ æé | 确认åºç¨æ im:message:send_as_bot æé |
rate limit exceeded |
API éæµ | çå¾ å ç§åéè¯ |
user not found |
ç¨æ·ä¸åå¨ | æ£æ¥é®ç®±æ ID æ¯å¦æ£ç¡® |
card content too large |
å¡ç JSON è¶ è¿ 30 KB | ç²¾ç®å¡çå 容ææåä¸ºå¤æ¡æ¶æ¯ |
åèææ¡£
references/message_content.mdï¼åæ¶æ¯ç±»åç content JSON ç»æè¯¦è§£references/card_schema.mdï¼å¡çæ¶æ¯å®æ´æé æåï¼ç»ä»¶ãå¸å±ã模æ¿ï¼