""" Точка входа PrimoGuard Bot """ from asyncio import run from configs import settings from bot import bot, dp, BotInfo, WebhookManager, setup_middlewares, router from database import get_manager from middleware.loggers import logger __all__ = ("main",) async def setup_services(setup_webhook: bool = True) -> str: """ Инициализация всех сервисов: БД и бот. Args: setup_webhook: Устанавливать ли webhook в BotInfo.setup() Returns: str: Username бота """ # База данных manager = get_manager() await manager.init() stats = await manager.get_stats() logger.info( f"📊 БД инициализирована: {stats.get('total_banwords', 0)} банвордов", log_type="DATABASE" ) # Бот: получение информации (БЕЗ webhook) await BotInfo.setup(bots=bot, setup_webhook=setup_webhook) # ВАЖНО: Регистрируем middleware и роутеры ДО установки webhook setup_middlewares( dp=dp, bot=bot, enable_spam_check=settings.ANTI_SPAM, channel_ids=[], ) # Подключение маршрутов dp.include_router(router) logger.info("✓ Все handlers и middleware зарегистрированы", log_type="STARTUP") return BotInfo.username async def on_startup(app) -> None: """Выполняется при запуске webhook-сервера.""" # 1. Инициализируем всё БЕЗ webhook username = await setup_services(setup_webhook=False) # 2. ТЕПЕРЬ устанавливаем webhook (когда всё готово) webhook = WebhookManager(bot, dp) if settings.WEBHOOK_URL: success = await webhook.setup( webhook_url=settings.WEBHOOK_URL, secret_token=settings.SECRET_TOKEN, drop_pending_updates=True ) if success: logger.success( f"✅ Бот @{username} запущен в режиме Webhook", log_type="STARTUP" ) else: logger.error( "❌ Не удалось установить webhook, но сервер запущен", log_type="STARTUP" ) else: logger.warning( "⚠️ WEBHOOK_URL не указан", log_type="STARTUP" ) async def on_shutdown(app) -> None: """Очистка ресурсов при остановке сервера.""" logger.info("👋 Остановка бота...", log_type="SHUTDOWN") try: await get_manager().close() await bot.session.close() except Exception as e: logger.error(f"Ошибка при закрытии: {e}", log_type="SHUTDOWN") logger.success("✅ Бот остановлен", log_type="SHUTDOWN") def start_webhook() -> None: """Запуск в режиме Webhook (синхронный).""" logger.setup() webhook = WebhookManager(bot, dp) # ВАЖНО: Конфигурируем webhook ПЕРЕД on_startup webhook.configure() # Добавляем startup/shutdown handlers webhook.app.on_startup.append(on_startup) webhook.app.on_shutdown.append(on_shutdown) # Запускаем webhook сервер logger.info("🌐 Запуск Webhook сервера...", log_type="MAIN") webhook.run() async def start_polling() -> None: """Запуск в режиме Polling (асинхронный).""" logger.setup() try: username = await setup_services(setup_webhook=False) # Удаляем webhook для polling режима webhook = WebhookManager(bot, dp) await webhook.delete(drop_pending_updates=True) logger.success( f"✅ Бот @{username} запущен в режиме Polling", log_type="STARTUP" ) # Запускаем polling await dp.start_polling(bot, drop_pending_updates=True) except Exception as e: logger.critical( f"🔥 Критическая ошибка: {e}", log_type="MAIN" ) raise finally: try: await bot.session.close() await get_manager().close() except: pass def main() -> None: """Входная точка проекта.""" try: if settings.WEBHOOK: # ========== WEBHOOK РЕЖИМ ========== start_webhook() else: # ========== POLLING РЕЖИМ ========== run(start_polling()) except KeyboardInterrupt: logger.info("⚠️ Остановка по сигналу Ctrl+C", log_type="MAIN") except Exception as e: logger.critical( f"🔥 Критическая ошибка при запуске: {e}", log_type="MAIN" ) raise if __name__ == "__main__": main()