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

123 lines
8.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Как срабатывает 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.tsx``fetch('/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.