Integrar o widget de voz no seu site
Guia para instalar e configurar o Tolky Voice Widget: script, namespace tolkyVoice, callbacks, segurança e compatibilidade de navegador
Visão geral
Como instalar o Tolky Voice Widget no seu site ou aplicação web. O visitante conversa por voz com o avatar; a integração segue o mesmo espírito do Minichat: poucas linhas no HTML e o canal fica disponível. O namespace público é window.tolkyVoice (distinto de window.tolky do Minichat) para permitir os dois widgets na mesma página.
Integrar o Minichat
Guia do widget de texto: estilos, script e liberação de domínios.
Conhecer o Minichat
Visão geral da interface e do banner do Minichat.
Objetivo da integração
O Tolky Voice Widget permite que qualquer site ofereça um canal de conversa por voz com um assistente inteligente da Tolky. O visitante fala e recebe uma resposta falada, natural e contextualizada.
- Conversa por voz bidirecional — o visitante fala e ouve a resposta, sem precisar digitar
- Contexto do negócio — o assistente busca informações relevantes do cliente via embeddings semânticos
- Sessão contínua — o histórico da conversa é mantido durante a sessão do visitante
- Fallback para texto — se houver falha no áudio, a resposta é exibida em texto
Com pipeline: 'backend' (padrão), o histórico e a persistência seguem o backend Tolky (pushToConversation e o fluxo de conversa na infraestrutura Tolky).
Pré-requisitos
| Requisito | Descrição |
|---|---|
| Conta Tolky | Conta ativa com pelo menos um host e slug configurado |
| Origem autorizada | O domínio do site deve estar registrado no painel Tolky |
| HTTPS | O site deve ser servido via HTTPS (obrigatório para acesso ao microfone) |
| Navegador compatível | Navegadores Chromium (Chrome, Edge, Opera, Brave) 90+ — veja Compatibilidade de navegador |
Transporte em tempo real (WebSocket)
A comunicação em tempo real entre o widget e o backend Tolky usa WebSocket, via Socket.IO no namespace /tolky-speech. Esse canal transmite atualizações mínimas de contexto dinâmico (por exemplo contextVersion, metadados e referência a snapshot); o texto completo do contexto não trafega no socket.
O visitante da página não configura URL de WebSocket no snippet: o widget negocia a ligação com a infraestrutura Tolky. Quem integra apenas o script precisa garantir que o navegador possa abrir ligações wss: para os hosts Tolky usados pelo widget (podem coincidir com voice.tolky.to ou outro host exposto pelo proxy; veja a seção Boas práticas de segurança nesta página, incluindo CSP).
Código de instalação
O objetivo é o mesmo do guia do Minichat: poucas linhas copiadas para o HTML e o canal já fica disponível no site.
Adicionando estilos
No Minichat, inclui-se um <link> para uma folha de estilos hospedada na Tolky. No widget de voz isso não é necessário para o caso básico: os estilos da interface vêm no próprio widget.js (injetados em tempo de execução). Não é obrigatório adicionar <link rel="stylesheet" …> para o funcionamento padrão.
Adicionando funcionalidades
Coloque o código antes do fechamento da tag </body>.
Recomendado (uma linha): o slug do host vai no atributo data-slug da tag que carrega o script. O widget localiza essa tag (compatível com async) e combina a configuração com window.tolkyVoice, se existir.
<script src="https://voice.tolky.to/widget.js" data-slug="SLUG_DO_AVATAR" async></script>
SLUG_DO_AVATAR: apelido do avatar / host, como emhttps://tolky.to/slug_do_avatar- Opcionalmente:
?slug=SLUG_DO_AVATARna URL dosrcse preferir query string; se existirdata-slug, ele tem prioridade sobre?slug=
Alternativa em duas linhas (mesmo espírito do Minichat: configuração inline + script externo):
<script>window.tolkyVoice=window.tolkyVoice||{config:{slug:"SLUG_DO_AVATAR"}};</script>
<script src="https://voice.tolky.to/widget.js" async></script>
Observações:
- O namespace público é
window.tolkyVoice(nãowindow.tolky), para coexistir com o Minichat na mesma página asyncevita bloquear a renderização da página- Se definir tanto
window.tolkyVoice.configquanto atributos na tag dowidget.js, os valores emwindow.tolkyVoice.configprevalecem (útil para callbacks e sobrescritas pontuais)
Atributos opcionais na tag <script src="…widget.js">
| Atributo | Valores | Descrição |
|---|---|---|
data-slug | string | Identificador do host (obrigatório via tag se não usar window.tolkyVoice.config.slug nem ?slug=) |
data-sub-slug | string | Avatar específico do host |
data-position | bottom-right, bottom-left | Posição do botão |
data-pipeline | backend, local | Mesmo significado da propriedade pipeline na tabela abaixo |
data-auto-greeting | true, false | Saudação em áudio ao abrir o painel |
Parâmetros de query no src (além de slug e subSlug): podem complementar; data-* na mesma tag tem precedência sobre a query quando ambos definem o mesmo campo.
Configurações
Propriedades de configuração
| Propriedade | Tipo | Obrigatório | Padrão | Descrição |
|---|---|---|---|---|
slug | string | Sim | — | Identificador do host no ecossistema Tolky |
subSlug | string | Não | null | Seleciona um avatar específico do host |
language | string | Não | "pt-BR" | Idioma preferencial (v1 suporta apenas pt-BR) |
position | string | Não | "bottom-right" | Posição do botão: "bottom-right" ou "bottom-left" |
pipeline | string | Não | "backend" | "backend": sessão e raciocínio Tolky via infraestrutura (produção). "local": apenas conversa e TTS neste serviço (demo/desenvolvimento sem backend-service) |
autoGreeting | boolean | Não | false | Se true, reproduz saudação em áudio ao abrir o painel do widget |
greetingText | string | Não | (texto fixo pt-BR) | Texto da saudação quando autoGreeting é true |
apiBaseUrl | string | Não | origem do script | Base URL HTTP do BFF (ex.: https://voice.tolky.to). Normalmente inferida a partir da tag <script>; só precisa definir para apontar a um deployment custom/staging |
socketBaseUrl | string | Não | heurística sobre apiBaseUrl | URL do Socket.IO (ex.: wss://api.tolky.to). Se omitida, é derivada de apiBaseUrl |
Callbacks
| Callback | Assinatura (TypeScript) | Descrição |
|---|---|---|
onReady | () => void | Widget carregado e pronto para uso |
onListening | () => void | Widget começou a capturar áudio do usuário |
onTranscript | (data) => void com data.text | Transcrição da fala do usuário disponível |
onResponse | (data) => void com data.text e data.audio | Resposta do assistente recebida |
onError | (data) => void com data.code e data.message | Erro ocorrido |
onSessionStart | (data) => void com data.sessionId | Sessão iniciada |
onSessionEnd | () => void | Sessão encerrada |
Exemplo com callbacks
<script>
window.tolkyVoice = window.tolkyVoice || {
config: {
slug: 'meu-slug',
position: 'bottom-right',
onReady: function () {
console.log('Widget de voz pronto');
},
onTranscript: function (data) {
console.log('Usuário disse:', data.text);
},
onResponse: function (data) {
console.log('Assistente respondeu:', data.text);
},
onError: function (err) {
console.error('[TolkyVoice]', err.code, err.message);
}
}
};
</script>
<script src="https://voice.tolky.to/widget.js" async></script>
Inicialização
Fluxo de carregamento
1. Página carrega o script widget.js
2. Script resolve o slug: window.tolkyVoice.config, depois atributos/query na tag do widget.js
└── Se não houver slug → widget não é renderizado
3. Widget cria uma sessão no backend
4. Widget estabelece a ligação em tempo real via WebSocket (Socket.IO /tolky-speech) quando aplicável
5. Widget busca a configuração do host (avatar, voz, contexto)
6. Botão de voz é renderizado na posição configurada
7. Callback onReady é disparado
Métodos públicos
Após a inicialização, os seguintes métodos ficam disponíveis em window.tolkyVoice:
// Abre o painel do widget
window.tolkyVoice.open();
// Fecha o painel do widget (botão permanece visível)
window.tolkyVoice.close();
// Inicia captura de voz manualmente
window.tolkyVoice.start();
// Para captura de voz
window.tolkyVoice.stop();
// Remove o widget completamente do DOM
window.tolkyVoice.destroy();
Eventos principais
Os eventos são recebidos via callbacks definidos no objeto de configuração.
Ciclo de vida de uma interação por voz
onReady
└── Usuário clica no botão
└── onListening
└── Usuário fala
└── onTranscript (texto: "Quais são os planos disponíveis?")
└── Assistente processa
└── onResponse (texto + áudio)
Ciclo de vida de uma sessão
onSessionStart (sessionId: abc-123)
└── (interações de voz)
└── onSessionEnd
Tratamento de erros
window.tolkyVoice = {
config: {
slug: 'meu-slug',
onError: function (err) {
switch (err.code) {
case 'MIC_PERMISSION_DENIED':
alert('Por favor, permita o acesso ao microfone.');
break;
case 'NETWORK_ERROR':
alert('Verifique sua conexão com a internet.');
break;
default:
console.error('[TolkyVoice]', err.code, err.message);
}
}
}
};
Boas práticas de segurança
-
Registre a origem do site no painel Tolky antes de publicar. Requisições de domínios não autorizados serão bloqueadas com erro
ORIGIN_DENIED. -
Nunca exponha tokens ou credenciais no código frontend. O widget se autentica automaticamente pela origem do domínio — nenhum token é necessário no snippet de integração.
-
Sirva o site via HTTPS. O acesso ao microfone (
getUserMedia) exige contexto seguro. Em HTTP, o navegador bloqueia o acesso ao áudio. -
Não armazene dados sensíveis em localStorage ou cookies criados pelo widget. O widget gerencia sua própria sessão internamente.
-
Content Security Policy (CSP). Se o site utiliza CSP, adicione as seguintes diretivas (incluindo
wss:para o canal WebSocket do widget):
script-src 'self' https://voice.tolky.to;
connect-src 'self' https://voice.tolky.to wss://voice.tolky.to;
media-src 'self' https://voice.tolky.to;
Se o ambiente Tolky apontar o Socket.IO para outro domínio, inclua também https:// e wss:// desse domínio em connect-src.
Mensagens de erro comuns
| Código | Mensagem | Causa provável | Solução |
|---|---|---|---|
SLUG_NOT_FOUND | Slug não encontrado | Slug inválido ou não configurado no painel | Verificar o slug no painel Tolky |
ORIGIN_DENIED | Origem não autorizada | Domínio do site não registrado | Adicionar o domínio nas origens autorizadas no painel |
MIC_PERMISSION_DENIED | Permissão de microfone negada | Usuário negou o acesso ao microfone | Orientar o visitante a permitir o microfone nas configurações do navegador |
MIC_NOT_AVAILABLE | Microfone não disponível | Dispositivo sem microfone ou hardware em uso | Verificar se o dispositivo possui microfone funcional |
NETWORK_ERROR | Erro de conexão | Falha de rede entre o navegador e o backend | Verificar a conexão do visitante |
TTS_UNAVAILABLE | Serviço de voz indisponível | Engine de síntese de voz temporariamente fora | Tentar novamente em alguns instantes |
SESSION_EXPIRED | Sessão expirada | Sessão inativa por tempo prolongado | No pipeline backend, o widget renova a sessão automaticamente e repete o pedido de raciocínio uma vez antes de propagar o erro para onError |
TEXT_TOO_LONG | Texto excede limite | Resposta do assistente acima de 5 000 caracteres | Contatar o suporte Tolky |
Compatibilidade de navegador
A primeira versão do widget de voz usa a Web Speech API nativa do Chromium para speech-to-text (STT), detectada via window.SpeechRecognition || window.webkitSpeechRecognition.
| Navegador | Motor | STT suportado |
|---|---|---|
| Google Chrome (desktop / Android) | Chromium | Sim |
| Microsoft Edge | Chromium | Sim |
| Opera | Chromium | Sim |
| Brave | Chromium | Sim |
| Safari (macOS / iOS) | WebKit | Não |
| Firefox | Gecko | Não |
iOS: todos os navegadores no iOS utilizam o motor WebKit. Chrome, Edge e Opera no iOS não suportam a Web Speech API para STT.
Quando o navegador não suporta a Web Speech API, o botão de microfone fica desabilitado e um aviso é exibido; o ciclo completo de conversa por voz não fica disponível nesse ambiente.
O STT do Chromium pode enviar áudio para infraestrutura do Google. Exige conexão com a internet e está sujeito aos termos do serviço do provedor.
Limitações da primeira versão
A versão inicial cobre o ciclo completo de conversa por voz. Os itens abaixo estão previstos para versões futuras e não fazem parte da v1:
- Idioma: apenas português brasileiro (pt-BR)
- Personalização visual: sem suporte a temas, cores ou posicionamento customizado além de
bottom-right/bottom-left - Modo offline: requer conexão com a internet
- Avatar animado: sem representação visual animada durante a conversa
- Interrupção de fala (barge-in): não é possível interromper a resposta do assistente no meio
- Ativação por voz (wake word): ativação apenas por clique no botão
- Multimodal: sem alternância entre voz e texto na mesma sessão
- Analytics embarcados: métricas de uso não são expostas no widget