Skava Skava / Wiki

Conexión de elementos personalizados para desarrolladores

Esta página está dirigida a los desarrolladores que conectan el backend de una empresa con Skava. La creación y publicación de un elemento de API se explica en Elementos personalizados: interfaces de API; aquí cubrimos todo lo que debe ocurrir en el otro extremo de la línea.

La idea en una frase: Skava no conoce tu dominio. Conoce exactamente un formato, la tarjeta. Tú decides qué dice, nosotros solo verificamos forma, tamaño y seguridad. Un pedido de materiales es un ejemplo; la siguiente empresa recopila comentarios de usuarios, y la siguiente archiva una foto de la obra en sus propios registros.

El flujo de un vistazo

  1. Un administrador de la empresa crea un elemento de API en Skava: un formulario más la dirección, el método y el token de tu backend.
  2. Alguien en el chat completa el formulario y lo envía.
  3. Skava llama a tu backend y envía los valores completados como JSON.
  4. Tu respuesta se convierte en la tarjeta del chat.
  5. Opcionalmente, informas de nuevos estados más tarde a través del callback. Cada informe se convierte en otra tarjeta; la anterior se mantiene.

Requisitos para tu backend

  • HTTPS. Solo https://, sin http, sin credenciales en la dirección, máximo 2000 caracteres.
  • Alcance público. El host debe resolverse exclusivamente a IPs públicas. Se rechazan localhost, redes privadas, link-local y metadatos de la nube, y esto se verifica en cada llamada.
  • Dirección fija. Skava resuelve el host una vez y fija la conexión a esa IP. Un cambio de DNS durante la llamada no tiene efecto.
  • Sin redirecciones. Un 301 a la dirección "correcta" cuenta como un fallo. Introduce la dirección final directamente.
  • Tiempo de respuesta. El tiempo de espera es configurable por elemento y limitado a 30 segundos. Si necesitas más tiempo, responde de inmediato y reporta el resultado después a través de la callback.
  • Tamaño de la respuesta. Skava lee un máximo de 256 KiB.
  • Content-Type. El cuerpo solo se analiza con application/json.

La solicitud que llega a ti

El método es GET, POST, PUT o PATCH, según el elemento. Con POST, PUT y PATCH, los valores llegan como un cuerpo JSON; con GET, como parámetros de consulta.

La autenticación es una cabecera cuyo nombre y prefijo de valor se configuran en el elemento, normalmente Authorization con el prefijo Bearer . El token se almacena cifrado en nuestro lado. Las cabeceras host, content-length, content-type, cookie y accept-encoding no se pueden establecer.

El cuerpo es un objeto plano. Las claves las elige quien construyó el elemento; la anidación solo aparece donde añadieron una tabla o un selector de producto:

{"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": "…"}

Tres claves siempre provienen de nosotros, así que no las utilices tú mismo:

  • locale: el código de idioma del usuario. Responde en ese idioma; nosotros no traducimos tus textos.
  • callback_url y callback_token: la devolución de llamada para esta interacción, ver más abajo. Solo están presentes cuando la llamada proviene de un chat.

Los campos de contexto, como nombre, empresa, proyecto o subchat, los rellena el propio servidor, derivados del canal en el que se ejecutó el elemento. Un cliente manipulado no puede afirmar un nombre de proyecto diferente allí.

La respuesta: el formato de tarjeta

Responde con 2xx y un objeto card. Eso es exactamente lo que se convierte en la tarjeta del chat:

