Drift Chat Event Tracking with Google Tag Manager – Less Code, More Analytics

The market for website chatbots is growing steadily and with it, there have been a lot of entrants since Intercom lead the way. From Hubspot to Whisbi, each has their own take on it. What I found especially impressive is how Drift has opened up the tech side of their platform. This makes it a really fun marketing technology. Building chatbots is a mix of analytical thinking, user experience design, and creativity. On top of that, it is easy to iterate and optimize quickly thanks to the amount of qualitative and quantitative feedback that the chats offer. While I’ve seen the Drift team steadily working on bot flow analytics, I’ll be honest I wouldn’t mind a lot more access to the data that is collected through the bot interactions.

Drift’s Javascript API provides a pretty comprehensive list of chat events to “listen” for (meaning you can trigger Javascript code when a chat event, like a “chat started” happens). With Google Tag Manager, you can send these events to an analytics tool like Google Analytics. You can even send along a bit of event metadata like the Drift inbox ID and conversation ID, so it’s easy to find the Drift conversation at the URL: https://app.drift.com/inboxes/{{inbox ID}}/conversations/{{conversation ID}}

Unfortunately, the API does not provide that actual text of the conversation (for a good reason) but using Google Analytics, you can still collect sidebar and message events and analyze them in aggregate. This can be really helpful in understanding on which URLs users are interacting with bots. From there you can spend your time building an optimizing bots with maximum effect.

Google Tag Manager Data Layer Events

The code at the end of the post registers a callback function for all the following events:

  • drift loaded
  • sidebar opened
  • sidebar closed
  • welcome message opened
  • welcome message closed
  • away message opened
  • away message closed
  • campaign message opened
  • campaign message closed
  • CTA clicked
  • campaign user started a chat or submitted an email
  • slider message closed
  • user started a new chat
  • user replied to a conversation
  • user submitted email address
  • schedule meeting card pushed to a conversation
  • user booked a meeting

Each event will push an object to the dataLayer that looks something like this:

  "driftEventType": "conversation",
  "driftEventName": "message:sent",
  "driftEventDescription": "user replied to a conversation",
  "event": "drift",
  "driftEventData": {
    "data": {
      "sidebarOpen": true,
      "widgetVisible": true,
      "isOnline": true
    "conversationId": XXXXXXXXX,
    "inboxId": XXXXXX
  "gtm.uniqueEventId": XX

That makes it easy to set up GTM Tags to fire on all Drift events based on a trigger with the firing rule: data layer event EQUALS drift You can be more specific about your firing rules by using the codedriftEventTypedriftEventName, or driftEventDescription.

The data layer event values can map directly to Google Analytics event values (driftEventName is good for Event Action and driftEventDescription is good for Event Description) Or, instead of using the driftEventDescription as the Google Analytics event description, you can use the inbox ID or conversation ID as well. You could even set event scoped custom-variable and capture all of it!

Enough talk! Get to the code.

To set up the Drift event listener, you will need to place the following Javascript code in GTM HTML tag between <script> tags. Make sure that the HTML tag is fired after the Drift is initialized so if you are using Google Tag Manager to instantiate Drift, setup your tags sequentially.

var driftEvents = [
  {driftEventType: 'sidebar', driftEventName: 'sidebarOpen', driftEventDescription: 'sidebar opened'},
  {driftEventType: 'sidebar', driftEventName: 'sidebarClose', driftEventDescription: 'sidebar closed'},
  {driftEventType: 'welcome message', driftEventName: 'welcomeMessage:open', driftEventDescription: 'welcome message opened'},
  {driftEventType: 'welcome message', driftEventName: 'welcomeMessage:close', driftEventDescription: 'welcome message closed'},
  {driftEventType: 'away message', driftEventName: 'awayMessage:open', driftEventDescription: 'away message opened'},
  {driftEventType: 'away message', driftEventName: 'awayMessage:close', driftEventDescription: 'away message closed'},
  {driftEventType: 'campaign', driftEventName: 'campaign:open', driftEventDescription: 'campaign message opened'},
  {driftEventType: 'campaign', driftEventName: 'campaign:dismiss', driftEventDescription: 'campaign message closed'},
  {driftEventType: 'campaign', driftEventName: 'campaign:click', driftEventDescription: 'CTA clicked'},
  {driftEventType: 'campaign', driftEventName: 'campaign:submit', driftEventDescription: 'campaign user started a chat or submitted an email'},
  {driftEventType: 'slider message', driftEventName: 'sliderMessage:close', driftEventDescription: 'slider message closed'},
  {driftEventType: 'conversation', driftEventName: 'startConversation', driftEventDescription: 'user started a new chat'},
  {driftEventType: 'conversation', driftEventName: 'message:sent', driftEventDescription: 'user replied to a conversation'},
  {driftEventType: 'conversation', driftEventName: 'message', description : 'user received a message from a team member'},
  {driftEventType: 'conversation', driftEventName: 'emailCapture', driftEventDescription: 'user submitted email address'},
  {driftEventType: 'conversation', driftEventName: 'scheduling:requestMeeting', driftEventDescription: 'schedule meeting card pushed to a conversation'},
  {driftEventType: 'conversation', driftEventName: 'scheduling:meetingBooked', driftEventDescription: 'user booked a meeting'}

drift.on('ready', function (api, payload) {
  dataLayer.push({event: 'drift', driftEventName: 'driftReady', driftEventDescription: 'drift loaded', driftEventData: payload});
  driftEvents.forEach(function (driftEvent) {
    drift.on(driftEvent.driftEventName, function (data) {
      driftEvent.event = 'drift';
      driftEvent.driftEventData = data;

This code might look weird at first glance but notice that instead of writing a code block to tell Drift to register a callback for each event, the code loops through all the events to register the callbacks. Paste it in your browser’s Javascript console (on a page that has Drift loaded) to see it work. When you interact with your Drift bot, you’ll see that events being sent to the data layer. You can also view the code on this Github Gist.

If this seems a bit intimidating today, I’d recommend checking out my open source guide: Digital Marketing Technical Fundamentals on GitHub for guidance on learning the tech side of digital marketing. Good luck!

Leave a Comment

Your email address will not be published. Required fields are marked *