媒體落地
最後更新
各平台的
Save 方法把收到的檔案下載到指定目錄,並回傳存檔路徑。簽名
- // core/telegram — fileID 取自 Input.Photo[i].FileID 或 Input.Document.FileID
- func (b *Bot) Save(ctx context.Context, fileID, dir string) (string, error)
- // core/discord — Input.Attachments 的其中一筆
- func (b *Bot) Save(ctx context.Context, att *discordgo.MessageAttachment, dir string) (string, error)
- // core/line — image、video、audio 或 file 訊息的 Input.MessageID
- func (b *Bot) Save(ctx context.Context, messageID, dir string) (string, error)
各平台行為
| Telegram | Discord | LINE | |
|---|---|---|---|
| 大小上限 | 20 MiB(Bot API getFile 上限) | 25 MiB | 50 MiB(函式庫自訂上限) |
| 下載前得知大小 | GetFile → FileSize | att.Size | ContentLength |
| 下載方式 | 以 http.DefaultClient 取 FileDownloadLink | 以 http.DefaultClient 取 att.URL | GetMessageContent 串流 |
| 副檔名 | 取自 Telegram 的 file_path | 取自 att.Filename | 依回應的 Content-Type 推得 |
共通步驟
- 空參數(
fileID/att/att.URL/messageID與dir)直接回 error。 - 回報的大小超過上限時,不下載直接回 error。
- HTTP 狀態非 200(Telegram、Discord)時回傳
http <code>: <body>,body 最多 8 KiB。 - 以
os.MkdirAll(dir, 0755)建立dir。 - 串流寫入
dir內的暫存檔<uuid>.*.tmp,最多讀取上限 + 1 bytes。實際內容超過上限(回報大小缺漏或錯誤)時刪除暫存檔並回 error;超過上限的檔案不會被截斷保存。 - 把暫存檔 rename 為
<uuid><ext>,回傳完整路徑。
檔名是
go-pkg/utils 產生的 v4 UUID;UUID 為空(亂數來源失敗)時回 error。Telegram/Discord 的原始檔名不保留;LINE file 訊息的原始檔名在 Input.FileName。LINE 副檔名對應
image/jpeg → .jpg、image/png → .png、image/gif → .gif、image/webp → .webp、video/mp4 → .mp4、audio/mp4 與 audio/x-m4a → .m4a、audio/aac → .aac、application/pdf → .pdf。其他類型取 mime.ExtensionsByType 的第一個副檔名;未知類型不加副檔名。範例
- bot.Reply(func(ctx context.Context, in discord.Input) string {
- for _, att := range in.Attachments {
- path, err := bot.Save(ctx, att, "./uploads")
- if err != nil {
- return "save failed: " + err.Error()
- }
- log.Println("saved", path)
- }
- return ""
- })
相關頁面
- Telegram 設定(
Input.Photo、Input.Document) - Discord 設定(
Input.Attachments) - LINE 訊息(媒體訊息事件)