Files
Telegram-bot-old/handlers/subscriptions.py

210 lines
8.2 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, types
import logging
from instences.config import BASE_URL_FASTAPI
import aiohttp
from aiogram.enums.parse_mode import ParseMode
from aiogram.filters import Command
from keyboard.keyboards import (
tarif_Lark_pro_keyboard,
tarif_Lark_keyboard,
tarif_Lark_family_keyboard,
tarif_confirm_keyboard,
buy_keyboard,
)
router = Router()
logger = logging.getLogger(__name__)
async def call_api(method, endpoint, data=None):
"""
Выполняет HTTP-запрос к FastAPI.
"""
url = f"{BASE_URL_FASTAPI}{endpoint}"
logger.info(f"Инициализация запроса: {method} {url} с данными {data}")
try:
async with aiohttp.ClientSession() as session:
async with session.request(method, url, json=data) as response:
logger.info(
f"Получен ответ от {url}: статус {response.status}")
if response.status in {200, 201}:
result = await response.json()
logger.debug(f"Ответ JSON: {result}")
return result
if response.status in {404, 400}:
result = await response.json()
logger.debug(f"Код {response.status}, возвращаю {result}")
return result
logger.error(
f"Ошибка в запросе: статус {response.status}, причина {response.reason}")
return "ERROR"
except Exception as e:
logger.exception(f"Исключение при выполнении запроса к {url}: {e}")
return "ERROR"
def escape_markdown_v2(text: str) -> str:
"""
Экранирует специальные символы для Markdown_V2.
"""
special_chars = r"_*[]()~`>#+-=|{}.!"
for char in special_chars:
text = text.replace(char, f"\\{char}")
return text
@router.message(Command("subscriptions"))
async def supp(message: types.Message):
"""
Меню системы подписок
"""
text = ""
uri = None # Инициализация переменной
try:
# Вызов API для получения URI
result = await call_api("GET", f"/uri?telegram_id={message.from_user.id}")
# Получаем URI из ответа или "Error", если ключ отсутствует
uri = result.get('detail', "Error")
# Проверка результата
if uri == "Error":
text = escape_markdown_v2("Произошла ошибка при получении URI")
elif uri == "SUB_ERROR":
text = escape_markdown_v2("Вы ещё не приобрели подписки!!")
elif "vless" in uri:
escaped_uri = escape_markdown_v2(uri) # Экранирование URI
text = f"Ваша подписка: ```{escaped_uri}```"
else:
text = escape_markdown_v2("Произошла ошибка при обработке URI")
except Exception as e:
# Логирование ошибок
logger.error(f"Ошибка при вызове API для подписки: {e}")
text = escape_markdown_v2(
"Произошла неожиданная ошибка при получении подписки.")
# Ответ пользователю
await message.answer(
text,
parse_mode=ParseMode.MARKDOWN_V2
)
@router.callback_query(lambda callback: callback.data == "buy_subscription")
async def buy_subscription_callback_handler(callback: types.CallbackQuery):
"""
Меню выбора тарифа: Basic / Pro / Family + показ баланса.
"""
# Тянем пользователя, чтобы показать баланс
user_data = await call_api("GET", f"/user/{callback.from_user.id}")
balance = user_data.get("balance", 0) if user_data else "?"
text = (
" <b>Подключить новую подписку</b>\n\n"
"🐣 Lark Basic - 200 ₽ / мес\n"
"🦅 Lark Pro - 400 ₽ / мес\n"
"👨‍👩‍👧 Lark Family - 700 ₽ / мес\n\n"
f"💰 Баланс: {balance}\n\n"
"Выбери тариф:"
)
await callback.message.edit_text(
text,
parse_mode=ParseMode.HTML,
reply_markup=buy_keyboard(),
)
await callback.answer()
@router.callback_query(lambda callback: callback.data == "subs")
async def subs_callback_handler(callback: types.CallbackQuery):
"""
Обработчик callback_query с data="subs".
"""
await callback.message.edit_text(
"Подписки птенчик",
reply_markup=tarif_Lark_keyboard()
)
@router.callback_query(lambda callback: callback.data == "subs_pro")
async def subs_pro_callback_handler(callback: types.CallbackQuery):
"""
Обработчик callback_query с data="subs_pro".
"""
await callback.message.edit_text(
"Подписки птенчик ПРО",
reply_markup=tarif_Lark_pro_keyboard()
)
@router.callback_query(lambda callback: callback.data == "subs_family")
async def subs_family_callback_handler(callback: types.CallbackQuery):
"""
Обработчик callback_query с data="subs_family".
"""
await callback.message.edit_text(
"Подписки Lark Family",
reply_markup=tarif_Lark_family_keyboard(),
)
await callback.answer()
@router.callback_query(lambda callback: callback.data.startswith("Lark:"))
async def lark_tariff_callback_handler(callback: types.CallbackQuery):
"""
Обработчик для выбора тарифа Lark.
"""
data = callback.data.split(":")
tariff_name = data[0]
tariff_class = data[1]
tariff_time = int(data[2])
# Определение окончания для месяцев
if tariff_time == 1:
months = f"{tariff_time} месяц"
elif 2 <= tariff_time <= 4:
months = f"{tariff_time} месяца"
else:
months = f"{tariff_time} месяцев"
text = f"Тариф {tariff_name} на {months}. Продолжите покупку..."
# Рендеринг клавиатуры
keyboard = tarif_confirm_keyboard(tariff_name, tariff_time, tariff_class)
await callback.message.edit_text(text=text, reply_markup=keyboard)
@router.callback_query(lambda callback: callback.data.startswith("confirm:"))
async def confirm_callback_handler(callback: types.CallbackQuery):
"""
Обработчик подтверждения подписки.
"""
try:
data = callback.data.split(":")[1]
tariff_info = data.split("_")
plan_id = f"{tariff_info[0]}_{tariff_info[1]}_{tariff_info[2]}"
result = await call_api("POST", "/subscription/buy", {"telegram_id": callback.from_user.id, "plan_id": plan_id})
detail = result.get("detail", {})
if detail == "ERROR":
await callback.message.edit_text("Произошла ошибка при оформлении подписки.")
elif detail == "INSUFFICIENT_FUNDS":
await callback.message.edit_text("Денег на вашем балансе не достаточно.")
elif detail == "TARIFF_NOT_FOUND":
await callback.message.edit_text("Ваш тариф не найден.")
elif detail == "ACTIVE_SUBSCRIPTION_EXISTS":
await callback.message.edit_text("Вы уже имеете активную подписку.")
else:
uri = result.get("message", {})
escaped_text = escape_markdown_v2(f"Подписка успешно оформлена!")
answer_text = f"Ваш конфиг для подключения: ```{uri}```"
await callback.message.edit_text(escaped_text)
await callback.message.answer(answer_text, parse_mode=ParseMode.MARKDOWN_V2)
except Exception as e:
logger.exception(f"Ошибка при обработке подтверждения подписки: {e}")
await callback.message.edit_text("Произошла ошибка при оформлении подписки.")
finally:
await callback.answer()