This document describes how to intercept and mirror events sent to Google Tag Manager
What are we looking to achieve?
Many companies send data to Google Tag Manager to make it surface in Google Analytics. Instead of rebuilding your conversion tracking from scratch, it sometimes makes more sense to intercept your Google Tag Manager event tracking and feed that into Optimize.
It is worth noting that depending on how many events you capture, this could flood your conversion tracking and make it difficult to find the events you’re looking for. Because of this, the walkthrough will consider tracking only particular named events that you want to mirror into Optimize.
Finally, please note that the two platforms – Google Analytics and Webtrends Optimize – are both different. Views, Sessions and Users may not be identical for a variety of reasons. For example, Optimize allows for throttling and segmentation, has performance thresholds, and does not sample users. GA does not throttle or segment but does often sample traffic.
Key considerations
dataLayer.push
– This is GTM’s mechanism for collecting information. The function behaves similarly to Array.prototype.push
, in that it will consume any arguments and output them to the Array
that is dataLayer
. This is the function that we will be proxying to intercept our data.
WT.helpers.CTrack
– this is Optimize’s REST API module for Conversion Tracking. It’ll simplify how we attempt to capture conversion events.
Understanding Proxy functions:
Proxy functions are a method in which you overwrite the namespace of the function you want to intercept and replace it with your own code. For example, one could overwrite dataLayer.push
with the following:
window.dataLayer.push = function(){
// my handling for console.log goes here.
};
After this code executes, anyone who calls dataLayer.push
would hit your code instead of the default mechanism. This is one of the ways in which websites can suppress the console.
However, if we wanted to simply hook into dataLayer.push
to act when we see something interesting, we need something like:
// store old dataLayer.push
var dataLayerPush__old = dataLayer.push;
// create a new version of that method. should receive an Object as the argument
dataLayer.push = function(o){
// trigger the old event, so we don't break existing functionality.
dataLayerPush__old.apply(this, arguments);
try {
var eventsWeAreInterestedIn = ["event_1", "event_2"];
var evt = o.event;
if(eventsWeAreInterestedIn.includes(evt)){
// we want to do soemthing here. this is an event we're interested in.
opt_data.push({event: evt});
}
} catch(err) {}
};
Putting it all together:
This is the code you would put into your tag to enable this functionality.
(function(){
var intvl = setInterval(function(){
if(!window.dataLayer || !window.dataLayer.push) return;
clearInterval(intvl);
// store old dataLayer.push
var dataLayerPush__old = dataLayer.push;
// create a new version of that method. should receive an Object as the argument
dataLayer.push = function(o){
// trigger the old event, so we don't break existing functionality.
dataLayerPush__old.apply(this, arguments);
try {
var eventsWeAreInterestedIn = ["event_1", "event_2", "event_3"];
var evt = o.event;
if(eventsWeAreInterestedIn.includes(evt)){
// we want to do soemthing here. this is an event we're interested in.
window.opt_data = window.opt_data || [];
opt_data.push({ event: evt });
}
} catch(err) {}
};
}, 500);
setTimeout(function(){
clearInterval(intvl);
}, 15000);
})();