feat: referral links now point to web cabinet instead of bot
Centralized referral link generation into settings.get_referral_link().
When CABINET_URL is configured, links use {CABINET_URL}?ref={code}.
Falls back to Telegram bot deep link when CABINET_URL is not set.
- URL-encodes referral_code for safety
- Handles CABINET_URL with existing query params (uses & vs ?)
- Guards against None referral_code in all call sites
- QR code caching uses link hash for auto-invalidation
This commit is contained in:
@@ -92,8 +92,7 @@ async def get_referral_info(
|
||||
available_balance = min(user.balance_kopeks, referral_entitlement)
|
||||
|
||||
# Build referral link
|
||||
bot_username = settings.get_bot_username() or 'bot'
|
||||
referral_link = f'https://t.me/{bot_username}?start={user.referral_code}'
|
||||
referral_link = settings.get_referral_link(user.referral_code) if user.referral_code else ''
|
||||
|
||||
return ReferralInfoResponse(
|
||||
referral_code=user.referral_code or '',
|
||||
|
||||
@@ -1415,6 +1415,26 @@ class Settings(BaseSettings):
|
||||
return value
|
||||
return None
|
||||
|
||||
_CABINET_URL_DEFAULT = 'https://example.com/cabinet'
|
||||
|
||||
def get_referral_link(self, referral_code: str, bot_username: str | None = None) -> str:
|
||||
"""Build a referral link pointing to the web cabinet.
|
||||
|
||||
Falls back to a Telegram bot deep link when CABINET_URL is not configured.
|
||||
"""
|
||||
from urllib.parse import quote
|
||||
|
||||
if not referral_code:
|
||||
raise ValueError('referral_code must not be empty or None')
|
||||
|
||||
safe_code = quote(referral_code, safe='')
|
||||
cabinet_url = (self.CABINET_URL or '').strip().rstrip('/')
|
||||
if cabinet_url and cabinet_url != self._CABINET_URL_DEFAULT:
|
||||
sep = '&' if '?' in cabinet_url else '?'
|
||||
return f'{cabinet_url}{sep}ref={safe_code}'
|
||||
username = bot_username or self.get_bot_username() or 'bot'
|
||||
return f'https://t.me/{username}?start={safe_code}'
|
||||
|
||||
def is_deep_links_enabled(self) -> bool:
|
||||
return self.ENABLE_DEEP_LINKS
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import hashlib
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
@@ -37,10 +38,14 @@ async def show_referral_info(callback: types.CallbackQuery, db_user: User, db: A
|
||||
|
||||
texts = get_texts(db_user.language)
|
||||
|
||||
if not db_user.referral_code:
|
||||
await callback.answer(texts.t('REFERRAL_CODE_NOT_ASSIGNED', 'Реферальный код не назначен'), show_alert=True)
|
||||
return
|
||||
|
||||
summary = await get_user_referral_summary(db, db_user.id)
|
||||
|
||||
bot_username = (await callback.bot.get_me()).username
|
||||
referral_link = f'https://t.me/{bot_username}?start={db_user.referral_code}'
|
||||
referral_link = settings.get_referral_link(db_user.referral_code, bot_username)
|
||||
|
||||
referral_text = (
|
||||
texts.t('REFERRAL_PROGRAM_TITLE', '👥 <b>Реферальная программа</b>')
|
||||
@@ -229,17 +234,22 @@ async def show_referral_qr(
|
||||
callback: types.CallbackQuery,
|
||||
db_user: User,
|
||||
):
|
||||
await callback.answer()
|
||||
|
||||
texts = get_texts(db_user.language)
|
||||
|
||||
if not db_user.referral_code:
|
||||
await callback.answer(texts.t('REFERRAL_CODE_NOT_ASSIGNED', 'Реферальный код не назначен'), show_alert=True)
|
||||
return
|
||||
|
||||
await callback.answer()
|
||||
|
||||
bot_username = (await callback.bot.get_me()).username
|
||||
referral_link = f'https://t.me/{bot_username}?start={db_user.referral_code}'
|
||||
referral_link = settings.get_referral_link(db_user.referral_code, bot_username)
|
||||
|
||||
qr_dir = Path('data') / 'referral_qr'
|
||||
qr_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
file_path = qr_dir / f'{db_user.id}.png'
|
||||
link_hash = hashlib.md5(referral_link.encode()).hexdigest()[:8]
|
||||
file_path = qr_dir / f'{db_user.id}_{link_hash}.png'
|
||||
if not file_path.exists():
|
||||
img = qrcode.make(referral_link)
|
||||
img.save(file_path)
|
||||
@@ -470,8 +480,12 @@ async def show_referral_analytics(callback: types.CallbackQuery, db_user: User,
|
||||
async def create_invite_message(callback: types.CallbackQuery, db_user: User):
|
||||
texts = get_texts(db_user.language)
|
||||
|
||||
if not db_user.referral_code:
|
||||
await callback.answer(texts.t('REFERRAL_CODE_NOT_ASSIGNED', 'Реферальный код не назначен'), show_alert=True)
|
||||
return
|
||||
|
||||
bot_username = (await callback.bot.get_me()).username
|
||||
referral_link = f'https://t.me/{bot_username}?start={db_user.referral_code}'
|
||||
referral_link = settings.get_referral_link(db_user.referral_code, bot_username)
|
||||
|
||||
invite_text = texts.t('REFERRAL_INVITE_TITLE', '🎉 Присоединяйся к VPN сервису!')
|
||||
|
||||
|
||||
@@ -2867,10 +2867,9 @@ async def _build_referral_info(
|
||||
referral_code = getattr(user, 'referral_code', None)
|
||||
referral_settings = settings.get_referral_settings() or {}
|
||||
|
||||
bot_username = settings.get_bot_username()
|
||||
referral_link = None
|
||||
if referral_code and bot_username:
|
||||
referral_link = f'https://t.me/{bot_username}?start={referral_code}'
|
||||
if referral_code:
|
||||
referral_link = settings.get_referral_link(referral_code)
|
||||
|
||||
minimum_topup_kopeks = int(referral_settings.get('minimum_topup_kopeks') or 0)
|
||||
first_topup_bonus_kopeks = int(referral_settings.get('first_topup_bonus_kopeks') or 0)
|
||||
|
||||
Reference in New Issue
Block a user