From c1021ae8f144811f5f604356e9d2c3aa49816094 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 23 Nov 2025 16:50:19 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=B8=D0=BB=20?= =?UTF-8?q?=D0=BB=D0=BE=D0=B3=D0=B8=D0=BA=D1=83=20=D0=B1=D0=BE=D1=82=D0=B0?= =?UTF-8?q?=20/=20=D1=84=D0=B8=D0=BA=D1=81=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- handlers/profile.py | 128 +++++++++++++---- handlers/start.py | 66 ++++++--- keyboard/keyboards.py | 315 ++++++++++++++++++++++++++++++++++-------- 3 files changed, 399 insertions(+), 110 deletions(-) diff --git a/handlers/profile.py b/handlers/profile.py index dc348d7..940ec51 100644 --- a/handlers/profile.py +++ b/handlers/profile.py @@ -6,13 +6,21 @@ from aiogram.enums.parse_mode import ParseMode import locale from instences.config import BASE_URL_FASTAPI import aiohttp -from keyboard.keyboards import account_keyboard, popup_keyboard, tranhist_keyboard, confirm_popup_keyboard, guide_keyboard, balance_keyboard +from keyboard.keyboards import ( + account_keyboard, + popup_keyboard, + tranhist_keyboard, + confirm_popup_keyboard, + guide_keyboard, + balance_keyboard, +) locale.setlocale(locale.LC_TIME, "ru_RU.UTF-8") router = Router() logger = logging.getLogger(__name__) + async def call_api(method, endpoint, data=None): """ Выполняет HTTP-запрос к FastAPI. @@ -23,7 +31,8 @@ async def call_api(method, endpoint, data=None): try: async with aiohttp.ClientSession() as session: async with session.request(method, url, json=data) as response: - logger.info(f"Получен ответ от {url}: статус {response.status}") + logger.info( + f"Получен ответ от {url}: статус {response.status}") if response.status in {200, 201}: result = await response.json() @@ -32,21 +41,27 @@ async def call_api(method, endpoint, data=None): if response.status == 404: logger.debug(f"Код {response.status}, возвращаю ничего") return None - logger.error(f"Ошибка в запросе: статус {response.status}, причина {response.reason}") + logger.error( + f"Ошибка в запросе: статус {response.status}, причина {response.reason}" + ) return "ERROR" except Exception as e: logger.exception(f"Исключение при выполнении запроса к {url}: {e}") return "ERROR" + @router.callback_query(lambda callback: callback.data == "profile") async def profile_callback_handler(callback: CallbackQuery): """ - Обработчик callback_query для профиля. + Профиль пользователя. + Логика работы с API сохранена, переписан только текст/визуал. """ try: user_data = await call_api("GET", f"/user/{callback.from_user.id}") if not user_data: - await callback.message.answer("Произошла ошибка, попробуйте позже или свяжитесь с администрацией.") + await callback.message.answer( + "Произошла ошибка, попробуйте позже или свяжитесь с администрацией." + ) await callback.answer() return @@ -54,21 +69,49 @@ async def profile_callback_handler(callback: CallbackQuery): if sub_data == "ERROR" or not isinstance(sub_data, dict): sub_data = None - balance_text = f"Баланс: {user_data['balance']} ₽" + balance_text = f"💰 Баланс: {user_data['balance']} ₽" + username = callback.from_user.username or "пользователь" + + # Нет подписки if not sub_data: - text = f"Профиль {callback.from_user.username}\n{balance_text}\nПополните баланс и приобретите подписку, чтобы получить активный статус (🐣,🦅)" + text = ( + f"📜 Профиль {username}\n\n" + f"{balance_text}\n\n" + "У тебя пока нет активной подписки.\n" + "Пополняй баланс и подключай тариф Lark, чтобы получить статус 🐣 или 🦅." + ) else: expiry_date = sub_data.get("expiry_date") - formatted_date = datetime.fromisoformat(expiry_date).strftime("%d %B %Y г.") if expiry_date else None - is_expired = datetime.fromisoformat(expiry_date) < datetime.now() if expiry_date else True + formatted_date = ( + datetime.fromisoformat(expiry_date).strftime("%d %B %Y г.") + if expiry_date + else None + ) + is_expired = ( + datetime.fromisoformat(expiry_date) < datetime.now() + if expiry_date + else True + ) status_icon = "✖️" if is_expired else "☑️" profile_status = "🦅" if "Pro" in sub_data.get("plan", "") else "🐣" - sub_text = ( - f"Ваша подписка действует до {formatted_date} {status_icon}" - if not is_expired else f"Статус подписки: {status_icon}" + + if not is_expired and formatted_date: + sub_text = ( + f"Подписка активна до {formatted_date} {status_icon}\n" + f"Текущий статус: {profile_status}" + ) + else: + sub_text = ( + f"Подписка неактивна {status_icon}\n" + "Ты можешь продлить её в разделе подписок." + ) + + text = ( + f"📜 Профиль {username} {profile_status}\n\n" + f"{sub_text}\n\n" + f"{balance_text}" ) - text = f"Профиль {callback.from_user.username} {profile_status}:\n{sub_text}\n{balance_text}" await callback.message.edit_text(text, reply_markup=account_keyboard()) except Exception as e: @@ -77,6 +120,7 @@ async def profile_callback_handler(callback: CallbackQuery): finally: await callback.answer() + @router.callback_query(lambda callback: callback.data == "balance") async def balance_callback_handler(callback: CallbackQuery): """ @@ -84,34 +128,45 @@ async def balance_callback_handler(callback: CallbackQuery): """ user_data = await call_api("GET", f"/user/{callback.from_user.id}") if not user_data: - await callback.message.answer("Произошла ошибка, попробуйте позже или свяжитесь с администрацией.") + await callback.message.answer( + "Произошла ошибка, попробуйте позже или свяжитесь с администрацией." + ) await callback.answer() return await callback.message.edit_text( - f"Ваш баланс: {user_data['balance']} ₽. Выберите сумму для пополнения 🐥", - reply_markup=balance_keyboard() + f"💰 Текущий баланс: {user_data['balance']} ₽\n\n" + "Выбери сумму, на которую хочешь пополнить счёт.", + reply_markup=balance_keyboard(), ) await callback.answer() + @router.callback_query(lambda callback: callback.data == "popup") async def popup_callback_handler(callback: CallbackQuery): """ - Обработчик callback_query для пополнения. + Обработчик callback_query для выбора суммы пополнения. """ user = await call_api("GET", f"/user/{callback.from_user.id}") if not user: - await callback.message.answer("Произошла ошибка, попробуйте позже или свяжитесь с администрацией.") + await callback.message.answer( + "Произошла ошибка, попробуйте позже или свяжитесь с администрацией." + ) await callback.answer() return - await callback.message.edit_text("Работает в режиме теста!!!", reply_markup=popup_keyboard()) + await callback.message.edit_text( + "Выбери сумму для пополнения баланса.", + reply_markup=popup_keyboard(), + ) await callback.answer() + @router.callback_query(lambda callback: callback.data == "tranhist") async def tranhist_callback_handler(callback: CallbackQuery): """ Обработчик callback_query для истории транзакций. + (Логику и формат Markdown_V2 не трогаем, чтобы не поймать новые баги) """ user_data = await call_api("GET", f"/user/{callback.from_user.id}") if not user_data: @@ -122,25 +177,34 @@ async def tranhist_callback_handler(callback: CallbackQuery): try: transactions = await call_api("GET", f"/user/{user_data['id']}/transactions") if not transactions: - await callback.message.edit_text("У вас нет транзакций.", reply_markup=tranhist_keyboard()) + await callback.message.edit_text( + "У вас нет транзакций.", reply_markup=tranhist_keyboard() + ) await callback.answer() return result = "Ваши транзакции:```\n" for count, tran in enumerate(transactions, start=1): - dt = datetime.fromisoformat(tran['created_at']).strftime("%d.%m.%Y %H:%M:%S") + dt = datetime.fromisoformat(tran["created_at"]).strftime( + "%d.%m.%Y %H:%M:%S" + ) result += f"{count}. Сумма: {tran['amount']}, Дата: {dt}\n" if len(result) > 4000: result += "...\nСлишком много транзакций для отображения." break result += "```" - await callback.message.edit_text(result,parse_mode=ParseMode.MARKDOWN_V2, reply_markup=tranhist_keyboard()) + await callback.message.edit_text( + result, + parse_mode=ParseMode.MARKDOWN_V2, + reply_markup=tranhist_keyboard(), + ) except Exception as e: logger.error(f"Ошибка обработки транзакций: {e}") await callback.message.edit_text("Произошла ошибка. Попробуйте позже.") finally: await callback.answer() + @router.callback_query(lambda callback: callback.data.startswith("popup:")) async def popup_confirm_callback_handler(callback: CallbackQuery): """ @@ -148,23 +212,31 @@ async def popup_confirm_callback_handler(callback: CallbackQuery): """ data = callback.data.split(":") popup_info = data[1] - result = await call_api("POST", f"/user/{callback.from_user.id}/balance/{float(popup_info)}") + result = await call_api( + "POST", + f"/user/{callback.from_user.id}/balance/{float(popup_info)}", + ) if result == "ERROR": - await callback.message.answer("Произошла ошибка, попробуйте позже или свяжитесь с администрацией.") + await callback.message.answer( + "Произошла ошибка, попробуйте позже или свяжитесь с администрацией." + ) await callback.answer() return - text = f"Вы пополнили свой баланс на {popup_info} ₽. Спасибо!" - await callback.message.edit_text(text=text, reply_markup=confirm_popup_keyboard()) + text = f"✅ Баланс пополнен на {popup_info} ₽. Спасибо, что остаёшься с Lark." + await callback.message.edit_text( + text=text, reply_markup=confirm_popup_keyboard() + ) await callback.answer() + @router.callback_query(lambda callback: callback.data == "guide") async def guide_callback_handler(callback: CallbackQuery): """ Обработчик callback_query для руководства. """ await callback.message.edit_text( - "Руководство по использованию продукта:", - reply_markup=guide_keyboard() + "Выбери платформу, для которой нужно руководство по подключению:", + reply_markup=guide_keyboard(), ) await callback.answer() diff --git a/handlers/start.py b/handlers/start.py index 47bbee8..65b6f29 100644 --- a/handlers/start.py +++ b/handlers/start.py @@ -9,6 +9,7 @@ from keyboard.keyboards import main_keyboard router = Router() logger = logging.getLogger(__name__) + async def call_api(method, endpoint, data=None): """ Выполняет HTTP-запрос к FastAPI. @@ -23,7 +24,8 @@ async def call_api(method, endpoint, data=None): try: async with aiohttp.ClientSession() as session: async with session.request(method, url, json=data) as response: - logger.info(f"Получен ответ от {url}: статус {response.status}") + logger.info( + f"Получен ответ от {url}: статус {response.status}") if response.status in {200, 201}: result = await response.json() @@ -32,61 +34,79 @@ async def call_api(method, endpoint, data=None): if response.status == 404: logger.debug(f"Код {response.status}, возвращаю ничего") return None - logger.error(f"Ошибка в запросе: статус {response.status}, причина {response.reason}") + logger.error( + f"Ошибка в запросе: статус {response.status}, причина {response.reason}") return "ERROR" except Exception as e: logger.exception(f"Исключение при выполнении запроса к {url}: {e}") return "ERROR" + +def _welcome_text(username: str | None) -> str: + uname = username or "птенец" + return ( + f"🪽 Добро пожаловать в Lark VPN, {uname}!\n\n" + "Здесь ты получаешь стабильный доступ к TikTok, YouTube, Discord, Instagram " + "и другим сервисам без ограничений.\n\n" + "1️⃣ Пополни баланс\n" + "2️⃣ Выбери подходящий тариф\n" + "3️⃣ Подключай конфиг на своих устройствах и забудь про блокировки.\n\n" + "Следи за акциями и розыгрышами в канале:\n" + "https://t.me/+0z5xqn3F1m02OTJi\n\n" + "Lark держит связь. 🐣🦅" + ) + + @router.message(Command("start")) async def start_command(message: Message): """ Обработчик команды /start. + Визуал и текст — обновлены, логика работы с API не тронута. """ - logger.info(f"Получена команда /start от пользователя: {message.from_user.id} ({message.from_user.username})") + logger.info( + f"Получена команда /start от пользователя: " + f"{message.from_user.id} ({message.from_user.username})" + ) try: user_data = await call_api("GET", f"/user/{message.from_user.id}") if not user_data: - logger.debug("Пользователь не найден в базе, создаем новую запись.") + logger.debug( + "Пользователь не найден в базе, создаем новую запись.") await call_api("POST", "/user/create", {"telegram_id": message.from_user.id}) logger.debug("Отправка приветственного сообщения пользователю.") await message.answer( - f"""Приветствуем в рядах птенец {message.from_user.username}🐣 - \nСкорее пополни баланс, приобрети подписку и получай доступ к TikTok, YouTube, Discord, Instagram на всех устройствах без ограничений ❕❕❕ - \nОзнакомься с руководством по пользованию и выбери подходящий тариф 🦅 - \nСледи за акциями, спец-предложениями, а также розыгрышами по ссылке ниже - \n👇👇👇 - \nhttps://t.me/+0z5xqn3F1m02OTJi - \nС любовью ваши пернатые разработчики 🤍🤍🤍""", - reply_markup=main_keyboard() + _welcome_text(message.from_user.username), + reply_markup=main_keyboard(), ) logger.info("Приветственное сообщение отправлено.") - except Exception as e: - logger.exception(f"Ошибка при обработке команды /start для пользователя {message.from_user.id}: {e}") + logger.exception( + f"Ошибка при обработке команды /start для пользователя " + f"{message.from_user.id}: {e}" + ) await message.answer("Произошла ошибка. Попробуйте позже.") + @router.callback_query(lambda callback: callback.data == "base") async def start_callback_handler(callback: CallbackQuery): """ Обработчик callback_query с data="base". + Возвращает пользователя в главное меню. """ try: user_data = await call_api("GET", f"/user/{callback.from_user.id}") if not user_data: - await call_api("POST", "/user/create", {"telegram_id": callback.from_user.id}) + await call_api( + "POST", + "/user/create", + {"telegram_id": callback.from_user.id}, + ) await callback.message.edit_text( - f"""Приветствуем в рядах птенец {callback.from_user.username}🐣 - \nСкорее пополни баланс, приобрети подписку и получай доступ к TikTok, YouTube, Discord, Instagram на всех устройствах без ограничений ❕❕❕ - \nОзнакомься с руководством по пользованию и выбери подходящий тариф 🦅 - \nСледи за акциями, спец-предложениями, а также розыгрышами по ссылке ниже - \n👇👇👇 - \nhttps://t.me/+0z5xqn3F1m02OTJi - \nС любовью ваши пернатые разработчики 🤍🤍🤍""", - reply_markup=main_keyboard() + _welcome_text(callback.from_user.username), + reply_markup=main_keyboard(), ) except Exception as e: logger.exception(f"Ошибка при обработке callback с data='base': {e}") diff --git a/keyboard/keyboards.py b/keyboard/keyboards.py index 604e5cd..f4f78ae 100644 --- a/keyboard/keyboards.py +++ b/keyboard/keyboards.py @@ -4,156 +4,353 @@ from aiogram.types import InlineKeyboardButton, KeyboardButton def main_keyboard(): """ - База + Главное меню (только визуал перетянут под твой стиль) """ builder = InlineKeyboardBuilder() - builder.row(InlineKeyboardButton(text="Профиль", callback_data="profile")) - builder.row(InlineKeyboardButton(text="❔FAQ❔", callback_data="faq")) - builder.row(InlineKeyboardButton(text="О нас", url="https://www.youtube.com/watch?v=Zirn-CKck-c")) + builder.row(InlineKeyboardButton( + text="📜 Профиль", callback_data="profile")) + builder.row(InlineKeyboardButton(text="❔ FAQ ❔", callback_data="faq")) + # Оставляем URL как у Вовы, меняем только текст + builder.row( + InlineKeyboardButton( + text="ℹ️ О нас", + url="https://www.youtube.com/watch?v=Zirn-CKck-c" + ) + ) return builder.as_markup() + def account_keyboard(): """ - Аккаунт + Аккаунт / профиль + Визуал — твой, callback_data — как у Вовы. """ builder = InlineKeyboardBuilder() - builder.row(InlineKeyboardButton(text="Пополнение баланса", callback_data="popup")) - builder.row(InlineKeyboardButton(text="Приобрести подписку", callback_data="buy_subscription")) - builder.row(InlineKeyboardButton(text="Руководство по подключению", callback_data="guide")) - builder.row(InlineKeyboardButton(text="📑История транзакций", callback_data="tranhist")) - builder.row(InlineKeyboardButton(text="Назад", callback_data="base")) + builder.row( + InlineKeyboardButton( + text="🪙 Пополнить баланс", + callback_data="popup", + ) + ) + builder.row( + InlineKeyboardButton( + text="🦴 Мои подписки", + callback_data="buy_subscription", + ) + ) + builder.row( + InlineKeyboardButton( + text="📡 Руководство по подключению", + callback_data="guide", + ) + ) + builder.row( + InlineKeyboardButton( + text="🧾 История транзакций", + callback_data="tranhist", + ) + ) + builder.row( + InlineKeyboardButton( + text="🔙 Назад", + callback_data="base", + ) + ) return builder.as_markup() + def ticket_list_keyboard(tickets): builder = InlineKeyboardBuilder() for ticket in tickets: - builder.row(InlineKeyboardButton(text=f"Тикет: {ticket['subject']}",callback_data=f"ticket_{ticket['id']}")) - builder.row(InlineKeyboardButton(text="Назад", callback_data="main_sup")) + builder.row( + InlineKeyboardButton( + text=f"Тикет: {ticket['subject']}", + callback_data=f"ticket_{ticket['id']}", + ) + ) + builder.row( + InlineKeyboardButton( + text="🔙 Назад", + callback_data="main_sup", + ) + ) return builder.as_markup() - + def sup_keyboard(): builder = InlineKeyboardBuilder() - builder.row(InlineKeyboardButton(text="Создать запрос", callback_data="make_ticket")) - builder.row(InlineKeyboardButton(text="Мои запросы", callback_data="my_tickets")) + builder.row( + InlineKeyboardButton( + text="📝 Создать запрос", + callback_data="make_ticket", + ) + ) + builder.row( + InlineKeyboardButton( + text="📂 Мои запросы", + callback_data="my_tickets", + ) + ) return builder.as_markup() + def ticket_keyboard(): builder = InlineKeyboardBuilder() - builder.row(InlineKeyboardButton(text="Отмена", callback_data="cancel")) + builder.row( + InlineKeyboardButton( + text="🔙 Отмена", + callback_data="cancel", + ) + ) return builder.as_markup() + def buy_keyboard(): """ - Приобрести подписку + Меню выбора тарифа. + Лейблы ближе к твоему стилю, но callback’и остаются старые. """ builder = InlineKeyboardBuilder() - builder.row(InlineKeyboardButton(text="Тариф Lark", callback_data="subs")) - builder.row(InlineKeyboardButton(text="Тариф Lark Pro", callback_data="subs_pro")) - builder.row(InlineKeyboardButton(text="О тарифах", url="https://t.me/proxylark/19")) - builder.row(InlineKeyboardButton(text="Назад", callback_data="profile")) + builder.row( + InlineKeyboardButton( + text="🐣 Lark (Basic)", + callback_data="subs", + ) + ) + builder.row( + InlineKeyboardButton( + text="🦅 Lark Pro", + callback_data="subs_pro", + ) + ) + builder.row( + InlineKeyboardButton( + text="ℹ️ О тарифах", + url="https://t.me/proxylark/19", + ) + ) + builder.row( + InlineKeyboardButton( + text="🔙 Назад", + callback_data="profile", + ) + ) return builder.as_markup() + def subhist_keyboard(): """ - Подписки + Подписки — история/список """ builder = InlineKeyboardBuilder() - builder.button(text="Назад", callback_data="profile") + builder.row( + InlineKeyboardButton( + text="🔙 Назад", + callback_data="profile", + ) + ) return builder.as_markup() + def popup_keyboard(): """ - Пополнение + Пополнение (суммы, стиль как в твоём topup_menu) """ builder = InlineKeyboardBuilder() - builder.row(InlineKeyboardButton(text="200₽", callback_data="popup:200"),InlineKeyboardButton(text="500₽", callback_data="popup:500")) - builder.row(InlineKeyboardButton(text="1000₽", callback_data="popup:1000"),InlineKeyboardButton(text="2000₽", callback_data="popup:2000")) - builder.row(InlineKeyboardButton(text="3000₽", callback_data="popup:3000"),InlineKeyboardButton(text="5000₽", callback_data="popup:5000")) - builder.row(InlineKeyboardButton(text="Назад", callback_data="profile")) + builder.row( + InlineKeyboardButton(text="200 ₽", callback_data="popup:200"), + InlineKeyboardButton(text="500 ₽", callback_data="popup:500"), + ) + builder.row( + InlineKeyboardButton(text="1000 ₽", callback_data="popup:1000"), + InlineKeyboardButton(text="2000 ₽", callback_data="popup:2000"), + ) + builder.row( + InlineKeyboardButton(text="3000 ₽", callback_data="popup:3000"), + InlineKeyboardButton(text="5000 ₽", callback_data="popup:5000"), + ) + builder.row( + InlineKeyboardButton( + text="🔙 Назад", + callback_data="profile", + ) + ) return builder.as_markup() + def balance_keyboard(): """ Баланс """ builder = InlineKeyboardBuilder() - builder.row(InlineKeyboardButton(text="Пополнение", callback_data="popup")) - builder.row(InlineKeyboardButton(text="История транзакций", callback_data="tranhist")) - builder.row(InlineKeyboardButton(text="Назад", callback_data="profile")) + builder.row( + InlineKeyboardButton( + text="🪙 Пополнить баланс", + callback_data="popup", + ) + ) + builder.row( + InlineKeyboardButton( + text="🧾 История транзакций", + callback_data="tranhist", + ) + ) + builder.row( + InlineKeyboardButton( + text="🔙 Назад", + callback_data="profile", + ) + ) return builder.as_markup() + def tarif_Lark_keyboard(): """ - Тариф Lark + Тариф Lark (Standart) — только подписи меняем. """ builder = InlineKeyboardBuilder() - builder.row(InlineKeyboardButton(text="Тариф Lark 1 Месяц", callback_data="Lark:Standart:1")) - builder.row(InlineKeyboardButton(text="Тариф Lark 6 Месяц", callback_data="Lark:Standart:6")) - builder.row(InlineKeyboardButton(text="Тариф Lark 12 Месяц", callback_data="Lark:Standart:12")) - builder.row(InlineKeyboardButton(text="Назад", callback_data="buy_subscription")) + builder.row( + InlineKeyboardButton( + text="🐣 Lark 1 месяц", + callback_data="Lark:Standart:1", + ) + ) + builder.row( + InlineKeyboardButton( + text="🐣 Lark 6 месяцев", + callback_data="Lark:Standart:6", + ) + ) + builder.row( + InlineKeyboardButton( + text="🐣 Lark 12 месяцев", + callback_data="Lark:Standart:12", + ) + ) + builder.row( + InlineKeyboardButton( + text="🔙 Назад", + callback_data="buy_subscription", + ) + ) return builder.as_markup() + def tarif_Lark_pro_keyboard(): """ Тариф Lark Pro """ builder = InlineKeyboardBuilder() - builder.row(InlineKeyboardButton(text="Тариф Lark Pro 1 Месяц", callback_data="Lark:Pro:1")) - builder.row(InlineKeyboardButton(text="Тариф Lark Pro 6 Месяц", callback_data="Lark:Pro:6")) - builder.row(InlineKeyboardButton(text="Тариф Lark Pro 12 Месяц", callback_data="Lark:Pro:12")) - builder.row(InlineKeyboardButton(text="Назад", callback_data="buy_subscription")) + builder.row( + InlineKeyboardButton( + text="🦅 Lark Pro 1 месяц", + callback_data="Lark:Pro:1", + ) + ) + builder.row( + InlineKeyboardButton( + text="🦅 Lark Pro 6 месяцев", + callback_data="Lark:Pro:6", + ) + ) + builder.row( + InlineKeyboardButton( + text="🦅 Lark Pro 12 месяцев", + callback_data="Lark:Pro:12", + ) + ) + builder.row( + InlineKeyboardButton( + text="🔙 Назад", + callback_data="buy_subscription", + ) + ) return builder.as_markup() + def guide_keyboard(): """ Руководство по подключению """ builder = InlineKeyboardBuilder() - builder.row(InlineKeyboardButton(text="IOS,Android", callback_data="mob")) - builder.row(InlineKeyboardButton(text="Windows,MacOS", callback_data="pc")) - builder.row(InlineKeyboardButton(text="Назад", callback_data="profile")) + builder.row( + InlineKeyboardButton( + text="📱 iOS / Android", + callback_data="mob", + ) + ) + builder.row( + InlineKeyboardButton( + text="💻 Windows / macOS", + callback_data="pc", + ) + ) + builder.row( + InlineKeyboardButton( + text="🔙 Назад", + callback_data="profile", + ) + ) return builder.as_markup() -# def about_tarifs_keyboard(): -# """ -# О тарифах -# """ -# builder = InlineKeyboardBuilder() -# builder.row(InlineKeyboardButton(text="Назад", callback_data="buy_subscription")) -# return builder.as_markup() - - def faq_keyboard(): """ FAQ """ builder = InlineKeyboardBuilder() - builder.row(InlineKeyboardButton(text="Назад", callback_data="base")) + builder.row( + InlineKeyboardButton( + text="🔙 Назад", + callback_data="base", + ) + ) return builder.as_markup() + def tranhist_keyboard(): """ История транзакций """ builder = InlineKeyboardBuilder() - builder.row(InlineKeyboardButton(text="Назад",callback_data="profile")) + builder.row( + InlineKeyboardButton( + text="🔙 Назад", + callback_data="profile", + ) + ) return builder.as_markup() -def tarif_confirm_keyboard(name,amount,classif): + +def tarif_confirm_keyboard(name, amount, classif): """ Подтверждение покупки тарифа """ builder = InlineKeyboardBuilder() - builder.row(InlineKeyboardButton(text="Подтвердить", callback_data=f"confirm:{name}_{classif}_{amount}")) - builder.row(InlineKeyboardButton(text="Отменить",callback_data="buy_subscription")) + builder.row( + InlineKeyboardButton( + text="✅ Подтвердить", + callback_data=f"confirm:{name}_{classif}_{amount}", + ) + ) + builder.row( + InlineKeyboardButton( + text="🔙 Отменить", + callback_data="buy_subscription", + ) + ) return builder.as_markup() + def confirm_popup_keyboard(): """ - Подтверждение пополнения + Подтверждение пополнения — без «иди нахуй», мы же под босса господина ларк это красим.... """ builder = InlineKeyboardBuilder() - builder.row(InlineKeyboardButton(text="Теперь иди нахуй", callback_data="profile")) + builder.row( + InlineKeyboardButton( + text="✅ Готово, вернуться в профиль", + callback_data="profile", + ) + ) return builder.as_markup()