From 5997d67640f887b55dd2087735d3b442afa7855d Mon Sep 17 00:00:00 2001 From: Disledg Date: Sat, 4 Jan 2025 21:19:39 +0300 Subject: [PATCH] =?UTF-8?q?=D0=92=D0=BE=D0=B7=D0=BC=D0=BE=D0=B6=D0=BD?= =?UTF-8?q?=D0=BE=D1=81=D1=82=D1=8C=20=D1=82=D0=B8=D0=BA=D0=B5=D1=82=D1=8B?= =?UTF-8?q?=20=D1=81=D0=BE=D0=B7=D0=B4=D0=B0=D0=B2=D0=B0=D1=82=D1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Lark_VPN_Bot.code-workspace | 11 ++++ handlers/handlers.py | 121 +++++++++++++++++++++++++++++------- keyboard/keyboards.py | 14 +++-- main.py | 4 +- 4 files changed, 121 insertions(+), 29 deletions(-) create mode 100644 Lark_VPN_Bot.code-workspace diff --git a/Lark_VPN_Bot.code-workspace b/Lark_VPN_Bot.code-workspace new file mode 100644 index 0000000..15bbdbb --- /dev/null +++ b/Lark_VPN_Bot.code-workspace @@ -0,0 +1,11 @@ +{ + "folders": [ + { + "path": "." + }, + { + "path": "../Bot" + } + ], + "settings": {} +} \ No newline at end of file diff --git a/handlers/handlers.py b/handlers/handlers.py index 8f025c5..74f7681 100644 --- a/handlers/handlers.py +++ b/handlers/handlers.py @@ -6,7 +6,7 @@ from datetime import datetime from instences.config import BASE_URL_FASTAPI import locale locale.setlocale(locale.LC_TIME, "ru_RU.UTF-8") -from keyboard.keyboards import subhist_keyboard,confirm_popup_keyboard,tarif_confirm_keyboard, popup_keyboard, main_keyboard,faq_keyboard, account_keyboard, buy_keyboard,balance_keyboard,guide_keyboard,tarif_Lark_keyboard,tarif_Lark_pro_keyboard,tranhist_keyboard +from keyboard.keyboards import subhist_keyboard,confirm_popup_keyboard,tarif_confirm_keyboard,ticket_keyboard, popup_keyboard, main_keyboard,faq_keyboard, account_keyboard, buy_keyboard,balance_keyboard,guide_keyboard,tarif_Lark_keyboard,tarif_Lark_pro_keyboard,tranhist_keyboard logger = logging.getLogger(__name__) # Инициализируем менеджер базы данных @@ -40,16 +40,105 @@ async def call_api(method, endpoint, data=None): return "ERROR" -async def popup_command(message: types.Message): +user_state = {} + +async def start_ticket_creation(message: types.Message): """ - Обработчик команды для отправки popup-сообщения. + Начинает процесс создания тикета. """ - await message.answer("HAHAHHAHAHAHAHHAHA", reply_markup=popup_keyboard()) + await message.answer( + "Введите тему тикета (или нажмите 'Отмена', чтобы выйти):", + reply_markup=ticket_keyboard() + ) + user_state[message.from_user.id] = {"step": "subject"} + +async def handle_ticket_input(message: types.Message): + """ + Обрабатывает ввод данных для тикета. + """ + user_id = message.from_user.id + text = message.text.lower() + + if text == "отмена": + await message.answer("Создание тикета отменено.", reply_markup=types.ReplyKeyboardRemove()) + user_state.pop(user_id, None) + return + + state = user_state.get(user_id) + if not state: + await message.answer("Нет активного процесса создания тикета. Введите /support для начала.") + return + + if state["step"] == "subject": + state["subject"] = message.text + state["step"] = "message" + await message.answer("Введите описание проблемы:") + elif state["step"] == "message": + state["message"] = message.text + await create_ticket(message, state) + user_state.pop(user_id, None) + +async def create_ticket(message: types.Message, state): + """ + Отправляет запрос на создание тикета через FastAPI. + """ + user_id = message.from_user.id + subject = state["subject"] + ticket_message = state["message"] + + try: + logger.info(f"Создание тикета для пользователя {user_id}: Тема - {subject}, Сообщение - {ticket_message}") + user_data = await call_api("GET", f"/user/{message.from_user.id}") + if not user_data: + await message.edit_text("Вы еще не зарегистрированы.") + await message.answer() + return + # Отправляем запрос через call_api + ticket_data = await call_api( + "POST", + f"/support/tickets?user_id={user_data['id']}", # Передаём user_id как query-параметр + data={"subject": subject, "message": ticket_message} + ) + + + if ticket_data != "ERROR": + await message.answer( + f"✅ Тикет успешно создан!\n" + f"📌 Тема: {ticket_data['subject']}\n" + f"📊 Статус: {ticket_data['status']}\n" + f"📅 Дата создания: {ticket_data['created_at']}" + ) + else: + await message.answer("❌ Ошибка создания тикета. Попробуйте позже.") + except Exception as e: + logger.exception(f"Ошибка при создании тикета для пользователя {user_id}: {e}") + await message.answer("❌ Произошла ошибка при создании тикета.") + + + async def subhist_command(message: types.Message): """ Обработчик команды для отправки истории подписок. """ + user_data = await call_api("GET", f"/user/{message.from_user.id}") + if not user_data: + await message.edit_text("Вы еще не зарегистрированы.") + await message.answer() + return + + subscriptions = await call_api("GET", f"/subscriptions/{user_data['id']}") + if not subscriptions: + await message.edit_text("У вас нет активных подписок.", reply_markup=account_keyboard()) + await message.answer() + return + + result = "Ваши подписки:\n" + for count, sub in enumerate(subscriptions, start=1): + result += f"{count}. Тариф: {sub['plan']}, Истекает: {sub['expiry_date']}\n" + await message.edit_text(result, reply_markup=account_keyboard()) + await message.answer() + await message.answer("subhist", reply_markup=subhist_keyboard()) async def start_command(message: types.Message): @@ -96,7 +185,7 @@ async def profile_callback_handler(callback: types.CallbackQuery): # Если подписки нет if not sub_data: - text = f"Профиль {callback.from_user.username}:\n{balance_text}\nПополните баланс и приобретите подписку чтобы получить активный статус (🐣,🦅)" + text = f"Профиль {callback.from_user.username}\n{balance_text}\nПополните баланс и приобретите подписку чтобы получить активный статус (🐣,🦅)" else: # Получение даты окончания подписки expiry_date = sub_data.get("expiry_date") @@ -191,25 +280,6 @@ async def tranhist_callback_handler(callback: types.CallbackQuery): await callback.message.edit_text(result, reply_markup=tranhist_keyboard()) await callback.answer() -async def subhist_callback_handler(callback: types.CallbackQuery): - user_data = await call_api("GET", f"/user/{callback.from_user.id}") - if not user_data: - await callback.message.edit_text("Вы еще не зарегистрированы.") - await callback.answer() - return - - subscriptions = await call_api("GET", f"/subscription/{user_data['id']}/last") - if not subscriptions: - await callback.message.edit_text("У вас нет активных подписок.", reply_markup=account_keyboard()) - await callback.answer() - return - - result = "Ваши подписки:\n" - for count, sub in enumerate(subscriptions, start=1): - result += f"{count}. Тариф: {sub['plan']}, Истекает: {sub['expiry_date']}\n" - await callback.message.edit_text(result, reply_markup=account_keyboard()) - await callback.answer() - async def buy_subscription_callback_handler(callback: types.CallbackQuery): """ Обработчик callback_query с data="buy_subscription". @@ -336,6 +406,9 @@ def register_handlers(dp: Dispatcher): dp.callback_query.register(tranhist_callback_handler, lambda c: c.data == "tranhist") dp.callback_query.register(buy_subscription_callback_handler, lambda c: c.data == "buy_subscription") dp.message.register(start_command, Command("start")) + dp.message.register(start_command, Command("subscriptions")) + dp.message.register(start_ticket_creation, Command("support")) + dp.message.register(handle_ticket_input) # Для любых сообщений dp.callback_query.register(balance_callback_handler, lambda c: c.data == "balance") dp.callback_query.register(guide_callback_handler, lambda c: c.data == "guide") # dp.callback_query.register(about_tarifs_callback_handler, lambda c: c.data == "about_tarifs") diff --git a/keyboard/keyboards.py b/keyboard/keyboards.py index 3572e49..967ec9e 100644 --- a/keyboard/keyboards.py +++ b/keyboard/keyboards.py @@ -1,5 +1,5 @@ -from aiogram.utils.keyboard import InlineKeyboardBuilder -from aiogram.types import InlineKeyboardButton +from aiogram.utils.keyboard import InlineKeyboardBuilder, ReplyKeyboardBuilder +from aiogram.types import InlineKeyboardButton, KeyboardButton def main_keyboard(): @@ -8,7 +8,7 @@ def main_keyboard(): """ builder = InlineKeyboardBuilder() builder.row(InlineKeyboardButton(text="Профиль", callback_data="profile")) - builder.row(InlineKeyboardButton(text="FAQ", callback_data="faq")) + builder.row(InlineKeyboardButton(text="❔FAQ❔", callback_data="faq")) builder.row(InlineKeyboardButton(text="О нас", url="https://www.youtube.com/watch?v=Zirn-CKck-c")) return builder.as_markup() @@ -20,11 +20,17 @@ def account_keyboard(): 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="tranhist")) builder.row(InlineKeyboardButton(text="Назад", callback_data="base")) return builder.as_markup() + +def ticket_keyboard(): + builder = ReplyKeyboardBuilder() + builder.row(KeyboardButton(text="Отмена")) + return builder.as_markup() + def buy_keyboard(): """ Приобрести подписку diff --git a/main.py b/main.py index 1b0c331..c1326fe 100644 --- a/main.py +++ b/main.py @@ -22,7 +22,9 @@ dp.message.middleware(AntiSpamMiddleware(rate_limit=1)) async def set_commands(): """Устанавливает команды для бота.""" commands = [ - BotCommand(command="/start", description="Запустить бота"), + BotCommand(command="/start", description="🥚Запустить бота"), + BotCommand(command="/subscriptions", description="🦴Мои подписки"), + BotCommand(command="/support", description="❕Поддержка❕"), ] await bot.set_my_commands(commands)