"""Support for Telegram bot using polling.""" import logging from telegram import Bot, Update from telegram.error import NetworkError, RetryAfter, TelegramError, TimedOut from telegram.ext import ApplicationBuilder, CallbackContext, TypeHandler from homeassistant.core import HomeAssistant from .bot import BaseTelegramBot, TelegramBotConfigEntry _LOGGER = logging.getLogger(__name__) async def async_setup_platform( hass: HomeAssistant, bot: Bot, config: TelegramBotConfigEntry ) -> BaseTelegramBot | None: """Set up the Telegram polling platform.""" pollbot = PollBot(hass, bot, config) await pollbot.start_polling() return pollbot async def process_error(update: object, context: CallbackContext) -> None: """Telegram bot error handler.""" if context.error: error_callback(context.error, update) def error_callback(error: Exception, update: object | None = None) -> None: """Log the error.""" try: raise error except (TimedOut, NetworkError, RetryAfter): # Long polling timeout or connection problem. Nothing serious. pass except TelegramError: if update is not None: _LOGGER.error('Update "%s" caused error: "%s"', update, error) else: _LOGGER.error("%s: %s", error.__class__.__name__, error) class PollBot(BaseTelegramBot): """Controls the Application object that holds the bot and an updater. The application is set up to pass telegram updates to `self.handle_update` """ def __init__( self, hass: HomeAssistant, bot: Bot, config: TelegramBotConfigEntry ) -> None: """Create Application to poll for updates.""" super().__init__(hass, config, bot) self.bot = bot self.application = ApplicationBuilder().bot(self.bot).build() self.application.add_handler(TypeHandler(Update, self.handle_update)) self.application.add_error_handler(process_error) async def shutdown(self) -> None: """Shutdown the app.""" await self.stop_polling() async def start_polling(self) -> None: """Start the polling task.""" _LOGGER.debug("Starting polling") await self.application.initialize() if self.application.updater: await self.application.updater.start_polling(error_callback=error_callback) await self.application.start() async def stop_polling(self) -> None: """Stop the polling task.""" _LOGGER.debug("Stopping polling") if self.application.updater: await self.application.updater.stop() await self.application.stop() await self.application.shutdown()