Add support for sending telegram messages to topics (#112715)
* Add support for sending telegram messages to topics Based on original PR #104059 by [jgresty](https://github.com/jgresty). Did not manage to merge conflicts, so I remade the changes from scratch, including suggestions from previous PR reviews. Topics were added to telegram groups in November 2022, and to the telegram-bot library in version 20.0. They are a purely additive change that is exposed by a single parameter `message_thread_id`. Not passing this parameter will not change the behaviour from current. This same parameter is used to send messages to threads and messages to topics inside groups. https://telegram.org/blog/topics-in-groups-collectible-usernames/it?setln=en#topics-in-groups Fixes #81888 Fixes #91750 * telegram_bot: add tests for threads feature. * telegram_bot: fixed tests for threads. * telegram_bot: fixed wrong line. * Update test_telegram_bot.py --------- Co-authored-by: J. Nick Koston <nick@koston.org> Co-authored-by: Erik Montnemery <erik@montnemery.com>
This commit is contained in:
parent
862c04a4b6
commit
0487b38ed3
5 changed files with 117 additions and 1 deletions
|
@ -18,6 +18,7 @@ from homeassistant.components.telegram_bot import (
|
|||
ATTR_DISABLE_NOTIF,
|
||||
ATTR_DISABLE_WEB_PREV,
|
||||
ATTR_MESSAGE_TAG,
|
||||
ATTR_MESSAGE_THREAD_ID,
|
||||
ATTR_PARSER,
|
||||
)
|
||||
from homeassistant.const import ATTR_LOCATION
|
||||
|
@ -91,6 +92,11 @@ class TelegramNotificationService(BaseNotificationService):
|
|||
disable_web_page_preview = data[ATTR_DISABLE_WEB_PREV]
|
||||
service_data.update({ATTR_DISABLE_WEB_PREV: disable_web_page_preview})
|
||||
|
||||
# Set message_thread_id
|
||||
if data is not None and ATTR_MESSAGE_THREAD_ID in data:
|
||||
message_thread_id = data[ATTR_MESSAGE_THREAD_ID]
|
||||
service_data.update({ATTR_MESSAGE_THREAD_ID: message_thread_id})
|
||||
|
||||
# Get keyboard info
|
||||
if data is not None and ATTR_KEYBOARD in data:
|
||||
keys = data.get(ATTR_KEYBOARD)
|
||||
|
|
|
@ -90,6 +90,7 @@ ATTR_ANSWERS = "answers"
|
|||
ATTR_OPEN_PERIOD = "open_period"
|
||||
ATTR_IS_ANONYMOUS = "is_anonymous"
|
||||
ATTR_ALLOWS_MULTIPLE_ANSWERS = "allows_multiple_answers"
|
||||
ATTR_MESSAGE_THREAD_ID = "message_thread_id"
|
||||
|
||||
CONF_ALLOWED_CHAT_IDS = "allowed_chat_ids"
|
||||
CONF_PROXY_URL = "proxy_url"
|
||||
|
@ -639,6 +640,7 @@ class TelegramNotificationService:
|
|||
ATTR_REPLYMARKUP: None,
|
||||
ATTR_TIMEOUT: None,
|
||||
ATTR_MESSAGE_TAG: None,
|
||||
ATTR_MESSAGE_THREAD_ID: None,
|
||||
}
|
||||
if data is not None:
|
||||
if ATTR_PARSER in data:
|
||||
|
@ -655,6 +657,8 @@ class TelegramNotificationService:
|
|||
params[ATTR_REPLY_TO_MSGID] = data[ATTR_REPLY_TO_MSGID]
|
||||
if ATTR_MESSAGE_TAG in data:
|
||||
params[ATTR_MESSAGE_TAG] = data[ATTR_MESSAGE_TAG]
|
||||
if ATTR_MESSAGE_THREAD_ID in data:
|
||||
params[ATTR_MESSAGE_THREAD_ID] = data[ATTR_MESSAGE_THREAD_ID]
|
||||
# Keyboards:
|
||||
if ATTR_KEYBOARD in data:
|
||||
keys = data.get(ATTR_KEYBOARD)
|
||||
|
@ -698,6 +702,10 @@ class TelegramNotificationService:
|
|||
}
|
||||
if message_tag is not None:
|
||||
event_data[ATTR_MESSAGE_TAG] = message_tag
|
||||
if kwargs_msg[ATTR_MESSAGE_THREAD_ID] is not None:
|
||||
event_data[ATTR_MESSAGE_THREAD_ID] = kwargs_msg[
|
||||
ATTR_MESSAGE_THREAD_ID
|
||||
]
|
||||
self.hass.bus.async_fire(
|
||||
EVENT_TELEGRAM_SENT, event_data, context=context
|
||||
)
|
||||
|
@ -731,6 +739,7 @@ class TelegramNotificationService:
|
|||
reply_to_message_id=params[ATTR_REPLY_TO_MSGID],
|
||||
reply_markup=params[ATTR_REPLYMARKUP],
|
||||
read_timeout=params[ATTR_TIMEOUT],
|
||||
message_thread_id=params[ATTR_MESSAGE_THREAD_ID],
|
||||
context=context,
|
||||
)
|
||||
|
||||
|
@ -864,6 +873,7 @@ class TelegramNotificationService:
|
|||
reply_markup=params[ATTR_REPLYMARKUP],
|
||||
read_timeout=params[ATTR_TIMEOUT],
|
||||
parse_mode=params[ATTR_PARSER],
|
||||
message_thread_id=params[ATTR_MESSAGE_THREAD_ID],
|
||||
context=context,
|
||||
)
|
||||
|
||||
|
@ -878,6 +888,7 @@ class TelegramNotificationService:
|
|||
reply_to_message_id=params[ATTR_REPLY_TO_MSGID],
|
||||
reply_markup=params[ATTR_REPLYMARKUP],
|
||||
read_timeout=params[ATTR_TIMEOUT],
|
||||
message_thread_id=params[ATTR_MESSAGE_THREAD_ID],
|
||||
context=context,
|
||||
)
|
||||
|
||||
|
@ -894,6 +905,7 @@ class TelegramNotificationService:
|
|||
reply_markup=params[ATTR_REPLYMARKUP],
|
||||
read_timeout=params[ATTR_TIMEOUT],
|
||||
parse_mode=params[ATTR_PARSER],
|
||||
message_thread_id=params[ATTR_MESSAGE_THREAD_ID],
|
||||
context=context,
|
||||
)
|
||||
elif file_type == SERVICE_SEND_DOCUMENT:
|
||||
|
@ -909,6 +921,7 @@ class TelegramNotificationService:
|
|||
reply_markup=params[ATTR_REPLYMARKUP],
|
||||
read_timeout=params[ATTR_TIMEOUT],
|
||||
parse_mode=params[ATTR_PARSER],
|
||||
message_thread_id=params[ATTR_MESSAGE_THREAD_ID],
|
||||
context=context,
|
||||
)
|
||||
elif file_type == SERVICE_SEND_VOICE:
|
||||
|
@ -923,6 +936,7 @@ class TelegramNotificationService:
|
|||
reply_to_message_id=params[ATTR_REPLY_TO_MSGID],
|
||||
reply_markup=params[ATTR_REPLYMARKUP],
|
||||
read_timeout=params[ATTR_TIMEOUT],
|
||||
message_thread_id=params[ATTR_MESSAGE_THREAD_ID],
|
||||
context=context,
|
||||
)
|
||||
elif file_type == SERVICE_SEND_ANIMATION:
|
||||
|
@ -938,6 +952,7 @@ class TelegramNotificationService:
|
|||
reply_markup=params[ATTR_REPLYMARKUP],
|
||||
read_timeout=params[ATTR_TIMEOUT],
|
||||
parse_mode=params[ATTR_PARSER],
|
||||
message_thread_id=params[ATTR_MESSAGE_THREAD_ID],
|
||||
context=context,
|
||||
)
|
||||
|
||||
|
@ -961,6 +976,7 @@ class TelegramNotificationService:
|
|||
reply_to_message_id=params[ATTR_REPLY_TO_MSGID],
|
||||
reply_markup=params[ATTR_REPLYMARKUP],
|
||||
read_timeout=params[ATTR_TIMEOUT],
|
||||
message_thread_id=params[ATTR_MESSAGE_THREAD_ID],
|
||||
context=context,
|
||||
)
|
||||
else:
|
||||
|
@ -987,6 +1003,7 @@ class TelegramNotificationService:
|
|||
disable_notification=params[ATTR_DISABLE_NOTIF],
|
||||
reply_to_message_id=params[ATTR_REPLY_TO_MSGID],
|
||||
read_timeout=params[ATTR_TIMEOUT],
|
||||
message_thread_id=params[ATTR_MESSAGE_THREAD_ID],
|
||||
context=context,
|
||||
)
|
||||
|
||||
|
@ -1018,6 +1035,7 @@ class TelegramNotificationService:
|
|||
disable_notification=params[ATTR_DISABLE_NOTIF],
|
||||
reply_to_message_id=params[ATTR_REPLY_TO_MSGID],
|
||||
read_timeout=params[ATTR_TIMEOUT],
|
||||
message_thread_id=params[ATTR_MESSAGE_THREAD_ID],
|
||||
context=context,
|
||||
)
|
||||
|
||||
|
|
|
@ -54,6 +54,10 @@ send_message:
|
|||
selector:
|
||||
number:
|
||||
mode: box
|
||||
message_thread_id:
|
||||
selector:
|
||||
number:
|
||||
mode: box
|
||||
|
||||
send_photo:
|
||||
fields:
|
||||
|
@ -126,6 +130,10 @@ send_photo:
|
|||
selector:
|
||||
number:
|
||||
mode: box
|
||||
message_thread_id:
|
||||
selector:
|
||||
number:
|
||||
mode: box
|
||||
|
||||
send_sticker:
|
||||
fields:
|
||||
|
@ -190,6 +198,10 @@ send_sticker:
|
|||
selector:
|
||||
number:
|
||||
mode: box
|
||||
message_thread_id:
|
||||
selector:
|
||||
number:
|
||||
mode: box
|
||||
|
||||
send_animation:
|
||||
fields:
|
||||
|
@ -262,6 +274,10 @@ send_animation:
|
|||
selector:
|
||||
number:
|
||||
mode: box
|
||||
message_thread_id:
|
||||
selector:
|
||||
number:
|
||||
mode: box
|
||||
|
||||
send_video:
|
||||
fields:
|
||||
|
@ -334,6 +350,10 @@ send_video:
|
|||
selector:
|
||||
number:
|
||||
mode: box
|
||||
message_thread_id:
|
||||
selector:
|
||||
number:
|
||||
mode: box
|
||||
|
||||
send_voice:
|
||||
fields:
|
||||
|
@ -398,6 +418,10 @@ send_voice:
|
|||
selector:
|
||||
number:
|
||||
mode: box
|
||||
message_thread_id:
|
||||
selector:
|
||||
number:
|
||||
mode: box
|
||||
|
||||
send_document:
|
||||
fields:
|
||||
|
@ -470,6 +494,10 @@ send_document:
|
|||
selector:
|
||||
number:
|
||||
mode: box
|
||||
message_thread_id:
|
||||
selector:
|
||||
number:
|
||||
mode: box
|
||||
|
||||
send_location:
|
||||
fields:
|
||||
|
@ -520,6 +548,10 @@ send_location:
|
|||
selector:
|
||||
number:
|
||||
mode: box
|
||||
message_thread_id:
|
||||
selector:
|
||||
number:
|
||||
mode: box
|
||||
|
||||
send_poll:
|
||||
fields:
|
||||
|
@ -564,6 +596,10 @@ send_poll:
|
|||
selector:
|
||||
number:
|
||||
mode: box
|
||||
message_thread_id:
|
||||
selector:
|
||||
number:
|
||||
mode: box
|
||||
|
||||
edit_message:
|
||||
fields:
|
||||
|
|
|
@ -47,6 +47,10 @@
|
|||
"reply_to_message_id": {
|
||||
"name": "Reply to message id",
|
||||
"description": "Mark the message as a reply to a previous message."
|
||||
},
|
||||
"message_thread_id": {
|
||||
"name": "Message thread id",
|
||||
"description": "Unique identifier for the target message thread (topic) of the forum; for forum supergroups only."
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -113,6 +117,10 @@
|
|||
"reply_to_message_id": {
|
||||
"name": "[%key:component::telegram_bot::services::send_message::fields::reply_to_message_id::name%]",
|
||||
"description": "[%key:component::telegram_bot::services::send_message::fields::reply_to_message_id::description%]"
|
||||
},
|
||||
"message_thread_id": {
|
||||
"name": "[%key:component::telegram_bot::services::send_message::fields::message_thread_id::name%]",
|
||||
"description": "[%key:component::telegram_bot::services::send_message::fields::message_thread_id::description%]"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -175,6 +183,10 @@
|
|||
"reply_to_message_id": {
|
||||
"name": "[%key:component::telegram_bot::services::send_message::fields::reply_to_message_id::name%]",
|
||||
"description": "[%key:component::telegram_bot::services::send_message::fields::reply_to_message_id::description%]"
|
||||
},
|
||||
"message_thread_id": {
|
||||
"name": "[%key:component::telegram_bot::services::send_message::fields::message_thread_id::name%]",
|
||||
"description": "[%key:component::telegram_bot::services::send_message::fields::message_thread_id::description%]"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -241,6 +253,10 @@
|
|||
"reply_to_message_id": {
|
||||
"name": "[%key:component::telegram_bot::services::send_message::fields::reply_to_message_id::name%]",
|
||||
"description": "[%key:component::telegram_bot::services::send_message::fields::reply_to_message_id::description%]"
|
||||
},
|
||||
"message_thread_id": {
|
||||
"name": "[%key:component::telegram_bot::services::send_message::fields::message_thread_id::name%]",
|
||||
"description": "[%key:component::telegram_bot::services::send_message::fields::message_thread_id::description%]"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -307,6 +323,10 @@
|
|||
"reply_to_message_id": {
|
||||
"name": "[%key:component::telegram_bot::services::send_message::fields::reply_to_message_id::name%]",
|
||||
"description": "[%key:component::telegram_bot::services::send_message::fields::reply_to_message_id::description%]"
|
||||
},
|
||||
"message_thread_id": {
|
||||
"name": "[%key:component::telegram_bot::services::send_message::fields::message_thread_id::name%]",
|
||||
"description": "[%key:component::telegram_bot::services::send_message::fields::message_thread_id::description%]"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -369,6 +389,10 @@
|
|||
"reply_to_message_id": {
|
||||
"name": "[%key:component::telegram_bot::services::send_message::fields::reply_to_message_id::name%]",
|
||||
"description": "[%key:component::telegram_bot::services::send_message::fields::reply_to_message_id::description%]"
|
||||
},
|
||||
"message_thread_id": {
|
||||
"name": "[%key:component::telegram_bot::services::send_message::fields::message_thread_id::name%]",
|
||||
"description": "[%key:component::telegram_bot::services::send_message::fields::message_thread_id::description%]"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -435,6 +459,10 @@
|
|||
"reply_to_message_id": {
|
||||
"name": "[%key:component::telegram_bot::services::send_message::fields::reply_to_message_id::name%]",
|
||||
"description": "[%key:component::telegram_bot::services::send_message::fields::reply_to_message_id::description%]"
|
||||
},
|
||||
"message_thread_id": {
|
||||
"name": "[%key:component::telegram_bot::services::send_message::fields::message_thread_id::name%]",
|
||||
"description": "[%key:component::telegram_bot::services::send_message::fields::message_thread_id::description%]"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -477,6 +505,10 @@
|
|||
"reply_to_message_id": {
|
||||
"name": "[%key:component::telegram_bot::services::send_message::fields::reply_to_message_id::name%]",
|
||||
"description": "[%key:component::telegram_bot::services::send_message::fields::reply_to_message_id::description%]"
|
||||
},
|
||||
"message_thread_id": {
|
||||
"name": "[%key:component::telegram_bot::services::send_message::fields::message_thread_id::name%]",
|
||||
"description": "[%key:component::telegram_bot::services::send_message::fields::message_thread_id::description%]"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -523,6 +555,10 @@
|
|||
"reply_to_message_id": {
|
||||
"name": "[%key:component::telegram_bot::services::send_message::fields::reply_to_message_id::name%]",
|
||||
"description": "[%key:component::telegram_bot::services::send_message::fields::reply_to_message_id::description%]"
|
||||
},
|
||||
"message_thread_id": {
|
||||
"name": "[%key:component::telegram_bot::services::send_message::fields::message_thread_id::name%]",
|
||||
"description": "[%key:component::telegram_bot::services::send_message::fields::message_thread_id::description%]"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -6,6 +6,7 @@ from telegram import Update
|
|||
|
||||
from homeassistant.components.telegram_bot import (
|
||||
ATTR_MESSAGE,
|
||||
ATTR_MESSAGE_THREAD_ID,
|
||||
DOMAIN,
|
||||
SERVICE_SEND_MESSAGE,
|
||||
)
|
||||
|
@ -35,7 +36,7 @@ async def test_send_message(hass: HomeAssistant, webhook_platform) -> None:
|
|||
await hass.services.async_call(
|
||||
DOMAIN,
|
||||
SERVICE_SEND_MESSAGE,
|
||||
{ATTR_MESSAGE: "test_message"},
|
||||
{ATTR_MESSAGE: "test_message", ATTR_MESSAGE_THREAD_ID: "123"},
|
||||
blocking=True,
|
||||
context=context,
|
||||
)
|
||||
|
@ -45,6 +46,25 @@ async def test_send_message(hass: HomeAssistant, webhook_platform) -> None:
|
|||
assert events[0].context == context
|
||||
|
||||
|
||||
async def test_send_message_thread(hass: HomeAssistant, webhook_platform) -> None:
|
||||
"""Test the send_message service for threads."""
|
||||
context = Context()
|
||||
events = async_capture_events(hass, "telegram_sent")
|
||||
|
||||
await hass.services.async_call(
|
||||
DOMAIN,
|
||||
SERVICE_SEND_MESSAGE,
|
||||
{ATTR_MESSAGE: "test_message", ATTR_MESSAGE_THREAD_ID: "123"},
|
||||
blocking=True,
|
||||
context=context,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert len(events) == 1
|
||||
assert events[0].context == context
|
||||
assert events[0].data[ATTR_MESSAGE_THREAD_ID] == "123"
|
||||
|
||||
|
||||
async def test_webhook_endpoint_generates_telegram_text_event(
|
||||
hass: HomeAssistant,
|
||||
webhook_platform,
|
||||
|
|
Loading…
Add table
Reference in a new issue