mysmarthome/custom_components/telegram_bot/polling.py

99 lines
3.0 KiB
Python

"""Support for Telegram bot using polling."""
import logging
from telegram import Update
from telegram.error import NetworkError, RetryAfter, TelegramError, TimedOut
from telegram.ext import CallbackContext, Dispatcher, Handler, Updater
from telegram.utils.types import HandlerArg
from homeassistant.const import EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP
from . import CONF_ALLOWED_CHAT_IDS, BaseTelegramBotEntity, initialize_bot
_LOGGER = logging.getLogger(__name__)
async def async_setup_platform(hass, config):
"""Set up the Telegram polling platform."""
bot = initialize_bot(config)
pol = TelegramPoll(bot, hass, config[CONF_ALLOWED_CHAT_IDS])
def _start_bot(_event):
"""Start the bot."""
pol.start_polling()
def _stop_bot(_event):
"""Stop the bot."""
pol.stop_polling()
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_START, _start_bot)
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, _stop_bot)
return True
def process_error(update: Update, context: CallbackContext):
"""Telegram bot error handler."""
try:
raise context.error
except (TimedOut, NetworkError, RetryAfter):
# Long polling timeout or connection problem. Nothing serious.
pass
except TelegramError:
_LOGGER.error('Update "%s" caused error: "%s"', update, context.error)
def message_handler(handler):
"""Create messages handler."""
class MessageHandler(Handler):
"""Telegram bot message handler."""
def __init__(self):
"""Initialize the messages handler instance."""
super().__init__(handler)
def check_update(self, update):
"""Check is update valid."""
return isinstance(update, Update)
def handle_update(
self,
update: HandlerArg,
dispatcher: Dispatcher,
check_result: object,
context: CallbackContext = None,
):
"""Handle update."""
optional_args = self.collect_optional_args(dispatcher, update)
context.args = optional_args
return self.callback(update, context)
return MessageHandler()
class TelegramPoll(BaseTelegramBotEntity):
"""Asyncio telegram incoming message handler."""
def __init__(self, bot, hass, allowed_chat_ids):
"""Initialize the polling instance."""
BaseTelegramBotEntity.__init__(self, hass, allowed_chat_ids)
self.updater = Updater(bot=bot, workers=4)
self.dispatcher = self.updater.dispatcher
self.dispatcher.add_handler(message_handler(self.process_update))
self.dispatcher.add_error_handler(process_error)
def start_polling(self):
"""Start the polling task."""
self.updater.start_polling()
def stop_polling(self):
"""Stop the polling task."""
self.updater.stop()
def process_update(self, update: HandlerArg, context: CallbackContext):
"""Process incoming message."""
self.process_message(update.to_dict())