As digital marketers, we have a responsibility to ensure that the we deliver value to our customers. Web analytics tools are one of the ways in which we can demonstrate this value. However, one of the challenging parts about working at scale is the time commitment involved from both the digital marketer and the customer. Unfortunately, this can often mean delays in the roll out of web analytics tools, like Google Analytics. This series of blog posts is about automating as much manual work as possible during the roll out process.
Google Apps Script is a serverless computing environment which makes it easy to interact with Google’s services. No infrastructure is needed and authentication with Google’s products is handled for you. Scripts are written in a language based on JavaScript and can be scheduled to run based off time intervals, events, Google Form submissions and more. The following solution outlines the basics you need to start building up Google Tag Manager containers on behalf of your customers. Go to https://script.google.com to get started.
The idea is that you can modify this code to meet your own needs, depending on what and how you want to track.
In Apps Script – go to Resources > Advanced Google Services and turn on the Tag Manager API.
Also, follow the link to the Google API Console and in the side bar go to APIs & Services > Library, search for the Google Tag Manager API and enable it. In your case, ‘MANAGE’ will say ‘ENABLE’ until you turn it on.
Unfortunately there is no account insert operation in the Google Tag Manager API, so to work around this you will only be creating a container for each customer, within large ‘holding accounts’ – which you will create in the Google Tag Manager UI.
As you’ll be hitting Google Tag Manager API endpoints quickly when creating and configuring multiple containers, you need a way to ensure that your script keeps going when it hits the rate limit. Exponential backoff is a way to solve this problem, where a script will stop and wait an exponentially increasing amount of time each time it hits the rate limit. This is based off https://gist.github.com/peterherrmann/2700284 with the only addition being it only starts the backoff process if it hits the rate limit errors from Google APIs.
function call(func, optLoggerFunction) { for (var n = 0; n < 6; n++) { try { return func() } catch (e) { Logger.log(e); if (e == "GoogleJsonResponseException: Quota Error: User Rate Limit Exceeded." || e == "GoogleJsonResponseException: Quota Error: Rate limit for writes exceeded.") { if (optLoggerFunction) { optLoggerFunction("GASRetry " + n + ": " + e) } if (n == 5) { throw e } Utilities.sleep((Math.pow(2, n) * 1000) + (Math.round(Math.random() * 1000))) } else { throw e } } } }
var params = { 'gtmAccountId': postData.gtmAccountId, 'customerName': postData.customerName, 'analyticsAccountId': postData.analyticsAccountId, 'websiteUrl': postData.websiteUrl, 'callTrackingId': postData.callTrackingId, //optional 'analyticsPropertyId': postData.analyticsPropertyId //optional }; var paramsHardcoded = { 'gtmAccountId': '1234567', 'customerName': 'Billy Bob', 'analyticsAccountId': '1242535', 'websiteUrl': 'https://billybob.co.nz', 'callTrackingId': '1234567', //optional 'analyticsPropertyId': 'UA-123456' //optional }
var path = 'accounts/' + params.gtmAccountId; var container = call(function() { return TagManager.Accounts.Containers.create({ 'name': params.customerName, 'usageContext': ['WEB'] }, path) }); var containerPath = container.path; var containerId = container.accountId;
// Creates a workspace in the container to track entity changes. var workspace = call(function() { return TagManager.Accounts.Containers.Workspaces.create({ 'name': 'Automated Workspace', 'description': 'Some description.' }, containerPath) }); var workspacePath = workspace.path;
/*FULL RESOURCE INFO CAN BE FOUND HERE: https://developers.google.com/tag-manager/api/v1/reference/accounts/containers/triggers#resource*/ //DOM Ready trigger var trigger1 = call(function() { return TagManager.Accounts.Containers.Workspaces.Triggers.create({ 'name': 'DOM Ready', 'type': 'domReady' }, workspacePath) }); //Page View trigger var trigger3 = call(function() { return TagManager.Accounts.Containers.Workspaces.Triggers.create({ 'name': 'Page View - All Pages', 'type': 'pageview' }, workspacePath) });
//Creating a regular GA pageview tag var tag2 = call(function() { return TagManager.Accounts.Containers.Workspaces.Tags.create({ 'name': 'UA Page Views All Pages', 'type': 'ua', 'liveOnly': false, 'parameter': [ { 'type': 'template', 'key': 'trackingId', 'value': params.analyticsPropertyId }, { 'type': 'template', 'key': 'trackType', 'value': 'TRACK_PAGEVIEW' }, { "key": "fieldsToSet", "type": "list", "list": [{ "type": "map", "map": [{ "type": "template", "key": "fieldName", "value": "cookieDomain" }, { "type": "template", "key": "value", "value": "auto" } ] }] } ], 'firingTriggerId': [trigger3.triggerId] }, workspacePath) });
var version = call(function() { return TagManager.Accounts.Containers.Workspaces .create_version({ 'name': 'GTM Automation' }, workspacePath) .containerVersion });
var publish = call(function() { return TagManager.Accounts.Containers.Versions.publish(version.path) });
Comments
There are no comments on this entry.