Firing unstructured events + custom contexts within Google Tag Manager

I haven’t been able to dig up any documentation regarding how one might go about firing unstructured events (plus custom contexts) when using a Google Tag Manager (GTM) implementation for Snowplow javascript tracker on the web. Thinking through it a bit leads me to believe that a dataLayer variable would have to be defined in GTM for every single property of every unstructured event and every custom context one would potentially want to send. What I can’t wrap my head around is how you could even set up the event firing tag without knowing which properties will be sent with the event (unstructured events might have optional properties / properties that don’t always get sent with every event fire). Has anyone else successfully implemented unstructured event firings with a GTM setup and if so, how?

Hi @travisdevitt,

Did you give a read to our wiki article on Integrating javascript tags with Google Tag-Manager? It provides a detailed explanation and example of firing a structured event (with lots of screenshots). The same idea should apply to both unstructured events and custom contexts.

And yes, you have to think through thoroughly upfront what data you will be sending. Even unstructured event has a predefined structure (by means of JSON schema). That’s why we prefer to call it a self-describing event as this term defines it better.

The process of “upfront” thinking involving defining all the objects and events you want to track with the help of GTM is described in this PDF documentation.

Hopefully it helps.

Regards,
Ihor

Hey @travisdevitt,

There are broadly three different strategies for tracking unstructured events via GTM:

####1. Have each of your variables in GTM refer to an individual property, and in GTM compose self-describing JSONs out of the individual properties.

You will need to write logic that checks for the existece of those individual variables and if so include them in the JSON.

In this case you push individual variables to the dataLayer:

dataLayer.push({
  'product_id': 123,
  'product_name': 'bread',
  'quantity': 1
  'event': 'add-to-basket'
});

In GTM you would then define a product_id variable, a product_name variable. You’d then write a tag in GTM that fired the following when the trigger event = 'add-to-bastet':

window.snowplow('trackUnstructEvent', {
    schema: 'iglu:com.acme_company/add-to-basket/jsonschema/1-0-0',
    data: {
        product_id: {{ product_id }},
        product_name: {{ product_name }},
        quantity: {{ quantity }}
    }
});

This means that your knowledge about schemas ‘lives’ in your GTM code.

####2. Have each of your variables in GTM refer to a full event JSON, and push the JSON as a whole to the dataLayer

In this case you push the data to the dataLayer as follows:

dataLayer.push({
  'event': 'add-to-basket',
  'properties': {
    'product_id': 123,
    'product_name': 'bread',
    'quantity': 1    
  }
});

You would define a variables in GTM called properties that mapped to the properties JSON in the dataLayer. You’d then create the following tag in GTM and configure it to fire when event = 'add-to-basket':

window.snowplow('trackUnstructEvent', {
    schema: 'iglu:com.acme_company/add-to-basket/jsonschema/1-0-0',
    data: {{ properties }}
});

####3, Have each of your variables in GTM refer to a full self-describing JSON

In this case you push a self-describing JSON to the dataLayer as follows:

dataLayer.push({
  'event': 'self-describing-event',
  'event_json':  {
    schema: 'iglu:com.acme_company/add-to-basket/jsonschema/1-0-0',
    data: {
        product_id: {{ product_id }},
        product_name: {{ product_name }},
        quantity: {{ quantity }}
     }
  } 
});

Then in GTM you’d define a single tag as follows and trigger it to fire any time 'event' = 'self-describing-event':

window.snowplow('trackUnstructEvent', {{ event_json }});

Note that the difference between the three approaches is where you logic around composing your self-describing JSONs live. If you prefer it to live in your platform and be pushed to the dataLayer, configuring GTM becomes a lot easier. If you want the logic to live in GTM and the platform to push an unordered set of name value pairs to the dataLayer, then the GTM implementation is more complex.

My preference is (3) - sending the data in a structured (self-describing) format from the platform (where it is anyway schema’d).

Note that the same considerations apply to contexts.

Does that make sense? Is it helpful?

3 Likes

Yes, that’s very helpful Yali! I wasn’t sure if I could pass full json to the dataLayer but it appears so. Thank you!!

My pleasure!