diff --git a/app/cabinet/routes/referral.py b/app/cabinet/routes/referral.py index 3da2c8ee..d20c8df5 100644 --- a/app/cabinet/routes/referral.py +++ b/app/cabinet/routes/referral.py @@ -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 '', diff --git a/app/config.py b/app/config.py index 3a90ec8f..b3bb201a 100644 --- a/app/config.py +++ b/app/config.py @@ -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 diff --git a/app/handlers/referral.py b/app/handlers/referral.py index 3b491e7b..b276fbff 100644 --- a/app/handlers/referral.py +++ b/app/handlers/referral.py @@ -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', '👥 Реферальная программа') @@ -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 сервису!') diff --git a/app/webapi/routes/miniapp.py b/app/webapi/routes/miniapp.py index 8f869078..cf9bc688 100644 --- a/app/webapi/routes/miniapp.py +++ b/app/webapi/routes/miniapp.py @@ -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)