Add non-blocking mode support to Telegram notification service
All checks were successful
Validate / Hassfest (push) Successful in 3s
All checks were successful
Validate / Hassfest (push) Successful in 3s
- Add `wait_for_response` parameter (default: true) for fire-and-forget operation - Change supports_response to OPTIONAL to allow both modes - Refactor execution logic into `_execute_telegram_notification` method - Background tasks created with `hass.async_create_task` when wait_for_response=false - Update documentation with non-blocking mode example and response behavior Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
18
README.md
18
README.md
@@ -186,6 +186,21 @@ data:
|
|||||||
parse_mode: "HTML" # Default, can be omitted
|
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 |
|
| Field | Description | Required |
|
||||||
|-------|-------------|----------|
|
|-------|-------------|----------|
|
||||||
| `chat_id` | Telegram chat ID to send to | Yes |
|
| `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 |
|
| `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 |
|
| `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 |
|
| `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
|
## Events
|
||||||
|
|
||||||
|
|||||||
@@ -114,9 +114,10 @@ async def async_setup_entry(
|
|||||||
vol.Optional("chunk_delay", default=0): vol.All(
|
vol.Optional("chunk_delay", default=0): vol.All(
|
||||||
vol.Coerce(int), vol.Range(min=0, max=60000)
|
vol.Coerce(int), vol.Range(min=0, max=60000)
|
||||||
),
|
),
|
||||||
|
vol.Optional("wait_for_response", default=True): bool,
|
||||||
},
|
},
|
||||||
"async_send_telegram_notification",
|
"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",
|
parse_mode: str = "HTML",
|
||||||
max_group_size: int = 10,
|
max_group_size: int = 10,
|
||||||
chunk_delay: int = 0,
|
chunk_delay: int = 0,
|
||||||
|
wait_for_response: bool = True,
|
||||||
) -> ServiceResponse:
|
) -> ServiceResponse:
|
||||||
"""Send notification to Telegram.
|
"""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).
|
Each item in urls should be a dict with 'url' and 'type' (photo/video).
|
||||||
Downloads media and uploads to Telegram to bypass CORS restrictions.
|
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 json
|
||||||
import aiohttp
|
import aiohttp
|
||||||
from aiohttp import FormData
|
from aiohttp import FormData
|
||||||
|
|||||||
@@ -109,3 +109,10 @@ send_telegram_notification:
|
|||||||
step: 100
|
step: 100
|
||||||
unit_of_measurement: "ms"
|
unit_of_measurement: "ms"
|
||||||
mode: slider
|
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:
|
||||||
|
|||||||
@@ -182,6 +182,10 @@
|
|||||||
"chunk_delay": {
|
"chunk_delay": {
|
||||||
"name": "Chunk Delay",
|
"name": "Chunk Delay",
|
||||||
"description": "Delay in milliseconds between sending multiple media groups (0-60000). Useful for rate limiting."
|
"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)."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -182,6 +182,10 @@
|
|||||||
"chunk_delay": {
|
"chunk_delay": {
|
||||||
"name": "Задержка между группами",
|
"name": "Задержка между группами",
|
||||||
"description": "Задержка в миллисекундах между отправкой нескольких медиа-групп (0-60000). Полезно для ограничения скорости."
|
"description": "Задержка в миллисекундах между отправкой нескольких медиа-групп (0-60000). Полезно для ограничения скорости."
|
||||||
|
},
|
||||||
|
"wait_for_response": {
|
||||||
|
"name": "Ждать ответа",
|
||||||
|
"description": "Ждать завершения отправки в Telegram перед возвратом. Установите false для фоновой отправки (автоматизация продолжается немедленно)."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user