Трекинг событий Shopping Assistant

Для анализа качества Shopping Assistant передавайте в Gravity Field custom events по ключевым шагам диалога. Эти события помогают понять, открывают ли пользователи чат, отправляют ли сообщения, получают ли ответы и где возникают ошибки или разрывы воронки.

Сначала определите, кто отправляет событие: готовый виджет, товарный шаблон или ваш интерфейс. История ответов сохраняется сервисом отдельно; custom events не создают диалог в кабинете.

Готовый Web-виджет

В версии 1.41 события отправляются через GF.API('event', ...), а в properties передаётся threadId. Дополнительные поля из таблицы ниже не добавляются автоматически. У chat_dialog_end виджет использует поле thread_id, а не threadId.

Источник Что уже отправляется Что делает интегратор
Чат chat_dialog_open, chat_dialog_close, assistant_message_sent, assistant_response_received, assistant_product_selection_received, assistant_suggestion_clicked, chat_dialog_end, chat_error. Не дублирует эти события в обработчиках тех же действий.
Встроенная кнопка assistant_icon_clicked. Для собственной кнопки отправляет этот event при клике, если он нужен в воронке.
Оценки assistant_feedback_submitted_positive, assistant_feedback_submitted_negative; сохранение реакции выполняется отдельным PUT. Проверяет успешность feedback-запроса; custom event не подтверждает запись реакции.
Товарный шаблон Показы и клики в рамках настройки шаблона. Привязывает шаблон к кампании и проверяет engagement. Не вызывает те же tracking URL повторно.

Виджет не обрабатывает корневые tracking URL ответа генерации автоматически. Для товарных показов выберите один механизм: шаблон либо обработка URL собственным интерфейсом. assistant_product_selection_received означает получение блока товаров, а не их видимость.

При использовании своей кнопки:

GF.API('event', {
  name: 'assistant_icon_clicked',
  properties: { threadId: assistant.threadId }
});
assistant.open();

Событие добавьте в уже существующий обработчик открытия, а не во второй обработчик той же кнопки. Для проверки смотрите запрос события в Network и правила Web-событий.


Базовая воронка

Рекомендации ниже относятся к вашему интерфейсу и обработчикам событий. В готовом Web-виджете не отправляйте повторно события, перечисленные выше.

Минимальная воронка диалога:

chat_dialog_open -> assistant_message_sent -> assistant_response_received

Если ответ содержит товарную подборку, дополнительно фиксируйте:

assistant_response_received -> assistant_product_selection_received

Ошибки и закрытия анализируются отдельно:

chat_error
chat_dialog_close
chat_dialog_end

События ассистента

Событие Когда отправлять
chat_dialog_open Пользователь открыл чат ассистента.
assistant_message_sent Пользователь отправил сообщение ассистенту.
assistant_response_received Frontend получил и отобразил ответ ассистента.
assistant_product_selection_received Ответ ассистента содержит товарную подборку.
chat_error Frontend зафиксировал ошибку в сценарии ассистента.
chat_dialog_close Пользователь закрыл чат.
chat_dialog_end Диалог завершен.

Как считать ответ полученным

Событие assistant_response_received отправляйте после того, как ответ успешно получен и добавлен в интерфейс чата. Если API ответил, но пользователь уже закрыл чат или frontend не смог отрендерить ответ, событие отправлять не нужно.

Как считать товарную подборку

Событие assistant_product_selection_received отправляйте, если в ответе ассистента есть блок:

{
  "type": "products",
    "value": [{ "sku": "demo-sku", "name": "Демонстрационный товар" }]
}

В собственном интерфейсе не отправляйте это событие, если блок products отсутствует или список товаров пустой. Виджет 1.41 отправляет его при обработке каждого блока products, включая пустой; событие не подтверждает наличие или видимость карточек.


Рекомендуемые поля

Передавайте технические идентификаторы, которые позволяют связать события одного диалога и одного запроса. resourceId берите из user.uid Gravity Field. Его можно получить через POST /user.

Поле Назначение
threadId ID диалога. Должен совпадать с threadId в /shopping/generate.
resourceId uid пользователя Gravity Field.
messageId ID пользовательского сообщения, если клиентская сторона его генерирует.
requestId ID запроса к ассистенту, если клиентская сторона его генерирует.
trafficType real или test, если это значение используется в интеграции.
tenant_id ID секции Gravity Field.
campaignId ID кампании, если ассистент запущен из кампании.
experienceId ID experience, если ассистент запущен из кампании.
variationId ID variation, если ассистент запущен из кампании.
latencyMs Время ожидания ответа, где применимо.
errorCode Код ошибки для chat_error, если он есть на стороне клиента.

Пример custom event

Ниже пример события для API V2. Дополнительные поля передаются в customProps.

{
  "type": "assistant_message_sent",
  "name": "Assistant Message Sent",
  "customProps": {
    "threadId": "thread-8f2b1c",
    "resourceId": "demo-user",
    "messageId": "message-1001",
    "requestId": "request-7001",
    "trafficType": "test",
    "tenant_id": "demo-section",
    "campaignId": "demo-campaign",
    "experienceId": "demo-experience",
    "variationId": "demo-variation"
  }
}

Для передачи события используйте тот же канал, который уже применяется в вашей интеграции: Web, API или SDK.


Tracking товарных подборок

В ответе Shopping Assistant tracking-события могут находиться на двух уровнях:

Уровень Где искать Когда использовать
Рекомендательный блок и оценка ответа events[] в корне ответа Для tracking URL всего блока или like/dislike при нажатии оценки.
Товарная карточка response.contents[type="products"].value[].events[] Для visible_impression и click конкретного товара.

При наступлении события обработайте все элементы events[] с соответствующим type. Для каждого элемента выполните GET-запрос по каждому URL из urls[].

Для like и dislike это нажатие кнопки оценки, а не получение или показ ответа. Полный контракт: Оценка ответа.

async function sendTrackingEvents(events, type) {
  const urls = events
    .filter((event) => event.type === type)
    .flatMap((event) => event.urls ?? (event.url ? [event.url] : []));

  await Promise.allSettled(
    urls.map((url) => fetch(url, { method: "GET", keepalive: true }))
  );
}

sendTrackingEvents(result.events ?? [], "WRIMP");
sendTrackingEvents(product.events ?? [], "visible_impression");

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


Диагностика разрывов

Разрыв воронки возникает, когда пользователь отправил сообщение, но frontend не зафиксировал получение ответа:

assistant_message_sent -> нет assistant_response_received

Чтобы такие случаи можно было анализировать, важно:

  • использовать стабильный threadId на протяжении всего диалога;
  • передавать messageId или requestId для каждого пользовательского сообщения;
  • отправлять chat_error, если frontend получил ошибку;
  • отправлять chat_dialog_close, если пользователь закрыл чат;
  • передавать latencyMs в assistant_response_received и chat_error, если время ожидания известно.