package app import ( "gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/config" "gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/db" "gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/handler" "gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/handler/iface" "gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/locale" "gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/logger" "github.com/mymmrac/telego" "go.uber.org/zap" ) type App struct { Logger *zap.SugaredLogger Telegram *telego.Bot BotProfile *telego.User Config *config.Config Repositories *db.Repositories Handlers map[handler.Type]handler.Handler } func (a *App) Start() error { if err := a.loadConfig(); err != nil { return err } if err := a.initLogger(); err != nil { return err } if a.Config.Debug { a.Logger.Debugf("loaded configuration: %+v", a.Config) } if err := a.migrateDB(); err != nil { return err } if err := a.initDB(); err != nil { return err } if err := a.initTelegram(); err != nil { return err } a.initHandlers() a.Logger.Info("Vega Poker Bot is running") return a.longPoll() } func (a *App) Log() *zap.SugaredLogger { return a.Logger } func (a *App) TG() *telego.Bot { return a.Telegram } func (a *App) TGProfile() *telego.User { return a.BotProfile } func (a *App) Conf() *config.Config { return a.Config } func (a *App) DB() iface.Repositories { return &DBWrapper{a.Repositories} } func (a *App) Localizer(lang string) locale.Localizer { return locale.For(lang) } func (a *App) loadConfig() error { config, err := config.LoadConfig() if err != nil { return err } a.Config = config return nil } func (a *App) initLogger() error { var err error a.Logger, err = logger.NewLogger(a.Config.Debug) return err } func (a *App) migrateDB() error { return db.Migrate(a.Config.PostgresDSN) } func (a *App) initDB() error { conn, err := db.Connect(a.Config.PostgresDSN) if err != nil { return err } a.Repositories = db.InitRepositories(conn) return nil } func (a *App) initTelegram() error { var err error a.Telegram, err = telego.NewBot(a.Config.TelegramToken, logger.WrapForTelego(a.Logger, a.Config.Debug)) if err != nil { return err } a.BotProfile, err = a.Telegram.GetMe() return err } func (a *App) initHandlers() { a.Handlers = map[handler.Type]handler.Handler{ handler.Noop: handler.NewNoopHandler(a.Logger, a.Config.Debug), handler.Message: handler.NewMessageHandler(a), handler.ChatMemberUpdated: handler.NewChatMemberUpdatedHandler(a), handler.CallbackQuery: handler.NewCallbackQueryHandler(a), } } func (a *App) handler(update telego.Update) handler.Handler { if update.Message != nil { return a.Handlers[handler.Message] } if update.MyChatMember != nil { return a.Handlers[handler.ChatMemberUpdated] } if update.CallbackQuery != nil { return a.Handlers[handler.CallbackQuery] } return a.Handlers[handler.Noop] } func (a *App) longPoll() error { updates, err := a.Telegram.UpdatesViaLongPolling(nil) if err != nil { return err } defer a.Telegram.StopLongPolling() for update := range updates { go func() { defer func() { if r := recover(); r != nil { a.Logger.Errorf("recovered from panic inside the handler: %v", r) } }() if err := a.handler(update).Handle(update); err != nil { a.Logger.Errorf("error while handling the update: %s", err) } }() } return nil }