175 lines
6.9 KiB
Python
175 lines
6.9 KiB
Python
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=_("✅ Короткое описание бота успешно изменено на: <b>{description}</b>").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Попробуйте снова через: <b>{retry_text}</b>").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 при изменении короткого описания: <pre>{error}</pre>").format(error=str(e)),
|
||
markup=settings_keyboard(),
|
||
state=state
|
||
)
|
||
|
||
except Exception as e:
|
||
logger.error(f"Непредвиденная ошибка при изменении короткого описания: {e}")
|
||
await msg(
|
||
update=message,
|
||
text=_("❌ Непредвиденная ошибка при изменении короткого описания: <pre>{error}</pre>").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 = _(
|
||
"📝 <b>Смена короткого описания бота</b>\n\n"
|
||
"Текущее короткое описание: <i>{current}</i>\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
|