skillZs
LIVE SKILL TAGS
>>> LIVE SKILLS INDEX <<<
* OPEN SOURCE *
NO LOGIN, NO TRACKING
REAL INSTALL DATA
← back to all skills
riba2534/feishu-cli877 installs

feishu-cli-msg

飞书消息发送。发送消息(text/post/interactive 卡片等 10 种类型:text/post/image/file/audio/media/sticker/interactive/share_chat/share_user;system 分割线 CLI 暂未直接支持,需用 `feishu-cli api` 透传)、回复消息、 转发/合并转发、消息加急、消息书签(flag 收藏/list/cancel)、下载消息资源(图片/文件)。 发送/回复/转发/加急默认 App Token(Bot 身份);msg flag 收藏/书签必需 User Token(`im:feed.flag:read/write`); msg resource-download 已登录时优先 User Token,未登录回落 App Token。 当用户明确请求通过飞书即时消息/Bot 消息发送、回复、转发、合并转发、加急、消息收藏/书签、 下载消息图片或文件时使用。邮件走 feishu-cli-mail;文档评论/共享权限走对应 skill。 注意:Reaction/Pin/获取消息详情/批量获取消息/话题回复/消息历史/搜索群聊/群聊管理, 以及消息删除(默认 App Token 用于 Bot 自撤回,可选 User Token 让管理员撤回他人) 请使用 feishu-cli-chat 技能。 发送 interactive 卡片时,先用 feishu-cli-card 构造 v2 JSON, 再回到本技能用 --msg-type interactive --content-file 发送。

How do I install this agent skill?

npx skills add https://github.com/riba2534/feishu-cli --skill feishu-cli-msg
view source ↗

Is this agent skill safe to install?

  • Gen Agent Trust Hubpass

    This skill allows an AI agent to send and manage messages on Feishu using the feishu-cli tool. It supports a wide range of message types, including rich cards and file attachments. The skill is well-structured and focuses on its intended purpose. A minor security consideration is the risk of indirect prompt injection, as the skill processes external message content which could potentially contain instructions for the agent.

  • Socketpass

    No alerts

  • Snykwarn

    Risk: MEDIUM · 1 issue

  • Runlayerpass

    3 files scanned · No issues

  • ZeroLeakspass

    Score: 93/100 · 2 sections analyzed

What does this agent skill do?

飞书消息发送技能

通过 feishu-cli 发送飞书消息、回复、转发、合并转发、加急和下载消息资源。

feishu-cli:如尚未安装,请前往 riba2534/feishu-cli 获取安装方式。

与 feishu-cli-chat 技能的职责边界

重要:CLI 路径 ≠ SKILL 归属。 feishu-cli msg 下的子命令同时被两个 SKILL 分管,按动作类型划分,不按 CLI 路径划分。

动作类型子命令归属 SKILL
发送类(本 SKILL 覆盖)send / reply / forward / merge-forward / urgent / flag / resource-downloadfeishu-cli-msg
读取类(请用 chat SKILL)history / list / get / mget / thread-messages / search-chats / read-users / pinsfeishu-cli-chat
互动类(请用 chat SKILL)reaction / pin / unpin / deletefeishu-cli-chat

端到端拉一段时间窗的群消息(含话题展开、名字反解、卡片解析)直接跑:

python3 skills/feishu-cli-chat/scripts/fetch_chat_history.py oc_xxx --since 24h

核心概念

消息架构

飞书消息 API 的 content 字段是一个 JSON 字符串(不是 JSON 对象)。CLI 提供三种输入方式:

输入方式参数适用场景
快捷文本--text "内容"纯文本消息,最简单
发送文件--file <路径>-f本地文件自动上传并发送(限 30MB)
发送图片--image <路径>本地图片自动上传并发送(限 10MB)
内联 JSON--content '{"key":"val"}'-c简单 JSON,一行搞定
JSON 文件--content-file file.json复杂消息(卡片、富文本等)

互斥:以上 5 种输入方式只能指定一个,同时指定会报错。

接收者类型

--receive-id-type说明示例
email邮箱地址user@example.com
open_idOpen IDou_xxx
user_idUser IDxxx
union_idUnion IDon_xxx
chat_id群聊 IDoc_xxx

消息类型选择

决策树(Claude 未指定类型时自动选择)

默认优先使用 interactive(卡片消息),样式美观、内容丰富、支持颜色/多列/按钮等。

