From 2c38964cead199758df744e64cb1a86ee722e45b Mon Sep 17 00:00:00 2001 From: Admin Date: Fri, 19 Jun 2026 15:40:17 +0400 Subject: [PATCH] fix(admin): escape HTML entities and convert Markdown formatting to prevent Telegram entity parsing errors --- handlers/admin.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/handlers/admin.py b/handlers/admin.py index bc02acb..8d9aa3b 100644 --- a/handlers/admin.py +++ b/handlers/admin.py @@ -124,13 +124,25 @@ async def process_jurist_question(message: Message, state: FSMContext): output = output.split("Update available:")[0].strip() if proc.returncode == 0: - if len(output) > 4000: - parts = [output[i:i+4000] for i in range(0, len(output), 4000)] + import html + import re + + # Заменяем
,
,
на переносы строк + clean_output = output.replace("
", "\n").replace("
", "\n").replace("
", "\n") + # Экранируем спецсимволы для parse_mode='HTML' + safe_output = html.escape(clean_output) + # Форматируем **жирный** текст -> жирный + safe_output = re.sub(r'\*\*(.*?)\*\*', r'\1', safe_output, flags=re.DOTALL) + # Форматируем [ссылка](url) -> \1 + safe_output = re.sub(r'\[(.*?)\]\((.*?)\)', r'\1', safe_output, flags=re.DOTALL) + + if len(safe_output) > 4000: + parts = [safe_output[i:i+4000] for i in range(0, len(safe_output), 4000)] await status_msg.edit_text(f"⚖️ Анализ NotebookLM (часть 1):\n\n{parts[0]}", parse_mode='HTML') for part in parts[1:]: await message.answer(part, parse_mode='HTML') else: - await status_msg.edit_text(f"⚖️ Анализ NotebookLM:\n\n{output}", parse_mode='HTML') + await status_msg.edit_text(f"⚖️ Анализ NotebookLM:\n\n{safe_output}", parse_mode='HTML') else: await status_msg.edit_text(f"❌ Ошибка запроса к NotebookLM:\n{error or output}") except Exception as e: