import asyncio import logging import signal from typing import Sequence from django.core.management.base import BaseCommand from bot.models import TelegramBot from bot.bot_factory import build_application_for_bot log = logging.getLogger(__name__) class Command(BaseCommand): help = "Запуск ВСЕХ активных ботов (PTB 22.3) в одном процессе." def handle(self, *args, **options): logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(name)s: %(message)s") # ORM здесь, в синхронном контексте bots: Sequence[TelegramBot] = list(TelegramBot.objects.filter(is_active=True)) if not bots: self.stderr.write(self.style.ERROR("Нет активных ботов (is_active=True).")) return asyncio.run(self._amain(bots)) async def _amain(self, bots: Sequence[TelegramBot]): apps = [] try: for tb in bots: app, allowed_updates = build_application_for_bot(tb) await app.initialize() await app.start() await app.updater.start_polling(allowed_updates=allowed_updates) apps.append(app) log.info("Bot started: %s (@%s)", tb.name, tb.username or "—") # Ждём SIGINT/SIGTERM stop_event = asyncio.Event() def _stop(*_): stop_event.set() loop = asyncio.get_running_loop() for sig in (signal.SIGINT, signal.SIGTERM): try: loop.add_signal_handler(sig, _stop) except NotImplementedError: pass # Windows await stop_event.wait() finally: for app in reversed(apps): try: await app.updater.stop() await app.stop() await app.shutdown() except Exception: log.exception("Shutdown error")