feat: initial commit
This commit is contained in:
37
internal/infrastructure/telegram/bot_gateway.go
Normal file
37
internal/infrastructure/telegram/bot_gateway.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package telegram
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
|
||||
)
|
||||
|
||||
type BotGateway struct {
|
||||
bot *tgbotapi.BotAPI
|
||||
logger *slog.Logger
|
||||
}
|
||||
|
||||
func NewBotGateway(bot *tgbotapi.BotAPI, logger *slog.Logger) *BotGateway {
|
||||
return &BotGateway{bot: bot, logger: logger}
|
||||
}
|
||||
|
||||
func (g *BotGateway) SendText(ctx context.Context, chatID int64, text string) error {
|
||||
msg := tgbotapi.NewMessage(chatID, text)
|
||||
msg.ParseMode = tgbotapi.ModeMarkdown
|
||||
_, err := g.bot.Send(msg)
|
||||
if err != nil {
|
||||
return fmt.Errorf("telegram send text: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *BotGateway) SendTyping(ctx context.Context, chatID int64) error {
|
||||
action := tgbotapi.NewChatAction(chatID, tgbotapi.ChatTyping)
|
||||
_, err := g.bot.Request(action)
|
||||
if err != nil {
|
||||
g.logger.WarnContext(ctx, "failed to send typing action", "error", err, "chat_id", chatID)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
48
internal/infrastructure/telegram/file_downloader.go
Normal file
48
internal/infrastructure/telegram/file_downloader.go
Normal file
@@ -0,0 +1,48 @@
|
||||
package telegram
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
|
||||
)
|
||||
|
||||
type TelegramFileDownloader struct {
|
||||
bot *tgbotapi.BotAPI
|
||||
client *http.Client
|
||||
}
|
||||
|
||||
func NewTelegramFileDownloader(bot *tgbotapi.BotAPI) *TelegramFileDownloader {
|
||||
return &TelegramFileDownloader{
|
||||
bot: bot,
|
||||
client: &http.Client{},
|
||||
}
|
||||
}
|
||||
|
||||
func (d *TelegramFileDownloader) Download(ctx context.Context, fileID string) ([]byte, string, error) {
|
||||
file, err := d.bot.GetFile(tgbotapi.FileConfig{FileID: fileID})
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("get file info: %w", err)
|
||||
}
|
||||
|
||||
url := file.Link(d.bot.Token)
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("create download request: %w", err)
|
||||
}
|
||||
|
||||
resp, err := d.client.Do(req)
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("download file: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("read file body: %w", err)
|
||||
}
|
||||
|
||||
return data, "audio/ogg", nil
|
||||
}
|
||||
50
internal/infrastructure/telegram/update_poller.go
Normal file
50
internal/infrastructure/telegram/update_poller.go
Normal file
@@ -0,0 +1,50 @@
|
||||
package telegram
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log/slog"
|
||||
|
||||
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
|
||||
)
|
||||
|
||||
type UpdateHandler interface {
|
||||
Handle(ctx context.Context, update tgbotapi.Update)
|
||||
}
|
||||
|
||||
type UpdatePoller struct {
|
||||
bot *tgbotapi.BotAPI
|
||||
handler UpdateHandler
|
||||
logger *slog.Logger
|
||||
timeout int
|
||||
}
|
||||
|
||||
func NewUpdatePoller(bot *tgbotapi.BotAPI, handler UpdateHandler, logger *slog.Logger) *UpdatePoller {
|
||||
return &UpdatePoller{
|
||||
bot: bot,
|
||||
handler: handler,
|
||||
logger: logger,
|
||||
timeout: 60,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *UpdatePoller) Start(ctx context.Context) error {
|
||||
u := tgbotapi.NewUpdate(0)
|
||||
u.Timeout = p.timeout
|
||||
|
||||
updates := p.bot.GetUpdatesChan(u)
|
||||
p.logger.InfoContext(ctx, "update poller started")
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
p.bot.StopReceivingUpdates()
|
||||
p.logger.InfoContext(ctx, "update poller stopped")
|
||||
return ctx.Err()
|
||||
case update, ok := <-updates:
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
go p.handler.Handle(ctx, update)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user