Conectando Elementos Personalizados para desenvolvedores
Esta página é para desenvolvedores que conectam o backend de uma empresa ao Skava. A criação e a publicação de um elemento de API são abordadas em Elementos Personalizados: interfaces de API; aqui, cobrimos tudo o que precisa acontecer na outra ponta 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 materiais é um exemplo; a próxima empresa coleta feedback de usuários, a seguinte arquiva uma foto do canteiro de obras em seus próprios registros.
O fluxo de relance
- Um administrador da empresa cria um elemento de API no Skava: um formulário, além do endereço, método e token do seu backend.
- Alguém no chat preenche o formulário e o envia.
- O Skava chama o seu backend e envia os valores preenchidos em JSON.
- A sua resposta torna-se o cartão no chat.
- Opcionalmente, você reporta novos estados mais tarde através do callback. Cada relatório torna-se outro cartão; o anterior permanece.
Requisitos para o seu backend
- HTTPS. Apenas
https://, semhttp, sem credenciais no endereço, no máximo 2000 caracteres. - Alcance público. 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 mudança 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. A Skava lê no máximo 256 KiB.
- Content-Type. O corpo é analisado apenas com
application/json.
A requisiçã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 corpo JSON, e 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 do 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; o aninhamento só aparece 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, então não as use você mesmo:
- 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 específica, veja abaixo. Eles só estão presentes quando a chamada vem de um chat.
Campos de contexto, como nome, empresa, projeto ou subchat, são preenchidos pelo próprio servidor, derivados do canal em que o elemento foi executado. Um cliente adulterado não pode reivindicar 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 o mapeamento de resposta configurado no elemento é aplicado. - title: o título do cartão.
- state: apenas cor e tom do ícone, um de
ok,pending,warn,error. Um valor desconhecido volta paraoke você recebe uma dica. - status_text: texto livre que não interpretamos. Fica no topo do cartão e também aparece na lista de chats e em uma notificação push.
- fields: uma lista de
labelevalue. No máximo 20 entradas,label80 caracteres,value200,titleestatus_text120 cada. Valores que são longos demais são encurtados, não rejeitados: um pedido não deve falhar por um detalhe. - icon: veja abaixo.
O que a Skava faz com seus textos antes que cheguem ao chat: quebras de linha e caracteres de controle são removidos (um caractere da direita para a esquerda poderia, caso contrário, inverter a exibição de um valor), crases são substituídas e qualquer coisa começando com [SKAVA: é neutralizada. A última impede que um valor do cartão seja lido como um elemento de chat diferente, por exemplo, uma solicitação 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 um backend externo seria um convite para reconstruir uma página de login.
Os entradas do usuário pertencem ao servidor: eles aparecem no primeiro cartão e você não pode sobrescrevê-los. No chat, eles são o registro do que foi efetivamente enviado.
Ícones
Com icon, o cartão recebe 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; uma doctype ou uma entidade leva à rejeição; o arquivo pode ter no máximo 8 KiB e conter no máximo 16 formas. Cor, espessura do traço e tamanho são definidos pela Skava, para que um ícone não se disfarce 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 mais tarde:
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, há três valores opcionais:
- seq: seu contador próprio. Um relatório com 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 se torna inválido e nenhum outro cartão aparece. Também permitido na primeira resposta, para fluxos sem follow-ups.
- notify: defina como
falsepara publicar o cartão silenciosamente, sem contagem de não lidos e sem notificação. 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, o anterior permanece. Assim fica legível qual estado foi reportado. Daí decorre uma 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 produz 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
200com{"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 repita a tentativa.410: interação encerrada ou expirada. Não repita a tentativa.422: cartão indisponível, comhintscomo motivo. Corrija primeiro.400JSON inválido,413muito grande,429muitas requisições (tente novamente com backoff),500falha nossa, tente mais tarde.
Exemplo 1: um pedido com histórico de status
Etapa 1, a requisição para o 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"}
Etapa 2, a 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.
Etapa 3, mais tarde durante a seleçã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 discreto, sem campos: apenas o status mudou.
Etapa 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, por isso não há notify: false.
Etapa 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 deixa de funcionar.
Exemplo 2: uma ação sem follow-ups
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 carrega 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 é livre, procure a primeira lista que tenha esse formato, em vez de um nome fixo. Antes de enviar, o Skava verifica se cada número realmente existe no catálogo daquela empresa, com no máximo 50 itens. No cartão, os itens aparecem como uma lista com imagem do produto, nome e quantidade.
Testes
- O Ping no editor de elementos envia um
HEADpuro, sem token e sem dados. Responda com qualquer coisa; qualquer resposta HTTP conta como acessível. - A Requisição de teste dispara uma chamada real com valores de exemplo, mesmo enquanto o elemento ainda é um rascunho, e exibe a requisição, a resposta e as mensagens do validador do cartão.
- Pré-visualização na aba ao lado: cole o JSON da resposta, verifique e veja o cartão finalizado com as dicas. A validação é feita no servidor com o mesmo código usado em produção.
- Servidor de exemplo: um fornecedor de exemplo completo está em execução em
api.skava.ioe utiliza tudo o que foi descrito acima. O código-fonte está no repositório emexample_order_server/, com cerca de 600 linhas de biblioteca padrão pura, feito para ser copiado.
O que mais você deve saber
- O cartão é uma mensagem de chat perfeitamente normal. Ele aparece na busca, 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 título indica qual sistema está escrevendo.
- Quem pode executá-lo é definido no elemento: apenas membros da empresa ou também pessoas externas que compartilham um chat com ele. Quando sua empresa sai do chat, a permissão termina automaticamente.
- Um elemento de API com token expirado fica inativo: os aplicativos atuais o ocultam no menu e uma chamada enviada mesmo assim é rejeitada no servidor. Um administrador salva um novo token para ele, o que também funciona em uma interface liberada.
Relacionados
Criar e liberar: Elementos personalizados: interfaces de API. Documentos preenchíveis em vez de interfaces: Elementos personalizados: documentos.