Files
telegram-helper-bot/helper_bot/main.py
Andrey 1c6a37bc12 Enhance bot functionality and refactor database interactions
- Added `ca-certificates` installation to Dockerfile for improved network security.
- Updated health check command in Dockerfile to include better timeout handling.
- Refactored `run_helper.py` to implement proper signal handling and logging during shutdown.
- Transitioned database operations to an asynchronous model in `async_db.py`, improving performance and responsiveness.
- Updated database schema to support new foreign key relationships and optimized indexing for better query performance.
- Enhanced various bot handlers to utilize async database methods, improving overall efficiency and user experience.
- Removed obsolete database and fix scripts to streamline the project structure.
2025-09-02 18:22:02 +03:00

104 lines
4.8 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.
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.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())
# Создаем экземпляр 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)
# Запускаем бота с retry логикой
await start_bot_with_retry(bot, dp)
except Exception as e:
logging.error(f"Error in bot startup: {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