import html from aiogram import Router from aiogram.types import Message from aiogram.fsm.context import FSMContext from bot.api.asf import get_all_bots, send_command from bot.logging_utils import describe_user, get_logger from bot.services.redeem import ( extract_keys, redeem_all_bots_keys, redeem_single_bot_keys, ) from bot.services.bot_accounts import ( get_owned_bot, list_user_activation_bot_accounts, ) from bot.states import ConsoleFlow, RedeemFlow from bot.ui.formatters import format_bot_ui, get_asf_status_text from bot.ui.keyboards import ( main_keyboard, bot_details_keyboard, delete_message_keyboard, ) router = Router() logger = get_logger(__name__) @router.message(ConsoleFlow.waiting_command) async def handle_console_message(message: Message, state: FSMContext): if not message.text: await message.answer("Отправьте текстовую команду.") return command = message.text.strip() if not command: await message.answer("Команда не может быть пустой.") return logger.info( "Пользователь %s отправил консольную команду: %s", describe_user(message.from_user), command, ) try: await message.delete() except Exception: logger.debug( "Не удалось удалить сообщение с консольной командой от %s", describe_user(message.from_user), exc_info=True, ) try: response = send_command(f"!{command}") if response.status_code != 200: logger.warning( "ASF вернул HTTP %s на консольную команду '%s' от %s", response.status_code, command, describe_user(message.from_user), ) text = f"Ошибка HTTP {response.status_code}" else: data = response.json() if not data.get("Success"): logger.warning( "ASF вернул неуспешный ответ на консольную команду '%s' от %s", command, describe_user(message.from_user), ) text = "Ошибка ASF" else: logger.info( "Консольная команда '%s' от %s выполнена успешно", command, describe_user(message.from_user), ) result = html.escape(str(data.get("Result", "Нет ответа"))) text = f"Команда: {command}\n\nОтвет:\n{result}" await message.answer(text, reply_markup=delete_message_keyboard()) except Exception as error: logger.exception( "Ошибка при выполнении консольной команды '%s' от %s", command, describe_user(message.from_user), ) await message.answer(f"Ошибка: {error}") @router.message(RedeemFlow.waiting_bot_keys) async def handle_single_bot_redeem(message: Message, state: FSMContext): state_data = await state.get_data() bot_name = state_data.get("bot_name") account_id = state_data.get("account_id") if not isinstance(account_id, int): await message.answer("Контекст потерян, попробуйте еще раз.") await state.clear() return account = await get_owned_bot(message.from_user.id, account_id) if account is None: await message.answer("Бот больше недоступен для активации ключей.") await state.clear() return bot_name = account.bot_name chat_id = message.chat.id menu_message_id = state_data.get("menu_message_id") logger.info( "Пользователь %s отправил ключи для бота %s", describe_user(message.from_user), bot_name, ) if menu_message_id: try: response = get_all_bots() bot_data = response.json().get("Result", {}).get(bot_name) if bot_data: await message.bot.edit_message_text( text=format_bot_ui(bot_data), reply_markup=bot_details_keyboard( account_id, bool(bot_data.get("HasMobileAuthenticator")) ), disable_web_page_preview=True, chat_id=chat_id, message_id=menu_message_id, ) except Exception: logger.debug( "Не удалось восстановить меню бота %s после ввода ключей от %s", bot_name, describe_user(message.from_user), exc_info=True, ) try: await message.bot.delete_message( chat_id=message.chat.id, message_id=message.message_id ) except Exception: logger.debug( "Не удалось удалить сообщение с ключами для бота %s от %s", bot_name, describe_user(message.from_user), exc_info=True, ) keys = extract_keys(message.text or "") if not keys: logger.info( "В сообщении от %s для бота %s не найдено ключей", describe_user(message.from_user), bot_name, ) await message.answer("Ключи не найдены") await state.clear() return logger.info( "Для бота %s получено %s ключ(ей) от %s", bot_name, len(keys), describe_user(message.from_user), ) checking = await message.answer( f"Аккаунт: {bot_name}\nНайдено ключей: {len(keys)}\nНачинаю активацию..." ) try: await checking.edit_text(await redeem_single_bot_keys(bot_name, keys)) except Exception as error: logger.exception( "Не удалось активировать ключи для бота %s от %s", bot_name, describe_user(message.from_user), ) try: await checking.edit_text(f"Ошибка: {error}") except Exception: await message.answer(f"Ошибка: {error}") finally: await state.clear() @router.message(RedeemFlow.waiting_all_keys) async def handle_all_bots_redeem(message: Message, state: FSMContext): state_data = await state.get_data() chat_id = message.chat.id menu_message_id = state_data.get("menu_message_id") logger.info( "Пользователь %s отправил ключи для активации на всех ботах", describe_user(message.from_user), ) if menu_message_id: try: await message.bot.edit_message_text( text=get_asf_status_text(message.from_user.id), reply_markup=main_keyboard(message.from_user.id), chat_id=chat_id, message_id=menu_message_id, ) except Exception: logger.debug( "Не удалось восстановить главное меню после массовой активации для %s", describe_user(message.from_user), exc_info=True, ) try: await message.bot.delete_message( chat_id=message.chat.id, message_id=message.message_id ) except Exception: logger.debug( "Не удалось удалить сообщение с массовой активацией от %s", describe_user(message.from_user), exc_info=True, ) keys = extract_keys(message.text or "") if not keys: logger.info( "В сообщении от %s для массовой активации не найдено ключей", describe_user(message.from_user), ) await message.answer("Ключи не найдены") await state.clear() return logger.info( "Для массовой активации получено %s ключ(ей) от %s", len(keys), describe_user(message.from_user), ) checking = await message.answer( f"Найдено ключей: {len(keys)}\nНачинаю активацию..." ) try: accounts = await list_user_activation_bot_accounts(message.from_user.id) await checking.edit_text( await redeem_all_bots_keys(keys, [account.bot_name for account in accounts]) ) except Exception as error: logger.exception( "Ошибка при массовой активации ключей от %s", describe_user(message.from_user), ) await checking.edit_text(f"Ошибка: {error}") await state.clear()