{"id":4836,"date":"2020-12-22T12:07:22","date_gmt":"2020-12-22T09:07:22","guid":{"rendered":"https:\/\/trackingchef.com\/?p=4836"},"modified":"2024-10-28T19:03:25","modified_gmt":"2024-10-28T16:03:25","slug":"debugging-gtm-with-integromat-google-sheets","status":"publish","type":"post","link":"https:\/\/trackingchef.com\/google-tag-manager\/debugging-gtm-with-integromat-google-sheets\/","title":{"rendered":"Debugging GTM with Integromat & Google Sheets"},"content":{"rendered":"\n

One of the challenges when working with Google Tag Manager (GTM) is the gap between preview mode and actual deployment.<\/p>\n\n\n\n

Plenty of times, you deploy a tag with a certain configuration, and results show up entirely different. Sometimes this is due to the nature of edge cases that you didn’t think about or couldn’t simulate on your machine.<\/p>\n\n\n\n

One tactic I’ve found for tracing back the source of the issue is simply logging the tag fired and its variables. This is done by capturing all these in an HTTP POST webhook that logs these in a Google Sheets spreadsheet.<\/p>\n\n\n\n

\"\"
GTM Log in Google Sheets. Notice the bad data sent in the Value column.<\/figcaption><\/figure>\n\n\n\n

To capture the webhook and pass the data to Google Sheets I’ve used Integromat<\/a>, which is my go-to tool for automations, but you can also use Zapier just the same. You can create a free Integromat account here<\/a>, and their pricing is very reasonable compared to Zapier.<\/p>\n\n\n\n

Creating the Integromat Scenario<\/h2>\n\n\n\n

Log into your Integromat account and create a new scenario. For the scenario, select Webhooks and Google Sheets (can also do this later).<\/p>\n\n\n

\n
\"\"<\/figure><\/div>\n\n\n

Select the Webhooks module as the first step and click “Custom Webhook”.<\/p>\n\n\n\n

Click Add to create a new webhook URL and give it a descriptive name, e.g. GTM Logger.<\/p>\n\n\n

\n
\"\"<\/figure><\/div>\n\n\n

Copy the webhook’s URL and have it available.<\/p>\n\n\n\n

Creating the Logger tag<\/h2>\n\n\n\n

In GTM, open the tag you want to log. Identify the specific variables it uses and the trigger that applies to it.<\/p>\n\n\n\n

Then, create a new tag of the Custom HTML. In the tag’s body, paste the following snippet.<\/p>\n\n\n\n

<script>\nvar xhr = new XMLHttpRequest();\n\n\/\/ Paste below the webhook URL from Integromat\nvar url = \"https:\/\/hook.integromat.com\/abcdefg1234567\";\n\nvar dl = dataLayer;\ndl = dl[dl.length -1];\ndl = JSON.stringify(dl);\nxhr.open(\"POST\", url, true);\nxhr.setRequestHeader(\"Content-Type\", \"application\/json\");\n\n\/\/This is the payload data sent to the webhook\nvar data = JSON.stringify({\n    \"id\": {{Google Ads ID}},\n    \"label\": {{Google Ads Label}},\n    \"value\": {{Product price USD}},\n    \"orderid\": {{Transaction ID}},\n    \"currency\": \"USD\",\n    \"dl\":dl\n});\n\nxhr.send(data);\n<\/script><\/code><\/pre>\n\n\n\n

Webhook URL<\/h3>\n\n\n\n

Paste the webhook URL from Integromat in the appropriate place.<\/p>\n\n\n\n

Data Layer<\/h3>\n\n\n\n

As an extra way to analyze, I’ve also added the current Data Layer to be sent with the webhook. No changes are required here.<\/p>\n\n\n\n

Payload Data<\/h3>\n\n\n\n

The payload data sent to the webhook is structured as a JSON. This means that each variable has a pair of key and name separated by a colon, e.g. “orderId” : “12345”<\/em>.<\/p>\n\n\n\n

In this example the date sent comes from a Google Ads tag, so I wanted to capture the values sent in its different variables:<\/p>\n\n\n\n

{
“id”: {{Google Ads ID}},
“label”: {{Google Ads Label}},
“value”: {{Product price USD}},
“orderid”: {{Transaction ID}},
“currency”: “USD”,
“dl”:dl
}<\/p>\n\n\n\n

The values using Curly brackets {{ are variables from GTM, same as the ones used in the Google Ads tag I was debugging.<\/p>\n\n\n\n

The Currency was set as a constant, so I didn’t use a variable but rather set it as a string.<\/p>\n\n\n\n

The DL is simply the Data Layer captured at that moment.<\/p>\n\n\n\n

You can edit any of these, add and remove, to tailor this to the payload you want to capture. <\/p>\n\n\n\n

For example, when debugging a a Google Analytics event you can send:<\/p>\n\n\n\n

{
“eventCategory”: {{eventCategory}},
“eventAction”: {{eventAction}},
“eventLabel”: {{eventLabel}},
“eventValue”: {{eventValue}},
“nonInteraction”: {{nonInteraction}},
“dl”:dl
}<\/p>\n\n\n\n

Trigger<\/h3>\n\n\n\n

After adjusting the tag’s structure, you can add a trigger to the tag. Most likely this will be the same trigger as the tag you’re debugging.<\/p>\n\n\n\n

Sending the request data<\/h2>\n\n\n\n

After you’ve set up the Custom HTML you can publish it and wait for a request to be sent (you can trigger on yourself of course).<\/p>\n\n\n\n

\n

Pro tip:<\/strong>
You can also manually send the data to Integromat using a tool such as Request Bin<\/a>. Just set the request type to POST and paste the JSON in the request’s body (with dummy values instead of variables)<\/p>\n<\/blockquote>\n\n\n\n

Once the first request has been processed in Integromat, the data structure in the scenario will be determined and you can move onwards to the next step.<\/p>\n\n\n\n

Mapping the values to Google Sheets<\/h2>\n\n\n\n

First, create a new Google Sheets spreadsheet that will serve as the log. Add headers in the first row to capture each value sent. I also like to add a timestamp column.<\/p>\n\n\n

\n
\"\"<\/figure><\/div>\n\n\n

In the Integromat scenario, add a new module of the type “Google Sheets – Add a row”.<\/p>\n\n\n

\n
\"\"<\/figure><\/div>\n\n\n

Select the connected Google account (or create a new connection). Then select the Spreadsheet and sheet you want to use. Once the spreadsheet loads, you will see the headers you’ve added and can now map the values to them.<\/p>\n\n\n

\n
\"\"<\/figure><\/div>\n\n\n

The Timestamp value can take the now<\/em> variable in Integromat.<\/p>\n\n\n

\n
\"\"<\/figure><\/div>\n\n\n

Save the mapping and activate the scenario. You’re all set.<\/p>\n\n\n\n

Viewing the logger<\/h2>\n\n\n\n

As new webhook calls come in, they will be added as new rows in Google Sheets. The first row might carry over the formatting of the header (Bold and Underlined as in my case), so simply remove the formatting and new rows will continue unformatted.<\/p>\n\n\n

\n
\"\"<\/figure><\/div>\n\n\n

Caveats<\/h2>\n\n\n\n

Well, not everything is perfect.<\/p>\n\n\n\n

First, Integromat has a limit on its free tier for how many operations you can use. The free plan has 1,000 operations, so the two modules in the scenario use up, well, two operations per run which leaves us with 500 logs per month on the free tier. Their next tier of 10,000 operations is only 9$\/month, so there’s no real reason not to use it for deeper logging.<\/p>\n\n\n\n

\n

UPDATE<\/strong>
The magnificent Eyal Gershon pointed out that you can create a similar solution with Pipedream<\/a> that features a higher operations count on their free plan. Not sure you’ll need it, but it’s good to have.<\/p>\n<\/blockquote>\n\n\n\n

Second, you’ll still need to find the bug. Sometimes it will show up in the variables sent (as in my example above). Other times it will show in the Data Layer sent.<\/p>\n","protected":false},"excerpt":{"rendered":"

One of the challenges when working with Google Tag Manager (GTM) is the gap between preview mode and actual deployment. Plenty of times, you deploy a tag with a certain configuration, and results show up entirely different. Sometimes this is due to the nature of edge cases that you didn’t think about or couldn’t simulate […]<\/p>\n","protected":false},"author":1,"featured_media":4849,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[39],"tags":[],"class_list":["post-4836","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-google-tag-manager"],"_links":{"self":[{"href":"https:\/\/trackingchef.com\/wp-json\/wp\/v2\/posts\/4836","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/trackingchef.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/trackingchef.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/trackingchef.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/trackingchef.com\/wp-json\/wp\/v2\/comments?post=4836"}],"version-history":[{"count":6,"href":"https:\/\/trackingchef.com\/wp-json\/wp\/v2\/posts\/4836\/revisions"}],"predecessor-version":[{"id":6086,"href":"https:\/\/trackingchef.com\/wp-json\/wp\/v2\/posts\/4836\/revisions\/6086"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/trackingchef.com\/wp-json\/wp\/v2\/media\/4849"}],"wp:attachment":[{"href":"https:\/\/trackingchef.com\/wp-json\/wp\/v2\/media?parent=4836"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/trackingchef.com\/wp-json\/wp\/v2\/categories?post=4836"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/trackingchef.com\/wp-json\/wp\/v2\/tags?post=4836"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}