Ir al contenido

Cómo integrar AnnA Chat con un usuario corporativo V3

Esta guía muestra cómo integrar AnnA Chat para un usuario corporativo autenticado mediante la API V3. El navegador recibe únicamente la URL generada de AnnA Chat. Mantén el hash de la empresa, las credenciales del usuario, el token bearer y todas las llamadas a la API V3 en tu backend.

Necesitas la siguiente información de tu entorno AnnA:

  • El hash de la empresa.
  • El usuario y la contraseña utilizados con REST/Credentials/GetToken.
  • El ID del usuario corporativo y, opcionalmente, su nombre.
  • La URL base de tu entorno AnnA.

V3 usa autenticación mediante token en lugar de las claves de cifrado requeridas por V2. El token tiene una duración corta y nunca debe exponerse en la página del cliente.

  1. Tu backend llama a REST/Credentials/GetToken con el hash de la empresa y las credenciales del servicio.
  2. Tu backend usa el token devuelto en el encabezado Authorization: Bearer <Token>.
  3. Tu backend llama a REST/AnnACorporate/User/UserHash o REST/AnnACorporate/User/UserHashForced con getAnnAChatLink establecido en true.
  4. Tu backend lee accessData.AnnAChatURL de la respuesta.
  5. Tu código del cliente usa esa URL generada como origen del iframe.

Usa UserHash cuando el usuario corporativo ya existe. Usa UserHashForced cuando AnnA deba crear o actualizar el usuario con el userName proporcionado antes de generar el hash.

La URL generada puede caducar. Genérala en el servidor para el usuario autenticado y no coloques el hash de la empresa, el usuario, la contraseña ni el token bearer en el código del navegador.

Primero solicita un token:

Endpoint: REST/Credentials/GetToken

{
"hash": "YOUR_COMPANY_HASH",
"user": "YOUR_API_USER",
"pass": "YOUR_API_PASSWORD"
}

Después llama al endpoint del usuario corporativo con el token:

Endpoint: REST/AnnACorporate/User/UserHash

{
"getAnnAChatLink": true,
"hash": "YOUR_COMPANY_HASH",
"userId": "USER_ID",
"startService": ""
}

Para un usuario que deba crearse o actualizarse, usa REST/AnnACorporate/User/UserHashForced y agrega la propiedad userName.

La respuesta correcta contiene la URL en accessData.AnnAChatURL:

{
"success": true,
"message": "User Hash generated successfully",
"accessData": {
"Hash": "USER_HASH",
"ChatURL": "CHAT_URL_WITH_USER_HASH",
"EmbeddedURL": "EMBEDDED_URL_WITH_USER_HASH",
"AnnAChatURL": "ANNACHAT_URL_FOR_IFRAME",
"Expires": "EXPIRATION_DATETIME"
}
}

Si success es false, gestiona el valor de message en el backend y no envíes una URL inválida al navegador.

Reemplaza ANNACHAT_URL_FROM_BACKEND por el valor de accessData.AnnAChatURL devuelto por tu backend. El botón crea la ventana del chat solamente después de que el usuario hace clic.

<!doctype html>
<html lang="es">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Demo de AnnA Chat integrado</title>
</head>
<body>
<h1>Sitio del cliente corporativo</h1>
<p>
El widget autenticado de AnnA Chat aparece en la esquina inferior derecha.
</p>
<script>
(function () {
const ANNA_URL = "ANNACHAT_URL_FROM_BACKEND"; // Usa el valor AnnAChatURL generado por el backend
const CHAT_W = 400,
CHAT_H = 600,
BTN_SIZE = 60;
const sideOffset = "clamp(16px, 2.2vw, 30px)";
const bottomOffset = "clamp(16px, 2.2vw, 30px)";
const btn = document.createElement("div");
btn.id = "anna-launcher";
Object.assign(btn.style, {
position: "fixed",
bottom: bottomOffset,
right: sideOffset,
width: BTN_SIZE + "px",
height: BTN_SIZE + "px",
borderRadius: "50%",
cursor: "pointer",
zIndex: "9999",
background: "#7c3aed",
display: "flex",
alignItems: "center",
justifyContent: "center",
boxShadow: "0 4px 12px rgba(0,0,0,0.25)",
transition: "transform 0.2s",
});
btn.innerHTML =
'<svg width="28" height="28" fill="#fff" viewBox="0 0 24 24"><path d="M20 2H4a2 2 0 0 0-2 2v18l4-4h14a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2z"/></svg>';
btn.onmouseenter = function () {
btn.style.transform = "scale(1.1)";
};
btn.onmouseleave = function () {
btn.style.transform = "scale(1)";
};
const chat = document.createElement("div");
chat.id = "anna-chat";
Object.assign(chat.style, {
position: "fixed",
bottom: `calc(${bottomOffset} + ${BTN_SIZE}px + 10px)`,
right: sideOffset,
width: `min(${CHAT_W}px, calc(100vw - 32px))`,
height: CHAT_H + "px",
maxHeight: `min(${CHAT_H}px, calc(100vh - 116px))`,
borderRadius: "12px",
overflow: "hidden",
boxShadow: "0 8px 30px rgba(0,0,0,0.3)",
display: "none",
zIndex: "9998",
});
chat.innerHTML =
'<iframe src="' +
ANNA_URL +
'" style="width:100%;height:100%;border:none" allow="camera *; microphone *; geolocation *"></iframe>';
btn.addEventListener("click", function () {
var open = chat.style.display === "none";
chat.style.display = open ? "block" : "none";
});
document.body.appendChild(chat);
document.body.appendChild(btn);
})();
</script>
</body>
</html>

Los ejemplos siguientes llaman a REST/Credentials/GetToken y después a REST/AnnACorporate/User/UserHash con getAnnAChatLink establecido en true. Analizan accessData.AnnAChatURL y devuelven el valor desde un método del backend.

Para usar el flujo forzado, reemplaza REST/AnnACorporate/User/UserHash por REST/AnnACorporate/User/UserHashForced y agrega userName al cuerpo de la solicitud.

using var http = new HttpClient { BaseAddress = new Uri("https://YOUR_ANNA_ENVIRONMENT/") };
var tokenResult = await http.PostAsJsonAsync("REST/Credentials/GetToken", new
{
hash = "YOUR_COMPANY_HASH", user = "YOUR_API_USER", pass = "YOUR_API_PASSWORD"
});
var token = JObject.Parse(await tokenResult.Content.ReadAsStringAsync())["data"]["Token"];
http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", (string)token);
var chatResult = await http.PostAsJsonAsync("REST/AnnACorporate/User/UserHash", new
{
getAnnAChatLink = true, hash = "YOUR_COMPANY_HASH", userId = "USER_ID", startService = ""
});
var response = JObject.Parse(await chatResult.Content.ReadAsStringAsync());
if ((bool?)response["success"] != true) throw new InvalidOperationException((string)response["message"]);
var annaChatUrl = (string)response["accessData"]["AnnAChatURL"];

Usa el valor devuelto en accessData.AnnAChatURL como ANNACHAT_URL_FROM_BACKEND en el ejemplo del cliente. No devuelvas el hash de la empresa, las credenciales de la API ni el token bearer al navegador.