Skava Skava / Wiki

Esta página é para desenvolvedores que conectam o backend de uma empresa ao Skava. Como um elemento de API é criado e lançado é abordado em Elementos Personalizados: interfaces de API; aqui cobrimos tudo o que precisa acontecer no outro extremo da linha.

A ideia em uma frase: O Skava não conhece o seu domínio. Ele conhece exatamente um formato, o cartão. Você decide o que ele diz, nós apenas verificamos forma, tamanho e segurança. Um pedido de material é um exemplo; a próxima empresa coleta feedback do usuário, a seguinte arquiva uma foto do canteiro de obras em seus próprios registros.

O fluxo em um panorama

  1. Um administrador da empresa cria um elemento de API no Skava: um formulário mais o endereço, método e token do seu backend.
  2. Alguém no chat preenche o formulário e o envia.
  3. O Skava chama o seu backend e envia os valores preenchidos como JSON.
  4. A sua resposta torna-se o card no chat.
  5. Opcionalmente, você pode relatar novos estados posteriormente através do callback. Cada relatório torna-se outro card; o anterior permanece.

Requisitos para o seu backend

  • HTTPS. Apenas https://, sem http, sem credenciais no endereço, no máximo 2000 caracteres.
  • Acessível publicamente. O host deve resolver exclusivamente para IPs públicos. Localhost, redes privadas, link-local e metadados de nuvem são rejeitados, e isso é verificado em cada chamada.
  • Endereço fixo. O Skava resolve o host uma vez e fixa a conexão naquele IP. Uma alteração de DNS durante a chamada não tem efeito.
  • Sem redirecionamentos. Um 301 para o endereço "correto" conta como falha. Insira o endereço final imediatamente.
  • Tempo de resposta. O tempo limite é configurável por elemento e limitado a 30 segundos. Se precisar de mais tempo, responda imediatamente e reporte o resultado depois através do callback.
  • Tamanho da resposta. O Skava lê no máximo 256 KiB.
  • Content-Type. O corpo é analisado apenas com application/json.

A solicitação que chega até você

O método é GET, POST, PUT ou PATCH, dependendo do elemento. Com POST, PUT e PATCH, os valores chegam como um corpo JSON; com GET, como parâmetros de consulta.

A autenticação é um único cabeçalho cujo nome e prefixo de valor são configurados no elemento, geralmente Authorization com o prefixo Bearer . O token é armazenado criptografado em nosso lado. Os cabeçalhos host, content-length, content-type, cookie e accept-encoding não podem ser definidos.

O corpo é um objeto plano. As chaves são escolhidas por quem construiu o elemento; aninhamento aparece apenas onde foi adicionada uma tabela ou um seletor de produto:

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

Três chaves sempre vêm de nós, portanto não as utilize:

  • locale: o código de idioma do usuário. Responda nesse idioma; nós não traduzimos seus textos.
  • callback_url e callback_token: o callback para esta interação, veja abaixo. Eles só estão presentes quando a chamada vem de um chat.

Campos de contexto como name, company, project ou subchat são preenchidos pelo próprio servidor, derivados do canal em que o elemento foi executado. Um cliente adulterado não pode alegar um nome de projeto diferente ali.

A resposta: o formato do cartão

Responda com 2xx e um objeto card. É exatamente isso que se torna o cartão no 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 (obrigatório): o inteiro 1. Como texto ("1") é rejeitado. Sem ele, a resposta não conta como cartão e aplica-se o mapeamento de resposta configurado no elemento.
  • title: o título do cartão.
  • state: apenas cor e tom do ícone, um de ok, pending, warn, error. Um valor desconhecido recorre a ok e você recebe uma dica.
  • status_text: texto livre que não interpretamos. Fica no topo do cartão e também é o que aparece na lista de chats e em uma notificação push.
  • fields: uma lista de label e value. No máximo 20 entradas, label 80 caracteres, value 200, title e status_text 120 cada. Valores muito longos são encurtados, não rejeitados: um pedido não deve falhar por causa de um detalhe.
  • icon: veja abaixo.

O que o Skava faz com seus textos antes de chegarem ao chat: quebras de linha e caracteres de controle são removidos (um caractere de direita para esquerda poderia inverter a exibição de um valor), crases são substituídas e tudo que começa com [SKAVA: é neutralizado. O último impede que um valor de cartão seja lido como um elemento de chat diferente, por exemplo, um pedido de pagamento.

Links em campos, HTML e imagens não podem ser definidos. Um chat é um ambiente confiável e um endereço clicável de uma origem externa seria um convite para reconstruir uma página de login.

As entradas do usuário pertencem ao servidor: aparecem no primeiro cartão e você não pode sobrescrevê-las. No chat, elas são o registro do que foi realmente enviado.

Ícones

Com icon, o cartão ganha sua própria marca no cabeçalho. Duas formas:

Um nome do conjunto incluído: 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.

Ou seu próprio SVG como uma string. A partir dele, a Skava extrai apenas a geometria (path, circle, ellipse, rect, line, polyline, polygon com seus atributos numéricos) e constrói sua própria imagem. Scripts, estilos, referências externas, foreignObject e atributos de eventos são descartados; um doctype ou entidade leva à rejeição; o arquivo pode ter no máximo 8 KiB e conter no máximo 16 formas. Cor, largura do traço e tamanho são definidos pela Skava, portanto um ícone não pode se disfarçar de controle. Trabalhe com uma grade de 24 por 24.

Sem icon, a marca padrão permanece.

O callback: relatar estados posteriores

A chamada contém callback_url e callback_token. Use-os para relatar novos estados posteriormente:

POST <callback_url> com Authorization: Bearer <callback_token> e Content-Type: application/json, corpo de no 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}

