钉钉机器人发送图片消息因 Base64 编码过大导致失败时,最推荐的优化方案是停止在消息体中直接传输 Base64 字符串,改为将图片上传至对象存储(OSS)或钉钉媒体接口,然后在消息中发送图片 URL。
先说结论:Base64 编码会增加约 33% 的文件体积,极易触发钉钉机器人消息内容长度限制,改用图片 URL 是稳定且官方推荐的方案。
- 先定位:确认报错信息是否包含内容长度超限或编码解析失败。
- 先做:将图片上传至支持 HTTPS 的外部存储,获取永久或长效访问链接。
- 再验证:发送仅包含图片 URL 的 Markdown 消息,确认机器人响应成功且图片正常渲染。
快速处理思路
如果不方便立即改造存储架构,可按以下顺序临时止血:
- 压缩图片:在发送前将图片分辨率压缩至适合移动端查看的大小(如宽度 1080px 以内)。
- 转换格式:将 PNG 转为 JPG 格式以减少文件体积。
- 更换发送方式:放弃 Base64,使用钉钉提供的媒体上传接口(需内部应用权限)或第三方图床获取 URL。
为什么会这样
根本原因是 Base64 编码机制导致数据膨胀,叠加钉钉机器人对消息总长度的严格限制。
Base64 编码会将二进制数据转换为文本格式,理论体积增加约 33%。钉钉自定义机器人(Webhook)对消息内容总长度有明确限制(通常约为 20KB),包含图片 Base64 字符串的消息体极易超出该阈值,导致接口返回错误或直接丢弃消息。此外,部分钉钉客户端版本出于安全考虑,可能不直接渲染 Data URI scheme 格式的 Base64 图片。
分步处理
按以下步骤重构图片发送逻辑,确保消息可达:
- 准备图片存储:
使用阿里云 OSS、腾讯云 COS 或公司内部文件服务器,确保图片可通过公网 HTTPS 访问。
检查点:浏览器直接访问图片链接应能显示图片,且协议为 HTTPS。 - 修改消息构造:
将消息类型设置为 markdown,使用语法嵌入图片。{ "msgtype": "markdown", "markdown": { "title": "图片通知", "text": "\n\n这里是相关文字说明" } } - 处理权限与时效:
若使用临时签名 URL,确保签名有效期覆盖消息发送时间;若使用钉钉媒体上传接口,需确认应用类型支持该权限。
风险边界:临时链接过期会导致图片在聊天窗口中无法加载。
怎么验证是否生效
通过接口响应码和客户端表现双重验证:
- 接口响应:发送请求后,检查 HTTP 响应 body 中的
errcode字段,值为0表示发送成功。 - 日志检查:查看服务端日志,确认请求体大小明显小于 Base64 方案。
- 客户端表现:钉钉群聊中应正常显示图片缩略图,点击可大图查看,无“图片加载失败”提示。
常见坑
- HTTP 协议限制:钉钉要求图片链接必须使用 HTTPS 协议,HTTP 链接可能被拦截或不显示。
- 跨域与鉴权:若图片存储需要鉴权,确保链接中包含有效的 Token 或签名,且不会因频繁访问触发防盗链限制。
- 特殊字符转义:Markdown 内容中的括号、感叹号等特殊字符需正确转义,避免破坏消息结构。
常见问题
钉钉机器人支持直接发 Base64 图片吗?
不建议使用。虽然部分版本可能解析 Data URI,但极易超出消息长度限制且兼容性差,官方文档推荐使用图片 URL。
消息内容长度限制具体是多少?
公开资料中通常指出自定义机器人消息内容限制在 20KB 左右,具体数值以钉钉开放平台最新文档为准,建议控制在 10KB 以内留有余量。
没有对象存储怎么获取图片 URL?
可调用钉钉内部应用的媒体上传接口获取 media_id,或使用公司现有的文件服务器生成临时公开链接,避免硬编码 Base64。