> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mindosoftware.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Widget de chat web

> Embebé el chat de MINDO en tu sitio web: snippet, identidad de usuarios logueados (HMAC) y personalización.

## Qué es

El widget de chat web es un **canal más** de MINDO (igual que WhatsApp, Instagram o
ManyChat): una burbuja de chat que embebés en tu sitio con un `<script>` y que
conecta a tus visitantes con tu bandeja de MINDO. Los mensajes que te escriban
aparecen en el mismo Inbox donde ya atendés WhatsApp, y tu equipo (o tu agente IA)
responde desde ahí — la respuesta le llega al visitante **en tiempo real**, sin que
tenga que recargar la página.

Soporta dos tipos de visitante:

* **Anónimo** — no requiere nada de tu backend. El widget genera un identificador
  de visitante propio (guardado en `localStorage` del navegador) para reconocerlo
  entre mensajes.
* **Identificado** — si el visitante ya está logueado en tu sitio, tu backend puede
  firmarle la identidad (`userId`) para que MINDO la reconozca. Esto une, bajo un
  mismo contacto, todos los chats que ese usuario abra desde distintos dispositivos.

## Antes de empezar

Asegurate de tener a mano lo siguiente:

* Acceso a **Configuración → Canales** en MINDO con rol de administrador.
* Acceso al código de tu sitio (para pegar un `<script>`).
* Si vas a identificar usuarios logueados: acceso al backend de tu sitio, para
  calcular una firma HMAC (no se calcula nunca en el navegador).

## Paso a paso

<Steps>
  <Step title="Crear el canal Web">
    Desde MINDO, andá a **Configuración** → **Canales** y buscá la sección
    **Widget de chat web**. Hacé clic en **+ Agregar canal Web**.

    <Frame caption="Sección Widget de chat web en Configuración → Canales">
      <img src="https://mintcdn.com/mindo/YSxPGAdbcOint0Tk/images/widget-web-canales.png?fit=max&auto=format&n=YSxPGAdbcOint0Tk&q=85&s=5d9f5b699a2b824f8fa1f5e1f025a890" alt="Sección de canales Web en MINDO" width="1280" height="720" data-path="images/widget-web-canales.png" />
    </Frame>

    Completá:

    * **Nombre de la sesión** — un nombre interno para identificar este canal (por
      ejemplo, "Chat de la tienda"). No es lo que ve el visitante.
    * **Color primario** — el color del header y de las burbujas del visitante.
    * **Mensaje de bienvenida** — el primer mensaje que ve el visitante si todavía
      no escribió nada.
    * **Agente** (opcional) — si querés que un agente de IA responda automáticamente
      en este canal.

    <Frame caption="Formulario de creación de un canal Web">
      <img src="https://mintcdn.com/mindo/YSxPGAdbcOint0Tk/images/widget-web-crear-canal.png?fit=max&auto=format&n=YSxPGAdbcOint0Tk&q=85&s=350252a959385aa35fd819eb7e8a5714" alt="Formulario para crear un canal Web" width="1280" height="720" data-path="images/widget-web-crear-canal.png" />
    </Frame>

    <Warning>
      **Estado actual (verificado en QA):** el color primario, el mensaje de
      bienvenida y el agente asignado no se están guardando al crear/editar el
      canal desde este formulario — el widget muestra el estilo por defecto hasta
      que se corrija. El snippet y el flujo de mensajería (anónimo, identificado,
      respuesta en tiempo real) sí funcionan con normalidad. Si la personalización
      es crítica para vos, contactá a soporte antes de lanzar.
    </Warning>
  </Step>

  <Step title="Copiar el snippet">
    Al crear el canal, MINDO te muestra el snippet listo para copiar:

    ```html theme={null}
    <script
      src="https://app.mindosoftware.com/widget.js"
      data-mindo-token="TU_TOKEN_DE_CANAL"
      async
    ></script>
    ```

    También vas a ver un **Secret HMAC** — lo necesitás únicamente si vas a
    identificar visitantes logueados (Paso 4). Guardalo en un lugar seguro; nunca
    debe quedar expuesto en el HTML de tu sitio.
  </Step>

  <Step title="Pegar el snippet en tu sitio">
    Pegá el `<script>` antes del cierre de `</body>` en las páginas donde querés
    que aparezca el chat. No hace falta ningún build step ni dependencia — es un
    script vanilla, autocontenido.

    Al cargar la página vas a ver una burbuja de chat abajo a la derecha. Al hacer
    clic, se abre un panel con el chat (es un `<iframe>` a MINDO, así que tu sitio
    no necesita implementar ninguna UI de chat).

    <Frame caption="Panel del widget abierto sobre un sitio de ejemplo">
      <img src="https://mintcdn.com/mindo/YSxPGAdbcOint0Tk/images/widget-web-panel-abierto.png?fit=max&auto=format&n=YSxPGAdbcOint0Tk&q=85&s=3d09dba99cc6bb3fd12267dcea1ec7d3" alt="Panel del widget abierto" width="1280" height="720" data-path="images/widget-web-panel-abierto.png" />
    </Frame>

    <Note>
      Si no aparece la burbuja, revisá la consola del navegador: el error más común
      es un `data-mindo-token` vacío o incorrecto.
    </Note>
  </Step>

  <Step title="(Opcional) Identificar visitantes logueados">
    Si tu sitio tiene usuarios logueados y querés que MINDO los reconozca (en vez
    de tratarlos como anónimos), tu **backend** debe agregar tres atributos más al
    `<script>`, calculados en el momento de renderizar la página (nunca hardcodeados
    ni calculados en el navegador):

    | Atributo               | Qué es                                                                                                  |
    | ---------------------- | ------------------------------------------------------------------------------------------------------- |
    | `data-mindo-user`      | El identificador único de tu usuario (`userId`) — el que uses vos internamente.                         |
    | `data-mindo-expires`   | Timestamp Unix (segundos) hasta cuándo es válida la firma. Recomendado: ahora + 24-72hs.                |
    | `data-mindo-signature` | `HMAC_SHA256(secret, "{userId}:{expires}")` en hexadecimal, calculado con el **Secret HMAC** del canal. |

    <CodeGroup>
      ```javascript Node.js theme={null}
      const crypto = require("crypto");

      function firmarVisitante(userId, secretDelCanal, ttlSegundos = 60 * 60 * 24) {
        const expires = Math.floor(Date.now() / 1000) + ttlSegundos;
        const signature = crypto
          .createHmac("sha256", secretDelCanal)
          .update(`${userId}:${expires}`)
          .digest("hex");
        return { userId, expires, signature };
      }
      ```

      ```python Python theme={null}
      import hmac
      import hashlib
      import time

      def firmar_visitante(user_id, secret_del_canal, ttl_segundos=60 * 60 * 24):
          expires = int(time.time()) + ttl_segundos
          mensaje = f"{user_id}:{expires}".encode("utf-8")
          signature = hmac.new(
              secret_del_canal.encode("utf-8"), mensaje, hashlib.sha256
          ).hexdigest()
          return {"userId": user_id, "expires": expires, "signature": signature}
      ```
    </CodeGroup>

    Renderizá el resultado en el `<script>` (por ejemplo, desde una plantilla del
    lado del servidor):

    ```html theme={null}
    <script
      src="https://app.mindosoftware.com/widget.js"
      data-mindo-token="TU_TOKEN_DE_CANAL"
      data-mindo-user="{{ userId }}"
      data-mindo-signature="{{ signature }}"
      data-mindo-expires="{{ expires }}"
      async
    ></script>
    ```

    <Warning>
      El **Secret HMAC** es un secreto de servidor. Nunca lo incluyas en HTML,
      JavaScript del cliente, ni en un repositorio público — solo debe existir en
      tu backend, del mismo modo que guardarías cualquier otra API key.
    </Warning>

    <Note>
      La firma es **opcional por diseño**: si falta, está vencida o es inválida, el
      visitante simplemente queda anónimo — el chat nunca se bloquea por un error
      de firma.
    </Note>
  </Step>
