___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___ { "displayName": "Trackingplan by Luratic", "categories": [ "ANALYTICS", "HEAT_MAP", "SESSION_RECORDING" ], "description": "This is an unofficial Google Tag Manager template for Trackingplan.", "securityGroups": [], "id": "cvt_temp_public_id", "type": "TAG", "version": 1, "brand": { "displayName": "Luratic", "id": "github.com_luratic", "thumbnail": "data:image/jpeg;base64,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\u003d\u003d" }, "containerContexts": [ "WEB" ] } ___TEMPLATE_PARAMETERS___ [ { "simpleValueType": true, "name": "id", "type": "TEXT", "valueValidators": [ { "type": "NON_EMPTY", "enablingConditions": [] }, { "type": "REGEX", "args": [ "TP.+" ] } ], "displayName": "Trackingplan ID", "valueHint": "TP123456", "help": "Your Trackingplan ID.", "alwaysInSummary": true }, { "type": "GROUP", "name": "basic_options", "displayName": "Basic init options", "groupStyle": "ZIPPY_OPEN", "subParams": [ { "type": "SELECT", "name": "environment", "displayName": "Environment", "simpleValueType": true, "help": "Recommended. Use PRODUCTION for the live website and DEV for staging, QA or test environments. This helps Trackingplan keep production data separated from testing traffic.", "selectItems": [ { "value": "", "displayValue": "Do not set" }, { "value": "PRODUCTION", "displayValue": "PRODUCTION" }, { "value": "DEV", "displayValue": "DEV" } ], "defaultValue": "PRODUCTION", "alwaysInSummary": true }, { "type": "TEXT", "name": "sourceAlias", "displayName": "Source alias", "simpleValueType": true, "valueHint": "Optional source name", "help": "Optional. Human-readable name for this source. Use it only if the same Trackingplan property receives data from different implementations, for example Web, iOS, Android or a specific site. Leave empty if this tag is your main web implementation.", "alwaysInSummary": true }, { "type": "SELECT", "name": "debug", "displayName": "Debug mode", "simpleValueType": true, "help": "Optional. Do not set it in normal implementations. Select true only while testing if you want Trackingplan debug information in the browser console. Select false only if you want to explicitly force debug mode off.", "selectItems": [ { "value": "", "displayValue": "Do not set" }, { "value": "true", "displayValue": "true" }, { "value": "false", "displayValue": "false" } ], "defaultValue": "" }, { "type": "SELECT", "name": "usePrivacy", "displayName": "Privacy encryption", "simpleValueType": true, "help": "Optional. Leave as Do not set unless you need to explicitly control Trackingplan privacy encryption for detected personal data. Do not set does not send the usePrivacy option, so Trackingplan will use its own default behaviour, currently equivalent to enabled. When enabled, Trackingplan encrypts detected personal data in its privacy report. Select false only if you explicitly need to disable this option.", "selectItems": [ { "value": "", "displayValue": "Do not set (default: true)" }, { "value": "true", "displayValue": "true" }, { "value": "false", "displayValue": "false" } ], "defaultValue": "" } ] }, { "type": "GROUP", "name": "tags_group", "displayName": "Tags / custom parameters", "groupStyle": "ZIPPY_OPEN", "subParams": [ { "type": "SIMPLE_TABLE", "name": "tags", "displayName": "Tags", "help": "Optional. Add custom key/value parameters to classify what Trackingplan receives. Useful for release version, GTM container version, country, page type, experiment name or build number. Empty rows are ignored.", "simpleTableColumns": [ { "defaultValue": "", "displayName": "Parameter name", "name": "tagName", "type": "TEXT" }, { "defaultValue": "", "displayName": "Parameter value", "name": "tagValue", "type": "TEXT" } ] } ] }, { "type": "GROUP", "name": "advanced_options", "displayName": "Advanced options", "groupStyle": "ZIPPY_CLOSED", "subParams": [ { "type": "SIMPLE_TABLE", "name": "customDomains", "displayName": "Custom monitored domains", "help": "Optional and advanced. Use this only when your website sends analytics or tracking requests to domains that Trackingplan does not detect by default. Add the request domain in the first column and the readable vendor/source name in the second column. Example: if your site sends requests to api.segment.io, use domain api.segment.io and alias Segment. Do not add your own website domain here; this is for the destination domains of tools you want Trackingplan to monitor.", "simpleTableColumns": [ { "defaultValue": "", "displayName": "Domain", "name": "domain", "type": "TEXT" }, { "defaultValue": "", "displayName": "Alias", "name": "alias", "type": "TEXT" } ] }, { "type": "TEXT", "name": "getDataLayer", "displayName": "Data layer getter", "simpleValueType": true, "valueHint": "{{Trackingplan - getDataLayer}}", "help": "Optional and advanced. Use only if your data layer is not available as the standard window.dataLayer or if you need to send a custom representation to Trackingplan. Select a GTM variable that returns the getter function, for example a Custom JavaScript Variable. Do not paste the function as plain text." } ] }, { "type": "GROUP", "name": "info", "displayName": "Information", "groupStyle": "ZIPPY_OPEN", "subParams": [ { "type": "LABEL", "name": "nosdeu_info", "displayName": "\u003cstrong\u003e\u003ca href\u003d\"https://dato.la/template_gtm\"\u003e🐮 nosDeu - The Data Cooperative \u003c/a\u003e\u003c/strong\u003e" }, { "type": "LABEL", "name": "info_web", "displayName": "\u003ca href\u003d\"https://nosd.eu/tp_gtm\"\u003eTrackingplan installation documentation\u003c/a\u003e" } ] } ] ___SANDBOXED_JS_FOR_WEB_TEMPLATE___ const injectScript = require('injectScript'); const callInWindow = require('callInWindow'); const log = require('logToConsole'); const trackingUrl = 'https://sdk.trackingplan.com/js/base/trackingplan-latest.min.js'; const isSet = value => value !== undefined && value !== null && value !== ''; const toBoolean = value => value === true || value === 'true'; const buildKeyValueObject = (rows, keyField, valueField) => { const object = {}; let hasValues = false; rows = rows || []; for (let i = 0; i < rows.length; i++) { const key = rows[i][keyField]; const value = rows[i][valueField]; if (isSet(key)) { object[key] = isSet(value) ? value : ''; hasValues = true; } } return {object: object, hasValues: hasValues}; }; const config = {}; if (isSet(data.environment)) { config.environment = data.environment; } if (isSet(data.sourceAlias)) { config.sourceAlias = data.sourceAlias; } if (isSet(data.debug)) { config.debug = toBoolean(data.debug); } if (isSet(data.usePrivacy)) { config.usePrivacy = toBoolean(data.usePrivacy); } const tags = buildKeyValueObject(data.tags, 'tagName', 'tagValue'); if (tags.hasValues) { config.tags = tags.object; } const customDomains = buildKeyValueObject(data.customDomains, 'domain', 'alias'); if (customDomains.hasValues) { config.customDomains = customDomains.object; } if (isSet(data.getDataLayer)) { config.getDataLayer = data.getDataLayer; } if (config.debug === true) { log('Trackingplan init options', config); } const onSuccess = () => { callInWindow('Trackingplan.init', data.id, config); data.gtmOnSuccess(); }; injectScript(trackingUrl, onSuccess, data.gtmOnFailure, 'tp'); ___WEB_PERMISSIONS___ [ { "instance": { "key": { "publicId": "inject_script", "versionId": "1" }, "param": [ { "key": "urls", "value": { "type": 2, "listItem": [ { "type": 1, "string": "https://sdk.trackingplan.com/js/base/trackingplan-latest.min.js" } ] } } ] }, "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": "Trackingplan" }, { "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": "Trackingplan.init" }, { "type": 8, "boolean": true }, { "type": 8, "boolean": true }, { "type": 8, "boolean": true } ] } ] } } ] }, "clientAnnotations": { "isEditedByUser": true }, "isRequired": true }, { "instance": { "key": { "publicId": "logging", "versionId": "1" }, "param": [ { "key": "environments", "value": { "type": 1, "string": "debug" } } ] }, "isRequired": true } ] ___TESTS___ scenarios: - name: gtmOnSuccess is invoked on injectScript success code: |- // test that gtmOnSuccess() is called when injectScript succeeds mock('injectScript', (url, onSuccess, onFailure) => { onSuccess(); }); // Call runCode to run the template's code. runCode(); // Verify that the tag finished successfully. assertApi('gtmOnSuccess').wasCalled(); - name: gtmOnFailure is invoked when injectScript fails code: |- // test gtmOnFailure() is called when injectScript fails mock('injectScript', (url, onSuccess, onFailure) => { onFailure(); }); // Call runCode to run the template's code. runCode(); // Verify onFailure was called assertApi('gtmOnFailure').wasCalled(); ___NOTES___ Developed by nosDeu - The Data Cooperative 🐮. Web: https://nosdeu.com https://www.linkedin.com/in/braiscalvo/ | https://twitter.com/braiscv https://www.linkedin.com/in/txemasm/