___TERMS_OF_SERVICE___ By creating or modifying this file you agree to Google Tag Manager's Community Template Gallery Developer Terms of Service available at https://developers.google.com/tag-manager/gallery-tos (or such other URL as Google may provide), as modified from time to time. ___INFO___ { "type": "TAG", "id": "cvt_temp_public_id", "version": 1, "securityGroups": [], "displayName": "walkerOS", "brand": { "id": "brand_dummy", "displayName": "elbwalker", "thumbnail": "data:image/png;base64,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\u003d\u003d" }, "description": "Install and configure walker.js", "containerContexts": [ "WEB" ] } ___TEMPLATE_PARAMETERS___ [ { "type": "LABEL", "name": "intro", "displayName": "This is the \u003cb\u003ewalkerOS Tag template\u003c/b\u003e (v1.1) for installing and configuring walker.js on a website. Learn more in the \u003ca href\u003d\"https://www.elbwalker.com/docs/stacks/gtm/tag_template\"\u003edocumentation at elbwalker.com\u003c/a\u003e." }, { "type": "GROUP", "name": "installationGroup", "displayName": "Installation", "groupStyle": "ZIPPY_OPEN", "subParams": [ { "type": "CHECKBOX", "name": "walkerjsLoad", "checkboxText": "Load walker.js", "simpleValueType": true, "subParams": [ { "type": "SELECT", "name": "walkerjsLoadType", "displayName": "From source", "macrosInSelect": false, "selectItems": [ { "value": "cdn", "displayValue": "CDN" }, { "value": "hosted", "displayValue": "Self-hosted" }, { "value": "window", "displayValue": "Window" } ], "simpleValueType": true, "subParams": [ { "type": "TEXT", "name": "walkerjsLoadCDN", "displayName": "With the version", "simpleValueType": true, "enablingConditions": [ { "paramName": "walkerjsLoadType", "paramValue": "cdn", "type": "EQUALS" } ], "defaultValue": "latest", "valueValidators": [ { "type": "NON_EMPTY" } ] }, { "type": "TEXT", "name": "walkerjsLoadURL", "displayName": "Full URL", "simpleValueType": true, "enablingConditions": [ { "paramName": "walkerjsLoadType", "paramValue": "hosted", "type": "EQUALS" } ], "defaultValue": "", "help": "Make sure to add the URL to\u003cbr /\u003e\u003cb\u003ePermissions -\u003e Injects Scripts\u003c/b\u003e", "valueHint": "https://", "valueValidators": [ { "type": "NON_EMPTY" } ] }, { "type": "TEXT", "name": "walkerjsLoadWindow", "displayName": "Name of the factory", "simpleValueType": true, "enablingConditions": [ { "paramName": "walkerjsLoadType", "paramValue": "window", "type": "EQUALS" } ], "defaultValue": "Walkerjs", "help": "Name of the function to create a walker.js instance. Make sure to have Permissions to read and execute.", "valueHint": "Walkerjs", "valueValidators": [ { "type": "NON_EMPTY" } ] } ], "enablingConditions": [ { "paramName": "walkerjsLoad", "paramValue": true, "type": "EQUALS" } ] } ], "defaultValue": true, "alwaysInSummary": false, "help": "There are multiple ways to load walker.js\u003cbr /\u003e\u003col\u003e\u003cli\u003e\u003cb\u003eCDN\u003c/b\u003e: Load from an external source (for quick testing)\u003c/li\u003e\u003cli\u003e\u003cb\u003eSelf-hosted\u003c/b\u003e: Upload the walker.js to your own server for first-party context\u003c/li\u003e\u003cli\u003e\u003cb\u003eWindow\u003c/b\u003e: Use a previously integrated version, e.g. via NPM (recommended)\u003c/li\u003e\u003c/ol\u003e" }, { "type": "SELECT", "name": "walkerjsMode", "displayName": "Mode", "macrosInSelect": false, "selectItems": [ { "value": "run", "displayValue": "Auto run" }, { "value": "consent", "displayValue": "Require consent" }, { "value": "manual", "displayValue": "Manual" } ], "simpleValueType": true, "help": "\u003col\u003e\u003cli\u003e\u003cb\u003eAuto run\u003c/b\u003e starts the walker immediately.\u003c/li\u003e\n\u003cli\u003e\u003cb\u003eRequire consent\u003c/b\u003e waits until the consent state is granted before calling \u0027walker run\u0027.\u003c/li\u003e\n\u003cli\u003e\u003cb\u003eManual\u003c/b\u003e won\u0027t do anything - it\u0027s up to you.\u003c/li\u003e\u003c/ol\u003e", "defaultValue": "run" }, { "type": "TEXT", "name": "walkerjsModeConsent", "displayName": "Required consent state", "simpleValueType": true, "enablingConditions": [ { "paramName": "walkerjsMode", "paramValue": "consent", "type": "EQUALS" } ], "help": "Enter the name of the consent group that has to be set to true via \u003cb\u003ewalker consent\u003c/b\u003e command. Granting that consent state will call \u003cb\u003ewalker run\u003c/b\u003e.", "valueHint": "functional", "valueValidators": [ { "type": "NON_EMPTY" } ], "defaultValue": "functional" }, { "type": "GROUP", "name": "walkerjsNamesGroup", "displayName": "Names", "groupStyle": "ZIPPY_OPEN_ON_PARAM", "subParams": [ { "type": "LABEL", "name": "introNames", "displayName": "Change the default names if there might be a conflict with already existing variables." }, { "type": "TEXT", "name": "walkerjsWindowInstance", "displayName": "walkerjs instance", "simpleValueType": true, "defaultValue": "walkerjs", "help": "This is the variable name that can be used to access the walker.js instance in the browser", "valueHint": "walkerjs", "valueValidators": [ { "type": "NON_EMPTY" } ] }, { "type": "TEXT", "name": "walkerjsWindowElb", "displayName": "elb function", "simpleValueType": true, "defaultValue": "elb", "help": "This is the variable name that can be used to access the elb function in the browser", "valueHint": "elb", "valueValidators": [ { "type": "NON_EMPTY" } ] }, { "type": "TEXT", "name": "walkerjsWindowElbLayer", "displayName": "elbLayer", "simpleValueType": true, "defaultValue": "elbLayer", "help": "This is the variable name for the elbLayer array.", "valueHint": "elbLayer", "valueValidators": [] } ] } ] }, { "type": "GROUP", "name": "optionsGroup", "displayName": "Options", "groupStyle": "ZIPPY_OPEN", "subParams": [ { "type": "TEXT", "name": "walkerjsOptionsTagging", "displayName": "Tagging version", "simpleValueType": true, "defaultValue": 1, "help": "Helps to debug the setup by knowing which tagging version was used during measurement.", "valueValidators": [ { "type": "POSITIVE_NUMBER" } ] }, { "type": "TEXT", "name": "walkerjsOptionsUserId", "displayName": "Set a user id", "simpleValueType": true, "help": "This will set the id for the user. Both device and session ids will be set in the Session section or via a custom on event." }, { "type": "SIMPLE_TABLE", "name": "walkerjsOptionsGlobals", "displayName": "Globals", "simpleTableColumns": [ { "defaultValue": "", "displayName": "Name", "name": "key", "type": "TEXT" }, { "defaultValue": "", "displayName": "Value", "name": "value", "type": "TEXT" } ], "newRowButtonText": "Add global", "help": "Add static globals that will be set to every single event." }, { "type": "CHECKBOX", "name": "walkerjsOptionsLog", "checkboxText": "Preview events in the console", "simpleValueType": true, "displayName": "Logging", "help": "This adds a destination to the walker.js that logs all events to the console." } ] }, { "type": "GROUP", "name": "sessionGroup", "displayName": "Session", "groupStyle": "ZIPPY_OPEN", "subParams": [ { "type": "LABEL", "name": "sessionNote", "displayName": "Session detection, user identification, and consent management are closely connected. Learn more about \u003ca href\u003d\"https://www.elbwalker.com/docs/utils/session\"\u003ehow to detect a session\u003c/a\u003e." }, { "type": "GROUP", "name": "sessionConfigGroup", "displayName": "", "groupStyle": "NO_ZIPPY", "subParams": [ { "type": "CHECKBOX", "name": "session", "checkboxText": "Enable session detection", "simpleValueType": true, "help": "This uses the \u003cb\u003esessionWindow Util\u003c/b\u003e as a cookie-less version", "alwaysInSummary": true, "defaultValue": true }, { "type": "CHECKBOX", "name": "sessionStorage", "checkboxText": "Use Storage", "simpleValueType": true, "help": "This additionally uses the \u003cb\u003esessionStorage Util\u003c/b\u003e to persist data and enhance session information and user identification.", "alwaysInSummary": true, "enablingConditions": [ { "paramName": "session", "paramValue": true, "type": "EQUALS" } ] }, { "type": "LABEL", "name": "infoSessionStorage", "displayName": "This uses \u003cb\u003eelbDeviceId\u003c/b\u003e and \u003cb\u003eelbSessionId\u003c/b\u003e in the \u003cb\u003elocalStorage\u003c/b\u003e. There is a virtual rule to limit the age to 30 days for the device ID and 30 minutes for a session ID, which updates with each new run.", "enablingConditions": [ { "paramName": "sessionStorage", "paramValue": true, "type": "EQUALS" } ] }, { "type": "TEXT", "name": "sessionStorageConsent", "displayName": "Required consent for storage access", "simpleValueType": true, "enablingConditions": [ { "paramName": "sessionStorage", "paramValue": true, "type": "EQUALS" } ], "help": "Once the user\u0027s consent choice is available, the session detection starts", "valueHint": "marketing", "notSetText": "Make sure to have granted consent for storage access." } ] } ], "enablingConditions": [ { "paramName": "walkerjsLoad", "paramValue": true, "type": "EQUALS" } ] }, { "type": "GROUP", "name": "destinationsGroup", "displayName": "Destinations", "groupStyle": "ZIPPY_OPEN", "subParams": [ { "type": "CHECKBOX", "name": "destinationDataLayer", "checkboxText": "Use dataLayer", "simpleValueType": true, "displayName": "Google Tag Manager", "defaultValue": true, "help": "Enabling this option will push every single event to the dataLayer automatically." }, { "type": "PARAM_TABLE", "name": "destinations", "displayName": "Additional destinations", "paramTableColumns": [ { "param": { "type": "TEXT", "name": "code", "displayName": "Code*", "simpleValueType": true, "help": "(Required) The destinations function code", "alwaysInSummary": false, "valueValidators": [ { "type": "NON_EMPTY" } ] }, "isUnique": false }, { "param": { "type": "TEXT", "name": "config", "displayName": "Config", "simpleValueType": true, "help": "Settings about mapping, required consent states and more." }, "isUnique": false } ], "newRowButtonText": "Add destination", "editRowTitle": "Edit destination" } ] }, { "type": "GROUP", "name": "onGroup", "displayName": "On Events", "groupStyle": "ZIPPY_OPEN", "subParams": [ { "type": "SIMPLE_TABLE", "name": "on", "displayName": "Code that gets called on the selected trigger", "simpleTableColumns": [ { "defaultValue": "", "displayName": "Trigger", "name": "trigger", "type": "SELECT", "selectItems": [ { "value": "consent", "displayValue": "Consent" }, { "value": "run", "displayValue": "Run" } ] }, { "defaultValue": "", "displayName": "Code", "name": "code", "type": "TEXT" } ], "newRowButtonText": "Add event" } ] }, { "type": "GROUP", "name": "hooksGroup", "displayName": "Hooks", "groupStyle": "ZIPPY_OPEN", "subParams": [ { "type": "SIMPLE_TABLE", "name": "hooks", "displayName": "Update default behavior with custom hooks", "simpleTableColumns": [ { "defaultValue": "", "displayName": "Hook", "name": "hookName", "type": "SELECT", "selectItems": [ { "value": "prePush", "displayValue": "prePush" }, { "value": "preDestinationInit", "displayValue": "preDestinationInit" }, { "value": "postDestinationInit", "displayValue": "postDestinationInit" }, { "value": "preDestinationPush", "displayValue": "preDestinationPush" }, { "value": "postDestinationPush", "displayValue": "postDestinationPush" }, { "value": "postPush", "displayValue": "postPush" } ], "valueValidators": [ { "type": "NON_EMPTY" } ] }, { "defaultValue": "", "displayName": "Code", "name": "hookCode", "type": "TEXT", "valueValidators": [ { "type": "NON_EMPTY" } ] } ], "newRowButtonText": "Add Hook", "help": "Hooks can be used to customize the default behavior of the walker.js. Three hooks are available: Push, DestinationInit, and DestinationPush. Hooks allows for validation, manipulation, or even eventual cancellation of default behavior. \u003ca href\u003d\"https://www.elbwalker.com/docs/clients/walkerjs/commands#hooks\"\u003eRead more about hooks\u003c/a\u003e." } ] } ] ___SANDBOXED_JS_FOR_WEB_TEMPLATE___ const log = require("logToConsole"); const callInWindow = require("callInWindow"); const copyFromWindow = require("copyFromWindow"); const createArgumentsQueue = require("createArgumentsQueue"); const injectScript = require("injectScript"); // log("data", data); function isObject(o) { return typeof o === "object" && o !== null; } // Names const elbLayerName = data.walkerjsWindowElbLayer ? data.walkerjsWindowElbLayer : "elbLayer"; // elbLayer name const walkerjsName = data.walkerjsWindowInstance ? data.walkerjsWindowInstance : "walkerjs"; // walkerjs instance name const elbName = data.walkerjsWindowElb ? data.walkerjsWindowElb : "elb"; // elb function name // elb let elb = copyFromWindow(elbName); // Get existing elb function if (!elb) elb = createArgumentsQueue(elbName, elbLayerName); // (Optional) create elb function // Installation function installation() { // Options const config = {}; // Window variables config.instance = walkerjsName; config.elb = elbName; // Tagging version if (data.walkerjsOptionsTagging) config.tagging = data.walkerjsOptionsTagging; // User ID if (data.walkerjsOptionsUserId) config.user = { id: data.walkerjsOptionsUserId }; // Globals if (data.walkerjsOptionsGlobals) { const globals = data.walkerjsOptionsGlobals.reduce(function (acc, global) { acc[global.key] = global.value; return acc; }, {}); config.globals = globals; } // DataLayer destination if (data.destinationDataLayer) config.dataLayer = true; // Session if (data.session) { config.session = {}; // Storage if (data.sessionStorage) config.session.storage = true; // Consent for storage access if (data.sessionStorageConsent) config.session.consent = data.sessionStorageConsent; } else { config.session = false; } // Init modes function requireConsentMode(instance, consent) { if (consent[data.walkerjsModeConsent]) elb("walker run"); } if (data.walkerjsMode == "consent") { // Require consent var consent = {}; consent[[data.walkerjsModeConsent]] = requireConsentMode; elb("walker on", "consent", consent); } else if (data.walkerjsMode == "run") { // Auto run config.run = true; } var factory = data.walkerjsLoadWindow ? data.walkerjsLoadWindow : "Walkerjs.default"; // Let's go callInWindow(factory, config); data.gtmOnSuccess(); } // Destinations if (data.destinations) { data.destinations.forEach(function (destination) { // Validation if (!isObject(destination.code)) data.gtmOnFailure(); var config = isObject(destination.config) ? destination.config : {}; // Add the destination elb("walker destination", destination.code, config); }); } // On Events if (data.on) { var onConsent = []; var onRun = []; data.on.forEach(function (on) { if (on.trigger == "consent") onConsent.push(on.code); if (on.trigger == "run") onRun.push(on.code); }); if (onConsent.length) elb("walker on", "consent", onConsent); if (onRun.length) elb("walker on", "run", onRun); } // Hooks if (data.hooks) { data.hooks.forEach(function (hook) { elb("walker hook", hook.hookName, hook.hookCode); }); } // Debug mode preview destination if (data.walkerjsOptionsLog) { elb( "walker destination", { push: function (e) { log("preview", e); }, }, { type: "preview" } ); } // Load if (data.walkerjsLoad) { var url = data.walkerjsLoadURL; // Load self-hosted // Load from CDN if (data.walkerjsLoadCDN) { url = "https://cdn.jsdelivr.net/npm/@elbwalker/walker.js@" + data.walkerjsLoadCDN + "/dist/index.browser.js"; } if (url) { injectScript(url, installation, data.gtmOnFailure, "walkerjs"); } else { installation(); } } else { data.gtmOnSuccess(); } ___WEB_PERMISSIONS___ [ { "instance": { "key": { "publicId": "logging", "versionId": "1" }, "param": [ { "key": "environments", "value": { "type": 1, "string": "debug" } } ] }, "clientAnnotations": { "isEditedByUser": true }, "isRequired": true }, { "instance": { "key": { "publicId": "access_globals", "versionId": "1" }, "param": [ { "key": "keys", "value": { "type": 2, "listItem": [ { "type": 3, "mapKey": [ { "type": 1, "string": "key" }, { "type": 1, "string": "read" }, { "type": 1, "string": "write" }, { "type": 1, "string": "execute" } ], "mapValue": [ { "type": 1, "string": "elb" }, { "type": 8, "boolean": true }, { "type": 8, "boolean": true }, { "type": 8, "boolean": true } ] }, { "type": 3, "mapKey": [ { "type": 1, "string": "key" }, { "type": 1, "string": "read" }, { "type": 1, "string": "write" }, { "type": 1, "string": "execute" } ], "mapValue": [ { "type": 1, "string": "walkerjs" }, { "type": 8, "boolean": true }, { "type": 8, "boolean": true }, { "type": 8, "boolean": false } ] }, { "type": 3, "mapKey": [ { "type": 1, "string": "key" }, { "type": 1, "string": "read" }, { "type": 1, "string": "write" }, { "type": 1, "string": "execute" } ], "mapValue": [ { "type": 1, "string": "elbLayer" }, { "type": 8, "boolean": true }, { "type": 8, "boolean": true }, { "type": 8, "boolean": false } ] }, { "type": 3, "mapKey": [ { "type": 1, "string": "key" }, { "type": 1, "string": "read" }, { "type": 1, "string": "write" }, { "type": 1, "string": "execute" } ], "mapValue": [ { "type": 1, "string": "Walkerjs" }, { "type": 8, "boolean": true }, { "type": 8, "boolean": true }, { "type": 8, "boolean": true } ] }, { "type": 3, "mapKey": [ { "type": 1, "string": "key" }, { "type": 1, "string": "read" }, { "type": 1, "string": "write" }, { "type": 1, "string": "execute" } ], "mapValue": [ { "type": 1, "string": "Walkerjs.default" }, { "type": 8, "boolean": true }, { "type": 8, "boolean": false }, { "type": 8, "boolean": true } ] } ] } } ] }, "clientAnnotations": { "isEditedByUser": true }, "isRequired": true }, { "instance": { "key": { "publicId": "inject_script", "versionId": "1" }, "param": [ { "key": "urls", "value": { "type": 2, "listItem": [ { "type": 1, "string": "https://cdn.jsdelivr.net/npm/@elbwalker/*" }, { "type": 1, "string": "https://elbwalker.com/*" } ] } } ] }, "clientAnnotations": { "isEditedByUser": true }, "isRequired": true } ] ___TESTS___ scenarios: - name: Default settings code: |- runCode({}); assertThat(copyFromWindow('elb')).isDefined(); assertThat(copyFromWindow('walkerjs')).isUndefined(); assertApi('gtmOnSuccess').wasCalled(); - name: Load Window code: | runCode(dataWalkerjsLoad); assertApi("callInWindow").wasCalledWith("Walkerjs", { instance: data.walkerjsWindowInstance, elb: data.walkerjsWindowElb, session: false, }); assertApi("gtmOnSuccess").wasCalled(); - name: Load CDN code: | runCode(assign( data, { walkerjsLoad: true, walkerjsLoadType: 'CDN', walkerjsLoadCDN: 'version', }) ); assertApi('injectScript').wasCalledWith("https://cdn.jsdelivr.net/npm/@elbwalker/walker.js@version/dist/index.browser.js", success, failure, 'walkerjs'); assertApi("callInWindow").wasCalledWith("Walkerjs.default", { instance: data.walkerjsWindowInstance, elb: data.walkerjsWindowElb, session: false, }); assertApi("gtmOnSuccess").wasCalled(); - name: Load self-hosted code: | runCode(assign( data, { walkerjsLoad: true, walkerjsLoadType: 'hosted', walkerjsLoadURL: 'CUSTOM_URL', }) ); assertApi('injectScript').wasCalledWith("CUSTOM_URL", success, failure, 'walkerjs'); assertApi("callInWindow").wasCalledWith("Walkerjs.default", { instance: data.walkerjsWindowInstance, elb: data.walkerjsWindowElb, session: false, }); assertApi("gtmOnSuccess").wasCalled(); - name: Mode Auto run code: | runCode(assign( dataWalkerjsLoad, { walkerjsMode: 'run' } )); assertApi("callInWindow").wasCalledWith("Walkerjs", { instance: data.walkerjsWindowInstance, elb: data.walkerjsWindowElb, session: false, run: true }); assertApi("gtmOnSuccess").wasCalled(); - name: Mode Require consent code: | runCode(assign( dataWalkerjsLoad, { walkerjsMode: 'consent' } )); assertApi("callInWindow").wasCalledWith("Walkerjs", { instance: data.walkerjsWindowInstance, elb: data.walkerjsWindowElb, session: false, }); assertApi("gtmOnSuccess").wasCalled(); setup: |- let log = require("logToConsole"); const copyFromWindow = require("copyFromWindow"); const setInWindow = require("setInWindow"); // Required fields with default values data.walkerjsWindowElbLayer = "elbLayer"; data.walkerjsWindowInstance = "walkerjs"; data.walkerjsWindowElb = "elb"; const dataWalkerjsLoad = assign( { walkerjsLoad: true, walkerjsLoadType: "window", walkerjsLoadWindow: "Walkerjs", }, data ); // Miss you, Object.assign function assign(o1, o2) { for (var key in o2) { if (o2.hasOwnProperty(key)) { o1[key] = o2[key]; } } return o1; } // Mocks let success, failure; mock("injectScript", (url, onsuccess, onfailure) => { success = onsuccess; failure = onfailure; onsuccess(); }); const elbCalls = []; function mockElb(a, b, c) { elbCalls.push(a, b, c); } setInWindow(data.walkerjsWindowElb, mockElb); ___NOTES___ Created on 3/15/2024, 3:08:28 PM