Chat Widget Controls
Explore the available JavaScript APIs for extending and controlling your embedded chatbot widget.
This documentation provides a reference for all JavaScript APIs available to control and extend the functionality of your embedded chatbot widget.
Open Chatbot Window
Programmatically opens the chatbot window, making it visible to users.
window.Chatbot.open();Try running this in your browser console where the chatbot is embedded to see it in action
Additional Instructions
- Ensure the chatbot script is fully loaded before calling this function.
- Note: The
open()function only works with popup style widgets and is not supported for in-page embedded widgets.
Close Chatbot Window
Programmatically closes the chatbot window, hiding it from view.
window.Chatbot.close();Try running this in your browser console where the chatbot is embedded to see it in action
Additional Instructions
- Confirm the chatbot script is loaded before invoking this method.
- Note: The
close()function only works with popup style widgets and is not supported for in-page embedded widgets.
Send Message Programmatically
Programmatically send messages to the chatbot from anywhere in your application. This powerful API enables automated chat flows, button-triggered conversations, and seamless integration with your website's UI.
Enable this feature first: Before using the sendMessage() API, you must
enable "Allow Programmatic Messages" in your widget configuration. Go to your
Widget Settings → Customize → Advanced tab and toggle on the "Allow
Programmatic Messages" switch. This feature is disabled by default for
security reasons.
// Send a simple message (auto-opens popup widget by default)
window.Chatbot.sendMessage("Hello! I need help.");
// Send a message with metadata for tracking
window.Chatbot.sendMessage("What are your pricing options?", {
metadata: {
source: "pricing-button",
userId: "12345",
page: window.location.pathname,
},
});
// Send a message without auto-opening the popup widget
window.Chatbot.sendMessage("Background task completed", {
metadata: {
source: "background-process",
},
canAutoOpen: false,
});Parameters:
message(string, required): The text message to send to the chatbotoptions(object, optional): Configuration object with the following properties:metadata(object, optional): Additional metadata to include with the messagecanAutoOpen(boolean, optional, default:true): Whether to automatically open the popup widget if it's closed
Behavior:
- Popup Widget: The widget automatically opens by default when sending a message. If
canAutoOpenis set tofalse, the message will be dispatched but the widget won't auto-open - In-Page Widget: The
canAutoOpenparameter has no effect (widget is always visible) - The message is sent through the normal chat flow as if the user typed it
- Metadata is merged with the widget's existing metadata and sent to your backend
Real-World Use Cases
Important: The
sendMessage()function sends messages as the user, not as bot responses. The message will appear in the chat as if the user typed it themselves and will be sent to your backend for processing.
1. Button-Triggered Chat Interactions
Allow users to ask specific questions by clicking buttons on your website:
<button
onclick="window.Chatbot.sendMessage('What are your pricing options?', { metadata: { source: 'pricing-button' } })"
>
Ask about Pricing
</button>
<button
onclick="window.Chatbot.sendMessage('I need technical support', { metadata: { source: 'support-button' } })"
>
Get Technical Support
</button>2. Form Integration
Send form data directly to the chatbot for processing:
document.getElementById("contactForm").addEventListener("submit", function (e) {
e.preventDefault();
const question = document.getElementById("questionInput").value;
window.Chatbot.sendMessage(question, {
metadata: {
source: "contact-form",
topic: document.getElementById("topicSelect").value,
submittedAt: new Date().toISOString(),
},
canAutoOpen: true, // Auto-open for user-initiated form submission
});
this.reset();
});3. URL Parameter Handling
Automatically start conversations based on URL parameters:
window.addEventListener("DOMContentLoaded", function () {
const urlParams = new URLSearchParams(window.location.search);
const question = urlParams.get("question");
if (question) {
setTimeout(() => {
window.Chatbot.sendMessage(decodeURIComponent(question), {
metadata: {
source: "url-parameter",
referrer: document.referrer,
},
});
}, 1000);
}
});
// Example URL: https://yoursite.com?question=How%20do%20I%20reset%20my%20password4. First-Time Visitor Auto-Question
Automatically start a conversation for first-time visitors (sends as user message):
window.myChatCallbacks = {
onWidgetOpen: function (data) {
const hasVisited = localStorage.getItem("chat_visited");
if (!hasVisited && data.openMethod === "user_click") {
setTimeout(() => {
// Auto-send a common first question to get the conversation started
window.Chatbot.sendMessage("Hi! Can you tell me what you offer?", {
metadata: {
source: "first-visit-auto-question",
isFirstVisit: true,
},
canAutoOpen: false, // Widget already open, no need to auto-open
});
}, 1000);
localStorage.setItem("chat_visited", "true");
}
},
};Advanced: Proactive User Assistance
The real power of sendMessage() comes from combining it with event callbacks to create proactive, helpful user experiences. Here are practical scenarios focused on enhancing user engagement:
1. Smart Inactivity & Time-Based Help
Detect when users are inactive or spending significant time on important pages without taking action, then proactively offer assistance:
let inactivityTimer = null;
let pageTimer = null;
let helpOffered = false;
// Track user activity and inactivity
function resetInactivityTimer() {
clearTimeout(inactivityTimer);
// Offer help after 30 seconds of inactivity
if (!helpOffered) {
inactivityTimer = setTimeout(() => {
window.Chatbot.open();
setTimeout(() => {
window.Chatbot.sendMessage("Do you need any help?", {
metadata: {
source: "inactivity-detection",
inactiveSeconds: 30,
page: window.location.pathname,
},
canAutoOpen: false,
});
helpOffered = true;
}, 500);
}, 30000); // 30 seconds
}
}
// Track time spent on high-intent pages
window.addEventListener("DOMContentLoaded", function () {
const currentPage = window.location.pathname;
// For important pages like pricing/features, offer help after 2 minutes
if (currentPage.includes("/pricing") || currentPage.includes("/features")) {
pageTimer = setTimeout(() => {
if (!helpOffered) {
window.Chatbot.open();
setTimeout(() => {
const pageType = currentPage.includes("/pricing")
? "pricing"
: "features";
window.Chatbot.sendMessage(
`I noticed you're checking out our ${pageType}. Can I help you find the right plan?`,
{
metadata: {
source: "time-spent-trigger",
page: currentPage,
timeSpent: 120,
},
canAutoOpen: false,
},
);
helpOffered = true;
}, 500);
}
}, 120000); // 2 minutes
}
// Track user interactions to reset inactivity timer
document.addEventListener("mousemove", resetInactivityTimer);
document.addEventListener("click", resetInactivityTimer);
document.addEventListener("scroll", resetInactivityTimer);
document.addEventListener("keypress", resetInactivityTimer);
resetInactivityTimer();
});
// Reset when chat is used
window.myChatCallbacks = {
onWidgetOpen: function () {
helpOffered = true;
},
onChatClear: function () {
helpOffered = false;
resetInactivityTimer();
},
};2. Page-Specific Help Suggestions
Automatically suggest relevant help based on which page the user is viewing:
window.myChatCallbacks = {
onWidgetOpen: function (data) {
const currentPage = window.location.pathname;
const pageVisitKey = `chat_offered_${currentPage}`;
const hasOfferedHelp = sessionStorage.getItem(pageVisitKey);
// Only offer help once per page per session
if (!hasOfferedHelp && data.openMethod === "user_click") {
let helpMessage = "";
const metadata = { source: "page-specific-help", page: currentPage };
if (currentPage.includes("/pricing")) {
helpMessage = "I'd like to know more about your pricing";
metadata.context = "pricing-page";
} else if (currentPage.includes("/docs")) {
helpMessage = "I need help understanding the documentation";
metadata.context = "docs-page";
} else if (currentPage.includes("/checkout")) {
helpMessage = "I have a question about checkout";
metadata.context = "checkout-page";
}
if (helpMessage) {
setTimeout(() => {
window.Chatbot.sendMessage(helpMessage, {
metadata: metadata,
canAutoOpen: false,
});
}, 800);
sessionStorage.setItem(pageVisitKey, "true");
}
}
},
};3. Form Submission to Chat
Convert form data into a single chat message for seamless handoff:
// Handle form submission via chat
document
.getElementById("contactForm")
?.addEventListener("submit", function (e) {
e.preventDefault();
// Gather form data
const name = e.target.name.value;
const company = e.target.company.value;
const email = e.target.email.value;
const interest = e.target.interest.value;
// Combine into a natural message
const message = `Hi! My name is ${name} from ${company}. I'm interested in ${interest}. You can reach me at ${email}.`;
// Open chat and send the message
window.Chatbot.open();
setTimeout(() => {
window.Chatbot.sendMessage(message, {
metadata: {
source: "contact-form",
formData: {
name: name,
company: company,
email: email,
interest: interest,
},
},
});
}, 500);
// Clear the form
this.reset();
});4. Business Hours Awareness
Notify users when they visit outside business hours and set proper expectations:
// Check if current time is within business hours
function isBusinessHours() {
const now = new Date();
const day = now.getDay(); // 0 = Sunday, 6 = Saturday
const hour = now.getHours();
// Monday-Friday, 9 AM - 5 PM
const isWeekday = day >= 1 && day <= 5;
const isDuringHours = hour >= 9 && hour < 17;
return isWeekday && isDuringHours;
}
window.myChatCallbacks = {
onWidgetOpen: function (data) {
const notifiedKey = "business_hours_notified";
const hasNotified = sessionStorage.getItem(notifiedKey);
// Only notify once per session if outside business hours
if (
!isBusinessHours() &&
!hasNotified &&
data.openMethod === "user_click"
) {
setTimeout(() => {
window.Chatbot.sendMessage(
"We're currently offline, but feel free to leave a message and we'll get back to you during business hours (Mon-Fri, 9 AM - 5 PM).",
{
metadata: {
source: "business-hours-notification",
isBusinessHours: false,
timestamp: new Date().toISOString(),
},
canAutoOpen: false,
},
);
sessionStorage.setItem(notifiedKey, "true");
}, 800);
}
},
};5. E-Commerce: Checkout Page Assistance
Detect when users hesitate on the checkout page and offer help (useful for e-commerce):
let checkoutTimer = null;
let checkoutHelpOffered = false;
window.addEventListener("DOMContentLoaded", function () {
const currentPage = window.location.pathname;
// Detect if user is on checkout page
if (currentPage.includes("/checkout") || currentPage.includes("/cart")) {
checkoutTimer = setTimeout(() => {
if (!checkoutHelpOffered) {
window.Chatbot.open();
setTimeout(() => {
window.Chatbot.sendMessage(
"I noticed you're at checkout. Do you have any questions about shipping, payment, or our return policy?",
{
metadata: {
source: "checkout-assistance",
page: currentPage,
timeSpent: 120,
context: "checkout-hesitation",
},
canAutoOpen: false,
},
);
checkoutHelpOffered = true;
}, 500);
}
}, 120000); // 2 minutes on checkout page
}
});
window.myChatCallbacks = {
onWidgetOpen: function () {
checkoutHelpOffered = true;
},
onChatClear: function () {
checkoutHelpOffered = false;
},
};Note: These are just a few examples of what's possible with
sendMessage(). The use cases are virtually limitless - you can adapt these patterns to fit your specific business needs, whether it's cart abandonment detection, product comparison help, or any other scenario where proactive assistance would benefit your users.
Best Practices
- Ensure the chatbot script is fully loaded before calling
window.Chatbot.sendMessage() - Use
canAutoOpen: truefor user-initiated actions (button clicks, form submissions) - Use
canAutoOpen: falsewhen the widget is already open or for background processes - Include metadata to track the source and context of automated messages
- Add delays (setTimeout) to make automated messages feel natural
- Always use flags or counters to prevent sending the same message multiple times
- Focus on user helpfulness - offer assistance when users might need it, not to spam them
- See the Event Callbacks documentation for more advanced integration options
Update Theme Dynamically
Dynamically update any theme property of the chat widget after initialization, without requiring a full re-initialization or page refresh. This enables real-time theme customization, context-based styling, and dynamic localization.
// Update the chat window title
window.Chatbot.updateTheme({
chatWindow: {
title: "Live Chat Support",
},
});Why Use updateTheme()?
- No Re-initialization Required - Update themes on the fly without losing chat state
- Seamless User Experience - Changes apply instantly without disrupting conversations
- Dynamic Customization - Adapt appearance based on user preferences, time of day, page context, etc.
- Fine-Grained Control - Update specific nested properties without affecting others
- Simple API - Single function call with intuitive structure
Parameters
- theme (object, required): A partial theme object containing the properties to update
- Can include any valid theme properties from the original initialization
- Supports deeply nested properties
- Only specified properties are updated; others remain unchanged
Common Use Cases
1. Context-Based Theme Updates
Automatically adapt the widget's appearance based on which page the user is viewing:
function updateThemeForPage(pageName) {
const themes = {
sales: {
chatWindow: {
title: "💼 Sales Team",
welcomeMessage:
"Hi! Interested in our products? Let me help you find the perfect solution.",
starterPrompts: [
"Request a demo",
"Compare pricing plans",
"Contact sales team",
"View customer testimonials",
],
},
button: {
backgroundColor: "#28a745",
},
},
support: {
chatWindow: {
title: "🛠️ Technical Support",
welcomeMessage:
"Having technical issues? I'm here to help troubleshoot and resolve them.",
starterPrompts: [
"Report a bug",
"Request a feature",
"Browse documentation",
"Check system status",
],
},
button: {
backgroundColor: "#007bff",
},
},
billing: {
chatWindow: {
title: "💳 Billing Support",
welcomeMessage:
"Need help with billing or payments? I can assist with invoices, subscriptions, and more.",
starterPrompts: [
"View my invoices",
"Update payment method",
"Cancel subscription",
"Request a refund",
],
},
button: {
backgroundColor: "#ffc107",
},
},
};
if (themes[pageName]) {
window.Chatbot.updateTheme(themes[pageName]);
}
}
// Detect page changes and update theme accordingly
window.addEventListener("DOMContentLoaded", function () {
const path = window.location.pathname;
if (path.includes("/sales") || path.includes("/pricing")) {
updateThemeForPage("sales");
} else if (path.includes("/support") || path.includes("/docs")) {
updateThemeForPage("support");
} else if (path.includes("/billing") || path.includes("/account")) {
updateThemeForPage("billing");
}
});2. Dynamic Localization
Switch the widget's language and messages based on user preferences:
function switchLanguage(lang) {
const translations = {
en: {
chatWindow: {
title: "Customer Support",
welcomeMessage: "Hello! How can we help you today?",
errorMessage: "Sorry, something went wrong. Please try again.",
starterPrompts: [
"What are your hours?",
"How do I return an item?",
"Track my order",
"Contact support",
],
textInput: {
placeholder: "Type your message...",
maxCharsWarningMessage: "Message is too long",
},
},
},
es: {
chatWindow: {
title: "Soporte al Cliente",
welcomeMessage: "¡Hola! ¿Cómo podemos ayudarte hoy?",
errorMessage:
"Lo sentimos, algo salió mal. Por favor, inténtalo de nuevo.",
starterPrompts: [
"¿Cuál es tu horario?",
"¿Cómo devuelvo un artículo?",
"Rastrear mi pedido",
"Contactar soporte",
],
textInput: {
placeholder: "Escribe tu mensaje...",
maxCharsWarningMessage: "El mensaje es demasiado largo",
},
},
},
fr: {
chatWindow: {
title: "Support Client",
welcomeMessage: "Bonjour! Comment pouvons-nous vous aider aujourd'hui?",
errorMessage:
"Désolé, quelque chose s'est mal passé. Veuillez réessayer.",
starterPrompts: [
"Quelles sont vos heures?",
"Comment retourner un article?",
"Suivre ma commande",
"Contacter le support",
],
textInput: {
placeholder: "Tapez votre message...",
maxCharsWarningMessage: "Le message est trop long",
},
},
},
de: {
chatWindow: {
title: "Kundensupport",
welcomeMessage: "Hallo! Wie können wir Ihnen heute helfen?",
errorMessage:
"Entschuldigung, etwas ist schief gelaufen. Bitte versuchen Sie es erneut.",
starterPrompts: [
"Was sind Ihre Öffnungszeiten?",
"Wie sende ich einen Artikel zurück?",
"Meine Bestellung verfolgen",
"Support kontaktieren",
],
textInput: {
placeholder: "Geben Sie Ihre Nachricht ein...",
maxCharsWarningMessage: "Nachricht ist zu lang",
},
},
},
};
if (translations[lang]) {
window.Chatbot.updateTheme(translations[lang]);
localStorage.setItem("chatLanguage", lang);
}
}
// Language selector
document
.getElementById("languageSelect")
?.addEventListener("change", function (e) {
switchLanguage(e.target.value);
});
// Auto-detect browser language on load
window.addEventListener("DOMContentLoaded", function () {
const savedLang = localStorage.getItem("chatLanguage");
const browserLang = navigator.language.split("-")[0]; // 'en-US' -> 'en'
const lang = savedLang || browserLang || "en";
if (["en", "es", "fr", "de"].includes(lang)) {
switchLanguage(lang);
}
});3. Time-Based Theme Switching
Automatically switch between day and night themes based on the time of day:
function applyTimeBasedTheme() {
const hour = new Date().getHours();
const isNightTime = hour >= 20 || hour < 6; // 8 PM to 6 AM
if (isNightTime) {
window.Chatbot.updateTheme({
chatWindow: {
backgroundColor: "#1a1a2e",
title: "🌙 Support (Night Mode)",
textInput: {
backgroundColor: "#16213e",
textColor: "#eef1f8",
},
botMessage: {
backgroundColor: "#0f3460",
textColor: "#eef1f8",
},
userMessage: {
backgroundColor: "#e94560",
textColor: "#ffffff",
},
},
button: {
backgroundColor: "#533483",
},
});
} else {
window.Chatbot.updateTheme({
chatWindow: {
backgroundColor: "#ffffff",
title: "☀️ Support",
textInput: {
backgroundColor: "#f8f9fa",
textColor: "#212529",
},
botMessage: {
backgroundColor: "#e9ecef",
textColor: "#212529",
},
userMessage: {
backgroundColor: "#3B81F6",
textColor: "#ffffff",
},
},
button: {
backgroundColor: "#3B81F6",
},
});
}
}
// Apply theme on page load
window.addEventListener("DOMContentLoaded", applyTimeBasedTheme);
// Check every hour if theme needs to change
setInterval(applyTimeBasedTheme, 3600000); // 1 hour4. Dynamic Starter Prompts Based on User Behavior
Update starter prompts based on user actions or browsing history:
// Track user behavior
const userBehavior = {
viewedPricing: false,
viewedDocs: false,
viewedAbout: false,
timeOnSite: 0,
};
// Update behavior tracking
if (window.location.pathname.includes("/pricing")) {
userBehavior.viewedPricing = true;
}
if (window.location.pathname.includes("/docs")) {
userBehavior.viewedDocs = true;
}
if (window.location.pathname.includes("/about")) {
userBehavior.viewedAbout = true;
}
// Update starter prompts based on behavior when widget opens
window.myChatCallbacks = {
onWidgetOpen: function () {
let prompts = [];
if (userBehavior.viewedPricing) {
prompts = [
"Compare pricing plans",
"Is there a free trial?",
"What payment methods do you accept?",
"Can I cancel anytime?",
];
} else if (userBehavior.viewedDocs) {
prompts = [
"Help me get started",
"Explain this feature",
"Show me examples",
"Troubleshooting guide",
];
} else {
prompts = [
"What does your product do?",
"See a demo",
"View pricing",
"Talk to sales",
];
}
window.Chatbot.updateTheme({
chatWindow: {
starterPrompts: prompts,
},
});
},
};5. Combining with Event Callbacks
You can use updateTheme() inside event callbacks to automatically adjust the widget's appearance based on user interactions. This works with all available callbacks like onWidgetOpen, onResponseReceived, onError, beforeSubmit, etc.
Example: Update starter prompts when widget opens based on current page:
window.myChatCallbacks = {
onWidgetOpen: function (data) {
const currentPage = window.location.pathname;
// Update theme based on which page user is on
if (currentPage.includes("/pricing")) {
window.Chatbot.updateTheme({
chatWindow: {
title: "Sales Support",
starterPrompts: [
"Compare pricing plans",
"Is there a free trial?",
"Schedule a demo",
],
},
button: {
backgroundColor: "#28a745",
},
});
} else if (currentPage.includes("/docs")) {
window.Chatbot.updateTheme({
chatWindow: {
title: "Technical Support",
starterPrompts: [
"Getting started guide",
"API documentation",
"Report an issue",
],
},
button: {
backgroundColor: "#007bff",
},
});
}
},
};See the Event Callbacks documentation for a complete list of available callbacks and their use cases.
Complete Theme Structure Reference
The following properties can be updated via updateTheme(). You can update any combination of these properties - only the specified ones will change:
{
// Chat window configuration
chatWindow: {
// Display settings
showTitle: boolean,
title: string,
titleAvatarSrc: string,
avatarSize: number,
welcomeMessage: string,
errorMessage: string,
// Appearance
backgroundColor: string,
height: number,
width: number,
fontSize: number,
borderRadiusStyle: 'rounded' | 'none',
avatarBorderRadius: number,
messageBorderRadius: number,
showScrollbar: boolean,
// Starter prompts
starterPrompts: string[],
starterPromptFontSize: number,
// Behavior settings
renderHTML: boolean,
clearChatOnReload: boolean,
// Text input configuration
textInput: {
backgroundColor: string,
textColor: string,
placeholder: string,
sendButtonColor: string,
maxChars: number,
maxCharsWarningMessage: string,
autoFocus: boolean,
borderRadius: number,
sendButtonBorderRadius: number
},
// Bot message styling
botMessage: {
backgroundColor: string,
textColor: string,
showAvatar: boolean,
avatarSrc: string,
showCopyToClipboardIcon: boolean
},
// User message styling
userMessage: {
backgroundColor: string,
textColor: string,
showAvatar: boolean,
avatarSrc: string
},
// File uploads
uploadsConfig: {
enabled: boolean,
acceptFileTypes: string[],
maxSizeInMB: number,
maxFiles: number
},
// Voice input
voiceInputConfig: {
enabled: boolean,
maxRecordingTime: number,
recordingNotSupportedMessage: string,
microphoneAccessErrorMessage: string
}
},
// Chat button configuration
button: {
size: 'small' | 'medium' | 'large' | number,
backgroundColor: string,
iconColor: string,
customIconSrc: string,
customIconSize: number,
customIconBorderRadius: number,
bottom: number,
right: number,
borderRadius: 'circle' | 'rounded' | 'none',
autoWindowOpen: {
autoOpen: boolean,
openDelay: number
}
},
// Tooltip configuration
tooltip: {
showTooltip: boolean,
tooltipMessage: string,
tooltipBackgroundColor: string,
tooltipTextColor: string,
tooltipFontSize: number,
hideTooltipOnMobile: boolean
}
}Best Practices
- Update only what's needed - Don't send the entire theme object if only changing one property:
// ✅ Good - Only update what changed
window.Chatbot.updateTheme({
chatWindow: { title: "New Title" },
});
// ❌ Unnecessary - Sending unchanged properties
window.Chatbot.updateTheme({
chatWindow: {
title: "New Title",
backgroundColor: "#ffffff",
fontSize: 14,
// ... 50 more unchanged properties
},
});- Batch related updates - Combine related changes in a single call:
// ✅ Good - Single call with related changes
window.Chatbot.updateTheme({
chatWindow: {
title: "Dark Mode Support",
backgroundColor: "#1a1a1a",
textInput: {
backgroundColor: "#2a2a2a",
textColor: "#ffffff",
},
},
button: {
backgroundColor: "#404040",
},
});
// ❌ Inefficient - Multiple separate calls
window.Chatbot.updateTheme({ chatWindow: { title: "Dark Mode Support" } });
window.Chatbot.updateTheme({ chatWindow: { backgroundColor: "#1a1a1a" } });
window.Chatbot.updateTheme({
chatWindow: { textInput: { backgroundColor: "#2a2a2a" } },
});- Provide fallbacks - Always have default values in your initial configuration:
// Initialize with sensible defaults
Chatbot.init({
n8nChatUrl: "https://your-webhook-url.com",
theme: {
chatWindow: {
title: "Support Chat", // Fallback if updateTheme fails
backgroundColor: "#ffffff",
fontSize: 14,
},
},
});
// Later updates won't break if some properties are missing
window.Chatbot.updateTheme({
chatWindow: { title: "Live Support" },
});Summary
open()- Opens the popup chatbot widget (popup mode only)close()- Closes the popup chatbot widget (popup mode only)sendMessage()- Programmatically send messages with optional metadata and auto-open controlupdateTheme()- Dynamically update any theme property without re-initialization or losing chat state- Each API provides fine-grained control over your chatbot widget's behavior
- Use these APIs to build an interactive, customizable chatbot experience tailored to your website's needs