飞书发送文件
飞书机器人发送普通文件(非图片/视频)需要两步:先上传文件获取 filekey,再用 filekey 发消息。
如果本地图片通过常规 message / media 路径发送后,用户在飞书里看到的是 /root/...png 路径文本而不是图片本体,不要继续重试同一种方式;直接改走本技能的稳定图片上传脚本。
快速流程
方式一:用脚本(推荐)
CODEBLOCK0
参数说明:
- -
file_path: 要发送的文件路径(HTML/PDF/ZIP/代码文件等) - INLINECODE4 : 接收者的 openid(从 inboundmeta 的 chat_id 字段获取,格式为
user:ou_xxx,取 ou_xxx 部分) - INLINECODE7 : 飞书应用 ID(从
openclaw.json 的 channels.feishu.appId 读取) - INLINECODE10 : 飞书应用密钥(从
openclaw.json 的 channels.feishu.appSecret 读取) - INLINECODE13 : 可选,自定义文件名(不填则用原文件名)
快速获取配置:
CODEBLOCK1
完整示例:
CODEBLOCK2
AI 助手使用示例:
CODEBLOCK3
方式二:手动两步
Step 1 - 上传文件:
CODEBLOCK4
Step 2 - 发送消息:
CODEBLOCK5
稳定发送图片(2026-03-15 补充)
什么时候不要再硬用 message + media
如果你把本地图片路径(尤其是 /root/myfiles/...)传给飞书消息链路后,用户在飞书里看到的是:
那就说明这次没有真正发成图片。不要继续重试同一种参数组合。
原因(真实世界版)
- - 飞书真正的图片消息不是“把本地路径塞给消息发送器”
- 正路是:先上传到
im/v1/images,拿到 image_key,再发送 msg_type=image - OpenClaw / Feishu 插件在某些本地路径场景下(特别是
/root/myfiles/...)可能无法走通本地媒体上传链路,随后自动降级成把路径文本发出去 - 所以:
messageId 返回成功 不等于 用户真的看到了图片
成功标准
只有一个成功标准:用户在飞书里实际看到图片本体。
如果回显的是路径文本,就视为失败。
推荐脚本(稳定版)
CODEBLOCK6
示例:
CODEBLOCK7
如果是国际版 Lark:
CODEBLOCK8
这和普通文件的区别
- - 普通文件:
im/v1/files -> file_key -> INLINECODE25 - 图片:
im/v1/images -> image_key -> INLINECODE28
这两条链路不要混用。
注意事项
- - 普通文件:必须走本技能的两步流程,直接用
filePath 参数只会显示路径 - 图片:理论上
message tool 的 media 参数可以工作;但如果用户看到的是路径文本而不是图片本体,立刻改用 INLINECODE32 - 不要把
/root/myfiles/... 本地路径回显误判为发送成功 - INLINECODE34 对应个人用户;群聊用
chat_id 并替换类型 - 飞书 file_type 用
stream 适用于所有普通文件类型
飞书发送文件
飞书机器人发送普通文件(非图片/视频)需要两步:先上传文件获取 filekey,再用 filekey 发消息。
如果本地图片通过常规 message / media 路径发送后,用户在飞书里看到的是 /root/...png 路径文本而不是图片本体,不要继续重试同一种方式;直接改走本技能的稳定图片上传脚本。
快速流程
方式一:用脚本(推荐)
bash
python3 scripts/sendfile.py path> id> id> secret> [filename]
参数说明:
- - filepath: 要发送的文件路径(HTML/PDF/ZIP/代码文件等)
- openid: 接收者的 openid(从 inboundmeta 的 chatid 字段获取,格式为 user:ouxxx,取 ouxxx 部分)
- appid: 飞书应用 ID(从 openclaw.json 的 channels.feishu.appId 读取)
- appsecret: 飞书应用密钥(从 openclaw.json 的 channels.feishu.appSecret 读取)
- filename: 可选,自定义文件名(不填则用原文件名)
快速获取配置:
bash
获取 appid 和 appsecret
grep -A 2 feishu /root/.openclaw/openclaw.json | grep -E (appId|appSecret)
完整示例:
bash
python3 /root/.openclaw/workspace/skills/feishu-send-file/scripts/send_file.py \
/root/myfiles/report.html \
OPENID> \
APPID> \
APPSECRET> \
report.html
AI 助手使用示例:
python
当需要发送文件给用户时,直接调用脚本
exec(f
python3 /root/.openclaw/workspace/skills/feishu-send-file/scripts/send_file.py \\
{file_path} \\
{user
openid} \\
{app_id} \\
{app_secret} \\
{custom_filename}
)
方式二:手动两步
Step 1 - 上传文件:
bash
TOKEN=$(curl -s -X POST https://open.feishu.cn/open-apis/auth/v3/tenantaccesstoken/internal \
-H Content-Type: application/json \
-d {appid:ID>,appsecret:SECRET>} | python3 -c import json,sys; print(json.load(sys.stdin)[tenantaccesstoken]))
FILE_KEY=$(curl -s -X POST https://open.feishu.cn/open-apis/im/v1/files \
-H Authorization: Bearer $TOKEN \
-F file_type=stream \
-F file_name=<文件名> \
-F file=@<文件路径> | python3 -c import json,sys; print(json.load(sys.stdin)[data][file_key]))
Step 2 - 发送消息:
bash
curl -s -X POST https://open.feishu.cn/open-apis/im/v1/messages?receiveidtype=open_id \
-H Authorization: Bearer $TOKEN \
-H Content-Type: application/json \
-d {\receiveid\:\ID>\,\msgtype\:\file\,\content\:\{\\\filekey\\\:\\\$FILE_KEY\\\}\}
稳定发送图片(2026-03-15 补充)
什么时候不要再硬用 message + media
如果你把本地图片路径(尤其是 /root/myfiles/...)传给飞书消息链路后,用户在飞书里看到的是:
- - 📎 /root/myfiles/xxx.png
- 或纯本地路径文本
那就说明这次没有真正发成图片。不要继续重试同一种参数组合。
原因(真实世界版)
- - 飞书真正的图片消息不是把本地路径塞给消息发送器
- 正路是:先上传到 im/v1/images,拿到 imagekey,再发送 msgtype=image
- OpenClaw / Feishu 插件在某些本地路径场景下(特别是 /root/myfiles/...)可能无法走通本地媒体上传链路,随后自动降级成把路径文本发出去
- 所以:messageId 返回成功 不等于 用户真的看到了图片
成功标准
只有一个成功标准:用户在飞书里实际看到图片本体。
如果回显的是路径文本,就视为失败。
推荐脚本(稳定版)
bash
python3 scripts/sendimage.py path> id> id> [domain]
示例:
bash
python3 /root/.openclaw/workspace/skills/feishu-send-file/scripts/send_image.py \
/root/myfiles/generated-images/demo.png \
OPENID> \
APPID> \
APPSECRET>
如果是国际版 Lark:
bash
python3 scripts/sendimage.py path> id> id> lark
这和普通文件的区别
- - 普通文件:im/v1/files -> filekey -> msgtype=file
- 图片:im/v1/images -> imagekey -> msgtype=image
这两条链路不要混用。
注意事项
- - 普通文件:必须走本技能的两步流程,直接用 filePath 参数只会显示路径
- 图片:理论上 message tool 的 media 参数可以工作;但如果用户看到的是路径文本而不是图片本体,立刻改用 scripts/sendimage.py
- 不要把 /root/myfiles/... 本地路径回显误判为发送成功
- receiveidtype=openid 对应个人用户;群聊用 chatid 并替换类型
- 飞书 filetype 用 stream 适用于所有普通文件类型