Настройка виджета бота
This commit is contained in:
174
bot/handlers/commands/settings/set_widget_cmd.py
Normal file
174
bot/handlers/commands/settings/set_widget_cmd.py
Normal file
@@ -0,0 +1,174 @@
|
|||||||
|
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 bot.utils import format_retry_time, status_clear
|
||||||
|
from configs import COMMANDS
|
||||||
|
from middleware.loggers import logger
|
||||||
|
|
||||||
|
__all__ = ("router",)
|
||||||
|
CMD: str = "set_widget".lower()
|
||||||
|
router: Router = Router(name=f"{CMD}_cmd_router")
|
||||||
|
|
||||||
|
|
||||||
|
class SetWidgetForm(StatesGroup):
|
||||||
|
"""Состояния FSM для изменения виджета (описания бота)."""
|
||||||
|
new_widget: State = State()
|
||||||
|
|
||||||
|
|
||||||
|
async def handle_set_widget(
|
||||||
|
new_widget: str,
|
||||||
|
message: Message | CallbackQuery,
|
||||||
|
state: FSMContext,
|
||||||
|
bot: Bot
|
||||||
|
) -> None:
|
||||||
|
"""
|
||||||
|
Устанавливает новое значение виджета (описания бота).
|
||||||
|
|
||||||
|
Args:
|
||||||
|
new_widget (str): Новый текст виджета.
|
||||||
|
message (Message | CallbackQuery): Объект сообщения или callback-запроса.
|
||||||
|
state (FSMContext): Контекст состояния FSM.
|
||||||
|
bot (Bot): Экземпляр текущего бота.
|
||||||
|
"""
|
||||||
|
# Проверка длины текста (Telegram API ограничивает description до 512 символов)
|
||||||
|
if len(new_widget) > 512:
|
||||||
|
await msg(
|
||||||
|
update=message,
|
||||||
|
text=_("❌ Виджет бота должен быть не более 512 символов. Текущая длина: {length}").format(
|
||||||
|
length=len(new_widget)
|
||||||
|
),
|
||||||
|
markup=settings_keyboard(),
|
||||||
|
state=state
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Устанавливаем описание через Telegram API
|
||||||
|
await bot.set_my_description(description=new_widget)
|
||||||
|
|
||||||
|
# Сохраняем в BotInfo для локального использования
|
||||||
|
BotInfo.widget = new_widget
|
||||||
|
|
||||||
|
# Очищаем состояние FSM
|
||||||
|
await state.clear()
|
||||||
|
|
||||||
|
# Отправляем уведомление пользователю
|
||||||
|
await msg(
|
||||||
|
update=message,
|
||||||
|
text=_("✅ Виджет бота успешно изменён на: <b>{new_widget}</b>").format(
|
||||||
|
new_widget=new_widget
|
||||||
|
),
|
||||||
|
markup=settings_keyboard(),
|
||||||
|
state=state
|
||||||
|
)
|
||||||
|
|
||||||
|
logger.info(f"Виджет бота изменён на: {new_widget}")
|
||||||
|
|
||||||
|
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:
|
||||||
|
# Ошибка Telegram API
|
||||||
|
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
|
||||||
|
) -> None:
|
||||||
|
"""
|
||||||
|
Обработчик команды /set_widget.
|
||||||
|
|
||||||
|
Поддерживает:
|
||||||
|
1. Немедленное изменение через аргумент команды (/set_widget TEXT).
|
||||||
|
2. Callback-запрос.
|
||||||
|
3. FSM ввод.
|
||||||
|
"""
|
||||||
|
# Получаем текущее значение виджета
|
||||||
|
current_widget: str = BotInfo.short_description
|
||||||
|
|
||||||
|
# Вариант 1: пользователь ввёл аргумент сразу (/set_widget TEXT)
|
||||||
|
if command and command.args:
|
||||||
|
new_widget: str = command.args.strip()
|
||||||
|
if len(new_widget) > 512:
|
||||||
|
await msg(
|
||||||
|
update=message,
|
||||||
|
text=_("❌ Виджет не должен превышать 512 символов. Текущая длина: {length}").format(
|
||||||
|
length=len(new_widget)
|
||||||
|
),
|
||||||
|
markup=settings_keyboard(),
|
||||||
|
state=state
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
await handle_set_widget(new_widget, message, state, bot)
|
||||||
|
return
|
||||||
|
|
||||||
|
# Вариант 2: Callback query или пустая команда → запускаем FSM
|
||||||
|
await status_clear(update=message, state=state)
|
||||||
|
text: str = _(
|
||||||
|
"📝 <b>Смена виджета бота</b>\n\n"
|
||||||
|
"Текущий виджет: <i>{current}</i>\n\n"
|
||||||
|
"Пожалуйста, введите новый виджет для бота (максимум 512 символов):"
|
||||||
|
).format(current=current_widget)
|
||||||
|
|
||||||
|
await msg(update=message, text=text, markup=settings_keyboard(), state=state)
|
||||||
|
await state.set_state(SetWidgetForm.new_widget)
|
||||||
|
|
||||||
|
|
||||||
|
@router.message(SetWidgetForm.new_widget, IsOwner())
|
||||||
|
async def process_new_widget(
|
||||||
|
message: Message,
|
||||||
|
state: FSMContext,
|
||||||
|
bot: Bot
|
||||||
|
) -> None:
|
||||||
|
"""
|
||||||
|
Обрабатывает ввод нового текста виджета через FSM.
|
||||||
|
"""
|
||||||
|
new_widget: str = message.text.strip()
|
||||||
|
|
||||||
|
# Проверяем, что пользователь что-то ввёл
|
||||||
|
if not new_widget:
|
||||||
|
await message.answer(_("❌ Пожалуйста, введите корректный виджет."))
|
||||||
|
return
|
||||||
|
|
||||||
|
await handle_set_widget(new_widget, message, state, bot)
|
||||||
Reference in New Issue
Block a user