from __future__ import annotations import asyncio import logging from yuxi.channel.extensions.telegram.config import TelegramConfigAdapter from yuxi.channel.extensions.telegram.polling import TelegramPolling logger = logging.getLogger(__name__) class TelegramGateway: def __init__(self): self._config_adapter = TelegramConfigAdapter() self._polling = TelegramPolling() self._tasks: list[asyncio.Task] = [] self._running = False self._queue: asyncio.Queue | None = None self._abort_event: asyncio.Event | None = None self._account: dict = {} async def start(self, ctx) -> object: account = await self._resolve_account(ctx) self._account = account if not account.get("token"): logger.warning("telegram account %s not configured, skipping start", account.get("account_id")) return {"running": False, "reason": "not-configured"} self._queue = asyncio.Queue(maxsize=1000) self._abort_event = asyncio.Event() self._running = True webhook_url = account.get("webhook_url", "") if webhook_url: task = asyncio.create_task( self._start_webhook_mode(account, self._queue, self._abort_event) ) else: task = asyncio.create_task( self._polling.start(account, self._queue, self._abort_event) ) self._tasks.append(task) logger.info("telegram gateway started for account %s (mode=%s)", account.get("account_id"), "webhook" if webhook_url else "polling") return {"running": True, "account_id": account.get("account_id"), "queue": self._queue} async def stop(self, ctx) -> None: self._running = False if self._abort_event: self._abort_event.set() await self._polling.stop() for task in self._tasks: task.cancel() self._tasks.clear() if self._account.get("webhook_url"): from yuxi.channel.extensions.telegram.webhook import stop_webhook await stop_webhook(self._account) from yuxi.channel.extensions.telegram.outbound import TelegramOutbound await TelegramOutbound.close_client() self._queue = None self._abort_event = None self._account = {} logger.info("telegram gateway stopped") async def _start_webhook_mode(self, account: dict, queue: asyncio.Queue, abort_event: asyncio.Event) -> None: from yuxi.channel.extensions.telegram.webhook import start_webhook await start_webhook(account, queue) while not abort_event.is_set(): await asyncio.sleep(1) async def _resolve_account(self, ctx) -> dict: config = getattr(ctx, "config", {}) if ctx else {} account_id = getattr(ctx, "account_id", "default") self._config_adapter.list_account_ids(config) return await self._config_adapter.resolve_account(account_id)