Hey all!
We all love following the data trail with our web pixels, we know this. In a custom web pixel, how are we supposed to track that a customer had consented to email or sms marketing within that checkout session?
I want this to trigger on checkout_completed
, and I can see there are fields event?.data?.checkout?.buyerAcceptsSmsMarketing
and event?.data?.checkout?.buyerAcceptsEmailMarketing
, these fields are persistent across checkout sessions since they relate to the customer. My goal here is to only dispatch these events on the checkout where the customer had checked off marketing consent and completed checkout.
I do not want these event to fire off every checkout_completed
for customers that consented unknown checkouts ago, but rather fire off events when we can determine to our best ability that the customer had 0 consent at the start, but given consent by the end.
I have tried a few ways, one was listening to input_changed
and checking when contact_marketing_opt_in
or contact_sms_marketing_opt_in
have been changed and they are checked, storing something to browser.sessionStorage
and then checking for the key and value on checkout_completed
and dispatch my dataLayer
event from there, but it doesn’t seem to be working, nor do I think it’s a great solution if the DOM identifiers ever change. This method does seem to work for email
but not sms
Another way I have tried is storing the value of event?.data?.checkout?.buyerAcceptsEmailMarketing
to a global variable on checkout_started
and comparing it to the end value of event?.data?.checkout?.buyerAcceptsEmailMarketing
on checkout_completed
but this never resolves a detection in consent for email
or sms
. I have noticed that any code outside of an analytics.subscribe()
doesn’t seem to execute first. I had defined a function that immediately logs a message, but my checkout_started
log seemed to run well before that, even though it was called well before. Maybe run order is a problem?
It seems shocking to me that Shopify doesn’t have a formal event for marketing_consent_granted
which would make our lives a lot easier.
Some app pixels allegedly seem to have no problem detecting sign up consent, so what am I getting wrong here?
Here is some example pixel code from the latest:
// debug log flags
const SHOW_CONSOLE_LOGS = true
// proxy function for console log if we have the debug flag on
const debug_log = (...args) => SHOW_CONSOLE_LOGS && console.log(...args);
debug_log(`custom pixel loaded`);
// Store the GTM ID as a variable so we only have 1 source of ID
const GTM_ID = 'ID';
// initialize the flags as false, set them in `checkout_started` and compare values in `checkout_completed`
let buyerAcceptsEmailMarketingOnCheckoutStarted = false;
let buyerAcceptsSmsMarketingOnCheckoutStarted = false;
// Push data to dataLayer and log it
const pushToDataLayer = (eventData) => {
debug_log(`pushToDataLayer():`, eventData);
// no event data for some reason, early exit.
if(!eventData) return;
window.dataLayer.push({ ecommerce: null });
window.dataLayer.push(eventData);
};
// When window.dataLayer is defined push up event data, if applicable.
// Otherwise, load the GTM script, and then push the sent event data, if applicable.
const initializeGTM = (eventData) => {
debug_log(`initializeGTM()`, eventData);
if(window.dataLayer) {
debug_log('GTM already loaded');
eventData && pushToDataLayer(eventData);
return;
}
debug_log(`window.dataLayer does not exist, creating script tag with onload callback.`)
window.dataLayer = [];
// establish our GTM script
const script = document.createElement('script');
script.async = true;
script.src = `https://www.googletagmanager.com/gtm.js?id=${GTM_ID}`;
script.onload = () => {
debug_log('GTM loaded');
pushToDataLayer({ 'gtm.start': new Date().getTime(), event: 'gtm.js' });
eventData && pushToDataLayer(eventData);
};
// insert the GTM script into the web pixel head using the old faithful
const firstScript = document.getElementsByTagName('script')[0];
firstScript.parentNode.insertBefore(script, firstScript);
};
// Subscribe to checkout_started and grab the current consent values
// The consent values on checkout_started will be used to determine if the customer was already signed up for marketing or not.
analytics.subscribe("checkout_started", (event) => {
// checkout started, initialize GTM if it is not already initialized.
// we have attempted to call this function outside of an analytics subscribe event, but it seems these events run well before anything outside.
initializeGTM();
// set our marketing consent flags as the checkout session is started.
buyerAcceptsEmailMarketingOnCheckoutStarted = event?.data?.checkout?.buyerAcceptsEmailMarketing;
buyerAcceptsSmsMarketingOnCheckoutStarted = event?.data?.checkout?.buyerAcceptsSmsMarketing;
debug_log(`checkout_started, buyerAcceptsSmsMarketing: ${buyerAcceptsSmsMarketingOnCheckoutStarted}, buyerAcceptsEmailMarketing: ${buyerAcceptsEmailMarketingOnCheckoutStarted}`);
});
// Subscribe to the checkout_completed event to check for consent, since consent can be toggled on and off during the contact info stage.
analytics.subscribe("checkout_completed", (event) => {
debug_log(`checkout_completed`);
// if the customer consented to email marketing
// If the buyer did not have email consent at the start of checkout, but does at the end, we will assume they just consented for email marketing in this checkout
if(buyerAcceptsEmailMarketingOnCheckoutStarted == false && event?.data?.checkout?.buyerAcceptsEmailMarketing == true){
debug_log(`Customer consented to email marketing in this checkout.`);
initializeGTM({
event: "gtmEvent",
event_name: "signup",
contact_type: "email",
signup_location: "checkout",
contact_data: event?.data?.checkout?.email
});
}
// if the customer consented to sms marketing
// If the buyer did not have sms consent at the start of checkout, but does at the end, we will assume they just consented for sms marketing in this checkout
if(buyerAcceptsSmsMarketingOnCheckoutStarted == false && event?.data?.checkout?.buyerAcceptsSmsMarketing == true){
debug_log(`Customer consented to sms marketing in this checkout.`);
initializeGTM({
event: "gtmEvent",
event_name: "signup",
contact_type: "sms",
signup_location: "checkout",
contact_data: event?.data?.checkout?.smsMarketingPhone
});
}
});