用户需求
├─ 【默认】通知/报告/告警/任何有信息量的消息 → interactive(卡片)
├─ 发送已上传的图片/文件/音视频 → image/file/audio/media
├─ 分享群聊或用户名片 → share_chat/share_user
└─ 仅以下场景才用 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_id30 KB
share_chat群名片{"chat_id":"oc_xxx"}
share_user个人名片{"user_id":"ou_xxx"}

system 系统分割线(仅 p2p)CLI --msg-type 白名单暂未收录(见 cmd/send_message.go:261-266),需要时用 feishu-cli api POST /open-apis/im/v1/messages 直接透传。

身份说明

本技能以发送类命令为主,默认使用 App Token(Bot 身份),无需登录。

  • 必需 User Tokenmsg flag 收藏/书签子命令(im:feed.flag:read/write),见末尾"消息书签"章节。
  • 优先 User Token + Tenant 兜底msg resource-download 已登录时自动用 User Token 下载(要求你能看到该消息),未登录则尝试 App Token(要求 Bot 能看到该消息)。

其他子命令(reaction/pin/delete/history/list/get/mget/thread-messages/search-chats)的 Token 策略见 feishu-cli-chat 技能。

发送命令

基础格式

feishu-cli msg send \
  --receive-id-type <type> \
  --receive-id <id> \
  [--msg-type <msg_type>] \
  [--text "<text>" | --file <path> | --image <path> | --content '<json>' | --content-file <file.json>]

file 类型(直发文件)

# 直接发送本地文件(自动上传,限 30MB)
feishu-cli msg send \
  --receive-id-type email \
  --receive-id user@example.com \
  --file /path/to/report.pdf

自动推断文件 MIME 类型(opus/mp4/pdf/doc/xls/ppt),未知类型使用 stream。超过 30MB 的文件请先用 file upload 上传到云空间,再用 --msg-type file --content '{"file_key":"..."}' 发送。

image 类型(直发图片)

# 直接发送本地图片(自动上传,限 10MB)
feishu-cli msg send \
  --receive-id-type chat_id \
  --receive-id oc_xxx \
  --image /path/to/screenshot.png

支持 JPEG、PNG、BMP、GIF、TIFF、WebP 格式。

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> —— ou_xxx 必须是真实 open_id
  • @ 所有人:<at user_id="all"></at>
  • @ 机器人:与 @ 用户语法相同,把 ou_xxx 换成机器人 open_id 即可

只能用 open_id<at email="..."> 在 text 消息里不会触发 @ entity(飞书 IM 客户端会把邮箱字符串自动渲染成超链接,看起来像 @ 但没有通知、不是真的提及)。需要 @ 邮箱用户,先查 open_id:

# 第一步:查 open_id
feishu-cli user search --email alice@example.com -o json
# 第二步:用真实 open_id @ 人
feishu-cli msg send --receive-id-type chat_id --receive-id oc_xxx \
  --text '<at user_id="ou_xxx">Alice</at> 你好'

