Widget do site
O widget é o chat do seu bot direto no seu site: um botão redondo no canto da página que abre uma conversa. Para o visitante é mais um jeito de falar com você; para o bot é um canal comum, com as mesmas reações e os mesmos diálogos de operador dos mensageiros. Visão geral da multicanalidade em Canais.
Instalar é colar um trecho de código no template do site. Todo o resto se configura no painel e é aplicado sem mexer no site de novo.
Onde pegar o código
No painel abra Widget → bloco Instalação no site → campo Código para inserir. O botão Copiar coloca o trecho inteiro na área de transferência.
O código é assim, com a sua chave no lugar das reticências:
<script>
window.mybot = { key: "eu-1a2b3c4d-..." };
</script>
<script async src="https://getmybot.dev/loader.js"></script>
Se, em vez do código, aparecer o aviso de que ainda não foi emitida uma chave de instalação para este bot, o canal do widget não está conectado. Fale com o suporte: a chave é emitida ao conectar o canal.
Abaixo do código há uma indicação de qual host o widget vai chamar. Se o seu site usa CSP (Content Security Policy), libere esse host para carregar scripts e receber requisições; caso contrário o navegador bloqueia o widget em silêncio.
Onde o código entra
O trecho vai no HTML de cada página em que o widget deve aparecer. Na prática: uma única vez no template comum — o rodapé, o campo «código antes de </body>» do seu CMS ou um contêiner do gerenciador de tags.
As regras são curtas:
- O melhor lugar é logo antes do
</body>de fechamento. No<head>também funciona, mas aí o navegador gasta tempo com o widget antes do seu conteúdo. - A ordem das duas tags importa: a primeira define a chave, a segunda carrega o widget. Não inverta nem separe pela página.
- A segunda tag tem
asynce não bloqueia a renderização. Não remova esse atributo. - Um trecho por página. Duas cópias são duas tentativas de iniciar o widget.
Daí em diante o carregador descobre de qual data center o seu bot é atendido e busca lá o código do widget. Nada é exigido de você para isso.
A chave de instalação é pública
A chave da primeira tag é um identificador público do seu bot, não uma senha. Ela fica no código-fonte da página: qualquer visitante pode abrir «Exibir código-fonte» e lê-la. Todo widget de chat funciona assim, e tudo bem.
O que importa:
- Com a chave não dá para entrar no painel, ler diálogos alheios, exportar sua base de assinantes nem alterar nada do bot. Ela habilita exatamente uma coisa: iniciar uma conversa nova com este bot.
- Não trate a chave como segredo: esconder ou ofuscar não adianta nada.
- Se for preciso trocá-la (após romper com um fornecedor, por exemplo), o suporte faz isso. Depois da troca o código antigo no site para de funcionar e precisa ser atualizado.
Lista de domínios permitidos
O widget tem uma lista de domínios permitidos (origin allowlist): os endereços de site a partir dos quais ele pode funcionar. Ela é definida ao conectar o canal e pode ser alterada depois sem reemitir a chave, então o seu código no site continua o mesmo.
As entradas são origens: esquema, host e, se não for o padrão, porta.
https://example.com
https://www.example.com
https://shop.example.com
http://localhost:3000
A comparação é exata, caractere a caractere:
- Não há curingas.
https://*.example.comnão funciona: liste os subdomínios um a um. example.comewww.example.comsão entradas diferentes. Se o site responde nos dois, adicione os dois.http://ehttps://também são entradas diferentes. Normalmente bastahttps://, mas um ambiente de teste emhttp://precisa ser adicionado explicitamente.- Sem caminho:
https://example.com/shopé recusado; uma origem é só o endereço do site.
Se o seu domínio real não estiver na lista, o widget não inicia. O navegador do visitante recebe a recusa «origin not allowed» e o chat simplesmente não abre. Isso costuma aparecer depois de uma mudança de domínio, um subdomínio novo ou o lançamento de uma segunda versão de idioma em endereço próprio: cada uma exige a sua entrada.
Se a lista estiver vazia não há restrição e o widget funciona de qualquer lugar. Encare isso como «ainda não configurado», não como abertura proposital: assim que souber seus domínios, cadastre-os.
O que essa restrição protege e o que não protege
Protege: impede que outro site incorpore o seu widget. Sem isso alguém poderia copiar o trecho para a própria página e os navegadores de visitantes reais entregariam a esse site o conteúdo das conversas com o seu bot. É exatamente o que a lista fecha.
Não protege: não impede quem copiou a chave e chama a plataforma diretamente — não pelo navegador, mas por um script, por exemplo. O cabeçalho com o endereço do site é colocado pelo navegador; um programa fora do navegador pode omiti-lo ou mandar outro. Trate a lista como restrição de incorporação, não como fronteira de segurança. Contra abuso protegem os limites de frequência e a moderação de diálogos da plataforma, não essa lista.
Aparência
Em Widget → Aparência se ajustam:
- Posição: o botão no canto inferior esquerdo ou direito.
- Cor de destaque: cor do botão e dos elementos do chat. Use a cor da sua marca para o widget não parecer estranho ao site.
- Nome do chat: rótulo do botão e título do painel. Em geral o nome da empresa ou o nome com que o bot se apresenta.
Ao lado há uma pré-visualização: um widget vivo que mostra o resultado antes de salvar.
O widget ainda não tem mensagem de boas-vindas: são apenas esses três ajustes. A primeira mensagem o bot envia em resposta ao visitante, seguindo as suas reações de sempre.
As mudanças chegam ao site sozinhas: o widget lê as configurações ao carregar a página, e o código inserido nunca precisa ser editado.
Os visitantes são anônimos
O visitante não preenche nada para escrever. Na primeira execução o widget recebe da plataforma um identificador anônimo de visitante e o guarda no navegador, para que ao voltar a pessoa veja a conversa anterior e não um chat vazio.
Disso decorre que:
- Nos diálogos esse visitante aparece como anônimo: sem nome, telefone ou e-mail enquanto ele mesmo não escrever.
- O identificador vive em um navegador específico. Outro navegador, outro aparelho ou dados do site apagados significam um visitante novo com histórico limpo.
- Um visitante anônimo pode ser vinculado a um cliente que você já conhece, por exemplo um usuário autenticado da sua área logada. Como fazer isso está na seção seguinte.
Vincular um visitante ao seu próprio usuário
Se o visitante já está autenticado no seu site, você pode dizer à plataforma quem ele é. Depois do vínculo a conversa deixa de ser anônima: ela é unida ao perfil dessa pessoa, e as mensagens anônimas anteriores não se perdem.
Basta uma chamada, com uma função que produz a prova:
mybot.identify(async (visitorId) => {
const res = await fetch("/mybot-sign", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ userId: currentUser.id, visitorId }),
});
return res.json(); // { userId, signature, expiresAt }
});
O widget chama sua função com visitorId — o identificador anônimo de visitante atual para esse navegador, o único valor que só o widget conhece — e espera que ela retorne, ou resolva para, { userId, signature, expiresAt }. A única tarefa da sua função é entregar visitorId ao seu próprio servidor, junto com o identificador do usuário autenticado (currentUser.id acima é o que isso for no seu site), e repassar exatamente o que seu servidor responder. A assinatura de verdade acontece no seu servidor, não nessa função — veja abaixo.
Um callback, não um valor já pronto nem uma forma de ler visitorId diretamente, por dois motivos:
- Momento em que existe. O widget cria o
visitorIdde forma assíncrona enquanto inicializa — ele não existe no instante em que o script de carregamento roda, e o própriomybot.identifysó é instalado depois que isso termina (mais detalhes abaixo). Então, no momento em que sua página consegue chamarmybot.identify, o identificador que sua função recebe é garantidamente real. Um getter simples não teria essa garantia: nada impediria uma página de lê-lo uma linha cedo demais e não obter nada, produzindo em silêncio uma assinatura que nunca bate, sem nenhuma pista do motivo. - Escopo. O código da sua própria página nunca precisa guardar, armazenar ou passar
visitorIdmanualmente — ele existe só dentro dessa função, para a única chamada que ela precisa fazer.
A partir do momento em que sai do widget, visitorId é uma credencial ao portador (bearer capability): quem conseguir uma assinatura para ele pode ser unido à sessão desse visitante. Envie-o só para o seu próprio servidor, na sua própria requisição autenticada, e para nenhum outro lugar — não registre em log, não repasse a terceiros e não coloque numa chamada de analytics do lado do cliente.
A assinatura é calculada só no seu próprio servidor
Dentro da sua função acima, o seu próprio servidor — nunca o navegador — calcula a assinatura: um HMAC-SHA256, com o segredo do widget como chave, em hexadecimal, os primeiros 32 caracteres, de três valores unidos numa só mensagem. A mesma fórmula aparece no painel ao lado do segredo, sob «Signing algorithm»:
signature = hex(HMAC-SHA256(key: secret, message: userId + "\n" + visitorId + "\n" + expiresAt)).slice(0, 32)
Cada + "\n" + acima é uma quebra de linha de verdade entre as partes, não os dois caracteres barra invertida e n. Se a sua função HMAC recebe a mensagem como uma única string, junte as três partes com uma quebra de linha real: três chamadas .update() separadas sem quebra de linha entre elas geram o hash de uma mensagem diferente, e errada.
As três partes:
userId— o identificador do usuário autenticado, o mesmo valor que seu servidor recebe da função acima e devolve na resposta.visitorId— o identificador anônimo de visitante que sua função recebeu como argumento e repassou sem alterar ao seu servidor.expiresAt— um timestamp unix em segundos (não em milissegundos) até quando essa assinatura específica continua válida, gerado pelo seu servidor no momento de assinar. A plataforma recusa uma chamada cujoexpiresAtjá esteja no passado, e também uma que esteja mais de 24 horas no futuro — assine bem antes de devolver o valor da sua função, não uma vez para reaproveitar em requisições futuras.
Essa expiração é o motivo real da mudança, não um detalhe secundário. A fórmula anterior cobria só o identificador do usuário, então uma assinatura capturada uma vez — registrada em algum log, interceptada no tráfego, tanto faz — continuava válida para sempre e servia para qualquer visitante, não só aquele para quem foi emitida. Quem conseguisse uma poderia reproduzi-la num navegador completamente diferente, e a plataforma acabaria unindo a navegação anônima de um estranho ao perfil de um cliente de verdade. Amarrar a assinatura a um visitorId específico e dar a ela uma vida curta fecha as duas pontas dessa brecha: ela só é válida para a sessão para a qual foi emitida, em nenhuma outra, e para de valer assim que expiresAt passa — então até uma assinatura vazada continua sendo um risco breve, de uma única sessão, não permanente.
Calcule os três valores no seu servidor e devolva-os da sua função já prontos. Isso não é formalidade: para calcular a assinatura no navegador seria preciso enviar o segredo até lá, ou seja, entregá-lo a cada visitante da página. A partir daí qualquer um poderia se passar por qualquer cliente seu e ler a conversa dele. A assinatura (e o visitorId/expiresAt para os quais foi calculada) é segura para devolver ao navegador; o segredo, não.
A chamada em si não mostra nada na tela: o vínculo acontece no servidor e em silêncio. Se a sua função lançar um erro ou sua promise for rejeitada, ou se a plataforma recusar a assinatura resultante — não bate, ou expiresAt está ausente, já passou ou está a mais de 24 horas no futuro —, nada mais acontece: o visitante não percebe nada e segue escrevendo como anônimo.
mybot.identify não existe de imediato: ele aparece depois que o pacote principal do widget carrega, junto com um visitorId real (veja «Momento em que existe» acima). Chame-o de um handler de carregamento da página, não como primeira linha do <head>.
Onde fica o segredo e como trocá-lo
O segredo do widget é a chave com que você assina. Ele fica nas configurações do widget, na seção «identify() secret». Se essa seção disser que o widget ainda não está conectado, conecte primeiro o canal web: o segredo aparece junto com ele.
Exibir. O botão «Reveal secret» busca o valor. Ele não aparece em texto claro: primeiro você vê pontos, e um alternador à parte, «Show», mostra os caracteres («Mask» volta a escondê-los). Ao lado há «Clear from screen», que tira o valor da tela.
Você pode exibi-lo quantas vezes quiser, e exibir não invalida nada: o segredo continua válido depois de fechar a tela. É assim porque ele é guardado criptografado e não em hash — a plataforma precisa do valor real para verificar cada assinatura. Se daqui a meio ano você subir um backend novo, é só voltar e consultá-lo de novo.
Depois de copiar, recolha você mesmo. A plataforma não consegue limpar sua área de transferência: do navegador isso não é confiável, então não prometemos. Tire o valor da tela e limpe a área de transferência à mão quando terminar, sobretudo num computador compartilhado.
Trocar. O botão «Rotate secret», com etapa de confirmação. É uma ação que quebra na hora: assim que o segredo novo existe, o antigo deixa de verificar. Não há janela de sobreposição, nem um instante em que as duas chaves valham.
O que quebra é exatamente o vínculo de visitantes com os seus usuários. As conversas não são interrompidas: os visitantes seguem escrevendo e recebendo resposta, só que como anônimos, até o seu backend assinar com o segredo novo. O código de instalação e a lista de domínios permitidos não são afetados; no seu site não há nada a mudar.
Portanto troque o segredo com consciência: prepare primeiro o deploy do backend com o valor novo e só então clique em «Rotate secret». Clicar para ver o que acontece é má ideia. O valor novo aparece na tela logo após a troca, então dá para copiá-lo na hora.
Como o widget se comporta na página
O widget foi feito de propósito para não atrapalhar o seu site:
- Ele vive em um contêiner isolado (Shadow DOM fechado). Seus estilos não entram nele e os dele não vazam para a página. Efeito colateral: você não consegue reestilizá-lo com o seu CSS — use os ajustes de aparência.
- O contêiner cobre a tela, mas não intercepta cliques: eles atravessam para a página, e só o botão e o painel do chat respondem.
- O widget fica sempre acima do seu conteúdo; suas camadas não conseguem cobri-lo.
- Qualquer erro dentro do widget fica dentro: na pior hipótese o botão do chat não funciona, e o site continua rodando. Se o widget não aparecer, olhe o console do navegador — quase sempre é a CSP ou um domínio faltando na lista.
Se o widget não aparecer
Percorra na ordem:
- Abra o código-fonte e confirme que as duas tags estão lá e que a chave não está vazia.
- Confirme que o endereço do site é exatamente o da lista, incluindo
https://ewww. - Veja o console do navegador: uma mensagem de Content Security Policy significa liberar o host da plataforma na CSP do site.
- Verifique se um bloqueador de anúncios não está removendo o widget: teste em janela anônima sem extensões.
O que vem depois
- Canais — multicanalidade e recursos dos canais.
- Reações: conceitos básicos — o que o bot vai responder a um visitante.
- Chats e operadores — como um operador responde na conversa.