From a68f605e50d4a533d2939123083aec47115e2778 Mon Sep 17 00:00:00 2001 From: Timm Date: Tue, 18 Oct 2022 00:45:20 +0200 Subject: [PATCH 1/3] Add attachments --- homeassistant/components/simplepush/const.py | 1 + homeassistant/components/simplepush/notify.py | 26 +++++++++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/simplepush/const.py b/homeassistant/components/simplepush/const.py index 6195a5fd1d98cc..101e7cb35fd773 100644 --- a/homeassistant/components/simplepush/const.py +++ b/homeassistant/components/simplepush/const.py @@ -6,6 +6,7 @@ DEFAULT_NAME: Final = "simplepush" DATA_HASS_CONFIG: Final = "simplepush_hass_config" +ATTR_ATTACHMENTS: Final = "attachments" ATTR_ENCRYPTED: Final = "encrypted" ATTR_EVENT: Final = "event" diff --git a/homeassistant/components/simplepush/notify.py b/homeassistant/components/simplepush/notify.py index b1c2eb5680ee8b..ef7b4bd5839a37 100644 --- a/homeassistant/components/simplepush/notify.py +++ b/homeassistant/components/simplepush/notify.py @@ -18,7 +18,7 @@ from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType -from .const import ATTR_EVENT, CONF_DEVICE_KEY, CONF_SALT, DOMAIN +from .const import ATTR_ATTACHMENTS, ATTR_EVENT, CONF_DEVICE_KEY, CONF_SALT, DOMAIN # Configuring Simplepush under the notify has been removed in 2022.9.0 PLATFORM_SCHEMA = BASE_PLATFORM_SCHEMA @@ -61,11 +61,26 @@ def send_message(self, message: str, **kwargs: Any) -> None: """Send a message to a Simplepush user.""" title = kwargs.get(ATTR_TITLE, ATTR_TITLE_DEFAULT) + attachments = None # event can now be passed in the service data event = None if data := kwargs.get(ATTR_DATA): event = data.get(ATTR_EVENT) + attachments_data = data.get(ATTR_ATTACHMENTS) + if isinstance(attachments_data, list) and attachments_data: + attachments = [] + for attachment in attachments_data: + if "attachment" in attachment and "thumbnail" in attachment: + attachments.append( + { + "video": attachment["attachment"], + "thumbnail": attachment["thumbnail"], + } + ) + elif "attachment" in attachment: + attachments.append(attachment["attachment"]) + # use event from config until YAML config is removed event = event or self._event @@ -77,10 +92,17 @@ def send_message(self, message: str, **kwargs: Any) -> None: salt=self._salt, title=title, message=message, + attachments=attachments, event=event, ) else: - send(key=self._device_key, title=title, message=message, event=event) + send( + key=self._device_key, + title=title, + message=message, + attachments=attachments, + event=event, + ) except BadRequest: _LOGGER.error("Bad request. Title or message are too long") From 8f879b380112dc2b64d8067bbcc307d54927a18c Mon Sep 17 00:00:00 2001 From: Timm Date: Wed, 19 Oct 2022 00:34:57 +0200 Subject: [PATCH 2/3] Add actions --- homeassistant/components/simplepush/const.py | 4 + homeassistant/components/simplepush/notify.py | 101 ++++++++++++++---- 2 files changed, 86 insertions(+), 19 deletions(-) diff --git a/homeassistant/components/simplepush/const.py b/homeassistant/components/simplepush/const.py index 101e7cb35fd773..48d8047831f671 100644 --- a/homeassistant/components/simplepush/const.py +++ b/homeassistant/components/simplepush/const.py @@ -6,9 +6,13 @@ DEFAULT_NAME: Final = "simplepush" DATA_HASS_CONFIG: Final = "simplepush_hass_config" +ATTR_ACTIONS: Final = "actions" ATTR_ATTACHMENTS: Final = "attachments" ATTR_ENCRYPTED: Final = "encrypted" ATTR_EVENT: Final = "event" +ATTR_FEEDBACK_ACTION_TIMEOUT: Final = "feedback_action_timeout" + +EVENT_ACTION_TRIGGERED: Final = "simplepush_action_triggered_event" CONF_DEVICE_KEY: Final = "device_key" CONF_SALT: Final = "salt" diff --git a/homeassistant/components/simplepush/notify.py b/homeassistant/components/simplepush/notify.py index ef7b4bd5839a37..15a861cd1149ec 100644 --- a/homeassistant/components/simplepush/notify.py +++ b/homeassistant/components/simplepush/notify.py @@ -4,7 +4,7 @@ import logging from typing import Any -from simplepush import BadRequest, UnknownError, send +from simplepush import BadRequest, FeedbackActionTimeout, UnknownError, async_send from homeassistant.components.notify import ( ATTR_DATA, @@ -15,10 +15,20 @@ ) from homeassistant.const import CONF_EVENT, CONF_PASSWORD from homeassistant.core import HomeAssistant +from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType -from .const import ATTR_ATTACHMENTS, ATTR_EVENT, CONF_DEVICE_KEY, CONF_SALT, DOMAIN +from .const import ( + ATTR_ACTIONS, + ATTR_ATTACHMENTS, + ATTR_EVENT, + ATTR_FEEDBACK_ACTION_TIMEOUT, + CONF_DEVICE_KEY, + CONF_SALT, + DOMAIN, + EVENT_ACTION_TRIGGERED, +) # Configuring Simplepush under the notify has been removed in 2022.9.0 PLATFORM_SCHEMA = BASE_PLATFORM_SCHEMA @@ -44,29 +54,53 @@ async def async_get_service( ) return None - return SimplePushNotificationService(discovery_info) + return SimplePushNotificationService(hass, discovery_info) class SimplePushNotificationService(BaseNotificationService): """Implementation of the notification service for Simplepush.""" - def __init__(self, config: dict[str, Any]) -> None: + def __init__(self, hass: HomeAssistant, config: dict[str, Any]) -> None: """Initialize the Simplepush notification service.""" + self.hass = hass + self.session = async_get_clientsession(hass) self._device_key: str = config[CONF_DEVICE_KEY] self._event: str | None = config.get(CONF_EVENT) self._password: str | None = config.get(CONF_PASSWORD) self._salt: str | None = config.get(CONF_SALT) - def send_message(self, message: str, **kwargs: Any) -> None: + async def async_send_message(self, message: str, **kwargs: Any) -> None: """Send a message to a Simplepush user.""" title = kwargs.get(ATTR_TITLE, ATTR_TITLE_DEFAULT) + actions = None + action_ids = {} attachments = None # event can now be passed in the service data event = None + feedback_action_timeout = None + if data := kwargs.get(ATTR_DATA): event = data.get(ATTR_EVENT) + actions_data = data.get(ATTR_ACTIONS) + if isinstance(actions_data, list) and actions_data: + actions = [] + for action in actions_data: + if "action" in action and "url" in action: + actions.append({"name": action["action"], "url": action["url"]}) + elif "action" in action: + actions.append(action["action"]) + if "id" in action: + action_ids.update({action["action"]: action["id"]}) + + try: + feedback_action_timeout = int( + data.get(ATTR_FEEDBACK_ACTION_TIMEOUT) + ) + except (ValueError, TypeError): + feedback_action_timeout = 60 + attachments_data = data.get(ATTR_ATTACHMENTS) if isinstance(attachments_data, list) and attachments_data: attachments = [] @@ -84,27 +118,56 @@ def send_message(self, message: str, **kwargs: Any) -> None: # use event from config until YAML config is removed event = event or self._event + def feedback_action_callback( + action_selected, action_selected_at, action_delivered_at, feedback_id + ): + payload = { + "action_selected": action_selected, + "action_selected_at": action_selected_at, + "action_delivered_at": action_delivered_at, + "feedback_id": feedback_id, + } + + if action_selected in action_ids: + payload.update({"id": action_ids[action_selected]}) + + self.hass.bus.async_fire(EVENT_ACTION_TRIGGERED, payload) + try: if self._password: - send( - key=self._device_key, - password=self._password, - salt=self._salt, - title=title, - message=message, - attachments=attachments, - event=event, + self.hass.async_create_task( + async_send( + key=self._device_key, + password=self._password, + salt=self._salt, + title=title, + message=message, + actions=actions, + attachments=attachments, + event=event, + feedback_callback=feedback_action_callback, + feedback_callback_timeout=feedback_action_timeout, + aiohttp_session=self.session, + ) ) else: - send( - key=self._device_key, - title=title, - message=message, - attachments=attachments, - event=event, + self.hass.async_create_task( + async_send( + key=self._device_key, + title=title, + message=message, + actions=actions, + attachments=attachments, + event=event, + feedback_callback=feedback_action_callback, + feedback_callback_timeout=feedback_action_timeout, + aiohttp_session=self.session, + ) ) except BadRequest: _LOGGER.error("Bad request. Title or message are too long") except UnknownError: _LOGGER.error("Failed to send the notification") + except FeedbackActionTimeout: + _LOGGER.error("Feedback action timed out") From 02da17926817968facd085d2b78d7fc6a1900a67 Mon Sep 17 00:00:00 2001 From: Timm Date: Wed, 26 Oct 2022 16:52:57 +0200 Subject: [PATCH 3/3] Remove attachments --- homeassistant/components/simplepush/const.py | 1 - homeassistant/components/simplepush/notify.py | 18 ------------------ 2 files changed, 19 deletions(-) diff --git a/homeassistant/components/simplepush/const.py b/homeassistant/components/simplepush/const.py index 48d8047831f671..fd630bcbffb530 100644 --- a/homeassistant/components/simplepush/const.py +++ b/homeassistant/components/simplepush/const.py @@ -7,7 +7,6 @@ DATA_HASS_CONFIG: Final = "simplepush_hass_config" ATTR_ACTIONS: Final = "actions" -ATTR_ATTACHMENTS: Final = "attachments" ATTR_ENCRYPTED: Final = "encrypted" ATTR_EVENT: Final = "event" ATTR_FEEDBACK_ACTION_TIMEOUT: Final = "feedback_action_timeout" diff --git a/homeassistant/components/simplepush/notify.py b/homeassistant/components/simplepush/notify.py index 15a861cd1149ec..99ef030879c0b3 100644 --- a/homeassistant/components/simplepush/notify.py +++ b/homeassistant/components/simplepush/notify.py @@ -21,7 +21,6 @@ from .const import ( ATTR_ACTIONS, - ATTR_ATTACHMENTS, ATTR_EVENT, ATTR_FEEDBACK_ACTION_TIMEOUT, CONF_DEVICE_KEY, @@ -75,7 +74,6 @@ async def async_send_message(self, message: str, **kwargs: Any) -> None: actions = None action_ids = {} - attachments = None # event can now be passed in the service data event = None feedback_action_timeout = None @@ -101,20 +99,6 @@ async def async_send_message(self, message: str, **kwargs: Any) -> None: except (ValueError, TypeError): feedback_action_timeout = 60 - attachments_data = data.get(ATTR_ATTACHMENTS) - if isinstance(attachments_data, list) and attachments_data: - attachments = [] - for attachment in attachments_data: - if "attachment" in attachment and "thumbnail" in attachment: - attachments.append( - { - "video": attachment["attachment"], - "thumbnail": attachment["thumbnail"], - } - ) - elif "attachment" in attachment: - attachments.append(attachment["attachment"]) - # use event from config until YAML config is removed event = event or self._event @@ -143,7 +127,6 @@ def feedback_action_callback( title=title, message=message, actions=actions, - attachments=attachments, event=event, feedback_callback=feedback_action_callback, feedback_callback_timeout=feedback_action_timeout, @@ -157,7 +140,6 @@ def feedback_action_callback( title=title, message=message, actions=actions, - attachments=attachments, event=event, feedback_callback=feedback_action_callback, feedback_callback_timeout=feedback_action_timeout,