Guía de integración
Todo lo que un ingeniero o agente de código necesita para instalar DeltaCrab.
Versión de la documentación: widget v1. No la mezcles con otras versiones.
Resumen
El widget de DeltaCrab es un script que crea un iframe en tu sitio. El iframe se ejecuta en el dominio de DeltaCrab; tu sitio nunca ve tokens ni mensajes.
El widget solo carga en orígenes autorizados en la página Instalación. Empieza en modo visitante; añade identidad verificada cuando tu app tenga servidor.
- 1. Copia la clave pública del sitio en la página Instalación.
- 2. Añade el origen de tu app (p. ej., https://app.ejemplo.com) en Orígenes autorizados.
- 3. Pega el snippet en el layout global.
- 4. Abre tu sitio, envía un mensaje y respóndelo desde la bandeja de entrada.
HTML / cualquier sitio
Pega antes de </body> en todas las páginas, o una vez en el layout principal.
<script>
window.DeltaCrabSettings = { siteKey: "dc_pk_YOUR_SITE_KEY" };
window.DeltaCrab = window.DeltaCrab || function () { (window.DeltaCrab.q = window.DeltaCrab.q || []).push(arguments); };
</script>
<script async src="https://app.deltacrab.com/widget.js"></script>Next.js (App Router)
Añádelo una vez en app/layout.tsx. Funciona con Server Components; el script carga después de la hidratación.
// app/layout.tsx — add once, inside <body>
import Script from "next/script";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
{children}
<Script id="deltacrab-settings" strategy="afterInteractive">
{`window.DeltaCrabSettings = { siteKey: "dc_pk_YOUR_SITE_KEY" };
window.DeltaCrab = window.DeltaCrab || function () { (window.DeltaCrab.q = window.DeltaCrab.q || []).push(arguments); };`}
</Script>
<Script src="https://app.deltacrab.com/widget.js" strategy="afterInteractive" />
</body>
</html>
);
}
// Optional, from any client component:
// window.DeltaCrab?.("setLocale", "pt-BR");
// window.DeltaCrab?.("setTheme", "dark");
// window.DeltaCrab?.("open");Identidad verificada
Tu servidor firma un token HS256 corto con el secreto generado en Instalación → Identidad verificada. El secreto queda solo en el servidor, en la variable DELTACRAB_IDENTITY_SECRET.
Claims obligatorios: site_key, sub (ID estable del cliente en tu base de datos), iat, exp (como máximo 10 minutos después de iat) y jti (único; cada token se usa una sola vez). Atributos aceptados: name, email, plan, organization, account_id, locale. Los demás campos se ignoran.
Pide un token nuevo y llama a identify en cada carga de página mientras el usuario tenga sesión, y justo después de iniciar sesión o cambiar de cuenta. Llama a logout al salir. El historial anónimo nunca se une al cliente identificado.
Al rotar el secreto, el anterior sigue siendo válido durante 24 horas para que publiques el nuevo sin cortar a nadie.
// app/api/deltacrab-token/route.ts — runs on YOUR server only.
// Requires DELTACRAB_IDENTITY_SECRET (from DeltaCrab → Install → Verified identity).
import { createHmac, randomUUID } from "node:crypto";
import { NextResponse } from "next/server";
import { getSession } from "@/lib/auth"; // your existing server-side session helper
function base64url(input: Buffer | string) {
return Buffer.from(input).toString("base64url");
}
export async function POST() {
const session = await getSession();
if (!session?.user) return NextResponse.json({ error: "unauthenticated" }, { status: 401 });
const now = Math.floor(Date.now() / 1000);
const header = base64url(JSON.stringify({ alg: "HS256", typ: "JWT" }));
const payload = base64url(JSON.stringify({
site_key: "dc_pk_YOUR_SITE_KEY",
sub: String(session.user.id), // stable customer ID from YOUR database
iat: now,
exp: now + 300, // at most 10 minutes
jti: randomUUID(), // single use
name: session.user.name, // optional, allowlisted attributes:
email: session.user.email, // name, email, plan, organization, account_id, locale
}));
const signature = createHmac("sha256", process.env.DELTACRAB_IDENTITY_SECRET!)
.update(`${header}.${payload}`)
.digest("base64url");
return NextResponse.json({ token: `${header}.${payload}.${signature}` });
}
// In the browser, on every page load while the user is signed in (tokens are
// single use and short-lived, so fetch a fresh one each time), and right
// after login or an account switch:
// const { token } = await fetch("/api/deltacrab-token", { method: "POST" }).then(r => r.json());
// window.DeltaCrab("identify", { token });
// On logout:
// window.DeltaCrab("logout");
// Widget script: https://app.deltacrab.com/widget.jsAPI del widget
Los comandos se pueden llamar antes de que el script termine de cargar: el stub del snippet guarda la cola y el cargador la ejecuta en orden.
window.DeltaCrab("open"); // open the panel
window.DeltaCrab("close"); // close the panel
window.DeltaCrab("setLocale", "pt-BR"); // en | pt-BR | es
window.DeltaCrab("setTheme", "dark"); // light | dark | system
window.DeltaCrab("identify", { token }); // signed identity token from YOUR server
window.DeltaCrab("logout"); // forget the signed-in customer on this deviceContent Security Policy
Si tu app define CSP, permite el origen de DeltaCrab en estas directivas:
Content-Security-Policy:
script-src 'self' https://app.deltacrab.com;
frame-src https://app.deltacrab.com;
connect-src 'self' https://app.deltacrab.com;Solución de problemas
La consola del navegador y la sección Diagnóstico de la página Instalación muestran la causa.
- "not in the allowed origins": añade el origen exacto (protocolo + host + puerto) en Orígenes autorizados.
- "Unknown site key": copia el snippet de nuevo desde la página Instalación.
- Rechazo de frame-ancestors en la consola: el origen no está autorizado para este sitio.
- Identidad rechazada: expired (token vencido), replay (jti repetido), bad_signature (secreto incorrecto), wrong_site (site_key distinto), lifetime_too_long (exp - iat por encima del límite).
- No aparece nada: revisa la CSP (script-src, frame-src, connect-src).