vegapokerbot/internal/app/app.go

219 lines
4.9 KiB
Go
Raw Normal View History

2024-05-07 21:49:09 +03:00
package app
import (
2024-05-07 22:07:53 +03:00
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/config"
2024-05-07 21:49:09 +03:00
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/db"
2024-05-07 22:07:53 +03:00
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/handler"
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/handler/fsmwizard"
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/handler/iface"
2024-05-07 23:45:28 +03:00
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/locale"
2024-05-07 21:49:09 +03:00
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/logger"
2024-05-14 14:44:41 +03:00
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/pkg/types"
2024-05-07 21:49:09 +03:00
"github.com/mymmrac/telego"
"go.uber.org/zap"
2024-05-10 11:46:43 +03:00
"gorm.io/gorm"
"net/url"
2024-05-14 14:44:41 +03:00
"time"
2024-05-07 21:49:09 +03:00
)
type App struct {
2024-05-07 22:07:53 +03:00
Logger *zap.SugaredLogger
Telegram *telego.Bot
BotProfile *telego.User
2024-05-07 22:07:53 +03:00
Config *config.Config
Repositories *db.Repositories
Handlers map[handler.Type]handler.Handler
2024-05-14 14:44:41 +03:00
updates types.Queue[*telego.Update]
2024-05-10 11:46:43 +03:00
db *gorm.DB
2024-05-07 21:49:09 +03:00
}
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
}
2024-05-07 22:07:53 +03:00
a.initHandlers()
2024-05-07 21:49:09 +03:00
a.Logger.Info("Vega Poker Bot is running")
2024-05-10 11:46:43 +03:00
if a.Config.Listen == "" || !a.isValidURL(a.Config.WebhookURL) {
return a.longPoll()
}
return a.listenWebhook()
2024-05-07 21:49:09 +03:00
}
2024-05-07 22:07:53 +03:00
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
}
2024-05-07 22:07:53 +03:00
func (a *App) Conf() *config.Config {
return a.Config
}
func (a *App) DB() iface.Repositories {
2024-05-09 17:42:42 +03:00
return &DBWrapper{a.Repositories}
2024-05-07 22:07:53 +03:00
}
2024-05-07 23:45:28 +03:00
func (a *App) Localizer(lang string) locale.Localizer {
return locale.For(lang)
}
2024-05-07 21:49:09 +03:00
func (a *App) loadConfig() error {
2024-05-07 22:07:53 +03:00
config, err := config.LoadConfig()
2024-05-07 21:49:09 +03:00
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
}
2024-05-07 22:07:53 +03:00
a.Repositories = db.InitRepositories(conn)
2024-05-07 21:49:09 +03:00
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()
2024-05-07 21:49:09 +03:00
return err
}
2024-05-07 22:07:53 +03:00
func (a *App) initHandlers() {
2024-05-14 14:44:41 +03:00
a.updates = types.NewQueue[*telego.Update]()
fsmwizard.PopulateStates(a)
2024-05-07 22:07:53 +03:00
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),
handler.InlineQuery: handler.NewInlineQueryHandler(a),
2024-05-07 22:07:53 +03:00
}
}
func (a *App) handler(update telego.Update) handler.Handler {
if update.Message != nil {
return a.Handlers[handler.Message]
}
if update.MyChatMember != nil {
2024-05-07 22:07:53 +03:00
return a.Handlers[handler.ChatMemberUpdated]
}
if update.CallbackQuery != nil {
return a.Handlers[handler.CallbackQuery]
}
if update.InlineQuery != nil {
return a.Handlers[handler.InlineQuery]
}
2024-05-07 22:07:53 +03:00
return a.Handlers[handler.Noop]
}
2024-05-14 14:44:41 +03:00
func (a *App) processUpdates() {
for {
item := a.updates.Dequeue()
if item == nil {
time.Sleep(time.Nanosecond * 200)
continue
}
a.processUpdate(*item)
}
}
2024-05-10 11:46:43 +03:00
func (a *App) processUpdate(update telego.Update) {
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)
}
}
2024-05-07 21:49:09 +03:00
func (a *App) longPoll() error {
2024-05-10 11:46:43 +03:00
_ = a.Telegram.DeleteWebhook(&telego.DeleteWebhookParams{})
2024-05-07 21:49:09 +03:00
updates, err := a.Telegram.UpdatesViaLongPolling(nil)
if err != nil {
return err
}
2024-05-14 14:44:41 +03:00
go a.processUpdates()
2024-05-07 21:49:09 +03:00
defer a.Telegram.StopLongPolling()
for update := range updates {
2024-05-14 14:44:41 +03:00
update := update
a.updates.Enqueue(&update)
2024-05-07 21:49:09 +03:00
}
return nil
}
2024-05-10 11:46:43 +03:00
func (a *App) listenWebhook() error {
uri, _ := url.Parse(a.Config.WebhookURL)
err := a.Telegram.SetWebhook(&telego.SetWebhookParams{
URL: a.Config.WebhookURL,
})
if err != nil {
return err
}
a.Logger.Debugf("fetching updates from webhook: %s", uri.Path)
updates, err := a.Telegram.UpdatesViaWebhook(uri.Path)
if err != nil {
return err
}
go func() {
_ = a.Telegram.StartWebhook(a.Config.Listen)
}()
defer func() {
_ = a.Telegram.StopWebhook()
}()
2024-05-14 14:44:41 +03:00
go a.processUpdates()
2024-05-10 11:46:43 +03:00
for update := range updates {
2024-05-14 14:44:41 +03:00
update := update
a.updates.Enqueue(&update)
2024-05-10 11:46:43 +03:00
}
return nil
}
func (a *App) isValidURL(uri string) bool {
if uri == "" {
return false
}
_, err := url.Parse(uri)
return err == nil
}