Аналитические события виджета
Типы событий, транспорт, схема данных и текущий статус сохранения для отслеживания аналитики виджета.
Виджет AACsearch автоматически отслеживает поведение пользователя и отправляет события на аналитический эндпоинт. Эти события питают панель аналитики поиска — топовые запросы, процент нулевых результатов, кликабельность (CTR) и поиски во времени.
Эндпоинт
POST /api/events/track
Authorization: Bearer <ключ ss_search_* или ss_scoped_*>
Content-Type: application/jsonТот же API-ключ, что используется для поиска (ss_search_*), аутентифицирует аналитические события. Эндпоинт разрешён для всех источников через CORS.
Типы событий
| Тип события | Триггер | Приоритет |
|---|---|---|
search_query | Пользователь отправляет поисковый запрос | P0 |
zero_results | Поиск не возвращает результатов | P0 |
result_click | Пользователь нажимает на результат товара | P0 |
widget_open | Виджет открывается / становится видимым | P1 |
filter_used | Пользователь применяет или изменяет фасетный фильтр | P1 |
Транспорт
Виджет отправляет события с keepalive: true, чтобы не терять события при навигации по странице:
fetch(eventsUrl, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer " + apiKey,
},
keepalive: true,
body: JSON.stringify(payload),
});Схема данных
Можно отправить одно событие или пакет до 50 событий.
Одиночное событие:
{
"type": "search_query",
"sessionId": "a1b2c3d4-e5f6-...",
"anonymousUserId": "uid_xyz",
"query": "blue running shoes",
"locale": "en",
"referrer": "https://myshop.example.com/search",
"metadata": {}
}Пакет:
{
"events": [
{ "type": "widget_open", "sessionId": "a1b2c3d4-..." },
{ "type": "search_query", "query": "blue running shoes", "sessionId": "a1b2c3d4-..." }
]
}Справочник полей
| Поле | Тип | Макс. длина | Описание |
|---|---|---|---|
type | string | — | Тип события (см. таблицу выше) |
sessionId | string | 64 | Эфемерный ID сессии (crypto.randomUUID() или запасной вариант) |
anonymousUserId | string | 64 | Стабильный анонимный ID пользователя (на браузер, может быть null в режиме приватности) |
query | string | 512 | Строка поискового запроса (события search_query и zero_results) |
productId | string | 128 | Внешний ID товара (события result_click) |
position | integer | — | Ранг нажатого результата, с 1 (события result_click) |
filters | object | — | Активные фасетные фильтры на момент события (события filter_used) |
sort | string | 128 | Активный вариант сортировки |
locale | string | 16 | Локаль из конфигурации виджета |
referrer | string | 512 | URL страницы (из document.referrer) |
metadata | object | 4 КБ | Непрозрачные дополнительные данные — без персональных данных |
Генерация ID сессии
Виджет генерирует ID сессии с помощью crypto.randomUUID() с запасным вариантом для простой случайной строки:
const sessionId =
typeof crypto !== "undefined" && crypto.randomUUID
? crypto.randomUUID()
: Math.random().toString(36).slice(2);ID сессии создаётся на экземпляр виджета / загрузку страницы. Он не сохраняется между сессиями.
Сохранение данных
Каждое событие сохраняется в таблицу SearchUsageEvent через recordSearchUsage(). Тип события сопоставляется следующим образом:
| Тип события виджета | Сохраняемый SearchUsageEvent.type |
|---|---|
search_query | "search_query" |
zero_results | "zero_results" |
result_click | "click" |
widget_open | "widget_open" |
filter_used | "filter_applied" |
Все поля метаданных (query, productId, position, filters, sort, locale, referrer, sessionId, anonymousUserId, user-agent) сохраняются как JSON-блоб в SearchUsageEvent.metadata.
Что хранится и что не хранится
Хранится:
- Тип события
- ID сессии (эфемерный, случайный)
- Анонимный ID пользователя (случайный, стабильный на браузер)
- Текст поискового запроса
- ID товара и позиция для событий кликов
- Фасетные фильтры
- Вариант сортировки
- Локаль
- URL реферера (не более 512 символов)
- Строка User-agent (не более 256 символов)
Не хранится:
- Полный IP-адрес — только серверная сторона запроса обрабатывается; IP не записывается в
SearchUsageEvent - Email или любой идентификатор аутентифицированного пользователя
- Сырые параметры строки запроса из URL реферера, которые могут содержать персональные данные
Оговорка о частичном сохранении
Если пакет событий отправлен и некоторые не удалось сохранить, эндпоинт возвращает:
{
"accepted": 4,
"rejected": 1
}Счётчик rejected отражает сбои записи в базу данных, а не ошибки валидации. Ошибки валидации возвращают ответ 400 до каких-либо записей. Виджет не повторяет отклонённые события.
Панель аналитики
События, хранимые в SearchUsageEvent, питают процедуры аналитики:
search.usage— сырые строки событий за периодsearch.usageSummary— агрегированные счётчики по типуsearch.topQueries— наиболее частые поисковые запросыsearch.analytics— аналитические данные на уровне панели управления
Страницы панели в Панель управления → Обзор (плитки KPI, поиски во времени, топ запросов) и Панель управления → Аналитика читают из этих процедур.