Widget para sites
O widget é o chat que os visitantes veem no seu site. Ele carrega o bot que você publicou e conduz toda a conversa no navegador. Sem modelo de linguagem, sem requisições a terceiros e com cerca de 22KB após a compressão. O chat com atendente é carregado de um arquivo separado, só quando você o ativa.
Instalação
Cole esta linha antes de </body> em cada página em que o bot deve aparecer. O painel mostra essa linha com a sua chave na página Instalação.
<script src="https://cdn.kavchat.com/v1/kavchat.js" data-key="pk_live_..." async></script>A chave pública (pk_live_...) pode ficar na página. Nunca coloque a chave secreta (sk_live_...) na página.
Atributos
| Atributo | Padrão | Descrição |
|---|---|---|
data-key | Obrigatório | Sua chave pública. |
data-api | https://api.kavchat.com | Endereço da API. |
data-locale | Idioma do navegador | Idioma da interface do widget (botões, formulário, avisos): he, en, ar, ru, es, fr, de, pt, it, tr. Se não houver tradução para o idioma, será usado o idioma do bot. O conteúdo do roteiro é sempre exibido como você o escreveu. he e ar são exibidos da direita para a esquerda. |
data-user-token | Nenhum | Token de identidade de um usuário conectado. Veja Identificação de usuários. |
data-user-name | Nenhum | Exibido na saudação ({name}) e preenchido automaticamente no formulário de contato. |
data-open | false | Com "true", o chat abre assim que é carregado. |
<script
src="https://cdn.kavchat.com/v1/kavchat.js"
data-key="pk_live_..."
data-locale="he"
data-user-token="<identity JWT>"
data-user-name="Dana"
data-open="false"
async></script>API JavaScript
O script disponibiliza window.Kavchat:
Kavchat.init({
publicKey: 'pk_live_...',
apiBase: 'https://api.kavchat.com', // optional
locale: 'he', // optional
userToken: '<identity JWT>', // optional
userName: 'Dana', // optional
open: false, // optional
onScreen(screen, targetId) {}, // optional: "screen" buttons in your scripts
onEvent(event) {}, // optional: ready, unavailable, open, close, effect, ticket
});
Kavchat.open();
Kavchat.close();
Kavchat.toggle();
Kavchat.setUser({ token: '<identity JWT>', name: 'Dana' }); // on login; setUser(null) on logout
Kavchat.offset({ bottom: 80 }); // lift the launcher, e.g. above a cookie banner; offset(null) resets
Kavchat.destroy();Não é necessário usar init quando a tag do script tem data-key. Uma nova chamada a init substitui o widget em execução.
Chamar a API antes de o script carregar
A tag do script é async, então seu código pode executar primeiro. Crie uma fila e adicione chamadas a ela. O widget executa essas chamadas na ordem quando é carregado. init sempre executa primeiro, e suas configurações têm prioridade sobre os atributos da tag.
<script>
window.Kavchat = window.Kavchat || { q: [] };
Kavchat.q.push(['init', { publicKey: 'pk_live_...', onScreen: function (s, id) { location.href = '/' + s + '/' + id; } }]);
Kavchat.q.push(['setUser', { token: '<identity JWT>', name: 'Dana' }]);
</script>
<script src="https://cdn.kavchat.com/v1/kavchat.js" async></script>Cada item da fila é [methodName, ...args]. Mesmo depois de o script carregar, Kavchat.q.push(...) continua funcionando e executa a chamada imediatamente. Assim, o mesmo código serve para os dois casos.
Espaço para o banner de cookies
Se o site tiver um elemento fixo na parte inferior da tela, como um banner de cookies, você pode posicionar o botão, a janela e os balões acima dele. Há duas formas de fazer isso: a variável CSS --kavchat-bottom ou o comando Kavchat.offset, que aceita um número em pixels ou um valor de comprimento, como 5rem. O deslocamento é somado à altura definida no painel de administração. Quando o banner for fechado, remova a variável ou chame offset(null). As duas formas funcionam também em sites com uma CSP restritiva. No celular, a janela ocupa a tela inteira e não se desloca.
/* while your cookie banner is shown */
body.cookie-banner-open { --kavchat-bottom: 80px; }// works before or after the widget script loads
window.Kavchat = window.Kavchat || { q: [] };
Kavchat.q.push(['offset', { bottom: banner.offsetHeight + 12 }]);
// after the visitor makes a choice
Kavchat.q.push(['offset', null]);Eventos
A função onEvent recebe um dos seguintes eventos:
type | Campos | Quando |
|---|---|---|
ready | version, offline | O bot foi carregado pela rede ou pela cópia salva, quando não há conexão. |
unavailable | reason? ('quota') | O bot está desativado, disponível apenas para usuários de teste ou atingiu a cota. Nada é exibido. |
open, close | A janela foi aberta ou fechada. | |
effect | effect | Um botão solicitou a abertura do formulário de contato, de um link ou de uma tela. |
ticket | id, number | Um chamado foi aberto. |
live | state, id | O estado da conversa com o atendente mudou: queued, active, closed ou ticket. |
Kavchat.init({
publicKey: 'pk_live_...',
onEvent(event) {
if (event.type === 'ready') console.log('Bot version', event.version, event.offline ? '(offline copy)' : '');
if (event.type === 'ticket') console.log('Request opened', event.number);
},
});Ações no roteiro
- Contato: abre o formulário de contato dentro do chat. A transcrição da conversa é anexada ao chamado.
- Link: abre links
https:etel:em uma nova aba (rel="noopener noreferrer"). Outros tipos de link não são abertos. - Tela: chama sua função
onScreen(screen, targetId). Sem ela, o botão não faz nada no site.
Lista de telas no editor
Declare uma única vez as telas que o aplicativo pode abrir na opção screens de Kavchat.init. O SDK envia a lista ao Kavchat automaticamente, e o editor de roteiros oferece essas telas em uma lista suspensa com seus nomes, em vez de um campo de texto livre. O editor também pede um identificador de item quando a tela precisa dele e avisa quando um botão leva a uma tela não declarada. Ninguém precisa digitar a lista de telas manualmente no painel.
Kavchat.init({
publicKey: 'pk_live_...',
screens: [
{ id: 'orders', label: 'My orders' },
{ id: 'product', label: 'Product page', needsTarget: true }, // the button also carries a product id
],
onScreen(screen, targetId) {
location.href = targetId ? `/${screen}/${targetId}` : `/${screen}`;
},
});idé o valor recebido poronScreen: letras latinas, números,_,.e-, até 40 caracteres.labelé o nome que o administrador vê, até 60 caracteres. Até 100 telas. Entradas inválidas e identificadores duplicados são descartados.needsTarget: o botão também inclui um identificador de item (por exemplo, o identificador de um produto), recebido poronScreencomotargetId.- A lista é enviada em segundo plano depois que a versão é carregada, apenas quando há alterações ou uma vez por semana. Se o envio falhar, nada é exibido, e uma nova tentativa será feita na próxima inicialização. O usuário não vê nada.
- As telas registradas aparecem no painel em Bot, Configurações, "Telas do aplicativo", com as plataformas que informaram cada tela. Uma tela removida do aplicativo pode ser excluída ali.
Identificação dos seus usuários
Para associar seu identificador de usuário às conversas e aos chamados, ou exibir o bot apenas para usuários de teste, assine um JWT no servidor e passe-o em data-user-token ou userToken. Quando o usuário entrar ou sair da conta, chame Kavchat.setUser(...). O widget envia o token no cabeçalho Authorization: Bearer <token> em cada chamada, e um usuário conectado pode abrir um chamado sem informar e-mail ou telefone. Saiba como criar o token em Identificação de usuários.
Política CSP
O widget funciona em sites com CSP rigorosa, sem 'unsafe-inline' e sem 'unsafe-eval'. Basta permitir nossas duas origens:
script-src https://cdn.kavchat.com;
connect-src https://api.kavchat.com;Os estilos são carregados como constructable stylesheets dentro do Shadow DOM, por isso não é necessário alterar style-src. Se o bot tiver uma imagem própria ou houver imagens nos roteiros, adicione a img-src o servidor de onde elas são carregadas. O widget não carrega nada de outras origens e não abre iframe.
Chat com atendente
Não é preciso configurar nada no site. Ao ativar o chat com atendentes no painel de administração, o widget carrega um arquivo adicional, kavchat-live.js, da mesma pasta e na mesma versão de kavchat.js. Sites sem chat com atendentes não baixam esse arquivo.
- A opção: ao lado de "Falar com a equipe", aparece a opção "Falar com um atendente", somente depois que o servidor confirma que há um atendente disponível. Fora do horário de atendimento, ou quando todos os atendentes estão ocupados, só o formulário de contato é exibido. Ao lado dele, aparece uma breve explicação e o horário de retorno da equipe, se for conhecido. Quando a cota mensal acaba, o formulário é exibido sem explicação.
- A solicitação: visitantes informam e-mail ou telefone, caso nenhum atendente fique disponível a tempo. Também podem adicionar o nome e uma mensagem inicial. Quando há mais de um departamento aberto, escolhem um departamento. Usuários identificados (
userToken) não precisam preencher dados de contato. Se nenhum atendente puder receber a conversa, o formulário de contato abre com os dados já preenchidos. - A espera: aparece "Aguardando um atendente", com uma contagem regressiva até o fim do tempo de espera que você definiu, e os botões "Deixar uma mensagem" e "Encerrar conversa". É possível escrever durante a espera. Quando o tempo acaba, a conversa vira um chamado automaticamente. O visitante vê o número do chamado e uma explicação de que nenhum atendente ficou disponível a tempo.
- A conversa: nome do atendente, mensagens, indicador de digitação, transferência para outro atendente e encerramento da conversa. Tudo que vem do servidor é exibido como texto simples, sem HTML e sem links. Leitores de tela anunciam novas mensagens e, quando a janela está fechada, aparece um ponto no botão flutuante.
- Tempo real: a conexão usa Server-Sent Events. Se a conexão cair, o widget tenta se reconectar em intervalos cada vez maiores e recupera tudo que não recebeu. Assim, nenhuma mensagem se perde ou aparece duas vezes. Em redes que bloqueiam essa conexão, o widget passa a fazer consultas repetidas (long-poll). Cada mensagem tem um identificador, então uma nova tentativa não gera duplicatas. Mensagens que não foram enviadas ficam sinalizadas e podem ser reenviadas com um toque.
- Recarregamento: a credencial de acesso à conversa fica salva em
localStoragepor chave pública e conversa, nunca na URL. Ela vale por até 12 horas ou até o fim da conversa. Assim, ao recarregar ou acessar outra página, toda a conversa é restaurada: a parte com o bot e, depois, a parte com o atendente. - Sem preflight: as chamadas são enviadas sem cabeçalhos especiais, e o corpo da requisição é JSON enviado como
text/plain.
Respostas de IA (Premium)
Não é preciso configurar nada no site. Ao ativar as respostas de IA no painel de administração (com sua própria chave de um provedor de IA), uma pergunta que nenhum roteiro responde é enviada ao Kavchat. Durante a espera, de até 20 segundos, o chat mostra que o bot está digitando. A resposta é exibida como texto simples com uma pequena indicação "Resposta de IA" no idioma da interface. Abaixo dela, aparecem um botão para um assunto relacionado, se houver, e o botão "Falar com a equipe".
Se não houver resposta, ou se a requisição falhar, demorar demais ou ultrapassar o limite (10 respostas por conversa a cada 15 minutos), o chat exibe a mensagem habitual "Não encontrei uma resposta". A pergunta continua aparecendo no relatório de perguntas sem resposta, e as respostas de IA ficam na conversa salva como qualquer outra mensagem.
Como o widget funciona
- Isolamento: tudo é exibido dentro de um Shadow DOM. Seu CSS não afeta o widget, e o CSS do widget não afeta a página.
- Cache: o bot publicado é salvo em
localStoragepor chave pública, junto com seu ETag. A cada carregamento, o cabeçalhoIf-None-Matché enviado e, se nada mudou, o servidor responde com 304. Quando não há conexão, o widget usa a cópia salva e exibe um aviso sobre isso. - Conversas: um identificador aleatório de conversa fica salvo em
sessionStorage, para que a mesma conversa continue ao navegar entre páginas. - Chat com atendente: uma conversa aberta fica salva em
localStoragee é restaurada na próxima página. - Dados: o andamento da conversa é enviado cerca de 2 segundos após cada ação e também quando a página fica oculta.
- Selo do Kavchat: aparece em todos os planos. No Premium, você pode ocultá-lo nas configurações do bot.
- Acessibilidade: a janela é uma caixa de diálogo com rótulo, o foco vai para ela e retorna ao sair, Esc fecha a janela, os botões são botões de verdade, novas mensagens do bot são anunciadas e as animações são reduzidas quando o visitante solicita.
Instalação via npm
Em um aplicativo de página única, você pode empacotar o widget junto com seu código em vez de carregar a tag do script:
yarn add @kavchat/widget
# or: npm install @kavchat/widgetimport { createWidget } from '@kavchat/widget';
const widget = createWidget({ publicKey: 'pk_live_...' });
await widget.ready;
widget.open();