{"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 (obligatorio): el entero 1. Como texto ("1") se rechaza. Sin este campo, la respuesta no se considera una tarjeta y se aplica el mapeo de respuesta configurado en el elemento.
  • title: el título de la tarjeta.
  • state: solo color y tono del icono, uno de ok, pending, warn, error. Un valor desconocido vuelve a ok y recibes una pista.
  • status_text: texto libre que no interpretamos. Se muestra en la parte superior de la tarjeta y también aparece en la lista de chats y en las notificaciones push.
  • fields: una lista de label y value. Máximo 20 entradas, label 80 caracteres, value 200, title y status_text 120 cada uno. Los valores demasiado largos se recortan, no se rechazan: un pedido no debería fallar por un detalle.
  • icon: ver más abajo.

Lo que Skava hace con tus textos antes de que lleguen al chat: se eliminan los saltos de línea y los caracteres de control (un carácter de derecha a izquierda podría invertir la visualización de un importe), se reemplazan las comillas invertidas y se neutraliza cualquier cosa que empiece por [SKAVA:. Lo último evita que un valor de la tarjeta se lea como otro elemento de chat, por ejemplo una solicitud de pago.

Los enlaces en campos, el HTML y las imágenes no se pueden establecer. Un chat es un entorno de confianza, y una dirección clicable desde un backend externo sería una invitación a reconstruir una página de inicio de sesión.

Las entradas del usuario pertenecen al servidor: aparecen en la primera tarjeta y no puedes sobrescribirlas. En el chat, son el registro de lo que realmente se envió.

Iconos

Con icon, la tarjeta obtiene su propia marca en la cabecera. Dos formas:

Un nombre del conjunto incluido: 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.

O tu propio SVG como cadena. De él, Skava toma solo la geometría (path, circle, ellipse, rect, line, polyline, polygon con sus atributos numéricos) y construye su propia imagen. Los scripts, estilos, referencias externas, foreignObject y atributos de eventos se descartan; una declaración de tipo de documento o una entidad lleva al rechazo; el archivo puede tener como máximo 8 KiB y contener como máximo 16 formas. El color, el grosor del trazo y el tamaño los define Skava, por lo que un icono no puede disfrazarse de control. Trabaja con una cuadrícula de 24 por 24.

Sin icon, se mantiene la marca predeterminada.

La función de devolución: informar estados posteriores

La llamada incluye callback_url y callback_token. Úsalos para informar nuevos estados más tarde:

POST <callback_url> con Authorization: Bearer <callback_token> y Content-Type: application/json, cuerpo de máximo 32 KiB:

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

Además de la tarjeta, hay tres valores opcionales:

  • seq: su propio contador. Un informe con un valor menor o igual se descarta para que dos informes no se adelanten entre sí. Sin seq, gana el último en llegar.
  • final: cierra la interacción. El token se vuelve inválido y no aparecen más tarjetas. También está permitido en la respuesta first, para flujos sin seguimientos.
  • notify: establécelo en false para publicar la tarjeta en silencio, sin contador de no leídos y sin notificación. Ideal para pasos intermedios que no deben despertar a nadie. Sin esta opción, la tarjeta es un mensaje completamente normal.

Cada informe se convierte en su propia tarjeta en el chat, y el anterior se conserva. Así se puede leer con claridad qué estado fue reportado. De ahí se deriva una recomendación: enviar solo lo que cambió. Una tarjeta que repite el número de pedido, los artículos y el total por cuarta vez es solo ruido para quien lee.

Dos límites: enviar el mismo informe dos veces no genera una segunda tarjeta, y una interacción puede publicar como máximo 50 tarjetas. Una interacción acepta informes durante 90 días.

Respuestas a las que debes reaccionar

  • 200 con {"result": "success", "updated": true, "seq": 3, "closed": false, "hints": []}. Lee las pistas: indican qué se acortó o eliminó.
  • 401: token o id de interacción incorrectos. No reintentes.
  • 410: interacción cerrada o expirada. No reintentes.
  • 422: tarjeta no utilizable, con hints como motivo. Corrígela primero.
  • 400 JSON incorrecto, 413 demasiado grande, 429 demasiadas solicitudes (reintenta con un back-off), 500 error nuestro, reintenta más tarde.

Ejemplo 1: un pedido con historial de estado

Paso 1, la solicitud a tu backend:

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"}

Paso 2, tu respuesta inmediata:

{"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"}]}}

El chat ahora muestra una tarjeta con un icono de paquete, el estado y las entradas del usuario.

Paso 3, más adelante al seleccionar:

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

Una segunda tarjeta silenciosa sin campos: solo cambió el estado.

Paso 4, al enviar:

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}

Esta tarjeta podría despertar a alguien, por lo que no usa notify: false.

Paso 5, al entregar:

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

Con final la interacción se cierra y el token deja de funcionar.

Ejemplo 2: una acción sin seguimientos

No todos los flujos tienen historial. Un elemento con un solo campo que envía algo a tu sistema solo necesita una respuesta:

{"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 es importante aquí: de lo contrario, la interacción permanecería abierta durante 90 días con un token válido, aunque nunca vuelvas a informar nada.

Selector de productos del catálogo

Una vez que la empresa ha subido su catálogo de artículos, el elemento puede incluir el bloque selector de productos. El usuario arma un carrito a partir de él y tú lo recibes como una lista bajo la clave elegida por quien construyó el elemento:

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

Como la clave es libre, busca la primera lista que tenga esta forma en lugar de un nombre fijo. Antes de enviar, Skava comprueba que cada número exista realmente en el catálogo de esa empresa, con un máximo de 50 artículos. En la tarjeta, los artículos aparecen como una lista con imagen del producto, nombre y cantidad.

Pruebas

  • Ping en el editor de elementos envía un HEAD sin token ni datos. Responde con lo que sea; cualquier respuesta HTTP cuenta como alcanzable.
  • Solicitud de prueba dispara una llamada real con valores de ejemplo, incluso mientras el elemento sigue siendo un borrador, y muestra la solicitud, la respuesta y los mensajes del validador de la tarjeta.
  • Vista previa en la pestaña adyacente: pega tu JSON de respuesta, compruébalo y verás la tarjeta terminada junto con las pistas. Se valida en el servidor con el mismo código que en producción.
  • Servidor de ejemplo: un proveedor de ejemplo completo se ejecuta en api.skava.io y utiliza todo lo descrito anteriormente. Su código fuente está en el repositorio bajo example_order_server/, unas 600 líneas de biblioteca estándar pura, pensado para ser copiado.

Lo que más debes saber

  • La tarjeta es un mensaje de chat completamente normal. Aparece en la búsqueda, se puede citar y permanece en el historial.
  • La envía el remitente del sistema, no una cuenta de tu empresa. Aun así, aparece en el lado de quien ejecutó el elemento, y el título indica de qué sistema proviene.
  • Quién puede ejecutarlo se define en el elemento: solo miembros de la empresa, o también personas externas que comparten un chat con él. Cuando tu empresa sale del chat, el permiso termina automáticamente.
  • Un elemento de API con un token caducado está inactivo: las aplicaciones actuales lo ocultan en el menú, y una llamada enviada de todos modos se rechaza en el servidor. Un administrador guarda un token nuevo para él, lo cual también funciona en una interfaz publicada.

Relacionado

Creación y publicación: Elementos personalizados: interfaces de API. Documentos rellenables en lugar de interfaces: Elementos personalizados: documentos.