O widget de Webchat exibe um balão de chat dentro do site ou sistema da sua empresa. Esta página é o guia técnico de implementação para a equipe de desenvolvimento: configuração, autenticação, personalização e validação.
|
Forma |
Onde fica e quem implementa |
O que oferece |
|---|---|---|
|
Widget (esta página) |
Balão de chat exibido dentro do site ou sistema do cliente. Implementação do cliente: inclusão do script na página e backend próprio para gerar as credenciais de sessão. |
Somente o chat. Não permite configurar formulário de entrada nem enviar variáveis para a criação do caso. |
|
WebChat com formulário |
Página servida pela cVortex, no subdomínio do tenant. Configurada e disponibilizada pela cVortex, a partir das informações fornecidas pelo cliente, por meio de solicitação ao time de CSM ou Comercial. |
Chat mais formulário de entrada. Os campos podem ser preenchidos pelo usuário ou recebidos por query params na URL. |
Se o cenário exige coletar dados antes da criação do caso, ou criar o caso já com nome, telefone e assunto preenchidos, o widget não atende. Consulte a página de Webchat com formulário de entrada.
Antes de começar
O widget só funciona sobre um canal de WebChat já configurado e ativo. Confirme os itens abaixo antes de escrever qualquer código.
No canal
O canal de WebChat é configurado no caminho Conversação > Canal > WebChat e depende de três cadastros prévios:
-
Unidade de Negócio cadastrada.
-
Conta do provedor de Webchat cadastrada.
-
Tipo de Caso cadastrado.
Horário de atendimento e mensagem fora do expediente também são definidos no canal, e não no objeto de configuração do widget.
Na sua implementação
-
O
identifierdo seu tenant, fornecido pela equipe cVortex na fase de setup, que antecede a integração. É a informação enviada ao endpoint/webchat/initpara obter a sessão. Ver o Passo 2. -
O
serverDigitalIddo canal de WebChat. Ele vem na resposta do/webchat/inite também pode ser consultado na tela de canais. Esse identificador é a referência de comunicação do canal. Se o canal for recriado, um novo identificador é gerado. -
O
tenantIdcorrespondente ao seu tenant. Ele vem na resposta do/webchat/init, no campotenantUUID. -
Um backend próprio, com um endpoint capaz de obter o
sessionId(e as demais credenciais) de forma segura. -
Se a notificação de nova mensagem em Android for necessária, a possibilidade de publicar o arquivo
cvortex-webchat-sw.jsna raiz do seu site. Ele precisa ser servido pela sua própria origem.
Por que o backend é necessário
O identifier do tenant jamais deve ser exposto diretamente no código client-side da página. A exposição dessa informação pode permitir que terceiros gerem sessões e façam requisições indevidas em nome da sua empresa.
A função getCredentials atua exclusivamente como ponto de entrada para consumir um serviço do seu próprio backend. Ela nunca deve conter o identifier, nem chamar o /webchat/init diretamente.
Como funciona a autenticação
O widget autentica exclusivamente por sessionId:
-
Nas chamadas HTTP, o
sessionIdé enviado no headerX-Session-Id. -
No WebSocket, é enviado como query param
?session_id=. -
Não há token de acesso (
access_token) nem refresh token. UmsessionIdinválido ou expirado é tratado diretamente como erro, sem renovação automática — seu backend precisa fornecer umsessionIdválido a cada inicialização.
Referência de configuração
Toda a configuração vive em um único objeto global chamado CVortex, declarado antes do carregamento do script do componente.
Objeto CVortex
|
Propriedade |
Tipo |
Obrigatório |
Descrição |
|---|---|---|---|
|
|
Função |
Sim |
Função assíncrona de autenticação. Deve retornar uma Promise com as credenciais de sessão. |
|
|
Objeto |
Não |
Definições visuais do widget. |
|
|
String |
Não |
Caminho, na origem do seu site, para o arquivo |
Se getCredentials não estiver presente, o componente lança erro e não é inicializado.
O serviceWorkerPath fica no nível raiz do objeto CVortex, ao lado de getCredentials, e não dentro de Webchat.
Retorno de getCredentials
A Promise deve ser resolvida com um objeto contendo:
|
Campo |
Tipo |
Obrigatório |
Descrição |
|---|---|---|---|
|
|
String |
Sim |
Identificador da sessão. É a credencial usada em toda a comunicação (HTTP e WebSocket). |
|
|
String |
Sim |
Identificador do tenant. |
|
|
String |
Sim |
Identificador do canal de WebChat, obtido na tela de canais. |
|
|
String |
Não |
Chave da conta do provedor. |
Se qualquer um dos três campos obrigatórios (sessionId, tenantId, serverDigitalId) estiver ausente, o widget considera as credenciais inválidas e não autentica.
Objeto Webchat
Todas as propriedades são opcionais.
|
Propriedade |
Tipo |
Descrição |
|---|---|---|
|
|
String |
Título exibido no topo do widget. Padrão: |
|
|
String |
URL pública da imagem usada como ícone do botão de abrir. |
|
|
String |
Cor de fundo do botão de abrir, em hexadecimal |
|
|
String |
Cor de fundo da barra superior. |
|
|
String |
Cor do texto da barra superior. |
|
|
String |
Cor do balão das mensagens do cliente. |
|
|
String |
Cor do balão das mensagens do agente. |
|
|
String |
URL da imagem de fundo da conversa. |
|
|
String |
Cor de destaque (accent) do tema. |
icon e iconBackgroundColor são independentes. Sem icon, o botão usa o ícone padrão do componente, e iconBackgroundColor continua sendo aplicado ao fundo. Informar as duas em conjunto é o uso recomendado, para garantir o contraste do ícone sobre o fundo.
Formatos aceitos
-
Cores do tema (
customerBalloonColor,agentBalloonColor,accentColor): hexadecimal de 3 ou 6 dígitos (#f50,#fe5000) ou notaçãorgb()/rgba()(rgba(254, 80, 0, 0.5)). Nomes de cor CSS, comored, não são aceitos. -
backgroundImage: apenas URLshttp://ouhttps://. URLsdata:ejavascript:são rejeitadas.
Valores fora desses formatos são ignorados silenciosamente e o widget aplica o padrão. Se uma cor não for aplicada, confira primeiro o formato do valor.
iconBackgroundColor, toolbarBackgroundColor e toolbarTextColor são aplicados diretamente no botão e na barra superior e não passam por essa validação.
Funcionalidades da barra de composição
Estas chaves também pertencem ao objeto Webchat e são todas opcionais.
|
Propriedade |
Tipo |
Padrão |
Descrição |
|---|---|---|---|
|
|
Boolean |
|
Gravação de áudio. Defina |
|
|
Boolean |
|
Envio de anexos. Defina |
|
|
Boolean |
|
Seletor de emoji. Defina |
|
|
Boolean |
|
Exibe o seletor de emoji também em dispositivos com toque. Por padrão ele é ocultado nesses dispositivos, porque o teclado do sistema já oferece emoji. |
As três primeiras desativam o recurso apenas quando recebem explicitamente false. enableEmojiOnMobile é o inverso: ativa apenas quando recebe explicitamente true, e depende de enableEmoji continuar habilitado.
O widget considera móvel qualquer dispositivo com tela sensível ao toque, o que inclui notebooks com touchscreen, e não apenas celulares e tablets.
Microfone: com enableAudioRecord ativo, o widget concede a permissão de microfone ao iframe do chat. Para o navegador liberar o microfone, a página que hospeda o widget precisa estar em HTTPS; se ela própria estiver dentro de outro iframe, o iframe externo também precisa delegar essa permissão.
Guia de implementação
Passo 1. Declarar o objeto de configuração
Declare o objeto em window antes de carregar o script do componente.
window.CVortex = {
getCredentials: async () => {
const response = await fetch("https://seu-backend.com.br/webchat/session", {
method: "POST"
});
const data = await response.json();
return {
sessionId: data.sessionId,
tenantId: data.tenantId,
serverDigitalId: data.serverDigitalId,
providerAccountKey: data.providerAccountKey // opcional
};
},
Webchat: {
title: "Título do Chat",
icon: "URL_DO_ICONE",
iconBackgroundColor: "COR_HEXADECIMAL"
}
};
Use window.CVortex e não var CVortex. Em aplicações que utilizam bundlers, como React ou Vue, uma declaração com var dentro de um módulo permanece no escopo do módulo e não se torna global. O widget não encontra a configuração e não é renderizado.
Passo 2. Implementar o endpoint de sessão no backend
O fluxo de autenticação segue quatro etapas:
-
O widget invoca a função
getCredentialsno navegador. -
Sua função realiza uma chamada, por exemplo via
fetch, para um endpoint server-side de sua responsabilidade. -
Seu servidor chama o endpoint de inicialização da cVortex de forma segura e privada, e obtém o
sessionId. -
Seu servidor retorna apenas as credenciais de sessão (
sessionId,tenantId,serverDigitalIde, quando aplicável,providerAccountKey) para o frontend, resolvendo a Promise.
Endpoint da cVortex
O sessionId é gerado pela cVortex. Seu backend — e somente ele — deve requisitar:
POST https://<tenant>.cvortex.com/webchat/init
O domínio é sempre cvortex.com; o subdomínio é específico do tenant do cliente.
Corpo da requisição
|
Campo |
Tipo |
Obrigatório |
Descrição |
|---|---|---|---|
|
|
String |
Sim |
Identificador fornecido pela cVortex na fase de setup do tenant. |
O identifier é definido durante o setup da cVortex, que antecede a integração. Solicite-o à equipe cVortex antes de implementar o endpoint.
curl -X POST "https://meutenant.cvortex.com/webchat/init" \
-H "Content-Type: application/json" \
-d '{"identifier":"minha-loja"}'
Resposta
{
"tenantUUID": "61a2b3c4d5e6f708192a3b4c",
"identifier": "minha-loja",
"serverDigitalId": "3f8a1c72-94b5-4e10-a6d3-7b2e5c019d84",
"appId": null,
"sessionId": "5c1d9f60-2a48-4b37-9e0c-8d6f41a2b7e5",
"providerAccountKey": "a7e4f2b1-6c93-48d5-b210-9f3c8e57d604"
}
Mapeamento para getCredentials
Os nomes dos campos não são idênticos aos esperados pelo widget. Faça a correspondência abaixo antes de resolver a Promise:
|
Campo em |
Campo em |
Observação |
|---|---|---|
|
|
|
— |
|
|
|
Renomear. |
|
|
|
— |
|
|
|
Opcional. |
|
|
— |
Eco da requisição; não é usado. |
|
|
— |
Não é usado pelo widget. |
Exemplo do endpoint no seu backend (Node.js):
app.post("/webchat/session", async (request, response) => {
const cvortexResponse = await fetch(
"https://meutenant.cvortex.com/webchat/init",
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ identifier: "minha-loja" })
}
);
const data = await cvortexResponse.json();
response.json({
sessionId: data.sessionId,
tenantId: data.tenantUUID,
serverDigitalId: data.serverDigitalId,
providerAccountKey: data.providerAccountKey
});
});
O serverDigitalId chega pronto na resposta do /webchat/init. Ainda assim, ele é o mesmo identificador exibido na tela de canais: se o canal for recriado, o identifier passa a apontar para um novo serverDigitalId.
Chame o /webchat/init a cada inicialização do widget. Um novo sessionId é gerado em cada acesso, com duração suficiente para a sessão — não é necessário armazenar nem reaproveitar o valor entre acessos.
CORS
O endpoint precisa liberar CORS para a origem da página onde o widget está instalado:
-
Access-Control-Allow-Origincom a origem da página -
Access-Control-Allow-Methodscom o método utilizado na chamada -
Access-Control-Allow-Headerscom os headers enviados pelo frontend -
Resposta ao preflight
OPTIONSquando a requisição enviaContent-Type: application/json
O /webchat/init da cVortex é chamado de servidor para servidor e não passa por CORS. Nunca chame esse endpoint diretamente do navegador.
Passo 3. Adicionar o script e o elemento customizado
<script defer src="https://components.cvortex.com/webchat/v2/cvortex-webchat.js"></script>
<cvortex-webchat></cvortex-webchat>
O script do componente utiliza o atributo defer, o que significa que ele será executado após o carregamento do documento, mas antes do evento DOMContentLoaded. A configuração precisa estar disponível antes da inicialização do script cvortex-webchat.js.
Passo 4. Habilitar a notificação de nova mensagem (opcional)
O widget avisa o visitante quando o atendente responde e a página não está em foco. São notificações locais do navegador: exigem a página aberta. Não há Web Push nem envio a partir do servidor da cVortex.
Em desktop, funciona sem nenhuma configuração adicional.
Para funcionar em Android
No Chrome para Android a notificação só pode ser exibida por um service worker, e esse arquivo precisa ser servido pela origem do seu site — não pode vir do domínio da cVortex. Por isso:
-
Copie o arquivo
cvortex-webchat-sw.js, distribuído junto do widget, para a raiz do seu site. -
Informe o caminho na configuração, no mesmo nível de
getCredentials:
window.CVortex = {
getCredentials: async () => { /* ... */ },
serviceWorkerPath: "/cvortex-webchat-sw.js",
Webchat: { title: "Suporte", icon: "https://cdn.exemplo/logo.png" }
};
Com o caminho configurado, o widget registra o worker e passa a notificar por ele em desktop e Android. Sem o caminho, ou se o arquivo não for encontrado, o widget volta sozinho para a notificação nativa do navegador, sem erro para o visitante.
O arquivo distribuído não intercepta requisições: não afeta o carregamento nem o cache do seu site.
A imagem da notificação é a mesma de Webchat.icon. Prefira um PNG quadrado — SVG não é renderizado de forma confiável como ícone de notificação no Android.
A permissão é solicitada no clique de abrir o chat, porque Safari e Firefox exigem um gesto do usuário.
Passo 5. Exemplo completo
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<title>Webchat - Host</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
</head>
<body>
<script>
window.CVortex = {
getCredentials: async () => {
const response = await fetch(
"https://seu-backend.com.br/webchat/session",
{ method: "POST" }
);
const data = await response.json();
return {
sessionId: data.sessionId,
tenantId: data.tenantId,
serverDigitalId: data.serverDigitalId,
providerAccountKey: data.providerAccountKey
};
},
serviceWorkerPath: "/cvortex-webchat-sw.js",
Webchat: {
title: "Título Personalizado",
icon: "https://media.cvortex.io/65bb9354b90287ed5a8dda92/icons/fee9875e23e34c45ea6f67c573c97b0d.jpg",
iconBackgroundColor: "#fe5000",
toolbarBackgroundColor: "#fe5000",
toolbarTextColor: "#ffffff",
customerBalloonColor: "#2e7d32",
agentBalloonColor: "#f3e5f5",
accentColor: "#fe5000",
enableAudioRecord: true,
enableAttachment: true,
enableEmoji: true,
enableEmojiOnMobile: false
}
};
</script>
<script
defer
src="https://components.cvortex.com/webchat/v2/cvortex-webchat.js"
></script>
<cvortex-webchat></cvortex-webchat>
</body>
</html>
Validar a instalação
Execute a validação em ambiente de homologação antes de publicar em produção.
Critérios de sucesso
-
O ícone do chat aparece na página, com a cor de fundo configurada em
iconBackgroundColor. -
Ao clicar no ícone, o painel do chat abre exibindo o valor de
titleno topo. -
Na aba Network do navegador, a chamada ao seu endpoint de sessão retorna
200comsessionId(e os demais campos) no corpo da resposta. -
É possível enviar uma mensagem pelo widget.
O que checar no console
Se algum critério falhar, abra o console do navegador antes de qualquer outra verificação:
-
Erros de carregamento do arquivo
cvortex-webchat.js -
Erro
getCredentials wasn't found(configuração ausente ou declarada comvar) -
Erros de CORS na chamada ao seu endpoint de sessão
-
O valor de
window.CVortex, para confirmar que a configuração está global e completa -
Avisos de registro do service worker de notificação, quando
serviceWorkerPathestiver configurado
|
Problema |
Possível causa |
Como resolver |
|---|---|---|
|
O widget não aparece na página. |
O script do componente não foi carregado, a tag customizada não foi adicionada, ou |
Confirme se o script |
|
Erro |
O objeto |
Use |
|
Erro |
O objeto |
Declare |
|
O chat aparece, mas não autentica o usuário. |
|
Verifique a resposta do endpoint e garanta os três campos obrigatórios com um |
|
Erro de canal ou atendimento indisponível. |
O |
Copie novamente o identificador na tela de canais e atualize o valor retornado por |
|
Ícone ou cor não são exibidos como esperado. |
A URL do ícone está inválida ou inacessível, ou o valor da cor está fora dos formatos aceitos (hexadecimal de 3 ou 6 dígitos, |
Use uma URL pública válida para o ícone e informe as cores nos formatos aceitos. A |
|
A notificação de nova mensagem não aparece no celular Android. |
|
Publique o arquivo na raiz do site e informe o caminho em |
|
O botão de gravar áudio aparece, mas o navegador não libera o microfone. |
A página do host não está em HTTPS, ou está dentro de outro iframe que não delega a permissão de microfone. |
Sirva a página por HTTPS e, havendo um iframe externo, delegue nele a permissão de microfone. |
|
Falhas intermitentes ao abrir o chat. |
O endpoint de sessão pode estar lento, indisponível ou bloqueado por CORS. |
Analise os logs do backend, valide a política de CORS e teste a chamada ao endpoint diretamente pelo navegador. |
Limitações
-
O widget não permite configurar formulário de entrada.
-
O widget não permite enviar variáveis para a criação do caso, como nome, telefone ou assunto. Para esse cenário, utilize a página hospedada com formulário de entrada.
-
As definições visuais disponíveis são as do objeto
Webchat(título, ícone, cores da barra, cores dos balões, imagem de fundo e cor de destaque). -
Não é suportado mais de um widget na mesma página. Não é possível atender múltiplos canais simultaneamente em uma única página.
-
O
serverDigitalIdnão é preservado quando o canal é recriado. -
A autenticação é por
sessionId, sem refresh: umsessionIdinválido ou expirado encerra a sessão. -
A notificação de nova mensagem é local do navegador e exige a página aberta. Não há Web Push: com o navegador fechado, nada é entregue.
-
No iOS Safari em aba não há notificação, nem com service worker — apenas em PWA instalado na tela de início (iOS 16.4+).
-
A notificação em Android depende de o arquivo
cvortex-webchat-sw.jsser publicado na sua própria origem; ele não pode ser servido pelo domínio da cVortex. -
Quando a mensagem recebida é apenas um anexo, o corpo da notificação é um texto fixo em português ("Enviou um anexo"), sem tradução.
-
A gravação de áudio depende de a página do host estar em HTTPS e, em cenários de iframe aninhado, de a permissão de microfone ser delegada.
Uso em WebView e mobile
O widget funciona em WebView. Ainda assim, para WebView e para aplicações mobile a cVortex recomenda a página hospedada com formulário de entrada, e não o widget.