Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions plugins/platforms/telegram/adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -4852,6 +4852,7 @@ async def edit_message(
chat_id=normalize_telegram_chat_id(chat_id),
message_id=int(message_id),
text=content,
**self._link_preview_kwargs(),
)
if _saturated_preview:
self._last_overflow_preview[_preview_key] = content
Expand All @@ -4864,6 +4865,7 @@ async def edit_message(
message_id=int(message_id),
text=formatted,
parse_mode=ParseMode.MARKDOWN_V2,
**self._link_preview_kwargs(),
)
except Exception as fmt_err:
# "Message is not modified" is a no-op, not an error
Expand All @@ -4881,6 +4883,7 @@ async def edit_message(
chat_id=normalize_telegram_chat_id(chat_id),
message_id=int(message_id),
text=_plain,
**self._link_preview_kwargs(),
)
return SendResult(success=True, message_id=message_id)
except Exception as e:
Expand Down Expand Up @@ -4909,6 +4912,7 @@ async def edit_message(
chat_id=normalize_telegram_chat_id(chat_id),
message_id=int(message_id),
text=truncated,
**self._link_preview_kwargs(),
)
self._last_overflow_preview[_preview_key] = truncated
return SendResult(success=True, message_id=message_id)
Expand All @@ -4934,6 +4938,7 @@ async def edit_message(
chat_id=normalize_telegram_chat_id(chat_id),
message_id=int(message_id),
text=content,
**self._link_preview_kwargs(),
)
return SendResult(success=True, message_id=message_id)
except Exception as retry_err:
Expand Down Expand Up @@ -5041,6 +5046,7 @@ async def _edit_overflow_split(
message_id=int(message_id),
text=formatted,
parse_mode=ParseMode.MARKDOWN_V2,
**self._link_preview_kwargs(),
)
except Exception as fmt_err:
if "not modified" not in str(fmt_err).lower():
Expand All @@ -5053,12 +5059,14 @@ async def _edit_overflow_split(
chat_id=normalize_telegram_chat_id(chat_id),
message_id=int(message_id),
text=_strip_mdv2(first_chunk),
**self._link_preview_kwargs(),
)
else:
await self._bot.edit_message_text(
chat_id=normalize_telegram_chat_id(chat_id),
message_id=int(message_id),
text=first_chunk,
**self._link_preview_kwargs(),
)
except Exception as e:
err_str = str(e).lower()
Expand Down
86 changes: 86 additions & 0 deletions tests/gateway/test_telegram_format.py
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,64 @@ async def _fake_send_message(**kwargs):


class TestEditMessageStreamingSafety:
@staticmethod
def _assert_link_previews_disabled(kwargs):
assert (
kwargs.get("disable_web_page_preview") is True
or kwargs.get("link_preview_options") is not None
)

@pytest.mark.asyncio
async def test_non_final_edit_disables_link_preview_when_configured(self):
adapter = TelegramAdapter(
PlatformConfig(
enabled=True,
token="fake-token",
extra={"disable_link_previews": True},
)
)
adapter._bot = MagicMock()
adapter._bot.edit_message_text = AsyncMock()

result = await adapter.edit_message(
"123",
"456",
"partial https://example.com",
finalize=False,
)

assert result.success is True
kwargs = adapter._bot.edit_message_text.await_args.kwargs
self._assert_link_previews_disabled(kwargs)

@pytest.mark.asyncio
async def test_final_edit_disables_link_preview_on_markdown_and_plain_fallback(
self,
):
adapter = TelegramAdapter(
PlatformConfig(
enabled=True,
token="fake-token",
extra={"disable_link_previews": True},
)
)
adapter._bot = MagicMock()
adapter._bot.edit_message_text = AsyncMock(
side_effect=[Exception("bad markdown"), None]
)

result = await adapter.edit_message(
"123",
"456",
"final https://example.com **bold**",
finalize=True,
)

assert result.success is True
first_call = adapter._bot.edit_message_text.await_args_list[0].kwargs
second_call = adapter._bot.edit_message_text.await_args_list[1].kwargs
self._assert_link_previews_disabled(first_call)
self._assert_link_previews_disabled(second_call)

@pytest.mark.asyncio
async def test_message_too_long_splits_into_continuations_not_silent_truncation(self):
Expand Down Expand Up @@ -525,6 +582,35 @@ async def _fake_send(**kwargs):
# Continuations were sent threaded as replies for visual grouping.
assert adapter._bot.send_message.await_count == len(result.continuation_message_ids)

@pytest.mark.asyncio
async def test_message_too_long_first_chunk_edit_disables_link_preview(self):
adapter = TelegramAdapter(
PlatformConfig(
enabled=True,
token="fake-token",
extra={"disable_link_previews": True},
)
)
adapter._bot = MagicMock()
adapter._bot.edit_message_text = AsyncMock()
_next_id = [1000]

async def _fake_send(**kwargs):
_next_id[0] += 1
return SimpleNamespace(message_id=_next_id[0])

adapter._bot.send_message = AsyncMock(side_effect=_fake_send)

result = await adapter.edit_message(
"123",
"456",
"https://example.com " + ("x" * 6000),
finalize=True,
)

assert result.success is True
first_edit = adapter._bot.edit_message_text.await_args_list[0].kwargs
self._assert_link_previews_disabled(first_edit)

@pytest.mark.asyncio
async def test_mid_stream_overflow_truncates_instead_of_splitting(self):
Expand Down
Loading