# Интеграция Shopping Assistant по API

Настройте Shopping Assistant в собственном интерфейсе через API. Ваше приложение самостоятельно вызывает Gravity Field API V2 и Shopping Assistant API, управляет состоянием диалога и отображает интерфейс ассистента.

Подробные контракты вынесены в [API-справочник](reference/overview.md). Следуйте шагам ниже, чтобы получить первый ответ и отобразить товары. Параметры методов, примеры ответов и ошибки находятся на отдельных страницах.

## Как работает интеграция

```mermaid
sequenceDiagram
    actor User as Покупатель
    participant Client as Клиентский канал
    participant GFAPI as Gravity Field API V2
    participant Assistant as Shopping Assistant API

    Client->>GFAPI: POST /visit<br/>user + ctx + device
    GFAPI-->>Client: user.uid + user.ses
    Client->>Client: Сохранить uid и ses
    Client->>GFAPI: POST /event<br/>e-commerce события

    Client->>GFAPI: POST /choose<br/>selector + user + ctx<br/>isBuildEngagementUrl + isImplicitImpression
    GFAPI-->>Client: Вариация + tracking URL<br/>welcome-настройки опционально

    alt JSON-контракт разрешает показ
        Client->>Client: Показать точку входа и welcome-экран
        Client->>GFAPI: GET campaign WRIMP URL
        User->>Client: Открывает ассистента и отправляет сообщение
        Client->>GFAPI: POST /event<br/>события диалога
        Client->>Assistant: POST /shopping/generate<br/>threadId + resourceId=user.uid + новое сообщение
        Assistant-->>Client: contents + ui.suggests + tracking events
        Client->>Client: Отобразить ответ
        Client->>GFAPI: POST /event + GET tracking URL
        User->>Client: Оценивает ответ
        Client->>Assistant: GET feedback URL или PUT /shopping/feedback<br/>messageId + reaction
    else JSON-контракт запрещает показ
        Client->>Client: Не показывать ассистента
    end
```

## Шаги интеграции

### 1. Синхронизируйте товарный фид

Shopping Assistant подбирает товары из каталога Gravity Field. До подключения API настройте синхронизацию фида и проверьте, что в нем есть актуальные товары, остатки и атрибуты, необходимые для подбора.

Формат, обязательные поля и настройка синхронизации описаны в разделе [Требования к товарному фиду](/Integration/products_catalogues/general_reqs.md).

Если поиск и ранжирование должен выполнять собственный сервис клиента, подключите его через BYOA: контракт API и условия подключения описаны в разделе [Свой поиск через BYOA](data/byoa_search_api.md).

Если ассистент должен отвечать о наличии товара в конкретном магазине, а магазинов много и остатки быстро меняются, подготовьте отдельный [API наличия товаров в магазинах](data/store_availability_api.md). Фид и `lng` не заменяют проверку актуального остатка по SKU и точке продаж.

### 2. Настройте API V2 и передачу просмотров

Получите `sec` и bearer API key, затем настройте HTTP-клиент по инструкции [Начало интеграции API V2](/Integration/api_integration/v2/getting_started.md).

Передавайте [`POST /visit`](/Integration/api_integration/v2/personalization/visit.md) при каждом просмотре страницы или экрана, а не только там, где должен отображаться ассистент. В запросе используйте актуальные `user`, `ctx` и `device`.

- Для нового пользователя передайте пустой `user`.
- Для известного пользователя передайте сохраненные `uid` и `ses`.
- Если используется собственный ID клиента, передайте `user.custom` вместе с `user.ses`.

Сохраняйте `user.uid` между сессиями, а `user.ses` - в рамках текущей сессии. Если API вернул обновленные значения, замените ими сохраненные. В дальнейших запросах Shopping Assistant используйте `user.uid` как `resourceId`.

Структура пользователя, авторизация и правила хранения идентификаторов описаны в разделе [Начало интеграции API V2](/Integration/api_integration/v2/getting_started.md).

### 3. Передавайте e-commerce события

Передавайте основные e-commerce события через [`POST /event`](/Integration/api_integration/v2/personalization/events.md):

- `add-to-cart-v1` - добавление товара в корзину;
- `purchase-v1` - покупка;
- `login-v1` и `signup-v1` - авторизация и регистрация для склейки профилей пользователя.

