How to embed AnnA Chat
AnnA Chat can be embedded in a client website using an iframe inside a floating launcher. The client website controls when the chat window opens, while AnnA Chat is loaded from the URL provided by your backend.
Before you start
Section titled “Before you start”You can set ANNA_URL in the example with either an URL generated by your backend or a URL assembled with the parameters described below.
Option 1: Backend-generated URL
Section titled “Option 1: Backend-generated URL”Generate the anonymous chat URL on your backend and replace ANNA_CHAT_URL in the example with the URL returned by REST/AnnAChat/Anonymous.
Option 2: URL with language and start service
Section titled “Option 2: URL with language and start service”You can also build the URL directly using two positional, unnamed parameters:
https://YOUR_ANNA_ENVIRONMENT_URL/annachatanonimo.aspx?LANGUAGE,@startServiceLANGUAGEmust bePORfor Brazilian Portuguese,SPAfor Spanish, orENGfor English.startServiceis the second parameter and must always start with@.- The parameters are separated by a comma and do not have parameter names.
For example, replace LANGUAGE and startService with ENG and @YOUR_START_SERVICE:
https://YOUR_ANNA_ENVIRONMENT_URL/annachatanonimo.aspx?ENG,@YOUR_START_SERVICEUse the complete URL as the value of ANNA_URL in the HTML sample.
Complete example
Section titled “Complete example”The following example creates a launcher in the lower-right corner of the page. Clicking the launcher opens or closes the chat window.
<!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 AnnA Chat widget appears in the lower-right corner.</p>
<script> (function () { const ANNA_URL = "ANNA_CHAT_URL"; // Replace with a backend-generated URL or the direct URL format described above 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>How it works
Section titled “How it works”ANNA_URLis the AnnA Chat URL that the iframe loads.- The launcher and chat window are created dynamically, so the page only needs the script and a place to include it.
- The chat window is hidden initially with
display: none. - Clicking the launcher toggles the chat window between hidden and visible states.
- The iframe uses the URL from
ANNA_URLand fills the chat window.
Adjusting the dimensions
Section titled “Adjusting the dimensions”Change CHAT_W, CHAT_H, and BTN_SIZE to adjust the chat width, chat height, and launcher size. The min() and clamp() expressions keep the chat and its offsets within the viewport on smaller screens.
Generating the chat URL on the backend
Section titled “Generating the chat URL on the backend”The URL for an anonymous embedded chat should be generated by your backend by calling REST/AnnAChat/Anonymous directly. This endpoint does not require a separate credentials or token request.
Select the tab for your backend language. Each example calls REST/AnnAChat/Anonymous and prints its response, which contains the URL to use as ANNA_CHAT_URL in the client-side example.
using System.Text;
using var http = new HttpClient{ BaseAddress = new Uri("https://YOUR_ANNA_ENVIRONMENT/")};
var result = await http.PostAsync( "REST/AnnAChat/Anonymous", new StringContent( """ { "language": "ENG", "startService": "" } """, Encoding.UTF8, "application/json"));
result.EnsureSuccessStatusCode();
Console.WriteLine(await result.Content.ReadAsStringAsync());import java.net.URI;import java.net.http.HttpClient;import java.net.http.HttpRequest;import java.net.http.HttpResponse;
public class Main { public static void main(String[] args) throws Exception { var httpClient = HttpClient.newHttpClient(); var baseUrl = "https://YOUR_ANNA_ENVIRONMENT/";
var anonymousRequest = HttpRequest.newBuilder() .uri(URI.create(baseUrl + "REST/AnnAChat/Anonymous")) .header("Content-Type", "application/json") .POST(HttpRequest.BodyPublishers.ofString(""" { "language": "ENG", "startService": "" } """)) .build();
var anonymousResponse = httpClient.send( anonymousRequest, HttpResponse.BodyHandlers.ofString());
if (anonymousResponse.statusCode() / 100 != 2) { throw new IllegalStateException( "AnnA Chat request failed: " + anonymousResponse.body()); }
System.out.println(anonymousResponse.body()); }}<?php
function postJson(string $url, array $payload): string{ $headers = ["Content-Type: application/json"];
$curl = curl_init($url); curl_setopt_array($curl, [ CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => $headers, CURLOPT_POSTFIELDS => json_encode($payload, JSON_THROW_ON_ERROR), ]);
$body = curl_exec($curl); if ($body === false) { $error = curl_error($curl); curl_close($curl); throw new RuntimeException($error); }
$statusCode = curl_getinfo($curl, CURLINFO_RESPONSE_CODE); curl_close($curl);
if ($statusCode < 200 || $statusCode >= 300) { throw new RuntimeException("Request failed: " . $body); }
return $body;}
$baseUrl = "https://YOUR_ANNA_ENVIRONMENT/";
$chatResponse = postJson( $baseUrl . "REST/AnnAChat/Anonymous", ["language" => "ENG", "startService" => ""]);
echo $chatResponse . PHP_EOL;This example requires the PHP cURL extension.
import requests
base_url = "https://YOUR_ANNA_ENVIRONMENT/"
chat_response = requests.post( f"{base_url}REST/AnnAChat/Anonymous", json={"language": "ENG", "startService": ""}, timeout=30,)chat_response.raise_for_status()
print(chat_response.text)Install the Requests library before running the example.
The code prints the response from REST/AnnAChat/Anonymous. Use the URL returned in that response as the value of ANNA_CHAT_URL in the client-side embedding example.
The language value in the backend request examples is ENG, which opens the chat in English. Use POR for Brazilian Portuguese or SPA for Spanish. The startService value is empty in the backend request example. When using the direct URL format, the startService parameter must always start with @.