Files
Telegram-bot-old/handlers/referrals.py
2025-12-02 14:28:03 +03:00

153 lines
5.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.filters import Command
from aiogram.enums.parse_mode import ParseMode
import logging
import aiohttp
from instences.config import BASE_URL_FASTAPI
router = Router()
logger = logging.getLogger(__name__)
async def call_api(method, endpoint, data=None, base_url=BASE_URL_FASTAPI):
"""
Универсальный HTTP-запрос к FastAPI для рефералок.
Ожидаем от бекенда:
GET /user/{telegram_id}/referrals -> {
"invited_count": int,
"bonus_total": float
}
"""
url = f"{base_url}{endpoint}"
logger.info(
f"[referrals] Инициализация запроса: {method} {url} с данными {data}")
try:
async with aiohttp.ClientSession() as session:
async with session.request(
method,
url,
json=data,
headers={"Content-Type": "application/json"},
) as response:
logger.info(
f"[referrals] Получен ответ от {url}: статус {response.status}"
)
if response.status in {200, 201}:
result = await response.json()
logger.debug(f"[referrals] Ответ JSON: {result}")
return result
if response.status == 404:
logger.debug(
f"[referrals] Код {response.status}, возвращаю None"
)
return None
logger.error(
f"[referrals] Ошибка в запросе: статус {response.status}, причина {response.reason}"
)
return "ERROR"
except Exception as e:
logger.exception(
f"[referrals] Исключение при выполнении запроса к {url}: {e}")
return "ERROR"
async def _build_referral_text(bot, user_id: int) -> str:
"""
Текст реферальной программы + статистика, если есть.
"""
me = await bot.get_me()
bot_username = me.username or "LarkVPN_bot"
link = f"https://t.me/{bot_username}?start=ref_{user_id}"
# Базовый текст: без фейковых тире и нулевых рублей
text = (
"👥 <b>Реферальная программа</b>\n\n"
"Зови друзей в Lark VPN и получай бонусы на баланс.\n\n"
f"🔗 Твоя ссылка:\n<code>{link}</code>\n\n"
)
invited_line = ""
bonus_line = ""
stats = await call_api("GET", f"/user/{user_id}/referrals")
if isinstance(stats, dict):
invited = stats.get("invited_count")
bonus = stats.get("bonus_total")
if invited is not None:
try:
invited_int = int(invited)
except (TypeError, ValueError):
invited_int = None
if invited_int is not None:
invited_line = f"👤 Приглашено: {invited_int}\n"
if bonus is not None:
try:
bonus_val = float(bonus)
except (TypeError, ValueError):
bonus_val = None
# Строку с бонусами показываем только если реально что-то начислено
if bonus_val is not None and bonus_val > 0:
bonus_line = f"💰 Начислено бонусов: {bonus_val:.2f}\n"
else:
logger.warning(
f"[referrals] Не удалось получить статистику для user_id={user_id}: {stats}"
)
if invited_line:
text += invited_line
if bonus_line:
text += bonus_line
if invited_line or bonus_line:
text += "\n"
text += (
"Бонусы падают автоматически, когда приглашённые пополняют баланс."
)
return text
@router.message(Command("referrals"))
async def referrals_command(message: types.Message):
"""
Команда /referrals — показывает текст реферальной программы.
"""
logger.info(f"Получена команда /referrals от {message.from_user.id}")
try:
text = await _build_referral_text(message.bot, message.from_user.id)
await message.answer(text, parse_mode=ParseMode.HTML)
except Exception as e:
logger.exception(f"Ошибка в обработчике /referrals: {e}")
await message.answer("Произошла ошибка. Попробуй позже.")
@router.callback_query(lambda callback: callback.data == "referral")
async def referrals_callback(callback: types.CallbackQuery):
"""
Кнопка «Реферальная программа» (если где-то есть).
"""
try:
text = await _build_referral_text(
callback.message.bot,
callback.from_user.id,
)
await callback.message.edit_text(
text,
parse_mode=ParseMode.HTML,
)
except Exception as e:
logger.exception(f"Ошибка в обработчике callback 'referral': {e}")
await callback.message.answer("Произошла ошибка. Попробуй позже.")
finally:
await callback.answer()