v0.5.0

Saving Media

Last updated


Each platform's Save method downloads a received file to a directory and returns the saved path.

Signatures


  1. // core/telegram — fileID from Input.Photo[i].FileID or Input.Document.FileID
  2. func (b *Bot) Save(ctx context.Context, fileID, dir string) (string, error)
  3. // core/discord — one entry of Input.Attachments
  4. func (b *Bot) Save(ctx context.Context, att *discordgo.MessageAttachment, dir string) (string, error)
  5. // core/line — Input.MessageID of an image, video, audio, or file message
  6. func (b *Bot) Save(ctx context.Context, messageID, dir string) (string, error)

Per-platform behavior


TelegramDiscordLINE
Size cap20 MiB (Bot API getFile limit)25 MiB50 MiB (library limit)
Size known before downloadGetFile → FileSizeatt.SizeContentLength
DownloadFileDownloadLink over http.DefaultClientatt.URL over http.DefaultClientGetMessageContent stream
ExtensionFrom Telegram's file_pathFrom att.FilenameFrom the response Content-Type

Shared steps


  1. Reject empty arguments (fileID / att / att.URL / messageID, and dir).
  2. Reject the file when the reported size exceeds the cap, before downloading.
  3. On a non-200 HTTP status (Telegram, Discord), return http <code>: <body> with at most 8 KiB of the body.
  4. Create dir with os.MkdirAll(dir, 0755).
  5. Stream into a temporary file <uuid>.*.tmp inside dir, reading at most cap + 1 bytes. If more than the cap arrives (the reported size was missing or wrong), delete the temp file and return an error. Oversized files are never truncated.
  6. Rename the temp file to <uuid><ext> and return the full path.

The file name is a v4 UUID from go-pkg/utils; an empty UUID (random source failure) is returned as an error. The original Telegram/Discord file name is not kept; for LINE file messages the original name is in Input.FileName.

LINE extension mapping


image/jpeg → .jpg, image/png → .png, image/gif → .gif, image/webp → .webp, video/mp4 → .mp4, audio/mp4 and audio/x-m4a → .m4a, audio/aac → .aac, application/pdf → .pdf. Other types use the first extension from mime.ExtensionsByType; unknown types get no extension.

Example


  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. })


中文