import { isLocale, type Locale } from './types.ts'; /** * Payload для t.me/?start= (LND-3, ONB-1). * Telegram ограничивает его 64 символами из [A-Za-z0-9_-], поэтому формат компактный: * * l-ru_a-AGENCY1 язык и код агентства * s-k3j9x2 короткий токен; язык, агентство и UTM лежат в БД (StartToken) * * Части разделены "_", ключ и значение — "-". Неизвестные части игнорируются. */ export interface StartPayload { locale?: Locale; agency?: string; token?: string; } export const START_PAYLOAD_MAX = 64; const SAFE = /^[A-Za-z0-9]+$/; export function normalizeAgencyCode(code: string): string | null { const c = code.trim().toUpperCase(); return SAFE.test(c) && c.length <= 32 ? c : null; } export function encodeStartPayload(p: StartPayload): string { const parts: string[] = []; if (p.token) { if (!SAFE.test(p.token)) throw new Error('Bad token'); parts.push(`s-${p.token}`); } if (p.locale) parts.push(`l-${p.locale}`); if (p.agency) { const a = normalizeAgencyCode(p.agency); if (a) parts.push(`a-${a}`); } const out = parts.join('_'); if (out.length > START_PAYLOAD_MAX) throw new Error('Start payload too long'); return out; } export function decodeStartPayload(raw: string | undefined | null): StartPayload { const out: StartPayload = {}; if (!raw) return out; for (const part of raw.slice(0, START_PAYLOAD_MAX).split('_')) { const [key, value] = [part.slice(0, 1), part.slice(2)]; if (part[1] !== '-' || !value) continue; if (key === 'l' && isLocale(value)) out.locale = value; else if (key === 'a') { const a = normalizeAgencyCode(value); if (a) out.agency = a; } else if (key === 's' && SAFE.test(value)) out.token = value; } return out; } export const UTM_KEYS = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_content', 'utm_term'] as const; export type Utm = Partial>; export function pickUtm(params: URLSearchParams): Utm { const utm: Utm = {}; for (const k of UTM_KEYS) { const v = params.get(k); if (v) utm[k] = v.slice(0, 120); } return utm; } export function botLink(username: string, payload: string): string { return `https://t.me/${username}${payload ? `?start=${payload}` : ''}`; }