from aiogram import Router, F, Bot from aiogram.exceptions import TelegramAPIError, TelegramRetryAfter from aiogram.filters import Command, CommandObject from aiogram.fsm.context import FSMContext from aiogram.fsm.state import StatesGroup, State from aiogram.types import Message, CallbackQuery from aiogram.utils.i18n import gettext as _ from bot.filters import IsSuperAdmin from bot.core.bots import BotInfo from bot.handlers.commands.settings.settings_cmd import settings_keyboard from bot.templates import msg from bot.utils import format_retry_time, status_clear from configs import COMMANDS from middleware.loggers import logger __all__ = ("router",) # Название команды CMD: str = "set_description".lower() # Роутер для обработки команды /set_description router: Router = Router(name=f"{CMD}_cmd_router") class SetBotDescriptionForm(StatesGroup): """Состояния FSM для изменения короткого описания бота.""" new_description: State = State() async def handle_set_bot_description( description: str, message: Message | CallbackQuery, state: FSMContext, bot: Bot ) -> None: """ Установка короткого описания (short description) бота с обработкой FSM и ошибок API. Args: description (str): Новый текст описания (до 120 символов). message (Message | CallbackQuery): Сообщение или callback-запрос. state (FSMContext): Контекст FSM. bot (Bot): Экземпляр бота. """ # Проверка ограничения Telegram if len(description) > 120: await msg( update=message, text=_("❌ Короткое описание бота должно быть не более 120 символов. Текущая длина: {length}").format( length=len(description) ), markup=settings_keyboard(), state=state ) return try: # Установка нового короткого описания await bot.set_my_short_description(short_description=description) # Сохраняем текущее значение в BotInfo BotInfo.widget = description # Сбрасываем состояние FSM await state.clear() # Отправляем сообщение об успехе await msg( update=message, text=_("✅ Короткое описание бота успешно изменено на: {description}").format( description=description ), markup=settings_keyboard(), state=state ) logger.info(f"Короткое описание бота изменено на: {description}") except TelegramRetryAfter as e: retry_text: str = format_retry_time(e.retry_after) logger.warning(f"Превышен лимит запросов при смене short description. Попробуйте через {retry_text}") await msg( update=message, text=_("⚠️ Слишком частая смена короткого описания!\nПопробуйте снова через: {retry_text}").format( retry_text=retry_text ), markup=settings_keyboard(), state=state ) except TelegramAPIError as e: logger.error(f"Ошибка Telegram API при изменении короткого описания: {e}") await msg( update=message, text=_("❌ Ошибка Telegram API при изменении короткого описания:
{error}
").format(error=str(e)), markup=settings_keyboard(), state=state ) except Exception as e: logger.error(f"Непредвиденная ошибка при изменении короткого описания: {e}") await msg( update=message, text=_("❌ Непредвиденная ошибка при изменении короткого описания:
{error}
").format(error=str(e)), markup=settings_keyboard(), state=state ) @router.callback_query(F.data.lower() == CMD, IsSuperAdmin()) @router.message(Command(*COMMANDS[CMD], prefix=BotInfo.prefix, ignore_case=True), IsSuperAdmin()) async def set_description_cmd( message: Message | CallbackQuery, state: FSMContext, bot: Bot, command: CommandObject | None = None ) -> None: """ Обработчик команды /set_description для короткого описания. Поддерживает: 1. Немедленное изменение через аргумент (/set_description TEXT). 2. Callback-запрос. 3. FSM-ввод. """ current_description: str = BotInfo.description # Вариант 1: если пользователь передал аргумент к команде if command and command.args: description: str = command.args.strip() if len(description) > 120: await msg( update=message, text=_("❌ Короткое описание не должно превышать 120 символов. Текущая длина: {length}").format( length=len(description) ), markup=settings_keyboard(), state=state ) return await handle_set_bot_description(description, message, state, bot) return # Вариант 2: без аргумента → включаем FSM await status_clear(update=message, state=state) text: str = _( "📝 Смена короткого описания бота\n\n" "Текущее короткое описание: {current}\n\n" "Введите новое короткое описание (максимум 120 символов):" ).format(current=current_description) await msg(update=message, text=text, markup=settings_keyboard(), state=state) await state.set_state(SetBotDescriptionForm.new_description) @router.message(SetBotDescriptionForm.new_description, IsSuperAdmin()) async def process_new_bot_description( message: Message, state: FSMContext, bot: Bot ) -> None: """ Обработка ввода нового короткого описания через FSM. """ description: str = message.text.strip() if not description: await message.answer(_("❌ Пожалуйста, введите корректное короткое описание.")) return await handle_set_bot_description(description, message, state, bot) BotInfo.description = description