Go SDK 文件与图片
本页介绍 Go SDK 中文件的上传与下载:先 Upload 上传得到 FileInfo,再用 SendMedia 把它作为图片、语音、视频或文件消息发出;下载时把消息里的文件地址换取签名直链或直接取回内容。消息发送的总体说明见消息,客户端初始化见初始化、登录与连接。
上传文件
Upload 按服务端的三步流程完成上传:创建上传 → 按预签名地址 PUT 直传 → 完成并返回 FileInfo。单文件不超过 32 MB:
go
data, err := os.ReadFile("photo.jpg")
if err != nil {
log.Fatal(err)
}
info, err := c.Upload(ctx, im.UploadInput{
Name: "photo.jpg",
ContentType: "image/jpeg",
Data: data,
Width: 1080, // 可选元数据
Height: 720,
})
if err != nil {
log.Fatal(err)
}
fmt.Println(info.URL, info.Size)入参 UploadInput:
| 字段 | 说明 |
|---|---|
Name | 文件名 |
ContentType | MIME 类型;Kind 为空时用它推断类型 |
Data | 文件内容([]byte,整个文件读入内存,≤32 MB) |
Purpose | 用途:attachment(消息附件,默认)、user_avatar、group_avatar、group_file、chatroom_avatar |
Kind | 类型:image、voice、video、file;为空时按 ContentType 推断(image/* → image,audio/* → voice,video/* → video,其他 → file) |
Width / Height / DurationMs | 可选元数据(图片尺寸、媒体时长),完成时写回返回的 FileInfo,随后随消息下发 |
内容直连存储
文件内容 PUT 到预签名的存储地址,不经过 IM 服务端的接口,请求也不带 IM 登录凭证。PUT 返回非 2xx 时以 *im.APIError(upload_failed)失败,Message 中是存储端的响应。
- 上传只得到文件,不发送消息,也不修改资料。
- 返回的
FileInfo中URL是文件地址,图片另有缩略图地址ThumbnailURL;Width、Height、DurationMs以你传入和完成时服务端返回的值为准。
FileInfo
上传完成后的文件信息,可直接作为 image、voice、video、file 消息的 body:
| 字段 | 说明 |
|---|---|
FileID | 文件 ID |
Name | 文件名 |
Size | 大小,字节 |
ContentType | MIME 类型 |
Width / Height | 图片宽高,像素 |
DurationMs | 语音、视频时长,毫秒 |
URL | 文件地址(需换取下载直链才能加载,见下文) |
ThumbnailURL | 缩略图地址,图片类附件有 |
SHA256 | 内容摘要 |
发送图片消息
SendMedia 把 FileInfo 序列化为消息体发出,msgType 传对应的类型:
go
// 1. 上传
data, _ := os.ReadFile("photo.jpg")
info, err := c.Upload(ctx, im.UploadInput{
Name: "photo.jpg",
ContentType: "image/jpeg",
Data: data,
})
if err != nil {
log.Fatal(err)
}
// 2. 作为图片消息发出
m, err := c.SendMedia(ctx, im.ToUser("bob"), "image", info, nil)
if err != nil {
log.Fatal(err)
}
fmt.Println(m.Seq)- 语音消息带
DurationMs(上传时通过UploadInput.DurationMs给出),视频可带宽高,方便接收方在下载前排版。 - 接收方按消息的“消息类型”把
body解析回im.FileInfo,用ThumbnailURL显示列表缩略图、URL取原图。 - 发送时
FileInfo原样成为消息体,因此发送前对info的修改(如补字段)会一并带给接收方。
下载
消息附件的 URL 是文件地址,不能直接请求。两种方式:
换取签名直链 DownloadURLs 批量换取(一次最多 100 个),每项一个结果:
go
items, err := c.DownloadURLs(ctx, []string{info.URL, info.ThumbnailURL})
if err != nil {
log.Fatal(err)
}
for _, it := range items {
if it.DownloadURL == "" {
fmt.Println(it.URL, it.Code, it.Message) // 失败:file_deleted、forbidden 等
continue
}
fmt.Println(it.DownloadURL, it.ExpiresAt) // 签名直链与到期时间
}直接下载内容 Download 内部先换取直链再 GET,返回文件字节:
go
var body im.FileInfo
_ = json.Unmarshal(m.Body, &body)
data, err := c.Download(ctx, body.URL) // 缩略图传 body.ThumbnailURL
if err != nil {
log.Fatal(err)
}
_ = os.WriteFile(body.Name, data, 0o644)- 直链短期有效(
ExpiresAt),不要持久化或写进消息;保存不变的文件地址,每次使用时换取。 - 单项失败不会拖垮整批:
DownloadURLs的结果里失败项只有URL、Code、Message;Download则把单项错误原样上抛(file_deleted、forbidden等,用im.IsCode判断)。 Download把内容整个读进内存,读取上限 128 MB。更大的文件请用DownloadURLs换直链后自行流式下载。- 换取直链和下载都不带 IM 登录凭证。
超时与取消
- 所有方法的第一个参数都是
context.Context:取消ctx后,进行中的 REST 请求、预签名 PUT 与下载会随之中止,适合接 UI 的取消按钮或请求级超时。 - REST 的总超时由创建客户端时的
Config.HTTPTimeout控制,缺省 15 秒;大文件上传、下载建议按需放宽,或依赖ctx控制。 Upload一次整文件直传,本 SDK 不做分片与断点续传;超过 32 MB 的文件无法通过Upload上传,请在应用层处理。- 进程退出后上传、下载不会续作;需要可靠投递的场景请在应用侧重试(再次
Upload会得到一个新的FileID)。
