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)。
