Files
PrimoGuardBot-/bot/handlers/commands/settings/set_name_cmd.py
2026-02-17 11:24:55 +07:00

158 lines
5.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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.core.bots import BotInfo
from bot.filters import IsOwner
from bot.handlers.commands.settings.settings_cmd import settings_keyboard
from bot.templates import msg
from configs import COMMANDS
from middleware.loggers import logger
__all__ = ("router",)
CMD: str = "set_name".lower()
router: Router = Router(name=f"{CMD}_cmd_router")
class SetNameForm(StatesGroup):
new_name: State = State()
def format_retry_time(retry_after: int) -> str:
"""Форматирование времени повторной попытки в читаемом виде"""
hours, remainder = divmod(retry_after, 3600)
minutes, seconds = divmod(remainder, 60)
if hours > 0:
return f"{hours} часов, {minutes} минут, {seconds} секунд"
elif minutes > 0:
return f"{minutes} минут, {seconds} секунд"
else:
return f"{seconds} секунд"
async def handle_set_name(
new_name: str,
message: Message | CallbackQuery,
state: FSMContext,
bot: Bot
) -> None:
"""
Установка имени бота с проверкой длины, обработкой перегрузки и логированием
"""
if len(new_name) > 64:
await msg(
update=message,
text=_("❌ Имя бота должно быть не более 64 символов. Текущая длина: {length}").format(
length=len(new_name)
),
markup=settings_keyboard(),
state=state
)
return
try:
await bot.set_my_name(new_name)
BotInfo.first_name = new_name
await state.clear()
await msg(
update=message,
text=_("✅ Имя бота успешно изменено на: <b>{new_name}</b>").format(new_name=new_name),
markup=settings_keyboard(),
state=state
)
logger.info(f"Имя бота изменено на: {new_name}")
except TelegramRetryAfter as e:
retry_text: str = format_retry_time(e.retry_after)
logger.warning(f"Превышен контроль перегрузки при смене имени. Попробуйте через {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, IsOwner())
@router.message(Command(*COMMANDS[CMD], prefix=BotInfo.prefix, ignore_case=True), IsOwner())
async def settings_cmd(
message: Message | CallbackQuery,
state: FSMContext,
bot: Bot,
command: CommandObject | None = None
):
"""
Обработчик команды /set_name с поддержкой:
1. Immediate установки через аргумент команды
2. Callback query
3. FSM ввод
"""
current_name = getattr(BotInfo, "first_name", "") or _("Не установлено")
# Immediate установка через аргумент команды
if command and command.args:
new_name = command.args.strip()
if len(new_name) > 64:
await msg(
update=message,
text=_("❌ Имя не должно превышать 64 символа. Текущая длина: {length}").format(
length=len(new_name)
),
markup=settings_keyboard(),
state=state
)
return
await handle_set_name(new_name, message, state, bot)
return
# Для callback query или пустой команды — показываем текущее имя и запускаем FSM
await state.clear()
if isinstance(message, CallbackQuery):
await message.answer()
text: str = _(
"🤖 <b>Смена имени бота</b>\n\n"
"Текущее имя: <i>{current}</i>\n\n"
"Пожалуйста, введите новое имя для бота (максимум 64 символа):"
).format(current=current_name)
await msg(update=message, text=text, markup=settings_keyboard(), state=state)
await state.set_state(SetNameForm.new_name)
@router.message(SetNameForm.new_name, IsOwner())
async def process_new_name(message: Message, state: FSMContext, bot: Bot):
"""
Обработка ввода нового имени через FSM
"""
new_name: str = message.text.strip()
if not new_name:
await message.answer(_("❌ Пожалуйста, введите корректное имя."))
return
await handle_set_name(new_name, message, state, bot)