Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

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 NameFired WhenExtra Detail Fields
chat_openThe user opens the chat windowNone
chat_responseThe chatbot returns a responseresponse_latency_ms
chat_recommendationThe chatbot returns product recommendationsNone
chat_product_clickThe user clicks a product link in the chatNone
chat_conversation_classifiedThe conversation is classified after a responseclassification

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.

ActionExtra FieldsWhen
productClickNoneUser clicks a product in the chat
navigateurlParent should navigate to product URL
userMessageSubmittedNoneUser submitted a message
firstMessageSentchatbotIDUser sent their first message
assistantFirstTokenNoneFirst token of AI response arrived
productRecommendationNoneProduct recommendations shown
conversationClassifiedemneConversation classified by AI
purchaseReportedchatbotID, totalPrice, currencyUser reported a purchase
expandChatNoneChat expanded
collapseChatNoneChat collapsed
closeChatNoneChat closed
toggleSizeNoneUser toggled chat size
Example listener:
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_ms value is the round-trip time in milliseconds from when the user sends a message until the chatbot response arrives.
  • The chat_conversation_classified event fires a few seconds after each response, once the backend finishes classifying the conversation. The classification value is the topic or category assigned by the AI, for example "Ordre", "Produktinformation", or "Reklamation", or null if 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.