Telegram message formatting and MarkdownV2 chunk indicator handling
Cluster 1456 · gateway. Data as of
1 open item. Fix merged in #1478 on 16 Mar 2026. Check it covers your case.
The short answer
- Known?
- Yes. 5 related items grouped here, 1 issue already closed.
- Fix event
- A fix was merged to main in PR #1478. Check it covers your case. No release data is tracked.
- Tracker
- The maintainers' tracker marks this
resolved, deciding PR #1478. That is separate from the fix event. - Still open
- 0 issues and 1 PR.
These issues and pull requests all concern how Telegram messages are formatted, especially when long messages are split into chunks. Some propose escaping chunk indicators for MarkdownV2, while others propose switching to HTML or MessageEntity, and one reports a fallback to plain text on chunked messages.
Open issues0
Open PRs1
- PR#11287feat(gateway): send Telegram messages via MessageEntity instead of MarkdownV2
Fixes on record
-
#1478 fix(telegram): escape chunk indicators in MarkdownV2
files:
gateway/platforms/telegram.py,tests/gateway/test_telegram_format.pyShow the diff
-
gateway/platforms/telegram.py@@ -322,6 +322,14 @@ async def send( # Format and split message if needed formatted = self.format_message(content) 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 = [] thread_id = metadata.get("thread_id") if metadata else None -
tests/gateway/test_telegram_format.py@@ -7,7 +7,7 @@ import re import sys -from unittest.mock import MagicMock +from unittest.mock import AsyncMock, MagicMock import pytest @@ -392,3 +392,27 @@ def test_plain_text_unchanged(self): def test_empty_string(self): assert _strip_mdv2("") == "" + + [redacted:email] +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])
-
2 PRs closed without merging
From the close comments: done elsewhere 1 · duplicate 1
Closed issues · 1
- Closed#1456[Bug]: Telegram formatting falls back to plain text on chunked messages
How this cluster was grouped
-
Link evidence (
structural links throughout): every member is connected by structural evidence: shared changed files, or a closing/superseded reference. -
Pairwise link density
0.40: the share of item pairs that carry a link, counting a structural link in full and a relevance-only link at 0.36.1.00means every pair is linked.
Pick up a Lab task
Check whether a fix covers the open issues here, with your own agent. Bring back evidence for maintainers.
Open the LabAt a glance
- Subsystem
- gateway
- Merged PRs
- #1478
- Closed issues
- 1
- Attempts
- 2 PRs closed without merging
- Fix link checked
- 16 Mar 2026. This confirmation is old and may be out of date (a revert or reopen would not have invalidated it here); re-verify.