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

Сохраните оценку конкретного сообщения ассистента. GET подходит для готовых ссылок из ответа генерации; PUT также позволяет снять реакцию. Оценки покупателей отображаются отдельно от отзывов команды в личном кабинете.

GET /shopping/feedback

После сохранения ответа генерация добавляет в корневой events[] ссылки двух типов:

{
  "events": [
    {
      "type": "like",
      "url": "https://shopping-assistant-api.gravityfield.ai/shopping/feedback?tenant_id=demo-section&resourceId=demo-user&threadId=demo-thread&messageId=demo-answer&reaction=like"
    },
    {
      "type": "dislike",
      "url": "https://shopping-assistant-api.gravityfield.ai/shopping/feedback?tenant_id=demo-section&resourceId=demo-user&threadId=demo-thread&messageId=demo-answer&reaction=dislike"
    }
  ]
}

Идентификаторы в примере условные. Используйте готовый url из фактического ответа: тело запроса и дополнительный токен не требуются.

  1. Найдите событие нужного типа рядом с сохранённым ответом.
  2. Вызовите его URL методом GET только при нажатии соответствующей кнопки.
  3. После 200 обновите состояние оценки; при ошибке сохраните предыдущее состояние.
async function rateAnswer(result, reaction) {
  const event = result.events?.find(item => item.type === reaction);
  if (!event?.url) throw new Error('Для ответа нет ссылки оценки');
  const response = await fetch(event.url, { method: 'GET', cache: 'no-store' });
  if (!response.ok) throw new Error('Не удалось сохранить оценку');
  return response.json();
}
// В обработчике кнопки «Нравится»: rateAnswer(result, 'like').

Не вызывайте все URL из events[] при получении ответа: like и dislike меняют состояние одного сообщения. Повторная реакция не создаёт дубликат, противоположная заменяет предыдущую.

Обязательные query-параметры: непустые tenant_id, resourceId, threadId, messageId и reaction: like | dislike. GET не принимает null; для снятия оценки используйте PUT. Все готовые ссылки ведут на production-домен, включая ссылки из другого окружения. Ответ должен существовать в принимающем сервисе.

HTTP Результат
200 { "reaction": "like", "updatedAt": "2026-10-13T10:00:00.000Z" }
400 Invalid request query: проверьте параметры.
404 Assistant message not found: нет сохранённого ответа с указанной связкой.
500 Failed to save feedback: предложите повторить позже.

GET не ограничивается списком разрешённых IP секции. Сервер проверяет принадлежность сообщения указанным секции, пользователю и диалогу; ссылка не подтверждает личность отправителя. Ответы используют Cache-Control: no-store.

Debug-ответы не сохраняются и не получают feedback-ссылки. History API не добавляет эти ссылки: для восстановленного ответа используйте PUT и id сообщения. Готовый Web-виджет 1.41 также использует PUT.

PUT /shopping/feedback

Чтобы собрать оценку конкретного ответа Shopping Assistant, вызовите:

PUT https://shopping-assistant-api.gravityfield.ai/shopping/feedback
Content-Type: application/json

Endpoint сохраняет текущую реакцию пользователя на сообщение ассистента. Повторная отправка того же состояния идемпотентна: она не создает дубликат оценки.

Запрос

curl --request PUT \
  --url 'https://shopping-assistant-api.gravityfield.ai/shopping/feedback' \
  --header 'Content-Type: application/json' \
  --data '{
    "tenant_id": "demo-section",
    "resourceId": "demo-user",
    "threadId": "thread-8f2b1c",
    "messageId": "shopping:assistant:8a21...",
    "reaction": "like"
  }'
Поле Обязательное Назначение
tenant_id Да ID секции Gravity Field. Должен совпадать с runtimeContext.tenant_id запроса /shopping/generate.
resourceId Да uid пользователя Gravity Field, которому принадлежит диалог.
threadId Да ID диалога, в котором был получен ответ.
messageId Да Значение assistantMessageId из ответа /shopping/generate или id сообщения ассистента из /shopping/history.
reaction Да like для положительной оценки, dislike для отрицательной или null, чтобы удалить ранее сохраненную оценку.

API принимает оценку только при точном совпадении tenant_id, resourceId, threadId и messageId. Это не позволяет записать реакцию на сообщение из другого диалога или профиля пользователя.

Ответ

{
  "reaction": "like",
  "updatedAt": "2026-08-07T10:00:00.000Z"
}

В reaction возвращается сохраненное состояние. Поле updatedAt содержит время его последнего изменения.

Чтобы заменить оценку, отправьте тот же запрос с другим значением reaction. Чтобы пользователь мог снять выбранную оценку, отправьте reaction: null.

Ошибки отправки оценки

HTTP-статус Причина Что делать клиенту
400 Некорректный JSON, отсутствует обязательное поле, передано пустое значение идентификатора или неподдерживаемая реакция. Проверить payload перед повторной отправкой.
403 IP не разрешён для секции. Проверить условия доступа с командой Gravity Field.
404 Сообщение ассистента не найдено или связка идентификаторов не совпадает. Не сохранять оценку локально как отправленную; проверить идентификаторы сообщения и диалога.
500 Оценку не удалось сохранить. Вернуть элемент управления в предыдущее состояние и предложить повторить запрос.

Проверьте положительную, отрицательную и повторную оценку, смену реакции и снятие через PUT. Диагностика: Оценка не сохраняется.