package main import ( "embed" "log" "net/http" "os" "stream-bot/internal/ai" "stream-bot/internal/audio" "stream-bot/internal/commands" "stream-bot/internal/db" "stream-bot/internal/events" "stream-bot/internal/gui" "stream-bot/internal/hotkey" "stream-bot/internal/logger" "stream-bot/internal/notifications" "stream-bot/internal/platforms" "stream-bot/internal/twitchapi" "stream-bot/internal/webui" "stream-bot/internal/webservices" ) //go:embed internal/webui/templates/* internal/webui/static/* var webAssets embed.FS func main() { // Создаём папку data if err := os.MkdirAll("data", 0755); err != nil { log.Fatalf("Cannot create data directory: %v", err) } if err := os.MkdirAll("data/sounds", 0755); err != nil { logger.Warn("Cannot create sounds directory: %v", err) } // Инициализация логгера if err := logger.Init("bot.log", 10*1024*1024); err != nil { log.Fatalf("Failed to init logger: %v", err) } logger.Info("Starting Stream Bot...") // Инициализация БД if err := db.Init("data/bot.db"); err != nil { logger.Fatal("DB init error: %v", err) } defer db.Close() // Инициализация эмулятора клавиш if err := hotkey.Init(); err != nil { logger.Warn("Hotkey emulator init: %v", err) } // Инициализация аудио-плеера if err := audio.Init(); err != nil { logger.Warn("Audio player init: %v", err) } defer audio.Close() // AI конфиг aiConfig, err := db.GetAIConfig() if err != nil { logger.Warn("Failed to load AI config: %v", err) } var aiProvider ai.Provider if aiConfig != nil && aiConfig.Provider != "" { aiProvider, err = ai.NewProvider(aiConfig) if err != nil { logger.Warn("Failed to create AI provider: %v", err) } } // Менеджер уведомлений notifMgr, err := notifications.NewManager() if err != nil { logger.Warn("Notification manager init: %v", err) } webSrvMgr := webservices.NewManager() twitchAPI := twitchapi.New() cmdProc := commands.NewProcessor(twitchAPI, aiProvider, webSrvMgr) var platformMgr *platforms.Manager sendMessage := func(platform string, text string) error { if platformMgr == nil { return nil } if p := platformMgr.GetPlatform(platform); p != nil { return p.SendMessage(text) } return nil } // Создаём обработчик событий, передавая notifMgr eventProc := events.NewProcessor(sendMessage, webSrvMgr) platformMgr = platforms.NewManager(cmdProc, eventProc, notifMgr, webSrvMgr) platformMgr.ConnectAll() webSrvMgr.StartAll() // Веб-сервер uiServer := webui.NewServer(webAssets, platformMgr, cmdProc, eventProc, notifMgr, webSrvMgr) getChatStatus := func() bool { return platformMgr.IsConnected("twitch") } getEventSubStatus := func() (bool, []string) { connected, subs, _ := platformMgr.GetTwitchEventSubStatus() return connected, subs } go func() { if err := uiServer.Start(":8080"); err != nil && err != http.ErrServerClosed { logger.Error("UI server error: %v", err) } }() webURL := "http://localhost:8080" gui.Run(webURL, getChatStatus, getEventSubStatus) logger.Info("Shutting down...") platformMgr.StopAll() uiServer.Stop() audio.Close() db.Close() logger.Info("Bot stopped") os.Exit(0) }