При необходимости передавайте и другие события, предусмотренные вашей интеграцией. Вместе с каждым событием используйте актуальные `user`, `ctx` и `device`.

Просмотры страниц и e-commerce события нужны для профиля пользователя, контекстного таргетинга, аналитики и оценки результатов кампании.

### 4. Запросите API-кампанию по selector

Создайте и опубликуйте API-кампанию с согласованным selector: [Создание API-кампании](/personalization/Campaigns/api_campaigns.md).

После `/visit` отдельно вызовите [`POST /choose`](/Integration/api_integration/v2/personalization/choose.md):

- передайте согласованный selector в `data[].selector`;
- используйте актуальные `user.uid`, `user.ses` и `ctx`;
- передайте `options.isBuildEngagementUrl: true`;
- передайте `options.isImplicitImpression: true`, чтобы зафиксировать `IMP` вместе с выбором вариации.

Gravity Field применяет таргетинг и распределение трафика внутри API-кампании и возвращает выбранную вариацию.

Заранее согласуйте контракт контрольной группы. Она может возвращать пустой JSON или специальный флаг внутри JSON. Клиентский канал должен определять необходимость показа ассистента по согласованному контракту вариации.

Welcome-настройки в вариации необязательны. При необходимости через [переменные кампании](/personalization/Campaigns/variables.md) можно передавать `title`, `subtitle` и `suggests[]`, а для разных `ctx` настраивать отдельные сценарии. Если значения не пришли, используйте настройки UI по умолчанию.

Передавайте в `/choose` актуальный [контекст](/Integration/api_integration/v2/context.md), чтобы Gravity Field мог применить нужный сценарий и таргетинг.

### 5. Отобразите кампанию и отправьте engagement

`IMP` фиксируется самим запросом `/choose` при включенном `options.isImplicitImpression`. Не вызывайте для него отдельный tracking URL.

Когда точка входа стала видимой, вызовите все tracking URL события `WRIMP` из ответа `/choose`.

Не собирайте engagement URL вручную и не ограничивайтесь первым URL в массиве. Общие правила описаны в разделе [Взаимодействия с кампаниями](/Integration/api_integration/v2/personalization/engagement.md).

### 6. Создайте диалог

Когда пользователь открывает ассистента:

