Skip to content

How to embed AnnA Chat with a Corporate User V2

This guide shows how to embed AnnA Chat for an authenticated Corporate User using the V2 API. The browser receives only the generated AnnA Chat URL. Keep the company hash, encryption and decryption keys, user data, and all V2 API calls on your backend.

You need the following information from your AnnA environment:

  • The company hash.
  • The Corporate User encryption and decryption keys.
  • The Corporate User ID.
  • The base URL of your AnnA environment.

The V2 integration uses 3DES encryption with CBC mode. See Encryption for the encryption requirements and helper methods used by the examples.

  1. Your backend sends an encrypted GENERATE_USER_HASH request to aannacorporateuser.aspx.
  2. Your backend sets GET_ANNA_CHAT_LINK to S so that AnnA returns the chat links.
  3. Your backend decrypts the response and reads the AnnAChatURL property.
  4. Your client-side code uses that generated URL as the iframe source.

The generated URL can expire. Generate it on the server for the signed-in user and do not put the company hash or encryption keys in browser code.

After decrypting the response, parse the JSON returned by AnnA. The AnnAChatURL property is the URL to use in the iframe.

{
"Status": "OK",
"Message": "User Hash generated successfully",
"Hash": "USER_HASH",
"ChatURL": "CHAT_URL_WITH_USER_HASH",
"EmbeddedURL": "EMBEDDED_URL_WITH_USER_HASH",
"AnnAChatURL": "ANNACHAT_URL_FOR_IFRAME",
"Expires": "EXPIRATION_DATETIME"
}

If the response status is not successful, handle the Message value on the backend and do not send an invalid URL to the browser.

Replace ANNACHAT_URL_FROM_BACKEND with the AnnAChatURL value returned by your backend. The launcher creates the chat window only after the user clicks it.

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>AnnA Chat Embedded Demo</title>
</head>
<body>
<h1>Corporate client site</h1>
<p>The authenticated AnnA Chat widget appears in the lower-right corner.</p>
<script>
(function () {
const ANNA_URL = "ANNACHAT_URL_FROM_BACKEND"; // Use the backend-generated AnnAChatURL value
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>

Send the request to YOUR_ANNA_URL/aannacorporateuser.aspx with ACTION=GENERATE_USER_HASH and GET_ANNA_CHAT_LINK=S. Encrypt the fields that the V2 API requires with the encryption key and request IV. Decrypt the returned payload with the response IV, then read AnnAChatURL from the JSON.

The Encrypt, Decrypt, GenerateIV, and DecryptAnnAResponse helpers in the examples represent the 3DES helpers described in Encryption. They must run on the backend.

using System.Collections.Specialized;
using System.Net;
using System.Text;
using Newtonsoft.Json.Linq;
public string GenerateCorporateChatUrl()
{
var companyHash = "YOUR_COMPANY_HASH";
var encryptionKey = "YOUR_CORPORATE_USER_ENCRYPTION_KEY";
var decryptionKey = "YOUR_CORPORATE_USER_DECRYPTION_KEY";
var userId = "USER_ID";
var startService = "";
var requestIv = GenerateIV();
var form = new NameValueCollection
{
["HASH"] = companyHash,
["ANNAEXEC"] = requestIv,
["ACTION"] = Encrypt("GENERATE_USER_HASH", encryptionKey, requestIv),
["USER_ID"] = Encrypt(userId, encryptionKey, requestIv),
["START_SERVICE"] = Encrypt(startService, encryptionKey, requestIv),
["GET_ANNA_CHAT_LINK"] = "S"
};
using (var client = new WebClient())
{
client.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
var responseText = Encoding.UTF8.GetString(client.UploadValues(
"https://YOUR_ANNA_URL/aannacorporateuser.aspx", "POST", form));
var jsonText = DecryptAnnAResponse(
responseText, requestIv, encryptionKey, decryptionKey);
var response = JObject.Parse(jsonText);
if ((string)response["Status"] != "OK")
{
throw new InvalidOperationException((string)response["Message"]);
}
return (string)response["AnnAChatURL"];
}
}

Use the value returned in AnnAChatURL as ANNACHAT_URL_FROM_BACKEND in the client-side example. Do not return the company hash, encryption keys, or decrypted authentication hash to the browser.