Last active
November 4, 2021 09:41
-
-
Save mbaersch/5919bc1c795031183a525cb8c64a9352 to your computer and use it in GitHub Desktop.
getUniqueEventId() - creates cacheable event ids for deduplication of events that cannot use the same trigger
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* create unique event ids for specific events that "live" for a limited time | |
(default: 1 scond). | |
returns a value that consist of the key, a random number and a timestamp; | |
dot-separated. An existing value for a key that is requested within the | |
defined lifespan will remain the same, otherwise (not existing or too old) | |
a new value is generated and stored. The limited lifespan can be used to | |
deduplicate several hits of the same type between page loads (e. g. Add2Cart | |
or multiple PageViews in SPAs). | |
the purpose is to deduplicate hits for client- and server-side Facebook | |
tracking even when GA4 tags and FB tags fire at different triggers (e. g. | |
for consent reasons) | |
if you create a variable named "getUniqueEventId" with this code, an | |
example call in a second variable to create a page_view event id would | |
look like this: | |
function() { return {{getUniqueEventId}}('page_view'); } | |
example result: "page_view.44935367.1630613990849" | |
use as Custom JS Variable to return the function to create event IDs for | |
PageViews or FB events like ViewContent, AddToCart, InitiateCheckout, | |
Purchase and others vs. Google Analytics (e-commerce) events that get | |
sent at different trigger events. Send value as eventID (FB tag | |
client-side) and event_id (GA4 client-side event property -> FB | |
tag server-side) in both tags. | |
Note: if can use the same dataLayer event to trigger / fire GA and FB tags | |
at the same time, you do not need to "cache" evend ids with this | |
function. Use the Custom Variable Template for client-side GTM at | |
https://tagmanager.google.com/gallery/#/owners/mbaersch/templates/event-id | |
instead to create an event id variable that can be used in both tags | |
without caching. | |
*/ | |
function() { | |
return function(key, lifespan) { | |
var getRandomInt = function(min, max) { | |
return Math.floor(Math.random() * (max - min)) + min; | |
} | |
lifespan = lifespan || 1; | |
window._eventIds = window._eventIds || []; | |
var e = window._eventIds[key]; | |
if (!(e && e.id && e.ts && ((Date.now() - e.ts) / 1000 < lifespan))) { | |
window._eventIds[key] = {ts: Date.now(), id: getRandomInt(10000000, 99999999)}; | |
e = window._eventIds[key]; | |
} | |
return key + "." + e.id+'.'+e.ts; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script> | |
/* | |
If a unique event id based on gtm.uniqueEventId fails, because GA4 picks up a different | |
event, an alternative solution can be to repush all relevant events with a complete | |
unique event id into the dataLayer. Fiddling around with the dataLayer in JS is not | |
an ideal solution and I have no clue why this works instead of using gtm.uniqueEventId | |
as part of a variable-based event id... but it solved the problem in some cases. | |
Note: If it is possible to add event ids to every dataLayer push directly when they are | |
created by the cms, it would be an ideal solution. Try to have that implemented. As a fix, | |
the following code can be used to provide a new html tag and trigger this with every | |
event that has to be duplicated. | |
The code extracts the last push to the dataLayer, adds a "customEventId" (a dot-separated | |
combination of a timestamp and a random 10-digit integer), changes gtm.uniqueEventId in | |
order to have the new event show up in preview mode for debugging and then repushes the | |
event to the dataLayer, adding ".unique" to the event name. | |
All tags for FB and "transport"-tags that are used to send the same event to the | |
server-side tag manager / CAPI (usually GA4 tags) can then be triggered by the new | |
dataLayer events (like "view_item.unique") and use the "customEventId" from the dataLayer | |
as a dataLayer variable for deduplication. | |
*/ | |
if (window.dataLayer) { | |
var ev = JSON.parse(JSON.stringify(window.dataLayer[window.dataLayer.length-1])); | |
ev.customEventId = (Date.now() + ".").concat( | |
Math.floor(Math.random() * (9999999999 - 1000000000 + 1)) + 1000000000 | |
); | |
ev.event += ".unique"; | |
ev["gtm.uniqueEventId"] += ".1"; | |
window.dataLayer.push(ev); | |
} | |
</script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script> | |
/*Code for adding a customEventId without repushing: | |
-------------------------------------------------- | |
If a repush using the solution from | |
https://gist.github.com/mbaersch/5919bc1c795031183a525cb8c64a9352#file-option-1-repush-events-with-id-html | |
means too much work adjusting and adding triggers, the customEventId can be added directly to | |
the last event in the dataLayer. | |
In order to achieve this, this first script tag and the contained code can be added as a | |
custom html tag to the container and then the new tag is used as a setup tag for every | |
tag that needs to access the unique customEventId. | |
Note: to access this value in GTM, you cannot use a dataLayer variable! at the time the | |
dataLayer is read, the key and value will not pe present yet. Use the code from the second | |
script (see below) to create a custom JS variable. This will enable tags to access the | |
customEventId from the anhanced dataLayer event push. | |
*/ | |
if (window.dataLayer) { | |
var ev = window.dataLayer[window.dataLayer.length-1]; | |
if (!ev.customEventId) { | |
ev.customEventId = (Date.now() + ".").concat(Math.floor(Math.random() * (9999999999 - 1000000000 + 1)) + 1000000000); | |
} | |
} | |
</script> | |
<script> | |
/* | |
Code for accessing the Id: | |
-------------------------- | |
paste the following code in a new custom JS variable. This variable can then be used | |
to add an eventId / event_id to all FB- and transport tags (usually GA4, sent to a | |
GTM server) that fire on the same event and use the setup tag to create the id first. | |
*/ | |
function(){ | |
if (window.dataLayer) { | |
var ev = window.dataLayer[window.dataLayer.length-1]; | |
return ev.customEventId; | |
} | |
} | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment