Files
RemnaWaveBOT/app/main.py
2026-04-22 18:34:13 +03:00

136 lines
4.6 KiB
Python

import asyncio
import logging
from pathlib import Path
from aiogram import Bot, Dispatcher
from aiogram.client.default import DefaultBotProperties
from aiogram.client.session.aiohttp import AiohttpSession
from aiogram.enums import ParseMode
from aiogram.exceptions import TelegramNetworkError
from aiogram.types import BotCommand
from app.bot.handlers.main import build_router
from app.config import Settings
from app.db.session import create_engine_and_session_factory, ensure_database_exists, init_db
from app.services.bot_config_service import BotConfigService
from app.services.notification_service import SubscriptionNotificationService
from app.services.payment_service import PaymentService
from app.services.remnawave_client import RemnawaveApiClient
from app.services.support_ticket_service import SupportTicketService
from app.services.sync_service import SyncService
async def main() -> None:
settings = Settings()
logging.basicConfig(
level=getattr(logging, settings.log_level.upper(), logging.INFO),
format="%(asctime)s | %(levelname)s | %(name)s | %(message)s",
)
logger = logging.getLogger(__name__)
engine = None
remnawave_client = None
bot = None
try:
if settings.create_database_on_start:
logger.info(
"Ensuring MariaDB database '%s' exists on %s:%s",
settings.db_name,
settings.db_host,
settings.db_port,
)
await ensure_database_exists(
settings.database_server_url,
settings.db_name,
echo=settings.db_echo,
)
engine, session_factory = create_engine_and_session_factory(
settings.database_url,
echo=settings.db_echo,
)
if settings.create_tables_on_start:
await init_db(engine)
remnawave_client = RemnawaveApiClient(
base_url=settings.remnawave_base_url,
api_token=settings.remnawave_api_token,
caddy_api_key=settings.remnawave_caddy_api_key,
timeout_seconds=settings.remnawave_timeout_seconds,
)
sync_service = SyncService(
settings=settings,
session_factory=session_factory,
remnawave_client=remnawave_client,
)
bot_config_service = BotConfigService(
settings=settings,
session_factory=session_factory,
)
support_ticket_service = SupportTicketService(session_factory=session_factory)
payment_service = PaymentService(
settings=settings,
session_factory=session_factory,
remnawave_client=remnawave_client,
sync_service=sync_service,
config_service=bot_config_service,
)
bot_session = AiohttpSession(proxy=settings.telegram_proxy_url or None)
bot = Bot(
token=settings.bot_token,
session=bot_session,
default=DefaultBotProperties(parse_mode=ParseMode.HTML),
)
dispatcher = Dispatcher()
dispatcher.include_router(
build_router(
settings=settings,
sync_service=sync_service,
support_ticket_service=support_ticket_service,
payment_service=payment_service,
bot_config_service=bot_config_service,
)
)
await bot.set_my_commands(
[
BotCommand(command="start", description="Открыть главное меню"),
]
)
project_root = Path(__file__).resolve().parent.parent
notification_service = SubscriptionNotificationService(
session_factory=session_factory,
sync_service=sync_service,
config_service=bot_config_service,
project_root=project_root,
)
notification_task = asyncio.create_task(
notification_service.run_periodic(bot),
)
try:
await dispatcher.start_polling(bot)
finally:
notification_task.cancel()
try:
await notification_task
except asyncio.CancelledError:
pass
except TelegramNetworkError:
logger.exception(
"Cannot reach Telegram API. Check outbound HTTPS access to api.telegram.org:443, DNS, firewall, VPN, or proxy."
)
raise
finally:
if remnawave_client is not None:
await remnawave_client.close()
if bot is not None:
await bot.session.close()
if engine is not None:
await engine.dispose()