Sending Google Analytics/GTM Events

The Google Analytics Platform lets you measure user interactions with your business across various devices and environments. Google Analytics provides the resources to collect, store, process, and report on these user-interactions.

You can collect analytics on the client side and on the server side.

Client-side analytics collection

You can use the Web Tracking (analytics.js) library to measure how users interact on your website. You can view user-interaction data in the Google Analytics user interface or use the Reporting APIs to fetch the data.

Sending widget events to Google Analytics

You can subscribe to the widget events, to send widget event data to Google Analytics. For example, if you want to send to Google Analytics when the widget was opened, you could use:

window.web1on1.on('widget:opened', function() {
    gtag('event', 'widget:opened');
});

gtag() is a function created by Google Analytics, as loaded on your website. You can use it to communicate with Google Analytics.

Using Google Tag Manager

Talking to the Google Tag Manager can be done with the dataLayer.push() function

window.web1on1.on('widget:opened', function() {
    dataLayer.push({ event: 'widget:opened'});
});

dataLayer.push() is a function created by Google Tag Manager on your website that is used to communicate with it.

Sending the conversation, contact and/or organization id to Google Analytics

The moment a new anonymous client sends a message to our system a conversation is created. When an Agent or a bot answers for the first time, the conversation, contact and organisation id are send to the widget. These properties can be then be send on to Google Analytics like this:.

// The moment a message is received from an agent or bot
window.web1on1.on('message:received', function(message, data) {
    if (message.metadata.conversation) {
        dataLayer.push({
            event: 'message:received',
            conversation: message.metadata.conversation,
            contact: message.metadata.contact,
            organization: message.metadata.organization,
        });
    }
});

// The moment a message is send by the contact
window.web1on1.on('message:sent', function(message) {
    var meta =  window.web1on1.getUser().properties;
    if (meta.conversation) {
        dataLayer.push({
            event: 'message:sent',
            conversation: meta.conversation,
            contact: meta.contact,
            organization: meta.organization,
        });
    }
});

Server-side analytics collection

You can use Google Analytics to track specific server-side webhook events, and take advantage of the rich user interface that Google Analytics provides to visualize, report, and export these server-side events.

You may want to re-use the same gaTrackingID and gaClientID you are using from the frontend, to be able to connect activities of Bots in Web1on1 to the same GA client.

We can record the gaClientID, gaTrackingID and optional gaUserID fields in the contact record as meta variables. We do this by passing them from the live chat widget to the Web1on1 backend using the updateUser() function.

Store GA properties as contact.meta data (on widget event)

The Google Analytics fields have to be added to the current visitor record, by calling the updateUser() function. Add the following code to the web pages where the widget is installed:

(function() {
    window.addEventListener('load', function () {
        window.web1on1.on('widget:opened', function() {
            gtag('get', 'G-XXXXXXX', 'client_id', function (gaClientId) {
                window.web1on1.updateUser({
                    properties: {
                        gaClientId: gaClientId,
                        gaTrackingId: 'G-XXXXXXX', // @TODO your tracker id here
                        //gaUserID: '12345', // optional, for logged-in users
                    }
                });
            });
        });
    })
})();

This will record the gaClientID, gaTrackingID and (outcommented, optional) gaUserID in contact.meta. Caveat: the updateUser() call will take effect (in our backend) on the first contact message.

To make it work in Google Tag Manager write the second script tag as explained here.

Store GA properties as contact.meta data (on load)

To store GA data immediately when loading the widget, we can use the callback attribute on the loading script to get any Google Analytics data and store it in the user profile as contact.meta.

<script>
    // wait for Google Analitics And Web1on1 until it is loaded
    // ampApi is passed by Web1on1 when it is loaded.
    //it will try to connect for 15 seconds before giving up
    window.ampLoaded = function(ampAPI, retries = 15) {
        if (
            window.gtag && typeof gtag === 'function'
            && window.web1on1 && window.web1on1.updateUser && typeof window.web1on1.updateUser === 'function'
        ) {
        
            gtag('get', 'G-XXXXXXX', 'client_id', function (gaClientId) {
                console.log('ampLoaded: updating gaClientId', gaClientId);
                window.web1on1.updateUser({
                    properties: {
                        gaClientId: gaClientId
                    }
                });
            });
        } else {
            if (retries > 0) {
                console.log('ampLoaded: Still trying to find analytics and amp');
                setTimeout(function() { window.ampLoaded(ampAPI, retries - 1) }, 1000);
            } else {
                console.log('ampLoaded: no analitics found.');
            }
        }
    }
</script>
<script defer
    src="https://cdn.web1on1.chat/widget/bundle.min.js"
    data-web1on1-appid="<your appid should be pasted here>"
    data-web1on1-callback='ampLoaded'>
</script>

Pass server-side events to Google Analytics

To enable server-side analytics collection, you can implement a webhook handler that subscribes to webhook events, and makes HTTP requests using the Google Analytics Measurement Protocol.

Listen to the contact.update webhook event to process contact data changes. An example on how to listen to a Web1on1 event in your code can be found here.

Listen to the message.create.contact.results webhook event to pass lead results to Google Analytics. Here's an example when using the NodeJS SDK:

const express = require('express');
const bodyParser = require('body-parser');
const fetch = require('node-fetch');

const app = express();
app.enable('trust proxy');

const trackEvent = (trackingId, clientId, category, action, label, value) => {
  const data = {
    // API Version.
    v: '1',
    // Tracking ID / Property ID.
    tid: trackingId,
    // Anonymous Client Identifier. Ideally, this should be a UUID that
    // is associated with particular user, device, or browser instance.
    cid: clientId,
    // Event hit type.
    t: 'event',
    // Event category.
    ec: category,
    // Event action.
    ea: action,
    // Event label.
    el: label,
    // Event value.
    ev: value,
  };

  return fetch('https://www.google-analytics.com/collect', {
    params: data,
  });
};

app.get('/webhook', (req, res) => {
    if (req.query.type === 'subscribe' && req.query.challenge) {
        res.status(200).send(req.query.challenge);
    } else {
        res.status(403).end();
    }
});

app.post('/webhook', bodyParser.json());

app.post('/webhook', async (req, res, next) => {
    if (req.body.event === 'message.create.contact.results') {
        try {
            const { trackingId, clientId } = req.body.data.contact.meta;
            const action = req.body.results.find(r => r.type === 'topic').name;
            await trackEvent(
              trackingId,
              clientId,
              'Lead Result',
              action,
              'hot lead',
              '100'
            );
            res.status(200).send('Event tracked.').end();
        } catch (error) {
            // Treat an event tracking error as a fatal error
            next(error);
        }
    } else {
        return res.status(200).end();
    }
});

const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
  console.log(`App listening on port ${PORT}`);
  console.log('Press Ctrl+C to quit.');
});

In addition to listening to webhook requests, you can also retrieve the contact.meta data through the API (chipchat.contacts.get(id).meta). See the SDK docs for more information.

Consult the Google Analytics developers guide for info on Event Tracking.