diff --git a/bot/handlers/admin/broadcast.py b/bot/handlers/admin/broadcast.py index aed5146..6a56cc7 100644 --- a/bot/handlers/admin/broadcast.py +++ b/bot/handlers/admin/broadcast.py @@ -1,7 +1,7 @@ import logging import asyncio from aiogram import Router, F, types, Bot -from aiogram.exceptions import TelegramRetryAfter +from aiogram.exceptions import TelegramRetryAfter, TelegramBadRequest from aiogram.fsm.context import FSMContext from typing import Optional @@ -65,6 +65,7 @@ async def process_broadcast_message_handler( i18n_data: dict, settings: Settings, session: AsyncSession, + bot: Bot, ): current_lang = i18n_data.get("current_language", settings.DEFAULT_LANGUAGE) i18n: Optional[JsonI18n] = i18n_data.get("i18n_instance") @@ -84,6 +85,31 @@ async def process_broadcast_message_handler( await message.answer(_("admin_broadcast_error_no_message")) return + # Предварительная проверка HTML: попробуем отправить и сразу удалить + # Если HTML некорректный, Telegram вернёт ошибку парсинга + try: + test_msg = await bot.send_message( + chat_id=message.chat.id, + text=text, + parse_mode="HTML", + disable_web_page_preview=True, + disable_notification=True, + ) + # Удалим тестовое сообщение + try: + await bot.delete_message(chat_id=message.chat.id, message_id=test_msg.message_id) + except Exception: + pass + except TelegramBadRequest as e: + await message.answer( + _( + "admin_broadcast_invalid_html", + default="❌ Некорректный HTML в сообщении. Пожалуйста, отправьте корректный HTML (поддерживаются теги Telegram) или уберите теги.\nОшибка: {error}", + error=str(e), + ) + ) + return + await state.update_data( broadcast_text=text, broadcast_entities=entities, @@ -190,6 +216,7 @@ async def confirm_broadcast_callback_handler( chat_id=uid, text=text, entities=entities, + parse_mode=None, # переопределяем глобальный HTML, т.к. используем entities ) sent_count += 1 diff --git a/locales/en.json b/locales/en.json index a7e77f4..071301c 100644 --- a/locales/en.json +++ b/locales/en.json @@ -165,6 +165,8 @@ "admin_broadcast_cancelled_alert": "Broadcast cancelled!", "admin_broadcast_cancelled_nav_back": "Broadcast cancelled. You are returned to the admin panel.", + "admin_broadcast_invalid_html": "❌ Invalid HTML in message. Please send valid HTML (Telegram-supported tags) or remove tags.", + "admin_promo_create_prompt": "Enter promo details in the format: CODE BONUS_DAYS MAX_USES [VALIDITY_DAYS]\nExample: {example_format}\n(Validity is optional; default is indefinite)", "admin_promo_invalid_format": "Invalid format. Please use: CODE BONUS_DAYS MAX_USES [VALIDITY_DAYS]", "admin_promo_invalid_code_format": "Code must be 3–30 alphanumeric characters.", diff --git a/locales/ru.json b/locales/ru.json index 34063e2..e66e70a 100644 --- a/locales/ru.json +++ b/locales/ru.json @@ -268,6 +268,7 @@ "sync_critical_error": "❌ Критическая ошибка синхронизации", "no_errors_placeholder": "нет", "admin_sync_initiated_from_panel": "Синхронизация запущена...", + "admin_broadcast_invalid_html": "❌ Некорректный HTML в сообщении. Пожалуйста, отправьте корректный HTML (поддерживаются теги Telegram) или уберите теги.", "admin_panel_user_creation_failed": "❌ Не удалось создать пользователя на панели для TG ID {user_id}. Панель недоступна?", "error_displaying_logs_too_long": "Ошибка: логи слишком длинные для отображения одним сообщением. Попробуйте найти логи по конкретному пользователю.", "error_displaying_statistics": "Ошибка отображения статистики.",