Bug fix for Telegram bot integration: handle last message id (#146378)

This commit is contained in:
hanwg 2025-06-10 02:01:16 +08:00 committed by GitHub
parent f401ffb08c
commit d58157ca9e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 55 additions and 16 deletions

View File

@ -241,6 +241,7 @@ class TelegramNotificationService:
self._parse_mode = self._parsers.get(parser)
self.bot = bot
self.hass = hass
self._last_message_id: dict[int, int] = {}
def _get_allowed_chat_ids(self) -> list[int]:
allowed_chat_ids: list[int] = [
@ -260,9 +261,6 @@ class TelegramNotificationService:
return allowed_chat_ids
def _get_last_message_id(self):
return dict.fromkeys(self._get_allowed_chat_ids())
def _get_msg_ids(self, msg_data, chat_id):
"""Get the message id to edit.
@ -277,9 +275,9 @@ class TelegramNotificationService:
if (
isinstance(message_id, str)
and (message_id == "last")
and (self._get_last_message_id()[chat_id] is not None)
and (chat_id in self._last_message_id)
):
message_id = self._get_last_message_id()[chat_id]
message_id = self._last_message_id[chat_id]
else:
inline_message_id = msg_data["inline_message_id"]
return message_id, inline_message_id
@ -408,10 +406,10 @@ class TelegramNotificationService:
if not isinstance(out, bool) and hasattr(out, ATTR_MESSAGEID):
chat_id = out.chat_id
message_id = out[ATTR_MESSAGEID]
self._get_last_message_id()[chat_id] = message_id
self._last_message_id[chat_id] = message_id
_LOGGER.debug(
"Last message ID: %s (from chat_id %s)",
self._get_last_message_id(),
self._last_message_id,
chat_id,
)
@ -480,9 +478,9 @@ class TelegramNotificationService:
context=context,
)
# reduce message_id anyway:
if self._get_last_message_id()[chat_id] is not None:
if chat_id in self._last_message_id:
# change last msg_id for deque(n_msgs)?
self._get_last_message_id()[chat_id] -= 1
self._last_message_id[chat_id] -= 1
return deleted
async def edit_message(self, type_edit, chat_id=None, context=None, **kwargs):

View File

@ -255,8 +255,8 @@ def mock_broadcast_config_entry() -> MockConfigEntry:
options={ATTR_PARSER: PARSER_MD},
subentries_data=[
ConfigSubentryData(
unique_id="1234567890",
data={CONF_CHAT_ID: 1234567890},
unique_id="123456",
data={CONF_CHAT_ID: 123456},
subentry_id="mock_id",
subentry_type=CONF_ALLOWED_CHAT_IDS,
title="mock chat",

View File

@ -413,7 +413,7 @@ async def test_subentry_flow_chat_error(
with patch(
"homeassistant.components.telegram_bot.config_flow.Bot.get_chat",
return_value=ChatFullInfo(
id=1234567890,
id=123456,
title="mock title",
first_name="mock first_name",
type="PRIVATE",
@ -423,7 +423,7 @@ async def test_subentry_flow_chat_error(
):
result = await hass.config_entries.subentries.async_configure(
result["flow_id"],
user_input={CONF_CHAT_ID: 1234567890},
user_input={CONF_CHAT_ID: 123456},
)
await hass.async_block_till_done()

View File

@ -17,8 +17,10 @@ from telegram.error import (
from homeassistant.components.telegram_bot import (
ATTR_CALLBACK_QUERY_ID,
ATTR_CAPTION,
ATTR_CHAT_ID,
ATTR_FILE,
ATTR_KEYBOARD_INLINE,
ATTR_LATITUDE,
ATTR_LONGITUDE,
ATTR_MESSAGE,
@ -34,7 +36,9 @@ from homeassistant.components.telegram_bot import (
PLATFORM_BROADCAST,
SERVICE_ANSWER_CALLBACK_QUERY,
SERVICE_DELETE_MESSAGE,
SERVICE_EDIT_CAPTION,
SERVICE_EDIT_MESSAGE,
SERVICE_EDIT_REPLYMARKUP,
SERVICE_SEND_ANIMATION,
SERVICE_SEND_DOCUMENT,
SERVICE_SEND_LOCATION,
@ -629,14 +633,23 @@ async def test_delete_message(
await hass.config_entries.async_setup(mock_broadcast_config_entry.entry_id)
await hass.async_block_till_done()
response = await hass.services.async_call(
DOMAIN,
SERVICE_SEND_MESSAGE,
{ATTR_MESSAGE: "mock message"},
blocking=True,
return_response=True,
)
assert response["chats"][0]["message_id"] == 12345
with patch(
"homeassistant.components.telegram_bot.bot.TelegramNotificationService.delete_message",
"homeassistant.components.telegram_bot.bot.Bot.delete_message",
AsyncMock(return_value=True),
) as mock:
await hass.services.async_call(
DOMAIN,
SERVICE_DELETE_MESSAGE,
{ATTR_CHAT_ID: 12345, ATTR_MESSAGEID: 12345},
{ATTR_CHAT_ID: 123456, ATTR_MESSAGEID: "last"},
blocking=True,
)
@ -655,7 +668,7 @@ async def test_edit_message(
await hass.async_block_till_done()
with patch(
"homeassistant.components.telegram_bot.bot.TelegramNotificationService.edit_message",
"homeassistant.components.telegram_bot.bot.Bot.edit_message_text",
AsyncMock(return_value=True),
) as mock:
await hass.services.async_call(
@ -668,6 +681,34 @@ async def test_edit_message(
await hass.async_block_till_done()
mock.assert_called_once()
with patch(
"homeassistant.components.telegram_bot.bot.Bot.edit_message_caption",
AsyncMock(return_value=True),
) as mock:
await hass.services.async_call(
DOMAIN,
SERVICE_EDIT_CAPTION,
{ATTR_CAPTION: "mock caption", ATTR_CHAT_ID: 12345, ATTR_MESSAGEID: 12345},
blocking=True,
)
await hass.async_block_till_done()
mock.assert_called_once()
with patch(
"homeassistant.components.telegram_bot.bot.Bot.edit_message_reply_markup",
AsyncMock(return_value=True),
) as mock:
await hass.services.async_call(
DOMAIN,
SERVICE_EDIT_REPLYMARKUP,
{ATTR_KEYBOARD_INLINE: [], ATTR_CHAT_ID: 12345, ATTR_MESSAGEID: 12345},
blocking=True,
)
await hass.async_block_till_done()
mock.assert_called_once()
async def test_async_setup_entry_failed(
hass: HomeAssistant, mock_broadcast_config_entry: MockConfigEntry