mirror of
https://github.com/BEDOLAGA-DEV/remnawave-bedolaga-telegram-bot.git
synced 2026-03-04 12:55:10 +00:00
Handle Happ cryptolink without unsupported Telegram URL
This commit is contained in:
@@ -1,17 +1,19 @@
|
||||
import logging
|
||||
from datetime import datetime, timedelta
|
||||
from aiogram import Dispatcher, types, F
|
||||
from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton
|
||||
from aiogram.fsm.context import FSMContext
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
import html
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
from typing import Dict, List, Any, Tuple, Optional
|
||||
from datetime import datetime, timedelta
|
||||
from typing import Any, Dict, List, Optional, Tuple
|
||||
|
||||
from app.config import settings, PERIOD_PRICES, get_traffic_prices
|
||||
from aiogram import F, Dispatcher, types
|
||||
from aiogram.fsm.context import FSMContext
|
||||
from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.config import PERIOD_PRICES, get_traffic_prices, settings
|
||||
from app.states import SubscriptionStates
|
||||
from app.database.crud.subscription import (
|
||||
get_subscription_by_user_id, create_trial_subscription,
|
||||
get_subscription_by_user_id, create_trial_subscription,
|
||||
create_paid_subscription, extend_subscription,
|
||||
add_subscription_traffic, add_subscription_devices,
|
||||
add_subscription_squad, update_subscription_autopay,
|
||||
@@ -64,7 +66,10 @@ from app.utils.pricing_utils import (
|
||||
format_period_description,
|
||||
)
|
||||
from app.utils.pagination import paginate_list
|
||||
from app.utils.subscription_utils import get_display_subscription_link
|
||||
from app.utils.subscription_utils import (
|
||||
get_display_subscription_link,
|
||||
is_supported_telegram_url,
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -4611,21 +4616,34 @@ async def handle_open_subscription_link(
|
||||
return
|
||||
|
||||
if settings.is_happ_cryptolink_mode():
|
||||
escaped_subscription_link = html.escape(subscription_link)
|
||||
can_open_directly = is_supported_telegram_url(subscription_link)
|
||||
|
||||
link_line = texts.t(
|
||||
"SUBSCRIPTION_HAPP_OPEN_LINK",
|
||||
"<a href=\"{subscription_link}\">🔓 Открыть ссылку в Happ</a>",
|
||||
)
|
||||
|
||||
if can_open_directly:
|
||||
formatted_link_line = link_line.format(subscription_link=subscription_link)
|
||||
else:
|
||||
formatted_link_line = texts.t(
|
||||
"SUBSCRIPTION_HAPP_OPEN_COPY",
|
||||
"🔓 Скопируйте ссылку и откройте в Happ: <code>{subscription_link}</code>",
|
||||
).format(subscription_link=escaped_subscription_link)
|
||||
|
||||
happ_message = (
|
||||
texts.t(
|
||||
"SUBSCRIPTION_HAPP_OPEN_TITLE",
|
||||
"🔗 <b>Подключение через Happ</b>",
|
||||
)
|
||||
+ "\n\n"
|
||||
+ texts.t(
|
||||
"SUBSCRIPTION_HAPP_OPEN_LINK",
|
||||
"<a href=\"{subscription_link}\">🔓 Открыть ссылку в Happ</a>",
|
||||
).format(subscription_link=subscription_link)
|
||||
+ formatted_link_line
|
||||
+ "\n\n"
|
||||
+ texts.t(
|
||||
"SUBSCRIPTION_HAPP_OPEN_HINT",
|
||||
"💡 Если ссылка не открывается автоматически, скопируйте её вручную: <code>{subscription_link}</code>",
|
||||
).format(subscription_link=subscription_link)
|
||||
).format(subscription_link=escaped_subscription_link)
|
||||
)
|
||||
|
||||
keyboard = get_happ_cryptolink_keyboard(subscription_link, db_user.language)
|
||||
@@ -4639,10 +4657,12 @@ async def handle_open_subscription_link(
|
||||
await callback.answer()
|
||||
return
|
||||
|
||||
escaped_subscription_link = html.escape(subscription_link)
|
||||
|
||||
link_text = (
|
||||
texts.t("SUBSCRIPTION_DEVICE_LINK_TITLE", "🔗 <b>Ссылка подписки:</b>")
|
||||
+ "\n\n"
|
||||
+ f"<code>{subscription_link}</code>\n\n"
|
||||
+ f"<code>{escaped_subscription_link}</code>\n\n"
|
||||
+ texts.t("SUBSCRIPTION_LINK_USAGE_TITLE", "📱 <b>Как использовать:</b>")
|
||||
+ "\n"
|
||||
+ "\n".join(
|
||||
|
||||
@@ -1,16 +1,21 @@
|
||||
from typing import List, Optional
|
||||
from aiogram import types
|
||||
from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton
|
||||
|
||||
import logging
|
||||
from datetime import datetime
|
||||
from app.database.models import User
|
||||
|
||||
from aiogram import types
|
||||
from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.config import settings, PERIOD_PRICES, TRAFFIC_PRICES
|
||||
from app.config import PERIOD_PRICES, TRAFFIC_PRICES, settings
|
||||
from app.database.models import User
|
||||
from app.localization.loader import DEFAULT_LANGUAGE
|
||||
from app.localization.texts import get_texts
|
||||
from app.utils.pricing_utils import format_period_description
|
||||
from app.utils.subscription_utils import get_display_subscription_link
|
||||
import logging
|
||||
from app.utils.subscription_utils import (
|
||||
get_display_subscription_link,
|
||||
is_supported_telegram_url,
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -255,48 +260,54 @@ def get_happ_download_button_row(texts) -> Optional[List[InlineKeyboardButton]]:
|
||||
|
||||
|
||||
def get_happ_cryptolink_keyboard(
|
||||
subscription_link: str,
|
||||
subscription_link: Optional[str],
|
||||
language: str = DEFAULT_LANGUAGE,
|
||||
) -> InlineKeyboardMarkup:
|
||||
texts = get_texts(language)
|
||||
buttons = [
|
||||
[
|
||||
buttons: List[List[InlineKeyboardButton]] = []
|
||||
|
||||
if is_supported_telegram_url(subscription_link):
|
||||
buttons.append([
|
||||
InlineKeyboardButton(
|
||||
text=texts.t("CONNECT_BUTTON", "🔗 Подключиться"),
|
||||
url=subscription_link,
|
||||
)
|
||||
],
|
||||
])
|
||||
|
||||
buttons.extend(
|
||||
[
|
||||
InlineKeyboardButton(
|
||||
text=texts.t("HAPP_PLATFORM_IOS", "🍎 iOS"),
|
||||
callback_data="happ_download_ios",
|
||||
)
|
||||
],
|
||||
[
|
||||
InlineKeyboardButton(
|
||||
text=texts.t("HAPP_PLATFORM_ANDROID", "🤖 Android"),
|
||||
callback_data="happ_download_android",
|
||||
)
|
||||
],
|
||||
[
|
||||
InlineKeyboardButton(
|
||||
text=texts.t("HAPP_PLATFORM_MACOS", "🖥️ Mac OS"),
|
||||
callback_data="happ_download_macos",
|
||||
)
|
||||
],
|
||||
[
|
||||
InlineKeyboardButton(
|
||||
text=texts.t("HAPP_PLATFORM_WINDOWS", "💻 Windows"),
|
||||
callback_data="happ_download_windows",
|
||||
)
|
||||
],
|
||||
[
|
||||
InlineKeyboardButton(
|
||||
text=texts.t("BACK_TO_MAIN_MENU_BUTTON", "⬅️ В главное меню"),
|
||||
callback_data="back_to_menu",
|
||||
)
|
||||
],
|
||||
]
|
||||
[
|
||||
InlineKeyboardButton(
|
||||
text=texts.t("HAPP_PLATFORM_IOS", "🍎 iOS"),
|
||||
callback_data="happ_download_ios",
|
||||
)
|
||||
],
|
||||
[
|
||||
InlineKeyboardButton(
|
||||
text=texts.t("HAPP_PLATFORM_ANDROID", "🤖 Android"),
|
||||
callback_data="happ_download_android",
|
||||
)
|
||||
],
|
||||
[
|
||||
InlineKeyboardButton(
|
||||
text=texts.t("HAPP_PLATFORM_MACOS", "🖥️ Mac OS"),
|
||||
callback_data="happ_download_macos",
|
||||
)
|
||||
],
|
||||
[
|
||||
InlineKeyboardButton(
|
||||
text=texts.t("HAPP_PLATFORM_WINDOWS", "💻 Windows"),
|
||||
callback_data="happ_download_windows",
|
||||
)
|
||||
],
|
||||
[
|
||||
InlineKeyboardButton(
|
||||
text=texts.t("BACK_TO_MAIN_MENU_BUTTON", "⬅️ В главное меню"),
|
||||
callback_data="back_to_menu",
|
||||
)
|
||||
],
|
||||
]
|
||||
)
|
||||
|
||||
return InlineKeyboardMarkup(inline_keyboard=buttons)
|
||||
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import logging
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
from sqlalchemy import select, delete, func
|
||||
from urllib.parse import urlsplit
|
||||
|
||||
from sqlalchemy import delete, func, select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from app.database.models import Subscription, User
|
||||
|
||||
from app.config import settings
|
||||
from app.database.models import Subscription, User
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -109,3 +112,17 @@ def get_display_subscription_link(subscription: Optional[Subscription]) -> Optio
|
||||
return crypto_link or base_link
|
||||
|
||||
return base_link
|
||||
|
||||
|
||||
def is_supported_telegram_url(url: Optional[str]) -> bool:
|
||||
"""Check whether Telegram allows using the given URL in inline buttons."""
|
||||
|
||||
if not url:
|
||||
return False
|
||||
|
||||
try:
|
||||
scheme = urlsplit(url).scheme
|
||||
except ValueError:
|
||||
return False
|
||||
|
||||
return scheme in {"http", "https", "tg", "ton"}
|
||||
|
||||
@@ -408,6 +408,7 @@
|
||||
"SUBSCRIPTION_DEVICE_GUIDE_TITLE": "📱 <b>Setup for {device_name}</b>",
|
||||
"SUBSCRIPTION_HAPP_OPEN_TITLE": "🔗 <b>Connect via Happ</b>",
|
||||
"SUBSCRIPTION_HAPP_OPEN_LINK": "<a href=\"{subscription_link}\">🔓 Open link in Happ</a>",
|
||||
"SUBSCRIPTION_HAPP_OPEN_COPY": "🔓 Copy the link and open it in Happ: <code>{subscription_link}</code>",
|
||||
"SUBSCRIPTION_HAPP_OPEN_HINT": "💡 If the link doesn't open automatically, copy it manually: <code>{subscription_link}</code>",
|
||||
"SUBSCRIPTION_DEVICE_LINK_TITLE": "🔗 <b>Subscription link:</b>",
|
||||
"SUBSCRIPTION_DEVICE_FEATURED_APP": "📋 <b>Recommended app:</b> {app_name}",
|
||||
|
||||
@@ -408,6 +408,7 @@
|
||||
"SUBSCRIPTION_DEVICE_GUIDE_TITLE": "📱 <b>Настройка для {device_name}</b>",
|
||||
"SUBSCRIPTION_HAPP_OPEN_TITLE": "🔗 <b>Подключение через Happ</b>",
|
||||
"SUBSCRIPTION_HAPP_OPEN_LINK": "<a href=\"{subscription_link}\">🔓 Открыть ссылку в Happ</a>",
|
||||
"SUBSCRIPTION_HAPP_OPEN_COPY": "🔓 Скопируйте ссылку и откройте в Happ: <code>{subscription_link}</code>",
|
||||
"SUBSCRIPTION_HAPP_OPEN_HINT": "💡 Если ссылка не открывается автоматически, скопируйте её вручную: <code>{subscription_link}</code>",
|
||||
"SUBSCRIPTION_DEVICE_LINK_TITLE": "🔗 <b>Ссылка подписки:</b>",
|
||||
"SUBSCRIPTION_DEVICE_FEATURED_APP": "📋 <b>Рекомендуемое приложение:</b> {app_name}",
|
||||
|
||||
Reference in New Issue
Block a user