1. Создайте стабильный `threadId` для новой чат-сессии.
2. Отобразите welcome-экран из настроек вариации или настроек UI по умолчанию.
3. Отправьте событие `chat_dialog_open` через API V2 `POST /event`.
4. При отправке сообщения передайте `assistant_message_sent`.
5. Вызовите `POST /shopping/generate`, передав:
   - тот же `threadId`;
   - `resourceId`, равный `user.uid`;
   - только новое сообщение пользователя;
   - `tenant_id` и актуальный контекст; если выбран магазин, передайте его ID в [`runtimeContext.ctx.attributes.storeId`](reference/generate.md#как-заполнять-ctx).

На следующих ходах сохраняйте те же `threadId` и `resourceId`. Историю сообщений повторно передавать не нужно.

Контракт запроса, текстовые и графические сообщения описаны в [API-справочнике](reference/overview.md).

Во время разработки проверьте транспорт и рендеринг на фиксированной заглушке: передайте `trafficType: "debug"`. Такой запрос не обращается к LLM, не расходует токены и не сохраняется в истории. Формат запроса, полный ответ и ограничения режима описаны в разделе [Режим отладки](reference/generate.md#режим-отладки).

### 7. Отобразите ответ

Клиентский канал отвечает за рендеринг блоков из ответа:

- `message` - сообщение ассистента;
- `products` - товарные карточки;
- `button` - действие клиента;
- `response.ui.suggests` - быстрые ответы.

Событие `assistant_response_received` отправляйте только после успешного добавления ответа в UI. Если ответ содержит непустой блок товаров, дополнительно отправьте `assistant_product_selection_received`.

Сохраните `assistantMessageId` из ответа `/shopping/generate` вместе с сообщением: он нужен для отправки пользовательской оценки.

Правила событий диалога: [Трекинг событий Shopping Assistant](./tracking.md). Полный контракт ответа: [API-справочник](reference/overview.md).

### 8. Передайте tracking товаров

Shopping Assistant возвращает готовые tracking URL:

- `events[]` верхнего уровня могут содержать tracking URL блока и ссылки оценки ответа;
- `events[]` внутри товара относятся к конкретной карточке.

При видимости блока или карточки и при клике вызовите все URL соответствующего события. Ошибка tracking-запроса не должна блокировать UI или действие пользователя.

Ссылки `like` и `dislike` обрабатывайте отдельно, только при нажатии оценки. Не вызывайте все события из ответа автоматически.

Подробная структура событий и пример обработчика приведены в разделе [Трекинг событий Shopping Assistant](./tracking.md#tracking-товарных-подборок).

## Дополнительные возможности

Следующие возможности не требуются для первого запуска. Подключайте их в зависимости от сценария клиентского интерфейса.

### Оценка ответа

Покажите элементы оценки рядом с ответами. Для нового ответа можно вызвать готовый GET URL типа `like` или `dislike` из `events[]`; для снятия реакции или оценки восстановленного сообщения используйте PUT. Сохраняйте идентификатор именно того ответа, который оценивается. Контракты и ошибки: [Оценка ответа](reference/feedback.md).

### Восстановление истории

Чтобы повторно открывать существующий диалог, вызывайте `POST /shopping/history` с теми же `tenant_id`, `resourceId` и `threadId`. Отображайте полученную историю в UI, но не отправляйте ее повторно в `/shopping/generate`. Контракт и пагинация описаны в [Shopping Assistant API](reference/history.md#post-shoppinghistory).

### Шаринг диалога

Чтобы покупатель мог поделиться историей разговора и товарной подборкой, добавьте действие «Поделиться» и создавайте публичную копию диалога (snapshot) через `POST /dialogs/share`. Публичный endpoint возвращает JSON; страницу для получателя и ее внешний вид реализует клиентский канал.

Используйте `resourceId` исходного диалога как `user_id`, а `threadId` — как `dialog_id`. Не передавайте `tenant_id`. Полный сценарий, контракт и ограничения описаны в разделе [Шаринг диалогов](reference/dialog_sharing.md).

## Проверка базовой интеграции

- [ ] Товарный фид успешно синхронизируется и содержит необходимые для подбора товары и атрибуты.
- [ ] `/visit` отправляется для всех просмотров страниц или экранов.
- [ ] E-commerce события передаются через `/event` с теми же идентификаторами пользователя.
- [ ] `/visit` возвращает или обновляет `uid` и `ses`, значения сохраняются корректно.
- [ ] `/choose` вызывается по selector с `isBuildEngagementUrl` и `isImplicitImpression`.
- [ ] API-кампания возвращает ожидаемые вариации и контрольную группу.
- [ ] При отсутствии welcome-настроек используются значения UI по умолчанию.
- [ ] Контрольная группа обрабатывается по согласованному JSON-контракту.
- [ ] Campaign `IMP` фиксируется через `isImplicitImpression`, а `WRIMP` отправляется по всем URL один раз при видимости.
- [ ] Один диалог использует неизменные `threadId` и `resourceId`.
- [ ] В `/shopping/generate` отправляется только новое сообщение.
- [ ] В debug-режиме клиент корректно отображает текст, товары и быстрые ответы из фиксированной заглушки.
- [ ] Текст, изображения, товары, кнопки и быстрые ответы отображаются корректно.
- [ ] `assistantMessageId` сохраняется вместе с каждым новым ответом ассистента.
- [ ] Custom events диалога отправляются через API V2 `POST /event`.
- [ ] Tracking URL блока товаров и отдельных карточек вызываются в нужный момент.
- [ ] Повтор запроса после ошибки не создает новый диалог и не дублирует сообщение.

### Проверка дополнительных возможностей

- [ ] Оценка отправляется выбранным методом GET или PUT, а ошибки не оставляют в UI неподтверждённое состояние.
- [ ] При восстановлении истории учитываются `feedback.reaction` и `id` сообщения ассистента.
- [ ] Для шаринга используются те же `resourceId` и `threadId`, что и в исходном диалоге.
- [ ] Публичная страница отображает только поля из snapshot-а и корректно обрабатывает недоступную или отозванную ссылку.
- [ ] `share_token` не попадает в аналитику, error tracking и прикладные логи.

## Связанные материалы

- [API-справочник](reference/overview.md)
- [Шаринг диалога](reference/dialog_sharing.md)
- [Трекинг](./tracking.md)
- [Собственный поиск BYOA](data/byoa_search_api.md)
