钉钉机器人发送的文件(Excel、PDF 等)在群聊中无法预览,通常是因为发送方式或文件来源不符合钉钉的预览机制。钉钉的预览功能依赖于文件被上传到钉钉的云端存储(MediaId),而不是仅仅发送一个网络链接。
以下是导致该问题的核心原因及解决方案:
❌ 核心原因分析
发送的是“链接”而非“文件”
现象:机器人发送的消息是一个蓝色的超链接(如
http://.../file.xlsx),点击后跳转浏览器下载,而不是在聊天窗口直接显示“预览”按钮。原因:大多数机器人代码是通过
Link消息类型发送的,只传递了 URL。钉钉无法预知外部链接的内容格式,因此不提供内置预览。解决:必须使用 “文件消息” (File Message) 接口,先将文件二进制流上传到钉钉服务器获取
media_id,再发送。文件格式不支持或损坏
文件扩展名与实际内容不符(例如把
.txt改名为.pdf)。文件加密或受密码保护(钉钉无法预览加密文档)。
文件版本过高(如某些特殊的 Excel 宏文件
.xlsm可能支持不佳,建议用.xlsx)。现象:显示了文件卡片,但点击预览报错或白屏。
原因:
使用了错误的消息类型
使用了
Markdown或Text消息类型来包裹文件链接,这永远无法触发预览。
✅ 解决方案:如何发送可预览的文件
要让文件在钉钉群内直接预览,必须遵循 “先上传,后发送” 的两步流程。
步骤 1:调用“上传临时素材”接口
先将本地文件上传到钉钉服务器,换取一个 media_id。该 ID 有效期通常为 3 天。
接口地址:
POST https://oapi.dingtalk.com/media/upload参数:
access_token: 机器人的访问令牌。type: 固定填file。media: 文件的二进制流 (multipart/form-data)。
Python 示例代码:
import requests
def upload_file_to_dingtalk(access_token, file_path):
url = f"https://oapi.dingtalk.com/media/upload?access_token={access_token}&type=file"
files = {
'media': open(file_path, 'rb')
}
response = requests.post(url, files=files)
result = response.json()
if result.get('errcode') == 0:
return result['media_id']
else:
raise Exception(f"上传失败: {result}")步骤 2:调用“发送文件消息”接口
使用上一步拿到的 media_id 发送消息。
接口地址:
POST https://oapi.dingtalk.com/robot/send(群机器人) 或/v1.0/im/agents/messages/send(新版)消息类型:
file关键参数:
media_id: 步骤 1 获取的 ID。fileName: 显示的文件名(必须带后缀,如report.xlsx)。fileSize: 文件大小(字节)。
Python 示例代码:
def send_file_message(webhook, media_id, file_name, file_size):
headers = {'Content-Type': 'application/json'}
data = {
"msgtype": "file",
"file": {
"media_id": media_id,
"fileName": file_name,
"fileSize": file_size
}
}
# 注意:如果是群机器人 webhook,不需要 access_token 在 URL 里,直接在 body 发
# 如果是企业内部 Agent,则用 /v1.0/im/agents/messages/send 接口
response = requests.post(webhook, json=data, headers=headers)
print(response.text)💡 特殊情况处理
1. 文件在 OSS/外部链接,不想下载再上传?
如果文件已经在阿里云 OSS 上,你想避免“下载到本地再上传到钉钉”的流量浪费:
方案:在服务器内存中流转。
使用代码从 OSS 读取流 (
stream) -> 直接requests.post给钉钉上传接口。不需要保存到本地磁盘,节省 IO 和空间。
2. 超大文件 (>20MB)
钉钉机器人对单个文件大小有限制(通常群机器人限制 20MB,企业内部应用可能稍大)。
超过限制:无法通过
file消息发送。替代方案:只能发送 Link 消息,引导用户去浏览器下载。此时无法预览是正常机制,无法绕过。
3. 新版接口 (Work Notice)
如果你使用的是钉钉新版开发平台(H5 微应用/企业内部应用),请使用 /v1.0/im/agents/messages/send 接口,逻辑一样,也是先上传媒体库获取 mediaId,再发送 msgKey: "sampleFile" (或对应 file 类型)。
🚀 快速自查清单
| 检查项 | 正确做法 | 错误做法 |
|---|---|---|
| 消息类型 | msgtype: "file" | msgtype: "link" 或 "markdown" |
| 文件来源 | 已上传至钉钉,拥有 media_id | 直接发送 http/https 外链 |
| 文件名 | 包含正确后缀 (.pdf, .xlsx) | 无后缀或后缀错误 |
| 文件大小 | < 20MB (群机器人) | > 20MB |
| 文件内容 | 未加密、标准格式 | 加密、损坏、特殊宏 |
总结
钉钉不支持对外部链接直接预览。
要实现预览,必须通过 API 将文件二进制流上传到钉钉服务器获取 media_id,然后以 file 消息类型发送。这是唯一能触发钉钉内置文档预览组件的方法。