diff --git a/.env.example b/.env.example index 84edbf42..2a02f129 100644 --- a/.env.example +++ b/.env.example @@ -5,6 +5,7 @@ # ===== TELEGRAM BOT ===== BOT_TOKEN= ADMIN_IDS= +# Ссылка на поддержку: Telegram username (например, @support) или полный URL SUPPORT_USERNAME=@support # Уведомления администраторов diff --git a/README.md b/README.md index 5479b8fb..e8c82ade 100644 --- a/README.md +++ b/README.md @@ -229,6 +229,7 @@ MAINTENANCE_MESSAGE=Ведутся технические работы. Серв # ===== TELEGRAM BOT ===== BOT_TOKEN= ADMIN_IDS= +# Ссылка на поддержку: Telegram username (например, @support) или полный URL SUPPORT_USERNAME=@support # Уведомления администраторов diff --git a/app/config.py b/app/config.py index fffe0214..926444e2 100644 --- a/app/config.py +++ b/app/config.py @@ -1,5 +1,6 @@ import os import re +import html from collections import defaultdict from typing import List, Optional, Union, Dict from pydantic_settings import BaseSettings @@ -604,10 +605,68 @@ class Settings(BaseSettings): def get_traffic_price(self, gb: int) -> int: packages = self.get_traffic_packages() - + for package in packages: if package["gb"] == gb and package["enabled"]: return package["price"] + + def _clean_support_contact(self) -> str: + return (self.SUPPORT_USERNAME or "").strip() + + def get_support_contact_url(self) -> Optional[str]: + contact = self._clean_support_contact() + + if not contact: + return None + + if contact.startswith(("http://", "https://", "tg://")): + return contact + + contact_without_prefix = contact.lstrip("@") + + if contact_without_prefix.startswith(("t.me/", "telegram.me/", "telegram.dog/")): + return f"https://{contact_without_prefix}" + + if contact.startswith(("t.me/", "telegram.me/", "telegram.dog/")): + return f"https://{contact}" + + if "." in contact_without_prefix: + return f"https://{contact_without_prefix}" + + if contact_without_prefix: + return f"https://t.me/{contact_without_prefix}" + + return None + + def get_support_contact_display(self) -> str: + contact = self._clean_support_contact() + + if not contact: + return "" + + if contact.startswith("@"): + return contact + + if contact.startswith(("http://", "https://", "tg://")): + return contact + + if contact.startswith(("t.me/", "telegram.me/", "telegram.dog/")): + url = self.get_support_contact_url() + return url if url else contact + + contact_without_prefix = contact.lstrip("@") + + if "." in contact_without_prefix: + url = self.get_support_contact_url() + return url if url else contact + + if re.fullmatch(r"[A-Za-z0-9_]{3,}", contact_without_prefix): + return f"@{contact_without_prefix}" + + return contact + + def get_support_contact_display_html(self) -> str: + return html.escape(self.get_support_contact_display()) enabled_packages = [pkg for pkg in packages if pkg["enabled"]] diff --git a/app/handlers/balance.py b/app/handlers/balance.py index f01f9588..e80b57d5 100644 --- a/app/handlers/balance.py +++ b/app/handlers/balance.py @@ -399,7 +399,7 @@ async def request_support_topup( 🛠️ Пополнение через поддержку Для пополнения баланса обратитесь в техподдержку: -{settings.SUPPORT_USERNAME} +{settings.get_support_contact_display_html()} Укажите: • ID: {db_user.telegram_id} @@ -416,8 +416,8 @@ async def request_support_topup( keyboard = types.InlineKeyboardMarkup(inline_keyboard=[ [types.InlineKeyboardButton( - text="💬 Написать в поддержку", - url=f"https://t.me/{settings.SUPPORT_USERNAME.lstrip('@')}" + text="💬 Написать в поддержку", + url=settings.get_support_contact_url() or "https://t.me/" )], [types.InlineKeyboardButton(text=texts.BACK, callback_data="balance_topup")] ]) @@ -606,7 +606,7 @@ async def process_yookassa_payment_amount( f"4. Деньги поступят на баланс автоматически\n\n" f"🔒 Оплата происходит через защищенную систему YooKassa\n" f"✅ Принимаем карты: Visa, MasterCard, МИР\n\n" - f"❓ Если возникнут проблемы, обратитесь в {settings.SUPPORT_USERNAME}", + f"❓ Если возникнут проблемы, обратитесь в {settings.get_support_contact_display_html()}", reply_markup=keyboard, parse_mode="HTML" ) @@ -691,7 +691,7 @@ async def process_yookassa_sbp_payment_amount( f"4. Деньги поступят на баланс автоматически\n\n" f"🔒 Оплата происходит через защищенную систему YooKassa\n" f"✅ Принимаем СБП от всех банков-участников\n\n" - f"❓ Если возникнут проблемы, обратитесь в {settings.SUPPORT_USERNAME}", + f"❓ Если возникнут проблемы, обратитесь в {settings.get_support_contact_display_html()}", reply_markup=keyboard, parse_mode="HTML" ) @@ -752,7 +752,9 @@ async def check_yookassa_payment_status( elif payment.is_pending: message_text += "\n⏳ Платеж ожидает оплаты. Нажмите кнопку 'Оплатить' выше." elif payment.is_failed: - message_text += f"\n❌ Платеж не прошел. Обратитесь в {settings.SUPPORT_USERNAME}" + message_text += ( + f"\n❌ Платеж не прошел. Обратитесь в {settings.get_support_contact_display()}" + ) await callback.answer(message_text, show_alert=True) @@ -890,7 +892,7 @@ async def process_cryptobot_payment_amount( f"4. Деньги поступят на баланс автоматически\n\n" f"🔒 Оплата проходит через защищенную систему CryptoBot\n" f"⚡ Поддерживаемые активы: USDT, TON, BTC, ETH\n\n" - f"❓ Если возникнут проблемы, обратитесь в {settings.SUPPORT_USERNAME}", + f"❓ Если возникнут проблемы, обратитесь в {settings.get_support_contact_display_html()}", reply_markup=keyboard, parse_mode="HTML" ) @@ -946,7 +948,9 @@ async def check_cryptobot_payment_status( elif payment.is_pending: message_text += "\n⏳ Платеж ожидает оплаты. Нажмите кнопку 'Оплатить' выше." elif payment.is_expired: - message_text += f"\n❌ Платеж истек. Обратитесь в {settings.SUPPORT_USERNAME}" + message_text += ( + f"\n❌ Платеж истек. Обратитесь в {settings.get_support_contact_display()}" + ) await callback.answer(message_text, show_alert=True) diff --git a/app/keyboards/inline.py b/app/keyboards/inline.py index b1fd2310..40f0fbdd 100644 --- a/app/keyboards/inline.py +++ b/app/keyboards/inline.py @@ -657,7 +657,10 @@ def get_support_keyboard(language: str = "ru") -> InlineKeyboardMarkup: texts = get_texts(language) return InlineKeyboardMarkup(inline_keyboard=[ [ - InlineKeyboardButton(text=texts.CONTACT_SUPPORT, url=f"https://t.me/{settings.SUPPORT_USERNAME.lstrip('@')}") + InlineKeyboardButton( + text=texts.CONTACT_SUPPORT, + url=settings.get_support_contact_url() or "https://t.me/" + ) ], [ InlineKeyboardButton(text=texts.BACK, callback_data="back_to_menu") diff --git a/app/localization/texts.py b/app/localization/texts.py index 499c03f2..4ad43c7c 100644 --- a/app/localization/texts.py +++ b/app/localization/texts.py @@ -399,7 +399,7 @@ class RussianTexts(Texts): По всем вопросам обращайтесь к нашей поддержке: -👤 {settings.SUPPORT_USERNAME} +👤 {settings.get_support_contact_display_html()} Мы поможем с: • Настройкой подключения