Visao geral
Widget de chat em modo host-controlled
Esta documentacao define o contrato recomendado para integrar o widget white-label da InfraStudio em qualquer aplicacao hospedeira. A ideia central e simples: o chat so existe quando o host permitir. Fora desse contexto, ele deve ser completamente destruido.
Montagem
O host decide quando chamar `mount(...)`.
Contexto
Tenant, usuario, recurso e rota devem refletir o momento atual.
Isolamento
Ao sair do contexto autorizado, destrua o widget imediatamente.
Base
Principios de integracao
Principio 1
O host decide quando o chat pode existir. O widget nao assume autonomia.
Principio 2
Ao sair do contexto autorizado, o host deve chamar `destroy()` imediatamente.
Principio 3
Ao trocar tenant, usuario, agente, recurso ou rota, o host deve invalidar o contexto anterior.
Principio 4
O SDK pode ser carregado uma vez, mas a montagem do chat so acontece por comando explicito.
Principio 5
O objetivo e evitar vazamento de contexto, UI e sessao entre clientes, paginas e recursos.
Referencia
API global
window.InfraChat.mount(config)
Monta o widget. Se ja existir uma instancia do mesmo projeto/agente, o SDK reaproveita a sessao, atualiza contexto/UI e pode reexibir um chat oculto.
window.InfraChat.updateContext(context)
Atualiza o contexto atual sem recarregar o script. Use quando a tela continua autorizada, mas o escopo mudou.
window.InfraChat.hide()
Oculta visualmente o widget sem destruir a instancia. Use apenas quando fizer sentido manter a mesma sessao ainda autorizada.
window.InfraChat.show({ open? })
Reexibe uma instancia previamente ocultada. Pode opcionalmente abrir o painel na volta com `open: true`.
window.InfraChat.destroy()
Desmonta completamente a instancia atual. Remove root, listeners, timers, controllers e estado em memoria.
window.InfraChat.isMounted()
Informa se existe uma instancia ativa do widget naquele momento.
window.InfraChat.getState()
Retorna um snapshot de debug com dados de montagem, loading, contexto e logs de ciclo de vida.
Observabilidade
Logs de ciclo de vida
Esses eventos ajudam a diagnosticar por que o widget montou, atualizou, ocultou, destruiu ou foi bloqueado.
Contrato
O que e obrigatorio e o que e opcional
Abaixo esta o contrato mais importante para o `mount`. Nem todo campo do contexto precisa existir sempre. O host deve mandar o que ele realmente sabe, sem inventar identificadores.
Campo
projeto'infrastudio'
Status
ObrigatorioDescricao
Slug ou identificador do projeto na InfraStudio. Sem ele o mount nao consegue resolver o contexto base.Campo
agente'agente-comercial-principal'
Status
ObrigatorioDescricao
Slug ou identificador do agente que deve atender esse canal.Campo
apiBase'https://infrastudio.pro'
Status
Obrigatorio na praticaDescricao
URL base onde o SDK vai chamar `/api/chat` e `/api/chat/config`. Se omitido, ele tenta usar o `src` do script como default.Campo
strictHostControltrue
Status
RecomendadoDescricao
Mantem o widget em modo estritamente controlado pelo host. Para este modelo, o valor esperado e `true`.Campo
context{ tenant, user, resource, route, ui }
Status
RecomendadoDescricao
Bloco de contexto de negocio e de tela. Quanto melhor o host informar esse contexto, melhor o isolamento e a personalizacao.Campo
policy{ allowed: true, allowedRoutes: ['/imoveis/*'] }
Status
RecomendadoDescricao
Regra de exibicao enviada pelo host. Serve para travar o chat a rotas ou cenarios permitidos.Campo
openfalse
Status
OpcionalDescricao
Se `true`, o widget ja monta aberto.Campo
hiddenfalse
Status
OpcionalDescricao
Se `true`, monta oculto visualmente. Em geral, prefira decidir isso no host antes de montar.Implementacao
Exemplos principais
Comece pelo minimo valido e avance para o exemplo completo quando quiser contexto, branding e regras de exibicao.
Exemplo minimo valido
Este e o menor exemplo que ainda respeita o modelo host-controlled. Ele cria o widget, mas nao traz contexto rico.
window.InfraChat.mount({
projeto: 'infrastudio',
agente: 'agente-comercial-principal',
apiBase: 'https://infrastudio.pro',
strictHostControl: true,
});Exemplo pratico recomendado
Este exemplo cobre rota autorizada, unlock, tenant, usuario, recurso, personalizacao visual e destruicao fora do contexto permitido.
<script src="https://infrastudio.pro/chat.js" data-projeto="infrastudio" data-agente="agente-comercial-principal"></script>
<script>
const isAllowedRoute = window.location.pathname.startsWith('/imoveis/');
const hasUnlockedChat = window.__unlockChat === true;
if (!isAllowedRoute || !hasUnlockedChat) {
window.InfraChat.destroy();
} else {
window.InfraChat.mount({
projeto: 'infrastudio',
agente: 'agente-comercial-principal',
apiBase: 'https://infrastudio.pro',
strictHostControl: true,
context: {
tenant: { id: 'cliente-a', nome: 'Cliente A' },
user: { id: 'lead-42', tipo: 'lead' },
resource: { id: 'imovel-99', tipo: 'imovel' },
route: { path: window.location.pathname },
ui: {
title: 'Especialista em imoveis',
theme: 'dark',
accent: '#2563eb',
transparent: true,
},
},
policy: {
allowed: true,
allowedRoutes: ['/imoveis/*'],
},
});
}
</script>Atualizando o contexto
Use isso quando a tela continua autorizada, mas o recurso ou o usuario mudou.
window.InfraChat.updateContext({
user: { id: 'lead-84', tipo: 'lead' },
resource: { id: 'imovel-123', tipo: 'imovel' },
route: { path: window.location.pathname },
});Ocultando e exibindo novamente
`hide()` some com o widget, mas preserva a sessao em memoria. Para voltar, use `show()` ou monte outra vez com o mesmo projeto e agente.
window.InfraChat.hide();
// Mais tarde, para voltar a exibir o mesmo chat
window.InfraChat.show({ open: true });Semantica
O que significa cada campo
O host pode adaptar os nomes internos do seu dominio, mas a semantica recomendada e esta: informar quem e o tenant, quem e o usuario, qual e o recurso da tela, em qual rota esta e qual politica permite a existencia do chat.
tenant
{ id: 'cliente-a', nome: 'Cliente A' }Identifica qual cliente, marca, operacao ou tenant e dono daquele contexto. Esse campo e importante quando a mesma InfraStudio atende mais de um cliente.
Use quando o mesmo host ou a mesma conta pode operar mais de um cliente.
Ajuda a evitar vazamento de sessao entre tenants.
Se o seu produto e single-tenant, voce pode omitir.
user
{ id: 'user-42', tipo: 'lead' }Representa a pessoa que esta usando ou vendo o chat naquela sessao.
`user.id` nao e obrigatorio.
Se o host nao conhece a pessoa ainda, pode omitir `user` ou mandar so dados parciais, como `{ tipo: 'lead' }`.
Nao invente IDs. Use apenas identificadores confiaveis do host.
resource
{ id: 'imovel-99', tipo: 'imovel' }Representa o objeto principal da pagina atual. Ele nao significa necessariamente imovel; significa o recurso de negocio atualmente aberto.
Num portal imobiliario, costuma ser o imovel atual.
Num e-commerce, pode ser o produto.
Numa oficina, pode ser o veiculo.
Num SaaS, pode ser um ticket, projeto, assinatura ou conta.
route
{ path: window.location.pathname }Informa em qual rota ou pagina o host esta. E a base mais comum para politica de exibicao e destruicao do widget.
O mais comum e mandar pelo menos `path`.
Se quiser, voce pode incluir metadados extras, como `name`, `section` ou `template`.
Esse campo ajuda o host a demonstrar explicitamente que o contexto de tela mudou.
ui
{ title: 'Atendimento premium', theme: 'dark', accent: '#2563eb' }Personaliza a identidade visual daquele contexto atual.
Pode variar por cliente, agente, campanha, imovel ou rota.
Use para refletir branding, titulo do atendimento e cor principal.
Nao substitui o isolamento de contexto; e apenas a camada visual.
policy
{ allowed: true, allowedRoutes: ['/imoveis/*'] }Define a permissao de existencia do chat naquele momento.
Se `allowed` for `false`, o widget deve ser bloqueado.
Se `allowedRoutes` existir e a rota nao bater, o widget deve ser bloqueado.
Quando bloqueado, o lifecycle log esperado e `blocked_by_policy` ou `blocked_by_route`.
Sobre `resource`
`resource` nao significa necessariamente "imovel". Ele significa "o recurso principal da pagina atual". Se o cliente for imobiliaria, costuma ser um imovel. Se for e-commerce, pode ser um produto. Se for oficina, pode ser um veiculo. Se for SaaS, pode ser uma assinatura, ticket ou projeto.
O mais importante e que, ao trocar esse recurso, o host atualize ou destrua o chat. Esse e um dos pontos mais sensiveis para evitar vazamento de contexto entre uma tela e outra.
Sobre `user.id`
`user.id` nao e obrigatorio. Se o host conhece a identidade da pessoa, ele deve enviar. Se ainda nao conhece, pode omitir `user` inteiro ou mandar apenas dados parciais, como `tipo`, `origem` ou `segmento`.
Nao invente IDs apenas para preencher o campo. Use somente identificadores reais e confiaveis do sistema hospedeiro.
Operacao
Quando usar `updateContext` e quando destruir
Situacao
Entrou numa pagina autorizada pela politica do hostAcao
Chamar `mount(...)` com o contexto atual.Situacao
Mudou o recurso, mas continua dentro de uma pagina ainda autorizadaAcao
Atualizar com `updateContext(...)` ou, se quiser isolamento maximo, `destroy()` seguido de `mount(...)` limpo.Situacao
Mudou de tenant, agente ou perfil de usuarioAcao
Preferir `destroy()` e `mount(...)` de novo para evitar heranca indevida.Situacao
Saiu da pagina autorizadaAcao
Chamar `destroy()` imediatamente.Situacao
Quer apenas ocultar temporariamente o mesmo chat ainda autorizadoAcao
Usar `hide()`.Situacao
O chat foi ocultado e precisa voltar sem perder a sessaoAcao
Usar `show({ open: true })` ou chamar `mount(...)` novamente com o mesmo projeto/agente.Adaptacao
Exemplos por dominio
O formato do contexto e sempre o mesmo, mas o significado de `resource` muda de acordo com o negocio do cliente.
Imobiliaria
O recurso principal costuma ser o imovel.
context: {
tenant: { id: 'imobiliaria-sol' },
user: { id: 'lead-42', tipo: 'lead' },
resource: { id: 'imovel-99', tipo: 'imovel' },
route: { path: '/imoveis/apartamento-centro' },
}E-commerce
O recurso principal costuma ser o produto em exibicao.
context: {
tenant: { id: 'loja-x' },
user: { id: 'cliente-77', tipo: 'comprador' },
resource: { id: 'sku-123', tipo: 'produto' },
route: { path: '/produtos/camiseta-premium' },
}Servico
O recurso principal pode ser um veiculo, atendimento ou ordem de servico.
context: {
tenant: { id: 'oficina-y' },
user: { id: 'cliente-19', tipo: 'condutor' },
resource: { id: 'placa-abc1d23', tipo: 'veiculo' },
route: { path: '/servicos/freio' },
}