Documentación

Identificación de usuarios

Identificar a los usuarios conecta las sesiones de chat anónimas con perfiles de usuario reales.

Cómo funciona

Cuando llamas a Respondo.identify(), los campos proporcionados se adjuntan a la conversación. Todos los campos son opcionales — pasa solo los que tengas. Por ejemplo, puedes enviar únicamente userId sin email ni nombre. Los agentes de soporte ven estos datos en el panel de detalles de la conversación.

Parámetros#

PropiedadTipoObligatorioDescripción
emailstringopcionalDirección de email del usuario
namestringopcionalNombre para mostrar
userIdstringopcionalTu ID interno de usuario o de visualización — se muestra tal cual en el panel
userHashstringopcionalFirma HMAC-SHA256 para la verificación de identidad
metadataobjectopcionalPares clave-valor de campos personalizados (plan, empresa, etc.)
propertiesobjectopcionalPropiedades de contacto personalizadas definidas en Agent Settings. Las claves deben coincidir con las definiciones de propiedades. Los valores se almacenan con el prefijo cp_ y se pueden filtrar en la Bandeja de entrada.
Ejemplo: aplicación de página única (SPA)javascript
// Tras un inicio de sesión correcto
async function onLogin(user) {
  await authenticateUser(user);

  Respondo.identify({
    email: user.email,
    name: user.fullName,
    userId: user.id,
    metadata: {
      plan: user.subscription.plan,
      company: user.company.name,
      role: user.role,
      signedUp: user.createdAt
    },
    properties: {                        // propiedades de contacto personalizadas
      account_type: user.accountType,    // deben coincidir con las claves de Agent Settings
      industry: user.industry,
      contract_tier: user.tier
    }
  });
}
Con el fragmento de instalación estándar puedes llamar a identify() en cualquier momento — las llamadas realizadas antes de que widget.js termine de cargar se encolan en el fragmento y se reproducen automáticamente cuando el widget se inicializa. Los datos de identidad solo se descartan (con una advertencia en la consola) si cargas widget.js por tu cuenta y llamas a identify() antes de haber llamado nunca a init() — en configuraciones manuales, llama siempre primero a init().

Visitantes anónimos#

Si no llamas a identify(), el widget asigna automáticamente un ID de visitante persistente almacenado en localStorage (clave respondoai_visitor_id). En el panel, la conversación aparece como Guest · Web widget.

ModoVisualización en el panelHMAC requerido
Sin identify()Guest · Web widgetNo
identify({ email, name })Se muestran nombre + emailNo — a menos que la Verificación de identidad esté activada; en ese caso, el email/nombre sin firmar se eliminan silenciosamente y la sesión permanece anónima
identify({ userId })userId se muestra tal cualNo — a menos que la Verificación de identidad esté activada; entonces se requiere un userHash válido o la identidad se elimina
identify({ userId, userHash })Identidad de usuario verificadaSí — verificado criptográficamente

Cuando la Verificación de identidad está activada para el canal, cualquier identify() que lleve email o userId sin un userHash válido se elimina en el servidor y el visitante permanece anónimo — consulta Verificación de identidad (HMAC) más abajo.

El ID de visitante persiste entre sesiones en el mismo navegador. Nunca se envía a Respondo como una identidad autenticada — solo se usa para dar continuidad a conversaciones anónimas.

Identificación solo con userId (sin email ni nombre)#

Si tu plataforma no dispone de emails ni nombres de usuario — por ejemplo, solo tienes un ID de visualización interno — puedes pasar únicamente userId. No se necesita ningún otro campo. El panel mostrará el userId tal cual en los detalles de la conversación.

userId + metadata (sin email ni nombre)javascript
// Tu plataforma solo tiene un ID de visualización — con eso basta
Respondo.identify({
  userId: user.displayId,      // p. ej. "USR-4821" — se muestra en el panel
  metadata: {                  // contexto adicional opcional
    plan: 'premium',
    region: 'eu-west'
  }
});
// No se necesita email ni nombre — el widget funciona solo con userId
Para evitar la suplantación del userId, combínalo con userHash (consulta Verificación de identidad más abajo). Sin HMAC, cualquiera puede pasar cualquier userId desde la consola del navegador.

