Skava Skava / Wiki

Эта страница предназначена для разработчиков, подключающих бэкенд компании к Skava. Создание и публикация элемента API описаны на странице Custom Elements: API interfaces; здесь мы рассмотрим всё, что должно произойти на другом конце линии.

Идея в одном предложении: Skava не знает вашей предметной области. Она знает только один формат — карточку. Вы решаете, что в ней написано, мы проверяем только форму, размер и безопасность. Заказ материалов — один из примеров; следующая компания собирает отзывы пользователей, а та, что после неё, сохраняет фото объекта в своих записях.

Общий обзор процесса

  1. Администратор компании создаёт в Skava элемент API: форму, а также адрес вашего бэкенда, метод и токен.
  2. Кто-то в чате заполняет форму и отправляет её.
  3. Skava обращается к вашему бэкенду и отправляет заполненные значения в формате JSON.
  4. Ваш ответ превращается в карточку в чате.
  5. Опционально вы можете позже сообщать о новых состояниях через обратный вызов. Каждое сообщение становится новой карточкой; предыдущая остаётся на месте.

Требования к вашему бэкенду

  • HTTPS. Только https://, без http, без учётных данных в адресе, максимум 2000 символов.
  • Доступно извне. Хост должен разрешаться исключительно в публичные IP-адреса. Локальный хост, частные сети, локальные адреса связи и метаданные облака отклоняются, и это проверяется при каждом вызове.
  • Фиксированный адрес. Skava разрешает хост один раз и привязывает соединение к этому IP. Изменение DNS во время вызова не оказывает эффекта.
  • Без перенаправлений. Перенаправление 301 на «правильный» адрес считается ошибкой. Введите конечный адрес сразу.
  • Время ответа. Таймаут настраивается для каждого элемента и жестко ограничен 30 секундами. Если требуется больше времени, отвечайте немедленно и сообщайте результат позже через обратный вызов.
  • Размер ответа. Skava считывает не более 256 Кбайт.
  • Content-Type. Тело запроса обрабатывается только с application/json.

Запрос, который вы получаете

Метод — GET, POST, PUT или PATCH в зависимости от элемента. При POST, PUT и PATCH значения поступают в теле JSON, при GET — в виде параметров запроса.

Аутентификация — это один заголовок, имя и префикс значения которого настраиваются в элементе, обычно Authorization с префиксом Bearer . Токен хранится у нас в зашифрованном виде. Заголовки host, content-length, content-type, cookie и accept-encoding установить нельзя.

Тело запроса — это плоский объект. Ключи выбираются разработчиком элемента; вложенность появляется только там, где добавлена таблица или выборщик товаров:

{"artikelnummer": "5100110", "menge": 20, "note": "Please deliver in the morning", "orderer": "Jonas Berger", "company": "Sanitar Berger GmbH", "project": "Spitalstrasse 11", "locale": "de", "callback_url": "https://chat.skava.io/api/v1/custom-elements/interactions/…", "callback_token": "…"}

Три ключа всегда предоставляются нами, поэтому не используйте их самостоятельно:

  • locale: код языка пользователя. Отвечайте на этом языке; мы не переводим ваши тексты.
  • callback_url и callback_token: обратный вызов для этого взаимодействия, см. ниже. Они присутствуют только при вызове из чата.

Контекстные поля, такие как name, company, project или subchat, заполняются самим сервером на основе канала, в котором был запущен элемент. Подделанный клиент не может указать там другое название проекта.

Ответ: формат карточки

Ответьте кодом 2xx и объектом card. Именно это превращается в карточку в чате:

{"card": {"v": 1, "title": "Order BST-10001", "state": "pending", "status_text": "Order received", "icon": "package", "fields": [{"label": "Order number", "value": "BST-10001"}, {"label": "Expected", "value": "14/08/2026"}]}}

  • v (обязательно): целое число 1. В виде текста ("1") оно отклоняется. Без этого параметра ответ не считается карточкой, и применяется сопоставление ответов, настроенное в элементе.
  • title: заголовок карточки.
  • state: только цвет и оттенок иконки, одно из значений ok, pending, warn, error. Неизвестное значение заменяется на ok, и вы получаете подсказку.
  • status_text: произвольный текст, который мы не интерпретируем. Он отображается в верхней части карточки, а также появляется в списке чатов и в push-уведомлении.
  • fields: список label и value. Не более 20 записей, label до 80 символов, value до 200, title и status_text по 120 символов. Слишком длинные значения укорачиваются, но не отклоняются: заказ не должен терпеть неудачу из-за детали.
  • icon: см. ниже.

