domovoy_bot/bot_instance.py
Admin 07d7a51f10 🚨 fix: Критические исправления рассылок
- Глобальный синглтон бота (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>
2026-04-12 17:57:18 +04:00

52 lines
1.6 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
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('🔒 Сессия бота закрыта')