Files
aiform_prod/docs/TELEGRAM_MINIAPP_FLOW.md
AI Assistant 2e45786e46 feat: Telegram Mini App integration and UX improvements
- Добавлена полная интеграция с 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 интеграции
2026-01-29 16:12:48 +03:00

8.0 KiB
Raw Permalink Blame History

Как срабатывает Telegram Mini App (по шагам)

Ты в Telegram нажимаешь кнопку «Открыть мини-апп» → открывается aiform.clientright.ru. Ниже — что происходит дальше и где.


1. Где открывается страница

  • Кто: Telegram (клиент на телефоне/десктопе).
  • Что: Открывает aiform.clientright.ru в своём встроенном браузере (WebView) как Mini App.
  • Важно: В этом режиме Telegram сам подставляет в страницу свой скрипт и объект window.Telegram.WebApp с полем initData (подпись пользователя и данные). В обычном браузере по прямой ссылке этого объекта нет.

2. Загрузка фронта (aiform.clientright.ru)

  • Загружается твой SPA (React): главная страница — форма заявки ClaimForm.
  • Рендерится первый экран формы (шаг 0).
  • Сразу при монтировании компонента запускается useEffect с функцией tryTelegramAuth()ClaimForm.tsx).

Где в коде: frontend/src/pages/ClaimForm.tsx, блок «Telegram Mini App: попытка авторизоваться через initData при первом заходе».


3. Проверка: это Mini App или обычный сайт?

Фронт делает:

  1. Смотрит, есть ли window.Telegram?.WebApp?.initData.
  2. Если нет — ждёт 300 ms (на случай асинхронной подгрузки скрипта Telegram) и проверяет снова.
  3. Если после этого нет initData → в консоль пишется «Telegram WebApp не обнаружен», авторизация по Telegram не вызывается, форма ведёт себя как обычный веб-сайт (SMS, сессия из localStorage и т.д.).
  4. Если есть initData:
    • Проверяет, есть ли уже в localStorage ключ session_token.
    • Если есть → считаем, что пользователь уже залогинен, tg/auth не вызываем, дальше работает обычное восстановление сессии.
    • Если нет → идём в шаг 4.

Итого: срабатывание tg/auth только когда:

  • страница открыта из Telegram (есть initData),
  • и в localStorage нет сохранённого session_token.

4. Запрос на бэкенд: POST /api/v1/tg/auth

  • Кто: фронт (ClaimForm).
  • Куда: на тот же домен aiform.clientright.ru → запрос уходит на твой backend (через nginx/proxy на порт 8200).
  • URL: POST /api/v1/tg/auth.
  • Тело: { "init_data": "<строка initData от Telegram>" }.

Где в коде: ClaimForm.tsxfetch('/api/v1/tg/auth', { method: 'POST', body: JSON.stringify({ init_data: webApp.initData }) }).


5. Обработка на бэкенде (tg/auth)

  • Где: backend/app/api/telegram_auth.py, эндпоинт POST /api/v1/tg/auth.

Последовательно:

  1. Валидация initData (backend/app/services/telegram_auth.py):

    • Проверка подписи через TELEGRAM_BOT_TOKEN из .env.
    • Если токена нет или подпись не совпадает → ответ 400 (или 500), фронт пишет «Telegram auth failed» и ведёт себя как обычный сайт.
  2. Извлечение пользователя Telegram: из initData достаются id, username, first_name, last_name.

  3. Запрос в n8n:

    • Бэкенд дергает N8N_TG_AUTH_WEBHOOK (URL из .env).
    • Передаёт: telegram_user_id, username, first_name, last_name, session_token, form_id.
    • Ожидает в ответе минимум unified_id (и при необходимости contact_id, phone, has_drafts).
  4. Создание сессии в Redis:

    • По session_token + unified_id (+ phone, contact_id) создаётся запись сессии (как после SMS-логина).
  5. Ответ фронту:
    { success: true, session_token, unified_id, contact_id?, phone?, has_drafts? }.

Если на любом шаге ошибка (нет токена, n8n не вернул unified_id и т.д.) — бэкенд отдаёт ошибку, фронт считает tg/auth неуспешным и продолжает как обычный веб.


6. Что делает фронт после успешного ответа

  • Сохраняет session_token в localStorage и в sessionIdRef.
  • Обновляет состояние формы: unified_id, phone, contact_id, session_id.
  • Ставит isPhoneVerified = true (шаг «телефон» считаем пройденным).
  • Если в ответе has_drafts === true → показывает экран выбора черновиков.
  • Если has_drafts нет или false → переводит на шаг 1 (описание проблемы).

Дальше пользователь идёт по форме как обычно: описание → черновик/визард → подтверждение → оплата и т.д., но уже без ввода телефона и SMS, потому что он «залогинен» через Telegram.


Сводка: где что срабатывает

Шаг Где Что происходит
1 Telegram Открывает aiform.clientright.ru в WebView, подставляет WebApp и initData
2 Браузер (WebView) Загружается SPA, монтируется ClaimForm
3 ClaimForm.tsx (фронт) Проверка: есть ли Telegram.WebApp.initData и нет ли session_token в localStorage
4 ClaimForm.tsx (фронт) POST /api/v1/tg/auth с init_data
5 telegram_auth.py (бэкенд) Валидация initData, запрос в n8n, создание сессии в Redis
6 ClaimForm.tsx (фронт) Сохранение session_token, переход на шаг черновиков или описание

Если открыть aiform.clientright.ru не из Telegram

  • В обычном браузере (Chrome, Safari по прямой ссылке) нет window.Telegram.WebApp.
  • Фронт пишет в консоль «Telegram WebApp не обнаружен» и не вызывает /api/v1/tg/auth.
  • Работает обычный сценарий: ввод телефона → SMS → сессия и т.д.

Что должно быть настроено

  1. В Telegram: у бота должна быть кнопка/меню, открывающее Mini App с URL https://aiform.clientright.ru (или с путём на эту форму).
  2. Backend .env:
    • TELEGRAM_BOT_TOKEN — токен этого же бота (для проверки initData).
    • N8N_TG_AUTH_WEBHOOK — URL webhook в n8n, который по telegram_user_id возвращает unified_id (и при необходимости contact_id, phone, has_drafts).
  3. n8n: workflow по этому webhook принимает JSON с telegram_user_id и т.д. и отдаёт JSON с полем unified_id (обязательно).

Если что-то из этого не настроено, цепочка обрывается на шаге 5 (бэкенд/n8n), и пользователь остаётся в «обычном» режиме формы без авторизации через Telegram.