- Added methods to delete audio moderation records and retrieve all audio records in async_db.py. - Enhanced AudioRepository with functionality to delete audio records by file name and retrieve all audio message records. - Improved logging for audio record operations to enhance monitoring and debugging capabilities. - Updated related handlers to ensure proper integration of new audio management features.
110 lines
5.2 KiB
Python
110 lines
5.2 KiB
Python
from aiogram import Bot, Dispatcher
|
||
from aiogram.client.default import DefaultBotProperties
|
||
from aiogram.fsm.storage.memory import MemoryStorage
|
||
from aiogram.fsm.strategy import FSMStrategy
|
||
import logging
|
||
import asyncio
|
||
from typing import Optional
|
||
|
||
from helper_bot.handlers.admin import admin_router
|
||
from helper_bot.handlers.callback import callback_router
|
||
from helper_bot.handlers.group import group_router
|
||
from helper_bot.handlers.private import private_router
|
||
from helper_bot.handlers.voice import VoiceHandlers
|
||
from helper_bot.middlewares.dependencies_middleware import DependenciesMiddleware
|
||
from helper_bot.middlewares.blacklist_middleware import BlacklistMiddleware
|
||
from helper_bot.middlewares.metrics_middleware import MetricsMiddleware, ErrorMetricsMiddleware
|
||
from helper_bot.middlewares.rate_limit_middleware import RateLimitMiddleware
|
||
from helper_bot.server_prometheus import start_metrics_server, stop_metrics_server
|
||
|
||
|
||
async def start_bot_with_retry(bot: Bot, dp: Dispatcher, max_retries: int = 5, base_delay: float = 1.0):
|
||
"""Запуск бота с автоматическим перезапуском при сетевых ошибках"""
|
||
for attempt in range(max_retries):
|
||
try:
|
||
logging.info(f"Запуск бота (попытка {attempt + 1}/{max_retries})")
|
||
await dp.start_polling(bot, skip_updates=True)
|
||
break
|
||
except Exception as e:
|
||
error_msg = str(e).lower()
|
||
if any(keyword in error_msg for keyword in ['network', 'disconnected', 'timeout', 'connection']):
|
||
if attempt < max_retries - 1:
|
||
delay = base_delay * (2 ** attempt) # Exponential backoff
|
||
logging.warning(f"Сетевая ошибка при запуске бота: {e}. Повтор через {delay:.1f}с (попытка {attempt + 1}/{max_retries})")
|
||
await asyncio.sleep(delay)
|
||
continue
|
||
else:
|
||
logging.error(f"Превышено максимальное количество попыток запуска бота: {e}")
|
||
raise
|
||
else:
|
||
logging.error(f"Критическая ошибка при запуске бота: {e}")
|
||
raise
|
||
|
||
|
||
async def start_bot(bdf):
|
||
token = bdf.settings['Telegram']['bot_token']
|
||
bot = Bot(token=token, default=DefaultBotProperties(
|
||
parse_mode='HTML',
|
||
link_preview_is_disabled=bdf.settings['Telegram']['preview_link']
|
||
), timeout=60.0) # Увеличиваем timeout для стабильности
|
||
|
||
dp = Dispatcher(storage=MemoryStorage(), fsm_strategy=FSMStrategy.GLOBAL_USER)
|
||
|
||
# ✅ Оптимизированная регистрация middleware
|
||
dp.update.outer_middleware(DependenciesMiddleware())
|
||
dp.update.outer_middleware(MetricsMiddleware())
|
||
dp.update.outer_middleware(BlacklistMiddleware())
|
||
dp.update.outer_middleware(RateLimitMiddleware())
|
||
|
||
# Создаем экземпляр VoiceHandlers
|
||
voice_handlers = VoiceHandlers(bdf, bdf.settings)
|
||
voice_router = voice_handlers.router
|
||
|
||
# Middleware уже добавлены на уровне dispatcher
|
||
dp.include_routers(admin_router, private_router, callback_router, group_router, voice_router)
|
||
|
||
# Добавляем обработчик завершения для корректного закрытия
|
||
@dp.shutdown()
|
||
async def on_shutdown():
|
||
logging.info("Bot shutdown initiated, cleaning up resources...")
|
||
try:
|
||
await bot.session.close()
|
||
logging.info("Bot session closed successfully")
|
||
except Exception as e:
|
||
logging.error(f"Error closing bot session during shutdown: {e}")
|
||
|
||
await bot.delete_webhook(drop_pending_updates=True)
|
||
|
||
# Запускаем HTTP сервер для метрик параллельно с ботом
|
||
metrics_host = bdf.settings.get('Metrics', {}).get('host', '0.0.0.0')
|
||
metrics_port = bdf.settings.get('Metrics', {}).get('port', 8080)
|
||
|
||
try:
|
||
# Запускаем метрики сервер
|
||
await start_metrics_server(metrics_host, metrics_port)
|
||
|
||
logging.info(f"✅ Метрики сервер запущен на {metrics_host}:{metrics_port}")
|
||
logging.info("✅ Метрики будут обновляться в реальном времени через middleware")
|
||
|
||
# Запускаем бота с retry логикой
|
||
await start_bot_with_retry(bot, dp)
|
||
|
||
logging.info("✅ Бот запущен")
|
||
except Exception as e:
|
||
logging.error(f"❌ Ошибка запуска бота: {e}")
|
||
raise
|
||
finally:
|
||
# Останавливаем метрики сервер при завершении
|
||
try:
|
||
await stop_metrics_server()
|
||
except Exception as e:
|
||
logging.error(f"Error stopping metrics server: {e}")
|
||
|
||
# Закрываем сессию бота
|
||
try:
|
||
await bot.session.close()
|
||
except Exception as e:
|
||
logging.error(f"Error closing bot session: {e}")
|
||
|
||
return bot
|