Подключение пользовательских элементов для разработчиков
Эта страница предназначена для разработчиков, которые подключают бэкенд компании к Skava. Создание и публикация API-элемента описаны на странице Пользовательские элементы: интерфейсы API; здесь мы рассматриваем всё, что должно происходить на другом конце линии.
Идея в одном предложении: Skava не знает вашу предметную область. Она знает только один формат, карточку. Вы решаете, что в ней написано, мы проверяем только форму, размер и безопасность. Заказ материалов, например, один из вариантов; следующая компания собирает обратную связь от пользователей, а та, что после неё, хранит фото объекта в собственных записях.
Общий вид процесса
- Администратор компании создаёт API-элемент в Skava: форму, а также адрес, метод и токен вашего бэкенда.
- Кто-то в чате заполняет форму и отправляет её.
- Skava обращается к вашему бэкенду и отправляет заполненные значения в формате JSON.
- Ваш ответ превращается в карточку в чате.
- При необходимости вы позже сообщаете о новых состояниях через callback. Каждое сообщение становится отдельной карточкой, а предыдущая остаётся.
Требования к вашему бэкенду
- HTTPS. Только
https://, безhttp, без учетных данных в адресе, не более 2000 символов. - Доступность извне. Хост должен разрешаться исключительно в публичные IP-адреса. Локальный хост, частные сети, link-local и метаданные облака отклоняются, и это проверяется при каждом вызове.
- Фиксированный адрес. Skava разрешает хост один раз и привязывает соединение к этому IP. Изменение DNS во время вызова не влияет на процесс.
- Без редиректов. Перенаправление 301 на «правильный» адрес считается ошибкой. Укажите конечный адрес сразу.
- Время ответа. Таймаут настраивается для каждого элемента и ограничен максимумом в 30 секунд. Если нужно больше, отвечайте сразу и отправляйте результат позже через callback.
- Размер ответа. 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: обратный вызов для этого конкретного взаимодействия, см. ниже. Они присутствуют только тогда, когда вызов идет из чата.
Поля контекста, такие как имя, компания, проект или подчат, заполняются самим сервером на основе канала, в котором был запущен элемент. Измененный клиент не может указать там другое имя проекта.
Ответ: формат карточки
Ответьте кодом 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-ответ считается достижимым. - Кнопка Test request выполняет реальный вызов с тестовыми значениями, даже если элемент ещё в черновике, и показывает запрос, ответ и сообщения валидатора карточки.
- Предпросмотр на соседней вкладке: вставьте ваш JSON-ответ, проверьте, и вы увидите готовую карточку вместе с подсказками. Проверка выполняется на сервере тем же кодом, что и в продакшене.
- Пример сервера: полный пример поставщика работает на
api.skava.ioи использует всё описанное выше. Его исходный код находится в репозитории в папкеexample_order_server/, около 600 строк на чистой стандартной библиотеке, созданный для копирования.
Что ещё стоит знать
- Карточка является обычным сообщением в чате. Она отображается в поиске, её можно цитировать, и она остаётся в истории.
- Она отправляется системным отправителем, а не аккаунтом вашей компании. Она всё равно появляется на стороне того, кто запустил элемент, а в заголовке указано, чья система пишет.
- Кто может запускать элемент, настраивается в его свойствах: только участники компании или также внешние участники, с которыми он разделяет чат. Когда ваша компания покидает чат, разрешение автоматически отзывается.
- API-элемент с истёкшим токеном находится в неактивном состоянии: текущие приложения скрывают его в меню, а запрос, отправленный принудительно, отклоняется на стороне сервера. Администратор может сохранить для него новый токен, что также работает для опубликованных интерфейсов.
Связанные материалы
Создание и публикация: Кастомные элементы: API-интерфейсы. Заполняемые документы вместо интерфейсов: Кастомные элементы: Документы.