Files
go-telegram-bot/telegram_helpers.go
T
2026-05-28 20:54:09 +02:00

63 lines
2.1 KiB
Go

package main
import (
"context"
"fmt"
"io"
"net/http"
tgbot "github.com/go-telegram/bot"
"github.com/go-telegram/bot/models"
)
// largestPhotoSize returns the highest-resolution PhotoSize from the slice
// Telegram returns for a single photo. Telegram pre-renders each upload at
// several resolutions; we want the largest for vision quality. Falls back to
// the zero value when the slice is empty (caller should guard upstream).
func largestPhotoSize(photos []models.PhotoSize) models.PhotoSize {
if len(photos) == 0 {
return models.PhotoSize{}
}
largest := photos[0]
largestArea := largest.Width * largest.Height
for i := 1; i < len(photos); i++ {
area := photos[i].Width * photos[i].Height
if area > largestArea {
largest = photos[i]
largestArea = area
}
}
return largest
}
// downloadTelegramFile resolves a Telegram file_id via the bot API, fetches the
// download URL, and reads the bytes into memory. The two-step dance (GetFile +
// fetch via FileDownloadLink) is required by Telegram's protocol — direct
// downloads aren't possible from file_id alone. Buffered into []byte because
// downstream callers (multipart uploads to ElevenLabs and Anthropic) re-read
// the body; streaming would require either tee-ing or a temp file.
func (b *Bot) downloadTelegramFile(ctx context.Context, fileID string) ([]byte, error) {
fileInfo, err := b.tgBot.GetFile(ctx, &tgbot.GetFileParams{FileID: fileID})
if err != nil {
return nil, fmt.Errorf("telegram GetFile %s: %w", fileID, err)
}
downloadURL := b.tgBot.FileDownloadLink(fileInfo)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, downloadURL, nil)
if err != nil {
return nil, fmt.Errorf("telegram download request %s: %w", fileID, err)
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, fmt.Errorf("telegram download %s: %w", fileID, err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("telegram download %s: status %d", fileID, resp.StatusCode)
}
data, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("telegram download read %s: %w", fileID, err)
}
return data, nil
}