From 1f44afcd45e3a017b8c5f681dc39a160617018ce Mon Sep 17 00:00:00 2001 From: hanwg Date: Sat, 10 May 2025 10:37:53 +0000 Subject: [PATCH] added config flow for telegram integration --- homeassistant/components/telegram/__init__.py | 53 +++++++++++++++++-- .../components/telegram/config_flow.py | 50 +++++++++++++++++ homeassistant/components/telegram/const.py | 6 +++ .../components/telegram/manifest.json | 1 + homeassistant/components/telegram/notify.py | 17 +++--- .../components/telegram/strings.json | 19 +++++++ homeassistant/generated/config_flows.py | 1 + homeassistant/generated/integrations.json | 2 +- 8 files changed, 139 insertions(+), 10 deletions(-) create mode 100644 homeassistant/components/telegram/config_flow.py create mode 100644 homeassistant/components/telegram/const.py diff --git a/homeassistant/components/telegram/__init__.py b/homeassistant/components/telegram/__init__.py index fe0b8d98530..7897f03e44d 100644 --- a/homeassistant/components/telegram/__init__.py +++ b/homeassistant/components/telegram/__init__.py @@ -1,6 +1,53 @@ """The telegram component.""" -from homeassistant.const import Platform +from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry +from homeassistant.const import CONF_NAME, CONF_PLATFORM, CONF_SOURCE, Platform +from homeassistant.core import HomeAssistant +from homeassistant.helpers import config_validation as cv, discovery +from homeassistant.helpers.typing import ConfigType -DOMAIN = "telegram" -PLATFORMS = [Platform.NOTIFY] +from .const import DOMAIN +from .notify import CONF_CHAT_ID + +CONFIG_SCHEMA = cv.config_entry_only_config_schema(DOMAIN) + + +async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: + """Pass notify platform config from configuration.yaml to config flow for import.""" + for notify in config[Platform.NOTIFY]: + if notify[CONF_PLATFORM] == DOMAIN: # Only import Telegram notifiers + hass.async_create_task( + hass.config_entries.flow.async_init( + DOMAIN, + context={CONF_SOURCE: SOURCE_IMPORT}, + data={ + CONF_NAME: notify[CONF_NAME], + CONF_CHAT_ID: notify[CONF_CHAT_ID], + }, + ) + ) + + return True + + +async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: + """Set up notifier from a config entry.""" + + await discovery.async_load_platform( + hass, + Platform.NOTIFY, + DOMAIN, + { + CONF_NAME: entry.data[CONF_NAME], + CONF_CHAT_ID: entry.data[CONF_CHAT_ID], + }, + {}, + ) + + return True + + +async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: + """Unload the notifier.""" + hass.services.async_remove(Platform.NOTIFY, entry.data[CONF_NAME]) + return True diff --git a/homeassistant/components/telegram/config_flow.py b/homeassistant/components/telegram/config_flow.py new file mode 100644 index 00000000000..3db5c26a9ab --- /dev/null +++ b/homeassistant/components/telegram/config_flow.py @@ -0,0 +1,50 @@ +"""Config flow for Telegram.""" + +from typing import Any + +import voluptuous as vol + +from homeassistant.config_entries import ConfigFlow, ConfigFlowResult +from homeassistant.const import CONF_NAME + +from . import DOMAIN +from .notify import CONF_CHAT_ID + + +class TelgramConfigFlow(ConfigFlow, domain=DOMAIN): + """Handle a config flow for Telegram.""" + + VERSION = 1 + + # triggered by async_setup() from __init__.py + async def async_step_import(self, import_data: dict[str, str]) -> ConfigFlowResult: + """Handle import of config entry from configuration.yaml.""" + return await self.async_step_user(import_data) + + async def async_step_user( + self, user_input: dict[str, Any] | None = None + ) -> ConfigFlowResult: + """Handle a flow initiated by the user.""" + errors: dict[str, str] = {} + if user_input is not None: + await self.async_set_unique_id(f"{user_input[CONF_NAME]}") + self._abort_if_unique_id_configured() + + return self.async_create_entry( + title=user_input[CONF_NAME], + data={ + CONF_NAME: user_input[CONF_NAME], + CONF_CHAT_ID: user_input[CONF_CHAT_ID], + }, + ) + + return self.async_show_form( + step_id="user", + data_schema=vol.Schema( + { + vol.Required(CONF_NAME): str, + vol.Required(CONF_CHAT_ID): vol.Coerce(int), + } + ), + errors=errors, + ) diff --git a/homeassistant/components/telegram/const.py b/homeassistant/components/telegram/const.py new file mode 100644 index 00000000000..3b1c26a788f --- /dev/null +++ b/homeassistant/components/telegram/const.py @@ -0,0 +1,6 @@ +"""Constants for the Telegram integration.""" + +from homeassistant.const import Platform + +DOMAIN = "telegram" +PLATFORMS = [Platform.NOTIFY] diff --git a/homeassistant/components/telegram/manifest.json b/homeassistant/components/telegram/manifest.json index 9022f357970..861207072c1 100644 --- a/homeassistant/components/telegram/manifest.json +++ b/homeassistant/components/telegram/manifest.json @@ -2,6 +2,7 @@ "domain": "telegram", "name": "Telegram", "codeowners": [], + "config_flow": true, "dependencies": ["telegram_bot"], "documentation": "https://www.home-assistant.io/integrations/telegram", "iot_class": "cloud_polling", diff --git a/homeassistant/components/telegram/notify.py b/homeassistant/components/telegram/notify.py index adb947bcf6b..98c1d41236b 100644 --- a/homeassistant/components/telegram/notify.py +++ b/homeassistant/components/telegram/notify.py @@ -3,6 +3,7 @@ from __future__ import annotations import logging +from typing import Any import voluptuous as vol @@ -26,7 +27,7 @@ from homeassistant.core import HomeAssistant from homeassistant.helpers.reload import setup_reload_service from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType -from . import DOMAIN as TELEGRAM_DOMAIN, PLATFORMS +from .const import DOMAIN as TELEGRAM_DOMAIN, PLATFORMS _LOGGER = logging.getLogger(__name__) @@ -48,19 +49,23 @@ PLATFORM_SCHEMA = NOTIFY_PLATFORM_SCHEMA.extend( def get_service( hass: HomeAssistant, config: ConfigType, - discovery_info: DiscoveryInfoType | None = None, + discovery_info: DiscoveryInfoType | None, ) -> TelegramNotificationService: """Get the Telegram notification service.""" - setup_reload_service(hass, TELEGRAM_DOMAIN, PLATFORMS) - chat_id = config.get(CONF_CHAT_ID) - return TelegramNotificationService(hass, chat_id) + + # chat_id can either come from configuration.yaml or from discovery (config flow) + chat_id: Any = ( + discovery_info[CONF_CHAT_ID] if discovery_info else config.get(CONF_CHAT_ID) + ) + + return TelegramNotificationService(hass, int(chat_id)) class TelegramNotificationService(BaseNotificationService): """Implement the notification service for Telegram.""" - def __init__(self, hass, chat_id): + def __init__(self, hass: HomeAssistant, chat_id: int) -> None: """Initialize the service.""" self._chat_id = chat_id self.hass = hass diff --git a/homeassistant/components/telegram/strings.json b/homeassistant/components/telegram/strings.json index 34a98f908dc..b3c8d98d72a 100644 --- a/homeassistant/components/telegram/strings.json +++ b/homeassistant/components/telegram/strings.json @@ -4,5 +4,24 @@ "name": "[%key:common::action::reload%]", "description": "Reloads telegram notify services." } + }, + "config": { + "step": { + "user": { + "data": { + "name": "Notifier name", + "chat_id": "Chat ID" + }, + "data_description": { + "name": "The name of the notifier.", + "chat_id": "The Telegram chat ID." + }, + "description": "Please enter the notifier information", + "title": "Notifier setup" + } + }, + "abort": { + "already_configured": "[%key:common::config_flow::abort::already_configured_service%]" + } } } diff --git a/homeassistant/generated/config_flows.py b/homeassistant/generated/config_flows.py index 8174dfc60b1..dc424385eef 100644 --- a/homeassistant/generated/config_flows.py +++ b/homeassistant/generated/config_flows.py @@ -630,6 +630,7 @@ FLOWS = { "tautulli", "technove", "tedee", + "telegram", "tellduslive", "tesla_fleet", "tesla_wall_connector", diff --git a/homeassistant/generated/integrations.json b/homeassistant/generated/integrations.json index 5e97e4c6626..8a96a9fcfe5 100644 --- a/homeassistant/generated/integrations.json +++ b/homeassistant/generated/integrations.json @@ -6535,7 +6535,7 @@ "integrations": { "telegram": { "integration_type": "hub", - "config_flow": false, + "config_flow": true, "iot_class": "cloud_polling", "name": "Telegram" },