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

243 lines
9.4 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
from aiogram.types import CallbackQuery
import logging
from datetime import datetime
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,
)
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.
"""
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 == 404:
logger.debug(f"Код {response.status}, возвращаю ничего")
return None
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):
"""
Профиль пользователя.
Логика работы с API сохранена, переписан только текст/визуал.
"""
try:
user_data = await call_api("GET", f"/user/{callback.from_user.id}")
if not user_data:
await callback.message.answer(
"Произошла ошибка, попробуйте позже или свяжитесь с администрацией."
)
await callback.answer()
return
sub_data = await call_api("GET", f"/subscription/{user_data['telegram_id']}/last")
if sub_data == "ERROR" or not isinstance(sub_data, dict):
sub_data = None
balance_text = f"💰 Баланс: {user_data['balance']}"
username = callback.from_user.username or "пользователь"
# Нет подписки
if not sub_data:
text = (
f"📜 Профиль {username}\n\n"
f"{balance_text}\n\n"
"У тебя пока нет активной подписки.\n"
"Пополняй баланс и подключай тариф Lark, чтобы получить статус 🐣 или 🦅."
)
else:
expiry_date = sub_data.get("end_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
)
status_icon = "✖️" if is_expired else "☑️"
profile_status = "🦅" if "Pro" in sub_data.get("plan", "") else "🐣"
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}"
)
await callback.message.edit_text(text, reply_markup=account_keyboard())
except Exception as e:
logger.exception(f"Ошибка в обработчике профиля: {e}")
await callback.message.answer("Произошла ошибка. Попробуйте позже.")
finally:
await callback.answer()
@router.callback_query(lambda callback: callback.data == "balance")
async def balance_callback_handler(callback: CallbackQuery):
"""
Обработчик callback_query для баланса.
"""
user_data = await call_api("GET", f"/user/{callback.from_user.id}")
if not user_data:
await callback.message.answer(
"Произошла ошибка, попробуйте позже или свяжитесь с администрацией."
)
await callback.answer()
return
await callback.message.edit_text(
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 для выбора суммы пополнения.
"""
user = await call_api("GET", f"/user/{callback.from_user.id}")
if not user:
await callback.message.answer(
"Произошла ошибка, попробуйте позже или свяжитесь с администрацией."
)
await callback.answer()
return
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:
await callback.message.edit_text("Вы еще не зарегистрированы.")
await callback.answer()
return
try:
transactions = await call_api("GET", f"/user/{user_data['telegram_id']}/transactions")
if not transactions:
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"
)
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(),
)
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):
"""
Обработчик подтверждения пополнения баланса.
"""
data = callback.data.split(":")
popup_info = data[1]
result = await call_api(
"POST",
f"/user/{callback.from_user.id}/balance/{float(popup_info)}",
)
if result == "ERROR":
await callback.message.answer(
"Произошла ошибка, попробуйте позже или свяжитесь с администрацией."
)
await callback.answer()
return
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(),
)
await callback.answer()