-
-
Notifications
You must be signed in to change notification settings - Fork 34.5k
Fix send telegram notification to multiple chats #144922
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -65,6 +65,7 @@ | |
ATTR_VERIFY_SSL, | ||
CONF_ALLOWED_CHAT_IDS, | ||
CONF_BOT_COUNT, | ||
CONF_CHAT_ID, | ||
CONF_CONFIG_ENTRY_ID, | ||
CONF_PROXY_PARAMS, | ||
CONF_PROXY_URL, | ||
|
@@ -320,15 +321,49 @@ async def async_send_telegram_message(service: ServiceCall) -> ServiceResponse: | |
service.hass.config_entries.async_entries(DOMAIN) | ||
) | ||
|
||
if len(config_entries) == 1: | ||
config_entry = config_entries[0] | ||
|
||
if len(config_entries) > 1: | ||
if len(config_entries) == 0: | ||
raise ServiceValidationError( | ||
"Multiple config entries found. Please specify the Telegram bot to use.", | ||
"No Telegram Bot config entries found. Please set up a Telegram Bot first.", | ||
translation_domain=DOMAIN, | ||
translation_key="multiple_config_entry", | ||
translation_key="no_config_entries", | ||
) | ||
if len(config_entries) == 1: | ||
config_entry = config_entries[0] | ||
else: | ||
# Multiple config entries: try to find matching bot | ||
target = kwargs.get(ATTR_TARGET) | ||
if target is not None: | ||
# Convert single target to list for consistent handling | ||
if isinstance(target, int): | ||
target = [target] | ||
|
||
# Find config entries that contain any of the target chat_ids | ||
matching_entries = [] | ||
for entry in config_entries: | ||
if hasattr(entry, "runtime_data") and entry.runtime_data: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you want to check that the bot is in a valid state then use |
||
entry_chat_ids = [ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here as well, we should use a set. Member checking between sets is much faster than between lists. |
||
subentry.data[CONF_CHAT_ID] | ||
for subentry in entry.subentries.values() | ||
] | ||
if any(chat_id in entry_chat_ids for chat_id in target): | ||
matching_entries.append(entry) | ||
|
||
if len(matching_entries) >= 1: | ||
# Use the first matching entry | ||
config_entry = matching_entries[0] | ||
else: | ||
raise ServiceValidationError( | ||
"No config entry found for the specified target chat IDs.", | ||
translation_domain=DOMAIN, | ||
translation_key="no_matching_target", | ||
) | ||
Comment on lines
+333
to
+359
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
e.g. Instead, remove There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, if there are more than one matching config entries found, we should raise ServiceValidationError as before. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just checking on the possible options:
Are we all in agreement item 3 needs to be done? Any decision on whether to go with item 1 or 2? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I guess you mean that we should send the message to all matching bots? This is about sending a message from Home Assistant to bots and not about receiving messages from bots, right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not following what should be done for 1. We want to differentiate between user errors and API errors. User errors, ie invalid service action input, should raise ServiceValidationError. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
My mistake, I forgot about the case where the target is not specified. Nevertheless, the logic in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Please disregard my comment. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I didn't fully understand: which of the proposed fixes is better? I don't have such a deep knowledge of HA There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What you have is fine. Also, there's mention about multiple bots with same chat IDs.
Your PR selects Bot A by default but the expected result should be a ServiceValidationError because we shouldn't make assumption that Bot A is the desired bot for sending the message. Thus, I think you can refine it like this:
The other issue is related to the default selection of the recipient (chat ID) handled in |
||
else: | ||
# No specific target: error out | ||
raise ServiceValidationError( | ||
"Multiple config entries found. Please specify the Telegram bot to use.", | ||
translation_domain=DOMAIN, | ||
translation_key="multiple_config_entry", | ||
) | ||
|
||
if not config_entry or not hasattr(config_entry, "runtime_data"): | ||
raise ServiceValidationError( | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should always convert to a set instead of a list.