"""Telegram bot client — stub implementation. Replace with python-telegram-bot or aiogram when TELEGRAM_BOT_TOKEN is set. """ from __future__ import annotations import logging from typing import Any logger = logging.getLogger("voidea.telegram.bot") class TelegramBotClient: """Stub Telegram bot client. All methods log instead of calling Telegram API. Replace with real implementation when TELEGRAM_BOT_TOKEN is configured. """ def __init__(self, token: str | None = None): self.token = token self.available = bool(token) if self.available: logger.info("Telegram bot client initialized with token") else: logger.warning("TELEGRAM_BOT_TOKEN not set — bot is in stub mode") async def send_message( self, chat_id: int | str, text: str, parse_mode: str = "HTML", reply_markup: dict[str, Any] | None = None, ) -> dict[str, Any] | None: """Send a message to a Telegram chat.""" if not self.available: logger.info("[STUB] send_message to %s: %s", chat_id, text[:80]) return None # TODO: real Telegram API call logger.info("send_message to %s: %s", chat_id, text[:80]) return {"ok": True} async def send_voice( self, chat_id: int | str, voice_url: str, ) -> dict[str, Any] | None: """Send a voice message.""" if not self.available: logger.info("[STUB] send_voice to %s: %s", chat_id, voice_url[:80]) return None logger.info("send_voice to %s: %s", chat_id, voice_url[:80]) return {"ok": True} async def set_webhook(self, url: str) -> bool: """Set the Telegram bot webhook URL.""" if not self.available: logger.info("[STUB] set_webhook: %s", url) return False logger.info("set_webhook: %s", url) return True async def delete_webhook(self) -> bool: """Remove the webhook.""" if not self.available: logger.info("[STUB] delete_webhook") return False return True async def set_commands(self, commands: list[dict[str, str]]) -> bool: """Register bot commands with Telegram.""" if not self.available: logger.info("[STUB] set_commands: %s", [c["command"] for c in commands]) return False logger.info("set_commands: %d commands", len(commands)) return True