mirror of
https://github.com/HKUDS/nanobot.git
synced 2026-08-04 08:28:36 +00:00
fix(telegram): fall back on overflow HTML rejection
This commit is contained in:
parent
a335ce07db
commit
3b14d59dcd
@ -1065,7 +1065,7 @@ class TelegramChannel(BaseChannel):
|
|||||||
chunks = _split_telegram_markdown_html_chunks(buf.text, TELEGRAM_HTML_MAX_LEN)
|
chunks = _split_telegram_markdown_html_chunks(buf.text, TELEGRAM_HTML_MAX_LEN)
|
||||||
if len(chunks) <= 1:
|
if len(chunks) <= 1:
|
||||||
return
|
return
|
||||||
_, first_html = chunks[0]
|
first_markdown, first_html = chunks[0]
|
||||||
try:
|
try:
|
||||||
await self._call_with_retry(
|
await self._call_with_retry(
|
||||||
self._app.bot.edit_message_text,
|
self._app.bot.edit_message_text,
|
||||||
@ -1073,20 +1073,44 @@ class TelegramChannel(BaseChannel):
|
|||||||
text=first_html,
|
text=first_html,
|
||||||
parse_mode="HTML",
|
parse_mode="HTML",
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except BadRequest as e:
|
||||||
if not self._is_not_modified_error(e):
|
if not self._is_not_modified_error(e):
|
||||||
self.logger.warning("Stream overflow edit failed: {}", e)
|
self.logger.warning(
|
||||||
raise
|
"Stream overflow HTML edit failed, falling back to plain text: {}", e
|
||||||
for _, html in chunks[1:-1]:
|
)
|
||||||
await self._call_with_retry(
|
try:
|
||||||
self._app.bot.send_message,
|
await self._call_with_retry(
|
||||||
chat_id=chat_id, text=html, parse_mode="HTML", **thread_kwargs,
|
self._app.bot.edit_message_text,
|
||||||
)
|
chat_id=chat_id, message_id=buf.message_id,
|
||||||
|
text=first_markdown,
|
||||||
|
)
|
||||||
|
except Exception as plain_error:
|
||||||
|
if not self._is_not_modified_error(plain_error):
|
||||||
|
self.logger.warning("Stream overflow plain edit failed: {}", plain_error)
|
||||||
|
raise
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.warning("Stream overflow edit failed: {}", e)
|
||||||
|
raise
|
||||||
|
|
||||||
|
async def send_chunk(markdown: str, html: str) -> Any:
|
||||||
|
try:
|
||||||
|
return await self._call_with_retry(
|
||||||
|
self._app.bot.send_message,
|
||||||
|
chat_id=chat_id, text=html, parse_mode="HTML", **thread_kwargs,
|
||||||
|
)
|
||||||
|
except BadRequest as e:
|
||||||
|
self.logger.warning(
|
||||||
|
"Stream overflow HTML send failed, falling back to plain text: {}", e
|
||||||
|
)
|
||||||
|
return await self._call_with_retry(
|
||||||
|
self._app.bot.send_message,
|
||||||
|
chat_id=chat_id, text=markdown, **thread_kwargs,
|
||||||
|
)
|
||||||
|
|
||||||
|
for markdown, html in chunks[1:-1]:
|
||||||
|
await send_chunk(markdown, html)
|
||||||
markdown_tail, tail_html = chunks[-1]
|
markdown_tail, tail_html = chunks[-1]
|
||||||
sent = await self._call_with_retry(
|
sent = await send_chunk(markdown_tail, tail_html)
|
||||||
self._app.bot.send_message,
|
|
||||||
chat_id=chat_id, text=tail_html, parse_mode="HTML", **thread_kwargs,
|
|
||||||
)
|
|
||||||
buf.message_id = sent.message_id
|
buf.message_id = sent.message_id
|
||||||
buf.text = markdown_tail
|
buf.text = markdown_tail
|
||||||
|
|
||||||
|
|||||||
@ -917,6 +917,43 @@ async def test_send_delta_incremental_html_expansion_does_not_overflow() -> None
|
|||||||
assert "<b>" not in buf.text
|
assert "<b>" not in buf.text
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_send_delta_incremental_html_parse_failure_falls_back_to_plain() -> None:
|
||||||
|
"""Telegram HTML rejections retry overflow chunks as plain text."""
|
||||||
|
from telegram.error import BadRequest
|
||||||
|
|
||||||
|
channel = TelegramChannel(
|
||||||
|
TelegramConfig(enabled=True, token="123:abc", allow_from=["*"]),
|
||||||
|
MessageBus(),
|
||||||
|
)
|
||||||
|
channel._app = _FakeApp(lambda: None)
|
||||||
|
channel._app.bot.edit_message_text = AsyncMock(
|
||||||
|
side_effect=[BadRequest("Can't parse entities"), None]
|
||||||
|
)
|
||||||
|
channel._app.bot.send_message = AsyncMock(
|
||||||
|
side_effect=[BadRequest("Can't parse entities"), SimpleNamespace(message_id=99)]
|
||||||
|
)
|
||||||
|
|
||||||
|
first_chunk = f"**{'x' * 3900}**\n"
|
||||||
|
tail = "**tail** " * 50
|
||||||
|
channel._stream_bufs["123"] = _StreamBuf(
|
||||||
|
text=first_chunk + tail, message_id=7, last_edit=0.0, stream_id="s:0"
|
||||||
|
)
|
||||||
|
|
||||||
|
await channel.send_delta("123", "y", stream_id="s:0")
|
||||||
|
|
||||||
|
edit_calls = channel._app.bot.edit_message_text.call_args_list
|
||||||
|
assert edit_calls[0].kwargs["parse_mode"] == "HTML"
|
||||||
|
assert edit_calls[1].kwargs["text"] == first_chunk.rstrip()
|
||||||
|
assert "parse_mode" not in edit_calls[1].kwargs
|
||||||
|
|
||||||
|
send_calls = channel._app.bot.send_message.call_args_list
|
||||||
|
assert send_calls[0].kwargs["parse_mode"] == "HTML"
|
||||||
|
assert send_calls[1].kwargs["text"] == tail + "y"
|
||||||
|
assert "parse_mode" not in send_calls[1].kwargs
|
||||||
|
assert channel._stream_bufs["123"].text == tail + "y"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_send_delta_initial_send_keeps_message_in_thread() -> None:
|
async def test_send_delta_initial_send_keeps_message_in_thread() -> None:
|
||||||
channel = TelegramChannel(
|
channel = TelegramChannel(
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user