All checks were successful
continuous-integration/drone/push Build is passing
88 lines
3.0 KiB
Go
88 lines
3.0 KiB
Go
package bot
|
||
|
||
import (
|
||
"context"
|
||
"fmt"
|
||
"log/slog"
|
||
|
||
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
|
||
"golang.org/x/time/rate"
|
||
)
|
||
|
||
// TelegramClientAdapter адаптирует библиотеку tgbotapi под наш интерфейс interfaces.TelegramClient.
|
||
type TelegramClientAdapter struct {
|
||
api *tgbotapi.BotAPI
|
||
cacheChatID int64
|
||
fastLimiter *rate.Limiter // Для общих быстрых запросов
|
||
cacheLimiter *rate.Limiter // Для медленных запросов в кэш-канал
|
||
}
|
||
|
||
// NewTelegramClientAdapter создает новый адаптер.
|
||
func NewTelegramClientAdapter(api *tgbotapi.BotAPI, cacheChatID int64, fastLimiter, cacheLimiter *rate.Limiter) *TelegramClientAdapter {
|
||
return &TelegramClientAdapter{
|
||
api: api,
|
||
cacheChatID: cacheChatID,
|
||
fastLimiter: fastLimiter,
|
||
cacheLimiter: cacheLimiter,
|
||
}
|
||
}
|
||
|
||
// SendAudioToCacheChannel загружает аудиофайл в кэш-канал и возвращает его FileID.
|
||
// ИСПОЛЬЗУЕТ МЕДЛЕННЫЙ ЛИМИТЕР.
|
||
func (t *TelegramClientAdapter) SendAudioToCacheChannel(ctx context.Context, audioPath, title, performer string) (string, error) {
|
||
// Ждем, пока МЕДЛЕННЫЙ лимитер разрешит выполнить запрос
|
||
if err := t.cacheLimiter.Wait(ctx); err != nil {
|
||
return "", err
|
||
}
|
||
|
||
audio := tgbotapi.NewAudio(t.cacheChatID, tgbotapi.FilePath(audioPath))
|
||
audio.Title = title
|
||
audio.Performer = performer
|
||
|
||
msg, err := t.api.Send(audio)
|
||
if err != nil {
|
||
return "", fmt.Errorf("failed to send audio to cache channel: %w", err)
|
||
}
|
||
if msg.Audio == nil {
|
||
return "", fmt.Errorf("sent message does not contain audio")
|
||
}
|
||
|
||
slog.Debug("Audio sent to cache channel", "file_id", msg.Audio.FileID)
|
||
return msg.Audio.FileID, nil
|
||
}
|
||
|
||
// AnswerInlineQuery отвечает на inline-запрос.
|
||
// ИСПОЛЬЗУЕТ БЫСТРЫЙ ЛИМИТЕР.
|
||
func (t *TelegramClientAdapter) AnswerInlineQuery(ctx context.Context, queryID string, results []interface{}) error {
|
||
// Ждем, пока БЫСТРЫЙ лимитер разрешит выполнить запрос
|
||
if err := t.fastLimiter.Wait(ctx); err != nil {
|
||
return err
|
||
}
|
||
|
||
inlineConfig := tgbotapi.InlineConfig{
|
||
InlineQueryID: queryID,
|
||
Results: results,
|
||
CacheTime: 1,
|
||
}
|
||
|
||
if _, err := t.api.Request(inlineConfig); err != nil {
|
||
return fmt.Errorf("failed to answer inline query: %w", err)
|
||
}
|
||
return nil
|
||
}
|
||
|
||
// SendMessage отправляет текстовое сообщение.
|
||
// ИСПОЛЬЗУЕТ БЫСТРЫЙ ЛИМИТЕР.
|
||
func (t *TelegramClientAdapter) SendMessage(ctx context.Context, chatID int64, text string) error {
|
||
// Ждем, пока БЫСТРЫЙ лимитер разрешит выполнить запрос
|
||
if err := t.fastLimiter.Wait(ctx); err != nil {
|
||
return err
|
||
}
|
||
|
||
msg := tgbotapi.NewMessage(chatID, text)
|
||
if _, err := t.api.Send(msg); err != nil {
|
||
return fmt.Errorf("failed to send message: %w", err)
|
||
}
|
||
return nil
|
||
}
|