#
Интеграция Shopping Assistant по API
Shopping Assistant - это AI-помощник для покупателей. Он ведет диалог, уточняет потребность, помогает выбрать подходящие товары из каталога и возвращает результат в структурированном формате для отображения в клиентском интерфейсе.
Этот вариант интеграции подходит, когда сайт, приложение, backend или другой клиентский канал самостоятельно реализует UI/UX чата и напрямую вызывает API Gravity:
POST https://shopping-assistant-api.gravityfield.ai/shopping/generate
Content-Type: application/json
API не возвращает готовый экран чата. В ответе приходят текстовые блоки, товарные карточки, кнопки действий и быстрые ответы. Клиентская сторона отвечает за отображение этих блоков, пользовательские сценарии вокруг чата и локальную историю сообщений в интерфейсе.
#
Что нужно реализовать на стороне клиента
- Создать чат-интерфейс: поле ввода, список сообщений, состояние загрузки, обработку ошибок и повтор запроса.
- Генерировать стабильный
threadIdна одну чат-сессию. Все запросы одного диалога должны отправляться с тем жеthreadId. - Передавать стабильный
resourceId- этоuidпользователя Gravity Field. Удобный способ получить его заранее:POST /user. - В
messagesпередавать текущее сообщение пользователя. Историю диалога повторно отправлять не нужно: контекст сохраняется на стороне Shopping Assistant поthreadIdиresourceId. - Рендерить блоки из
response.contents:messageкак текстовое сообщение ассистента;productsкак список товарных карточек;buttonкак действие, например переход в поддержку.
- Рендерить
response.ui.suggestsкак быстрые ответы. При нажатии быстрый ответ отправляется как обычное новое сообщение пользователя. - Для товарных карточек использовать
skuкак основной идентификатор товара. Открытие PDP, добавление в корзину, получение изображения и актуальной цены остаются на стороне клиентского канала или клиентского каталога.
#
Типовой поток
- Пользователь открывает чат, клиентская сторона создает
threadId. - Если у клиентской стороны еще нет
uidGravity Field, она получает или создает пользователя черезPOST /userи используетuser.uidкакresourceId. - Пользователь отправляет сообщение.
- Клиентская сторона вызывает
/shopping/generateс текущим сообщением пользователя вmessages. - API возвращает структурированный ответ и сохраняет ход диалога в memory по
threadIdиresourceId. - Клиентская сторона отображает ответ и сохраняет его в локальной истории интерфейса.
- На следующем ходе клиентская сторона снова отправляет только новое сообщение пользователя с тем же
threadIdиresourceId.
Для обычной интеграции используйте роль user.
#
Контракт запроса
type ShoppingGenerateRequest = {
threadId: string;
resourceId: string;
trafficType?: "real" | "test";
messages: Array<{
role: "user";
content: string;
}>;
runtimeContext: {
tenant_id: string;
ctx?: {
type?: string;
data?: unknown;
lng?: string | null;
location?: string | null;
};
};
};
#
Поля запроса
#
Как заполнять ctx
ctx использует ту же модель контекста, что и API V2. Основные типы: HOMEPAGE, SEARCH, PRODUCT, CATEGORY, CART, OTHER.
- Общие правила и список типов: API V2: общий контекст.
- Если нужно заранее создать пользователя вместе с контекстом:
POST /user. - Для старых V1/server-side интеграций с
context.page: Передача контекста страницы.
Если чат открыт на карточке товара, передайте SKU товара в контексте:
{
"runtimeContext": {
"tenant_id": "670ccaae56afcafaf808c146",
"ctx": {
"type": "PRODUCT",
"data": ["1066109"]
}
}
}
#
Минимальный пример
#
Запрос
curl --request POST \
--url 'https://shopping-assistant-api.gravityfield.ai/shopping/generate' \
--header 'Content-Type: application/json' \
--data '{
"threadId": "thread-8f2b1c",
"resourceId": "665f0a000000000000000001",
"trafficType": "test",
"messages": [
{
"role": "user",
"content": "Помогите выбрать корм для взрослой кошки"
}
],
"runtimeContext": {
"tenant_id": "670ccaae56afcafaf808c146"
}
}'
#
Ответ
{
"threadId": "thread-8f2b1c",
"resourceId": "665f0a000000000000000001",
"response": {
"contents": [
{
"type": "message",
"value": "Подберу корм, но сначала уточню пару деталей. Кошка стерилизована и есть ли особенности по здоровью?"
}
],
"ui": {
"suggests": [
"Стерилизована, без особенностей",
"Не стерилизована, чувствительное пищеварение",
"Пожилая кошка, нужен мягкий корм"
]
}
}
}
#
Пример ответа с товарами
{
"threadId": "thread-8f2b1c",
"resourceId": "665f0a000000000000000001",
"response": {
"contents": [
{
"type": "message",
"value": "Вот несколько подходящих вариантов. Смотрите на возраст, стерилизацию и чувствительность пищеварения."
},
{
"type": "products",
"value": [
{
"sku": "1066109",
"name": "Сухой корм для взрослых кошек",
"price": 1299,
"features": "Для взрослых кошек; повседневный рацион",
"is_stm": false,
"brand": "Demo Brand",
"url": "https://example.com/product/1066109",
"image_url": "https://example.com/product/1066109.jpg"
},
{
"sku": "1023814",
"name": "Корм для стерилизованных кошек",
"price": 1599,
"features": "Для стерилизованных кошек; контроль веса",
"is_stm": true
}
]
},
{
"type": "message",
"value": "Если кошка стерилизована, лучше начать со второго варианта. Если нет, подойдет первый."
}
],
"ui": {
"suggests": [
"Показать варианты дешевле",
"Нужен влажный корм",
"У кошки чувствительное пищеварение"
]
}
}
}
#
Контракт ответа
type ShoppingGenerateResponse = {
threadId: string;
resourceId: string;
response: {
contents: Array<
| { type: "message"; value: string }
| { type: "products"; value: Product[] }
| { type: "button"; value: string; action: string }
>;
ui?: {
suggests: string[];
};
};
};
type Product = {
sku?: string;
name: string;
price?: number | null;
features?: string;
is_stm?: boolean;
brand?: string;
url?: string;
image_url?: string;
};
Для кнопок клиентская сторона должна обработать action. Например, open_support_chat можно связать с открытием клиентского чата поддержки.
Для товарных карточек считайте sku основным идентификатором товара. Поля price, brand, url, image_url и другие данные могут использоваться для быстрого отображения карточки, но актуализация цены, изображения, наличия, открытие PDP и добавление в корзину остаются на стороне клиентского канала или клиентского каталога.
#
Ошибки и повтор запроса
Рекомендуем показывать индикатор загрузки до получения ответа, не создавать новый threadId при повторе того же пользовательского сообщения и защищаться от двойной отправки одинакового сообщения при нестабильной сети.