/*************************************************************************** * * AUTHOR: Jon Bourne, jonbourne.com * * COMPANY: Digital Pi, digitalpi.com * * REVISED: 2016-10-06 * * DESCRIPTION: This script retrieves UTM query string values, if present, * and saves them in a cookie. If a Marketo form is present, the script will * add hidden fields to it and populate them with the UTM values stored in * the cookie if any exist. * * USAGE: * 1) Configure fields in your Marketo instance for tracking UTM parameters. * You will need one field for each UTM parameter you want to track. * 2) Download this script and configure your Marketo field names in the * configuration options below. * 3) Optionally, configure your domain name. This will use the current root * domain (hostname) if you don't change the default below. Auto-detect * only works with .com, .net, .org, .co.uk, .co and .us domains. * 4) Upload the file to somewhere it will be publicly accessible, perhaps * in your Marketo instance's Design Studio or on your corporate website. * 5) Insert the code below just before the closing tag on your * website or Marketo landing page template(s) where you want to use the * UTM tracking functionality. * * ***************************************************************************/ /*************************************************************************** * AUTHOR: Jeffrey Balmeo * * COMPANY: Neudesic, neudesic.com * * REVISED: 2018-12-13 * * DESCRIPTION: Added First Touch values. These fields must be created in Marketo * to be set. Also, Added NULL to clear out old Marketo fields so old values * are not connected to the form submission. * ***************************************************************************/ /************************** CONFIGURATION OPTIONS **************************/ /* MARKETO UTM FIELDS: * Input field names for your Marketo instance in the right column below. * If you're not sure what to put here, export all fields from within your * Marketo instance under Admin > Field Management > Export Field Names * (requires admin access) and use your UTM fields' SOAP API Name from the * downloaded Fields.xls file. This is case sensitive! */ var dpi_marketoUtmFields = { 'utm_source' : 'utm_source' ,'utm_medium' : 'utm_medium' ,'utm_campaign' : 'utm_campaign' ,'utm_term' : 'utm_term' }; var dpi_marketoUtmFieldsFT = { 'utm_source' : 'utm_sourceFT' ,'utm_medium' : 'utm_mediumFT' ,'utm_campaign' : 'utm_campaignFT' ,'utm_term' : 'utm_termFT' }; /* DOMAIN NAME (optional): * Optionally, set your primary domain name so that the cookie can be read on * your main website and across all subdomains. Will auto-detect current * domain if unchanged. */ var dpi_cookieDomain = 'neuronesb.com'; var dpi_cookieDomain_www = 'www.neuronesb.com'; /*********************** DO NOT EDIT BELOW THIS LINE ************************/ /*! * JavaScript Cookie v2.1.3 * https://github.com/js-cookie/js-cookie * * Copyright 2006, 2015 Klaus Hartl & Fagner Brack * Released under the MIT license */ ;(function (factory) { var registeredInModuleLoader = false; if (typeof define === 'function' && define.amd) { define(factory); registeredInModuleLoader = true; } if (typeof exports === 'object') { module.exports = factory(); registeredInModuleLoader = true; } if (!registeredInModuleLoader) { var OldCookies = window.Cookies; var api = window.Cookies = factory(); api.noConflict = function () { window.Cookies = OldCookies; return api; }; } }(function () { function extend () { var i = 0; var result = {}; for (; i < arguments.length; i++) { var attributes = arguments[ i ]; for (var key in attributes) { result[key] = attributes[key]; } } return result; } function init (converter) { function api (key, value, attributes) { var result; if (typeof document === 'undefined') { return; } // Write if (arguments.length > 1) { attributes = extend({ path: '/' }, api.defaults, attributes); if (typeof attributes.expires === 'number') { var expires = new Date(); expires.setMilliseconds(expires.getMilliseconds() + attributes.expires * 864e+5); attributes.expires = expires; } try { result = JSON.stringify(value); if (/^[\{\[]/.test(result)) { value = result; } } catch (e) {} if (!converter.write) { value = encodeURIComponent(String(value)) .replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent); } else { value = converter.write(value, key); } key = encodeURIComponent(String(key)); key = key.replace(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent); key = key.replace(/[\(\)]/g, escape); return (document.cookie = [ key, '=', value, attributes.expires ? '; expires=' + attributes.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE attributes.path ? '; path=' + attributes.path : '', attributes.domain ? '; domain=' + attributes.domain : '', attributes.secure ? '; secure' : '' ].join('')); } // Read if (!key) { result = {}; } // To prevent the for loop in the first place assign an empty array // in case there are no cookies at all. Also prevents odd result when // calling "get()" var cookies = document.cookie ? document.cookie.split('; ') : []; var rdecode = /(%[0-9A-Z]{2})+/g; var i = 0; for (; i < cookies.length; i++) { var parts = cookies[i].split('='); var cookie = parts.slice(1).join('='); if (cookie.charAt(0) === '"') { cookie = cookie.slice(1, -1); } try { var name = parts[0].replace(rdecode, decodeURIComponent); cookie = converter.read ? converter.read(cookie, name) : converter(cookie, name) || cookie.replace(rdecode, decodeURIComponent); if (this.json) { try { cookie = JSON.parse(cookie); } catch (e) {} } if (key === name) { result = cookie; break; } if (!key) { result[name] = cookie; } } catch (e) {} } return result; } api.set = api; api.get = function (key) { return api.call(api, key); }; api.getJSON = function () { return api.apply({ json: true }, [].slice.call(arguments)); }; api.defaults = {}; api.remove = function (key, attributes) { api(key, '', extend(attributes, { expires: -1 })); }; api.withConverter = init; return api; } return init(function () {}); })); /***************************** CUSTOM FUNCTIONS *****************************/ // Retrieve a named value from query string function dpi_getQueryStringValue(key) { key = key.replace(/[*+?^$.\[\]{}()|\\\/]/g, "\\$&"); // escape RegEx meta chars var match = location.search.match(new RegExp("[?&]"+key+"=([^&]+)(&|$)")); return match && decodeURIComponent(match[1].replace(/\+/g, " ")); } // Get domain name function dpi_getDomain() { var regex = /[\w-]+.(com|net|org|co.uk|co|us|ai)/ig; var url = location.hostname; return url.match(regex)[0]; } /************************ MARKETO UTM TRACKING LOGIC ************************/ // Create empty objects for UTM parameters var dpi_queryStringUtmVals = {}; var dpi_cookieUtmVals = {}; // Set cookie domain from current domain if default is not changed if(dpi_cookieDomain == 'example.com') { dpi_cookieDomain = dpi_getDomain(); } // Retrieve all UTM query string params and values, store to object for( property in dpi_marketoUtmFields ) { if(dpi_getQueryStringValue(property) && dpi_getQueryStringValue(property).length > 0) { dpi_queryStringUtmVals[dpi_marketoUtmFields[property]] = dpi_getQueryStringValue(property); } } // Retrieve all UTM query string params and values, store to object for First Touch for( property in dpi_marketoUtmFieldsFT ) { if(dpi_getQueryStringValue(property) && dpi_getQueryStringValue(property).length > 0) { dpi_queryStringUtmVals[dpi_marketoUtmFieldsFT[property]] = dpi_getQueryStringValue(property); } } // If we have any UTM query string values... if(Object.keys(dpi_queryStringUtmVals).length > 0) { // Then create or update the cookie with whatever query string variables are available Cookies.set('dpi_utmVals', dpi_queryStringUtmVals , { expires: 3652, domain: '.'+dpi_cookieDomain }); } // Is there a cookie set with UTM values? if( typeof Cookies.getJSON('dpi_utmVals') != "undefined" ) { // Yes, the cookie is set // Wait two seconds to make sure MktoForms2 library has had time to load setTimeout(function(){ // Is Marketo's Forms 2.0 API library loaded? if ( typeof MktoForms2 != "undefined") { // Yes, it is loaded // If/when a Marketo form says it's ready... MktoForms2.whenReady(function (form){ // ...then add hidden UTM fields to the form form.addHiddenFields( Cookies.getJSON('dpi_utmVals'), { domain: '.'+dpi_cookieDomain } ); // On successful form submission, delete the cookie form.onSuccess(function(form){ Cookies.remove('dpi_utmVals', { domain: '.'+dpi_cookieDomain } ); }); }); } }, 2000); // two-second delay } else { // No, the cookie is set // Wait two seconds to make sure MktoForms2 library has had time to load for( property in dpi_marketoUtmFields ) { dpi_queryStringUtmVals[dpi_marketoUtmFields[property]] = "NULL"; } setTimeout(function(){ // Is Marketo's Forms 2.0 API library loaded? if ( typeof MktoForms2 != "undefined") { // Yes, it is loaded Cookies.set('dpi_utmVals', dpi_queryStringUtmVals , { expires: 3652, domain: '.'+dpi_cookieDomain }); // If/when a Marketo form says it's ready... MktoForms2.whenReady(function (form){ // ...then add hidden UTM fields = Null to the form form.addHiddenFields( Cookies.getJSON('dpi_utmVals'), { domain: '.'+dpi_cookieDomain } ); // On successful form submission, delete the cookie form.onSuccess(function(form){ Cookies.remove('dpi_utmVals', { domain: '.'+dpi_cookieDomain } ); }); }); } }, 2500); // two-second delay } // Is there a cookie set with Referrer values? if( typeof Cookies.getJSON('leadSourceLastRef') != "undefined" ) { //alert(Cookies.getJSON('leadSourceLastRef')); setTimeout(function(){ // Is Marketo's Forms 2.0 API library loaded? if ( typeof MktoForms2 != "undefined") { // Yes, it is loaded // If/when a Marketo form says it's ready... MktoForms2.whenReady(function (form){ // ...then add hidden UTM fields to the form form.addHiddenFields({ leadSourceLast : Cookies.getJSON('leadSourceLastRef') }) form.addHiddenFields({ leadSourceTypeLast : Cookies.getJSON('leadSourceTypeLast') }) // On successful form submission, delete the cookie form.onSuccess(function(form){ Cookies.remove('leadSourceLastRef', { domain: '.'+dpi_cookieDomain_www } ); Cookies.remove('leadSourceLast', { domain: '.'+dpi_cookieDomain_www } ); Cookies.remove('leadSourceTypeLast', { domain: '.'+dpi_cookieDomain_www } ); }); }); } }, 2000); // two-second delay }