Files
Vladimir Zagainov 4005371767
Some checks failed
continuous-integration/drone/push Build is failing
fixed gitignore
2025-06-23 16:29:45 +03:00

78 lines
2.0 KiB
Go

package bot
import (
"context"
"log/slog"
"os"
"os/signal"
"slices"
"syscall"
"gitea.mrixs.me/Mrixs/yamusic-bot/internal/admin"
"gitea.mrixs.me/Mrixs/yamusic-bot/internal/config"
"gitea.mrixs.me/Mrixs/yamusic-bot/internal/interfaces"
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
)
// App - главное приложение бота.
type App struct {
cfg *config.Config
api *tgbotapi.BotAPI
storage interfaces.TrackStorage
adminHandler *admin.Handler
inlineHandler *InlineHandler
}
// NewApp создает новый экземпляр приложения.
func NewApp(cfg *config.Config, api *tgbotapi.BotAPI, storage interfaces.TrackStorage, adminHandler *admin.Handler, inlineHandler *InlineHandler) *App {
return &App{
cfg: cfg,
api: api,
storage: storage,
adminHandler: adminHandler,
inlineHandler: inlineHandler,
}
}
// Run запускает основной цикл бота.
func (a *App) Run(ctx context.Context) {
ctx, cancel := signal.NotifyContext(ctx, os.Interrupt, syscall.SIGTERM)
defer cancel()
u := tgbotapi.NewUpdate(0)
u.Timeout = 60
updates := a.api.GetUpdatesChan(u)
slog.Info("Bot is running and waiting for updates...")
for {
select {
case update := <-updates:
a.handleUpdate(ctx, update)
case <-ctx.Done():
slog.Info("Shutting down...")
a.api.StopReceivingUpdates()
if err := a.storage.Close(); err != nil {
slog.Error("Failed to close storage", "error", err)
}
return
}
}
}
func (a *App) handleUpdate(ctx context.Context, update tgbotapi.Update) {
if update.InlineQuery != nil {
go a.inlineHandler.HandleInlineQuery(ctx, update.InlineQuery)
} else if update.Message != nil && update.Message.IsCommand() {
if a.isAdmin(update.Message.From.ID) {
go a.adminHandler.HandleCommand(ctx, update.Message)
} else {
slog.Warn("Unauthorized command attempt", "user_id", update.Message.From.ID)
}
}
}
func (a *App) isAdmin(userID int64) bool {
return slices.Contains(a.cfg.TelegramAdminIDs, userID)
}