- Глобальный синглтон бота (bot_instance.py) — работает из любого процесса - Прямые HTTP запросы в send_smart_broadcast — нет ошибки Timeout context - Исправлен joinedload в InitiativeGroupService - Удалён дубликат route /broadcast - Удалена страница /broadcasts — всё в одном месте с табами - Удалён /api/broadcast/send — дублировал /api/broadcast/create - Добавлен dry_run режим для тестирования без отправки - Двойное подтверждение перед реальной рассылкой - Добавлен файл КРИТИЧЕСКИЕ-ПРАВИЛА.md Инцидент: тестовая рассылка ушла реальным пользователям Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
52 lines
1.6 KiB
Python
52 lines
1.6 KiB
Python
"""
|
||
Глобальный экземпляр бота — доступен из любого процесса
|
||
"""
|
||
from aiogram import Bot
|
||
from aiogram.client.default import DefaultBotProperties
|
||
from aiogram.enums import ParseMode
|
||
from aiogram.client.session.aiohttp import AiohttpSession
|
||
from config import BOT_TOKEN, get_proxy_url, PROXY_TYPE, PROXY_HOST, PROXY_PORT
|
||
import logging
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
# Глобальный синглтон
|
||
bot: Bot | None = None
|
||
|
||
|
||
def get_bot() -> Bot:
|
||
"""Получить экземпляр бота (создаёт если ещё не создан)"""
|
||
global bot
|
||
|
||
if bot is None:
|
||
bot = _create_bot()
|
||
|
||
return bot
|
||
|
||
|
||
def _create_bot() -> Bot:
|
||
"""Создать бота с настройкой прокси"""
|
||
proxy_url = get_proxy_url()
|
||
|
||
if proxy_url:
|
||
logger.info(f'🔒 Создание бота с прокси: {PROXY_TYPE}://{PROXY_HOST}:{PROXY_PORT}')
|
||
aiogram_session = AiohttpSession(proxy=proxy_url)
|
||
return Bot(
|
||
token=BOT_TOKEN,
|
||
session=aiogram_session,
|
||
default=DefaultBotProperties(parse_mode=ParseMode.HTML)
|
||
)
|
||
else:
|
||
logger.info('🔓 Создание бота без прокси')
|
||
return Bot(
|
||
token=BOT_TOKEN,
|
||
default=DefaultBotProperties(parse_mode=ParseMode.HTML)
|
||
)
|
||
|
||
|
||
async def close_bot():
|
||
"""Закрыть сессию бота"""
|
||
global bot
|
||
if bot and bot.session:
|
||
await bot.session.close()
|
||
logger.info('🔒 Сессия бота закрыта')
|