Add HTML validation for broadcast messages in admin handler
- Implemented a preliminary check for HTML validity in broadcast messages by attempting to send a test message before processing. - Added error handling for invalid HTML, providing user feedback in both English and Russian. - Updated localization files to include new error messages for invalid HTML input.
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
import logging
|
import logging
|
||||||
import asyncio
|
import asyncio
|
||||||
from aiogram import Router, F, types, Bot
|
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 aiogram.fsm.context import FSMContext
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
@@ -65,6 +65,7 @@ async def process_broadcast_message_handler(
|
|||||||
i18n_data: dict,
|
i18n_data: dict,
|
||||||
settings: Settings,
|
settings: Settings,
|
||||||
session: AsyncSession,
|
session: AsyncSession,
|
||||||
|
bot: Bot,
|
||||||
):
|
):
|
||||||
current_lang = i18n_data.get("current_language", settings.DEFAULT_LANGUAGE)
|
current_lang = i18n_data.get("current_language", settings.DEFAULT_LANGUAGE)
|
||||||
i18n: Optional[JsonI18n] = i18n_data.get("i18n_instance")
|
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"))
|
await message.answer(_("admin_broadcast_error_no_message"))
|
||||||
return
|
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(
|
await state.update_data(
|
||||||
broadcast_text=text,
|
broadcast_text=text,
|
||||||
broadcast_entities=entities,
|
broadcast_entities=entities,
|
||||||
@@ -190,6 +216,7 @@ async def confirm_broadcast_callback_handler(
|
|||||||
chat_id=uid,
|
chat_id=uid,
|
||||||
text=text,
|
text=text,
|
||||||
entities=entities,
|
entities=entities,
|
||||||
|
parse_mode=None, # переопределяем глобальный HTML, т.к. используем entities
|
||||||
)
|
)
|
||||||
sent_count += 1
|
sent_count += 1
|
||||||
|
|
||||||
|
|||||||
@@ -165,6 +165,8 @@
|
|||||||
"admin_broadcast_cancelled_alert": "Broadcast cancelled!",
|
"admin_broadcast_cancelled_alert": "Broadcast cancelled!",
|
||||||
"admin_broadcast_cancelled_nav_back": "Broadcast cancelled. You are returned to the admin panel.",
|
"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: <code>{example_format}</code>\n(Validity is optional; default is indefinite)",
|
"admin_promo_create_prompt": "Enter promo details in the format: CODE BONUS_DAYS MAX_USES [VALIDITY_DAYS]\nExample: <code>{example_format}</code>\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_format": "Invalid format. Please use: CODE BONUS_DAYS MAX_USES [VALIDITY_DAYS]",
|
||||||
"admin_promo_invalid_code_format": "Code must be 3–30 alphanumeric characters.",
|
"admin_promo_invalid_code_format": "Code must be 3–30 alphanumeric characters.",
|
||||||
|
|||||||
@@ -268,6 +268,7 @@
|
|||||||
"sync_critical_error": "❌ Критическая ошибка синхронизации",
|
"sync_critical_error": "❌ Критическая ошибка синхронизации",
|
||||||
"no_errors_placeholder": "нет",
|
"no_errors_placeholder": "нет",
|
||||||
"admin_sync_initiated_from_panel": "Синхронизация запущена...",
|
"admin_sync_initiated_from_panel": "Синхронизация запущена...",
|
||||||
|
"admin_broadcast_invalid_html": "❌ Некорректный HTML в сообщении. Пожалуйста, отправьте корректный HTML (поддерживаются теги Telegram) или уберите теги.",
|
||||||
"admin_panel_user_creation_failed": "❌ Не удалось создать пользователя на панели для TG ID {user_id}. Панель недоступна?",
|
"admin_panel_user_creation_failed": "❌ Не удалось создать пользователя на панели для TG ID {user_id}. Панель недоступна?",
|
||||||
"error_displaying_logs_too_long": "Ошибка: логи слишком длинные для отображения одним сообщением. Попробуйте найти логи по конкретному пользователю.",
|
"error_displaying_logs_too_long": "Ошибка: логи слишком длинные для отображения одним сообщением. Попробуйте найти логи по конкретному пользователю.",
|
||||||
"error_displaying_statistics": "Ошибка отображения статистики.",
|
"error_displaying_statistics": "Ошибка отображения статистики.",
|
||||||
|
|||||||
Reference in New Issue
Block a user