Identificar visitantes e passar contexto
Como informar usuários conectados com ReactiveChat('identify'), assinar o userHash com HMAC-SHA256 no servidor, fazer a rotação do segredo e passar ao assistente contexto estruturado da página, como produto ou carrinho.
Se seu site sabe quem está presente, informe isso ao chat. Sua equipe passa a ver um nome no painel de atendimento em vez de “Visitante 4f2a”, e recursos como dados de clientes e o portal do cliente se tornam possíveis.
O princípio: o navegador não comprova nada. Qualquer visitante pode falsificar no console o que uma página declara por identify. Um usuário só conta como confirmado com uma assinatura calculada pelo seu servidor, usando um segredo que nunca chega ao navegador.
A chamada no navegador
ReactiveChat('identify', {
userId: '4711',
email: 'kim@example.com',
name: 'Kim Berger',
userHash: '9c1f…',
exp: 1792503600
});
- userId (string, recomendado) – seu próprio ID permanente do usuário. Não um endereço de e-mail nem um número sequencial que possa mudar.
- email (string, opcional) – exibido no painel de atendimento. Só é confirmado se também tiver sido assinado (abaixo).
- name (string, opcional) – nome de exibição no painel de atendimento.
- userHash (string, obrigatório para confirmação) – 64 caracteres hexadecimais, calculados no seu servidor.
- exp (inteiro, recomendado) – prazo de validade do hash em segundos Unix, no máximo 24 horas no futuro.
Outros campos são descartados. identify pode ser chamado antes de o widget carregar; entra na fila e não antecipa o carregamento. Os valores são enviados quando a conexão é estabelecida e, se o widget já estiver conectado, imediatamente.
O segredo
Na conta, em Projeto → Verificação de identidade, você gera o segredo do projeto (permissão: editar o projeto). Ele tem 64 caracteres hexadecimais e é exibido por inteiro exatamente uma vez; depois, apenas oculto. Coloque-o no ambiente do servidor, nunca em um script no navegador, aplicativo ou repositório.
Importante para o cálculo: a chave HMAC é a própria string de 64 caracteres, exatamente como exibida, não os bytes decodificados a partir dela.
Calcular a assinatura
userHash = hex( HMAC_SHA256( secret, userId + "." + exp ) )
Hexadecimal em minúsculas, 64 caracteres. Com endereço de e-mail confirmado:
userHash = hex( HMAC_SHA256( secret, userId + "." + exp + "." + email ) )
Somente no segundo formato o endereço de e-mail conta como confirmado. Ele exige exp.
PHP:
<?php
$geheim = getenv('RC_IDENT_SECRET'); // 64 hex characters from the account
$userId = (string) $kunde->id;
$exp = time() + 3600; // at most 24 h
$userHash = hash_hmac('sha256', $userId . '.' . $exp, $geheim);
?>
<script nonce="<?= $cspNonce ?>">
ReactiveChat('identify', {
userId: <?= json_encode($userId) ?>,
userHash: <?= json_encode($userHash) ?>,
exp: <?= (int) $exp ?>
});
</script>
Node.js:
const crypto = require('crypto');
function rcIdentitaet(kunde) {
const userId = String(kunde.id);
const exp = Math.floor(Date.now() / 1000) + 3600;
const userHash = crypto.createHmac('sha256', process.env.RC_IDENT_SECRET)
.update(userId + '.' + exp)
.digest('hex');
return { userId, userHash, exp };
}
Python:
import hmac, hashlib, os, time
def rc_identitaet(kunde_id: str) -> dict:
exp = int(time.time()) + 3600
msg = f"{kunde_id}.{exp}".encode()
key = os.environ["RC_IDENT_SECRET"].encode() # the hex string as text
return {"userId": kunde_id, "exp": exp,
"userHash": hmac.new(key, msg, hashlib.sha256).hexdigest()}
Com endereço de e-mail (PHP):
$userHash = hash_hmac('sha256', $userId . '.' . $exp . '.' . $email, $geheim);
O endereço deve ser assinado exatamente como você o passa a identify.
Sem script inline (CSP rigorosa)
Se sua Content Security Policy não permitir scripts inline, disponibilize os valores como dados e chame identify de um arquivo de script próprio:
<meta name="rc-ident" content='{"userId":"4711","userHash":"9c1f…","exp":1792503600}'>
// /js/chat-ident.js
var m = document.querySelector('meta[name="rc-ident"]');
if (m) { ReactiveChat('identify', JSON.parse(m.content)); }
Em aplicações de página única, busque os três valores no servidor por fetch após o login.
O que o servidor verifica
expé um inteiro (segundos Unix), está no futuro e no máximo 24 horas à frente (mais 5 minutos de tolerância).- O hash corresponde a
userId + "." + exp(ou ao formato com e-mail). Letras maiúsculas no hash são toleradas. - A comparação é feita em tempo constante.
Confirmado e atual é um usuário com hash válido e exp. Só então ele recebe dados de clientes e acesso ao portal do cliente.
Formato antigo sem exp: userHash = HMAC_SHA256(secret, userId) ainda é aceito como confirmado, mas não como atual: basta para o histórico de conversas e a exibição no painel de atendimento, mas não para os dados de clientes. Atualize as integrações existentes para o formato com exp.
Quando a verificação falha
O chat continua funcionando, mas de forma anônima. O widget recebe o erro auth_failed com um motivo em detail.reason:
- no_hash –
userHashausente. - no_secret – nenhum segredo foi configurado para o projeto.
- bad_exp –
expnão é um inteiro válido em segundos (frequentemente: foram passados milissegundos). - expired –
expestá no passado (página aberta há muito tempo, relógio do servidor incorreto). - exp_too_far –
expestá mais de 24 horas no futuro. - bad_hash – o hash não corresponde: segredo incorreto, sequência incorreta,
userIdassinado como número em vez de string, e-mail escrito de outra forma.
Na aba de rede das ferramentas do desenvolvedor, o motivo está no quadro error da conexão WebSocket; init_ok.identity mostra verified e reason.
Não há configuração para “permitir somente visitantes confirmados”: visitantes não confirmados sempre conversam de forma anônima.
Fazer a rotação do segredo
- Gerar novo segredo: o anterior continua válido por mais 24 horas. Configure o novo nos seus servidores dentro desse prazo.
- Remover: invalida ambos imediatamente. Todos os usuários passam a ser considerados não confirmados até que um novo segredo seja configurado.
Trocar de usuário e sair
- Se você chamar
identifycom um usuário diferente (por exemplo, após trocar de conta em uma SPA), o widget separa o rascunho da mensagem do usuário anterior. - Não há um comando específico para sair. A identidade só se aplica à visualização atual da página: depois de sair, sirva páginas sem
identify. A conversa e o ID do visitante permanecem no navegador; se um dispositivo compartilhado não deve mais mostrar nada, o visitante pode excluir seus dados no widget.
Passar contexto
Além da identidade, sua página pode informar ao assistente e à equipe o que está acontecendo agora, por exemplo, qual produto está sendo exibido ou o que há no carrinho. Isso funciona por track:
ReactiveChat('track', 'warenkorb', {
page_type: 'cart',
cart_value: 129.80,
cart_items: 3,
currency: 'EUR'
});
Somente estes campos são aceitos; todo o restante é descartado:
- Página:
url,path,title,referrer,page_type,landing_path - Produto:
product_id,variant_id,category,price,currency,in_stock - Carrinho:
cart_value,cart_items - Campanha:
utm_source,utm_medium,utm_campaign,gclid,msclkid,fbclid - Sinais:
intent,intent_confidence,rage_score,scroll_pct,dwell_ms
O widget já registra endereço, título, referrer e parâmetros de campanha a cada mudança de página por conta própria. O contexto só é transmitido com consentimento (Integração de privacidade). Não insira dados pessoais nesses campos; para isso, use identify.
Aplicativos móveis
Em um aplicativo, você passa a identidade por JavaScript após a WebView carregar, nunca pelo endereço. Aqui também o hash é calculado no servidor, não no aplicativo: Aplicativos móveis.
A seguir: Endpoint de dados de clientes · SPA e mudanças de página
Última actualització: