Untitled
unknown
plain_text
2 years ago
16 kB
6
Indexable
const encodeUriComponent = require('encodeUriComponent');
const getAllEventData = require('getAllEventData');
const JSON = require('JSON');
const Math = require('Math');
const sendHttpRequest = require('sendHttpRequest');
const getTimestampMillis = require('getTimestampMillis');
const setCookie = require('setCookie');
const getCookieValues = require('getCookieValues');
const getContainerVersion = require('getContainerVersion');
const logToConsole = require('logToConsole');
const sha256Sync = require('sha256Sync');
const decodeUriComponent = require('decodeUriComponent');
const parseUrl = require('parseUrl');
const computeEffectiveTldPlusOne = require('computeEffectiveTldPlusOne');
const generateRandom = require('generateRandom');
const getRequestHeader = require('getRequestHeader');
const getType = require('getType');
const makeString = require('makeString');
const makeNumber = require('makeNumber');
const isLoggingEnabled = determinateIsLoggingEnabled();
const traceId = isLoggingEnabled ? getRequestHeader('trace-id') : undefined;
const eventData = getAllEventData();
const url = eventData.page_location || getRequestHeader('referer');
const subDomainIndex = url
? computeEffectiveTldPlusOne(url).split('.').length - 1
: 1;
if (url && url.lastIndexOf('https://gtm-msr.appspot.com/', 0) === 0) {
return data.gtmOnSuccess();
}
let fbc = getCookieValues('_fbc')[0];
let fbp = getCookieValues('_fbp')[0];
if (!fbc) fbc = eventData._fbc;
if (!fbp) fbp = eventData._fbp;
if (url) {
const urlParsed = parseUrl(url);
if (urlParsed && urlParsed.searchParams.fbclid) {
if (
!fbc ||
(fbc &&
fbc.split('.')[fbc.split('.').length - 1] !==
decodeUriComponent(urlParsed.searchParams.fbclid))
) {
fbc =
'fb.' +
subDomainIndex +
'.' +
getTimestampMillis() +
'.' +
decodeUriComponent(urlParsed.searchParams.fbclid);
}
}
}
if (!fbp && data.generateFbp) {
fbp =
'fb.' +
subDomainIndex +
'.' +
getTimestampMillis() +
'.' +
generateRandom(1000000000, 2147483647);
}
const apiVersion = '15.0';
const postUrl =
'https://graph.facebook.com/v' +
apiVersion +
'/' +
enc(data.pixelId) +
'/events?access_token=' +
enc(data.accessToken);
const mappedEventData = mapEvent(eventData, data);
const postBody = {
data: [mappedEventData],
partner_agent: 'stape-gtmss-2.0.0',
};
if (eventData.test_event_code || data.testId) {
postBody.test_event_code = eventData.test_event_code
? eventData.test_event_code
: data.testId;
}
if (isLoggingEnabled) {
logToConsole(
JSON.stringify({
Name: 'Facebook',
Type: 'Request',
TraceId: traceId,
EventName: mappedEventData.event_name,
RequestMethod: 'POST',
RequestUrl: postUrl,
RequestBody: postBody,
})
);
}
sendHttpRequest(
postUrl,
(statusCode, headers, body) => {
if (isLoggingEnabled) {
logToConsole(
JSON.stringify({
Name: 'Facebook',
Type: 'Response',
TraceId: traceId,
EventName: mappedEventData.event_name,
ResponseStatusCode: statusCode,
ResponseHeaders: headers,
ResponseBody: body,
})
);
}
if (statusCode >= 200 && statusCode < 300) {
if (fbc) {
setCookie('_fbc', fbc, {
domain: 'auto',
path: '/',
samesite: 'Lax',
secure: true,
'max-age': 7776000, // 90 days
HttpOnly: !!data.useHttpOnlyCookie,
});
}
if (fbp) {
setCookie('_fbp', fbp, {
domain: 'auto',
path: '/',
samesite: 'Lax',
secure: true,
'max-age': 7776000, // 90 days
HttpOnly: !!data.useHttpOnlyCookie,
});
}
data.gtmOnSuccess();
} else {
data.gtmOnFailure();
}
},
{ headers: { 'content-type': 'application/json' }, method: 'POST' },
JSON.stringify(postBody)
);
function getEventName(data) {
if (data.inheritEventName === 'inherit') {
let eventName = eventData.event_name;
let gaToFacebookEventName = {
page_view: 'PageView',
'gtm.dom': 'PageView',
add_payment_info: 'AddPaymentInfo',
add_to_cart: 'AddToCart',
add_to_wishlist: 'AddToWishlist',
sign_up: 'CompleteRegistration',
begin_checkout: 'InitiateCheckout',
generate_lead: 'Lead',
purchase: 'Purchase',
search: 'Search',
view_item: 'ViewContent',
contact: 'Contact',
customize_product: 'CustomizeProduct',
donate: 'Donate',
find_location: 'FindLocation',
schedule: 'Schedule',
start_trial: 'StartTrial',
submit_application: 'SubmitApplication',
subscribe: 'Subscribe',
'gtm4wp.addProductToCartEEC': 'AddToCart',
'gtm4wp.productClickEEC': 'ViewContent',
'gtm4wp.checkoutOptionEEC': 'InitiateCheckout',
'gtm4wp.checkoutStepEEC': 'AddPaymentInfo',
'gtm4wp.orderCompletedEEC': 'Purchase',
};
if (!gaToFacebookEventName[eventName]) {
return eventName;
}
return gaToFacebookEventName[eventName];
}
return data.eventName === 'standard'
? data.eventNameStandard
: data.eventNameCustom;
}
function mapEvent(eventData, data) {
let eventName = getEventName(data);
let mappedData = {
event_name: eventName,
action_source: 'website',
event_source_url: eventData.page_location,
event_time: Math.round(getTimestampMillis() / 1000),
custom_data: {},
user_data: {
client_user_agent: eventData.user_agent,
},
};
if (eventData.ip_override) {
mappedData.user_data.client_ip_address = eventData.ip_override
.split(' ')
.join('')
.split(',')[0];
}
if (fbc) mappedData.user_data.fbc = fbc;
if (fbp) mappedData.user_data.fbp = fbp;
mappedData = addServerEventData(eventData, data, mappedData);
mappedData = addUserData(eventData, mappedData);
mappedData = addEcommerceData(eventData, mappedData);
mappedData = overrideDataIfNeeded(data, mappedData);
mappedData = cleanupData(mappedData);
mappedData = hashDataIfNeeded(mappedData);
return mappedData;
}
function enc(data) {
data = data || '';
return encodeUriComponent(data);
}
function isHashed(value) {
if (!value) {
return false;
}
return makeString(value).match('^[A-Fa-f0-9]{64}$') !== null;
}
function hashData(key, value) {
if (!value) {
return value;
}
const type = getType(value);
if (type === 'undefined' || value === 'undefined') {
return undefined;
}
if (type === 'object') {
return value.map((val) => {
return hashData(key, val);
});
}
if (isHashed(value)) {
return value;
}
value = makeString(value).trim().toLowerCase();
if (key === 'ph') {
value = value
.split(' ')
.join('')
.split('-')
.join('')
.split('(')
.join('')
.split(')')
.join('')
.split('+')
.join('');
} else if (key === 'ct') {
value = value.split(' ').join('');
}
return sha256Sync(value, { outputEncoding: 'hex' });
}
function hashDataIfNeeded(mappedData) {
if (mappedData.user_data) {
for (let key in mappedData.user_data) {
if (
key === 'em' ||
key === 'ph' ||
key === 'ge' ||
key === 'db' ||
key === 'ln' ||
key === 'fn' ||
key === 'ct' ||
key === 'st' ||
key === 'zp' ||
key === 'country'
) {
mappedData.user_data[key] = hashData(key, mappedData.user_data[key]);
}
}
}
return mappedData;
}
function overrideDataIfNeeded(data, mappedData) {
if (data.userDataList) {
data.userDataList.forEach((d) => {
mappedData.user_data[d.name] = d.value;
});
}
if (data.customDataList) {
data.customDataList.forEach((d) => {
mappedData.custom_data[d.name] = d.value;
});
}
return mappedData;
}
function cleanupData(mappedData) {
if (mappedData.user_data) {
let userData = {};
for (let userDataKey in mappedData.user_data) {
if (mappedData.user_data[userDataKey]) {
userData[userDataKey] = mappedData.user_data[userDataKey];
}
}
mappedData.user_data = userData;
}
if (mappedData.custom_data) {
let customData = {};
for (let customDataKey in mappedData.custom_data) {
if (mappedData.custom_data[customDataKey] || customDataKey === 'value') {
customData[customDataKey] = mappedData.custom_data[customDataKey];
}
}
mappedData.custom_data = customData;
}
return mappedData;
}
function addEcommerceData(eventData, mappedData) {
let currencyFromItems = '';
let valueFromItems = 0;
if (eventData.items && eventData.items[0]) {
mappedData.custom_data.contents = [];
mappedData.custom_data.content_type = 'product';
currencyFromItems = eventData.items[0].currency;
if (!eventData.items[1]) {
if (eventData.items[0].item_name)
mappedData.custom_data.content_name = eventData.items[0].item_name;
if (eventData.items[0].item_category)
mappedData.custom_data.content_category =
eventData.items[0].item_category;
if (eventData.items[0].price) {
mappedData.custom_data.value = eventData.items[0].quantity
? eventData.items[0].quantity * eventData.items[0].price
: eventData.items[0].price;
}
}
const itemIdKey = data.itemIdKey ? data.itemIdKey : 'item_id';
eventData.items.forEach((d, i) => {
let content = {};
if (d[itemIdKey]) content.id = d[itemIdKey];
if (d.item_name) content.title = d.item_name;
if (d.item_brand) content.brand = d.item_brand;
if (d.quantity) content.quantity = d.quantity;
if (d.item_category) content.category = d.item_category;
if (d.price) {
content.item_price = makeNumber(d.price);
valueFromItems += d.quantity
? d.quantity * content.item_price
: content.item_price;
}
mappedData.custom_data.contents.push(content);
});
}
if (eventData['x-ga-mp1-ev'])
mappedData.custom_data.value = eventData['x-ga-mp1-ev'];
else if (eventData['x-ga-mp1-tr'])
mappedData.custom_data.value = eventData['x-ga-mp1-tr'];
else if (eventData.value) mappedData.custom_data.value = eventData.value;
if (eventData.currency) mappedData.custom_data.currency = eventData.currency;
else if (currencyFromItems)
mappedData.custom_data.currency = currencyFromItems;
if (eventData.search_term)
mappedData.custom_data.search_string = eventData.search_term;
if (eventData.transaction_id)
mappedData.custom_data.order_id = eventData.transaction_id;
if (mappedData.event_name === 'Purchase') {
if (!mappedData.custom_data.currency) {
mappedData.custom_data.currency = 'USD';
}
if (!mappedData.custom_data.value) {
mappedData.custom_data.value = valueFromItems ? valueFromItems : 0;
}
}
return mappedData;
}
function addUserData(eventData, mappedData) {
let address = {};
let user_data = {};
if (getType(eventData.user_data) === 'object') {
user_data = eventData.user_data;
const addressType = getType(user_data.address);
if (addressType === 'object' || addressType === 'array') {
address = user_data.address[0] || user_data.address;
}
}
if (eventData.fb_login_id)
mappedData.user_data.fb_login_id = eventData.fb_login_id;
if (eventData.external_id)
mappedData.user_data.external_id = eventData.external_id;
else if (eventData.user_id)
mappedData.user_data.external_id = eventData.user_id;
else if (eventData.userId)
mappedData.user_data.external_id = eventData.userId;
if (eventData.subscription_id)
mappedData.user_data.subscription_id = eventData.subscription_id;
else if (eventData.subscriptionId)
mappedData.user_data.subscription_id = eventData.subscriptionId;
if (eventData.lead_id) mappedData.user_data.lead_id = eventData.lead_id;
else if (eventData.leadId) mappedData.user_data.lead_id = eventData.leadId;
if (eventData.lastName) mappedData.user_data.ln = eventData.lastName;
else if (eventData.LastName) mappedData.user_data.ln = eventData.LastName;
else if (eventData.nameLast) mappedData.user_data.ln = eventData.nameLast;
else if (eventData.last_name) mappedData.user_data.ln = eventData.last_name;
else if (user_data.last_name) mappedData.user_data.ln = user_data.last_name;
else if (address.last_name) mappedData.user_data.ln = address.last_name;
if (eventData.firstName) mappedData.user_data.fn = eventData.firstName;
else if (eventData.FirstName) mappedData.user_data.fn = eventData.FirstName;
else if (eventData.nameFirst) mappedData.user_data.fn = eventData.nameFirst;
else if (eventData.first_name) mappedData.user_data.fn = eventData.first_name;
else if (user_data.first_name) mappedData.user_data.fn = user_data.first_name;
else if (address.first_name) mappedData.user_data.fn = address.first_name;
if (eventData.email) mappedData.user_data.em = eventData.email;
else if (user_data.email_address)
mappedData.user_data.em = user_data.email_address;
else if (user_data.email) mappedData.user_data.em = user_data.email;
if (eventData.phone) mappedData.user_data.ph = eventData.phone;
else if (user_data.phone_number)
mappedData.user_data.ph = user_data.phone_number;
if (eventData.city) mappedData.user_data.ct = eventData.city;
else if (address.city) mappedData.user_data.ct = address.city;
if (eventData.state) mappedData.user_data.st = eventData.state;
else if (eventData.region) mappedData.user_data.st = eventData.region;
else if (user_data.region) mappedData.user_data.st = user_data.region;
else if (address.region) mappedData.user_data.st = address.region;
if (eventData.zip) mappedData.user_data.zp = eventData.zip;
else if (eventData.postal_code)
mappedData.user_data.zp = eventData.postal_code;
else if (user_data.postal_code)
mappedData.user_data.zp = user_data.postal_code;
else if (address.postal_code) mappedData.user_data.zp = address.postal_code;
if (eventData.countryCode)
mappedData.user_data.country = eventData.countryCode;
else if (eventData.country) mappedData.user_data.country = eventData.country;
else if (user_data.country) mappedData.user_data.country = user_data.country;
else if (address.country) mappedData.user_data.country = address.country;
if (eventData.gender) mappedData.user_data.ge = eventData.gender;
if (eventData.db) mappedData.user_data.db = eventData.db;
return mappedData;
}
function addServerEventData(eventData, data, mappedData) {
let serverEventDataList = {};
if (eventData.event_id) mappedData.event_id = eventData.event_id;
else if (eventData.transaction_id)
mappedData.event_id = eventData.transaction_id;
if (data.serverEventDataList) {
data.serverEventDataList.forEach((d) => {
serverEventDataList[d.name] = d.value;
});
}
if (serverEventDataList) {
if (serverEventDataList.action_source)
mappedData.action_source = serverEventDataList.action_source;
if (serverEventDataList.event_time)
mappedData.event_time = serverEventDataList.event_time;
if (serverEventDataList.event_source_url)
mappedData.event_source_url = serverEventDataList.event_source_url;
if (serverEventDataList.opt_out)
mappedData.opt_out = serverEventDataList.opt_out;
if (serverEventDataList.event_id)
mappedData.event_id = serverEventDataList.event_id;
if (serverEventDataList.data_processing_options) {
mappedData.data_processing_options =
serverEventDataList.data_processing_options;
if (serverEventDataList.data_processing_options_country)
mappedData.data_processing_options_country =
serverEventDataList.data_processing_options_country;
if (serverEventDataList.data_processing_options_state)
mappedData.data_processing_options_state =
serverEventDataList.data_processing_options_state;
}
}
return mappedData;
}
function determinateIsLoggingEnabled() {
const containerVersion = getContainerVersion();
const isDebug = !!(
containerVersion &&
(containerVersion.debugMode || containerVersion.previewMode)
);
if (!data.logType) {
return isDebug;
}
if (data.logType === 'no') {
return false;
}
if (data.logType === 'debug') {
return isDebug;
}
return data.logType === 'always';
}Editor is loading...