Files
aiform_prod/docs/PROFILE_AND_N8N_CONTACT_WEBHOOK.md

6.1 KiB
Raw Permalink Blame History

Профиль пользователя и контакт-вебхук (N8N_CONTACT_WEBHOOK)

Описание изменений: раздел «Профиль» в мини-апе, передача chat_id в n8n, формат ответа вебхука и Code-нода для формирования JSON из SQL.


1. Раздел «Профиль» в мини-апе

  • Роут: /profile (фронт), кнопка «Профиль» в нижней панели ведёт на него без перезагрузки.
  • API: GET/POST /api/v1/profile/contact — по session_token (или unified_id) запрашивает контактные данные из CRM через n8n-вебхук N8N_CONTACT_WEBHOOK.
  • Фронт: страница Profile.tsx показывает поля: фамилия, имя, отчество, дата/место рождения, ИНН, email, адрес регистрации, почтовый адрес, банк для возмещения, мобильный телефон. Поддерживаются snake_case и camelCase из ответа.

2. Конфиг и бэкенд

  • config.py: добавлена настройка n8n_contact_webhook из переменной окружения N8N_CONTACT_WEBHOOK.
  • main.py: подключён роутер profile.
  • profile.py: реализованы GET/POST /api/v1/profile/contact, верификация сессии по session_token, сборка тела запроса к вебхуку и нормализация ответа n8n в формат { "items": [...] }.

3. Передача chat_id (Telegram / Max user id)

  • Сессия (session.py):

    • В SessionCreateRequest добавлено опциональное поле chat_id.
    • При создании сессии в Redis сохраняется chat_id, если передан.
    • В SessionVerifyResponse и в ответе verify_session возвращается chat_id.
  • Где передаётся chat_id при создании сессии:

    • auth2 (TG): chat_id = str(tg_user["telegram_user_id"]).
    • auth2 (MAX): chat_id = str(max_user["max_user_id"]).
    • telegram_auth: chat_id = str(telegram_user_id).
    • max_auth: chat_id = str(max_user_id).
    • SMS-флоу: chat_id не передаётся.
  • Профиль (profile.py):

    • В запрос к API добавлен параметр chat_id (query/body).
    • При верификации сессии chat_id подставляется из сессии, если не передан явно.
    • В теле POST на N8N_CONTACT_WEBHOOK всегда добавляется поле chat_id (строка), когда оно известно.
  • Фронт (Profile.tsx):

    • При запросе профиля передаётся chat_id: из Telegram.WebApp.initDataUnsafe?.user?.id или из WebApp.initDataUnsafe?.user?.id (MAX).

4. Формат запроса на N8N_CONTACT_WEBHOOK

Тело POST от бэкенда к n8n:

  • unified_id (str) — идентификатор в CRM
  • entry_channel (str) — "telegram" | "max" | "web"
  • chat_id (str, опционально) — Telegram user id или Max user id
  • session_token, contact_id, phone (опционально)

5. Формат ответа из n8n (как возвращать и как маппится)

Ничего не нашли: HTTP 200, тело: [] или { "items": [] }.

Нашли контакт(ы): HTTP 200, тело одно из:

  • массив [{...}, ...] → нормализуется в { "items": [...] };
  • { "items": [...] } — без изменений;
  • { "contact": {...} } / { "contact": [...] } → в items;
  • { "data": [...] } → в items;
  • один объект {...}{ "items": [{...}] };
  • пустой объект {}{ "items": [] }.

Поля контакта (snake_case или camelCase):
last_name, first_name, middle_name, birth_date, birth_place, inn, email, registration_address, mailing_address, bank_for_compensation, phone.

Подробности и маппинг полей описаны в докстринге модуля backend/app/api/profile.py.


6. Code-нода n8n для ответа вебхука из SQL

  • Файл: docs/N8N_CODE_PROFILE_CONTACT_RESPONSE.js
  • Назначение: после ноды select_user1 (SQL) формирует JSON для ответа вебхука.
  • Вход: данные из ноды select_user1 (массив строк с полями contactid, firstname, lastname, email, mobile, phone, birthday, mailingstreet, middle_name, birthplace, inn, bank и т.д.).
  • Выход: один item с { "items": [ {...}, ... ] } в формате полей для мини-апа (snake_case). Пустой результат → { "items": [] }.
  • Маппинг: mailingstreet → registration_address, birthday → birth_date, birthplace → birth_place, bank → bank_for_compensation, mobile/phone → phone и т.д.

Инструкция по цепочке Webhook → SQL → Code → Respond to Webhook: docs/N8N_PROFILE_CONTACT_WEBHOOK_RESPONSE.md.


7. Прочие изменения (в рамках той же задачи)

  • События SSE: единый формат event_type + message, цвета по типу (trash_message, out_of_scope, consumer_consultation, consumer_complaint), не показывать «Подключено к событиям» как ответ, не перезаписывать consumer_consultation в out_of_scope.
  • Кнопка «Домой» — программная навигация на главную.
  • Закрытие приложения при need_contact от вебхука (повторный вызов close, fallback без initData).
  • Передача в контакт-хук: unified_id, entry_channel, session_token, contact_id, phone, chat_id.