diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b47af2d5c..81a51f28a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,26 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +### [1.71.1](https://github.com/rudderlabs/rudder-transformer/compare/v1.71.0...v1.71.1) (2024-07-10) + + +### Bug Fixes + +* ga4 v2 userproperties ([#3544](https://github.com/rudderlabs/rudder-transformer/issues/3544)) ([bc7b886](https://github.com/rudderlabs/rudder-transformer/commit/bc7b886fd314f35b5b5573989d8f094b7ba0321f)) +* tiktok: remove default value for content type for all events ([#3545](https://github.com/rudderlabs/rudder-transformer/issues/3545)) ([0ca08c3](https://github.com/rudderlabs/rudder-transformer/commit/0ca08c3fe8e4d53f92ce16eccd1f60224e1f1409)) + +## [1.71.0](https://github.com/rudderlabs/rudder-transformer/compare/v1.70.1...v1.71.0) (2024-07-08) + + +### Features + +* onboard new custom destination: wunderkind ([#3456](https://github.com/rudderlabs/rudder-transformer/issues/3456)) ([7f49a01](https://github.com/rudderlabs/rudder-transformer/commit/7f49a01b04322a38c5f96199d21097a9210e80fc)) + + +### Bug Fixes + +* zapier event lower case issue ([#3535](https://github.com/rudderlabs/rudder-transformer/issues/3535)) ([277c1f0](https://github.com/rudderlabs/rudder-transformer/commit/277c1f00606b0ec5974e6bf24dae6749a1679069)) + ### [1.70.1](https://github.com/rudderlabs/rudder-transformer/compare/v1.70.0...v1.70.1) (2024-07-03) ### Bug Fixes diff --git a/package-lock.json b/package-lock.json index 515f6195ba..268141d2cd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "rudder-transformer", - "version": "1.70.1", + "version": "1.71.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "rudder-transformer", - "version": "1.70.1", + "version": "1.71.1", "license": "ISC", "dependencies": { "@amplitude/ua-parser-js": "0.7.24", diff --git a/package.json b/package.json index aeecf9da70..e7710d74af 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rudder-transformer", - "version": "1.70.1", + "version": "1.71.1", "description": "", "homepage": "https://github.com/rudderlabs/rudder-transformer#readme", "bugs": { diff --git a/src/v0/destinations/ga4/utils.js b/src/v0/destinations/ga4/utils.js index 77f78fbfdb..18994efd7f 100644 --- a/src/v0/destinations/ga4/utils.js +++ b/src/v0/destinations/ga4/utils.js @@ -554,21 +554,17 @@ const buildDeliverablePayload = (payload, Config) => { return response; }; -const sanitizeUserProperties = (userProperties) => { - Object.keys(userProperties).forEach((key) => { - const propetyValue = userProperties[key]; - if ( - typeof propetyValue === 'string' || - typeof propetyValue === 'number' || - typeof propetyValue === 'boolean' - ) { - delete userProperties[key]; - userProperties[key] = { - value: propetyValue, - }; +function sanitizeUserProperties(userPropertiesObj) { + const sanitizedObj = {}; + // eslint-disable-next-line no-restricted-syntax, guard-for-in + for (const key in userPropertiesObj) { + const { value } = userPropertiesObj[key]; + if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') { + sanitizedObj[key] = { value }; } - }); -}; + } + return sanitizedObj; +} const basicConfigvalidaiton = (Config) => { if (!Config.typesOfClient) { diff --git a/src/v0/destinations/ga4_v2/customMappingsHandler.js b/src/v0/destinations/ga4_v2/customMappingsHandler.js index 1eb1c2c868..0f20788076 100644 --- a/src/v0/destinations/ga4_v2/customMappingsHandler.js +++ b/src/v0/destinations/ga4_v2/customMappingsHandler.js @@ -12,6 +12,7 @@ const { buildDeliverablePayload, GA4_PARAMETERS_EXCLUSION, prepareUserProperties, + sanitizeUserProperties, } = require('../ga4/utils'); const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { @@ -158,6 +159,11 @@ const boilerplateOperations = (ga4Payload, message, Config, eventName) => { if (!isEmptyObject(consents)) { ga4Payload.consent = consents; } + + // Prepare GA4 user properties + if (isDefinedAndNotNull(ga4Payload.user_properties)) { + ga4Payload.user_properties = sanitizeUserProperties(ga4Payload.user_properties); + } }; module.exports = { diff --git a/src/v0/destinations/tiktok_ads/config.js b/src/v0/destinations/tiktok_ads/config.js index 61009d4c31..e3a49755e5 100644 --- a/src/v0/destinations/tiktok_ads/config.js +++ b/src/v0/destinations/tiktok_ads/config.js @@ -39,6 +39,9 @@ const mappingConfig = getMappingConfig(ConfigCategory, __dirname); // tiktok docs for max batch size for events 2.0: https://business-api.tiktok.com/portal/docs?id=1771100779668482 const maxBatchSizeV2 = 1000; const trackEndpointV2 = 'https://business-api.tiktok.com/open_api/v1.3/event/track/'; +// Following is the list of standard events for which some parameters are recommended +// Ref: https://business-api.tiktok.com/portal/docs?id=1771101186666498 +const eventsWithRecommendedParams = ['AddToCart', 'CompletePayment', 'PlaceAnOrder', 'ViewContent']; module.exports = { TRACK_ENDPOINT, BATCH_ENDPOINT, @@ -50,4 +53,5 @@ module.exports = { DESTINATION: 'TIKTOK_ADS', trackEndpointV2, maxBatchSizeV2, + eventsWithRecommendedParams, }; diff --git a/src/v0/destinations/tiktok_ads/transformV2.js b/src/v0/destinations/tiktok_ads/transformV2.js index 8760dee52c..73fcc1be31 100644 --- a/src/v0/destinations/tiktok_ads/transformV2.js +++ b/src/v0/destinations/tiktok_ads/transformV2.js @@ -19,7 +19,13 @@ const { const { getContents, hashUserField } = require('./util'); const config = require('./config'); -const { trackMappingV2, trackEndpointV2, eventNameMapping, PARTNER_NAME } = config; +const { + trackMappingV2, + trackEndpointV2, + eventNameMapping, + PARTNER_NAME, + eventsWithRecommendedParams, +} = config; const { JSON_MIME_TYPE } = require('../../util/constant'); /** @@ -94,7 +100,14 @@ const trackResponseBuilder = async (message, { Config }) => { Object.keys(standardEventsMap).forEach((key) => { if (key === event) { standardEventsMap[event].forEach((eventName) => { - responseList.push(getTrackResponsePayload(message, Config, eventName)); + responseList.push( + getTrackResponsePayload( + message, + Config, + eventName, + eventsWithRecommendedParams.includes(eventName), + ), + ); }); } }); @@ -105,11 +118,15 @@ const trackResponseBuilder = async (message, { Config }) => { Doc https://ads.tiktok.com/help/article/standard-events-parameters?lang=en */ event = message.event; - responseList.push(getTrackResponsePayload(message, Config, event, false)); + responseList.push( + getTrackResponsePayload(message, Config, event, eventsWithRecommendedParams.includes(event)), + ); } else { // incoming event name is already a standard event name event = eventNameMapping[event]; - responseList.push(getTrackResponsePayload(message, Config, event)); + responseList.push( + getTrackResponsePayload(message, Config, event, eventsWithRecommendedParams.includes(event)), + ); } // set event source and event_source_id response.body.JSON = { diff --git a/test/integrations/destinations/tiktok_ads/processor/data.ts b/test/integrations/destinations/tiktok_ads/processor/data.ts index 4dfd32d671..f459e68681 100644 --- a/test/integrations/destinations/tiktok_ads/processor/data.ts +++ b/test/integrations/destinations/tiktok_ads/processor/data.ts @@ -5385,7 +5385,6 @@ export const data = [ event_id: '1616318632825_357', event_time: 1600372167, properties: { - content_type: 'product', contents: [ { price: 8, @@ -5550,7 +5549,6 @@ export const data = [ event_id: '1616318632825_357', event_time: 1600372167, properties: { - content_type: 'product', contents: [ { price: 8, @@ -5586,7 +5584,6 @@ export const data = [ event_id: '1616318632825_357', event_time: 1600372167, properties: { - content_type: 'product', contents: [ { price: 8, @@ -5745,7 +5742,6 @@ export const data = [ event_id: '1616318632825_357', event_time: 1600372167, properties: { - content_type: 'product', contents: [ { price: 8, @@ -5784,7 +5780,6 @@ export const data = [ event_id: '1616318632825_357', event_time: 1600372167, properties: { - content_type: 'product', contents: [ { price: 8, @@ -6627,7 +6622,6 @@ export const data = [ event_id: '1616318632825_357', event_time: 1600372167, properties: { - content_type: 'product', contents: [ { price: 8, @@ -7048,7 +7042,6 @@ export const data = [ event: 'Search', event_id: '84e26acc-56a5-4835-8233-591137fca468', event_time: 1600372167, - properties: { content_type: 'product' }, user: { locale: 'en-US', email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', diff --git a/test/integrations/destinations/tiktok_ads/router/data.ts b/test/integrations/destinations/tiktok_ads/router/data.ts index 7246b8c04a..eaf5049433 100644 --- a/test/integrations/destinations/tiktok_ads/router/data.ts +++ b/test/integrations/destinations/tiktok_ads/router/data.ts @@ -976,7 +976,6 @@ export const data = [ content_id: '1197218', }, ], - content_type: 'product', currency: 'USD', value: 46, }, @@ -2294,7 +2293,6 @@ export const data = [ content_id: '1197218', }, ], - content_type: 'product', currency: 'USD', value: 46, },