Chatbot Analytics
This document covers the analytics events emitted by the chatbot script and how to consume them in your own tracking setup, for example Google Tag Manager.
Prerequisites
The chatbot script must be loaded on the page:
<script src="https://scripts.dialogintelligens.dk/universal-chatbot.js?id=YOUR_CHATBOT_ID"></script>No additional scripts or configuration are needed. Analytics events are emitted automatically.
How It Works
The chatbot dispatches CustomEvents on the global window object whenever key interactions
occur. These events are intentionally decoupled from any specific analytics platform, so you keep
full control over how to forward and map the data.
Available Events
| Event Name | Fired When | Extra Detail Fields |
|---|---|---|
chat_open | The user opens the chat window | None |
chat_response | The chatbot returns a response | response_latency_ms |
chat_recommendation | The chatbot returns product recommendations | None |
chat_product_click | The user clicks a product link in the chat | None |
chat_conversation_classified | The conversation is classified after a response | classification |
All events include chat_type: "shopping_assistant" in their detail payload.
Listening to Events
window.addEventListener("chat_open", (e) => {
console.log("Chat opened", e.detail);
});
window.addEventListener("chat_response", (e) => {
console.log("Response latency:", e.detail.response_latency_ms, "ms");
});
window.addEventListener("chat_recommendation", (e) => {
console.log("Recommendation shown", e.detail);
});
window.addEventListener("chat_product_click", (e) => {
console.log("Product clicked", e.detail);
});
window.addEventListener("chat_conversation_classified", (e) => {
console.log("Classification:", e.detail.classification);
});Google Tag Manager Integration
Push events into the GTM dataLayer by listening to the chatbot events and mapping them:
<script>
window.addEventListener("chat_open", function () {
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
event: "chat_open",
chat_type: "shopping_assistant",
});
});
window.addEventListener("chat_response", function (e) {
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
event: "chat_response",
chat_type: "shopping_assistant",
response_latency_ms: e.detail.response_latency_ms,
});
});
window.addEventListener("chat_recommendation", function () {
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
event: "chat_recommendation",
chat_type: "shopping_assistant",
});
});
window.addEventListener("chat_product_click", function () {
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
event: "chat_product_click",
chat_type: "shopping_assistant",
});
});
window.addEventListener("chat_conversation_classified", function (e) {
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
event: "chat_conversation_classified",
chat_type: "shopping_assistant",
classification: e.detail.classification,
});
});
</script>Then create corresponding triggers in GTM using Custom Event with the event names above.
Event Detail Payloads
Every event carries a detail object accessible via e.detail:
chat_open
{ "chat_type": "shopping_assistant" }chat_response
{ "chat_type": "shopping_assistant", "response_latency_ms": 1234 }chat_recommendation
{ "chat_type": "shopping_assistant" }chat_product_click
{ "chat_type": "shopping_assistant" }chat_conversation_classified
{ "chat_type": "shopping_assistant", "classification": "Produktinformation" }postMessage from Chatbot Iframe
The chatbot iframe sends postMessage events to the parent window. You can listen to these
instead of, or in addition to, the CustomEvents above. Use this when you need raw access to
iframe messages or when the chatbot script is not loaded on your page.
Origin: https://chatbot.dialogintelligens.dk (or http://localhost:3002 in development)
Payload format: Each message has an action field. Some actions include extra fields.
| Action | Extra Fields | When |
|---|---|---|
productClick | None | User clicks a product in the chat |
navigate | url | Parent should navigate to product URL |
userMessageSubmitted | None | User submitted a message |
firstMessageSent | chatbotID | User sent their first message |
assistantFirstToken | None | First token of AI response arrived |
productRecommendation | None | Product recommendations shown |
conversationClassified | emne | Conversation classified by AI |
purchaseReported | chatbotID, totalPrice, currency | User reported a purchase |
expandChat | None | Chat expanded |
collapseChat | None | Chat collapsed |
closeChat | None | Chat closed |
toggleSize | None | User toggled chat size |
const CHATBOT_ORIGIN = "https://chatbot.dialogintelligens.dk";
window.addEventListener("message", (event) => {
if (event.origin !== CHATBOT_ORIGIN) return;
const data = event.data ?? {};
if (data.action !== "productClick") return;
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
event: "chat_product_click",
chat_type: "shopping_assistant",
});
});Mapping to CustomEvents: The chatbot script on the parent translates some postMessage actions
into CustomEvents. If the script is loaded, you get both the raw postMessage and the
CustomEvent. Actions that map to CustomEvents:
productClick -> chat_product_click,
assistantFirstToken -> chat_response,
productRecommendation -> chat_recommendation,
conversationClassified -> chat_conversation_classified.
Notes
- Events are dispatched automatically. No initialization or opt-in is required.
- The
response_latency_msvalue is the round-trip time in milliseconds from when the user sends a message until the chatbot response arrives. - The
chat_conversation_classifiedevent fires a few seconds after each response, once the backend finishes classifying the conversation. Theclassificationvalue is the topic or category assigned by the AI, for example"Ordre","Produktinformation", or"Reklamation", ornullif classification failed. - The implementation is decoupled from GTM on purpose. You are responsible for listening, mapping, and pushing data to your analytics platform.
- Events are standard
CustomEvents, so they work with any analytics tool that can listen to DOM events.