</Steps>

## ¿Qué pasa después?

* Cada mensaje que un visitante te escribe crea (o continúa) un chat en tu Inbox de
  MINDO, con `Canal: Web`.
* Si identificaste al visitante (Paso 4) y esa misma persona te escribe desde otro
  dispositivo con el mismo `userId`, MINDO intenta unificar el historial bajo un
  solo contacto.
* Si tenés un agente de IA asignado al canal, puede responder automáticamente;
  si no, el chat espera respuesta humana como cualquier otro canal.

## Preguntas frecuentes

<AccordionGroup>
  <Accordion title="¿Necesito instalar algo en mi sitio además del script?">
    No. El `<script>` es autocontenido: crea su propia burbuja y su propio panel de
    chat (un iframe). No requiere CSS, dependencias ni build step.
  </Accordion>

  <Accordion title="¿Puedo tener el widget en varias páginas de mi sitio?">
    Sí, pegá el mismo snippet en todas las páginas donde quieras que aparezca. El
    visitante se identifica por un ID guardado en su navegador, así que si navega
    entre tus páginas mantiene la misma conversación.
  </Accordion>

  <Accordion title="¿Qué pasa si el visitante recarga la página en medio de una conversación?">
    El widget recupera el historial la próxima vez que el visitante manda un
    mensaje. Si todavía no escribió nada nuevo después de recargar, puede ver el
    chat vacío por un instante — no perdió la conversación, solo no se muestra hasta
    que vuelve a interactuar.
  </Accordion>

  <Accordion title="¿Qué pasa si no configuro la identificación por HMAC?">
    Nada se rompe: todos los visitantes quedan como anónimos, cada uno con su
    propio chat. Podés agregar la identificación más adelante sin cambiar nada de
    lo ya instalado.
  </Accordion>

  <Accordion title="¿Puedo restringir en qué sitios se puede usar mi token?">
    Sí, existe una restricción de orígenes permitidos (anti-abuso) a nivel de canal.
    Si necesitás activarla, contactá a soporte — todavía no está expuesta en el
    formulario de Configuración.
  </Accordion>

  <Accordion title="¿Puedo pedirle teléfono o email al visitante antes de que escriba?">
    La funcionalidad existe a nivel de backend (formulario "pre-chat" opcional u
    obligatorio) pero **todavía no está disponible en el widget ni en
    Configuración**. Si la necesitás para tu caso de uso, contactá a soporte antes
    de depender de ella.
  </Accordion>

  <Accordion title="¿Tiene costo adicional?">
    El canal Web no tiene un costo de mensajería como WhatsApp (no depende de Meta).
    Consultá con tu plan de MINDO si aplica algún límite de uso.
  </Accordion>
</AccordionGroup>
