___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": "CLIENT", "id": "cvt_temp_public_id", "version": 1, "securityGroups": [], "displayName": "Data Client", "brand": { "id": "brand_dummy", "displayName": "Stape", "thumbnail": "data:image/png;base64,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" }, "description": "Use this Client as a mapper from Request Data to Event Data.", "containerContexts": [ "SERVER" ] } ___TEMPLATE_PARAMETERS___ [ { "type": "CHECKBOX", "name": "exposeFPIDCookie", "checkboxText": "Expose FPID Cookie", "simpleValueType": true, "help": "If enabled, the server only accessible FPID cookie, generated by UA/GA4 client, will be duplicated to FPIDP cookie, which will be accessible from the client JS. Highly recommend using this option only in case it is necessary." }, { "type": "CHECKBOX", "name": "generateClientId", "checkboxText": "Always generate client_id parameter", "simpleValueType": true, "help": "If enabled, even if the `client_id` parameter will not be determined from the request, it will still be generated. The `client_id` parameter is required by UA/GA4 tags.", "defaultValue": true }, { "type": "CHECKBOX", "name": "prolongCookies", "checkboxText": "Automatically prolong Data Tag cookies", "simpleValueType": true, "help": "If enabled, cookies generated by Data tag will be reseated from the server with an expiration time of two years. Useful if you use Data tag store functionality.", "defaultValue": true }, { "type": "GROUP", "name": "responseSettings", "displayName": "Response Settings", "groupStyle": "ZIPPY_CLOSED", "subParams": [ { "type": "SELECT", "name": "responseBody", "displayName": "Response Body", "macrosInSelect": false, "selectItems": [ { "value": "timestamp", "displayValue": "JSON Object with timestamp (recommended)" }, { "value": "eventData", "displayValue": "JSON Object with Event Data" }, { "value": "empty", "displayValue": "Empty" } ], "simpleValueType": true, "defaultValue": "timestamp" }, { "type": "CHECKBOX", "name": "responseBodyGet", "checkboxText": "Send Response Body for GET request", "simpleValueType": true, "help": "By default, for the GET request type, the answer is image pixel. \u003ca target\u003d\"_blank\" href\u003d\"https://developers.google.com/tag-manager/serverside/api#setpixelresponse\"\u003eMore Info\u003c/a\u003e." } ] }, { "type": "GROUP", "name": "pathSettings", "displayName": "Accepted Path Settings", "groupStyle": "ZIPPY_CLOSED", "subParams": [ { "type": "SIMPLE_TABLE", "name": "path", "displayName": "Type additional paths that will be claimed by this client", "simpleTableColumns": [ { "defaultValue": "", "displayName": "For example: /callback", "name": "path", "type": "TEXT", "isUnique": true, "valueValidators": [ { "type": "NON_EMPTY" } ] } ], "newRowButtonText": "Add path", "help": "By default path \u003cb\u003e/data\u003c/b\u003e will be claimed. But you can add more paths that will be claimed by this client." } ] } ] ___SANDBOXED_JS_FOR_SERVER___ const returnResponse = require('returnResponse'); const runContainer = require('runContainer'); const setResponseHeader = require('setResponseHeader'); const setResponseStatus = require('setResponseStatus'); const setResponseBody = require('setResponseBody'); const JSON = require('JSON'); const fromBase64 = require('fromBase64'); const getTimestampMillis = require('getTimestampMillis'); const getCookieValues = require('getCookieValues'); const getRequestBody = require('getRequestBody'); const getRequestMethod = require('getRequestMethod'); const getRequestHeader = require('getRequestHeader'); const getRequestPath = require('getRequestPath'); const getRequestQueryParameters = require('getRequestQueryParameters'); const makeInteger = require('makeInteger'); const getRemoteAddress = require('getRemoteAddress'); const setCookie = require('setCookie'); const setPixelResponse = require('setPixelResponse'); const generateRandom = require('generateRandom'); const computeEffectiveTldPlusOne = require('computeEffectiveTldPlusOne'); const requestMethod = getRequestMethod(); const path = getRequestPath(); let isClientUsed = false; if (path === '/data') { runClient(); } if (data.path && !isClientUsed) { for (let key in data.path) { if (!isClientUsed && data.path[key].path === path) { runClient(); } } } function runClient() { isClientUsed = true; require('claimRequest')(); if (requestMethod === 'OPTIONS') { setResponseHeaders(); returnResponse(); return; } let eventModel = { timestamp: makeInteger(getTimestampMillis() / 1000), unique_event_id: getTimestampMillis() + '_' + generateRandom(100000000, 999999999) }; eventModel = addQueryParametersToEventModel(eventModel); eventModel = addBodyParametersToEventModel(eventModel); eventModel = addRequiredParametersToEventModel(eventModel); eventModel = addCommonParametersToEventModel(eventModel); eventModel = addClientIdToEventModel(eventModel); storeClientId(eventModel); exposeFPIDCookie(eventModel); prolongDataTagCookies(eventModel); setResponseHeaders(); runContainer(eventModel, () => { if (requestMethod === 'POST' || data.responseBodyGet) { prepareResponseBody(eventModel); returnResponse(); } else { setPixelResponse(); returnResponse(); } }); } function addCommonParametersToEventModel(eventModel) { let userData = {}; let userAddressData = {}; if (eventModel.user_data) userData = eventModel.user_data; if (userData.address) userAddressData = userData.address; if (!eventModel.ip_override) { if (eventModel.ip) eventModel.ip_override = eventModel.ip; else if (eventModel.ipOverride) eventModel.ip_override = eventModel.ipOverride; else eventModel.ip_override = getRemoteAddress(); } if (!eventModel.user_agent) { if (eventModel.userAgent) eventModel.user_agent = eventModel.userAgent; else if (getRequestHeader('User-Agent')) eventModel.user_agent = getRequestHeader('User-Agent'); } if (!eventModel.language) { const acceptLanguageHeader = getRequestHeader('Accept-Language'); if (acceptLanguageHeader) { eventModel.language = acceptLanguageHeader.split(';')[0].substring(0, 2).toLowerCase(); } } if (!eventModel.page_hostname) { if (eventModel.pageHostname) eventModel.page_hostname = eventModel.pageHostname; else if (eventModel.hostname) eventModel.page_hostname = eventModel.hostname; } if (!eventModel.page_location) { if (eventModel.pageLocation) eventModel.page_location = eventModel.pageLocation; else if (eventModel.url) eventModel.page_location = eventModel.url; else if (eventModel.href) eventModel.page_location = eventModel.href; } if (!eventModel.page_referrer) { if (eventModel.pageReferrer) eventModel.page_referrer = eventModel.pageReferrer; else if (eventModel.referrer) eventModel.page_referrer = eventModel.referrer; } if (eventModel.items && eventModel.items[0]) { if (!eventModel.currency && eventModel.items[0].currency) eventModel.currency = eventModel.items[0].currency; if (!eventModel.items[1]) { if (!eventModel.item_id && eventModel.items[0].item_id) eventModel.item_id = eventModel.items[0].item_id; if (!eventModel.item_name && eventModel.items[0].item_name) eventModel.item_name = eventModel.items[0].item_name; if (!eventModel.item_brand && eventModel.items[0].item_brand) eventModel.item_brand = eventModel.items[0].item_brand; if (!eventModel.item_quantity && eventModel.items[0].quantity) eventModel.item_quantity = eventModel.items[0].quantity; if (!eventModel.item_category && eventModel.items[0].item_category) eventModel.item_category = eventModel.items[0].item_category; if (eventModel.items[0].price) { if (!eventModel.item_price) eventModel.item_price = eventModel.items[0].price; if (!eventModel.value) eventModel.value = eventModel.items[0].quantity ? eventModel.items[0].quantity * eventModel.items[0].price : eventModel.items[0].price; } } else if (!eventModel.value) { let valueFromItems = 0; eventModel.items.forEach((d) => { if (d.price) valueFromItems += d.quantity ? d.quantity * d.price : d.price; }); if (valueFromItems) eventModel.value = valueFromItems; } } const ecommerceAction = getEcommerceAction(eventModel); if (ecommerceAction) { if (!eventModel['x-ga-mp1-pa']) eventModel['x-ga-mp1-pa'] = ecommerceAction; if (ecommerceAction === 'purchase' && eventModel.ecommerce.purchase.actionField) { if (!eventModel['x-ga-mp1-tr']) eventModel['x-ga-mp1-tr'] = eventModel.ecommerce.purchase.actionField.revenue; if (!eventModel.revenue) eventModel.revenue = eventModel.ecommerce.purchase.actionField.revenue; if (!eventModel.affiliation) eventModel.affiliation = eventModel.ecommerce.purchase.actionField.affiliation; if (!eventModel.tax) eventModel.tax = eventModel.ecommerce.purchase.actionField.tax; if (!eventModel.shipping) eventModel.shipping = eventModel.ecommerce.purchase.actionField.shipping; if (!eventModel.coupon) eventModel.coupon = eventModel.ecommerce.purchase.actionField.coupon; if (!eventModel.transaction_id) eventModel.transaction_id = eventModel.ecommerce.purchase.actionField.id; } } if (!userData.email_address) { if (eventModel.userEmail) userData.email_address = eventModel.userEmail; else if (eventModel.email_address) userData.email_address = eventModel.email_address; else if (eventModel.email) userData.email_address = eventModel.email; else if (eventModel.mail) userData.email_address = eventModel.mail; } if (!userData.phone_number) { if (eventModel.userPhoneNumber) userData.phone_number = eventModel.userPhoneNumber; else if (eventModel.phone_number) userData.phone_number = eventModel.phone_number; else if (eventModel.phoneNumber) userData.phone_number = eventModel.phoneNumber; else if (eventModel.phone) userData.phone_number = eventModel.phone; } if (!eventModel.page_encoding && eventModel.pageEncoding) eventModel.page_encoding = eventModel.pageEncoding; if (!eventModel.page_path && eventModel.pagePath) eventModel.page_path = eventModel.pagePath; if (!eventModel.page_title && eventModel.pageTitle) eventModel.page_title = eventModel.pageTitle; if (!eventModel.screen_resolution && eventModel.screenResolution) eventModel.screen_resolution = eventModel.screenResolution; if (!eventModel.viewport_size && eventModel.viewportSize) eventModel.viewport_size = eventModel.viewportSize; if (!eventModel.user_id && eventModel.userId) eventModel.user_id = eventModel.userId; if (!userAddressData.street && eventModel.street) userAddressData.street = eventModel.street; if (!userAddressData.city && eventModel.city) userAddressData.city = eventModel.city; if (!userAddressData.region && eventModel.region) userAddressData.region = eventModel.region; if (!userAddressData.country && eventModel.country) userAddressData.country = eventModel.country; if (!userAddressData.first_name) { if (eventModel.userFirstName) userAddressData.first_name = eventModel.userFirstName; else if (eventModel.first_name) userAddressData.first_name = eventModel.first_name; else if (eventModel.firstName) userAddressData.first_name = eventModel.firstName; else if (eventModel.name) userAddressData.first_name = eventModel.name; } if (!userAddressData.last_name) { if (eventModel.userLastName) userAddressData.last_name = eventModel.userLastName; else if (eventModel.last_name) userAddressData.last_name = eventModel.last_name; else if (eventModel.lastName) userAddressData.last_name = eventModel.lastName; else if (eventModel.surname) userAddressData.last_name = eventModel.surname; else if (eventModel.family_name) userAddressData.last_name = eventModel.family_name; else if (eventModel.familyName) userAddressData.last_name = eventModel.familyName; } if (!userAddressData.region) { if (eventModel.region) userAddressData.region = eventModel.region; else if (eventModel.state) userAddressData.region = eventModel.state; } if (!userAddressData.postal_code) { if (eventModel.postal_code) userAddressData.postal_code = eventModel.postal_code; else if (eventModel.postalCode) userAddressData.postal_code = eventModel.postalCode; else if (eventModel.zip) userAddressData.postal_code = eventModel.zip; } if (getObjectLength(userAddressData) !== 0) { userData.address = userAddressData; } if (getObjectLength(userData) !== 0) { eventModel.user_data = userData; } return eventModel; } function addQueryParametersToEventModel(eventModel) { const requestQueryParameters = getRequestQueryParameters(); if (requestQueryParameters) { for (let queryParameterKey in requestQueryParameters) { if ((queryParameterKey === 'dtcd' || queryParameterKey === 'dtdc') && requestMethod === 'GET') { let dt = queryParameterKey === 'dtcd' ? JSON.parse(requestQueryParameters[queryParameterKey]) : JSON.parse(fromBase64(requestQueryParameters[queryParameterKey])); for (let dtKey in dt) { eventModel[dtKey] = dt[dtKey]; } } else { eventModel[queryParameterKey] = requestQueryParameters[queryParameterKey]; } } } return eventModel; } function addClientIdToEventModel(eventModel) { if (eventModel.client_id) return eventModel; if (eventModel.data_client_id) eventModel.client_id = eventModel.data_client_id; else if (eventModel._dcid) eventModel.client_id = eventModel._dcid; else if (getCookieValues('_dcid') && getCookieValues('_dcid')[0]) eventModel.client_id = getCookieValues('_dcid')[0]; else if (data.generateClientId) eventModel.client_id = 'dcid.1.' + getTimestampMillis() + '.' + generateRandom(100000000, 999999999); return eventModel; } function addBodyParametersToEventModel(eventModel) { const body = getRequestBody(); if (body) { const bodyJson = JSON.parse(body); if (bodyJson) { for (let bodyKey in bodyJson) { eventModel[bodyKey] = bodyJson[bodyKey]; } } } return eventModel; } function prolongDataTagCookies(eventModel) { if (data.prolongCookies) { let stapeData = getCookieValues('stape'); if (stapeData.length) { setCookie('stape', stapeData[0], { domain: 'auto', path: '/', samesite: getCookieType(eventModel), secure: true, 'max-age': 63072000, // 2 years httpOnly: false }); } } } function addRequiredParametersToEventModel(eventModel) { if (!eventModel.event_name) { let eventName = 'Data'; if (eventModel.eventName) eventName = eventModel.eventName; else if (eventModel.event) eventName = eventModel.event; eventModel.event_name = eventName; } return eventModel; } function exposeFPIDCookie(eventModel) { if (data.exposeFPIDCookie) { let fpid = getCookieValues('FPID'); if (fpid.length) { setCookie('FPIDP', fpid[0], { domain: 'auto', path: '/', samesite: getCookieType(eventModel), secure: true, 'max-age': 63072000, // 2 years httpOnly: false }); } } } function storeClientId(eventModel) { if (data.generateClientId) { setCookie('_dcid', eventModel.client_id, { domain: 'auto', path: '/', samesite: getCookieType(eventModel), secure: true, 'max-age': 63072000, // 2 years httpOnly: false }); } } function getObjectLength(object) { let length = 0; for (let key in object) { if (object.hasOwnProperty(key)) { ++length; } } return length; } function setResponseHeaders() { setResponseHeader('Access-Control-Max-Age', '600'); setResponseHeader('Access-Control-Allow-Origin', getRequestHeader('origin')); setResponseHeader('Access-Control-Allow-Methods', 'GET,POST,PUT,DELETE,OPTIONS'); setResponseHeader('Access-Control-Allow-Headers', 'content-type,set-cookie,x-robots-tag,x-gtm-server-preview,x-stape-preview'); setResponseHeader('Access-Control-Allow-Credentials', 'true'); setResponseStatus(200); } function getCookieType(eventModel) { if (!eventModel.page_location) { return 'Lax'; } const host = getRequestHeader('host'); const effectiveTldPlusOne = computeEffectiveTldPlusOne(eventModel.page_location); if (!host || !effectiveTldPlusOne) { return 'Lax'; } if (host && host.indexOf(effectiveTldPlusOne) !== -1) { return 'Lax'; } return 'None'; } function prepareResponseBody(eventModel) { if (data.responseBody === 'empty') { return; } setResponseHeader('Content-Type', 'application/json'); if (data.responseBody === 'eventData') { setResponseBody(JSON.stringify(eventModel)); return; } setResponseBody(JSON.stringify({ timestamp: eventModel.timestamp, unique_event_id: eventModel.unique_event_id, })); } function getEcommerceAction(eventModel) { if (eventModel.ecommerce) { const actions = ['detail', 'click', 'add', 'remove', 'checkout', 'checkout_option', 'purchase', 'refund']; for (let index = 0; index < actions.length; ++index) { const action = actions[index]; if (eventModel.ecommerce[action]) { return action; } } } return null; } ___SERVER_PERMISSIONS___ [ { "instance": { "key": { "publicId": "return_response", "versionId": "1" }, "param": [] }, "isRequired": true }, { "instance": { "key": { "publicId": "access_response", "versionId": "1" }, "param": [ { "key": "writeResponseAccess", "value": { "type": 1, "string": "any" } }, { "key": "writeHeaderAccess", "value": { "type": 1, "string": "specific" } } ] }, "clientAnnotations": { "isEditedByUser": true }, "isRequired": true }, { "instance": { "key": { "publicId": "run_container", "versionId": "1" }, "param": [] }, "isRequired": true }, { "instance": { "key": { "publicId": "get_cookies", "versionId": "1" }, "param": [ { "key": "cookieAccess", "value": { "type": 1, "string": "specific" } }, { "key": "cookieNames", "value": { "type": 2, "listItem": [ { "type": 1, "string": "stape" }, { "type": 1, "string": "_dcid" }, { "type": 1, "string": "FPIDP" } ] } } ] }, "clientAnnotations": { "isEditedByUser": true }, "isRequired": true }, { "instance": { "key": { "publicId": "read_request", "versionId": "1" }, "param": [ { "key": "requestAccess", "value": { "type": 1, "string": "any" } }, { "key": "headerAccess", "value": { "type": 1, "string": "any" } }, { "key": "queryParameterAccess", "value": { "type": 1, "string": "any" } } ] }, "clientAnnotations": { "isEditedByUser": true }, "isRequired": true }, { "instance": { "key": { "publicId": "set_cookies", "versionId": "1" }, "param": [ { "key": "allowedCookies", "value": { "type": 2, "listItem": [ { "type": 3, "mapKey": [ { "type": 1, "string": "name" }, { "type": 1, "string": "domain" }, { "type": 1, "string": "path" }, { "type": 1, "string": "secure" }, { "type": 1, "string": "session" } ], "mapValue": [ { "type": 1, "string": "stape" }, { "type": 1, "string": "*" }, { "type": 1, "string": "*" }, { "type": 1, "string": "any" }, { "type": 1, "string": "any" } ] }, { "type": 3, "mapKey": [ { "type": 1, "string": "name" }, { "type": 1, "string": "domain" }, { "type": 1, "string": "path" }, { "type": 1, "string": "secure" }, { "type": 1, "string": "session" } ], "mapValue": [ { "type": 1, "string": "_dcid" }, { "type": 1, "string": "*" }, { "type": 1, "string": "*" }, { "type": 1, "string": "any" }, { "type": 1, "string": "any" } ] }, { "type": 3, "mapKey": [ { "type": 1, "string": "name" }, { "type": 1, "string": "domain" }, { "type": 1, "string": "path" }, { "type": 1, "string": "secure" }, { "type": 1, "string": "session" } ], "mapValue": [ { "type": 1, "string": "FPIDP" }, { "type": 1, "string": "*" }, { "type": 1, "string": "*" }, { "type": 1, "string": "any" }, { "type": 1, "string": "any" } ] } ] } } ] }, "clientAnnotations": { "isEditedByUser": true }, "isRequired": true } ] ___TESTS___ scenarios: [] ___NOTES___ Created on 21/03/2021, 11:24:30