v0.5.0

媒體落地

最後更新


各平台的 Save 方法把收到的檔案下載到指定目錄,並回傳存檔路徑。

簽名


  1. // core/telegram — fileID 取自 Input.Photo[i].FileID 或 Input.Document.FileID
  2. func (b *Bot) Save(ctx context.Context, fileID, dir string) (string, error)
  3. // core/discord — Input.Attachments 的其中一筆
  4. func (b *Bot) Save(ctx context.Context, att *discordgo.MessageAttachment, dir string) (string, error)
  5. // core/line — image、video、audio 或 file 訊息的 Input.MessageID
  6. func (b *Bot) Save(ctx context.Context, messageID, dir string) (string, error)

各平台行為


TelegramDiscordLINE
大小上限20 MiB(Bot API getFile 上限)25 MiB50 MiB(函式庫自訂上限)
下載前得知大小GetFile → FileSizeatt.SizeContentLength
下載方式以 http.DefaultClient 取 FileDownloadLink以 http.DefaultClient 取 att.URLGetMessageContent 串流
副檔名取自 Telegram 的 file_path取自 att.Filename依回應的 Content-Type 推得

共通步驟


  1. 空參數(fileID/att/att.URL/messageID 與 dir)直接回 error。
  2. 回報的大小超過上限時,不下載直接回 error。
  3. HTTP 狀態非 200(Telegram、Discord)時回傳 http <code>: <body>,body 最多 8 KiB。
  4. 以 os.MkdirAll(dir, 0755) 建立 dir。
  5. 串流寫入 dir 內的暫存檔 <uuid>.*.tmp,最多讀取上限 + 1 bytes。實際內容超過上限(回報大小缺漏或錯誤)時刪除暫存檔並回 error;超過上限的檔案不會被截斷保存。
  6. 把暫存檔 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 的第一個副檔名;未知類型不加副檔名。

範例


  1. bot.Reply(func(ctx context.Context, in discord.Input) string {
  2. for _, att := range in.Attachments {
  3. path, err := bot.Save(ctx, att, "./uploads")
  4. if err != nil {
  5. return "save failed: " + err.Error()
  6. }
  7. log.Println("saved", path)
  8. }
  9. return ""
  10. })

相關頁面


EN