# Verificación de identidad: dile al agente quiénes son tus visitantes con sesión iniciada

> Firma los IDs de tus usuarios en tu servidor con un secreto HMAC para que intoCHAT sepa quién está chateando: conversaciones verificadas, marcadores {{user.*}} en las acciones API y la opción de que solo chateen los visitantes con sesión iniciada.

La verificación de identidad permite que tu web le diga al agente quién es un visitante con sesión iniciada, de una forma que nadie puede falsificar. Tu servidor firma el ID del usuario con un secreto que solo conocen tu servidor e intoCHAT, y tu página pasa el ID y la firma al widget del chat.

## Qué hace

Para un visitante verificado:

- La conversación muestra **Verified:** y el ID de usuario en **Activity**, con el nombre y el correo que pasó tu página. La exportación CSV tiene una columna **Verified user ID**, y los [webhooks](/es/docs/webhooks) de leads, formularios y reservas incluyen un objeto `identity`.
- Las [acciones API del lado del servidor](/es/docs/api-actions) pueden usar el ID, el correo, el nombre y los metadatos del visitante como [marcadores](#marcadores-en-las-acciones-del-lado-del-servidor), que rellena intoCHAT, nunca la IA.
- Los manejadores de las [acciones del lado del cliente](/es/docs/client-actions) en tu página reciben al visitante como `context.user`.
- La IA sabe que el visitante está verificado y su nombre, así que puede saludarle. Nada más; consulta [Qué ve la IA](#que-ve-la-ia).

Si quieres, puedes hacer que [solo los visitantes verificados puedan chatear](#solo-los-visitantes-verificados-pueden-chatear).

La verificación de identidad necesita la burbuja de chat de la [etiqueta script](/es/docs/script-tag), porque la identidad llega desde tu página a través del [SDK de JavaScript](/es/docs/javascript-sdk).

## Configurarla

### 1. Generar un secreto

1. Abre tu agente y ve a la pestaña **Share**.
2. En la tarjeta **Identity verification**, haz clic en **Generate secret**.
3. Copia el secreto y guárdalo en tu servidor, por ejemplo en una variable de entorno llamada `INTOCHAT_IDENTITY_SECRET`.

Solo el propietario de la cuenta y los admins pueden generar, mostrar o rotar el secreto. Los editors y los viewers ven si hay uno configurado y sus cuatro últimos caracteres.

> El secreto solo debe estar en tu servidor. Nunca lo pongas en el HTML ni en el JavaScript de tu página: cualquiera que lo tenga puede firmar cualquier ID de usuario y chatear como ese usuario.

### 2. Firmar el ID de usuario en tu servidor

Para el usuario con sesión iniciada, calcula `userHash`: el HMAC-SHA256 del ID de usuario, con el secreto como clave, escrito en hexadecimal en minúsculas. Firma exactamente el texto que pasarás como `userId`.

Node.js:

```js
import { createHmac } from "node:crypto";

const userHash = createHmac("sha256", process.env.INTOCHAT_IDENTITY_SECRET)
  .update(String(user.id))
  .digest("hex");
```

PHP:

```php
<?php
$userHash = hash_hmac('sha256', (string) $user->id, getenv('INTOCHAT_IDENTITY_SECRET'));
```

Python:

```python
import hashlib, hmac, os

user_hash = hmac.new(
    os.environ["INTOCHAT_IDENTITY_SECRET"].encode(),
    str(user.id).encode(),
    hashlib.sha256,
).hexdigest()
```

Incluye el ID de usuario y el hash en la página que envías a ese usuario.

### 3. Identificar al visitante en la página

Después del snippet, llama a `IntoChat.identify` en cada carga de página mientras el visitante tenga la sesión iniciada:

```html
<script src="https://www.intochat.ai/api/embed.js" data-chatbot-id="YOUR_AGENT_ID"></script>
<script>
  window.IntoChat.identify({
    userId: "4711",
    userHash: "THE_HASH_FROM_YOUR_SERVER",
    name: "Ada Lovelace",         // optional
    email: "ada@example.com",     // optional
    metadata: { plan: "pro" }     // optional
  });
</script>
```

Los límites de cada campo aparecen en [identify](/es/docs/javascript-sdk#identify). El widget envía la identidad con cada mensaje, y el servidor de intoCHAT comprueba la firma cada vez.

### 4. Restablecer al cerrar sesión

Cuando el visitante cierre sesión, llama a:

```js
IntoChat.reset();
```

Esto olvida la identidad y empieza un chat nuevo, para que la siguiente persona en ese navegador no vea la conversación anterior. Identificar a un usuario distinto también empieza un chat nuevo por sí solo. Un visitante que chateó antes de iniciar sesión conserva esa conversación, que pasa entonces a estar verificada.

## Solo los visitantes verificados pueden chatear

Activa **Only verified visitors can chat** en la misma tarjeta para reservar el chat a los usuarios con sesión iniciada:

- Hasta que tu página identifique al visitante con una firma válida, el widget muestra un breve aviso que le pide iniciar sesión, en el idioma del widget, en lugar del campo de mensaje.
- La API del chat rechaza los mensajes sin una identidad válida, con el motivo `identity_required`, así que la regla también se cumple fuera del widget.
- Un [iframe en la página, un enlace directo](/es/docs/iframe-and-link) y la [página de ayuda](/es/docs/help-page) no pueden identificar a nadie, así que solo muestran el aviso. Los [enlaces de vista previa](/es/docs/preview-links) para clientes potenciales siguen funcionando: tienen su propio chat.
- Tu propio [Playground](/es/docs/instructions#prueba-en-el-playground) sigue funcionando, así que puedes seguir probando el agente.

El interruptor necesita un secreto, así que genera uno primero. Los editors pueden activarlo o desactivarlo.

## Marcadores en las acciones del lado del servidor

Una [acción API del lado del servidor](/es/docs/api-actions) puede usar estos marcadores en cualquier parte de su URL, sus parámetros, sus cabeceras y su cuerpo:

| Marcador | Se rellena con |
| --- | --- |
| `{{user.id}}` | El ID de usuario verificado |
| `{{user.email}}` | El correo que pasó tu página |
| `{{user.name}}` | El nombre que pasó tu página |
| `{{user.metadata.<key>}}` | Un valor de los metadatos, por ejemplo `{{user.metadata.plan}}` |

```text
GET https://api.example.com/customers/{{user.id}}/orders
```

intoCHAT los rellena en sus servidores, solo a partir de la identidad verificada:

- Para un visitante que no está verificado, quedan vacíos. Un parámetro o un campo del cuerpo vacío se omite de la petición.
- La IA nunca los ve y no puede elegirlos ni cambiarlos. Aunque la IA pase un valor que parezca `{{user.id}}`, se envía como texto sin más.
- **Send test request** en el editor no tiene visitante, así que ahí también quedan vacíos.
- Un marcador que es únicamente `{{user.metadata.seats}}` en el cuerpo conserva el tipo del valor, así que un número sigue siendo un número.

Cualquier otro marcador `{{user.…}}`, como `{{user.phone}}`, no se puede guardar. En una [acción del lado del cliente](/es/docs/client-actions), cuya petición se monta en el navegador del visitante, estos marcadores quedan vacíos; tu manejador recibe al visitante como `context.user`.

> Solo se firma el ID de usuario. El nombre, el correo y los metadatos son lo que tu página pasó junto con una firma válida, así que un visitante con sesión iniciada podría cambiar su propia copia en el navegador. Consulta lo que importe, como pedidos o permisos, por `{{user.id}}` en tu lado.

## Los visitantes verificados pasan a ser contactos

Cada visitante verificado se guarda como [contacto](/es/docs/contacts) del agente, con su ID de usuario como **External ID**, el nombre y el correo que pasó tu página, y como atributos las claves de los metadatos que son nombres de atributo válidos (letras minúsculas, dígitos y guiones bajos, empezando por una letra). Cuando tu página pasa datos nuevos, el contacto se actualiza. El contacto se busca únicamente por el ID de usuario: un visitante verificado nunca se fusiona con otro contacto porque coincidan los correos, y solo recibe el correo si ningún otro contacto lo tiene. Después, las acciones del lado del servidor pueden leer el contacto, incluidos los atributos que importaste o añadiste por la API, como marcadores `{{contact.*}}`. Los visitantes de **Test as a signed-in visitor** en el Playground no pasan a ser contactos.

## Qué ve la IA

A la IA se le dice que el visitante tiene la sesión iniciada y está verificado, y el nombre que pasó tu página, que puede usar para saludarle. Nunca recibe la dirección de correo, el ID de usuario ni los metadatos, así que no puede repetirlos ni ser convencida para revelarlos. Si quieres que el agente sepa más, escríbelo tú en tus [instrucciones](/es/docs/instructions).

## Probar en el Playground

Para probar los marcadores o el saludo del agente sin iniciar sesión en tu web, abre el **Playground** y despliega **Test as a signed-in visitor** encima del chat. Escribe un **User ID** y, si quieres, un **Name**, un **Email** y **Metadata** como objeto JSON, por ejemplo `{"plan": "pro", "seats": 5}`. Se aplican los mismos límites que en tu web; consulta [Límites](#limites). Mientras haya algo que corregir, un mensaje en rojo indica qué, y el Playground chatea como un visitante anónimo.

Con un ID de usuario rellenado, tus mensajes del Playground cuentan como verificados:

- Las [acciones del lado del servidor](#marcadores-en-las-acciones-del-lado-del-servidor) reciben estos valores como marcadores `{{user.*}}`.
- A la IA se le dice que el visitante está verificado y su nombre, como se explica en [Qué ve la IA](#que-ve-la-ia).
- La conversación del Playground registra al usuario, así que muestra **Verified** en la pestaña Conversations.

No hace falta firma, porque has iniciado sesión en intoCHAT. La identidad de prueba solo se acepta desde el Playground de tu panel, y del propietario, un admin o un editor; los viewers no pueden usarla, y el widget de chat, los enlaces y la API REST la ignoran. Los visitantes de tu web siempre necesitan una firma válida. [Solo los visitantes verificados pueden chatear](#solo-los-visitantes-verificados-pueden-chatear) nunca rechaza el Playground, con o sin identidad de prueba.

Una conversación conserva el primer usuario verificado que ve, así que pulsa **Reset** antes de probar como otro usuario.

## El secreto

- **Reveal** vuelve a mostrar el secreto actual, al propietario y a los admins.
- **Rotate** crea un secreto nuevo y pide confirmación antes. El anterior deja de funcionar al momento: hasta que tu servidor firme con el secreto nuevo, todos los visitantes cuentan como no verificados y, con **Only verified visitors can chat** activado, no pueden chatear.
- El secreto se guarda cifrado. Al duplicar un agente no se copian ni el secreto ni el interruptor.

## Límites

- Un secreto por agente. Con varios agentes en una página, cada uno solo verifica las firmas hechas con su propio secreto.
- Una firma incorrecta o ausente nunca se muestra al visitante como error: simplemente chatea sin verificar, salvo que solo puedan chatear los visitantes verificados.
- Una conversación pertenece al primer usuario verificado en ella. Si otro usuario verificado escribe en la misma sesión, sin el chat nuevo que normalmente inicia `identify`, esos mensajes se tratan como no verificados.
- Un ID de usuario tiene hasta 200 caracteres, un nombre hasta 100, un correo hasta 254, y los metadatos hasta 20 claves y 2 KB.
- La identidad no se comprueba cuando un visitante vuelve a abrir un chat anterior desde la lista de su navegador; [Restablecer al cerrar sesión](#4-restablecer-al-cerrar-sesion) vacía esa lista.
