fix(telegram): escape chunk indicators in MarkdownV2 (#1478)
This commit is contained in:
parent
7148534401
commit
a56937735e
2 changed files with 33 additions and 1 deletions
|
|
@ -322,6 +322,14 @@ class TelegramAdapter(BasePlatformAdapter):
|
||||||
# Format and split message if needed
|
# Format and split message if needed
|
||||||
formatted = self.format_message(content)
|
formatted = self.format_message(content)
|
||||||
chunks = self.truncate_message(formatted, self.MAX_MESSAGE_LENGTH)
|
chunks = self.truncate_message(formatted, self.MAX_MESSAGE_LENGTH)
|
||||||
|
if len(chunks) > 1:
|
||||||
|
# truncate_message appends a raw " (1/2)" suffix. Escape the
|
||||||
|
# MarkdownV2-special parentheses so Telegram doesn't reject the
|
||||||
|
# chunk and fall back to plain text.
|
||||||
|
chunks = [
|
||||||
|
re.sub(r" \((\d+)/(\d+)\)$", r" \\(\1/\2\\)", chunk)
|
||||||
|
for chunk in chunks
|
||||||
|
]
|
||||||
|
|
||||||
message_ids = []
|
message_ids = []
|
||||||
thread_id = metadata.get("thread_id") if metadata else None
|
thread_id = metadata.get("thread_id") if metadata else None
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ or corrupt user-visible content.
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
from unittest.mock import MagicMock
|
from unittest.mock import AsyncMock, MagicMock
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
|
@ -392,3 +392,27 @@ class TestStripMdv2:
|
||||||
|
|
||||||
def test_empty_string(self):
|
def test_empty_string(self):
|
||||||
assert _strip_mdv2("") == ""
|
assert _strip_mdv2("") == ""
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_send_escapes_chunk_indicator_for_markdownv2(adapter):
|
||||||
|
adapter.MAX_MESSAGE_LENGTH = 80
|
||||||
|
adapter._bot = MagicMock()
|
||||||
|
|
||||||
|
sent_texts = []
|
||||||
|
|
||||||
|
async def _fake_send_message(**kwargs):
|
||||||
|
sent_texts.append(kwargs["text"])
|
||||||
|
msg = MagicMock()
|
||||||
|
msg.message_id = len(sent_texts)
|
||||||
|
return msg
|
||||||
|
|
||||||
|
adapter._bot.send_message = AsyncMock(side_effect=_fake_send_message)
|
||||||
|
|
||||||
|
content = ("**bold** chunk content " * 12).strip()
|
||||||
|
result = await adapter.send("123", content)
|
||||||
|
|
||||||
|
assert result.success is True
|
||||||
|
assert len(sent_texts) > 1
|
||||||
|
assert re.search(r" \\\([0-9]+/[0-9]+\\\)$", sent_texts[0])
|
||||||
|
assert re.search(r" \\\([0-9]+/[0-9]+\\\)$", sent_texts[-1])
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue