feat: open bot install guides in mini app
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
"""Helpers for Telegram bot install-guide links."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, Optional
|
||||
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from bot.utils.mini_app_url import (
|
||||
subscription_mini_app_install_url,
|
||||
subscription_public_install_url,
|
||||
)
|
||||
from config.subscription_guides_config import subscription_guides_available
|
||||
from db.dal import subscription_dal
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class InstallGuideLinks:
|
||||
personal_url: Optional[str] = None
|
||||
public_share_url: Optional[str] = None
|
||||
|
||||
|
||||
def bot_install_guides_enabled(settings: Any) -> bool:
|
||||
return bool(
|
||||
getattr(settings, "SUBSCRIPTION_GUIDES_BOT_MENU_ENABLED", False)
|
||||
and subscription_guides_available(settings)
|
||||
and subscription_mini_app_install_url(settings)
|
||||
)
|
||||
|
||||
|
||||
def bot_install_guide_url(settings: Any) -> Optional[str]:
|
||||
if not bot_install_guides_enabled(settings):
|
||||
return None
|
||||
return subscription_mini_app_install_url(settings)
|
||||
|
||||
|
||||
async def ensure_user_install_guide_links(
|
||||
session: AsyncSession,
|
||||
settings: Any,
|
||||
user_id: int,
|
||||
panel_user_uuid: Optional[str] = None,
|
||||
local_subscription: Optional[Any] = None,
|
||||
) -> InstallGuideLinks:
|
||||
personal_url = bot_install_guide_url(settings)
|
||||
if not personal_url:
|
||||
return InstallGuideLinks()
|
||||
|
||||
public_share_url = None
|
||||
try:
|
||||
local_sub = (
|
||||
local_subscription
|
||||
if local_subscription is not None
|
||||
else await subscription_dal.get_active_subscription_by_user_id(
|
||||
session,
|
||||
user_id,
|
||||
panel_user_uuid,
|
||||
)
|
||||
)
|
||||
if local_sub is not None:
|
||||
share_token = await subscription_dal.ensure_install_share_token(session, local_sub)
|
||||
public_share_url = subscription_public_install_url(settings, share_token)
|
||||
except Exception:
|
||||
logging.exception("Failed to resolve install guide share link for user %s.", user_id)
|
||||
|
||||
return InstallGuideLinks(personal_url=personal_url, public_share_url=public_share_url)
|
||||
|
||||
|
||||
def append_install_share_link_text(
|
||||
text: str,
|
||||
translator: Any,
|
||||
public_share_url: Optional[str],
|
||||
) -> str:
|
||||
if not public_share_url:
|
||||
return text
|
||||
try:
|
||||
share_line = translator(
|
||||
"install_guide_share_link_line",
|
||||
install_share_link=public_share_url,
|
||||
)
|
||||
except Exception:
|
||||
share_line = f"\n\nInstall guide:\n<code>{public_share_url}</code>"
|
||||
return f"{text}{share_line}"
|
||||
@@ -3,9 +3,10 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Optional
|
||||
from urllib.parse import parse_qsl, urlencode, urlsplit, urlunsplit
|
||||
from urllib.parse import parse_qsl, quote, urlencode, urlsplit, urlunsplit
|
||||
|
||||
from config.settings import Settings
|
||||
from db.dal.subscription_dal import normalize_install_share_token
|
||||
|
||||
|
||||
def append_query_params(base_url: str, params: dict[str, str]) -> str:
|
||||
@@ -31,3 +32,31 @@ def subscription_mini_app_topup_url(settings: Settings, kind: str) -> Optional[s
|
||||
return None
|
||||
normalized = "premium" if str(kind or "").strip().lower() == "premium" else "regular"
|
||||
return append_query_params(base, {"topup": normalized})
|
||||
|
||||
|
||||
def subscription_mini_app_path_url(settings: Settings, path: str) -> Optional[str]:
|
||||
"""Return a Mini App URL with ``path`` appended to the configured app base."""
|
||||
base = str(getattr(settings, "SUBSCRIPTION_MINI_APP_URL", None) or "").strip()
|
||||
if not base:
|
||||
return None
|
||||
normalized_path = f"/{str(path or '').lstrip('/')}"
|
||||
return f"{base.rstrip('/')}{normalized_path}"
|
||||
|
||||
|
||||
def subscription_mini_app_install_url(settings: Settings) -> Optional[str]:
|
||||
"""Return the personal embedded install guide URL."""
|
||||
return subscription_mini_app_path_url(settings, "/install")
|
||||
|
||||
|
||||
def subscription_public_install_url(settings: Settings, share_token: str) -> Optional[str]:
|
||||
"""Return the public install guide URL for a normalized share token."""
|
||||
token = normalize_install_share_token(share_token)
|
||||
base = str(getattr(settings, "SUBSCRIPTION_MINI_APP_URL", None) or "").strip()
|
||||
if not token or not base:
|
||||
return None
|
||||
parts = urlsplit(base)
|
||||
if parts.scheme and parts.netloc:
|
||||
public_base = urlunsplit((parts.scheme, parts.netloc, "", "", ""))
|
||||
else:
|
||||
public_base = base.rstrip("/")
|
||||
return f"{public_base.rstrip('/')}/s/{quote(token)}"
|
||||
|
||||
Reference in New Issue
Block a user