Что Skava делает с вашими текстами перед отправкой в чат: удаляются переносы строк и управляющие символы (символ справа налево мог бы иначе перевернуть отображение суммы), обратные кавычки заменяются, а всё, что начинается с [SKAVA:, обезвреживается. Последнее предотвращает чтение значения карточки как другого элемента чата, например, запроса на оплату.

Ссылки в полях, HTML и изображениях установить нельзя. Чат — это доверенная среда, и кликаемый адрес из внешнего бэкенда стал бы приглашением к созданию страницы входа.

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

Иконки

С помощью icon карточка получает свой значок в заголовке. Два способа:

Название из встроенного набора: package, package-check, package-open, box, boxes, truck, forklift, warehouse, settings, cog, gauge, wrench, hammer, drill, hard-hat, ruler, paint-roller, construction, clipboard-check, receipt, file-text, camera, clock, calendar-clock, circle-check, circle-alert, triangle-alert, send, mail-check, shopping-cart, credit-card, map-pin.

Или ваш собственный SVG в виде строки. Skava извлекает из него только геометрию (path, circle, ellipse, rect, line, polyline, polygon с их числовыми атрибутами) и создаёт собственное изображение. Скрипты, стили, внешние ссылки, foreignObject и атрибуты событий отбрасываются; наличие doctype или сущности приводит к отклонению; файл не должен превышать 8 Кбайт и содержать более 16 фигур. Цвет, толщина обводки и размер задаются Skava, поэтому иконка не может маскироваться под элемент управления. Работайте с сеткой 24 на 24.

Без icon остаётся значок по умолчанию.

Обратный вызов: сообщение о последующих состояниях

Вызов содержит callback_url и callback_token. Используйте их для отправки новых состояний позже:

POST <callback_url> с заголовками Authorization: Bearer <callback_token> и Content-Type: application/json, тело запроса не более 32 КБ:

{"card": {"v": 1, "title": "Order BST-10001", "state": "pending", "status_text": "Shipped", "icon": "truck", "fields": [{"label": "Tracking number", "value": "DPD123456789"}]}, "seq": 3, "final": false}

Помимо карточки есть три необязательных значения:

  • seq: ваш собственный счетчик. Отчет с меньшим или равным значением отбрасывается, чтобы два отчета не могли обогнать друг друга. Без seq побеждает последний пришедший отчет.
  • final: завершает взаимодействие. Токен становится недействительным, и новые карточки больше не появляются. Допустимо также в первом ответе для потоков без последующих шагов.
  • notify: установите значение false, чтобы опубликовать карточку тихо, без счетчика непрочитанных и без уведомления. Подходит для промежуточных шагов, которые не должны будить пользователей. Без этого параметра карточка отображается как обычное сообщение.

Каждый отчет становится отдельной карточкой в чате, предыдущая остается на месте. Так понятно, какое состояние было сообщено. Отсюда рекомендация: отправляйте только то, что изменилось. Карточка, которая в четвертый раз повторяет номер заказа, позиции и итоговую сумму, — это просто шум для читателя.

Два ограничения: повторный отчет не создает вторую карточку, а взаимодействие может опубликовать не более 50 карточек. Взаимодействие принимает отчеты в течение 90 дней.

Ответы, на которые нужно реагировать

  • 200 с {"result": "success", "updated": true, "seq": 3, "closed": false, "hints": []}. Прочитайте подсказки: в них указано, что было сокращено или удалено.
  • 401: неверный токен или идентификатор взаимодействия. Не повторяйте попытку.
  • 410: взаимодействие закрыто или истекло. Не повторяйте попытку.
  • 422: карточка не работает, причина указана в hints. Сначала исправьте ошибку.
  • 400 некорректный JSON, 413 слишком большой размер, 429 слишком много запросов (повторите с задержкой), 500 наша ошибка, повторите позже.

Пример 1: заказ с историей статусов

Шаг 1, запрос к вашему бэкенду:

POST https://api.example.com/v1/orders
Authorization: Bearer <your token>
{"artikelnummer": "5100110", "menge": 20, "orderer": "Jonas Berger", "company": "Sanitar Berger GmbH", "locale": "de", "callback_url": "https://chat.skava.io/api/v1/custom-elements/interactions/1111…", "callback_token": "secret"}

Шаг 2, ваш немедленный ответ:

{"card": {"v": 1, "title": "Order BST-10001", "state": "pending", "status_text": "Order received", "icon": "package", "fields": [{"label": "Order number", "value": "BST-10001"}, {"label": "Expected", "value": "14/08/2026"}]}}

В чате теперь отображается карточка с иконкой посылки, статусом и введёнными пользователем данными.

Шаг 3, позже при комплектации:

POST <callback_url> to {"card": {"v": 1, "title": "Order BST-10001", "state": "pending", "status_text": "Being picked", "icon": "cog", "fields": []}, "seq": 2, "notify": false}

Тихая вторая карточка без полей: изменился только статус.

Шаг 4, при отправке:

POST <callback_url> to {"card": {"v": 1, "title": "Order BST-10001", "state": "pending", "status_text": "Shipped", "icon": "truck", "fields": [{"label": "Tracking number", "value": "DPD123456789"}, {"label": "Carrier", "value": "DPD"}]}, "seq": 3}

Эта карточка может разбудить кого-то, поэтому нет notify: false.

Шаг 5, при доставке:

POST <callback_url> to {"card": {"v": 1, "title": "Order BST-10001", "state": "ok", "status_text": "Delivered", "icon": "package-check", "fields": []}, "seq": 4, "final": true}

С final взаимодействие завершается, и токен больше не работает.

Пример 2: действие без последующих шагов

Не у каждого потока есть история. Элемент с одним полем, который передает данные вашей системе, требует только одного ответа:

{"card": {"v": 1, "title": "Filed", "state": "ok", "status_text": "Stored under project 4711", "icon": "clipboard-check", "fields": [{"label": "Case", "value": "4711"}]}, "final": true}

Здесь важно свойство final: true: иначе взаимодействие останется открытым на 90 дней с действительным токеном, даже если вы больше никогда ничего не отправите.

Выбор товара из каталога

После того как компания загрузит свой каталог товаров, элемент может содержать блок выбора товара. Пользователь формирует корзину, а вы получаете её в виде списка под ключом, выбранным создателем элемента:

{"items": [{"artikelnummer": "5100110", "menge": 20}, {"artikelnummer": "5100111", "menge": 2}], "note": "…"}

Так как ключ свободный, ищите первый список с такой структурой, а не с фиксированным именем. Перед отправкой Skava проверяет, что каждый номер действительно существует в каталоге этой компании, максимум 50 позиций. В карточке элементы отображаются списком с изображением товара, названием и количеством.

Тестирование

  • Ping в редакторе элементов отправляет чистый запрос HEAD без токена и данных. Ответьте чем угодно; любой HTTP-ответ считается достижимым.
  • Тестовый запрос выполняет реальный вызов с тестовыми значениями, даже если элемент ещё в черновике, и показывает запрос, ответ и сообщения валидатора карточки.
  • Предпросмотр на соседней вкладке: вставьте ваш JSON-ответ, проверьте, и вы увидите готовую карточку вместе с подсказками. Проверка выполняется на сервере с тем же кодом, что и в продакшене.
  • Пример сервера: полный пример поставщика работает на api.skava.io и использует всё описанное выше. Его исходный код находится в репозитории в папке example_order_server/, около 600 строк чистого стандартного библиотеки, предназначенных для копирования.

Что ещё следует знать

  • Карточка — это обычное сообщение в чате. Она отображается в поиске, её можно цитировать, и она остаётся в истории.
  • Она отправляется системным отправителем, а не от имени аккаунта вашей компании. Она всё равно появляется на стороне того, кто запустил элемент, а в заголовке указано, чья система её создала.
  • Кто может запускать элемент, настраивается в самом элементе: только члены компании или также внешние пользователи, с которыми ведётся общий чат. Когда ваша компания покидает чат, разрешение автоматически прекращает действовать.
  • Элемент API с истекшим токеном находится в неактивном состоянии и не отображается в меню, пока администратор не сохранит новый токен.

См. также

Создание и публикация: Пользовательские элементы: интерфейсы API. Заполняемые документы вместо интерфейсов: Пользовательские элементы: документы.