// Telegram Mini App deep-link "start parameters", mirroring the connector's Go // scheme (platform/telegram/internal/deeplink): a one-character kind prefix plus a // value — // g open that game // i open that invitation // f<6-digit code> redeem that friend code // An empty or unrecognised parameter opens the lobby. export type DeepLink = | { kind: 'lobby' } | { kind: 'game'; id: string } | { kind: 'invitation'; id: string } | { kind: 'friendCode'; code: string }; /** parseStartParam classifies a Telegram start parameter into a routing target. */ export function parseStartParam(param: string | undefined | null): DeepLink { if (!param) return { kind: 'lobby' }; const value = param.slice(1); if (!value) return { kind: 'lobby' }; switch (param[0]) { case 'g': return { kind: 'game', id: value }; case 'i': return { kind: 'invitation', id: value }; case 'f': return { kind: 'friendCode', code: value }; default: return { kind: 'lobby' }; } } /** gameParam builds the start parameter that opens a game. */ export const gameParam = (id: string): string => 'g' + id; /** invitationParam builds the start parameter that opens an invitation. */ export const invitationParam = (id: string): string => 'i' + id; /** friendCodeParam builds the start parameter that redeems a friend code. */ export const friendCodeParam = (code: string): string => 'f' + code; function envVar(name: string): string | undefined { return (import.meta.env as Record)[name]; } /** * telegramBase returns the single bot's Mini App link base (e.g. https://t.me//) * from VITE_TELEGRAM_LINK, or null when it is not configured. */ function telegramBase(): string | null { return envVar('VITE_TELEGRAM_LINK') || null; } /** * botUsername extracts the bot's @username (without the @) from the configured Mini App * link: the first path segment of https://t.me//. Returns null when no base is * configured or the link carries no path. */ export function botUsername(): string | null { const base = telegramBase(); if (!base) return null; try { const seg = new URL(base).pathname.split('/').filter(Boolean)[0]; return seg || null; } catch { return null; } } /** * shareLink wraps a deep-link start parameter in a t.me Mini App link for the single * bot. Returns null when no base is configured, so callers can hide the share affordance. */ export function shareLink(param: string): string | null { const base = telegramBase(); if (!base) return null; const sep = base.includes('?') ? '&' : '?'; return `${base}${sep}startapp=${encodeURIComponent(param)}`; }