diff --git a/README.md b/README.md index d58aa33..dafaea0 100644 --- a/README.md +++ b/README.md @@ -186,6 +186,21 @@ data: parse_mode: "HTML" # Default, can be omitted ``` +Non-blocking mode (fire-and-forget): + +```yaml +service: immich_album_watcher.send_telegram_notification +target: + entity_id: sensor.album_name_asset_count +data: + chat_id: "-1001234567890" + urls: + - url: "https://immich.example.com/api/assets/xxx/thumbnail?key=yyy" + type: photo + caption: "Quick notification" + wait_for_response: false # Automation continues immediately +``` + | Field | Description | Required | |-------|-------------|----------| | `chat_id` | Telegram chat ID to send to | Yes | @@ -197,8 +212,9 @@ data: | `parse_mode` | How to parse caption/text. Options: `HTML`, `Markdown`, `MarkdownV2`, or empty string for plain text. Default: `HTML` | No | | `max_group_size` | Maximum media items per group (2-10). Large lists split into multiple groups. Default: 10 | No | | `chunk_delay` | Delay in milliseconds between sending multiple groups (0-60000). Useful for rate limiting. Default: 0 | No | +| `wait_for_response` | Wait for Telegram to finish processing. Set to `false` for fire-and-forget (automation continues immediately). Default: `true` | No | -The service returns a response with `success` status and `message_id` (single message), `message_ids` (media group), or `groups_sent` (number of groups when split). +The service returns a response with `success` status and `message_id` (single message), `message_ids` (media group), or `groups_sent` (number of groups when split). When `wait_for_response` is `false`, the service returns immediately with `{"success": true, "status": "queued"}` while processing continues in the background. ## Events diff --git a/custom_components/immich_album_watcher/sensor.py b/custom_components/immich_album_watcher/sensor.py index c3cfb17..93a08fb 100644 --- a/custom_components/immich_album_watcher/sensor.py +++ b/custom_components/immich_album_watcher/sensor.py @@ -114,9 +114,10 @@ async def async_setup_entry( vol.Optional("chunk_delay", default=0): vol.All( vol.Coerce(int), vol.Range(min=0, max=60000) ), + vol.Optional("wait_for_response", default=True): bool, }, "async_send_telegram_notification", - supports_response=SupportsResponse.ONLY, + supports_response=SupportsResponse.OPTIONAL, ) @@ -186,6 +187,7 @@ class ImmichAlbumBaseSensor(CoordinatorEntity[ImmichAlbumWatcherCoordinator], Se parse_mode: str = "HTML", max_group_size: int = 10, chunk_delay: int = 0, + wait_for_response: bool = True, ) -> ServiceResponse: """Send notification to Telegram. @@ -197,7 +199,53 @@ class ImmichAlbumBaseSensor(CoordinatorEntity[ImmichAlbumWatcherCoordinator], Se Each item in urls should be a dict with 'url' and 'type' (photo/video). Downloads media and uploads to Telegram to bypass CORS restrictions. + + If wait_for_response is False, the task will be executed in the background + and the service will return immediately. """ + # If non-blocking mode, create a background task and return immediately + if not wait_for_response: + self.hass.async_create_task( + self._execute_telegram_notification( + chat_id=chat_id, + urls=urls, + bot_token=bot_token, + caption=caption, + reply_to_message_id=reply_to_message_id, + disable_web_page_preview=disable_web_page_preview, + parse_mode=parse_mode, + max_group_size=max_group_size, + chunk_delay=chunk_delay, + ) + ) + return {"success": True, "status": "queued", "message": "Notification queued for background processing"} + + # Blocking mode - execute and return result + return await self._execute_telegram_notification( + chat_id=chat_id, + urls=urls, + bot_token=bot_token, + caption=caption, + reply_to_message_id=reply_to_message_id, + disable_web_page_preview=disable_web_page_preview, + parse_mode=parse_mode, + max_group_size=max_group_size, + chunk_delay=chunk_delay, + ) + + async def _execute_telegram_notification( + self, + chat_id: str, + urls: list[dict[str, str]] | None = None, + bot_token: str | None = None, + caption: str | None = None, + reply_to_message_id: int | None = None, + disable_web_page_preview: bool | None = None, + parse_mode: str = "HTML", + max_group_size: int = 10, + chunk_delay: int = 0, + ) -> ServiceResponse: + """Execute the Telegram notification (internal method).""" import json import aiohttp from aiohttp import FormData diff --git a/custom_components/immich_album_watcher/services.yaml b/custom_components/immich_album_watcher/services.yaml index d0f3690..618ee30 100644 --- a/custom_components/immich_album_watcher/services.yaml +++ b/custom_components/immich_album_watcher/services.yaml @@ -109,3 +109,10 @@ send_telegram_notification: step: 100 unit_of_measurement: "ms" mode: slider + wait_for_response: + name: Wait For Response + description: Wait for Telegram to finish processing before returning. Set to false for fire-and-forget (automation continues immediately). + required: false + default: true + selector: + boolean: diff --git a/custom_components/immich_album_watcher/translations/en.json b/custom_components/immich_album_watcher/translations/en.json index 66df4ae..ef45e30 100644 --- a/custom_components/immich_album_watcher/translations/en.json +++ b/custom_components/immich_album_watcher/translations/en.json @@ -182,6 +182,10 @@ "chunk_delay": { "name": "Chunk Delay", "description": "Delay in milliseconds between sending multiple media groups (0-60000). Useful for rate limiting." + }, + "wait_for_response": { + "name": "Wait For Response", + "description": "Wait for Telegram to finish processing before returning. Set to false for fire-and-forget (automation continues immediately)." } } } diff --git a/custom_components/immich_album_watcher/translations/ru.json b/custom_components/immich_album_watcher/translations/ru.json index 74627f5..e75f475 100644 --- a/custom_components/immich_album_watcher/translations/ru.json +++ b/custom_components/immich_album_watcher/translations/ru.json @@ -182,6 +182,10 @@ "chunk_delay": { "name": "Задержка между группами", "description": "Задержка в миллисекундах между отправкой нескольких медиа-групп (0-60000). Полезно для ограничения скорости." + }, + "wait_for_response": { + "name": "Ждать ответа", + "description": "Ждать завершения отправки в Telegram перед возвратом. Установите false для фоновой отправки (автоматизация продолжается немедленно)." } } }