diff --git a/main.py b/main.py index c1f9f9fa..41e31470 100644 --- a/main.py +++ b/main.py @@ -6,20 +6,18 @@ from aiogram import Bot, Dispatcher from aiogram.fsm.storage.memory import MemoryStorage from aiogram.client.default import DefaultBotProperties from aiogram.enums import ParseMode +from lucky_game import lucky_game_router -# ДОБАВЛЯЕМ ДЕБАГ ЗАГРУЗКИ .env ПЕРЕД ИМПОРТОМ CONFIG print("🚀 Запуск бота...") print(f"📍 Рабочая директория: {os.getcwd()}") print(f"📁 Файлы в директории: {os.listdir('.')}") -# Проверяем наличие .env файла if os.path.exists('.env'): print("✅ Файл .env найден") else: print("❌ Файл .env НЕ НАЙДЕН!") print("💡 Создайте файл .env в корне проекта") -# Import our modules ПОСЛЕ проверки .env from config import load_config, debug_environment from database import Database from remnawave_api import RemnaWaveAPI @@ -28,7 +26,6 @@ from middlewares import DatabaseMiddleware, UserMiddleware, LoggingMiddleware, T from handlers import router from admin_handlers import admin_router -# Configure logging logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', @@ -40,7 +37,6 @@ logging.basicConfig( logger = logging.getLogger(__name__) class BotApplication: - """Main bot application class""" def __init__(self): self.config = None @@ -51,21 +47,16 @@ class BotApplication: self.monitor_service = None async def initialize(self): - """Initialize all components""" - # ДЕБАГ: проверяем переменные окружения debug_environment() - # Load configuration self.config = load_config() - # ДЕБАГ: проверяем что загрузилось print(f"🔧 Загруженная конфигурация:") print(f" BOT_USERNAME: '{self.config.BOT_USERNAME}'") print(f" REFERRAL_FIRST_REWARD: {self.config.REFERRAL_FIRST_REWARD}") print(f" ADMIN_IDS: {self.config.ADMIN_IDS}") - # Validate required environment variables if not self.config.BOT_TOKEN: logger.error("BOT_TOKEN is required") raise ValueError("BOT_TOKEN is required") @@ -74,7 +65,6 @@ class BotApplication: logger.error("REMNAWAVE_URL and REMNAWAVE_TOKEN are required") raise ValueError("REMNAWAVE_URL and REMNAWAVE_TOKEN are required") - # ПРЕДУПРЕЖДЕНИЕ если BOT_USERNAME не установлен if not self.config.BOT_USERNAME: logger.warning("⚠️ BOT_USERNAME не установлен! Реферальные ссылки работать не будут!") print("💡 Добавьте BOT_USERNAME=your_bot_username в .env файл") @@ -84,11 +74,9 @@ class BotApplication: logger.info(f"Admin IDs: {self.config.ADMIN_IDS}") logger.info(f"Bot Username: {self.config.BOT_USERNAME}") - # Initialize database self.db = Database(self.config.DATABASE_URL) await self._init_database() - # Initialize RemnaWave API self.api = RemnaWaveAPI( self.config.REMNAWAVE_URL, self.config.REMNAWAVE_TOKEN, @@ -96,26 +84,20 @@ class BotApplication: ) logger.info("RemnaWave API initialized") - # Test API connection (optional - don't fail if it doesn't work) await self._test_api_connection() - # Initialize bot and dispatcher self.bot = Bot( token=self.config.BOT_TOKEN, default=DefaultBotProperties(parse_mode=ParseMode.HTML) ) - # Test bot token await self._test_bot_token() - # Initialize dispatcher self._setup_dispatcher() - # Initialize subscription monitor service await self._init_monitor_service() async def _init_database(self): - """Initialize database with retry logic""" max_retries = 3 for attempt in range(max_retries): try: @@ -127,10 +109,9 @@ class BotApplication: if attempt == max_retries - 1: logger.error("Failed to initialize database after all retries") raise - await asyncio.sleep(2) # Wait before retry + await asyncio.sleep(2) async def _test_api_connection(self): - """Test API connection""" try: system_stats = await self.api.get_system_stats() if system_stats: @@ -141,12 +122,10 @@ class BotApplication: logger.warning(f"RemnaWave API connection error: {e} - continuing anyway") async def _test_bot_token(self): - """Test bot token before starting""" try: bot_info = await self.bot.get_me() logger.info(f"Bot started: @{bot_info.username} ({bot_info.first_name})") - # АВТОМАТИЧЕСКИ обновляем BOT_USERNAME если он не был установлен if not self.config.BOT_USERNAME and bot_info.username: self.config.BOT_USERNAME = bot_info.username logger.info(f"✅ BOT_USERNAME автоматически установлен: {bot_info.username}") @@ -157,19 +136,16 @@ class BotApplication: raise def _setup_dispatcher(self): - """Setup dispatcher with middlewares and routers""" storage = MemoryStorage() self.dp = Dispatcher(storage=storage) - # Store config, api, db, and monitor_service in dispatcher workflow_data for access in handlers self.dp.workflow_data.update({ "config": self.config, "api": self.api, "db": self.db, - "monitor_service": None # Will be updated after monitor service is created + "monitor_service": None }) - # Setup middlewares in correct order self.dp.message.middleware(LoggingMiddleware()) self.dp.callback_query.middleware(LoggingMiddleware()) @@ -188,35 +164,56 @@ class BotApplication: self.dp.message.middleware(UserMiddleware(self.db, self.config)) self.dp.callback_query.middleware(UserMiddleware(self.db, self.config)) - # Register routers self.dp.include_router(router) self.dp.include_router(admin_router) + self.dp.include_router(lucky_game_router) async def _init_monitor_service(self): - """Initialize subscription monitor service""" try: + logger.info("🔧 Initializing subscription monitor service...") + + if not self.bot: + logger.error("❌ Bot instance is None, cannot initialize monitor") + return + + if not self.db: + logger.error("❌ Database instance is None, cannot initialize monitor") + return + + if not self.config: + logger.error("❌ Config instance is None, cannot initialize monitor") + return + self.monitor_service = await create_subscription_monitor( self.bot, self.db, self.config, self.api ) - - # Update workflow_data with monitor service + + if not self.monitor_service: + logger.error("❌ Failed to create monitor service instance") + return + self.dp.workflow_data["monitor_service"] = self.monitor_service - - # Start the monitor service + logger.info("✅ Monitor service added to workflow_data") + + logger.info("🚀 Starting monitor service...") await self.monitor_service.start() - logger.info("Subscription monitor service started successfully") - + + status = await self.monitor_service.get_service_status() + if status['is_running']: + logger.info("✅ Subscription monitor service started successfully") + logger.info(f"📊 Monitor status: interval={status['check_interval']}s, daily_hour={status['daily_check_hour']}, warning_days={status['warning_days']}") + else: + logger.warning("⚠️ Monitor service created but not running") + logger.warning(f"📊 Monitor status: {status}") + except Exception as e: - logger.error(f"Failed to initialize monitor service: {e}") - # Don't fail the entire application if monitor service fails - logger.warning("Continuing without monitor service") + logger.error(f"❌ Failed to initialize monitor service: {e}", exc_info=True) + logger.warning("⚠️ Continuing without monitor service") self.monitor_service = None async def start(self): - """Start bot polling""" logger.info("Bot polling started successfully") - # ФИНАЛЬНАЯ ПРОВЕРКА конфигурации if self.config.BOT_USERNAME: logger.info(f"🎁 Реферальная система активна! Ссылки: https://t.me/{self.config.BOT_USERNAME}?start=ref_USERID") else: @@ -231,10 +228,8 @@ class BotApplication: await self.shutdown() async def shutdown(self): - """Shutdown all services""" logger.info("Shutting down bot...") - # Stop monitor service first if self.monitor_service: try: await self.monitor_service.stop() @@ -242,7 +237,6 @@ class BotApplication: except Exception as e: logger.error(f"Error stopping monitor service: {e}") - # Close API connection if self.api: try: await self.api.close() @@ -250,7 +244,6 @@ class BotApplication: except Exception as e: logger.error(f"Error closing API: {e}") - # Close database connection if self.db: try: await self.db.close() @@ -258,7 +251,6 @@ class BotApplication: except Exception as e: logger.error(f"Error closing database: {e}") - # Close bot session if self.bot: try: await self.bot.session.close() @@ -269,7 +261,6 @@ class BotApplication: logger.info("Bot shutdown complete") async def main(): - """Main function""" app = None try: app = BotApplication()