- Добавлена полная интеграция с Telegram Mini App (динамическая загрузка SDK) - Отдельный компактный дизайн для Telegram Mini App - Добавлен loader при инициализации (предотвращает мелькание SMS-авторизации) - Улучшена навигация: кнопки "Назад" и "К списку заявок" теперь сохраняют авторизацию - Telegram Mini App: кнопка "Выход" просто закрывает приложение - Telegram Mini App: заявки "В работе" скрыты из списка - Веб-версия: для заявок "В работе" добавлена кнопка "Просмотреть в Telegram" (ссылка на @klientprav_bot) - Telegram Mini App: кнопки действий в черновиках расположены вертикально - Веб-версия: убрано отображение номера телефона в приветствии - Исправлена проблема с возвратом к списку черновиков (не требует повторной SMS-авторизации) - Заблокировано удаление и редактирование заявок со статусом "В работе" - Добавлена документация по Telegram Mini App интеграции
63 lines
1.9 KiB
JavaScript
63 lines
1.9 KiB
JavaScript
/**
|
||
* n8n Code node: парсинг сырого init_data из Telegram WebApp
|
||
*
|
||
* Вход: объект с полем init_data (строка query string от Telegram).
|
||
* Выход: тот же объект + поля init_data_parsed и user_decoded.
|
||
*
|
||
* Подключение: после Webhook — в Code передаётся $input.item.json.
|
||
* init_data должен быть в $json.init_data (как шлёт наш бэкенд).
|
||
*/
|
||
|
||
const item = $input.first().json;
|
||
|
||
// Сырая строка init_data (query string)
|
||
const rawInitData = item.init_data || item.body?.init_data || '';
|
||
|
||
if (!rawInitData) {
|
||
return [{ json: { ...item, init_data_error: 'init_data отсутствует' } }];
|
||
}
|
||
|
||
/**
|
||
* Парсит query string в объект (значения URL-декодированы)
|
||
*/
|
||
function parseQueryString(qs) {
|
||
const result = {};
|
||
const pairs = qs.split('&');
|
||
for (const pair of pairs) {
|
||
const [key, value] = pair.split('=').map(s => decodeURIComponent(s || ''));
|
||
if (key) result[key] = value;
|
||
}
|
||
return result;
|
||
}
|
||
|
||
const parsed = parseQueryString(rawInitData);
|
||
|
||
// user приходит как URL-encoded JSON строка
|
||
let userDecoded = null;
|
||
if (parsed.user) {
|
||
try {
|
||
userDecoded = JSON.parse(parsed.user);
|
||
} catch (e) {
|
||
userDecoded = { _parse_error: String(e), raw: parsed.user };
|
||
}
|
||
}
|
||
|
||
return [{
|
||
json: {
|
||
...item,
|
||
init_data_parsed: {
|
||
query_id: parsed.query_id || null,
|
||
auth_date: parsed.auth_date ? parseInt(parsed.auth_date, 10) : null,
|
||
hash: parsed.hash || null,
|
||
signature: parsed.signature || null,
|
||
user_raw: parsed.user || null,
|
||
},
|
||
user_decoded: userDecoded,
|
||
// удобные поля для маппинга в CRM
|
||
telegram_user_id: userDecoded?.id ?? null,
|
||
telegram_username: userDecoded?.username ?? null,
|
||
telegram_first_name: userDecoded?.first_name ?? null,
|
||
telegram_last_name: userDecoded?.last_name ?? null,
|
||
},
|
||
}];
|