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

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

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

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

В версии 1.42 события отправляются через window.SL.API('event', ...). Если сайт использует GF, настройте совместимость с SL. В properties передаётся только threadId; дополнительные поля из таблицы ниже не добавляются автоматически. Модуль аналитики преобразует внутреннее поле thread_id события chat_dialog_end в properties.threadId.

У chat_dialog_open, chat_dialog_close и chat_error значение properties.threadId равно null: вызывающий код не передаёт ID. Наличие этих событий не позволяет автоматически связать их с конкретной перепиской. У остальных перечисленных событий ID берётся из текущего диалога либо из контекста оцениваемого ответа; до первого открытия или после завершения он также может быть null.

Источник Что уже отправляется Что делает интегратор
Чат 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_new_chat_clicked, assistant_support_chat_button_clicked. Не дублирует события встроенных кнопок. Программный вызов startNewChat() не отправляет событие клика.
История assistant_dialogs_opened, assistant_dialog_selected. Не дублирует события открытия списка и выбора диалога. При восстановлении сообщений виджет не отправляет события получения новых ответов и подборок.
Кнопка-ссылка assistant_follow_url_button_clicked. Для своего перехода использует DOM-событие shopping-assistant-follow-url. URL не попадает в properties: модуль аналитики передаёт только threadId.
Оценки 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-событий.

chat_dialog_end виджет отправляет после выбора оценки, до подтверждения PUT. В 1.42 при этом threadId сохраняется, и покупатель может продолжить тот же разговор: событие не подтверждает фактическое завершение диалога. Кнопка «Новый чат» вызывает startNewChat() без chat_dialog_end, а закрытие отправляет только chat_dialog_close. Эти различия учитывайте при анализе завершений и разрывов воронки.


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

Рекомендации ниже относятся к вашему интерфейсу и обработчикам событий. В готовом 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.42 отправляет его при обработке каждого нового блока products, включая пустой; событие не подтверждает наличие или видимость карточек. При восстановлении истории этот custom event не отправляется, хотя DOM-событие shopping-assistant-recs для непустых блоков приходит снова.


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

Передавайте технические идентификаторы, которые позволяют связать события одного диалога и одного запроса. В resourceId передавайте тот же идентификатор, что в запросах Shopping Assistant: user.uid Gravity Field или значение user.custom, если ваша интеграция использует внешний ID. user.uid можно получить через POST /user. Гостевые токены не меняют способ идентификации пользователя; в события их не передавайте.

Поле Назначение
threadId ID диалога. Должен совпадать с threadId в /shopping/generate.
resourceId Тот же идентификатор, что в /shopping/generate: user.uid или используемый в интеграции user.custom.
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 это нажатие кнопки оценки, а не получение или показ ответа. В гостевой интеграции используйте PUT с заголовком Authorization вместо обычного вызова GET-ссылки. Полный контракт: Оценка ответа.

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, если время ожидания известно.