Além do cartão, existem três valores opcionais:

  • seq: seu próprio contador. Um relatório com um valor menor ou igual é descartado para que dois relatórios não se sobreponham. Sem seq, o último a chegar prevalece.
  • final: encerra a interação. O token torna-se inválido e nenhum outro cartão aparece. Também permitido na resposta first, para fluxos sem acompanhamento.
  • notify: defina como false para publicar o cartão silenciosamente, sem contagem de não lidos e sem notificação. Ideal para etapas intermediárias que não devem acordar ninguém. Sem isso, o cartão é uma mensagem perfeitamente normal.

Cada relatório se torna seu próprio cartão no chat, mantendo o anterior. Assim, fica claro qual estado foi relatado. Daí a recomendação: envie apenas o que mudou. Um cartão que repete número do pedido, itens e total pela quarta vez é apenas ruído para o leitor.

Dois limites: o mesmo relatório duas vezes não gera um segundo cartão, e uma interação pode publicar no máximo 50 cartões. Uma interação aceita relatórios por 90 dias.

Respostas às quais você deve reagir

  • 200 com {"result": "success", "updated": true, "seq": 3, "closed": false, "hints": []}. Leia as dicas: elas indicam o que foi encurtado ou descartado.
  • 401: token ou ID de interação incorretos. Não tente novamente.
  • 410: interação encerrada ou expirada. Não tente novamente.
  • 422: cartão inutilizável, com hints como motivo. Corrija primeiro.
  • 400 JSON inválido, 413 muito grande, 429 muitas solicitações (tente novamente com back-off), 500 nossa falha, tente mais tarde.

Exemplo 1: um pedido com histórico de status

Passo 1, a solicitação ao seu 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"}

Passo 2, sua resposta imediata:

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

O chat agora exibe um cartão com um ícone de pacote, o status e as entradas do usuário.

Passo 3, mais tarde durante a separação:

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

Um segundo cartão silencioso sem campos: apenas o status mudou.

Passo 4, no envio:

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}

Este cartão pode acordar alguém, portanto sem notify: false.

Passo 5, na 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}

Com final a interação é encerrada e o token não funciona mais.

Exemplo 2: uma ação sem acompanhamento

Nem todo fluxo tem histórico. Um elemento com um único campo que envia algo para o seu sistema precisa apenas de uma resposta:

{"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 é importante aqui: caso contrário, a interação permaneceria aberta por 90 dias com um token válido, mesmo que você nunca mais reporte nada.

Seletor de produtos do catálogo

Depois que a empresa carregar seu catálogo de artigos, o elemento pode conter o bloco seletor de produtos. O usuário monta um carrinho a partir dele e você o recebe como uma lista sob a chave escolhida por quem criou o elemento:

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

Como a chave é gratuita, procure a primeira lista com esse formato em vez de um nome fixo. Antes de enviar, o Skava verifica se cada número realmente existe no catálogo da empresa, no máximo 50 itens. No cartão, os itens aparecem como uma lista com imagem do produto, nome e quantidade.

Teste

  • Ping no editor de elementos envia um HEAD simples sem token e sem dados. Responda com qualquer coisa; qualquer resposta HTTP conta como acessível.
  • Solicitar teste executa uma chamada real com valores de exemplo, mesmo enquanto o elemento ainda é um rascunho, e mostra a solicitação, a resposta e as mensagens do validador de cartão.
  • Visualização na aba ao lado: cole seu JSON de resposta, verifique e você verá o cartão finalizado além das dicas. Ele é verificado no servidor com o mesmo código usado em produção.
  • Exemplo de servidor: um exemplo completo de fornecedor está em execução em api.skava.io e utiliza tudo o que foi descrito acima. O seu código-fonte encontra-se no repositório em example_order_server/, cerca de 600 linhas de biblioteca padrão pura, destinado a ser copiado.

O que mais deve saber

  • O cartão é uma mensagem de chat perfeitamente normal. Aparece na pesquisa, pode ser citado e permanece no histórico.
  • É enviado pelo remetente do sistema, não por uma conta da sua empresa. Ainda assim, aparece do lado de quem executou o elemento, e o sistema que está a escrever é indicado no título.
  • Quem pode executá-lo é definido no elemento: apenas membros da empresa ou também pessoas externas que partilham um chat com ela. Quando a sua empresa sai do chat, a permissão termina automaticamente.
  • Um elemento de API com token expirado fica inativo e nem aparece no menu até que um administrador armazene um novo.

Relacionado

Criar e publicar: Elementos personalizados: interfaces de API. Documentos preenchíveis em vez de interfaces: Elementos personalizados: documentos.