From 5abe2733e8d25f3c7b51fd068b268b39d5d46d0d Mon Sep 17 00:00:00 2001 From: sandeepdigumarty Date: Tue, 10 Oct 2023 14:58:55 +0530 Subject: [PATCH 1/4] feat: facebook pixel audit refactor --- src/v0/destinations/facebook_pixel/config.js | 30 +++- .../destinations/facebook_pixel/transform.js | 167 +++++------------- src/v0/destinations/facebook_pixel/utils.js | 87 +++++++-- 3 files changed, 146 insertions(+), 138 deletions(-) diff --git a/src/v0/destinations/facebook_pixel/config.js b/src/v0/destinations/facebook_pixel/config.js index 09be8e043d..99c3c70b2d 100644 --- a/src/v0/destinations/facebook_pixel/config.js +++ b/src/v0/destinations/facebook_pixel/config.js @@ -15,31 +15,37 @@ const CONFIG_CATEGORIES = { PRODUCT_LIST_VIEWED: { standard: true, type: 'product list viewed', + eventName: 'ViewContent', name: 'FBPIXELPSimpleCustomConfig', }, PRODUCT_VIEWED: { standard: true, type: 'product viewed', + eventName: 'ViewContent', name: 'FBPIXELPSimpleCustomConfig', }, PRODUCT_ADDED: { standard: true, type: 'product added', + eventName: 'AddToCart', name: 'FBPIXELPSimpleCustomConfig', }, ORDER_COMPLETED: { standard: true, type: 'order completed', + eventName: 'Purchase', name: 'FBPIXELPSimpleCustomConfig', }, PRODUCTS_SEARCHED: { standard: true, type: 'products searched', + eventName: 'Search', name: 'FBPIXELPSimpleCustomConfig', }, CHECKOUT_STARTED: { standard: true, type: 'checkout started', + eventName: 'InitiateCheckout', name: 'FBPIXELPSimpleCustomConfig', }, OTHER_STANDARD: { @@ -50,9 +56,15 @@ const CONFIG_CATEGORIES = { PAGE_VIEW: { standard: true, type: 'page_view', + eventName: 'PageView', + name: 'FBPIXELPSimpleCustomConfig', + }, + PAGE: { + standard: false, + type: 'page', + eventName: 'PageView', name: 'FBPIXELPSimpleCustomConfig', }, - PAGE: { standard: false, type: 'page', name: 'FBPIXELPSimpleCustomConfig' }, }; const MAPPING_CONFIG = getMappingConfig(CONFIG_CATEGORIES, __dirname); @@ -67,6 +79,21 @@ const ACTION_SOURCES_VALUES = [ 'other', ]; +const OTHER_STANDARD_EVENTS = [ + 'AddToWishlist', + 'AddPaymentInfo', + 'Lead', + 'CompleteRegistration', + 'Contact', + 'CustomizeProduct', + 'Donate', + 'FindLocation', + 'Schedule', + 'StartTrial', + 'SubmitApplication', + 'Subscribe', +]; + const FB_PIXEL_DEFAULT_EXCLUSION = ['opt_out', 'event_id', 'action_source']; const STANDARD_ECOMM_EVENTS_TYPE = [ CONFIG_CATEGORIES.PRODUCT_LIST_VIEWED.type, @@ -83,5 +110,6 @@ module.exports = { ACTION_SOURCES_VALUES, FB_PIXEL_DEFAULT_EXCLUSION, STANDARD_ECOMM_EVENTS_TYPE, + OTHER_STANDARD_EVENTS, DESTINATION: 'FACEBOOK_PIXEL', }; diff --git a/src/v0/destinations/facebook_pixel/transform.js b/src/v0/destinations/facebook_pixel/transform.js index c81718dea0..1c792cfdc0 100644 --- a/src/v0/destinations/facebook_pixel/transform.js +++ b/src/v0/destinations/facebook_pixel/transform.js @@ -7,6 +7,7 @@ const { MAPPING_CONFIG, FB_PIXEL_DEFAULT_EXCLUSION, STANDARD_ECOMM_EVENTS_TYPE, + OTHER_STANDARD_EVENTS, } = require('./config'); const { EventType } = require('../../../constants'); @@ -17,6 +18,7 @@ const { getIntegrationsObj, getValidDynamicFormConfig, simpleProcessRouterDest, + getHashFromArray, } = require('../../util'); const { @@ -28,13 +30,18 @@ const { handleProductListViewed, handleOrder, formingFinalResponse, + populateCustomDataBasedOnCategory, } = require('./utils'); const { InstrumentationError, ConfigurationError } = require('../../util/errorTypes'); -const responseBuilderSimple = (message, category, destination, categoryToContent) => { - const { Config } = destination; +const responseBuilderSimple = (message, category, destination) => { + const { Config, ID } = destination; const { pixelId, accessToken } = Config; + let { categoryToContent } = Config; + if (Array.isArray(categoryToContent)) { + categoryToContent = getValidDynamicFormConfig(categoryToContent, 'from', 'to', 'FB_PIXEL', ID); + } if (!pixelId) { throw new ConfigurationError('Pixel Id not found. Aborting'); @@ -59,12 +66,15 @@ const responseBuilderSimple = (message, category, destination, categoryToContent const userData = fetchUserData(message, Config); - let customData = {}; - let commonData = {}; - - commonData = constructPayload(message, MAPPING_CONFIG[CONFIG_CATEGORIES.COMMON.name], 'fb_pixel'); + const commonData = constructPayload( + message, + MAPPING_CONFIG[CONFIG_CATEGORIES.COMMON.name], + 'fb_pixel', + ); commonData.action_source = getActionSource(commonData, message?.channel); + let customData = {}; + if (category.type !== 'identify') { customData = flattenJson( extractCustomFields(message, customData, ['properties'], FB_PIXEL_DEFAULT_EXCLUSION), @@ -85,71 +95,17 @@ const responseBuilderSimple = (message, category, destination, categoryToContent category.standard, integrationsObj, ); - message.properties = message.properties || {}; if (category.standard) { - switch (category.type) { - case 'product list viewed': - customData = { - ...customData, - ...handleProductListViewed(message, categoryToContent), - }; - commonData.event_name = 'ViewContent'; - break; - case 'product viewed': - customData = { - ...customData, - ...handleProduct(message, categoryToContent, valueFieldIdentifier), - }; - commonData.event_name = 'ViewContent'; - break; - case 'product added': - customData = { - ...customData, - ...handleProduct(message, categoryToContent, valueFieldIdentifier), - }; - commonData.event_name = 'AddToCart'; - break; - case 'order completed': - customData = { - ...customData, - ...handleOrder(message, categoryToContent), - }; - commonData.event_name = 'Purchase'; - break; - case 'products searched': { - customData = { - ...customData, - ...handleSearch(message), - }; - commonData.event_name = 'Search'; - break; - } - case 'checkout started': { - const orderPayload = handleOrder(message, categoryToContent); - delete orderPayload.content_name; - customData = { - ...customData, - ...orderPayload, - }; - commonData.event_name = 'InitiateCheckout'; - break; - } - case 'page_view': // executed when sending track calls but with standard type PageView - case 'page': // executed when page call is done with standard PageView turned on - customData = { ...customData }; - commonData.event_name = 'PageView'; - break; - case 'otherStandard': - customData = { ...customData }; - commonData.event_name = category.event; - break; - default: - throw new InstrumentationError( - `${category.standard} type of standard event does not exist`, - ); - } + commonData.event_name = category.eventName; + customData = populateCustomDataBasedOnCategory( + customData, + message, + category, + categoryToContent, + valueFieldIdentifier, + ); customData.currency = STANDARD_ECOMM_EVENTS_TYPE.includes(category.type) - ? message.properties.currency || 'USD' + ? message.properties?.currency || 'USD' : undefined; } else { const { type } = category; @@ -159,7 +115,7 @@ const responseBuilderSimple = (message, category, destination, categoryToContent : `Viewed a ${type}`; } if (type === 'simple track') { - customData.value = message.properties ? message.properties.revenue : undefined; + customData.value = message.properties?.revenue; delete customData.revenue; } } @@ -189,54 +145,45 @@ const responseBuilderSimple = (message, category, destination, categoryToContent ); }; -function getCategoryFromEvent(checkEvent) { +function getCategoryFromEvent(eventName) { let category; - switch (checkEvent) { + switch (eventName) { case CONFIG_CATEGORIES.PRODUCT_LIST_VIEWED.type: - case 'ViewContent': + case CONFIG_CATEGORIES.PRODUCT_LIST_VIEWED.eventName: category = CONFIG_CATEGORIES.PRODUCT_LIST_VIEWED; break; case CONFIG_CATEGORIES.PRODUCT_VIEWED.type: category = CONFIG_CATEGORIES.PRODUCT_VIEWED; break; case CONFIG_CATEGORIES.PRODUCT_ADDED.type: - case 'AddToCart': + case CONFIG_CATEGORIES.PRODUCT_ADDED.eventName: category = CONFIG_CATEGORIES.PRODUCT_ADDED; break; case CONFIG_CATEGORIES.ORDER_COMPLETED.type: - case 'Purchase': + case CONFIG_CATEGORIES.ORDER_COMPLETED.eventName: category = CONFIG_CATEGORIES.ORDER_COMPLETED; break; case CONFIG_CATEGORIES.PRODUCTS_SEARCHED.type: - case 'Search': + case CONFIG_CATEGORIES.PRODUCTS_SEARCHED.eventName: category = CONFIG_CATEGORIES.PRODUCTS_SEARCHED; break; case CONFIG_CATEGORIES.CHECKOUT_STARTED.type: - case 'InitiateCheckout': + case CONFIG_CATEGORIES.CHECKOUT_STARTED.eventName: category = CONFIG_CATEGORIES.CHECKOUT_STARTED; break; - case 'AddToWishlist': - case 'AddPaymentInfo': - case 'Lead': - case 'CompleteRegistration': - case 'Contact': - case 'CustomizeProduct': - case 'Donate': - case 'FindLocation': - case 'Schedule': - case 'StartTrial': - case 'SubmitApplication': - case 'Subscribe': - category = CONFIG_CATEGORIES.OTHER_STANDARD; - category.event = checkEvent; - break; - case 'PageView': + case CONFIG_CATEGORIES.PAGE_VIEW.eventName: category = CONFIG_CATEGORIES.PAGE_VIEW; break; default: category = CONFIG_CATEGORIES.SIMPLE_TRACK; break; } + + if (OTHER_STANDARD_EVENTS.includes(eventName)) { + category = CONFIG_CATEGORIES.OTHER_STANDARD; + category.eventName = eventName; + } + return category; } @@ -265,7 +212,7 @@ const processEvent = (message, destination) => { } let eventsToEvents; - if (destination.Config.eventsToEvents) + if (Array.isArray(destination.Config.eventsToEvents)) { eventsToEvents = getValidDynamicFormConfig( destination.Config.eventsToEvents, 'from', @@ -273,21 +220,12 @@ const processEvent = (message, destination) => { 'FB_PIXEL', destination.ID, ); - let categoryToContent; - if (destination.Config.categoryToContent) - categoryToContent = getValidDynamicFormConfig( - destination.Config.categoryToContent, - 'from', - 'to', - 'FB_PIXEL', - destination.ID, - ); + } + const { advancedMapping } = destination.Config; - let standard; - let standardTo = ''; - let checkEvent; const messageType = message.type.toLowerCase(); let category; + let mappedEvent; switch (messageType) { case EventType.IDENTIFY: if (advancedMapping) { @@ -309,24 +247,17 @@ const processEvent = (message, destination) => { if (typeof message.event !== 'string') { throw new InstrumentationError('event name should be string'); } - standard = eventsToEvents; - if (standard) { - standardTo = standard.reduce((filtered, standards) => { - if (standards.from.toLowerCase() === message.event.toLowerCase()) { - filtered = standards.to; - } - return filtered; - }, ''); + if (eventsToEvents) { + const eventMappingHash = getHashFromArray(eventsToEvents); + mappedEvent = eventMappingHash[message.event.toLowerCase()]; } - checkEvent = standardTo !== '' ? standardTo : message.event.toLowerCase(); - - category = getCategoryFromEvent(checkEvent); + category = getCategoryFromEvent(mappedEvent || message.event.toLowerCase()); break; default: throw new InstrumentationError(`Message type ${messageType} not supported`); } // build the response - return responseBuilderSimple(message, category, destination, categoryToContent); + return responseBuilderSimple(message, category, destination); }; const process = (event) => processEvent(event.message, event.destination); diff --git a/src/v0/destinations/facebook_pixel/utils.js b/src/v0/destinations/facebook_pixel/utils.js index e1347278bf..2bcd6a5ff2 100644 --- a/src/v0/destinations/facebook_pixel/utils.js +++ b/src/v0/destinations/facebook_pixel/utils.js @@ -7,6 +7,7 @@ const { constructPayload, defaultPostRequestConfig, defaultRequestConfig, + getHashFromArray, } = require('../../util'); const { ACTION_SOURCES_VALUES, CONFIG_CATEGORIES, MAPPING_CONFIG } = require('./config'); @@ -18,7 +19,7 @@ const { InstrumentationError, TransformationError } = require('../../util/errorT */ const formatRevenue = (revenue) => { - const formattedRevenue = parseFloat(parseFloat(revenue || 0).toFixed(2)); + const formattedRevenue = parseFloat(parseFloat(revenue || '0').toFixed(2)); if (!Number.isNaN(formattedRevenue)) { return formattedRevenue; } @@ -29,7 +30,7 @@ const formatRevenue = (revenue) => { * * @param {*} message Rudder Payload * @param {*} defaultValue product / product_group - * @param {*} categoryToContent [ { from: 'clothing', to: 'product' } ] + * @param {*} categoryToContent example: [ { from: 'clothing', to: 'product' } ] * * We will be mapping properties.category to user provided content else taking the default value as per ecomm spec * If category is clothing it will be set to ["product"] @@ -37,7 +38,6 @@ const formatRevenue = (revenue) => { * - https://developers.facebook.com/docs/facebook-pixel/reference/#object-properties */ const getContentType = (message, defaultValue, categoryToContent) => { - let tempCategoryToContent = categoryToContent; const { properties } = message; const integrationsObj = getIntegrationsObj(message, 'fb_pixel'); @@ -51,22 +51,15 @@ const getContentType = (message, defaultValue, categoryToContent) => { if (products && products.length > 0 && Array.isArray(products) && isObject(products[0])) { category = products[0].category; } - } else { - if (tempCategoryToContent === undefined) { - tempCategoryToContent = []; - } - const mapped = tempCategoryToContent; - const mappedTo = mapped.reduce((filtered, map) => { - let filter = filtered; - if (map.from === category) { - filter = map.to; - } - return filter; - }, ''); - if (mappedTo.length > 0) { - return mappedTo; + } + + if (Array.isArray(categoryToContent) && category) { + const categoryToContentHash = getHashFromArray(categoryToContent, 'from', 'to', false); + if (categoryToContentHash[category]) { + return categoryToContentHash[category]; } } + return defaultValue; }; @@ -190,7 +183,7 @@ const transformedPayloadData = ( /** * * @param {*} message - * @returns fbc parameter which is a combined string of the parameters below + * @returns string which is fbc parameter * * version : "fb" (default) * @@ -405,7 +398,7 @@ const handleProductListViewed = (message, categoryToContent) => { /** * * @param {*} message Rudder Payload - * @param {*} categoryToContent [ { from: 'clothing', to: 'product' } ] + * @param {*} categoryToContent Example: [ { from: 'clothing', to: 'product' } ] * @param {*} valueFieldIdentifier it can be either value or price which will be matched from properties and assigned to value for fb payload */ const handleProduct = (message, categoryToContent, valueFieldIdentifier) => { @@ -476,6 +469,61 @@ const handleSearch = (message) => { }; }; +const populateCustomDataBasedOnCategory = ( + customData, + message, + category, + categoryToContent, + valueFieldIdentifier, +) => { + let updatedCustomData; + switch (category.type) { + case 'product list viewed': + updatedCustomData = { + ...customData, + ...handleProductListViewed(message, categoryToContent), + }; + break; + case 'product viewed': + case 'product added': + updatedCustomData = { + ...customData, + ...handleProduct(message, categoryToContent, valueFieldIdentifier), + }; + break; + case 'order completed': + updatedCustomData = { + ...customData, + ...handleOrder(message, categoryToContent), + }; + break; + case 'products searched': { + updatedCustomData = { + ...customData, + ...handleSearch(message), + }; + break; + } + case 'checkout started': { + const orderPayload = handleOrder(message, categoryToContent); + delete orderPayload.content_name; + updatedCustomData = { + ...customData, + ...orderPayload, + }; + break; + } + case 'page_view': // executed when sending track calls but with standard type PageView + case 'page': // executed when page call is done with standard PageView turned on + case 'otherStandard': + updatedCustomData = { ...customData }; + break; + default: + throw new InstrumentationError(`${category.standard} type of standard event does not exist`); + } + return updatedCustomData; +}; + const formingFinalResponse = ( userData, commonData, @@ -521,4 +569,5 @@ module.exports = { handleProductListViewed, handleOrder, formingFinalResponse, + populateCustomDataBasedOnCategory, }; From 3980223359228b38e848d0d48dc3e7d007312b44 Mon Sep 17 00:00:00 2001 From: sandeepdigumarty Date: Tue, 10 Oct 2023 15:11:20 +0530 Subject: [PATCH 2/4] feat: moved a function to util --- .../destinations/facebook_pixel/transform.js | 44 +--------------- src/v0/destinations/facebook_pixel/utils.js | 50 ++++++++++++++++++- 2 files changed, 50 insertions(+), 44 deletions(-) diff --git a/src/v0/destinations/facebook_pixel/transform.js b/src/v0/destinations/facebook_pixel/transform.js index 1c792cfdc0..4a4c79af9e 100644 --- a/src/v0/destinations/facebook_pixel/transform.js +++ b/src/v0/destinations/facebook_pixel/transform.js @@ -7,7 +7,6 @@ const { MAPPING_CONFIG, FB_PIXEL_DEFAULT_EXCLUSION, STANDARD_ECOMM_EVENTS_TYPE, - OTHER_STANDARD_EVENTS, } = require('./config'); const { EventType } = require('../../../constants'); @@ -31,6 +30,7 @@ const { handleOrder, formingFinalResponse, populateCustomDataBasedOnCategory, + getCategoryFromEvent, } = require('./utils'); const { InstrumentationError, ConfigurationError } = require('../../util/errorTypes'); @@ -145,48 +145,6 @@ const responseBuilderSimple = (message, category, destination) => { ); }; -function getCategoryFromEvent(eventName) { - let category; - switch (eventName) { - case CONFIG_CATEGORIES.PRODUCT_LIST_VIEWED.type: - case CONFIG_CATEGORIES.PRODUCT_LIST_VIEWED.eventName: - category = CONFIG_CATEGORIES.PRODUCT_LIST_VIEWED; - break; - case CONFIG_CATEGORIES.PRODUCT_VIEWED.type: - category = CONFIG_CATEGORIES.PRODUCT_VIEWED; - break; - case CONFIG_CATEGORIES.PRODUCT_ADDED.type: - case CONFIG_CATEGORIES.PRODUCT_ADDED.eventName: - category = CONFIG_CATEGORIES.PRODUCT_ADDED; - break; - case CONFIG_CATEGORIES.ORDER_COMPLETED.type: - case CONFIG_CATEGORIES.ORDER_COMPLETED.eventName: - category = CONFIG_CATEGORIES.ORDER_COMPLETED; - break; - case CONFIG_CATEGORIES.PRODUCTS_SEARCHED.type: - case CONFIG_CATEGORIES.PRODUCTS_SEARCHED.eventName: - category = CONFIG_CATEGORIES.PRODUCTS_SEARCHED; - break; - case CONFIG_CATEGORIES.CHECKOUT_STARTED.type: - case CONFIG_CATEGORIES.CHECKOUT_STARTED.eventName: - category = CONFIG_CATEGORIES.CHECKOUT_STARTED; - break; - case CONFIG_CATEGORIES.PAGE_VIEW.eventName: - category = CONFIG_CATEGORIES.PAGE_VIEW; - break; - default: - category = CONFIG_CATEGORIES.SIMPLE_TRACK; - break; - } - - if (OTHER_STANDARD_EVENTS.includes(eventName)) { - category = CONFIG_CATEGORIES.OTHER_STANDARD; - category.eventName = eventName; - } - - return category; -} - const processEvent = (message, destination) => { if (!message.type) { throw new InstrumentationError("'type' is missing"); diff --git a/src/v0/destinations/facebook_pixel/utils.js b/src/v0/destinations/facebook_pixel/utils.js index 2bcd6a5ff2..3b8baba2d7 100644 --- a/src/v0/destinations/facebook_pixel/utils.js +++ b/src/v0/destinations/facebook_pixel/utils.js @@ -9,7 +9,12 @@ const { defaultRequestConfig, getHashFromArray, } = require('../../util'); -const { ACTION_SOURCES_VALUES, CONFIG_CATEGORIES, MAPPING_CONFIG } = require('./config'); +const { + ACTION_SOURCES_VALUES, + CONFIG_CATEGORIES, + MAPPING_CONFIG, + OTHER_STANDARD_EVENTS, +} = require('./config'); const { InstrumentationError, TransformationError } = require('../../util/errorTypes'); @@ -524,6 +529,48 @@ const populateCustomDataBasedOnCategory = ( return updatedCustomData; }; +const getCategoryFromEvent = (eventName) => { + let category; + switch (eventName) { + case CONFIG_CATEGORIES.PRODUCT_LIST_VIEWED.type: + case CONFIG_CATEGORIES.PRODUCT_LIST_VIEWED.eventName: + category = CONFIG_CATEGORIES.PRODUCT_LIST_VIEWED; + break; + case CONFIG_CATEGORIES.PRODUCT_VIEWED.type: + category = CONFIG_CATEGORIES.PRODUCT_VIEWED; + break; + case CONFIG_CATEGORIES.PRODUCT_ADDED.type: + case CONFIG_CATEGORIES.PRODUCT_ADDED.eventName: + category = CONFIG_CATEGORIES.PRODUCT_ADDED; + break; + case CONFIG_CATEGORIES.ORDER_COMPLETED.type: + case CONFIG_CATEGORIES.ORDER_COMPLETED.eventName: + category = CONFIG_CATEGORIES.ORDER_COMPLETED; + break; + case CONFIG_CATEGORIES.PRODUCTS_SEARCHED.type: + case CONFIG_CATEGORIES.PRODUCTS_SEARCHED.eventName: + category = CONFIG_CATEGORIES.PRODUCTS_SEARCHED; + break; + case CONFIG_CATEGORIES.CHECKOUT_STARTED.type: + case CONFIG_CATEGORIES.CHECKOUT_STARTED.eventName: + category = CONFIG_CATEGORIES.CHECKOUT_STARTED; + break; + case CONFIG_CATEGORIES.PAGE_VIEW.eventName: + category = CONFIG_CATEGORIES.PAGE_VIEW; + break; + default: + category = CONFIG_CATEGORIES.SIMPLE_TRACK; + break; + } + + if (OTHER_STANDARD_EVENTS.includes(eventName)) { + category = CONFIG_CATEGORIES.OTHER_STANDARD; + category.eventName = eventName; + } + + return category; +}; + const formingFinalResponse = ( userData, commonData, @@ -570,4 +617,5 @@ module.exports = { handleOrder, formingFinalResponse, populateCustomDataBasedOnCategory, + getCategoryFromEvent, }; From b31ac7ac9b1338b1da648c19db5cfe3d6c3c307d Mon Sep 17 00:00:00 2001 From: sandeepdigumarty Date: Wed, 11 Oct 2023 16:55:09 +0530 Subject: [PATCH 3/4] feat: added event type mapping json for all standard events --- src/v0/destinations/facebook_pixel/config.js | 12 +- .../FBPIXELCheckoutStartedCustomData.json | 48 +++++ .../data/FBPIXELOrderCompletedCustomData.json | 52 +++++ .../data/FBPIXELProductAddedCustomData.json | 48 +++++ .../FBPIXELProductListViewedCustomData.json | 35 +++ .../FBPIXELProductSearchedCustomData.json | 39 ++++ .../data/FBPIXELProductViewedCustomData.json | 56 +++++ .../destinations/facebook_pixel/transform.js | 10 +- .../facebook_pixel/transform.test.js | 201 ------------------ src/v0/destinations/facebook_pixel/utils.js | 166 +++++---------- 10 files changed, 339 insertions(+), 328 deletions(-) create mode 100644 src/v0/destinations/facebook_pixel/data/FBPIXELCheckoutStartedCustomData.json create mode 100644 src/v0/destinations/facebook_pixel/data/FBPIXELOrderCompletedCustomData.json create mode 100644 src/v0/destinations/facebook_pixel/data/FBPIXELProductAddedCustomData.json create mode 100644 src/v0/destinations/facebook_pixel/data/FBPIXELProductListViewedCustomData.json create mode 100644 src/v0/destinations/facebook_pixel/data/FBPIXELProductSearchedCustomData.json create mode 100644 src/v0/destinations/facebook_pixel/data/FBPIXELProductViewedCustomData.json delete mode 100644 src/v0/destinations/facebook_pixel/transform.test.js diff --git a/src/v0/destinations/facebook_pixel/config.js b/src/v0/destinations/facebook_pixel/config.js index 99c3c70b2d..e3c20d291c 100644 --- a/src/v0/destinations/facebook_pixel/config.js +++ b/src/v0/destinations/facebook_pixel/config.js @@ -16,37 +16,37 @@ const CONFIG_CATEGORIES = { standard: true, type: 'product list viewed', eventName: 'ViewContent', - name: 'FBPIXELPSimpleCustomConfig', + name: 'FBPIXELProductListViewedCustomData', }, PRODUCT_VIEWED: { standard: true, type: 'product viewed', eventName: 'ViewContent', - name: 'FBPIXELPSimpleCustomConfig', + name: 'FBPIXELProductViewedCustomData', }, PRODUCT_ADDED: { standard: true, type: 'product added', eventName: 'AddToCart', - name: 'FBPIXELPSimpleCustomConfig', + name: 'FBPIXELProductAddedCustomData', }, ORDER_COMPLETED: { standard: true, type: 'order completed', eventName: 'Purchase', - name: 'FBPIXELPSimpleCustomConfig', + name: 'FBPIXELOrderCompletedCustomData', }, PRODUCTS_SEARCHED: { standard: true, type: 'products searched', eventName: 'Search', - name: 'FBPIXELPSimpleCustomConfig', + name: 'FBPIXELProductSearchedCustomData', }, CHECKOUT_STARTED: { standard: true, type: 'checkout started', eventName: 'InitiateCheckout', - name: 'FBPIXELPSimpleCustomConfig', + name: 'FBPIXELCheckoutStartedCustomData', }, OTHER_STANDARD: { standard: true, diff --git a/src/v0/destinations/facebook_pixel/data/FBPIXELCheckoutStartedCustomData.json b/src/v0/destinations/facebook_pixel/data/FBPIXELCheckoutStartedCustomData.json new file mode 100644 index 0000000000..47938912b4 --- /dev/null +++ b/src/v0/destinations/facebook_pixel/data/FBPIXELCheckoutStartedCustomData.json @@ -0,0 +1,48 @@ +[ + { + "destKey": "content_category", + "sourceKeys": "properties.category" + }, + { + "destKey": "content_ids", + "sourceKeys": "", + "metadata": { + "defaultValue": [] + } + }, + { + "destKey": "content_type", + "sourceKeys": "", + "metadata": { + "defaultValue": "product" + } + }, + { + "destKey": "currency", + "sourceKeys": "properties.currency", + "metadata": { + "defaultValue": "USD" + } + }, + { + "destKey": "value", + "sourceKeys": "properties.revenue", + "metadata": { + "type": "numberForRevenue" + } + }, + { + "destKey": "contents", + "sourceKeys": "", + "metadata": { + "defaultValue": [] + } + }, + { + "destKey": "num_items", + "sourceKeys": "", + "metadata": { + "defaultValue": 0 + } + } +] diff --git a/src/v0/destinations/facebook_pixel/data/FBPIXELOrderCompletedCustomData.json b/src/v0/destinations/facebook_pixel/data/FBPIXELOrderCompletedCustomData.json new file mode 100644 index 0000000000..a95315008b --- /dev/null +++ b/src/v0/destinations/facebook_pixel/data/FBPIXELOrderCompletedCustomData.json @@ -0,0 +1,52 @@ +[ + { + "destKey": "content_category", + "sourceKeys": "properties.category" + }, + { + "destKey": "content_ids", + "sourceKeys": "", + "metadata": { + "defaultValue": [] + } + }, + { + "destKey": "content_type", + "sourceKeys": "", + "metadata": { + "defaultValue": "product" + } + }, + { + "destKey": "currency", + "sourceKeys": "properties.currency", + "metadata": { + "defaultValue": "USD" + } + }, + { + "destKey": "value", + "sourceKeys": "properties.revenue", + "metadata": { + "type": "numberForRevenue" + } + }, + { + "destKey": "contents", + "sourceKeys": "", + "metadata": { + "defaultValue": [] + } + }, + { + "destKey": "num_items", + "sourceKeys": "", + "metadata": { + "defaultValue": 0 + } + }, + { + "destKey": "content_name", + "sourceKeys": "properties.contentName" + } +] diff --git a/src/v0/destinations/facebook_pixel/data/FBPIXELProductAddedCustomData.json b/src/v0/destinations/facebook_pixel/data/FBPIXELProductAddedCustomData.json new file mode 100644 index 0000000000..786cb58e62 --- /dev/null +++ b/src/v0/destinations/facebook_pixel/data/FBPIXELProductAddedCustomData.json @@ -0,0 +1,48 @@ +[ + { + "destKey": "content_ids", + "sourceKeys": ["properties.product_id", "properties.sku", "properties.id"] + }, + { + "destKey": "content_type", + "sourceKeys": "", + "metadata": { + "defaultValue": "product" + } + }, + { + "destKey": "content_name", + "sourceKeys": ["properties.product_name", "properties.name"], + "metadata": { + "defaultValue": "" + } + }, + { + "destKey": "content_category", + "sourceKeys": "properties.category", + "metadata": { + "defaultValue": "" + } + }, + { + "destKey": "currency", + "sourceKeys": "properties.currency", + "metadata": { + "defaultValue": "USD" + } + }, + { + "destKey": "value", + "sourceKeys": "properties.value", + "metadata": { + "type": "numberForRevenue" + } + }, + { + "destKey": "contents", + "sourceKeys": "", + "metadata": { + "defaultValue": [] + } + } +] diff --git a/src/v0/destinations/facebook_pixel/data/FBPIXELProductListViewedCustomData.json b/src/v0/destinations/facebook_pixel/data/FBPIXELProductListViewedCustomData.json new file mode 100644 index 0000000000..d2658f33e7 --- /dev/null +++ b/src/v0/destinations/facebook_pixel/data/FBPIXELProductListViewedCustomData.json @@ -0,0 +1,35 @@ +[ + { + "destKey": "content_ids", + "sourceKeys": "", + "metadata": { + "defaultValue": [] + } + }, + { + "destKey": "content_type", + "sourceKeys": "" + }, + { + "destKey": "contents", + "sourceKeys": "", + "metadata": { + "defaultValue": [] + } + }, + { + "destKey": "content_category", + "sourceKeys": "properties.category" + }, + { + "destKey": "content_name", + "sourceKeys": "properties.contentName" + }, + { + "destKey": "value", + "sourceKeys": "properties.value", + "metadata": { + "type": "numberForRevenue" + } + } +] diff --git a/src/v0/destinations/facebook_pixel/data/FBPIXELProductSearchedCustomData.json b/src/v0/destinations/facebook_pixel/data/FBPIXELProductSearchedCustomData.json new file mode 100644 index 0000000000..15635b7cf3 --- /dev/null +++ b/src/v0/destinations/facebook_pixel/data/FBPIXELProductSearchedCustomData.json @@ -0,0 +1,39 @@ +[ + { + "destKey": "content_ids", + "sourceKeys": ["properties.product_id", "properties.sku", "properties.id"] + }, + { + "destKey": "content_category", + "sourceKeys": "properties.category", + "metadata": { + "defaultValue": "" + } + }, + { + "destKey": "value", + "sourceKeys": "properties.value", + "metadata": { + "type": "numberForRevenue" + } + }, + { + "destKey": "contents.0.id", + "sourceKeys": ["properties.product_id", "properties.sku", "properties.id"] + }, + { + "destKey": "contents.0.quantity", + "sourceKeys": "properties.quantity", + "metadata": { + "defaultValue": 1 + } + }, + { + "destKey": "contents.0.item_price", + "sourceKeys": "properties.price" + }, + { + "destKey": "search_string", + "sourceKeys": "properties.query" + } +] diff --git a/src/v0/destinations/facebook_pixel/data/FBPIXELProductViewedCustomData.json b/src/v0/destinations/facebook_pixel/data/FBPIXELProductViewedCustomData.json new file mode 100644 index 0000000000..e233641b8a --- /dev/null +++ b/src/v0/destinations/facebook_pixel/data/FBPIXELProductViewedCustomData.json @@ -0,0 +1,56 @@ +[ + { + "destKey": "content_ids", + "sourceKeys": ["properties.product_id", "properties.sku", "properties.id"] + }, + { + "destKey": "content_type", + "sourceKeys": "", + "metadata": { + "defaultValue": "product" + } + }, + { + "destKey": "content_name", + "sourceKeys": ["properties.product_name", "properties.name"], + "metadata": { + "defaultValue": "" + } + }, + { + "destKey": "content_category", + "sourceKeys": "properties.category", + "metadata": { + "defaultValue": "" + } + }, + { + "destKey": "currency", + "sourceKeys": "properties.currency", + "metadata": { + "defaultValue": "USD" + } + }, + { + "destKey": "value", + "sourceKeys": "properties.value", + "metadata": { + "type": "numberForRevenue" + } + }, + { + "destKey": "contents.0.id", + "sourceKeys": ["properties.product_id", "properties.sku", "properties.id"] + }, + { + "destKey": "contents.0.quantity", + "sourceKeys": "properties.quantity", + "metadata": { + "defaultValue": 1 + } + }, + { + "destKey": "contents.0.item_price", + "sourceKeys": "properties.price" + } +] diff --git a/src/v0/destinations/facebook_pixel/transform.js b/src/v0/destinations/facebook_pixel/transform.js index 4a4c79af9e..798b3157d9 100644 --- a/src/v0/destinations/facebook_pixel/transform.js +++ b/src/v0/destinations/facebook_pixel/transform.js @@ -24,10 +24,6 @@ const { transformedPayloadData, getActionSource, fetchUserData, - handleProduct, - handleSearch, - handleProductListViewed, - handleOrder, formingFinalResponse, populateCustomDataBasedOnCategory, getCategoryFromEvent, @@ -227,9 +223,5 @@ const processRouterDest = async (inputs, reqMetadata) => { module.exports = { process, - processRouterDest, - handleSearch, - handleProductListViewed, - handleProduct, - handleOrder, + processRouterDest }; diff --git a/src/v0/destinations/facebook_pixel/transform.test.js b/src/v0/destinations/facebook_pixel/transform.test.js deleted file mode 100644 index 25332d770c..0000000000 --- a/src/v0/destinations/facebook_pixel/transform.test.js +++ /dev/null @@ -1,201 +0,0 @@ -const { - handleSearch, - handleProductListViewed, - handleProduct, - handleOrder, -} = require('../../../../src/v0/destinations/facebook_pixel/transform'); - -const getTestMessage = () => { - let message = { - properties: { - currency: 'CAD', - quantity: 1, - price: 24.75, - value: 30, - name: 'my product 1', - category: 'clothing', - sku: 'p-298', - testDimension: true, - testMetric: true, - position: 4.5, - query: 'HDMI Cable', - }, - }; - return message; -}; - -const getTestCategoryToContent = () => { - let categoryToContent = [ - { - from: 'spin_result', - to: 'Schedule', - }, - ]; - return categoryToContent; -}; - -describe('Unit test cases for facebook_pixel handle search', () => { - it('should return content with all fields not null', async () => { - const expectedOutput = { - content_ids: ['p-298'], - content_category: 'clothing', - value: 30, - search_string: 'HDMI Cable', - contents: [ - { - id: 'p-298', - quantity: 1, - item_price: 24.75, - }, - ], - }; - expect(handleSearch(getTestMessage())).toEqual(expectedOutput); - }); - - it("mapping 'product_id' with contentId", async () => { - let message = getTestMessage(); - message.properties.product_id = 'prd-123'; - - const expectedOutput = { - content_ids: ['prd-123'], - content_category: 'clothing', - value: 30, - search_string: 'HDMI Cable', - contents: [ - { - id: 'prd-123', - quantity: 1, - item_price: 24.75, - }, - ], - }; - expect(handleSearch(message)).toEqual(expectedOutput); - }); - - it("null/undefined 'properties'", async () => { - let message = getTestMessage(); - message.properties = null; - - const expectedOutput = { - content_category: '', - content_ids: [], - contents: [], - search_string: undefined, - value: 0, - }; - expect(handleSearch(message)).toEqual(expectedOutput); - }); -}); - -describe('Unit test cases for facebook_pixel handleProductListViewed', () => { - it('without product array', () => { - let expectedOutput = { - content_category: 'clothing', - content_ids: ['clothing'], - content_name: undefined, - content_type: 'product_group', - contents: [{ id: 'clothing', quantity: 1 }], - value: 30, - }; - expect(handleProductListViewed(getTestMessage(), getTestCategoryToContent())).toEqual( - expectedOutput, - ); - }); - - it('with product array', () => { - let fittingPayload = { ...getTestMessage() }; - fittingPayload.properties.products = [{ id: 'clothing', quantity: 2 }]; - let expectedOutput = { - content_category: 'clothing', - content_ids: ['clothing'], - content_name: undefined, - content_type: 'product', - contents: [{ id: 'clothing', item_price: undefined, quantity: 2 }], - value: 30, - }; - expect(handleProductListViewed(fittingPayload, getTestCategoryToContent())).toEqual( - expectedOutput, - ); - }); -}); - -describe('Unit test cases for facebook_pixel handleProduct', () => { - it('with valueFieldIdentifier properties.value', () => { - let expectedOutput = { - content_category: 'clothing', - content_ids: ['p-298'], - content_name: 'my product 1', - content_type: 'product', - contents: [{ id: 'p-298', item_price: 24.75, quantity: 1 }], - currency: 'CAD', - value: 30, - }; - expect(handleProduct(getTestMessage(), getTestCategoryToContent(), 'properties.value')).toEqual( - expectedOutput, - ); - }); - - it('with valueFieldIdentifier properties.price', () => { - let expectedOutput = { - content_category: 'clothing', - content_ids: ['p-298'], - content_name: 'my product 1', - content_type: 'product', - contents: [{ id: 'p-298', item_price: 24.75, quantity: 1 }], - currency: 'CAD', - value: 24.75, - }; - expect(handleProduct(getTestMessage(), getTestCategoryToContent(), 'properties.price')).toEqual( - expectedOutput, - ); - }); -}); - -describe('Unit test cases for facebook_pixel handleOrder', () => { - it('without product array', () => { - let expectedOutput = { - content_category: 'clothing', - content_ids: [], - content_name: undefined, - content_type: 'product', - contents: [], - currency: 'CAD', - num_items: 0, - value: 0, - }; - expect(handleOrder(getTestMessage(), getTestCategoryToContent())).toEqual(expectedOutput); - }); - - it('with product array without revenue', () => { - let fittingPayload = { ...getTestMessage() }; - fittingPayload.properties.products = [{ id: 'clothing', quantity: 2 }]; - let expectedOutput = { - content_category: 'clothing', - content_ids: ['clothing'], - content_name: undefined, - content_type: 'product', - contents: [{ id: 'clothing', item_price: 24.75, quantity: 2 }], - currency: 'CAD', - num_items: 1, - value: 0, - }; - expect(handleOrder(fittingPayload, getTestCategoryToContent())).toEqual(expectedOutput); - }); - - it('with product array with revenue', () => { - let fittingPayload = { ...getTestMessage() }; - fittingPayload.properties.products = [{ id: 'clothing', quantity: 2 }]; - fittingPayload.properties.revenue = 124; - let expectedOutput = { - content_category: 'clothing', - content_ids: ['clothing'], - content_name: undefined, - content_type: 'product', - contents: [{ id: 'clothing', item_price: 24.75, quantity: 2 }], - currency: 'CAD', - num_items: 1, - value: 124, - }; - expect(handleOrder(fittingPayload, getTestCategoryToContent())).toEqual(expectedOutput); - }); -}); diff --git a/src/v0/destinations/facebook_pixel/utils.js b/src/v0/destinations/facebook_pixel/utils.js index 3b8baba2d7..bf7585fd7b 100644 --- a/src/v0/destinations/facebook_pixel/utils.js +++ b/src/v0/destinations/facebook_pixel/utils.js @@ -300,21 +300,11 @@ const fetchUserData = (message, Config) => { return userData; }; -/** - * - * @param {*} message Rudder element - * @param {*} categoryToContent [ { from: 'clothing', to: 'product' } ] - * - * Handles order completed and checkout started types of specific events - */ -const handleOrder = (message, categoryToContent) => { - const { products, revenue } = message.properties; - const value = formatRevenue(revenue); - - const contentType = getContentType(message, 'product', categoryToContent); +const updateCustomDataForOrderCompletedAndCheckoutStarted = (customData, message, categoryToContent) => { + const { products } = message.properties; const contentIds = []; const contents = []; - const { category, quantity, price, currency, contentName } = message.properties; + const { quantity, price} = message.properties; if (products) { if (products.length > 0 && Array.isArray(products)) { products.forEach((singleProduct) => { @@ -336,30 +326,20 @@ const handleOrder = (message, categoryToContent) => { } } - return { - content_category: getContentCategory(category), - content_ids: contentIds, - content_type: contentType, - currency: currency || 'USD', - value, - contents, - num_items: contentIds.length, - content_name: contentName, - }; + const updatedCustomData = { ...customData } + updatedCustomData.content_category = getContentCategory(customData.content_category); + updatedCustomData.content_ids = contentIds; + updatedCustomData.content_type = getContentType(message, customData.content_type, categoryToContent); + updatedCustomData.contents = contents; + updatedCustomData.num_items = contentIds.length; + + return updatedCustomData; }; -/** - * - * @param {*} message Rudder element - * @param {*} categoryToContent [ { from: 'clothing', to: 'product' } ] - * - * Handles product list viewed - */ -const handleProductListViewed = (message, categoryToContent) => { - let contentType; +const updateCustomDataForProductListViewed = (customData, message, categoryToContent) => { const contentIds = []; const contents = []; - const { products, category, quantity, value, contentName } = message.properties; + const { products, quantity } = message.properties; if (products && products.length > 0 && Array.isArray(products)) { products.forEach((product, index) => { if (isObject(product)) { @@ -378,6 +358,8 @@ const handleProductListViewed = (message, categoryToContent) => { }); } + let contentType; + const category = customData.content_category; if (contentIds.length > 0) { contentType = 'product'; // for viewContent event content_ids and content arrays are not mandatory @@ -390,35 +372,19 @@ const handleProductListViewed = (message, categoryToContent) => { contentType = 'product_group'; } - return { - content_ids: contentIds, - content_type: getContentType(message, contentType, categoryToContent), - contents, - content_category: getContentCategory(category), - content_name: contentName, - value: formatRevenue(value), - }; + const updatedCustomData = { ...customData } + updatedCustomData.content_ids = contentIds; + updatedCustomData.content_type = getContentType(message, contentType, categoryToContent); + updatedCustomData.contents = contents; + updatedCustomData.content_category = getContentCategory(category); + + return updatedCustomData; }; -/** - * - * @param {*} message Rudder Payload - * @param {*} categoryToContent Example: [ { from: 'clothing', to: 'product' } ] - * @param {*} valueFieldIdentifier it can be either value or price which will be matched from properties and assigned to value for fb payload - */ -const handleProduct = (message, categoryToContent, valueFieldIdentifier) => { +const updateCustomDataForProductAddedAndProductViewed = (customData, message, categoryToContent, valueFieldIdentifier) => { const contentIds = []; const contents = []; - const useValue = valueFieldIdentifier === 'properties.value'; - const contentId = - message.properties?.product_id || message.properties?.sku || message.properties?.id; - const contentType = getContentType(message, 'product', categoryToContent); - const contentName = message.properties.product_name || message.properties.name || ''; - const contentCategory = message.properties.category || ''; - const currency = message.properties.currency || 'USD'; - const value = useValue - ? formatRevenue(message.properties.value) - : formatRevenue(message.properties.price); + const contentId = customData.content_ids; if (contentId) { contentIds.push(contentId); contents.push({ @@ -427,19 +393,22 @@ const handleProduct = (message, categoryToContent, valueFieldIdentifier) => { item_price: message.properties.price, }); } - return { - content_ids: contentIds, - content_type: contentType, - content_name: contentName, - content_category: getContentCategory(contentCategory), - currency, - value, - contents, - }; + + const updatedCustomData = { ...customData } + updatedCustomData.content_ids = contentIds; + updatedCustomData.content_type = getContentType(message, customData.content_type, categoryToContent); + updatedCustomData.content_category = getContentCategory(customData.content_category); + const useValue = valueFieldIdentifier === 'properties.value'; + if (!useValue) { + updatedCustomData.value = formatRevenue(message?.properties?.price); + } + updatedCustomData.contents = contents; + + return updatedCustomData; }; -const handleSearch = (message) => { - const query = message?.properties?.query; +const updateCustomDataForProductSearched = (customData, message) => { + const query = customData.search_string; /** * Facebook Pixel states "search_string" a string type * ref: https://developers.facebook.com/docs/meta-pixel/reference#:~:text=an%20exact%20value.-,search_string,-String @@ -453,10 +422,7 @@ const handleSearch = (message) => { const contentIds = []; const contents = []; - const contentId = - message.properties?.product_id || message.properties?.sku || message.properties?.id; - const contentCategory = message?.properties?.category || ''; - const value = message?.properties?.value; + const contentId = customData.content_ids; if (contentId) { contentIds.push(contentId); contents.push({ @@ -465,13 +431,13 @@ const handleSearch = (message) => { item_price: message?.properties?.price, }); } - return { - content_ids: contentIds, - content_category: getContentCategory(contentCategory), - value: formatRevenue(value), - contents, - search_string: query, - }; + + const updatedCustomData = { ...customData } + updatedCustomData.content_ids = contentIds; + updatedCustomData.content_category = getContentCategory(customData.content_category); + updatedCustomData.contents = contents; + + return updatedCustomData; }; const populateCustomDataBasedOnCategory = ( @@ -481,52 +447,32 @@ const populateCustomDataBasedOnCategory = ( categoryToContent, valueFieldIdentifier, ) => { - let updatedCustomData; + let eventTypeCustomData = constructPayload(message, category.name); switch (category.type) { case 'product list viewed': - updatedCustomData = { - ...customData, - ...handleProductListViewed(message, categoryToContent), - }; + eventTypeCustomData = updateCustomDataForProductListViewed(eventTypeCustomData, message, categoryToContent); break; case 'product viewed': case 'product added': - updatedCustomData = { - ...customData, - ...handleProduct(message, categoryToContent, valueFieldIdentifier), - }; + eventTypeCustomData = updateCustomDataForProductAddedAndProductViewed(eventTypeCustomData, message, categoryToContent, valueFieldIdentifier); break; case 'order completed': - updatedCustomData = { - ...customData, - ...handleOrder(message, categoryToContent), - }; + case 'checkout started': + eventTypeCustomData = updateCustomDataForOrderCompletedAndCheckoutStarted(eventTypeCustomData, message, categoryToContent); break; case 'products searched': { - updatedCustomData = { - ...customData, - ...handleSearch(message), - }; - break; - } - case 'checkout started': { - const orderPayload = handleOrder(message, categoryToContent); - delete orderPayload.content_name; - updatedCustomData = { - ...customData, - ...orderPayload, - }; + eventTypeCustomData = updateCustomDataForProductSearched(eventTypeCustomData, message); break; } case 'page_view': // executed when sending track calls but with standard type PageView case 'page': // executed when page call is done with standard PageView turned on case 'otherStandard': - updatedCustomData = { ...customData }; + eventTypeCustomData = { ...eventTypeCustomData }; break; default: throw new InstrumentationError(`${category.standard} type of standard event does not exist`); } - return updatedCustomData; + return { ...customData, ...eventTypeCustomData }; }; const getCategoryFromEvent = (eventName) => { @@ -611,10 +557,6 @@ module.exports = { transformedPayloadData, getActionSource, fetchUserData, - handleProduct, - handleSearch, - handleProductListViewed, - handleOrder, formingFinalResponse, populateCustomDataBasedOnCategory, getCategoryFromEvent, From 33b80063c47af679076c70447a342b6d77e31e69 Mon Sep 17 00:00:00 2001 From: sandeepdigumarty Date: Wed, 11 Oct 2023 17:00:09 +0530 Subject: [PATCH 4/4] feat: added event type mapping json for all standard events --- src/v0/destinations/facebook_pixel/utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/v0/destinations/facebook_pixel/utils.js b/src/v0/destinations/facebook_pixel/utils.js index bf7585fd7b..4788065c3d 100644 --- a/src/v0/destinations/facebook_pixel/utils.js +++ b/src/v0/destinations/facebook_pixel/utils.js @@ -447,7 +447,7 @@ const populateCustomDataBasedOnCategory = ( categoryToContent, valueFieldIdentifier, ) => { - let eventTypeCustomData = constructPayload(message, category.name); + let eventTypeCustomData = constructPayload(message, MAPPING_CONFIG[category.name]); switch (category.type) { case 'product list viewed': eventTypeCustomData = updateCustomDataForProductListViewed(eventTypeCustomData, message, categoryToContent);