refactor referral handlers with photo helper

This commit is contained in:
yazhog
2025-09-10 01:48:41 +03:00
parent 9b32de5fb2
commit ea958ea6c0
2 changed files with 74 additions and 63 deletions

View File

@@ -11,6 +11,7 @@ from app.config import settings
from app.database.models import User
from app.keyboards.inline import get_referral_keyboard
from app.localization.texts import get_texts
from app.utils.photo_message import edit_or_answer_photo
from app.utils.user_utils import (
get_detailed_referral_list,
get_referral_analytics,
@@ -91,25 +92,11 @@ async def show_referral_info(
referral_text += "📢 Приглашайте друзей и зарабатывайте!"
is_qr = callback.message.caption and callback.message.caption.startswith("🔗 Ваша реферальная ссылка")
media = callback.message.photo[-1].file_id if callback.message.photo and not is_qr else FSInputFile("vpn_logo.png")
if callback.message.photo and not is_qr:
await callback.message.edit_media(
types.InputMediaPhoto(
media=media,
caption=referral_text,
parse_mode="HTML",
),
reply_markup=get_referral_keyboard(db_user.language),
)
else:
await callback.message.delete()
await callback.message.answer_photo(
FSInputFile("vpn_logo.png"),
caption=referral_text,
reply_markup=get_referral_keyboard(db_user.language),
parse_mode="HTML",
)
await edit_or_answer_photo(
callback,
referral_text,
get_referral_keyboard(db_user.language),
)
await callback.answer()
@@ -161,19 +148,17 @@ async def show_detailed_referral_list(
page: int = 1
):
texts = get_texts(db_user.language)
media = callback.message.photo[-1].file_id if callback.message.photo else FSInputFile("vpn_logo.png")
referrals_data = await get_detailed_referral_list(db, db_user.id, limit=10, offset=(page - 1) * 10)
if not referrals_data['referrals']:
await callback.message.edit_media(
types.InputMediaPhoto(
media=media,
caption="📋 У вас пока нет рефералов.\n\nПоделитесь своей реферальной ссылкой, чтобы начать зарабатывать!",
await edit_or_answer_photo(
callback,
"📋 У вас пока нет рефералов.\n\nПоделитесь своей реферальной ссылкой, чтобы начать зарабатывать!",
types.InlineKeyboardMarkup(
inline_keyboard=[[types.InlineKeyboardButton(text=texts.BACK, callback_data="menu_referrals")]]
),
reply_markup=types.InlineKeyboardMarkup(inline_keyboard=[
[types.InlineKeyboardButton(text=texts.BACK, callback_data="menu_referrals")]
]),
parse_mode=None,
)
await callback.answer()
return
@@ -216,17 +201,14 @@ async def show_detailed_referral_list(
keyboard.append(nav_buttons)
keyboard.append([types.InlineKeyboardButton(
text=texts.BACK,
text=texts.BACK,
callback_data="menu_referrals"
)])
await callback.message.edit_media(
types.InputMediaPhoto(
media=media,
caption=text,
parse_mode="HTML",
),
reply_markup=types.InlineKeyboardMarkup(inline_keyboard=keyboard),
await edit_or_answer_photo(
callback,
text,
types.InlineKeyboardMarkup(inline_keyboard=keyboard),
)
await callback.answer()
@@ -237,33 +219,29 @@ async def show_referral_analytics(
db: AsyncSession
):
texts = get_texts(db_user.language)
media = callback.message.photo[-1].file_id if callback.message.photo else FSInputFile("vpn_logo.png")
analytics = await get_referral_analytics(db, db_user.id)
text = f"📊 <b>Аналитика рефералов</b>\n\n"
text += f"💰 <b>Доходы по периодам:</b>\n"
text += f"• Сегодня: {texts.format_price(analytics['earnings_by_period']['today'])}\n"
text += f"За неделю: {texts.format_price(analytics['earnings_by_period']['week'])}\n"
text += f"За месяц: {texts.format_price(analytics['earnings_by_period']['month'])}\n"
text += f"За квартал: {texts.format_price(analytics['earnings_by_period']['quarter'])}\n\n"
if analytics['top_referrals']:
text += f"🏆 <b>Топ-{len(analytics['top_referrals'])} рефералов:</b>\n"
for i, ref in enumerate(analytics['top_referrals'], 1):
text += f"{i}. {ref['referral_name']}: {texts.format_price(ref['total_earned_kopeks'])} ({ref['earnings_count']} начислений)\n"
text += "\n"
text += "📈 Продолжайте развивать свою реферальную сеть!"
await callback.message.edit_media(
types.InputMediaPhoto(
media=media,
caption=text,
parse_mode="HTML",
),
reply_markup=types.InlineKeyboardMarkup(inline_keyboard=[
await edit_or_answer_photo(
callback,
text,
types.InlineKeyboardMarkup(inline_keyboard=[
[types.InlineKeyboardButton(text=texts.BACK, callback_data="menu_referrals")]
]),
)
@@ -278,37 +256,33 @@ async def create_invite_message(
bot_username = (await callback.bot.get_me()).username
referral_link = f"https://t.me/{bot_username}?start={db_user.referral_code}"
invite_text = f"🎉 Присоединяйся к VPN сервису!\n\n"
invite_text += f"💎 При первом пополнении от {texts.format_price(settings.REFERRAL_MINIMUM_TOPUP_KOPEKS)} ты получишь {texts.format_price(settings.REFERRAL_FIRST_TOPUP_BONUS_KOPEKS)} бонусом на баланс!\n\n"
invite_text += f"🚀 Быстрое подключение\n"
invite_text += f"🌍 Серверы по всему миру\n"
invite_text += f"🔒 Надежная защита\n\n"
invite_text += f"👇 Переходи по ссылке:\n{referral_link}"
keyboard = types.InlineKeyboardMarkup(inline_keyboard=[
[types.InlineKeyboardButton(
text="📤 Поделиться",
switch_inline_query=invite_text
switch_inline_query=invite_text
)],
[types.InlineKeyboardButton(
text=texts.BACK,
callback_data="menu_referrals"
)]
])
media = callback.message.photo[-1].file_id if callback.message.photo else FSInputFile("vpn_logo.png")
await callback.message.edit_media(
types.InputMediaPhoto(
media=media,
caption=(
f"📝 <b>Приглашение создано!</b>\n\n"
f"Нажмите кнопку «📤 Поделиться» чтобы отправить приглашение в любой чат, или скопируйте текст ниже:\n\n"
f"<code>{invite_text}</code>"
),
parse_mode="HTML",
await edit_or_answer_photo(
callback,
(
f"📝 <b>Приглашение создано!</b>\n\n"
f"Нажмите кнопку «📤 Поделиться» чтобы отправить приглашение в любой чат, или скопируйте текст ниже:\n\n"
f"<code>{invite_text}</code>"
),
reply_markup=keyboard,
keyboard,
)
await callback.answer()

View File

@@ -0,0 +1,37 @@
from aiogram import types
from aiogram.exceptions import TelegramBadRequest
from aiogram.types import FSInputFile, InputMediaPhoto
from .message_patch import LOGO_PATH
def _is_qr_message(message: types.Message) -> bool:
return bool(message.caption and message.caption.startswith("\uD83D\uDD17 Ваша реферальная ссылка"))
def _resolve_media(message: types.Message):
if message.photo and not _is_qr_message(message):
return message.photo[-1].file_id
return FSInputFile(LOGO_PATH)
async def edit_or_answer_photo(
callback: types.CallbackQuery,
caption: str,
keyboard: types.InlineKeyboardMarkup,
parse_mode: str | None = "HTML",
) -> None:
media = _resolve_media(callback.message)
try:
await callback.message.edit_media(
InputMediaPhoto(media=media, caption=caption, parse_mode=parse_mode),
reply_markup=keyboard,
)
except TelegramBadRequest:
await callback.message.delete()
await callback.message.answer_photo(
FSInputFile(LOGO_PATH),
caption=caption,
reply_markup=keyboard,
parse_mode=parse_mode,
)