Identificação de Usuários
Esta funcionalidade é exclusiva para os planos Padrão, Pro e Enterprise, não estando disponível para o plano Gratuito.
A Identificação de Usuários permite que o chatbot reconheça com segurança o visitante que está interagindo no seu site. A partir de um token assinado pelo seu backend, o WiseMind passa a saber quem é o usuário, personaliza as respostas e disponibiliza os dados verificados para uso em Ações de Chat.
Sem identificação, o chatbot trata todo visitante como anônimo. Com identificação ativa, você pode:
- Cumprimentar o usuário pelo nome
- Usar dados verificados (
{{identity.email}},{{identity.account_id}}, etc.) na ação Chamada de API - Enviar informações públicas ao LLM como contexto adicional
Como funciona
A identificação utiliza um JWT assinado pelo seu backend com uma chave secreta gerada no painel do WiseMind. O token é entregue ao widget no navegador e validado pela API a cada mensagem trocada.
Fluxo resumido
- Geração da chave secreta — você gera uma chave única para o widget no painel.
- Assinatura do token — seu backend assina um JWT com essa chave para cada sessão autenticada.
- Entrega ao widget — o frontend chama
window.wisemind('identify', { token, ...traits }). - Verificação no servidor — a API valida a assinatura, extrai os claims e os utiliza com segurança.
Gerando a chave secreta
Acesse a tela de configuração do chatbot e localize a seção Identificação de Usuários.
- Clique em Gerar chave secreta para criar uma chave aleatória de 32 bytes (formato hexadecimal).
- A chave é exibida em formato mascarado, com botão para copiar.
- Use o botão Rotacionar chave para invalidar a chave atual e gerar uma nova.
A chave secreta nunca deve ser exposta no frontend. Mantenha-a apenas em variáveis de ambiente do seu backend. Tokens emitidos com uma chave rotacionada deixam de ser aceitos imediatamente.
Assinando o token JWT
O token deve ser HS256, assinado com a chave secreta gerada no passo anterior. Os claims a seguir são interpretados pela API:
| Claim | Obrigatório | Descrição |
|---|---|---|
sub | Sim | Identificador único e estável do usuário (userId). |
aud | Recomendado | Deve ser "widget". |
exp | Sim | Expiração do token (Unix timestamp). Recomendado: 1 hora. |
iat | Recomendado | Data de emissão. |
| Demais claims | Não | Quaisquer claims extras (ex.: email, name, account_id, role). |
Os claims customizados ficam disponíveis em Ações de Chat como {{identity.<nome_do_claim>}} após verificação da assinatura.
Exemplos de assinatura
- Node.js
- Python
- PHP
import jwt from "jsonwebtoken";
const token = jwt.sign(
{
email: user.email,
name: user.name,
account_id: user.accountId,
role: user.role,
},
process.env.WISEMIND_IDENTIFY_SECRET,
{
algorithm: "HS256",
subject: String(user.id),
audience: "widget",
expiresIn: "1h",
},
);
import jwt
import time
import os
token = jwt.encode(
{
"sub": str(user.id),
"aud": "widget",
"iat": int(time.time()),
"exp": int(time.time()) + 3600,
"email": user.email,
"name": user.name,
"account_id": user.account_id,
"role": user.role,
},
os.environ["WISEMIND_IDENTIFY_SECRET"],
algorithm="HS256",
)
use Firebase\JWT\JWT;
$token = JWT::encode(
[
'sub' => (string) $user->id,
'aud' => 'widget',
'iat' => time(),
'exp' => time() + 3600,
'email' => $user->email,
'name' => $user->name,
'account_id' => $user->account_id,
'role' => $user->role,
],
getenv('WISEMIND_IDENTIFY_SECRET'),
'HS256'
);
Recomendado: TTL de 1 hora. O frontend deve buscar um novo token antes da expiração para manter a sessão de identificação ativa.
Identificando o usuário no frontend
Chame o comando identify assim que tiver o token assinado pelo seu backend.
Os exemplos abaixo usam /api/wisemind-token apenas como placeholder. Trata-se de uma rota no seu próprio backend que assina o JWT com a chave secreta (ver seção anterior). O WiseMind não expõe nenhum endpoint para gerar tokens — a chave secreta nunca deve sair do seu servidor.
- JavaScript
- React
- Angular
// Rota no SEU backend que assina o JWT com a chave secreta
fetch("/api/wisemind-token")
.then((r) => r.json())
.then(({ token }) => {
window.wisemind("identify", {
token,
// Traços públicos (visíveis ao LLM, NÃO verificados)
firstName: "Maria",
plan: "pro",
});
});
import { useEffect } from "react";
export function WisemindIdentify({ user }) {
useEffect(() => {
if (!user) return;
// Rota no SEU backend que assina o JWT com a chave secreta
fetch("/api/wisemind-token")
.then((r) => r.json())
.then(({ token }) => {
window.wisemind("identify", {
token,
// Traços públicos (visíveis ao LLM, NÃO verificados)
firstName: user.firstName,
plan: user.plan,
});
});
return () => {
window.wisemind("reset");
};
}, [user]);
return null;
}
import { Component, OnInit, OnDestroy } from "@angular/core";
import { HttpClient } from "@angular/common/http";
declare global {
interface Window {
wisemind: (command: string, payload?: Record<string, unknown>) => void;
}
}
@Component({
selector: "app-wisemind-identify",
template: "",
})
export class WisemindIdentifyComponent implements OnInit, OnDestroy {
constructor(private http: HttpClient) {}
ngOnInit(): void {
// Rota no SEU backend que assina o JWT com a chave secreta
this.http
.get<{ token: string }>("/api/wisemind-token")
.subscribe(({ token }) => {
window.wisemind("identify", {
token,
// Traços públicos (visíveis ao LLM, NÃO verificados)
firstName: "Maria",
plan: "pro",
});
});
}
ngOnDestroy(): void {
window.wisemind("reset");
}
}
Parâmetros do comando identify
| Campo | Tipo | Descrição |
|---|---|---|
token | string | JWT assinado pelo seu backend (obrigatório). |
| Demais chaves | Record<string, *> | Informações públicas, enviados ao LLM como contexto. Não são verificados. |
- Chaves dentro do
token: verificados pela API e seguros para usar em REST tools ({{identity.*}}). - Chaves fora do token: visíveis ao LLM apenas como contexto — nunca confie nesses valores para decisões sensíveis.
Encerrando a sessão
Ao deslogar o usuário, limpe o estado de identificação:
window.wisemind("reset");
O comando reset:
- Remove o token e os traços armazenados em memória
- Limpa o cache de mensagens do
localStorage(chaveado pelouserId) - Reseta a UI do widget
Usando os dados em Ações de Chat
Em qualquer Ação de Chamada de API (URL, headers, query params, body), interpole os claims verificados usando a sintaxe {{identity.<claim>}}:
GET https://api.seusite.com/customers/{{identity.account_id}}/orders
Authorization: Bearer {{identity.api_token}}
Os valores são substituídos somente após a verificação da assinatura do JWT. Se o token estiver ausente, expirado ou inválido, a interpolação falha e a ação não é executada.
Consulte Ações de Chat para detalhes sobre como configurar requisições REST.
Segurança
- Algoritmo: HS256. Outros algoritmos não são aceitos.
- Verificação: a cada mensagem enviada via WebSocket, a API revalida a assinatura e a expiração do token.
- Rotação: rotacionar a chave invalida imediatamente todos os tokens em circulação.
- Escopo de confiança:
- Use chaves do token para qualquer decisão sensível (acesso a dados, cobrança, escrita).
- Trate informações públicas como entrada do usuário — eles podem ser manipulados no navegador.
- Armazenamento local: o widget armazena no
localStorageapenas o cache de mensagens. O token e os claims não são persistidos em disco, ficando apenas em memória.
Solução de problemas
| Sintoma | Causa provável |
|---|---|
| Identificação não tem efeito | Plano sem flag identity habilitada. Confirme em Planos. |
{{identity.*}} retorna vazio em REST tool | Token ausente, expirado, ou claim com nome diferente do interpolado. |
{{identity.email}} vazio mesmo com email enviado | email foi enviado como trait público (fora do token). Apenas claims dentro do JWT são interpolados. |
| Mensagens duplicadas / histórico misturado | sub (userId) não estável entre sessões. Use um identificador imutável. |
| Erro de assinatura no servidor | Chave secreta no backend diferente da exibida no painel. Verifique a rotação. |
| Token rejeitado após rotação | Comportamento esperado. Reemita tokens com a nova chave. |