import crypto from 'crypto'; interface TelegramUser { id: number; first_name: string; last_name?: string; username?: string; language_code?: string; } interface TelegramInitData { query_id?: string; user: TelegramUser; auth_date: number; hash: string; } export async function verifyTelegramWebAppData(initData: string): Promise { try { const botToken = process.env.TELEGRAM_BOT_TOKEN; if (!botToken) { throw new Error('TELEGRAM_BOT_TOKEN is not defined'); } // Разбираем строку initData const searchParams = new URLSearchParams(initData); const hash = searchParams.get('hash'); searchParams.delete('hash'); // Сортируем параметры const params = Array.from(searchParams.entries()) .sort(([a], [b]) => a.localeCompare(b)) .map(([key, value]) => `${key}=${value}`) .join('\n'); // Создаем секретный ключ const secretKey = crypto .createHmac('sha256', 'WebAppData') .update(botToken) .digest(); // Вычисляем хеш const calculatedHash = crypto .createHmac('sha256', secretKey) .update(params) .digest('hex'); // Проверяем хеш if (calculatedHash !== hash) { return null; } // Парсим данные пользователя const user: TelegramUser = JSON.parse(searchParams.get('user') || '{}'); const authDate = parseInt(searchParams.get('auth_date') || '0', 10); return { query_id: searchParams.get('query_id') || undefined, user, auth_date: authDate, hash: hash || '', }; } catch (error) { console.error('Error verifying Telegram data:', error); return null; } }