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

344 lines
16 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 types, Dispatcher
from aiogram.filters import Command
import aiohttp
import logging
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
logger = logging.getLogger(__name__)
# Инициализируем менеджер базы данных
async def call_api(method, endpoint, data=None):
"""
Выполняет HTTP-запрос к FastAPI.
:param method: HTTP метод (GET, POST, и т.д.)
:param endpoint: конечная точка API
:param data: тело запроса (если необходимо)
:return: JSON-ответ или "ERROR" при неуспехе
"""
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
logger.error(f"Ошибка в запросе: статус {response.status}, причина {response.reason}")
return "ERROR"
except Exception as e:
logger.exception(f"Исключение при выполнении запроса к {url}: {e}")
return "ERROR"
async def popup_command(message: types.Message):
"""
Обработчик команды для отправки popup-сообщения.
"""
await message.answer("HAHAHHAHAHAHAHHAHA", reply_markup=popup_keyboard())
async def subhist_command(message: types.Message):
"""
Обработчик команды для отправки истории подписок.
"""
await message.answer("subhist", reply_markup=subhist_keyboard())
async def start_command(message: types.Message):
"""
Обработчик команды /start.
"""
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())
async def start_callback_handler(callback: types.CallbackQuery):
"""
Обработчик callback_query с data="base".
"""
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()
)
async def profile_callback_handler(callback: types.CallbackQuery):
try:
# Создание пользователя
user_data = await call_api("POST", "/user/create", {"telegram_id": callback.from_user.id})
if user_data == "ERROR" or not isinstance(user_data, dict):
raise ValueError("Не удалось создать пользователя.")
# Получение подписки
sub_data = await call_api("GET", f"/subscription/{user_data['id']}/last")
if sub_data == "ERROR" or not isinstance(sub_data, dict):
sub_data = None
# Формирование текста баланса
balance_text = f"Баланс: {user_data['balance']}"
# Если подписки нет
if not sub_data:
text = f"Профиль {callback.from_user.username}:\n{balance_text}\nПополните баланс и приобретите подписку чтобы получить активный статус (🐣,🦅)"
else:
# Получение даты окончания подписки
expiry_date = sub_data.get("expiry_date")
formatted_date = None
# Преобразование времени в презентабельный формат
if expiry_date:
expiry_datetime = datetime.fromisoformat(expiry_date)
formatted_date = expiry_datetime.strftime("%d %B %Y г.")
# Проверка на истечение подписки
is_expired = datetime.fromisoformat(expiry_date) < datetime.now() if expiry_date else True
plan_type = sub_data.get("plan", "")
status_icon = "✖️" if is_expired else "☑️"
# Определение статуса
if "Pro" in plan_type:
profile_status = "🦅"
else:
profile_status = "🐣"
# Формирование текста профиля
sub_text = (
f"Ваша подписка действует до {formatted_date} {status_icon}"
if not is_expired else f"Статус подписки: {status_icon}"
)
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 ValueError as e:
await callback.message.answer(f"Ошибка: {e}")
except Exception as e:
logger.exception(f"Ошибка в обработчике профиля: {e}")
await callback.message.answer("Произошла ошибка. Попробуйте позже.")
finally:
await callback.answer()
async def balance_callback_handler(callback: types.CallbackQuery):
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']} ₽. Выберите сумму для пополнения 🐥",
reply_markup=balance_keyboard()
)
await callback.answer()
async def popup_callback_handler(callback: types.CallbackQuery):
"""
Обработчик callback_query с data="popup".
"""
user = await call_api("POST", "/user/create", {"telegram_id": callback.from_user.id})
if user == "ERROR":
await callback.message.answer(
"Произошла ошибка, попробуйте позже или свяжитесь с администрацией."
)
await callback.answer()
return
if user:
await callback.message.edit_text(
f"Работает в режиме теста!!!",
reply_markup=popup_keyboard()
)
else:
await callback.message.edit_text("Вы еще не зарегистрированы.")
await callback.answer()
async def tranhist_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
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.answer()
return
result = "Ваши транзакции:\n"
for count, tran in enumerate(transactions, start=1):
result += f"{count}. Сумма: {tran['amount']}, Дата: {tran['created_at']}\n"
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".
"""
await callback.message.edit_text(
f"Ознакомься с условиями в вкладке \"О тарифах\" и выбери подходящий 🦅",
reply_markup=buy_keyboard()
)
async def guide_callback_handler(callback:types.CallbackQuery):
"""
Обработчик callback_query с data="guide".
"""
await callback.message.edit_text(
f"Руководство по использованию продкута что мы высрали;)",
reply_markup=guide_keyboard()
)
async def subs_callback_handler(callback: types.CallbackQuery):
"""
Обработчик callback_query с data="subs".
"""
await callback.message.edit_text(
f"Подписки птенчик",
reply_markup=tarif_Lark_keyboard()
)
async def subs_pro_callback_handler(callback: types.CallbackQuery):
"""
Обработчик callback_query с data="subs_pro".
"""
await callback.message.edit_text(
f"Подписки птенчик ПРО",
reply_markup=tarif_Lark_pro_keyboard()
)
# async def about_tarifs_callback_handler(callback: types.CallbackQuery):
# """
# Обработчик callback_query с data="about_tarifs".
# """
# await callback.message.edit_text(
# f"Бла бла бла, хуйня на хуйне",
# reply_markup=about_tarifs_keyboard()
# )
async def faq_callback_handler(callback:types.CallbackQuery):
"""
Обработчик callback_query с data="faq".
"""
await callback.message.edit_text(
f"FAQ YOU",
reply_markup=faq_keyboard()
)
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)
async def popup_confirm_callback_handler(callback: types.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}. P.S. Мы завтра закрываемся"
await callback.message.edit_text(text=text, reply_markup=confirm_popup_keyboard())
async def confirm_callback_handler(callback: types.CallbackQuery):
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})
error_detail = result.get("detail",{})
error_code = error_detail.get("code", "")
if error_code == "ERROR":
await callback.message.edit_text("Произошла ошибка при оформлении подписки.")
if error_code == "INSUFFICIENT_FUNDS":
await callback.message.edit_text("Денег на вашем балансе не достаточно.")
if error_code == "TARIFF_NOT_FOUND":
await callback.message.edit_text("Ваш тариф не найден.")
if error_code == "ACTIVE_SUBSCRIPTION_EXISTS":
await callback.message.edit_text("Вы уже имеете активную подписку.")
else:
await callback.message.edit_text(f"Подписка успешно оформлена!")
await callback.answer()
def register_handlers(dp: Dispatcher):
"""
Регистрация хэндлеров в диспетчере.
"""
dp.callback_query.register(popup_callback_handler, lambda c: c.data == "popup")
dp.callback_query.register(start_callback_handler, lambda c: c.data == "base")
dp.callback_query.register(subs_callback_handler, lambda c: c.data == "subs")
dp.callback_query.register(subs_pro_callback_handler, lambda c: c.data == "subs_pro")
dp.callback_query.register(faq_callback_handler, lambda c: c.data == "faq")
dp.callback_query.register(profile_callback_handler, lambda c: c.data == "profile")
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.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")
dp.callback_query.register(lark_tariff_callback_handler, lambda c: c.data.startswith("Lark:"))
dp.callback_query.register(confirm_callback_handler, lambda c: c.data.startswith("confirm:"))
dp.callback_query.register(popup_confirm_callback_handler, lambda c: c.data.startswith("popup:"))