Widget¶
Quick Start¶
Get your agent up and running in three steps.
Step 1 — Create an Agent in Cavuer¶
An agent is an AI profile that manages your channels. You can connect multiple channels to a single agent.
- Sign up at console.cavuer.com
-
On the main page, click "Create Agent", enter a name and select a language model
-
After creating the agent, open its settings and add an instruction — rules for how the agent should interact with customers
Instruction Example
You are a polite support assistant for "MyCompany".
Always address the customer by name.
Only answer questions related to our services.
If you don't know the answer — suggest contacting a live operator.
Choosing a Language Model
Each model differs in speed, accuracy, and cost. For most support tasks, GPT-4 and Claude Haiku models work great. For complex analytical tasks, consider GPT-5, Claude Sonnet, or Claude Opus models.
Step 2 — Connect the Widget Channel¶
Step 3 — Configure the Widget and Start¶
After creating the channel, go to its settings to complete the configuration.
1. Add the Script to Your Website¶
In the "Installation" section, copy the script and paste it into your website's HTML code before the closing </body> tag:
<script src="https://widget.cavuer.com/embed.js" data-token="your_token"></script>
2. Allowed Domains and User Identification¶
In the "Security" section, add the domains from which messages are allowed to be sent in the widget.
You can also enable mandatory user identification (learn more about identification) using the "Secret Key" by toggling the switch in the "Security" section.
Important
If no domains are specified, the widget will not be available.
3. Customize Appearance and Content¶
In the "Settings" section, customize the widget to match your website's style:
Toggle the switch in the "Status" section and click "Save".
Done! The widget will appear on your website, and the AI agent will start automatically responding to visitors.
Advanced Setup¶
Agent Settings in Cavuer Dashboard¶
Configure the agent's behavior at console.cavuer.com:
| Parameter | Description |
|---|---|
| Name | Rename the agent and channel for easier management in the Cavuer dashboard |
| Model | Select a language model |
| Instruction | Agent behavior rules: greeting, company description, operator transfer conditions, language settings. Specify whether the agent should respond in the customer's language or only in a specific language |
| Response Delay | Delay before responding. Useful when customers send multiple messages in a row — the agent will wait and process all messages together |
| Process Images | Allows the agent to view and analyze image content (Currently not available for the Widget channel) |
| Process Audio | Enables the agent to recognize voice messages (Currently not available for the Widget channel) |
| Knowledge Base | Upload .txt, .pdf, or .docx files and connect them in the agent settings |
Full parameter reference: Agent and Channel Setup
Knowledge Base Setup¶
Go to Knowledge Base → click Upload Data → enter the article title and select a file.
Then, in the agent settings, check the box next to the uploaded articles and save your changes. For more details, see Knowledge Base.
Knowledge Base Best Practices
- Use keywords in titles — e.g. "Pricing, cost, payment, plan" instead of just "Pricing"
- Break up large texts — create smaller articles for specific topics (e.g. separate articles for "Delivery", "Payment", "Returns")
- Titles cannot be changed — article content can be updated, but the title remains permanent
- Link to documentation — upload key information and include a link to the full documentation
User Identification¶
By default, each visitor receives a random identifier like v_.... If your website has an authentication system, you can pass your own user identifier to:
- merge conversations from the same user across different browsers and devices into a single chat
- see real user IDs in the Cavuer dashboard instead of random ones
Requirements
Setting up identification requires a server (Node.js, Python, PHP, etc.), as the secret key must be stored server-side and never exposed to the browser.
How It Works¶
- The server computes an HMAC-SHA256 hash of the user identifier using the secret key from the Cavuer dashboard
- The hash is passed to the widget script via the
data-user-idanddata-user-hashattributes - Once a valid hash is received, users will be identified
Setup¶
1. Get the Secret Key¶
In the Cavuer dashboard, go to the Widget channel settings → Security and copy the Secret Key.
2. Compute the Hash on the Server¶
const crypto = require("crypto");
const SECRET_KEY = process.env.CAVUER_SECRET_KEY;
function computeHash(userId) {
return crypto
.createHmac("sha256", SECRET_KEY)
.update(userId)
.digest("hex");
}
// Example: computeHash("john@example.com")
import hmac
import hashlib
import os
SECRET_KEY = os.environ["CAVUER_SECRET_KEY"]
def compute_hash(user_id: str) -> str:
return hmac.new(
SECRET_KEY.encode(),
user_id.encode(),
hashlib.sha256
).hexdigest()
# Example: compute_hash("john@example.com")
$secretKey = getenv('CAVUER_SECRET_KEY');
function computeHash(string $userId): string {
global $secretKey;
return hash_hmac('sha256', $userId, $secretKey);
}
// Example: computeHash("john@example.com")
3. Pass Data to the Widget Script¶
Add the data-user-id and data-user-hash attributes to the widget script:
<script
src="https://widget.cavuer.com/embed.js"
data-token="your_public_token"
data-user-id="john@example.com"
data-user-hash="computed_hash">
</script>
Security
Never include the secret key (Secret Key) in client-side code. The hash must be computed exclusively on the server side.
Behavior Scenarios¶
| Scenario | Result |
|---|---|
data-user-id and a valid data-user-hash are provided | Your user ID is displayed in the chat. Conversations from different browsers are merged |
| No attributes provided (guest) | The user receives a random ID like v_... |
An invalid data-user-hash is provided | The message will not be sent — protection against spoofing |
Test Server¶
You can use a ready-made Node.js test server to verify user identification.
Installing and Running the Test Server
Installation¶
mkdir widget-id-test
cd widget-id-test
npm init -y
npm install express
Create the server.js File¶
const express = require("express");
const crypto = require("crypto");
const app = express();
const PORT = 3000;
// =============================================
// INSERT YOUR VALUES FROM THE CAVUER DASHBOARD
// =============================================
const WIDGET_TOKEN = "wgt_INSERT_PUBLIC_TOKEN";
const SECRET_KEY = "sk_INSERT_SECRET_KEY";
const WIDGET_SCRIPT = "https://widget.cavuer.com/embed.js";
// =============================================
// Test users
// =============================================
const USERS = {
john: { id: "john@example.com", name: "John" },
anna: { id: "anna@example.com", name: "Anna" },
guest: null, // no identification
};
function computeHash(userId) {
return crypto
.createHmac("sha256", SECRET_KEY)
.update(userId)
.digest("hex");
}
// Home page — user selection
app.get("/", (req, res) => {
res.send(`
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Widget Identification Test</title>
<style>
body { font-family: sans-serif; max-width: 600px; margin: 40px auto; }
a { display: block; margin: 10px 0; padding: 12px 20px;
background: #6C47FF; color: white; text-decoration: none;
border-radius: 8px; text-align: center; }
a:hover { background: #5a3ad9; }
.guest { background: #666; }
.guest:hover { background: #555; }
</style>
</head>
<body>
<h1>Widget Identification Test</h1>
<p>Select a user to test:</p>
<a href="/chat/john">John (john@example.com)</a>
<a href="/chat/anna">Anna (anna@example.com)</a>
<a href="/chat/guest" class="guest">Guest (no identification)</a>
</body>
</html>
`);
});
// Chat page for a specific user
app.get("/chat/:userKey", (req, res) => {
const user = USERS[req.params.userKey];
const hash = user ? computeHash(user.id) : null;
const scriptTag = user
? '<script src="' + WIDGET_SCRIPT + '" data-token="' + WIDGET_TOKEN
+ '" data-user-id="' + user.id
+ '" data-user-hash="' + hash + '"></script>'
: '<script src="' + WIDGET_SCRIPT + '" data-token="'
+ WIDGET_TOKEN + '"></script>';
const displayName = user
? user.name + " (" + user.id + ")"
: "Guest (no identification)";
res.send(`
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Chat — ${displayName}</title>
<style>
body { font-family: sans-serif; max-width: 600px; margin: 40px auto; }
.badge { display: inline-block; padding: 6px 14px;
border-radius: 6px; font-size: 14px; margin-bottom: 16px; }
.identified { background: #dcfce7; color: #166534; }
.anonymous { background: #fef3c7; color: #92400e; }
a { color: #6C47FF; }
pre { background: #f1f5f9; padding: 12px; border-radius: 8px;
font-size: 12px; overflow-x: auto; }
</style>
</head>
<body>
<a href="/">← Back to user selection</a>
<h1>${displayName}</h1>
<span class="badge ${user ? "identified" : "anonymous"}">
${user ? "Identified user" : "Anonymous visitor"}
</span>
${user ? `
<h3>Identification data:</h3>
<pre>user-id: ${user.id}\nuser-hash: ${hash}</pre>
` : `
<p>The widget is running in default mode — random visitor ID.</p>
`}
<p>Open the widget in the bottom-right corner and send a message.</p>
${scriptTag}
</body>
</html>
`);
});
app.listen(PORT, () => {
console.log("Test server running: 'test domain':" + PORT);
console.log("Add 'test domain':" + PORT
+ " to the widget's allowed domains in the Cavuer dashboard");
});
Run¶
node server.js
Open the specified domain in your browser.
Need Help?
If you have any questions about setting up the widget or user identification, please contact our support team.





