fix(telegram): improve MarkdownV2 edit fallback and fix _strip_mdv2 bold handling

When edit_message(finalize=True) fails with a MarkdownV2 parse error,
the silent fallback previously sent raw content with escape sequences.
Now it logs the error and strips markdown formatting via _strip_mdv2()
for clean plain-text fallback.

Also fixes _strip_mdv2 to handle standard markdown bold (\*\*text\*\*)
before MarkdownV2 bold (\*text\*), preventing half-stripped asterisks.

Refs: #41955, #41732
This commit is contained in:
ruangraung 2026-06-09 00:12:31 +07:00 committed by Teknium
parent 6d2732e786
commit f4531feee8
2 changed files with 11 additions and 3 deletions

View file

@ -181,6 +181,8 @@ def _strip_mdv2(text: str) -> str:
""" """
# Remove escape backslashes before special characters # Remove escape backslashes before special characters
cleaned = re.sub(r'\\([_*\[\]()~`>#\+\-=|{}.!\\])', r'\1', text) cleaned = re.sub(r'\\([_*\[\]()~`>#\+\-=|{}.!\\])', r'\1', text)
# Remove standard markdown bold (**text** → text) BEFORE MarkdownV2 bold
cleaned = re.sub(r'\*\*([^*]+)\*\*', r'\1', cleaned)
# Remove MarkdownV2 bold markers that format_message converted from **bold** # Remove MarkdownV2 bold markers that format_message converted from **bold**
cleaned = re.sub(r'\*([^*]+)\*', r'\1', cleaned) cleaned = re.sub(r'\*([^*]+)\*', r'\1', cleaned)
# Remove MarkdownV2 italic markers that format_message converted from *italic* # Remove MarkdownV2 italic markers that format_message converted from *italic*
@ -2208,11 +2210,17 @@ class TelegramAdapter(BasePlatformAdapter):
# "Message is not modified" is a no-op, not an error # "Message is not modified" is a no-op, not an error
if "not modified" in str(fmt_err).lower(): if "not modified" in str(fmt_err).lower():
return SendResult(success=True, message_id=message_id) return SendResult(success=True, message_id=message_id)
# Fallback: retry without markdown formatting # Fallback: strip MarkdownV2 escapes and retry as clean plain text
logger.warning(
"[%s] MarkdownV2 edit failed, falling back to plain text: %s",
self.name,
fmt_err,
)
_plain = _strip_mdv2(content) if content else content
await self._bot.edit_message_text( await self._bot.edit_message_text(
chat_id=int(chat_id), chat_id=int(chat_id),
message_id=int(message_id), message_id=int(message_id),
text=content, text=_plain,
) )
return SendResult(success=True, message_id=message_id) return SendResult(success=True, message_id=message_id)
except Exception as e: except Exception as e:

View file

@ -835,7 +835,7 @@ class TestEditMessageStreamingSafety:
assert second_call == { assert second_call == {
"chat_id": 123, "chat_id": 123,
"message_id": 456, "message_id": 456,
"text": "final **bold**", "text": "final bold",
} }
@pytest.mark.asyncio @pytest.mark.asyncio