package main import ( "context" "fmt" "log/slog" "os" "os/signal" "syscall" "time" "github.com/mymmrac/telego" "git.entityseven.com/rilaxik/pllist/internal/config" "git.entityseven.com/rilaxik/pllist/internal/database" "git.entityseven.com/rilaxik/pllist/internal/repository" "git.entityseven.com/rilaxik/pllist/internal/service" "git.entityseven.com/rilaxik/pllist/internal/telegram" ) const pendingTTL = 5 * time.Minute func main() { logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{ Level: slog.LevelInfo, })) slog.SetDefault(logger) if err := run(logger); err != nil { logger.Error("bot stopped with error", "error", err) os.Exit(1) } } func run(logger *slog.Logger) error { cfg, err := config.Load() if err != nil { return fmt.Errorf("load config: %w", err) } ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM) defer stop() db, err := database.Open(ctx, cfg.DatabaseURL) if err != nil { return err } sqlDB, err := db.DB() if err != nil { return fmt.Errorf("get sql database: %w", err) } defer sqlDB.Close() if cfg.AutoMigrate { if err := repository.Migrate(db); err != nil { return fmt.Errorf("migrate database: %w", err) } } tgBot, err := telego.NewBot( cfg.TelegramBotToken, telego.WithAPICaller(telegram.NewCaller()), ) if err != nil { return fmt.Errorf("create bot: %w", err) } userRepo := repository.NewUserRepository(db) shareRepo := repository.NewShareRepository(db) users := service.NewUserService(userRepo) botAccess := service.NewBotAccessService( repository.NewBotAccessRepository(db), cfg.BotOwnerID, shareRepo, ) listRepo := repository.NewListRepository(db) access := service.NewAccessService(listRepo) lists := service.NewListService(listRepo, access) itemRepo := repository.NewItemRepository(db) items := service.NewItemService(itemRepo, access) shares := service.NewShareService(shareRepo, userRepo, access, botAccess) pending := service.NewPendingStore(pendingTTL) updates, err := tgBot.UpdatesViaLongPolling(ctx, nil) if err != nil { return fmt.Errorf("start long polling: %w", err) } bot, err := telegram.New( tgBot, updates, users, lists, items, shares, access, botAccess, pending, logger, ) if err != nil { return err } logger.Info("bot started") if err := bot.Run(); err != nil { return err } logger.Info("bot stopped") return nil }