Google Tag Manager / identify() diferido#

Al integrar mediante GTM, es posible que los datos del usuario no estén disponibles cuando se carga la página. Dos enfoques:

Opción A: localStorageKey (sin necesidad de JS)javascript
// Si tu plataforma ya escribe el ID de usuario en localStorage:
Respondo.init({
  agentId: 'YOUR_AGENT_ID',
  localStorageKey: 'myapp_user_id'  // lee localStorage.getItem('myapp_user_id') automáticamente
});
// No hace falta llamar a identify() — el widget toma el userId por su cuenta
Opción B: identify() diferido mediante dataLayerjavascript
// 1. Inicializa el widget de inmediato (etiqueta de GTM)
Respondo.init({ agentId: 'YOUR_AGENT_ID' });

// 2. Más tarde, cuando aparezcan los datos del usuario (p. ej. desde dataLayer o tu app):
var waitForUser = setInterval(function() {
  var uid = localStorage.getItem('myapp_user_id');
  if (uid && window.Respondo && typeof window.Respondo.identify === 'function') {
    clearInterval(waitForUser);
    Respondo.identify({ userId: uid });
  }
}, 500);
localStorageKey solo se usa si aún no se ha establecido ningún userId mediante identify(). Las llamadas explícitas a identify() siempre tienen prioridad.

Verificación de identidad (HMAC)#

Sin verificación, cualquiera podría hacerse pasar por un usuario pasando un userId o un email falso. La verificación de identidad usa HMAC-SHA256 para demostrar criptográficamente que la identidad del usuario fue establecida por tu servidor, no por código del lado del cliente.

Cómo funciona#

  1. Activa la verificación de identidad en la configuración de tu canal — obtendrás una clave secreta.
  2. En tu servidor, calcula HMAC-SHA256(secret, userId) — el secret es la clave y el userId es el mensaje — y envía el resultado al frontend. Si identificas a los usuarios solo por email (sin userId), firma el email en su lugar: la carga firmada es el userId cuando está definido, y si no, el email. Si pasas ambos, firma el userId; tiene prioridad.
  3. Pasa el hash como userHash en Respondo.identify().
  4. Respondo verifica el hash en el servidor. Si no es válido, se elimina la identidad y el usuario se trata como anónimo.
Nunca expongas tu clave secreta en el código del frontend. El HMAC debe calcularse en tu backend.
Una vez activada la verificación, toda llamada a identify() que lleve userId o email debe incluir un userHash válido — de lo contrario, los campos de identidad se eliminan y el visitante se trata como anónimo.

Ejemplos del lado del servidor#

Node.jsjavascript
const crypto = require('crypto');

const SECRET = process.env.RESPONDO_IDENTITY_SECRET;

function generateUserHash(userId) {
  return crypto
    .createHmac('sha256', SECRET)
    .update(userId)
    .digest('hex');
}

// En tu endpoint de API:
app.get('/api/respondo-hash', (req, res) => {
  const hash = generateUserHash(req.user.id);
  res.json({ userHash: hash });
});
Pythonpython
import hmac, hashlib, os

SECRET = os.environ['RESPONDO_IDENTITY_SECRET']

def generate_user_hash(user_id: str) -> str:
    return hmac.new(
        SECRET.encode(),
        user_id.encode(),
        hashlib.sha256
    ).hexdigest()

# En tu vista / endpoint:
user_hash = generate_user_hash(request.user.id)
Gogo
import (
    "crypto/hmac"
    "crypto/sha256"
    "encoding/hex"
)

func GenerateUserHash(userID, secret string) string {
    mac := hmac.New(sha256.New, []byte(secret))
    mac.Write([]byte(userID))
    return hex.EncodeToString(mac.Sum(nil))
}

Uso en el frontend#

Con verificación de identidadjavascript
// Obtén el hash desde TU servidor
const { userHash } = await fetch('/api/respondo-hash').then(r => r.json());

Respondo.identify({
  email: user.email,
  name: user.name,
  userId: user.id,
  userHash: userHash  // firma HMAC-SHA256
});