Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to send a POST request from GTM custom tag template?

I'm developing a simple custom tag template for Google Tag Manager. It's supposed to bind to some events and send event data to our servers as JSON in the body of a POST request.

The sandboxed GTM Javascript runtime provides the sendPixel() API. However, that only provides GET requests.

How one sends a POST request from within this sandboxed runtime?

like image 424
Jen Avatar asked Jan 26 '23 15:01

Jen


2 Answers

You can use a combination of the injectScript and copyFromWindow APIs found here Custom Template APIs.

Basically, the workflow goes like this.

  1. Build a simple script that contains a function attached to the window object that sends a normal XHR post request. The script I made and use can be found here: https://storage.googleapis.com/common-scripts/basicMethods.js
  2. Upload that script somewhere publically accessible so you can import it into your template.
  3. Use the injectScript API to add the script to your custom template.
  4. The injectScript API wants you to provide an onSuccess callback function. Within that function, use the copyWindow api to grab the post request function you created in your script and save it as a variable.
  5. You can now use that variable to send a post request the same way you would use a normal JS function.

The script I included above also includes JSON encode and Base64 encode functions which you can use the same way via the copyWindow api.

I hope that helps. If you need some specific code examples for parts I can help.

like image 87
Ian Mitchell Avatar answered Apr 06 '23 08:04

Ian Mitchell


According to @Ian Mitchell answer - I've made similar solution.

This is the basic code pattern that can be used inside GTM template code section in such as scenario:

const injectScript = require('injectScript');
const callInWindow = require('callInWindow');
const log = require('logToConsole');
const queryPermission = require('queryPermission');
 
const postScriptUrl = 'https://myPostScriptUrl'; //provide your script url
const endpoint = 'https://myEndpoint'; //provide your endpoint url
  
//provide your data; data object contains all properties from fields tab of the GTM template
const data = {
  sessionId: data.sessionId,
  name: data.name,
  description: data.description
};
 
//add appropriate permission to inject script from 'https://myPostScriptUrl' url in GTM template's privileges tab
if (queryPermission('inject_script', postScriptUrl)) {
  injectScript(postScriptUrl, onSuccess, data.gtmOnFailure, postScriptUrl);
} else {
  log('postScriptUrl: Script load failed due to permissions mismatch.');
  data.gtmOnFailure();
}
 
function onSuccess() {
  //add appropriate permission to call `sendData` variable in GTM template's privileges tab
  callInWindow('sendData', gtmData, endpoint);
  data.gtmOnSuccess();
}

It's important to remember to add all necessary privillages inside GTM template. Appropriate permissions will show automatically in privillages tab after use pertinent options inside code section.

Your script at 'https://myPostScriptUrl' may looks like this:

function sendData(data, endpoint) {
  var xhr = new XMLHttpRequest();
  var stringifiedData = JSON.stringify(data);

  xhr.open('POST', endpoint);
  xhr.setRequestHeader('Content-type', 'application/json');
  xhr.send(stringifiedData);

  xhr.onload = function () {
    if (xhr.status.toString()[0] !== '2') {
      console.error(xhr.status + '> ' + xhr.statusText);
    }
  };
}
like image 27
Maciej Kubiak Avatar answered Apr 06 '23 08:04

Maciej Kubiak