Files
PrimoGuardBot-/main.py
2026-02-17 11:24:55 +07:00

173 lines
5.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
Точка входа 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()