容错(仅 --text 模式)msg send / msg reply--text 模式下会自动修正 AI 易写错的 @ 标签格式,下列写法都会被规范化为标准 <at user_id="...">

  • <at id=ou_xxx>(缺引号 / 用 id 而非 user_id
  • <at open_id="ou_xxx"/>(自闭合 / 用 open_id
  • <at user_id=ou_xxx/>(自闭合无引号)

--content / --content-file 模式不做隐式 normalize(用户自己写的 JSON 自己负责,避免破坏结构)。

注意: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
mdMarkdowntext(独占段落,推荐使用)

图片自动上传(--upload-images)

msg send 支持 --upload-images,扫描 post / interactive 消息中的 Markdown 图片语法 ![alt](path),把 path 指向的本地图片自动上传到飞书 IM 图床、替换为 image_key,再发送。

维度行为
触发条件仅当 --msg-type post--msg-type interactive 时生效(其他类型即使传也忽略,见 cmd/send_message.go:212
适用语法内容里的 ![alt](path) 标记;URL(http/https)和已有 image_key 不会被改写
路径解析相对路径:以 --content-file 所在目录为 basePath;用 --content 内联 JSON 时以当前工作目录为 basePath(见 cmd/send_message.go:213-220
失败回落上传失败直接报错退出,不会继续发送残缺消息(避免 image_key 缺失被服务端拒绝)
进度提示上传 > 0 张时 stderr 打印 已自动上传 N 张本地图片
# post 内嵌本地图:自动上传相对路径 ./diagrams/foo.png
feishu-cli msg send --receive-id-type email --receive-id user@example.com \
  --msg-type post --content-file /path/to/post.json --upload-images

# interactive 卡片内嵌本地图同理
feishu-cli msg send --receive-id-type chat_id --receive-id oc_xxx \
  --msg-type interactive --content-file /tmp/card.json --upload-images

不需要预先调 feishu-cli media upload:本标志已包装了"上传 + 替换 + 发送"的全流程。需要把图片当作独立 image 消息发送,请直接用 --image <path> 快捷方式。

interactive 类型(卡片消息)

卡片消息有三种发送方式:

方式一:完整 Card JSON(仅发送;复杂卡片先用 feishu-cli-card 生成)

cat > /tmp/card.json << 'EOF'
{
  "schema": "2.0",
  "header": {
    "template": "blue",
    "title": {"tag": "plain_text", "content": "任务完成通知"}
  },
  "body": {
    "direction": "vertical",
    "elements": [
      {"tag": "markdown", "content": "**项目**: feishu-cli\n**状态**: 已完成\n**负责人**: <at id=all></at>"}
    ]
  }
}
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"}}'

Interactive 卡片职责边界

本技能只负责发送 interactive 消息,不负责设计卡片 JSON。

  • 结构化或美观卡片必须先使用 feishu-cli-card 生成 v2 JSON(schema=2.0)。
  • 本技能发送:feishu-cli msg send --msg-type interactive --content-file <card.json>。
  • 不要在本技能内新写 v1 elements/action/note 卡片模板;旧 v1 示例仅用于历史兼容排查。

执行流程

发送消息流程

  1. 确定接收者:默认 user@example.com(email),或从上下文获取
  2. 选择消息类型
    • 用户明确指定类型 → 使用指定类型
    • 结构化或美观通知 → 先用 feishu-cli-card 构造 JSON,再用 interactive 发送
    • 用户明确要求纯文本/富文本,或内容很短 → 使用 text / post
  3. 准备内容:纯文本直接传 --text;卡片 JSON 使用 --content-file;文件/图片使用 --file / --image
  4. 发送并检查结果:执行命令,确认返回 message_id

权限要求

权限说明
im:message消息读写(发送/回复/转发)
im:message:send_as_bot以机器人身份发送消息

注意事项

限制说明
text 大小限制单条最大 150 KB
卡片/富文本大小限制单条最大 30 KB
system 消息CLI --msg-type 暂不支持,仅 p2p 会话有效;需用 feishu-cli api 透传
sticker 消息仅支持转发收到的表情包,不支持自行上传
卡片按钮回调按钮的交互回调需应用服务端支持,CLI 发送的按钮仅 url 跳转有效
API 频率限制请求过快返回 429,等待几秒后重试
删除消息仅能删除机器人发送的消息

错误处理

错误原因解决
content format of a post type is incorrectpost 类型 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 exceededAPI 限流等待几秒后重试
user not found用户不存在检查邮箱或 ID 是否正确
card content too large卡片 JSON 超过 30 KB精简卡片内容或拆分为多条消息
Bot/User can NOT be out of the chatBot 不在目标群内添加 --user-access-token 切换为 User 身份重试

批量获取消息

读消息详情和批量获取消息请使用 feishu-cli-chat 技能。msg get/list/history/mget 默认请求 user_card_content 并额外提取 card_texts,该行为和排错说明维护在 chat skill 中,避免发送与读取职责混在一起。

下载消息资源

下载消息中的图片或文件附件。

# 下载消息中的图片
feishu-cli msg resource-download <message_id> <file_key> --type image -o /tmp/photo.png

# 下载消息中的文件
feishu-cli msg resource-download <message_id> <file_key> --type file -o /tmp/attachment.pdf

# Bot 不可见但当前用户可见的历史消息资源,可显式用 User Token
feishu-cli msg resource-download <message_id> <file_key> --type file --user-access-token u-xxx -o /tmp/attachment.pdf

# 下载大文件时指定超时时间
feishu-cli msg resource-download <message_id> <file_key> --type file --user-access-token u-xxx -o /tmp/large.bin --timeout 30m
参数说明默认值
<message_id>消息 ID必填
<file_key>资源的 file_key必填
--type资源类型 image/file必填
-o, --output输出文件路径
--user-access-token使用用户身份下载用户可见、但 Bot 不可见的历史消息资源
--timeout下载超时时间(Go duration 格式,如 10m30m1h5m

file_key 来源:通过 msg get <message_id> 获取消息详情,从 content 中提取 image_keyfile_key。 使用用户身份直连下载时,如遇到飞书大文件限制,会自动使用 HTTP Range 分片下载并合并。

话题(Thread)消息

发送到已有话题

msg send 支持 --thread-id(等价于 --receive-id-type thread_id --receive-id <thread_id>):

# 在已有话题内追加一条消息
feishu-cli msg send --thread-id omt_xxx --text "话题内继续聊"

# 卡片消息也支持
feishu-cli msg send --thread-id omt_xxx \
  --msg-type interactive \
  --content "$(cat card.json)"

--thread-id--receive-id-type/--receive-id 互斥,只能指定一组。

回复时开启话题

msg reply 支持 --reply-in-threadreply_in_thread=true):

# 在非话题群聊中,以话题形式回复某条消息(会开启一个新话题)
feishu-cli msg reply om_xxx --text "这里开个话题" --reply-in-thread

# 若群聊已是话题模式,--reply-in-thread 会自动回复到消息所在话题

话题回复列表

获取话题回复属于读取消息,请使用 feishu-cli-chat 技能。发送话题内消息仍使用本技能的 msg send --thread-id

参考文档

  • references/message_content.md:各消息类型的 content JSON 结构详解
  • references/card_schema.md:interactive 发送格式与历史卡片排障;新增卡片构造优先用 feishu-cli-card

消息书签(msg flag,v1.23+ 新增)

服务端称 message flag,用于把消息加 Feed 标记,把消息推上用户 Feed/书签。 对应 HTTP API POST/GET/PATCH /open-apis/im/v1/flags。需 User Access Token:list 需要 im:feed.flag:readcreate/cancel 需要 im:feed.flag:write

命令速查

  • feishu-cli msg flag create <message_id> — 创建消息层书签(默认 --item-type default --flag-type message
  • feishu-cli msg flag create <message_id> --flag-type feed — feed 层书签,自动读取 chat_mode 判断 thread / msg_thread
  • feishu-cli msg flag create <message_id> --item-type msg_thread --flag-type feed — feed 层书签(显式指定普通群线程)
  • feishu-cli msg flag list [--page-size 50] [--page-token xxx] — 列当前用户的书签
  • feishu-cli msg flag cancel <message_id> [--item-type ... --flag-type ...] — 默认尽量取消消息层 + feed 层;显式传 item/flag 时只取消指定层

关键枚举(服务端真值,绝勿按 0/1/2 顺序臆造)

CLI flag 用字符串,底层映射到 OpenAPI 整数枚举:

字段CLI 字符串OpenAPI 整数含义
--item-typedefault0普通消息
--item-typethread4topic-style 话题群
--item-typemsg_thread11普通群消息线程
--flag-typemessage2消息层书签(默认)
--flag-typefeed1feed 层(侧边栏书签)

⚠️ 反向陷阱:网上某些第三方教程(含部分 lark-cli 旧版示例)把 flag_type: 1=message / 2=feed 写反了。本项目以飞书 OpenAPI 官方真值为准(1=feed / 2=message,见上表)。list 命令输出里也是这套真值,写代码处理 JSON 时认上面这张表。

list 命令不接受 --flag-type/--item-type 作为入参(list 是全量返回),只能在输出 flag_items[*].flag_type 字段上过滤。要看自己有哪些书签直接 feishu-cli msg flag list -o json

支持的组合(其余服务端拒绝):

  • default + message:消息层书签,最常见
  • thread + feed:topic-style 话题群 feed 层
  • msg_thread + feed:普通群消息线程 feed 层

源码引用:internal/client/flag.go:23-28(本仓库权威,对齐 lark-cli shortcuts/im 的 ItemType/FlagType 定义)。

Add the canonical catalog link to the repository README so users can inspect current installs and available audits. The publishing guide covers the complete discovery path.

<a href="https://skillzs.dev/skills/riba2534/feishu-cli/feishu-cli-msg">View feishu-cli-msg on skillZs</a>