# bot/management/commands/runbots.py import asyncio import logging import signal 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") asyncio.run(self._amain()) async def _amain(self): bots = list(TelegramBot.objects.filter(is_active=True)) if not bots: self.stderr.write(self.style.ERROR("Нет активных ботов (is_active=True).")) return apps = [] try: # Инициализация и старт polling для каждого бота for tb in bots: app, allowed_updates = build_application_for_bot(tb) await app.initialize() await app.start() # в 22.x polling запускается через updater await app.updater.start_polling(allowed_updates=allowed_updates) apps.append(app) log.info("Bot started: %s (@%s)", tb.name, tb.username or "—") # Ожидание сигнала остановки 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: # Windows pass 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")