Skava Skava / Wiki

Esta página es para desarrolladores que conectan el backend de una empresa con Skava. Cómo se crea y publica 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 conexión.

La idea en una frase: Skava no conoce tu dominio. Solo conoce un formato exacto: la tarjeta. Tú decides qué dice; nosotros solo verificamos la forma, el tamaño y la 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 en 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 rellenados como JSON.
  4. Tu respuesta se convierte en la tarjeta del chat.
  5. Opcionalmente, puedes informar 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 y un máximo de 2000 caracteres.
  • Alcance público. El host debe resolver exclusivamente a direcciones IP públicas. Se rechazan localhost, redes privadas, direcciones link-local y metadatos de la nube, y esto se comprueba en cada llamada.
  • Dirección fija. Skava resuelve el host una sola vez y fija la conexión a esa IP. Un cambio de DNS durante la llamada no tiene efecto.
  • Sin redirecciones. Una redirección 301 a la dirección "correcta" se considera un error. Introduzca la dirección final directamente.
  • Tiempo de respuesta. El tiempo de espera es configurable por elemento y tiene un límite máximo de 30 segundos. Si necesita más tiempo, responda inmediatamente e informe del resultado más tarde a través de la devolución de llamada.
  • Tamaño de la respuesta. Skava lee como máximo 256 KiB.
  • Content-Type. El cuerpo solo se analiza con application/json.

La solicitud que recibe

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, mientras que con GET llegan como parámetros de consulta.

La autenticación es un encabezado 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. No se pueden establecer los encabezados host, content-length, content-type, cookie y accept-encoding.

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 productos:

{"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 uses 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 única, 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 se rellenan por 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 él, 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 indicación.
  • status_text: texto libre que no interpretamos. Se sitúa en la parte superior de la tarjeta y es también lo que aparece en la lista de chats y en una notificación push.
  • fields: una lista de label y value. Como máximo 20 entradas, label 80 caracteres, value 200, title y status_text 120 cada uno. Los valores demasiado largos se acortan, no se rechazan: un pedido no debe fallar por un detalle.
  • icon: ver más abajo.

Lo que Skava hace con sus 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 sustituyen las comillas invertidas y se neutraliza todo lo que empiece por [SKAVA:. Esto último evita que un valor de tarjeta se interprete como otro elemento del chat, por ejemplo una solicitud de pago.

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

Los inputs del usuario pertenecen al servidor: aparecen en la primera tarjeta y no puede sobrescribirlos. En el chat constituyen el registro de lo que se envió realmente.

Iconos

Con icon la tarjeta obtiene su propio marcador en el encabezado. 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 extrae solo la geometría (path, circle, ellipse, rect, line, polyline, polygon con sus atributos numéricos) y construye su propia imagen. Se descartan scripts, estilos, referencias externas, foreignObject y atributos de eventos; un doctype o una entidad provocan el 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 se definen por Skava, por lo que un icono no puede disfrazarse de control. Trabaja con una cuadrícula de 24 por 24.

Sin icon permanece el marcador predeterminado.

El callback: informar estados posteriores

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

POST <callback_url> con Authorization: Bearer <callback_token> y Content-Type: application/json, cuerpo de como 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: tu 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 primera respuesta, para flujos sin seguimientos.
  • notify: establece en false para publicar la tarjeta en silencio, sin contador de no leídos ni notificación. Útil para pasos intermedios que no deben despertar a nadie. Sin ello, la tarjeta es un mensaje perfectamente normal.

Cada informe se convierte en su propia tarjeta en el chat, y el anterior se mantiene. Así se puede leer claramente qué estado se notificó. De ahí surge una recomendación: envíe solo lo que haya cambiado. Una tarjeta que repite por cuarta vez el número de pedido, los artículos y el total es solo ruido para el lector.

Dos límites: 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 sugerencias: indican qué se acortó o eliminó.
  • 401: token o id de interacción incorrectos. No reintente.
  • 410: interacción cerrada o caducada. No reintentar.
  • 422: tarjeta inutilizable, con hints como motivo. Corríjalo primero.
  • 400 JSON inválido, 413 demasiado grande, 429 demasiadas solicitudes (reintente con un retraso), 500 error de nuestro lado, reintente 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 tarde 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, sobre el envío:

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 tanto, no use notify: false.

Paso 5, en la entrega:

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 ya no funciona.

Ejemplo 2: una acción sin seguimientos

No todos los flujos tienen historial. Un elemento con un solo campo que entrega 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 reportar nada.

Selector de productos del catálogo

Una vez que la empresa ha cargado su catálogo de artículos, el elemento puede contener el bloque de selector de productos. El usuario crea un carrito con él y usted lo recibe 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 gratuita, 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 cualquier cosa; cualquier respuesta HTTP cuenta como accesible.
  • Solicitud de prueba realiza 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 tarjetas.
  • Vista previa en la pestaña adyacente: pegue su respuesta en formato JSON, verifíquela y verá la tarjeta finalizada junto con las sugerencias. Se comprueba en el servidor con el mismo código que en producción.
  • Ejemplo de servidor: un proveedor de ejemplo completo se ejecuta en api.skava.io y utiliza todo lo descrito anteriormente. Su código fuente se encuentra en el repositorio bajo example_order_server/, unas 600 líneas de biblioteca estándar pura, diseñadas para ser copiadas.

Lo que más debe saber

  • La tarjeta es un mensaje de chat perfectamente normal. Aparece en la búsqueda, se puede citar y se queda en el historial.
  • Se envía desde el remitente del sistema, no desde una cuenta de tu empresa. Aparece en el lado de quien ejecutó el elemento y en el título se indica qué sistema está escribiendo.
  • Quién puede ejecutarlo se define en el elemento: solo miembros de la empresa o también personas externas que compartan un chat con él. Cuando tu empresa abandona el chat, el permiso caduca automáticamente.
  • Un elemento de API con un token caducado está inactivo y ni siquiera aparece en el menú hasta que un administrador guarda uno nuevo.

Relacionado

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