From 88b2d5709da00445ffae54f5a36de855cb5f8479 Mon Sep 17 00:00:00 2001 From: Manish Kumar Date: Fri, 10 May 2024 09:47:22 +0530 Subject: [PATCH 01/11] feat: onboard koddi destination --- src/cdk/v2/destinations/koddi/config.js | 20 +++++ .../destinations/koddi/data/ClicksConfig.json | 35 ++++++++ .../koddi/data/ConversionsConfig.json | 53 ++++++++++++ .../koddi/data/ImpressionsConfig.json | 22 +++++ .../v2/destinations/koddi/procWorkflow.yaml | 31 +++++++ src/cdk/v2/destinations/koddi/utils.js | 84 +++++++++++++++++++ 6 files changed, 245 insertions(+) create mode 100644 src/cdk/v2/destinations/koddi/config.js create mode 100644 src/cdk/v2/destinations/koddi/data/ClicksConfig.json create mode 100644 src/cdk/v2/destinations/koddi/data/ConversionsConfig.json create mode 100644 src/cdk/v2/destinations/koddi/data/ImpressionsConfig.json create mode 100644 src/cdk/v2/destinations/koddi/procWorkflow.yaml create mode 100644 src/cdk/v2/destinations/koddi/utils.js diff --git a/src/cdk/v2/destinations/koddi/config.js b/src/cdk/v2/destinations/koddi/config.js new file mode 100644 index 0000000000..c7af5c0b57 --- /dev/null +++ b/src/cdk/v2/destinations/koddi/config.js @@ -0,0 +1,20 @@ +const { getMappingConfig } = require('../../../../v0/util'); + +const ConfigCategories = { + IMPRESSIONS: { + type: 'track', + name: 'impressionsMapping', + }, + CLICKS: { + type: 'track', + name: 'clicksMapping', + }, + CONVERSIONS: { + type: 'track', + name: 'conversionsMapping', + }, +}; + +const mappingConfig = getMappingConfig(ConfigCategories, __dirname); + +module.exports = { ConfigCategories, mappingConfig }; diff --git a/src/cdk/v2/destinations/koddi/data/ClicksConfig.json b/src/cdk/v2/destinations/koddi/data/ClicksConfig.json new file mode 100644 index 0000000000..96ab27b2ae --- /dev/null +++ b/src/cdk/v2/destinations/koddi/data/ClicksConfig.json @@ -0,0 +1,35 @@ +[ + { + "sourceKeys": "properties.tracking_data", + "required": true, + "destKey": "trackingData" + }, + { + "sourceKeys": "properties.rank", + "required": true, + "destKey": "rank" + }, + { + "sourceKeys": "properties.beacon_issued", + "required": true, + "destKey": "beaconIssued" + }, + { + "sourceKeys": "userId", + "sourceFromGenericMap": true, + "required": true, + "destKey": "userGuid" + }, + { + "sourceKeys": "properties.test_version_override", + "destKey": "testVersionOverride" + }, + { + "sourceKeys": "properties.destination_url", + "destKey": "destinationUrl" + }, + { + "sourceKeys": "properties.overrides", + "destKey": "overrides" + } +] diff --git a/src/cdk/v2/destinations/koddi/data/ConversionsConfig.json b/src/cdk/v2/destinations/koddi/data/ConversionsConfig.json new file mode 100644 index 0000000000..0d49e39c32 --- /dev/null +++ b/src/cdk/v2/destinations/koddi/data/ConversionsConfig.json @@ -0,0 +1,53 @@ +[ + { + "sourceKeys": "context.page.referring_domain", + "destKey": "domain" + }, + { + "sourceKeys": "context.locale", + "required": true, + "destKey": "culture" + }, + { + "sourceKeys": "properties.currency", + "required": true, + "destKey": "currency" + }, + { + "sourceKeys": ["context.ip", "request_ip"], + "destKey": "user_ip" + }, + { + "sourceKeys": "context.userAgent", + "destKey": "user_agent" + }, + { + "sourceKeys": "userId", + "sourceFromGenericMap": true, + "required": true, + "destKey": "userGuid" + }, + { + "sourceKeys": "context.device.type", + "destKey": "device_type" + }, + { + "sourceKeys": ["properties.order_id", "properties.transaction_id"], + "required": true, + "destKey": "transaction_id" + }, + { + "sourceKeys": "properties.conversion_source", + "destKey": "conversion_source" + }, + { + "sourceKeys": "timestamp", + "sourceFromGenericMap": true, + "destKey": "unixtime" + }, + { + "sourceKeys": "properties.bidders", + "required": true, + "destKey": "bidders" + } +] diff --git a/src/cdk/v2/destinations/koddi/data/ImpressionsConfig.json b/src/cdk/v2/destinations/koddi/data/ImpressionsConfig.json new file mode 100644 index 0000000000..de53703b32 --- /dev/null +++ b/src/cdk/v2/destinations/koddi/data/ImpressionsConfig.json @@ -0,0 +1,22 @@ +[ + { + "sourceKeys": "properties.tracking_data", + "required": true, + "destKey": "trackingData" + }, + { + "sourceKeys": "properties.rank", + "required": true, + "destKey": "rank" + }, + { + "sourceKeys": "properties.beacon_issued", + "required": true, + "destKey": "beaconIssued" + }, + { + "sourceKeys": "timestamp", + "sourceFromGenericMap": true, + "destKey": "ts" + } +] diff --git a/src/cdk/v2/destinations/koddi/procWorkflow.yaml b/src/cdk/v2/destinations/koddi/procWorkflow.yaml new file mode 100644 index 0000000000..d632b73273 --- /dev/null +++ b/src/cdk/v2/destinations/koddi/procWorkflow.yaml @@ -0,0 +1,31 @@ +bindings: + - name: EventType + path: ../../../../constants + - path: ../../bindings/jsontemplate + - name: defaultRequestConfig + path: ../../../../v0/util + - name: removeUndefinedAndNullValues + path: ../../../../v0/util + - path: ./utils + +steps: + - name: messageType + template: | + .message.type.toLowerCase(); + - name: validateInput + template: | + let messageType = $.outputs.messageType; + $.assert(messageType, "message Type is not present. Aborting message."); + $.assert(messageType in {{$.EventType.([.TRACK])}}, "message type " + messageType + " is not supported"); + $.assert(.message.event, "Event name is not present. Aborting"); + $.assert(typeof .message.event === "string", "event name should be a string"); + $.assertConfig(.destination.Config.apiBaseUrl, "API Base URL is not present. Aborting"); + $.assertConfig(.destination.Config.clientName, "Client Name is not present. Aborting"); + - name: preparePayload + template: | + const payload = $.constructFullPayload(.message, .destination.Config); + $.context.payload = $.removeUndefinedAndNullValues(payload); + - name: buildResponse + template: | + const response = $.constructResponse(.context.payload, .destination.Config, .message); + response diff --git a/src/cdk/v2/destinations/koddi/utils.js b/src/cdk/v2/destinations/koddi/utils.js new file mode 100644 index 0000000000..2936d519a8 --- /dev/null +++ b/src/cdk/v2/destinations/koddi/utils.js @@ -0,0 +1,84 @@ +const config = require('./config'); +const { constructPayload, defaultRequestConfig } = require('../../../../v0/util'); + +/** + * + * @param message + * @param Config + * @returns {{}} + */ +const constructFullPayload = (message, Config) => { + let payload; + switch (message.event) { + case 'Impressions': + payload = constructPayload( + message, + config.mappingConfig[config.ConfigCategories.IMPRESSIONS.name], + ); + payload.clientName = Config.clientName; + break; + case 'Clicks': + payload = constructPayload( + message, + config.mappingConfig[config.ConfigCategories.CLICKS.name], + ); + payload.clientName = Config.clientName; + if (Config.testVersionOverride === false) { + payload.properties.test_version_override = null; + } + if (Config.overrides === false) { + payload.properties.overrides = null; + } + break; + case 'Conversions': + payload = constructPayload( + message, + config.mappingConfig[config.ConfigCategories.CONVERSIONS.name], + ); + payload.client_name = Config.clientName; + break; + default: + break; + } + return payload; +}; + +const getEndpoint = (Config, message) => { + let endpoint = Config.apiBaseUrl; + switch (message.event) { + case 'Impressions': + endpoint += '?action=impression'; + break; + case 'Clicks': + endpoint += '?action=click'; + break; + case 'Conversions': + endpoint += '/conversion'; + break; + default: + break; + } + return endpoint; +}; + +const constructResponse = (payload, Config, message) => { + const response = defaultRequestConfig(); + response.endpoint = getEndpoint(Config, message); + response.headers = { + accept: 'application/json', + }; + if (message.event === 'Conversions') { + response.body.JSON = payload; + response.method = 'POST'; + response.headers = { + ...response.headers, + 'content-type': 'application/json', + }; + } else { + response.params = payload; + response.method = 'GET'; + } + return response; +}; + +module.exports = { constructFullPayload, getEndpoint, constructResponse }; From 847e3e04d3ef67b9a7b5e35127251f3fc34ba3bf Mon Sep 17 00:00:00 2001 From: Gauravudia Date: Fri, 10 May 2024 16:56:03 +0530 Subject: [PATCH 02/11] fix: config --- src/cdk/v2/destinations/koddi/config.js | 18 ++++++++++++------ src/cdk/v2/destinations/koddi/utils.js | 17 ++++------------- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/src/cdk/v2/destinations/koddi/config.js b/src/cdk/v2/destinations/koddi/config.js index c7af5c0b57..dfae60a257 100644 --- a/src/cdk/v2/destinations/koddi/config.js +++ b/src/cdk/v2/destinations/koddi/config.js @@ -1,20 +1,26 @@ const { getMappingConfig } = require('../../../../v0/util'); -const ConfigCategories = { +const CONFIG_CATEGORIES = { IMPRESSIONS: { type: 'track', - name: 'impressionsMapping', + name: 'ImpressionsConfig', }, CLICKS: { type: 'track', - name: 'clicksMapping', + name: 'ClicksConfig', }, CONVERSIONS: { type: 'track', - name: 'conversionsMapping', + name: 'ConversionsConfig', }, }; -const mappingConfig = getMappingConfig(ConfigCategories, __dirname); +const MAPPING_CONFIG = getMappingConfig(CONFIG_CATEGORIES, __dirname); -module.exports = { ConfigCategories, mappingConfig }; +module.exports = { + CONFIG_CATEGORIES, + MAPPING_CONFIG, + IMPRESSIONS_CONFIG: MAPPING_CONFIG[CONFIG_CATEGORIES.IMPRESSIONS.name], + CLICKS_CONFIG: MAPPING_CONFIG[CONFIG_CATEGORIES.CLICKS.name], + CONVERSIONS_CONFIG: MAPPING_CONFIG[CONFIG_CATEGORIES.CONVERSIONS.name], +}; diff --git a/src/cdk/v2/destinations/koddi/utils.js b/src/cdk/v2/destinations/koddi/utils.js index 2936d519a8..e9f2c6a412 100644 --- a/src/cdk/v2/destinations/koddi/utils.js +++ b/src/cdk/v2/destinations/koddi/utils.js @@ -1,4 +1,4 @@ -const config = require('./config'); +const { IMPRESSIONS_CONFIG, CLICKS_CONFIG, CONVERSIONS_CONFIG } = require('./config'); const { constructPayload, defaultRequestConfig } = require('../../../../v0/util'); /** @@ -11,17 +11,11 @@ const constructFullPayload = (message, Config) => { let payload; switch (message.event) { case 'Impressions': - payload = constructPayload( - message, - config.mappingConfig[config.ConfigCategories.IMPRESSIONS.name], - ); + payload = constructPayload(message, IMPRESSIONS_CONFIG); payload.clientName = Config.clientName; break; case 'Clicks': - payload = constructPayload( - message, - config.mappingConfig[config.ConfigCategories.CLICKS.name], - ); + payload = constructPayload(message, CLICKS_CONFIG); payload.clientName = Config.clientName; if (Config.testVersionOverride === false) { payload.properties.test_version_override = null; @@ -31,10 +25,7 @@ const constructFullPayload = (message, Config) => { } break; case 'Conversions': - payload = constructPayload( - message, - config.mappingConfig[config.ConfigCategories.CONVERSIONS.name], - ); + payload = constructPayload(message, CONVERSIONS_CONFIG); payload.client_name = Config.clientName; break; default: From ddf8d46fed980204c561f95daa12fc740302e6e3 Mon Sep 17 00:00:00 2001 From: Manish Kumar Date: Sun, 12 May 2024 20:59:12 +0530 Subject: [PATCH 03/11] fix: added conversions bidders validation and improved implementation --- src/cdk/v2/destinations/koddi/config.js | 7 ++ .../v2/destinations/koddi/procWorkflow.yaml | 12 ++- src/cdk/v2/destinations/koddi/rtWorkflow.yaml | 35 ++++++++ src/cdk/v2/destinations/koddi/utils.js | 81 +++++++++++++------ 4 files changed, 107 insertions(+), 28 deletions(-) create mode 100644 src/cdk/v2/destinations/koddi/rtWorkflow.yaml diff --git a/src/cdk/v2/destinations/koddi/config.js b/src/cdk/v2/destinations/koddi/config.js index dfae60a257..fa595dc627 100644 --- a/src/cdk/v2/destinations/koddi/config.js +++ b/src/cdk/v2/destinations/koddi/config.js @@ -1,5 +1,11 @@ const { getMappingConfig } = require('../../../../v0/util'); +const EVENT_NAMES = { + IMPRESSIONS: 'impressions', + CLICKS: 'clicks', + CONVERSIONS: 'conversions', +}; + const CONFIG_CATEGORIES = { IMPRESSIONS: { type: 'track', @@ -18,6 +24,7 @@ const CONFIG_CATEGORIES = { const MAPPING_CONFIG = getMappingConfig(CONFIG_CATEGORIES, __dirname); module.exports = { + EVENT_NAMES, CONFIG_CATEGORIES, MAPPING_CONFIG, IMPRESSIONS_CONFIG: MAPPING_CONFIG[CONFIG_CATEGORIES.IMPRESSIONS.name], diff --git a/src/cdk/v2/destinations/koddi/procWorkflow.yaml b/src/cdk/v2/destinations/koddi/procWorkflow.yaml index d632b73273..28d062d4a4 100644 --- a/src/cdk/v2/destinations/koddi/procWorkflow.yaml +++ b/src/cdk/v2/destinations/koddi/procWorkflow.yaml @@ -2,30 +2,34 @@ bindings: - name: EventType path: ../../../../constants - path: ../../bindings/jsontemplate - - name: defaultRequestConfig - path: ../../../../v0/util - name: removeUndefinedAndNullValues path: ../../../../v0/util - path: ./utils + - path: ./config steps: - name: messageType template: | .message.type.toLowerCase(); + - name: eventName + template: | + .message.integrations.koddi.eventName.toLowerCase(); - name: validateInput template: | let messageType = $.outputs.messageType; + let eventName = $.outputs.eventName; $.assert(messageType, "message Type is not present. Aborting message."); $.assert(messageType in {{$.EventType.([.TRACK])}}, "message type " + messageType + " is not supported"); + $.assert(eventName in {{$.EVENT_NAMES.([.IMPRESSIONS, .CLICKS, .CONVERSIONS])}}, "event name " + eventName + " is not supported"); $.assert(.message.event, "Event name is not present. Aborting"); $.assert(typeof .message.event === "string", "event name should be a string"); $.assertConfig(.destination.Config.apiBaseUrl, "API Base URL is not present. Aborting"); $.assertConfig(.destination.Config.clientName, "Client Name is not present. Aborting"); - name: preparePayload template: | - const payload = $.constructFullPayload(.message, .destination.Config); + const payload = $.constructFullPayload($.outputs.eventName, .message, .destination.Config); $.context.payload = $.removeUndefinedAndNullValues(payload); - name: buildResponse template: | - const response = $.constructResponse(.context.payload, .destination.Config, .message); + const response = $.constructResponse($.outputs.eventName, .destination.Config, $.context.payload); response diff --git a/src/cdk/v2/destinations/koddi/rtWorkflow.yaml b/src/cdk/v2/destinations/koddi/rtWorkflow.yaml new file mode 100644 index 0000000000..30dd3fdd95 --- /dev/null +++ b/src/cdk/v2/destinations/koddi/rtWorkflow.yaml @@ -0,0 +1,35 @@ +bindings: + - path: ./config + - name: handleRtTfSingleEventError + path: ../../../../v0/util/index + - path: ./utils +steps: + - name: validateInput + template: | + $.assert(Array.isArray(^) && ^.length > 0, "Invalid event array") + + - name: transform + externalWorkflow: + path: ./procWorkflow.yaml + loopOverInput: true + + - name: successfulEvents + template: | + $.outputs.transform#idx.output.({ + "output": .body.JSON.events[0], + "destination": ^[idx].destination, + "metadata": ^[idx].metadata + })[] + - name: failedEvents + template: | + $.outputs.transform#idx.error.( + $.handleRtTfSingleEventError(^[idx], .originalError ?? ., {}) + )[] + - name: batchSuccessfulEvents + description: Batches the successfulEvents + template: | + $.batchResponseBuilder($.outputs.successfulEvents); + + - name: finalPayload + template: | + [...$.outputs.failedEvents, ...$.outputs.batchSuccessfulEvents] diff --git a/src/cdk/v2/destinations/koddi/utils.js b/src/cdk/v2/destinations/koddi/utils.js index e9f2c6a412..6e8d5ba12b 100644 --- a/src/cdk/v2/destinations/koddi/utils.js +++ b/src/cdk/v2/destinations/koddi/utils.js @@ -1,32 +1,58 @@ -const { IMPRESSIONS_CONFIG, CLICKS_CONFIG, CONVERSIONS_CONFIG } = require('./config'); -const { constructPayload, defaultRequestConfig } = require('../../../../v0/util'); +const { InstrumentationError } = require('@rudderstack/integrations-lib'); +const { EVENT_NAMES, IMPRESSIONS_CONFIG, CLICKS_CONFIG, CONVERSIONS_CONFIG } = require('./config'); +const { constructPayload, defaultRequestConfig, toUnixTimestamp } = require('../../../../v0/util'); + +const validateBidders = (bidders) => { + if (!Array.isArray(bidders)) { + throw new InstrumentationError('properties.bidders should be an array of objects. Aborting.'); + } + if (bidders.length === 0) { + throw new InstrumentationError( + 'properties.bidders should contains at least one bidder. Aborting.', + ); + } + bidders.forEach((bidder) => { + if (!(bidder.bidder || bidder.alternate_bidder)) { + throw new InstrumentationError('bidder or alternate_bidder is not present. Aborting.'); + } + if (!bidder.count) { + throw new InstrumentationError('count is not present. Aborting.'); + } + if (!bidder.base_price) { + throw new InstrumentationError('base_price is not present. Aborting.'); + } + }); +}; /** - * - * @param message - * @param Config - * @returns {{}} + * This function constructs payloads based upon mappingConfig for all calls. + * @param {*} eventName + * @param {*} message + * @param {*} Config + * @returns */ -const constructFullPayload = (message, Config) => { +const constructFullPayload = (eventName, message, Config) => { let payload; - switch (message.event) { - case 'Impressions': + switch (eventName) { + case EVENT_NAMES.IMPRESSIONS: payload = constructPayload(message, IMPRESSIONS_CONFIG); payload.clientName = Config.clientName; break; - case 'Clicks': + case EVENT_NAMES.CLICKS: payload = constructPayload(message, CLICKS_CONFIG); payload.clientName = Config.clientName; - if (Config.testVersionOverride === false) { - payload.properties.test_version_override = null; + if (!Config.testVersionOverride) { + payload.testVersionOverride = null; } - if (Config.overrides === false) { - payload.properties.overrides = null; + if (!Config.overrides) { + payload.overrides = null; } break; - case 'Conversions': + case EVENT_NAMES.CONVERSIONS: payload = constructPayload(message, CONVERSIONS_CONFIG); payload.client_name = Config.clientName; + payload.unixtime = toUnixTimestamp(payload.unixtime); + validateBidders(payload.bidders); break; default: break; @@ -34,16 +60,16 @@ const constructFullPayload = (message, Config) => { return payload; }; -const getEndpoint = (Config, message) => { +const getEndpoint = (eventName, Config) => { let endpoint = Config.apiBaseUrl; - switch (message.event) { - case 'Impressions': + switch (eventName) { + case EVENT_NAMES.IMPRESSIONS: endpoint += '?action=impression'; break; - case 'Clicks': + case EVENT_NAMES.CLICKS: endpoint += '?action=click'; break; - case 'Conversions': + case EVENT_NAMES.CONVERSIONS: endpoint += '/conversion'; break; default: @@ -52,13 +78,20 @@ const getEndpoint = (Config, message) => { return endpoint; }; -const constructResponse = (payload, Config, message) => { +/** + * This function constructs response based upon event. + * @param {*} eventName + * @param {*} Config + * @param {*} payload + * @returns + */ +const constructResponse = (eventName, Config, payload) => { const response = defaultRequestConfig(); - response.endpoint = getEndpoint(Config, message); + response.endpoint = getEndpoint(eventName, Config); response.headers = { accept: 'application/json', }; - if (message.event === 'Conversions') { + if (eventName === EVENT_NAMES.CONVERSIONS) { response.body.JSON = payload; response.method = 'POST'; response.headers = { @@ -72,4 +105,4 @@ const constructResponse = (payload, Config, message) => { return response; }; -module.exports = { constructFullPayload, getEndpoint, constructResponse }; +module.exports = { constructFullPayload, constructResponse }; From bc7970c4f0a70e9fe8ad06ffd92f8f4b2a4ec910 Mon Sep 17 00:00:00 2001 From: Manish Kumar Date: Mon, 13 May 2024 18:04:23 +0530 Subject: [PATCH 04/11] fix: fixed some issue and added unit test --- src/cdk/v2/destinations/koddi/utils.js | 18 +- src/cdk/v2/destinations/koddi/utils.test.js | 423 ++++++++++++++++++++ src/features.json | 3 +- 3 files changed, 438 insertions(+), 6 deletions(-) create mode 100644 src/cdk/v2/destinations/koddi/utils.test.js diff --git a/src/cdk/v2/destinations/koddi/utils.js b/src/cdk/v2/destinations/koddi/utils.js index 6e8d5ba12b..f6521d1a66 100644 --- a/src/cdk/v2/destinations/koddi/utils.js +++ b/src/cdk/v2/destinations/koddi/utils.js @@ -1,6 +1,11 @@ const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { EVENT_NAMES, IMPRESSIONS_CONFIG, CLICKS_CONFIG, CONVERSIONS_CONFIG } = require('./config'); -const { constructPayload, defaultRequestConfig, toUnixTimestamp } = require('../../../../v0/util'); +const { + constructPayload, + defaultRequestConfig, + toUnixTimestamp, + stripTrailingSlash, +} = require('../../../../v0/util'); const validateBidders = (bidders) => { if (!Array.isArray(bidders)) { @@ -55,13 +60,13 @@ const constructFullPayload = (eventName, message, Config) => { validateBidders(payload.bidders); break; default: - break; + throw new InstrumentationError(`event name ${eventName} is not supported.`); } return payload; }; const getEndpoint = (eventName, Config) => { - let endpoint = Config.apiBaseUrl; + let endpoint = stripTrailingSlash(Config.apiBaseUrl); switch (eventName) { case EVENT_NAMES.IMPRESSIONS: endpoint += '?action=impression'; @@ -73,7 +78,7 @@ const getEndpoint = (eventName, Config) => { endpoint += '/conversion'; break; default: - break; + throw new InstrumentationError(`event name ${eventName} is not supported.`); } return endpoint; }; @@ -86,6 +91,9 @@ const getEndpoint = (eventName, Config) => { * @returns */ const constructResponse = (eventName, Config, payload) => { + if (!Object.values(EVENT_NAMES).includes(eventName)) { + throw new InstrumentationError(`event name ${eventName} is not supported.`); + } const response = defaultRequestConfig(); response.endpoint = getEndpoint(eventName, Config); response.headers = { @@ -105,4 +113,4 @@ const constructResponse = (eventName, Config, payload) => { return response; }; -module.exports = { constructFullPayload, constructResponse }; +module.exports = { getEndpoint, validateBidders, constructFullPayload, constructResponse }; diff --git a/src/cdk/v2/destinations/koddi/utils.test.js b/src/cdk/v2/destinations/koddi/utils.test.js new file mode 100644 index 0000000000..e31bd6d9a7 --- /dev/null +++ b/src/cdk/v2/destinations/koddi/utils.test.js @@ -0,0 +1,423 @@ +const { + getEndpoint, + validateBidders, + constructFullPayload, + constructResponse, +} = require('./utils'); +const { InstrumentationError } = require('@rudderstack/integrations-lib'); + +describe('getEndpoint', () => { + it('returns the correct endpoint for IMPRESSIONS event', () => { + const eventName = 'impressions'; + const Config = { + apiBaseUrl: 'https://www.test-client.com/', + clientName: 'test-client', + }; + const result = getEndpoint(eventName, Config); + expect(result).toEqual('https://www.test-client.com?action=impression'); + }); + + it('returns the correct endpoint for CLICKS event', () => { + const eventName = 'clicks'; + const Config = { + apiBaseUrl: 'https://www.test-client.com', + clientName: 'test-client', + }; + const result = getEndpoint(eventName, Config); + expect(result).toEqual('https://www.test-client.com?action=click'); + }); + + it('returns the correct endpoint for IMPRESSIONS event', () => { + const eventName = 'conversions'; + const Config = { + apiBaseUrl: 'https://www.test-client.com', + clientName: 'test-client', + }; + const result = getEndpoint(eventName, Config); + expect(result).toEqual('https://www.test-client.com/conversion'); + }); + + it('should throw error for unsupported event', () => { + const eventName = 'test'; + const Config = { + apiBaseUrl: 'https://www.test-client.com', + clientName: 'test-client', + }; + expect(() => getEndpoint(eventName, Config).toThrow(InstrumentationError)); + expect(() => getEndpoint(eventName, Config).toThrow('event name test is not supported.')); + }); +}); + +describe('validateBidders', () => { + it('should throw error if bidders is not an array', () => { + const bidders = {}; + expect(() => validateBidders(bidders)).toThrow(InstrumentationError); + expect(() => validateBidders(bidders)).toThrow( + 'properties.bidders should be an array of objects. Aborting.', + ); + }); + + it('should throw error if bidders is an empty array', () => { + const bidders = []; + expect(() => validateBidders(bidders)).toThrow(InstrumentationError); + expect(() => validateBidders(bidders)).toThrow( + 'properties.bidders should contains at least one bidder. Aborting.', + ); + }); + + it('should throw error if bidder or alternate_bidder is not present', () => { + const bidders = [ + { count: 1, base_price: 100 }, + { bidder: 'bidder1', count: 2, base_price: 200 }, + { alternate_bidder: 'alternate1', count: 3, base_price: 300 }, + ]; + expect(() => validateBidders(bidders)).toThrow(InstrumentationError); + expect(() => validateBidders(bidders)).toThrow( + 'bidder or alternate_bidder is not present. Aborting.', + ); + }); + + it('should throw error if count is not present', () => { + const bidders = [{ bidder: 'bidder1', alternate_bidder: 'alternate1', base_price: 100 }]; + expect(() => validateBidders(bidders)).toThrow(InstrumentationError); + expect(() => validateBidders(bidders)).toThrow('count is not present. Aborting.'); + }); + + it('should throw error if base_price is not present', () => { + const bidders = [ + { bidder: 'bidder1', alternate_bidder: 'alternate1', count: 1 }, // Missing base_price + ]; + expect(() => validateBidders(bidders)).toThrow(InstrumentationError); + expect(() => validateBidders(bidders)).toThrow('base_price is not present. Aborting.'); + }); + + it('should not throw error if all fields are present for all bidders', () => { + const bidders = [ + { bidder: 'bidder1', alternate_bidder: 'alternate1', count: 1, base_price: 100 }, + { bidder: 'bidder2', alternate_bidder: 'alternate2', count: 2, base_price: 200 }, + ]; + expect(() => validateBidders(bidders)).not.toThrow(); + }); +}); + +describe('constructFullPayload', () => { + it('should construct payload for IMPRESSIONS event', () => { + const eventName = 'impressions'; + const message = { + type: 'track', + event: 'Impressions Event', + properties: { + tracking_data: 'dummy-tracking-data', + rank: 1, + beacon_issued: '2024-03-04T15:32:56.409Z', + }, + timestamp: '2024-03-03T00:29:12.117+05:30', + }; + const Config = { + apiBaseUrl: 'https://www.test-client.com', + clientName: 'test-client', + }; + const expectedPayload = { + beaconIssued: '2024-03-04T15:32:56.409Z', + clientName: 'test-client', + rank: 1, + trackingData: 'dummy-tracking-data', + ts: '2024-03-03T00:29:12.117+05:30', + }; + const payload = constructFullPayload(eventName, message, Config); + expect(payload).toEqual(expectedPayload); + }); + it('should throw error if required value is missing for IMPRESSIONS event', () => { + const eventName = 'impressions'; + const message = { + type: 'track', + event: 'Impressions Event', + properties: { + tracking_data: '', + rank: 1, + beacon_issued: '2024-03-04T15:32:56.409Z', + }, + timestamp: '2024-03-03T00:29:12.117+05:30', + }; + const Config = { + apiBaseUrl: 'https://www.test-client.com', + clientName: 'test-client', + }; + try { + const payload = constructFullPayload(eventName, message, Config); + } catch (error) { + expect(error.message).toEqual('Missing required value from "properties.tracking_data"'); + } + }); + + it('should construct payload for CLICKS event', () => { + const eventName = 'clicks'; + const message = { + type: 'track', + event: 'Clicks Event', + properties: { + tracking_data: 'dummy-tracking-data', + rank: 1, + beacon_issued: '2024-03-04T15:32:56.409Z', + }, + anonymousId: '1234', + }; + const Config = { + apiBaseUrl: 'https://www.test-client.com', + clientName: 'test-client', + }; + const expectedPayload = { + beaconIssued: '2024-03-04T15:32:56.409Z', + clientName: 'test-client', + rank: 1, + trackingData: 'dummy-tracking-data', + userGuid: '1234', + overrides: null, + testVersionOverride: null, + }; + const payload = constructFullPayload(eventName, message, Config); + expect(payload).toEqual(expectedPayload); + }); + it('should construct payload with non-null value if overrides and testVersionOverride are enable and values for these are provided for CLICKS event ', () => { + const eventName = 'clicks'; + const message = { + type: 'track', + event: 'Clicks Event', + properties: { + tracking_data: 'dummy-tracking-data', + rank: 1, + beacon_issued: '2024-03-04T15:32:56.409Z', + overrides: 'overridden-value', + testVersionOverride: 1, + }, + anonymousId: '1234', + }; + const Config = { + apiBaseUrl: 'https://www.test-client.com', + clientName: 'test-client', + overrides: true, + testVersionOverride: false, + }; + const expectedPayload = { + beaconIssued: '2024-03-04T15:32:56.409Z', + clientName: 'test-client', + rank: 1, + trackingData: 'dummy-tracking-data', + userGuid: '1234', + overrides: 'overridden-value', + testVersionOverride: null, + }; + const payload = constructFullPayload(eventName, message, Config); + expect(payload).toEqual(expectedPayload); + }); + it('should throw error if required value is missing for CLICKS event', () => { + const eventName = 'clicks'; + const message = { + type: 'track', + event: 'Clicks Event', + properties: { + tracking_data: 'dummy-tracking-data', + rank: 1, + beacon_issued: '2024-03-04T15:32:56.409Z', + }, + }; + const Config = { + apiBaseUrl: 'https://www.test-client.com', + clientName: 'test-client', + }; + try { + const payload = constructFullPayload(eventName, message, Config); + } catch (error) { + expect(error.message).toEqual('Missing required value from "userId"'); + } + }); + + it('should construct payload for CONVERSIONS event', () => { + const eventName = 'conversions'; + const message = { + type: 'track', + event: 'Conversions Event', + properties: { + currency: 'USD', + order_id: '123', + bidders: [ + { + bidder: 'dummy-bidder-id', + count: 1, + base_price: 100.1, + }, + ], + }, + context: { + locale: 'en-US', + ip: '127.0.0.1', + }, + timestamp: '2024-03-03T00:29:12.117+05:30', + anonymousId: '1234', + }; + const Config = { + apiBaseUrl: 'https://www.test-client.com', + clientName: 'test-client', + }; + const expectedPayload = { + client_name: 'test-client', + culture: 'en-US', + currency: 'USD', + transaction_id: '123', + unixtime: 1709405952, + userGuid: '1234', + user_ip: '127.0.0.1', + bidders: [ + { + bidder: 'dummy-bidder-id', + count: 1, + base_price: 100.1, + }, + ], + }; + const payload = constructFullPayload(eventName, message, Config); + expect(payload).toEqual(expectedPayload); + }); + it('should throw error if required value is missing for CONVERSIONS event', () => { + const eventName = 'conversions'; + const message = { + type: 'track', + event: 'Conversions Event', + properties: { + currency: 'USD', + order_id: '123', + bidders: [ + { + bidder: 'dummy-bidder-id', + count: 1, + base_price: 100.1, + }, + ], + }, + context: { + ip: '127.0.0.1', + }, + timestamp: '2024-03-03T00:29:12.117+05:30', + anonymousId: '1234', + }; + const Config = { + apiBaseUrl: 'https://www.test-client.com', + clientName: 'test-client', + }; + try { + const payload = constructFullPayload(eventName, message, Config); + } catch (error) { + expect(error.message).toEqual('Missing required value from "context.locale"'); + } + }); + + it('should throw error for unsupported event', () => { + const eventName = 'test'; + const message = {}; + const Config = {}; + expect(() => constructFullPayload(eventName, message, Config).toThrow(InstrumentationError)); + expect(() => + constructFullPayload(eventName, message, Config).toThrow('event name test is not supported.'), + ); + }); +}); + +describe('constructResponse', () => { + it('should construct response for IMPRESSIONS event', () => { + const eventName = 'impressions'; + const Config = { + apiBaseUrl: 'https://www.test-client.com', + clientName: 'test-client', + }; + const payload = { + beaconIssued: '2024-03-04T15:32:56.409Z', + clientName: 'test-client', + rank: 1, + trackingData: 'dummy-tracking-data', + ts: '2024-03-03T00:29:12.117+05:30', + }; + const expectedResponse = { + endpoint: 'https://www.test-client.com?action=impression', + headers: { + accept: 'application/json', + }, + method: 'GET', + params: payload, + }; + const response = constructResponse(eventName, Config, payload); + expect(response).toMatchObject(expectedResponse); + }); + + it('should construct response for CLICKS event', () => { + const eventName = 'clicks'; + const Config = { + apiBaseUrl: 'https://www.test-client.com', + clientName: 'test-client', + }; + const payload = { + beaconIssued: '2024-03-04T15:32:56.409Z', + clientName: 'test-client', + rank: 1, + trackingData: 'dummy-tracking-data', + userGuid: '1234', + }; + const expectedResponse = { + endpoint: 'https://www.test-client.com?action=click', + headers: { + accept: 'application/json', + }, + method: 'GET', + params: payload, + }; + const response = constructResponse(eventName, Config, payload); + expect(response).toMatchObject(expectedResponse); + }); + + it('should construct response for CONVERSIONS event', () => { + const eventName = 'conversions'; + const Config = { + apiBaseUrl: 'https://www.test-client.com', + clientName: 'test-client', + }; + const payload = { + client_name: 'test-client', + culture: 'en-US', + currency: 'USD', + transaction_id: '123', + unixtime: 1709405952, + userGuid: '1234', + user_ip: '127.0.0.1', + bidders: [ + { + bidder: 'dummy-bidder-id', + count: 1, + base_price: 100.1, + }, + ], + }; + + const expectedResponse = { + endpoint: 'https://www.test-client.com/conversion', + headers: { + accept: 'application/json', + 'content-type': 'application/json', + }, + method: 'POST', + body: { + JSON: payload, + }, + }; + const response = constructResponse(eventName, Config, payload); + expect(response).toMatchObject(expectedResponse); + }); + + it('should throw error for unsupported event', () => { + const eventName = 'test'; + const Config = {}; + const payload = {}; + expect(() => constructResponse(eventName, Config, payload).toThrow(InstrumentationError)); + expect(() => + constructResponse(eventName, Config, payload).toThrow('event name test is not supported.'), + ); + }); +}); diff --git a/src/features.json b/src/features.json index 6d2cac9340..49b82e722a 100644 --- a/src/features.json +++ b/src/features.json @@ -70,7 +70,8 @@ "KOALA": true, "LINKEDIN_ADS": true, "BLOOMREACH": true, - "MOVABLE_INK": true + "MOVABLE_INK": true, + "KODDI": true }, "regulations": [ "BRAZE", From d4a82e2d2df7ee86c4b149bca7e0c12be3a6a545 Mon Sep 17 00:00:00 2001 From: Manish Kumar Date: Mon, 13 May 2024 18:39:09 +0530 Subject: [PATCH 05/11] fix: fixed unit test issue --- src/cdk/v2/destinations/koddi/utils.test.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/cdk/v2/destinations/koddi/utils.test.js b/src/cdk/v2/destinations/koddi/utils.test.js index e31bd6d9a7..ed12ecd5dd 100644 --- a/src/cdk/v2/destinations/koddi/utils.test.js +++ b/src/cdk/v2/destinations/koddi/utils.test.js @@ -43,8 +43,8 @@ describe('getEndpoint', () => { apiBaseUrl: 'https://www.test-client.com', clientName: 'test-client', }; - expect(() => getEndpoint(eventName, Config).toThrow(InstrumentationError)); - expect(() => getEndpoint(eventName, Config).toThrow('event name test is not supported.')); + expect(() => getEndpoint(eventName, Config)).toThrow(InstrumentationError); + expect(() => getEndpoint(eventName, Config)).toThrow('event name test is not supported.'); }); }); @@ -91,7 +91,7 @@ describe('validateBidders', () => { expect(() => validateBidders(bidders)).toThrow('base_price is not present. Aborting.'); }); - it('should not throw error if all fields are present for all bidders', () => { + it('should not throw error if all required fields are present for all bidders', () => { const bidders = [ { bidder: 'bidder1', alternate_bidder: 'alternate1', count: 1, base_price: 100 }, { bidder: 'bidder2', alternate_bidder: 'alternate2', count: 2, base_price: 200 }, @@ -315,9 +315,9 @@ describe('constructFullPayload', () => { const eventName = 'test'; const message = {}; const Config = {}; - expect(() => constructFullPayload(eventName, message, Config).toThrow(InstrumentationError)); - expect(() => - constructFullPayload(eventName, message, Config).toThrow('event name test is not supported.'), + expect(() => constructFullPayload(eventName, message, Config)).toThrow(InstrumentationError); + expect(() => constructFullPayload(eventName, message, Config)).toThrow( + 'event name test is not supported.', ); }); }); @@ -415,9 +415,9 @@ describe('constructResponse', () => { const eventName = 'test'; const Config = {}; const payload = {}; - expect(() => constructResponse(eventName, Config, payload).toThrow(InstrumentationError)); - expect(() => - constructResponse(eventName, Config, payload).toThrow('event name test is not supported.'), + expect(() => constructResponse(eventName, Config, payload)).toThrow(InstrumentationError); + expect(() => constructResponse(eventName, Config, payload)).toThrow( + 'event name test is not supported.', ); }); }); From 189cf9367a907dc1848257733e13713245458579 Mon Sep 17 00:00:00 2001 From: Manish Kumar Date: Tue, 14 May 2024 20:40:04 +0530 Subject: [PATCH 06/11] fix: added componenet test --- src/cdk/v2/destinations/koddi/rtWorkflow.yaml | 16 +- .../integrations/destinations/koddi/common.ts | 78 ++++++ .../destinations/koddi/processor/clicks.ts | 70 ++++++ .../koddi/processor/conversions.ts | 142 +++++++++++ .../destinations/koddi/processor/data.ts | 5 + .../koddi/processor/impressions.ts | 70 ++++++ .../destinations/koddi/router/data.ts | 232 ++++++++++++++++++ 7 files changed, 603 insertions(+), 10 deletions(-) create mode 100644 test/integrations/destinations/koddi/common.ts create mode 100644 test/integrations/destinations/koddi/processor/clicks.ts create mode 100644 test/integrations/destinations/koddi/processor/conversions.ts create mode 100644 test/integrations/destinations/koddi/processor/data.ts create mode 100644 test/integrations/destinations/koddi/processor/impressions.ts create mode 100644 test/integrations/destinations/koddi/router/data.ts diff --git a/src/cdk/v2/destinations/koddi/rtWorkflow.yaml b/src/cdk/v2/destinations/koddi/rtWorkflow.yaml index 30dd3fdd95..dd438a911c 100644 --- a/src/cdk/v2/destinations/koddi/rtWorkflow.yaml +++ b/src/cdk/v2/destinations/koddi/rtWorkflow.yaml @@ -1,8 +1,7 @@ bindings: - - path: ./config - name: handleRtTfSingleEventError path: ../../../../v0/util/index - - path: ./utils + steps: - name: validateInput template: | @@ -16,20 +15,17 @@ steps: - name: successfulEvents template: | $.outputs.transform#idx.output.({ - "output": .body.JSON.events[0], + "batchedRequest": ., + "batched": false, "destination": ^[idx].destination, - "metadata": ^[idx].metadata + "metadata": ^[idx].metadata[], + "statusCode": 200 })[] - name: failedEvents template: | $.outputs.transform#idx.error.( $.handleRtTfSingleEventError(^[idx], .originalError ?? ., {}) )[] - - name: batchSuccessfulEvents - description: Batches the successfulEvents - template: | - $.batchResponseBuilder($.outputs.successfulEvents); - - name: finalPayload template: | - [...$.outputs.failedEvents, ...$.outputs.batchSuccessfulEvents] + [...$.outputs.successfulEvents, ...$.outputs.failedEvents] diff --git a/test/integrations/destinations/koddi/common.ts b/test/integrations/destinations/koddi/common.ts new file mode 100644 index 0000000000..ec83a0f446 --- /dev/null +++ b/test/integrations/destinations/koddi/common.ts @@ -0,0 +1,78 @@ +import { Destination } from '../../../../src/types'; + +const destType = 'koddi'; +const destTypeInUpperCase = 'KODDI'; +const displayName = 'Koddi'; +const channel = 'web'; +const destination: Destination = { + Config: { + apiBaseUrl: 'https://www.test-client.com', + clientName: 'test-client', + }, + DestinationDefinition: { + DisplayName: displayName, + ID: '123', + Name: destTypeInUpperCase, + Config: { cdkV2Enabled: true }, + }, + Enabled: true, + ID: '123', + Name: destTypeInUpperCase, + Transformations: [], + WorkspaceID: 'test-workspace-id', +}; + +const processorInstrumentationErrorStatTags = { + destType: destTypeInUpperCase, + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'cdkV2', + module: 'destination', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', +}; + +const RouterInstrumentationErrorStatTags = { + ...processorInstrumentationErrorStatTags, + feature: 'router', +}; + +const getHeader = { + accept: 'application/json', +}; + +const postHeader = { + ...getHeader, + 'content-type': 'application/json', +}; + +const bidders = [ + { + bidder: 'bidder1', + alternate_bidder: 'alternate1', + count: 1, + base_price: 100, + total_price: 227, + }, +]; + +const alternateBidders = [ + { + count: 1, + base_price: 100, + total_price: 227, + }, +]; + +export { + destType, + channel, + destination, + processorInstrumentationErrorStatTags, + RouterInstrumentationErrorStatTags, + getHeader, + postHeader, + bidders, + alternateBidders, +}; diff --git a/test/integrations/destinations/koddi/processor/clicks.ts b/test/integrations/destinations/koddi/processor/clicks.ts new file mode 100644 index 0000000000..6270c0468d --- /dev/null +++ b/test/integrations/destinations/koddi/processor/clicks.ts @@ -0,0 +1,70 @@ +import { ProcessorTestData } from '../../../testTypes'; +import { generateMetadata, transformResultBuilder } from '../../../testUtils'; +import { destType, channel, destination, getHeader } from '../common'; + +export const clicks: ProcessorTestData[] = [ + { + id: 'Clicks-test', + name: destType, + description: 'Clicks call: Example Clicks Event', + scenario: 'Framework+Business', + successCriteria: + 'Response should contain the input payload with mappings configured in transformer and status code should be 200', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: { + type: 'track', + channel, + anonymousId: 'anonId123', + userId: 'userId123', + event: 'Example Clicks Event', + properties: { + tracking_data: 'dummy-tracking-data', + rank: 1, + beacon_issued: '2024-03-04T15:32:56.409Z', + }, + integrations: { + All: true, + koddi: { + eventName: 'Clicks', + }, + }, + originalTimestamp: '2024-03-04T15:32:56.409Z', + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + method: 'GET', + endpoint: destination.Config.apiBaseUrl + '?action=click', + headers: getHeader, + userId: '', + params: { + trackingData: 'dummy-tracking-data', + rank: 1, + beaconIssued: '2024-03-04T15:32:56.409Z', + userGuid: 'userId123', + clientName: destination.Config.clientName, + }, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/koddi/processor/conversions.ts b/test/integrations/destinations/koddi/processor/conversions.ts new file mode 100644 index 0000000000..35d1670b95 --- /dev/null +++ b/test/integrations/destinations/koddi/processor/conversions.ts @@ -0,0 +1,142 @@ +import { ProcessorTestData } from '../../../testTypes'; +import { generateMetadata, transformResultBuilder } from '../../../testUtils'; +import { + destType, + channel, + destination, + postHeader, + bidders, + alternateBidders, + processorInstrumentationErrorStatTags, +} from '../common'; + +export const conversions: ProcessorTestData[] = [ + { + id: 'Conversions-test-1', + name: destType, + description: 'Conversions call: Example Conversions Event', + scenario: 'Framework+Business', + successCriteria: + 'Response should contain the input payload with mappings configured in transformer and status code should be 200', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: { + type: 'track', + channel, + anonymousId: 'anonId123', + userId: 'userId123', + event: 'Example Conversions Event', + properties: { + currency: 'USD', + transaction_id: 'ABC123', + bidders, + }, + context: { + locale: 'en-US', + ip: '127.0.0.1', + }, + integrations: { + All: true, + koddi: { + eventName: 'Conversions', + }, + }, + originalTimestamp: '2024-03-04T15:32:56.409Z', + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + method: 'POST', + endpoint: destination.Config.apiBaseUrl + '/conversion', + headers: postHeader, + userId: '', + JSON: { + client_name: destination.Config.clientName, + culture: 'en-US', + currency: 'USD', + transaction_id: 'ABC123', + unixtime: 1709566376, + userGuid: 'userId123', + user_ip: '127.0.0.1', + bidders: bidders, + }, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'Conversions-test-2', + name: destType, + description: 'Conversions call: Example Conversions Event with missing required field', + scenario: 'Framework+Business', + successCriteria: 'Response should contain error and status code should be 400', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: { + type: 'track', + channel, + anonymousId: 'anonId123', + userId: 'userId123', + event: 'Example Conversions Event', + properties: { + currency: 'USD', + transaction_id: 'ABC123', + alternateBidders, + }, + context: { + locale: 'en-US', + ip: '127.0.0.1', + }, + integrations: { + All: true, + koddi: { + eventName: 'Conversions', + }, + }, + originalTimestamp: '2024-03-04T15:32:56.409Z', + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + 'Missing required value from "properties.bidders": Workflow: procWorkflow, Step: preparePayload, ChildStep: undefined, OriginalError: Missing required value from "properties.bidders"', + statusCode: 400, + metadata: generateMetadata(1), + statTags: processorInstrumentationErrorStatTags, + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/koddi/processor/data.ts b/test/integrations/destinations/koddi/processor/data.ts new file mode 100644 index 0000000000..5c3d7da472 --- /dev/null +++ b/test/integrations/destinations/koddi/processor/data.ts @@ -0,0 +1,5 @@ +import { impressions } from './impressions'; +import { clicks } from './clicks'; +import { conversions } from './conversions'; + +export const data = [...impressions, ...clicks, ...conversions]; diff --git a/test/integrations/destinations/koddi/processor/impressions.ts b/test/integrations/destinations/koddi/processor/impressions.ts new file mode 100644 index 0000000000..35ffcad22b --- /dev/null +++ b/test/integrations/destinations/koddi/processor/impressions.ts @@ -0,0 +1,70 @@ +import { ProcessorTestData } from '../../../testTypes'; +import { generateMetadata, transformResultBuilder } from '../../../testUtils'; +import { destType, channel, destination, getHeader } from '../common'; + +export const impressions: ProcessorTestData[] = [ + { + id: 'Impressions-test', + name: destType, + description: 'Impressions call: Example Impression Event', + scenario: 'Framework+Business', + successCriteria: + 'Response should contain the input payload with mappings configured in transformer and status code should be 200', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: { + type: 'track', + channel, + anonymousId: 'anonId123', + userId: 'userId123', + event: 'Example Impression Event', + properties: { + tracking_data: 'dummy-tracking-data', + rank: 1, + beacon_issued: '2024-03-04T15:32:56.409Z', + }, + integrations: { + All: true, + koddi: { + eventName: 'Impressions', + }, + }, + originalTimestamp: '2024-03-04T15:32:56.409Z', + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + method: 'GET', + endpoint: destination.Config.apiBaseUrl + '?action=impression', + headers: getHeader, + userId: '', + params: { + trackingData: 'dummy-tracking-data', + rank: 1, + beaconIssued: '2024-03-04T15:32:56.409Z', + ts: '2024-03-04T15:32:56.409Z', + clientName: destination.Config.clientName, + }, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/koddi/router/data.ts b/test/integrations/destinations/koddi/router/data.ts new file mode 100644 index 0000000000..f5fae9bfd4 --- /dev/null +++ b/test/integrations/destinations/koddi/router/data.ts @@ -0,0 +1,232 @@ +import { RouterTransformationRequest } from '../../../../../src/types'; +import { generateMetadata } from '../../../testUtils'; +import { + destType, + channel, + destination, + getHeader, + postHeader, + RouterInstrumentationErrorStatTags, + bidders, +} from '../common'; + +const routerRequest: RouterTransformationRequest = { + input: [ + { + destination, + message: { + type: 'track', + channel, + anonymousId: 'anonId123', + userId: 'userId123', + event: 'Example Impression Event', + properties: { + tracking_data: 'dummy-tracking-data', + rank: 1, + beacon_issued: '2024-03-04T15:32:56.409Z', + }, + integrations: { + All: true, + koddi: { + eventName: 'Impressions', + }, + }, + originalTimestamp: '2024-03-04T15:32:56.409Z', + }, + metadata: generateMetadata(1), + }, + { + destination, + message: { + type: 'track', + channel, + anonymousId: 'anonId123', + userId: 'userId123', + event: 'Example Clicks Event', + properties: { + tracking_data: 'dummy-tracking-data', + rank: 1, + beacon_issued: '2024-03-04T15:32:56.409Z', + }, + integrations: { + All: true, + koddi: { + eventName: 'Clicks', + }, + }, + originalTimestamp: '2024-03-04T15:32:56.409Z', + }, + metadata: generateMetadata(2), + }, + { + destination, + message: { + type: 'track', + channel, + anonymousId: 'anonId123', + userId: 'userId123', + event: 'Example Conversions Event', + properties: { + currency: 'USD', + transaction_id: 'ABC123', + bidders, + }, + context: { + locale: 'en-US', + ip: '127.0.0.1', + }, + integrations: { + All: true, + koddi: { + eventName: 'Conversions', + }, + }, + originalTimestamp: '2024-03-04T15:32:56.409Z', + }, + metadata: generateMetadata(3), + }, + { + destination, + message: { + type: 'track', + channel, + anonymousId: 'anonId123', + userId: 'userId123', + event: 'Example Impression Event', + properties: { + rank: 1, + beacon_issued: '2024-03-04T15:32:56.409Z', + }, + integrations: { + All: true, + koddi: { + eventName: 'Impressions', + }, + }, + originalTimestamp: '2024-03-04T15:32:56.409Z', + }, + metadata: generateMetadata(4), + }, + ], + destType, +}; + +export const data = [ + { + id: 'koddi-router-test', + name: destType, + description: 'Basic Router Test to test payloads and missing field error', + scenario: 'Framework', + successCriteria: + 'Some events should be transformed successfully and some should fail for missing fields and status code should be 200', + feature: 'router', + module: 'destination', + version: 'v0', + input: { + request: { + body: routerRequest, + }, + }, + output: { + response: { + status: 200, + body: { + output: [ + { + batched: false, + batchedRequest: { + version: '1', + type: 'REST', + method: 'GET', + endpoint: destination.Config.apiBaseUrl + '?action=impression', + headers: getHeader, + params: { + trackingData: 'dummy-tracking-data', + rank: 1, + beaconIssued: '2024-03-04T15:32:56.409Z', + ts: '2024-03-04T15:32:56.409Z', + clientName: destination.Config.clientName, + }, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + }, + destination, + metadata: [generateMetadata(1)], + statusCode: 200, + }, + { + batched: false, + batchedRequest: { + version: '1', + type: 'REST', + method: 'GET', + endpoint: destination.Config.apiBaseUrl + '?action=click', + headers: getHeader, + params: { + trackingData: 'dummy-tracking-data', + rank: 1, + beaconIssued: '2024-03-04T15:32:56.409Z', + userGuid: 'userId123', + clientName: destination.Config.clientName, + }, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + }, + destination, + metadata: [generateMetadata(2)], + statusCode: 200, + }, + { + batched: false, + batchedRequest: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: destination.Config.apiBaseUrl + '/conversion', + headers: postHeader, + params: {}, + body: { + JSON: { + client_name: 'test-client', + culture: 'en-US', + currency: 'USD', + transaction_id: 'ABC123', + unixtime: 1709566376, + userGuid: 'userId123', + user_ip: '127.0.0.1', + bidders: bidders, + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + }, + destination, + metadata: [generateMetadata(3)], + statusCode: 200, + }, + { + batched: false, + error: 'Missing required value from "properties.tracking_data"', + destination, + metadata: [generateMetadata(4)], + statTags: RouterInstrumentationErrorStatTags, + statusCode: 400, + }, + ], + }, + }, + }, + }, +]; From 31e6460ccc0c18014ebf67eab23b59abe5d81ef6 Mon Sep 17 00:00:00 2001 From: Manish Kumar Date: Wed, 15 May 2024 18:55:50 +0530 Subject: [PATCH 07/11] fix: minor mapping issue in conversions --- src/cdk/v2/destinations/koddi/data/ConversionsConfig.json | 2 +- src/cdk/v2/destinations/koddi/utils.test.js | 2 +- test/integrations/destinations/koddi/processor/conversions.ts | 2 +- test/integrations/destinations/koddi/router/data.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cdk/v2/destinations/koddi/data/ConversionsConfig.json b/src/cdk/v2/destinations/koddi/data/ConversionsConfig.json index 0d49e39c32..495574f198 100644 --- a/src/cdk/v2/destinations/koddi/data/ConversionsConfig.json +++ b/src/cdk/v2/destinations/koddi/data/ConversionsConfig.json @@ -25,7 +25,7 @@ "sourceKeys": "userId", "sourceFromGenericMap": true, "required": true, - "destKey": "userGuid" + "destKey": "user_guid" }, { "sourceKeys": "context.device.type", diff --git a/src/cdk/v2/destinations/koddi/utils.test.js b/src/cdk/v2/destinations/koddi/utils.test.js index ed12ecd5dd..59a02b62a0 100644 --- a/src/cdk/v2/destinations/koddi/utils.test.js +++ b/src/cdk/v2/destinations/koddi/utils.test.js @@ -265,7 +265,7 @@ describe('constructFullPayload', () => { currency: 'USD', transaction_id: '123', unixtime: 1709405952, - userGuid: '1234', + user_guid: '1234', user_ip: '127.0.0.1', bidders: [ { diff --git a/test/integrations/destinations/koddi/processor/conversions.ts b/test/integrations/destinations/koddi/processor/conversions.ts index 35d1670b95..7c8494d258 100644 --- a/test/integrations/destinations/koddi/processor/conversions.ts +++ b/test/integrations/destinations/koddi/processor/conversions.ts @@ -70,7 +70,7 @@ export const conversions: ProcessorTestData[] = [ currency: 'USD', transaction_id: 'ABC123', unixtime: 1709566376, - userGuid: 'userId123', + user_guid: 'userId123', user_ip: '127.0.0.1', bidders: bidders, }, diff --git a/test/integrations/destinations/koddi/router/data.ts b/test/integrations/destinations/koddi/router/data.ts index f5fae9bfd4..85f1319e39 100644 --- a/test/integrations/destinations/koddi/router/data.ts +++ b/test/integrations/destinations/koddi/router/data.ts @@ -202,7 +202,7 @@ export const data = [ currency: 'USD', transaction_id: 'ABC123', unixtime: 1709566376, - userGuid: 'userId123', + user_guid: 'userId123', user_ip: '127.0.0.1', bidders: bidders, }, From 7c0d963d3ee87a3ed5712492300dc50768c529de Mon Sep 17 00:00:00 2001 From: Manish Kumar Date: Mon, 20 May 2024 14:20:40 +0530 Subject: [PATCH 08/11] fix: resolving comments --- src/cdk/v2/destinations/koddi/config.js | 10 ++- .../v2/destinations/koddi/procWorkflow.yaml | 14 ++-- src/cdk/v2/destinations/koddi/utils.js | 40 +++++----- src/cdk/v2/destinations/koddi/utils.test.js | 78 +++++++++---------- .../destinations/koddi/processor/clicks.ts | 2 +- .../koddi/processor/conversions.ts | 4 +- .../koddi/processor/impressions.ts | 2 +- .../destinations/koddi/router/data.ts | 38 ++++++++- 8 files changed, 110 insertions(+), 78 deletions(-) diff --git a/src/cdk/v2/destinations/koddi/config.js b/src/cdk/v2/destinations/koddi/config.js index fa595dc627..927e1858fc 100644 --- a/src/cdk/v2/destinations/koddi/config.js +++ b/src/cdk/v2/destinations/koddi/config.js @@ -1,6 +1,12 @@ const { getMappingConfig } = require('../../../../v0/util'); -const EVENT_NAMES = { +/** + * ref :- https://developers.koddi.com/reference/winning-ads + * impressions - https://developers.koddi.com/reference/impressions-1 + * clicks - https://developers.koddi.com/reference/clicks-1 + * conversions - https://developers.koddi.com/reference/conversions-1 + */ +const EVENT_TYPES = { IMPRESSIONS: 'impressions', CLICKS: 'clicks', CONVERSIONS: 'conversions', @@ -24,7 +30,7 @@ const CONFIG_CATEGORIES = { const MAPPING_CONFIG = getMappingConfig(CONFIG_CATEGORIES, __dirname); module.exports = { - EVENT_NAMES, + EVENT_TYPES, CONFIG_CATEGORIES, MAPPING_CONFIG, IMPRESSIONS_CONFIG: MAPPING_CONFIG[CONFIG_CATEGORIES.IMPRESSIONS.name], diff --git a/src/cdk/v2/destinations/koddi/procWorkflow.yaml b/src/cdk/v2/destinations/koddi/procWorkflow.yaml index 28d062d4a4..cc3f0166dc 100644 --- a/src/cdk/v2/destinations/koddi/procWorkflow.yaml +++ b/src/cdk/v2/destinations/koddi/procWorkflow.yaml @@ -11,25 +11,23 @@ steps: - name: messageType template: | .message.type.toLowerCase(); - - name: eventName + - name: eventType template: | - .message.integrations.koddi.eventName.toLowerCase(); + .message.integrations.koddi.eventType.toLowerCase(); - name: validateInput template: | let messageType = $.outputs.messageType; - let eventName = $.outputs.eventName; + let eventType = $.outputs.eventType; $.assert(messageType, "message Type is not present. Aborting message."); $.assert(messageType in {{$.EventType.([.TRACK])}}, "message type " + messageType + " is not supported"); - $.assert(eventName in {{$.EVENT_NAMES.([.IMPRESSIONS, .CLICKS, .CONVERSIONS])}}, "event name " + eventName + " is not supported"); - $.assert(.message.event, "Event name is not present. Aborting"); - $.assert(typeof .message.event === "string", "event name should be a string"); + $.assert(eventType in {{$.EVENT_TYPES.([.IMPRESSIONS, .CLICKS, .CONVERSIONS])}}, "event type " + eventType + " is not supported"); $.assertConfig(.destination.Config.apiBaseUrl, "API Base URL is not present. Aborting"); $.assertConfig(.destination.Config.clientName, "Client Name is not present. Aborting"); - name: preparePayload template: | - const payload = $.constructFullPayload($.outputs.eventName, .message, .destination.Config); + const payload = $.constructFullPayload($.outputs.eventType, .message, .destination.Config); $.context.payload = $.removeUndefinedAndNullValues(payload); - name: buildResponse template: | - const response = $.constructResponse($.outputs.eventName, .destination.Config, $.context.payload); + const response = $.constructResponse($.outputs.eventType, .destination.Config, $.context.payload); response diff --git a/src/cdk/v2/destinations/koddi/utils.js b/src/cdk/v2/destinations/koddi/utils.js index f6521d1a66..13014e2e7c 100644 --- a/src/cdk/v2/destinations/koddi/utils.js +++ b/src/cdk/v2/destinations/koddi/utils.js @@ -1,5 +1,5 @@ const { InstrumentationError } = require('@rudderstack/integrations-lib'); -const { EVENT_NAMES, IMPRESSIONS_CONFIG, CLICKS_CONFIG, CONVERSIONS_CONFIG } = require('./config'); +const { EVENT_TYPES, IMPRESSIONS_CONFIG, CLICKS_CONFIG, CONVERSIONS_CONFIG } = require('./config'); const { constructPayload, defaultRequestConfig, @@ -31,19 +31,19 @@ const validateBidders = (bidders) => { /** * This function constructs payloads based upon mappingConfig for all calls. - * @param {*} eventName + * @param {*} eventType * @param {*} message * @param {*} Config * @returns */ -const constructFullPayload = (eventName, message, Config) => { +const constructFullPayload = (eventType, message, Config) => { let payload; - switch (eventName) { - case EVENT_NAMES.IMPRESSIONS: + switch (eventType) { + case EVENT_TYPES.IMPRESSIONS: payload = constructPayload(message, IMPRESSIONS_CONFIG); payload.clientName = Config.clientName; break; - case EVENT_NAMES.CLICKS: + case EVENT_TYPES.CLICKS: payload = constructPayload(message, CLICKS_CONFIG); payload.clientName = Config.clientName; if (!Config.testVersionOverride) { @@ -53,53 +53,53 @@ const constructFullPayload = (eventName, message, Config) => { payload.overrides = null; } break; - case EVENT_NAMES.CONVERSIONS: + case EVENT_TYPES.CONVERSIONS: payload = constructPayload(message, CONVERSIONS_CONFIG); payload.client_name = Config.clientName; payload.unixtime = toUnixTimestamp(payload.unixtime); validateBidders(payload.bidders); break; default: - throw new InstrumentationError(`event name ${eventName} is not supported.`); + throw new InstrumentationError(`event type ${eventType} is not supported.`); } return payload; }; -const getEndpoint = (eventName, Config) => { +const getEndpoint = (eventType, Config) => { let endpoint = stripTrailingSlash(Config.apiBaseUrl); - switch (eventName) { - case EVENT_NAMES.IMPRESSIONS: + switch (eventType) { + case EVENT_TYPES.IMPRESSIONS: endpoint += '?action=impression'; break; - case EVENT_NAMES.CLICKS: + case EVENT_TYPES.CLICKS: endpoint += '?action=click'; break; - case EVENT_NAMES.CONVERSIONS: + case EVENT_TYPES.CONVERSIONS: endpoint += '/conversion'; break; default: - throw new InstrumentationError(`event name ${eventName} is not supported.`); + throw new InstrumentationError(`event type ${eventType} is not supported.`); } return endpoint; }; /** * This function constructs response based upon event. - * @param {*} eventName + * @param {*} eventType * @param {*} Config * @param {*} payload * @returns */ -const constructResponse = (eventName, Config, payload) => { - if (!Object.values(EVENT_NAMES).includes(eventName)) { - throw new InstrumentationError(`event name ${eventName} is not supported.`); +const constructResponse = (eventType, Config, payload) => { + if (!Object.values(EVENT_TYPES).includes(eventType)) { + throw new InstrumentationError(`event type ${eventType} is not supported.`); } const response = defaultRequestConfig(); - response.endpoint = getEndpoint(eventName, Config); + response.endpoint = getEndpoint(eventType, Config); response.headers = { accept: 'application/json', }; - if (eventName === EVENT_NAMES.CONVERSIONS) { + if (eventType === EVENT_TYPES.CONVERSIONS) { response.body.JSON = payload; response.method = 'POST'; response.headers = { diff --git a/src/cdk/v2/destinations/koddi/utils.test.js b/src/cdk/v2/destinations/koddi/utils.test.js index 59a02b62a0..2c1f660f70 100644 --- a/src/cdk/v2/destinations/koddi/utils.test.js +++ b/src/cdk/v2/destinations/koddi/utils.test.js @@ -8,43 +8,43 @@ const { InstrumentationError } = require('@rudderstack/integrations-lib'); describe('getEndpoint', () => { it('returns the correct endpoint for IMPRESSIONS event', () => { - const eventName = 'impressions'; + const eventType = 'impressions'; const Config = { apiBaseUrl: 'https://www.test-client.com/', clientName: 'test-client', }; - const result = getEndpoint(eventName, Config); + const result = getEndpoint(eventType, Config); expect(result).toEqual('https://www.test-client.com?action=impression'); }); it('returns the correct endpoint for CLICKS event', () => { - const eventName = 'clicks'; + const eventType = 'clicks'; const Config = { apiBaseUrl: 'https://www.test-client.com', clientName: 'test-client', }; - const result = getEndpoint(eventName, Config); + const result = getEndpoint(eventType, Config); expect(result).toEqual('https://www.test-client.com?action=click'); }); it('returns the correct endpoint for IMPRESSIONS event', () => { - const eventName = 'conversions'; + const eventType = 'conversions'; const Config = { apiBaseUrl: 'https://www.test-client.com', clientName: 'test-client', }; - const result = getEndpoint(eventName, Config); + const result = getEndpoint(eventType, Config); expect(result).toEqual('https://www.test-client.com/conversion'); }); it('should throw error for unsupported event', () => { - const eventName = 'test'; + const eventType = 'test'; const Config = { apiBaseUrl: 'https://www.test-client.com', clientName: 'test-client', }; - expect(() => getEndpoint(eventName, Config)).toThrow(InstrumentationError); - expect(() => getEndpoint(eventName, Config)).toThrow('event name test is not supported.'); + expect(() => getEndpoint(eventType, Config)).toThrow(InstrumentationError); + expect(() => getEndpoint(eventType, Config)).toThrow('event type test is not supported.'); }); }); @@ -84,9 +84,7 @@ describe('validateBidders', () => { }); it('should throw error if base_price is not present', () => { - const bidders = [ - { bidder: 'bidder1', alternate_bidder: 'alternate1', count: 1 }, // Missing base_price - ]; + const bidders = [{ bidder: 'bidder1', alternate_bidder: 'alternate1', count: 1 }]; expect(() => validateBidders(bidders)).toThrow(InstrumentationError); expect(() => validateBidders(bidders)).toThrow('base_price is not present. Aborting.'); }); @@ -102,7 +100,7 @@ describe('validateBidders', () => { describe('constructFullPayload', () => { it('should construct payload for IMPRESSIONS event', () => { - const eventName = 'impressions'; + const eventType = 'impressions'; const message = { type: 'track', event: 'Impressions Event', @@ -124,11 +122,11 @@ describe('constructFullPayload', () => { trackingData: 'dummy-tracking-data', ts: '2024-03-03T00:29:12.117+05:30', }; - const payload = constructFullPayload(eventName, message, Config); + const payload = constructFullPayload(eventType, message, Config); expect(payload).toEqual(expectedPayload); }); it('should throw error if required value is missing for IMPRESSIONS event', () => { - const eventName = 'impressions'; + const eventType = 'impressions'; const message = { type: 'track', event: 'Impressions Event', @@ -144,14 +142,14 @@ describe('constructFullPayload', () => { clientName: 'test-client', }; try { - const payload = constructFullPayload(eventName, message, Config); + const payload = constructFullPayload(eventType, message, Config); } catch (error) { expect(error.message).toEqual('Missing required value from "properties.tracking_data"'); } }); it('should construct payload for CLICKS event', () => { - const eventName = 'clicks'; + const eventType = 'clicks'; const message = { type: 'track', event: 'Clicks Event', @@ -175,11 +173,11 @@ describe('constructFullPayload', () => { overrides: null, testVersionOverride: null, }; - const payload = constructFullPayload(eventName, message, Config); + const payload = constructFullPayload(eventType, message, Config); expect(payload).toEqual(expectedPayload); }); it('should construct payload with non-null value if overrides and testVersionOverride are enable and values for these are provided for CLICKS event ', () => { - const eventName = 'clicks'; + const eventType = 'clicks'; const message = { type: 'track', event: 'Clicks Event', @@ -207,11 +205,11 @@ describe('constructFullPayload', () => { overrides: 'overridden-value', testVersionOverride: null, }; - const payload = constructFullPayload(eventName, message, Config); + const payload = constructFullPayload(eventType, message, Config); expect(payload).toEqual(expectedPayload); }); it('should throw error if required value is missing for CLICKS event', () => { - const eventName = 'clicks'; + const eventType = 'clicks'; const message = { type: 'track', event: 'Clicks Event', @@ -226,14 +224,14 @@ describe('constructFullPayload', () => { clientName: 'test-client', }; try { - const payload = constructFullPayload(eventName, message, Config); + const payload = constructFullPayload(eventType, message, Config); } catch (error) { expect(error.message).toEqual('Missing required value from "userId"'); } }); it('should construct payload for CONVERSIONS event', () => { - const eventName = 'conversions'; + const eventType = 'conversions'; const message = { type: 'track', event: 'Conversions Event', @@ -275,11 +273,11 @@ describe('constructFullPayload', () => { }, ], }; - const payload = constructFullPayload(eventName, message, Config); + const payload = constructFullPayload(eventType, message, Config); expect(payload).toEqual(expectedPayload); }); it('should throw error if required value is missing for CONVERSIONS event', () => { - const eventName = 'conversions'; + const eventType = 'conversions'; const message = { type: 'track', event: 'Conversions Event', @@ -305,26 +303,26 @@ describe('constructFullPayload', () => { clientName: 'test-client', }; try { - const payload = constructFullPayload(eventName, message, Config); + const payload = constructFullPayload(eventType, message, Config); } catch (error) { expect(error.message).toEqual('Missing required value from "context.locale"'); } }); it('should throw error for unsupported event', () => { - const eventName = 'test'; + const eventType = 'test'; const message = {}; const Config = {}; - expect(() => constructFullPayload(eventName, message, Config)).toThrow(InstrumentationError); - expect(() => constructFullPayload(eventName, message, Config)).toThrow( - 'event name test is not supported.', + expect(() => constructFullPayload(eventType, message, Config)).toThrow(InstrumentationError); + expect(() => constructFullPayload(eventType, message, Config)).toThrow( + 'event type test is not supported.', ); }); }); describe('constructResponse', () => { it('should construct response for IMPRESSIONS event', () => { - const eventName = 'impressions'; + const eventType = 'impressions'; const Config = { apiBaseUrl: 'https://www.test-client.com', clientName: 'test-client', @@ -344,12 +342,12 @@ describe('constructResponse', () => { method: 'GET', params: payload, }; - const response = constructResponse(eventName, Config, payload); + const response = constructResponse(eventType, Config, payload); expect(response).toMatchObject(expectedResponse); }); it('should construct response for CLICKS event', () => { - const eventName = 'clicks'; + const eventType = 'clicks'; const Config = { apiBaseUrl: 'https://www.test-client.com', clientName: 'test-client', @@ -369,12 +367,12 @@ describe('constructResponse', () => { method: 'GET', params: payload, }; - const response = constructResponse(eventName, Config, payload); + const response = constructResponse(eventType, Config, payload); expect(response).toMatchObject(expectedResponse); }); it('should construct response for CONVERSIONS event', () => { - const eventName = 'conversions'; + const eventType = 'conversions'; const Config = { apiBaseUrl: 'https://www.test-client.com', clientName: 'test-client', @@ -407,17 +405,17 @@ describe('constructResponse', () => { JSON: payload, }, }; - const response = constructResponse(eventName, Config, payload); + const response = constructResponse(eventType, Config, payload); expect(response).toMatchObject(expectedResponse); }); it('should throw error for unsupported event', () => { - const eventName = 'test'; + const eventType = 'test'; const Config = {}; const payload = {}; - expect(() => constructResponse(eventName, Config, payload)).toThrow(InstrumentationError); - expect(() => constructResponse(eventName, Config, payload)).toThrow( - 'event name test is not supported.', + expect(() => constructResponse(eventType, Config, payload)).toThrow(InstrumentationError); + expect(() => constructResponse(eventType, Config, payload)).toThrow( + 'event type test is not supported.', ); }); }); diff --git a/test/integrations/destinations/koddi/processor/clicks.ts b/test/integrations/destinations/koddi/processor/clicks.ts index 6270c0468d..6101e9bafe 100644 --- a/test/integrations/destinations/koddi/processor/clicks.ts +++ b/test/integrations/destinations/koddi/processor/clicks.ts @@ -32,7 +32,7 @@ export const clicks: ProcessorTestData[] = [ integrations: { All: true, koddi: { - eventName: 'Clicks', + eventType: 'Clicks', }, }, originalTimestamp: '2024-03-04T15:32:56.409Z', diff --git a/test/integrations/destinations/koddi/processor/conversions.ts b/test/integrations/destinations/koddi/processor/conversions.ts index 7c8494d258..1647ffed7d 100644 --- a/test/integrations/destinations/koddi/processor/conversions.ts +++ b/test/integrations/destinations/koddi/processor/conversions.ts @@ -44,7 +44,7 @@ export const conversions: ProcessorTestData[] = [ integrations: { All: true, koddi: { - eventName: 'Conversions', + eventType: 'Conversions', }, }, originalTimestamp: '2024-03-04T15:32:56.409Z', @@ -114,7 +114,7 @@ export const conversions: ProcessorTestData[] = [ integrations: { All: true, koddi: { - eventName: 'Conversions', + eventType: 'Conversions', }, }, originalTimestamp: '2024-03-04T15:32:56.409Z', diff --git a/test/integrations/destinations/koddi/processor/impressions.ts b/test/integrations/destinations/koddi/processor/impressions.ts index 35ffcad22b..840ed9139f 100644 --- a/test/integrations/destinations/koddi/processor/impressions.ts +++ b/test/integrations/destinations/koddi/processor/impressions.ts @@ -32,7 +32,7 @@ export const impressions: ProcessorTestData[] = [ integrations: { All: true, koddi: { - eventName: 'Impressions', + eventType: 'Impressions', }, }, originalTimestamp: '2024-03-04T15:32:56.409Z', diff --git a/test/integrations/destinations/koddi/router/data.ts b/test/integrations/destinations/koddi/router/data.ts index 85f1319e39..1601a481e5 100644 --- a/test/integrations/destinations/koddi/router/data.ts +++ b/test/integrations/destinations/koddi/router/data.ts @@ -28,7 +28,7 @@ const routerRequest: RouterTransformationRequest = { integrations: { All: true, koddi: { - eventName: 'Impressions', + eventType: 'Impressions', }, }, originalTimestamp: '2024-03-04T15:32:56.409Z', @@ -51,7 +51,7 @@ const routerRequest: RouterTransformationRequest = { integrations: { All: true, koddi: { - eventName: 'Clicks', + eventType: 'Clicks', }, }, originalTimestamp: '2024-03-04T15:32:56.409Z', @@ -78,7 +78,7 @@ const routerRequest: RouterTransformationRequest = { integrations: { All: true, koddi: { - eventName: 'Conversions', + eventType: 'Conversions', }, }, originalTimestamp: '2024-03-04T15:32:56.409Z', @@ -100,13 +100,35 @@ const routerRequest: RouterTransformationRequest = { integrations: { All: true, koddi: { - eventName: 'Impressions', + eventType: 'Impressions', }, }, originalTimestamp: '2024-03-04T15:32:56.409Z', }, metadata: generateMetadata(4), }, + { + destination, + message: { + type: 'track', + channel, + anonymousId: 'anonId123', + userId: 'userId123', + properties: { + tracking_data: 'dummy-tracking-data', + rank: 1, + beacon_issued: '2024-03-04T15:32:56.409Z', + }, + integrations: { + All: true, + koddi: { + eventType: 'Unknown', + }, + }, + originalTimestamp: '2024-03-04T15:32:56.409Z', + }, + metadata: generateMetadata(5), + }, ], destType, }; @@ -224,6 +246,14 @@ export const data = [ statTags: RouterInstrumentationErrorStatTags, statusCode: 400, }, + { + batched: false, + error: 'event type unknown is not supported', + destination, + metadata: [generateMetadata(5)], + statTags: RouterInstrumentationErrorStatTags, + statusCode: 400, + }, ], }, }, From 90e60a5a28b1f868ecb50ce56406f2e706b10e7f Mon Sep 17 00:00:00 2001 From: Gauravudia <60897972+Gauravudia@users.noreply.github.com> Date: Wed, 22 May 2024 15:40:03 +0530 Subject: [PATCH 09/11] refactor: deprecate mixpanel /track endpoint (#2833) (#3399) * refactor: deprecate mixpanel /track endpoint (#2833) * refactor: deprecate mixpanel /track endpoint * fix: used token in place of apiSecret for merge call * fix: no-case-declarations * refactor: responseBuilderSimple --- src/util/prometheus.js | 6 - src/v0/destinations/mp/config.js | 2 - src/v0/destinations/mp/transform.js | 83 ++-- src/v0/destinations/mp/util.js | 8 +- src/v0/destinations/mp/util.test.js | 14 - test/integrations/destinations/mp/common.ts | 2 +- .../destinations/mp/processor/data.ts | 363 ++++++++++-------- .../destinations/mp/router/data.ts | 12 +- 8 files changed, 249 insertions(+), 241 deletions(-) diff --git a/src/util/prometheus.js b/src/util/prometheus.js index 882dff9e75..a46eae12c9 100644 --- a/src/util/prometheus.js +++ b/src/util/prometheus.js @@ -587,12 +587,6 @@ class Prometheus { type: 'gauge', labelNames: ['destination_id'], }, - { - name: 'mixpanel_batch_track_pack_size', - help: 'mixpanel_batch_track_pack_size', - type: 'gauge', - labelNames: ['destination_id'], - }, { name: 'mixpanel_batch_import_pack_size', help: 'mixpanel_batch_import_pack_size', diff --git a/src/v0/destinations/mp/config.js b/src/v0/destinations/mp/config.js index 35b40294f5..3abdf2eebb 100644 --- a/src/v0/destinations/mp/config.js +++ b/src/v0/destinations/mp/config.js @@ -49,7 +49,6 @@ const MP_IDENTIFY_EXCLUSION_LIST = [ ]; const GEO_SOURCE_ALLOWED_VALUES = [null, 'reverse_geocoding']; -const TRACK_MAX_BATCH_SIZE = 50; const IMPORT_MAX_BATCH_SIZE = 2000; const ENGAGE_MAX_BATCH_SIZE = 2000; const GROUPS_MAX_BATCH_SIZE = 200; @@ -68,7 +67,6 @@ module.exports = { MP_IDENTIFY_EXCLUSION_LIST, getCreateDeletionTaskEndpoint, DISTINCT_ID_MAX_BATCH_SIZE, - TRACK_MAX_BATCH_SIZE, IMPORT_MAX_BATCH_SIZE, ENGAGE_MAX_BATCH_SIZE, GROUPS_MAX_BATCH_SIZE, diff --git a/src/v0/destinations/mp/transform.js b/src/v0/destinations/mp/transform.js index 09a7862f9a..2065764b98 100644 --- a/src/v0/destinations/mp/transform.js +++ b/src/v0/destinations/mp/transform.js @@ -24,7 +24,6 @@ const { mappingConfig, BASE_ENDPOINT, BASE_ENDPOINT_EU, - TRACK_MAX_BATCH_SIZE, IMPORT_MAX_BATCH_SIZE, ENGAGE_MAX_BATCH_SIZE, GROUPS_MAX_BATCH_SIZE, @@ -47,21 +46,19 @@ const mPEventPropertiesConfigJson = mappingConfig[ConfigCategory.EVENT_PROPERTIE const setImportCredentials = (destConfig) => { const endpoint = destConfig.dataResidency === 'eu' ? `${BASE_ENDPOINT_EU}/import/` : `${BASE_ENDPOINT}/import/`; - const headers = { 'Content-Type': 'application/json' }; const params = { strict: destConfig.strictMode ? 1 : 0 }; - const { apiSecret, serviceAccountUserName, serviceAccountSecret, projectId } = destConfig; - if (apiSecret) { - headers.Authorization = `Basic ${base64Convertor(`${apiSecret}:`)}`; + const { serviceAccountUserName, serviceAccountSecret, projectId, token } = destConfig; + let credentials; + if (token) { + credentials = `${token}:`; } else if (serviceAccountUserName && serviceAccountSecret && projectId) { - headers.Authorization = `Basic ${base64Convertor( - `${serviceAccountUserName}:${serviceAccountSecret}`, - )}`; + credentials = `${serviceAccountUserName}:${serviceAccountSecret}`; params.projectId = projectId; - } else { - throw new InstrumentationError( - 'Event timestamp is older than 5 days and no API secret or service account credentials (i.e. username, secret and projectId) are provided in destination configuration', - ); } + const headers = { + 'Content-Type': 'application/json', + Authorization: `Basic ${base64Convertor(credentials)}`, + }; return { endpoint, headers, params }; }; @@ -70,46 +67,34 @@ const responseBuilderSimple = (payload, message, eventType, destConfig) => { response.method = defaultPostRequestConfig.requestMethod; response.userId = message.userId || message.anonymousId; response.body.JSON_ARRAY = { batch: JSON.stringify([removeUndefinedValues(payload)]) }; - const { apiSecret, serviceAccountUserName, serviceAccountSecret, projectId, dataResidency } = - destConfig; + const { dataResidency } = destConfig; const duration = getTimeDifference(message.timestamp); + + const setCredentials = () => { + const credentials = setImportCredentials(destConfig); + response.endpoint = credentials.endpoint; + response.headers = credentials.headers; + response.params = { + project_id: credentials.params?.projectId, + strict: credentials.params.strict, + }; + }; + switch (eventType) { case EventType.ALIAS: case EventType.TRACK: case EventType.SCREEN: - case EventType.PAGE: - if ( - !apiSecret && - !(serviceAccountUserName && serviceAccountSecret && projectId) && - duration.days <= 5 - ) { - response.endpoint = - dataResidency === 'eu' ? `${BASE_ENDPOINT_EU}/track/` : `${BASE_ENDPOINT}/track/`; - response.headers = {}; - } else if (duration.years > 5) { + case EventType.PAGE: { + if (duration.years > 5) { throw new InstrumentationError('Event timestamp should be within last 5 years'); - } else { - const credentials = setImportCredentials(destConfig); - response.endpoint = credentials.endpoint; - response.headers = credentials.headers; - response.params = { - project_id: credentials.params?.projectId, - strict: credentials.params.strict, - }; - break; } + setCredentials(); break; - case 'merge': - // eslint-disable-next-line no-case-declarations - const credentials = setImportCredentials(destConfig); - response.endpoint = credentials.endpoint; - response.headers = credentials.headers; - response.params = { - project_id: credentials.params?.projectId, - strict: credentials.params.strict, - }; + } + case 'merge': { + setCredentials(); break; - + } default: response.endpoint = dataResidency === 'eu' ? `${BASE_ENDPOINT_EU}/engage/` : `${BASE_ENDPOINT}/engage/`; @@ -484,7 +469,6 @@ const processRouterDest = async (inputs, reqMetadata) => { const batchSize = { engage: 0, groups: 0, - track: 0, import: 0, }; @@ -516,23 +500,16 @@ const processRouterDest = async (inputs, reqMetadata) => { ); transformedPayloads = lodash.flatMap(transformedPayloads); - const { engageEvents, groupsEvents, trackEvents, importEvents, batchErrorRespList } = + const { engageEvents, groupsEvents, importEvents, batchErrorRespList } = groupEventsByEndpoint(transformedPayloads); const engageRespList = batchEvents(engageEvents, ENGAGE_MAX_BATCH_SIZE, reqMetadata); const groupsRespList = batchEvents(groupsEvents, GROUPS_MAX_BATCH_SIZE, reqMetadata); - const trackRespList = batchEvents(trackEvents, TRACK_MAX_BATCH_SIZE, reqMetadata); const importRespList = batchEvents(importEvents, IMPORT_MAX_BATCH_SIZE, reqMetadata); - const batchSuccessRespList = [ - ...engageRespList, - ...groupsRespList, - ...trackRespList, - ...importRespList, - ]; + const batchSuccessRespList = [...engageRespList, ...groupsRespList, ...importRespList]; batchSize.engage += engageRespList.length; batchSize.groups += groupsRespList.length; - batchSize.track += trackRespList.length; batchSize.import += importRespList.length; return [...batchSuccessRespList, ...batchErrorRespList]; diff --git a/src/v0/destinations/mp/util.js b/src/v0/destinations/mp/util.js index d564e805ad..b2807d6e11 100644 --- a/src/v0/destinations/mp/util.js +++ b/src/v0/destinations/mp/util.js @@ -136,7 +136,7 @@ const createIdentifyResponse = (message, type, destination, responseBuilderSimpl * @returns */ const isImportAuthCredentialsAvailable = (destination) => - destination.Config.apiSecret || + destination.Config.token || (destination.Config.serviceAccountSecret && destination.Config.serviceAccountUserName && destination.Config.projectId); @@ -179,7 +179,6 @@ const groupEventsByEndpoint = (events) => { const eventMap = { engage: [], groups: [], - track: [], import: [], }; const batchErrorRespList = []; @@ -204,7 +203,6 @@ const groupEventsByEndpoint = (events) => { return { engageEvents: eventMap.engage, groupsEvents: eventMap.groups, - trackEvents: eventMap.track, importEvents: eventMap.import, batchErrorRespList, }; @@ -349,7 +347,6 @@ const generatePageOrScreenCustomEventName = (message, userDefinedEventTemplate) * @param {Object} batchSize - The object containing the batch size for different endpoints. * @param {number} batchSize.engage - The batch size for engage endpoint. * @param {number} batchSize.groups - The batch size for group endpoint. - * @param {number} batchSize.track - The batch size for track endpoint. * @param {number} batchSize.import - The batch size for import endpoint. * @param {string} destinationId - The ID of the destination. * @returns {void} @@ -361,9 +358,6 @@ const recordBatchSizeMetrics = (batchSize, destinationId) => { stats.gauge('mixpanel_batch_group_pack_size', batchSize.groups, { destination_id: destinationId, }); - stats.gauge('mixpanel_batch_track_pack_size', batchSize.track, { - destination_id: destinationId, - }); stats.gauge('mixpanel_batch_import_pack_size', batchSize.import, { destination_id: destinationId, }); diff --git a/src/v0/destinations/mp/util.test.js b/src/v0/destinations/mp/util.test.js index 40cdb34649..3666081f59 100644 --- a/src/v0/destinations/mp/util.test.js +++ b/src/v0/destinations/mp/util.test.js @@ -18,7 +18,6 @@ describe('Unit test cases for groupEventsByEndpoint', () => { expect(result).toEqual({ engageEvents: [], groupsEvents: [], - trackEvents: [], importEvents: [], batchErrorRespList: [], }); @@ -122,19 +121,6 @@ describe('Unit test cases for groupEventsByEndpoint', () => { }, }, ], - trackEvents: [ - { - message: { - endpoint: '/track', - body: { - JSON_ARRAY: { - batch: '[{prop:4}]', - }, - }, - userId: 'user1', - }, - }, - ], importEvents: [ { message: { diff --git a/test/integrations/destinations/mp/common.ts b/test/integrations/destinations/mp/common.ts index 82f0e3202b..d40afa0c02 100644 --- a/test/integrations/destinations/mp/common.ts +++ b/test/integrations/destinations/mp/common.ts @@ -7,7 +7,7 @@ const defaultMockFns = () => { const sampleDestination: Destination = { Config: { apiKey: 'dummyApiKey', - token: 'dummyApiKey', + token: 'test_api_token', prefixProperties: true, useNativeSDK: false, }, diff --git a/test/integrations/destinations/mp/processor/data.ts b/test/integrations/destinations/mp/processor/data.ts index 2d70d15384..db5bc840c2 100644 --- a/test/integrations/destinations/mp/processor/data.ts +++ b/test/integrations/destinations/mp/processor/data.ts @@ -12,7 +12,7 @@ export const data = [ request: { body: [ { - destination: overrideDestination(sampleDestination, { token: 'dummyApiKey' }), + destination: overrideDestination(sampleDestination, { token: 'test_api_token' }), message: { anonymousId: 'e6ab2c5e-2cda-44a9-a962-e2f67df78bca', channel: 'web', @@ -87,14 +87,17 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/track/', - headers: {}, - params: {}, + endpoint: 'https://api.mixpanel.com/import/', + headers: { + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + 'Content-Type': 'application/json', + }, + params: { strict: 0 }, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"Loaded a Page","properties":{"ip":"0.0.0.0","campaign_id":"test_name","$user_id":"hjikl","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"dd266c67-9199-4a52-ba32-f46ddde67312","token":"dummyApiKey","distinct_id":"hjikl","time":1579847342402,"utm_campaign":"test_name","utm_source":"rudder","utm_medium":"test_medium","utm_term":"test_tem","utm_content":"test_content","utm_test":"test","utm_keyword":"test_keyword","name":"Contact Us","$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', + '[{"event":"Loaded a Page","properties":{"ip":"0.0.0.0","campaign_id":"test_name","$user_id":"hjikl","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"dd266c67-9199-4a52-ba32-f46ddde67312","token":"test_api_token","distinct_id":"hjikl","time":1579847342402,"utm_campaign":"test_name","utm_source":"rudder","utm_medium":"test_medium","utm_term":"test_tem","utm_content":"test_content","utm_test":"test","utm_keyword":"test_keyword","name":"Contact Us","$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', }, XML: {}, FORM: {}, @@ -191,14 +194,17 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/track/', - headers: {}, - params: {}, + endpoint: 'https://api.mixpanel.com/import/', + headers: { + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + 'Content-Type': 'application/json', + }, + params: { strict: 0 }, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"Viewed a Contact Us page","properties":{"ip":"0.0.0.0","$user_id":"hjikl","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"dd266c67-9199-4a52-ba32-f46ddde67312","token":"dummyApiKey","distinct_id":"hjikl","time":1579847342402,"name":"Contact Us","category":"Contact","$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', + '[{"event":"Viewed a Contact Us page","properties":{"ip":"0.0.0.0","$user_id":"hjikl","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"dd266c67-9199-4a52-ba32-f46ddde67312","token":"test_api_token","distinct_id":"hjikl","time":1579847342402,"name":"Contact Us","category":"Contact","$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', }, XML: {}, FORM: {}, @@ -272,14 +278,17 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/track/', - headers: {}, - params: {}, + endpoint: 'https://api.mixpanel.com/import/', + headers: { + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + 'Content-Type': 'application/json', + }, + params: { strict: 0 }, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"Loaded a Screen","properties":{"category":"communication","ip":"0.0.0.0","$user_id":"hjikl","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"dd266c67-9199-4a52-ba32-f46ddde67312","token":"dummyApiKey","distinct_id":"hjikl","time":1579847342402,"name":"Contact Us"}}]', + '[{"event":"Loaded a Screen","properties":{"category":"communication","ip":"0.0.0.0","$user_id":"hjikl","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"dd266c67-9199-4a52-ba32-f46ddde67312","token":"test_api_token","distinct_id":"hjikl","time":1579847342402,"name":"Contact Us"}}]', }, XML: {}, FORM: {}, @@ -360,14 +369,17 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/track/', - headers: {}, - params: {}, + endpoint: 'https://api.mixpanel.com/import/', + headers: { + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + 'Content-Type': 'application/json', + }, + params: { strict: 0 }, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"Loaded a Screen","properties":{"path":"/tests/html/index2.html","referrer":"","search":"","title":"","url":"http://localhost/tests/html/index2.html","ip":"0.0.0.0","$user_id":"hjiklmk","$screen_dpi":2,"mp_lib":"RudderLabs Android SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"dd266c67-9199-4a52-ba32-f46ddde67312","token":"dummyApiKey","distinct_id":"hjiklmk","time":1579847342402,"name":"Contact Us","category":"Contact"}}]', + '[{"event":"Loaded a Screen","properties":{"path":"/tests/html/index2.html","referrer":"","search":"","title":"","url":"http://localhost/tests/html/index2.html","ip":"0.0.0.0","$user_id":"hjiklmk","$screen_dpi":2,"mp_lib":"RudderLabs Android SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"dd266c67-9199-4a52-ba32-f46ddde67312","token":"test_api_token","distinct_id":"hjiklmk","time":1579847342402,"name":"Contact Us","category":"Contact"}}]', }, XML: {}, FORM: {}, @@ -440,14 +452,17 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/track/', - headers: {}, - params: {}, + endpoint: 'https://api.mixpanel.com/import/', + headers: { + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + 'Content-Type': 'application/json', + }, + params: { strict: 0 }, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"Loaded a Screen","properties":{"ip":"0.0.0.0","$user_id":"hjikl","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"dd266c67-9199-4a52-ba32-f46ddde67312","token":"dummyApiKey","distinct_id":"hjikl","time":1579847342402,"name":"Contact Us"}}]', + '[{"event":"Loaded a Screen","properties":{"ip":"0.0.0.0","$user_id":"hjikl","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"dd266c67-9199-4a52-ba32-f46ddde67312","token":"test_api_token","distinct_id":"hjikl","time":1579847342402,"name":"Contact Us"}}]', }, XML: {}, FORM: {}, @@ -550,7 +565,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$created":"2020-01-23T08:54:02.362Z","$email":"mickey@disney.com","$first_name":"Mickey","$last_name":"Mouse","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', + '[{"$set":{"$created":"2020-01-23T08:54:02.362Z","$email":"mickey@disney.com","$first_name":"Mickey","$last_name":"Mouse","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', }, XML: {}, FORM: {}, @@ -664,7 +679,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$append":{"$transactions":{"$time":"2020-01-24T06:29:02.403Z","$amount":45.89}},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca"}]', + '[{"$append":{"$transactions":{"$time":"2020-01-24T06:29:02.403Z","$amount":45.89}},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca"}]', }, XML: {}, FORM: {}, @@ -686,7 +701,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$add":{"counter":1,"item_purchased":"2"},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca"}]', + '[{"$add":{"counter":1,"item_purchased":"2"},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca"}]', }, XML: {}, FORM: {}, @@ -701,14 +716,17 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/track/', - headers: {}, - params: {}, + endpoint: 'https://api.mixpanel.com/import/', + headers: { + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + 'Content-Type': 'application/json', + }, + params: { strict: 0 }, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"test revenue MIXPANEL","properties":{"currency":"USD","revenue":45.89,"counter":1,"item_purchased":"2","number_of_logins":"","city":"Disney","country":"USA","email":"mickey@disney.com","firstName":"Mickey","ip":"0.0.0.0","campaign_id":"test_name","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"a6a0ad5a-bd26-4f19-8f75-38484e580fc7","token":"dummyApiKey","distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","time":1579847342403,"utm_campaign":"test_name","utm_source":"rudder","utm_medium":"test_medium","utm_term":"test_tem","utm_content":"test_content","utm_test":"test","utm_keyword":"test_keyword","$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', + '[{"event":"test revenue MIXPANEL","properties":{"currency":"USD","revenue":45.89,"counter":1,"item_purchased":"2","number_of_logins":"","city":"Disney","country":"USA","email":"mickey@disney.com","firstName":"Mickey","ip":"0.0.0.0","campaign_id":"test_name","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"a6a0ad5a-bd26-4f19-8f75-38484e580fc7","token":"test_api_token","distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","time":1579847342403,"utm_campaign":"test_name","utm_source":"rudder","utm_medium":"test_medium","utm_term":"test_tem","utm_content":"test_content","utm_test":"test","utm_keyword":"test_keyword","$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', }, XML: {}, FORM: {}, @@ -796,14 +814,17 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/track/', - headers: {}, - params: {}, + endpoint: 'https://api.mixpanel.com/import/', + headers: { + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + 'Content-Type': 'application/json', + }, + params: { strict: 0 }, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"$create_alias","properties":{"distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","alias":"1234abc","token":"dummyApiKey"}}]', + '[{"event":"$create_alias","properties":{"distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","alias":"1234abc","token":"test_api_token"}}]', }, XML: {}, FORM: {}, @@ -933,7 +954,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$append":{"$transactions":{"$time":"2020-01-24T06:29:02.402Z","$amount":25}},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca"}]', + '[{"$append":{"$transactions":{"$time":"2020-01-24T06:29:02.402Z","$amount":25}},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca"}]', }, XML: {}, FORM: {}, @@ -948,14 +969,17 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/track/', - headers: {}, - params: {}, + endpoint: 'https://api.mixpanel.com/import/', + headers: { + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + 'Content-Type': 'application/json', + }, + params: { strict: 0 }, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"KM Order Completed","properties":{"affiliation":"Google Store","checkout_id":"fksdjfsdjfisjf9sdfjsd9f","coupon":"hasbros","currency":"USD","discount":2.5,"order_id":"50314b8e9bcf000000000000","products":[{"category":"Games","image_url":"https:///www.example.com/product/path.jpg","name":"Monopoly: 3rd Edition","price":19,"product_id":"507f1f77bcf86cd799439011","quantity":1,"sku":"45790-32","url":"https://www.example.com/product/path"},{"category":"Games","name":"Uno Card Game","price":3,"product_id":"505bd76785ebb509fc183733","quantity":2,"sku":"46493-32"}],"revenue":25,"shipping":3,"subtotal":22.5,"tax":2,"total":27.5,"city":"Disney","country":"USA","email":"mickey@disney.com","firstName":"Mickey","ip":"0.0.0.0","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"aa5f5e44-8756-40ad-ad1e-b0d3b9fa710a","token":"dummyApiKey","distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","time":1579847342402,"$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', + '[{"event":"KM Order Completed","properties":{"affiliation":"Google Store","checkout_id":"fksdjfsdjfisjf9sdfjsd9f","coupon":"hasbros","currency":"USD","discount":2.5,"order_id":"50314b8e9bcf000000000000","products":[{"category":"Games","image_url":"https:///www.example.com/product/path.jpg","name":"Monopoly: 3rd Edition","price":19,"product_id":"507f1f77bcf86cd799439011","quantity":1,"sku":"45790-32","url":"https://www.example.com/product/path"},{"category":"Games","name":"Uno Card Game","price":3,"product_id":"505bd76785ebb509fc183733","quantity":2,"sku":"46493-32"}],"revenue":25,"shipping":3,"subtotal":22.5,"tax":2,"total":27.5,"city":"Disney","country":"USA","email":"mickey@disney.com","firstName":"Mickey","ip":"0.0.0.0","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"aa5f5e44-8756-40ad-ad1e-b0d3b9fa710a","token":"test_api_token","distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","time":1579847342402,"$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', }, XML: {}, FORM: {}, @@ -1089,7 +1113,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$append":{"$transactions":{"$time":"2020-01-24T06:29:02.402Z","$amount":34}},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca"}]', + '[{"$append":{"$transactions":{"$time":"2020-01-24T06:29:02.402Z","$amount":34}},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca"}]', }, XML: {}, FORM: {}, @@ -1104,14 +1128,17 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/track/', - headers: {}, - params: {}, + endpoint: 'https://api.mixpanel.com/import/', + headers: { + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + 'Content-Type': 'application/json', + }, + params: { strict: 0 }, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"KM Order Completed","properties":{"affiliation":"Google Store","checkout_id":"fksdjfsdjfisjf9sdfjsd9f","coupon":"hasbros","currency":"USD","discount":2.5,"order_id":"50314b8e9bcf000000000000","revenue":34,"key_1":{"child_key1":"child_value1","child_key2":{"child_key21":"child_value21","child_key22":"child_value22"}},"products":[{"category":"Games","image_url":"https:///www.example.com/product/path.jpg","name":"Monopoly: 3rd Edition","price":19,"product_id":"507f1f77bcf86cd799439011","quantity":1,"sku":"45790-32","url":"https://www.example.com/product/path"},{"category":"Games","name":"Uno Card Game","price":3,"product_id":"505bd76785ebb509fc183733","quantity":2,"sku":"46493-32"}],"shipping":3,"subtotal":22.5,"tax":2,"total":27.5,"city":"Disney","country":"USA","email":"mickey@disney.com","first_name":"Mickey","lastName":"Mouse","name":"Mickey Mouse","ip":"0.0.0.0","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"aa5f5e44-8756-40ad-ad1e-b0d3b9fa710a","token":"dummyApiKey","distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","time":1579847342402,"$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', + '[{"event":"KM Order Completed","properties":{"affiliation":"Google Store","checkout_id":"fksdjfsdjfisjf9sdfjsd9f","coupon":"hasbros","currency":"USD","discount":2.5,"order_id":"50314b8e9bcf000000000000","revenue":34,"key_1":{"child_key1":"child_value1","child_key2":{"child_key21":"child_value21","child_key22":"child_value22"}},"products":[{"category":"Games","image_url":"https:///www.example.com/product/path.jpg","name":"Monopoly: 3rd Edition","price":19,"product_id":"507f1f77bcf86cd799439011","quantity":1,"sku":"45790-32","url":"https://www.example.com/product/path"},{"category":"Games","name":"Uno Card Game","price":3,"product_id":"505bd76785ebb509fc183733","quantity":2,"sku":"46493-32"}],"shipping":3,"subtotal":22.5,"tax":2,"total":27.5,"city":"Disney","country":"USA","email":"mickey@disney.com","first_name":"Mickey","lastName":"Mouse","name":"Mickey Mouse","ip":"0.0.0.0","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"aa5f5e44-8756-40ad-ad1e-b0d3b9fa710a","token":"test_api_token","distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","time":1579847342402,"$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', }, XML: {}, FORM: {}, @@ -1235,14 +1262,17 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/track/', - headers: {}, - params: {}, + endpoint: 'https://api.mixpanel.com/import/', + headers: { + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + 'Content-Type': 'application/json', + }, + params: { strict: 0 }, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":" new Order Completed totally","properties":{"affiliation":"Google Store","checkout_id":"fksdjfsdjfisjf9sdfjsd9f","coupon":"hasbros","currency":"USD","discount":2.5,"total":23,"order_id":"50314b8e9bcf000000000000","key_1":{"child_key1":"child_value1","child_key2":{"child_key21":"child_value21","child_key22":"child_value22"}},"products":[{"category":"Games","image_url":"https:///www.example.com/product/path.jpg","name":"Monopoly: 3rd Edition","price":19,"product_id":"507f1f77bcf86cd799439011","quantity":1,"sku":"45790-32","url":"https://www.example.com/product/path"},{"category":"Games","name":"Uno Card Game","price":3,"product_id":"505bd76785ebb509fc183733","quantity":2,"sku":"46493-32"}],"shipping":3,"subtotal":22.5,"tax":2,"city":"Disney","country":"USA","email":"mickey@disney.com","firstName":"Mickey","ip":"0.0.0.0","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"aa5f5e44-8756-40ad-ad1e-b0d3b9fa710a","token":"dummyApiKey","distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","time":1579847342402,"$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', + '[{"event":" new Order Completed totally","properties":{"affiliation":"Google Store","checkout_id":"fksdjfsdjfisjf9sdfjsd9f","coupon":"hasbros","currency":"USD","discount":2.5,"total":23,"order_id":"50314b8e9bcf000000000000","key_1":{"child_key1":"child_value1","child_key2":{"child_key21":"child_value21","child_key22":"child_value22"}},"products":[{"category":"Games","image_url":"https:///www.example.com/product/path.jpg","name":"Monopoly: 3rd Edition","price":19,"product_id":"507f1f77bcf86cd799439011","quantity":1,"sku":"45790-32","url":"https://www.example.com/product/path"},{"category":"Games","name":"Uno Card Game","price":3,"product_id":"505bd76785ebb509fc183733","quantity":2,"sku":"46493-32"}],"shipping":3,"subtotal":22.5,"tax":2,"city":"Disney","country":"USA","email":"mickey@disney.com","firstName":"Mickey","ip":"0.0.0.0","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"aa5f5e44-8756-40ad-ad1e-b0d3b9fa710a","token":"test_api_token","distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","time":1579847342402,"$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', }, XML: {}, FORM: {}, @@ -1366,14 +1396,17 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/track/', - headers: {}, - params: {}, + endpoint: 'https://api.mixpanel.com/import/', + headers: { + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + 'Content-Type': 'application/json', + }, + params: { strict: 0 }, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":" Order Completed ","properties":{"affiliation":"Google Store","checkout_id":"fksdjfsdjfisjf9sdfjsd9f","coupon":"hasbros","currency":"USD","discount":2.5,"total":23,"order_id":"50314b8e9bcf000000000000","key_1":{"child_key1":"child_value1","child_key2":{"child_key21":"child_value21","child_key22":"child_value22"}},"products":[{"category":"Games","image_url":"https:///www.example.com/product/path.jpg","name":"Monopoly: 3rd Edition","price":19,"product_id":"507f1f77bcf86cd799439011","quantity":1,"sku":"45790-32","url":"https://www.example.com/product/path"},{"category":"Games","name":"Uno Card Game","price":3,"product_id":"505bd76785ebb509fc183733","quantity":2,"sku":"46493-32"}],"shipping":3,"subtotal":22.5,"tax":2,"Billing Amount":"77","city":"Disney","country":"USA","email":"mickey@disney.com","firstName":"Mickey","ip":"0.0.0.0","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"aa5f5e44-8756-40ad-ad1e-b0d3b9fa710a","token":"dummyApiKey","distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","time":1579847342402,"$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', + '[{"event":" Order Completed ","properties":{"affiliation":"Google Store","checkout_id":"fksdjfsdjfisjf9sdfjsd9f","coupon":"hasbros","currency":"USD","discount":2.5,"total":23,"order_id":"50314b8e9bcf000000000000","key_1":{"child_key1":"child_value1","child_key2":{"child_key21":"child_value21","child_key22":"child_value22"}},"products":[{"category":"Games","image_url":"https:///www.example.com/product/path.jpg","name":"Monopoly: 3rd Edition","price":19,"product_id":"507f1f77bcf86cd799439011","quantity":1,"sku":"45790-32","url":"https://www.example.com/product/path"},{"category":"Games","name":"Uno Card Game","price":3,"product_id":"505bd76785ebb509fc183733","quantity":2,"sku":"46493-32"}],"shipping":3,"subtotal":22.5,"tax":2,"Billing Amount":"77","city":"Disney","country":"USA","email":"mickey@disney.com","firstName":"Mickey","ip":"0.0.0.0","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"aa5f5e44-8756-40ad-ad1e-b0d3b9fa710a","token":"test_api_token","distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","time":1579847342402,"$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', }, XML: {}, FORM: {}, @@ -1541,7 +1574,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$email":"mickey@disney.com","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$firstName":"Mickey","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', + '[{"$set":{"$email":"mickey@disney.com","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$firstName":"Mickey","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', }, XML: {}, FORM: {}, @@ -1628,7 +1661,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$token":"dummyApiKey","$distinct_id":"hjikl","$set":{"company":["testComp"]},"$ip":"0.0.0.0"}]', + '[{"$token":"test_api_token","$distinct_id":"hjikl","$set":{"company":["testComp"]},"$ip":"0.0.0.0"}]', }, XML: {}, FORM: {}, @@ -1650,7 +1683,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$token":"dummyApiKey","$group_key":"company","$group_id":"testComp","$set":{"company":"testComp"}}]', + '[{"$token":"test_api_token","$group_key":"company","$group_id":"testComp","$set":{"company":"testComp"}}]', }, XML: {}, FORM: {}, @@ -1737,7 +1770,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$token":"dummyApiKey","$distinct_id":"hjikl","$set":{"company":["testComp","testComp1"]},"$ip":"0.0.0.0"}]', + '[{"$token":"test_api_token","$distinct_id":"hjikl","$set":{"company":["testComp","testComp1"]},"$ip":"0.0.0.0"}]', }, XML: {}, FORM: {}, @@ -1759,7 +1792,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$token":"dummyApiKey","$group_key":"company","$group_id":"testComp","$set":{"company":["testComp","testComp1"]}}]', + '[{"$token":"test_api_token","$group_key":"company","$group_id":"testComp","$set":{"company":["testComp","testComp1"]}}]', }, XML: {}, FORM: {}, @@ -1781,7 +1814,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$token":"dummyApiKey","$group_key":"company","$group_id":"testComp1","$set":{"company":["testComp","testComp1"]}}]', + '[{"$token":"test_api_token","$group_key":"company","$group_id":"testComp1","$set":{"company":["testComp","testComp1"]}}]', }, XML: {}, FORM: {}, @@ -1869,7 +1902,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$token":"dummyApiKey","$distinct_id":"hjikl","$set":{"company":["testComp"]},"$ip":"0.0.0.0"}]', + '[{"$token":"test_api_token","$distinct_id":"hjikl","$set":{"company":["testComp"]},"$ip":"0.0.0.0"}]', }, XML: {}, FORM: {}, @@ -1891,7 +1924,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$token":"dummyApiKey","$group_key":"company","$group_id":"testComp","$set":{"company":"testComp"}}]', + '[{"$token":"test_api_token","$group_key":"company","$group_id":"testComp","$set":{"company":"testComp"}}]', }, XML: {}, FORM: {}, @@ -2019,7 +2052,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$append":{"$transactions":{"$time":"2020-01-24T06:29:02.402Z","$amount":25}},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca"}]', + '[{"$append":{"$transactions":{"$time":"2020-01-24T06:29:02.402Z","$amount":25}},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca"}]', }, XML: {}, FORM: {}, @@ -2034,14 +2067,17 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api-eu.mixpanel.com/track/', - headers: {}, - params: {}, + endpoint: 'https://api-eu.mixpanel.com/import/', + headers: { + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + 'Content-Type': 'application/json', + }, + params: { strict: 0 }, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"KM Order Completed","properties":{"affiliation":"Google Store","checkout_id":"fksdjfsdjfisjf9sdfjsd9f","coupon":"hasbros","currency":"USD","discount":2.5,"order_id":"50314b8e9bcf000000000000","products":[{"category":"Games","image_url":"https:///www.example.com/product/path.jpg","name":"Monopoly: 3rd Edition","price":19,"product_id":"507f1f77bcf86cd799439011","quantity":1,"sku":"45790-32","url":"https://www.example.com/product/path"},{"category":"Games","name":"Uno Card Game","price":3,"product_id":"505bd76785ebb509fc183733","quantity":2,"sku":"46493-32"}],"revenue":25,"shipping":3,"subtotal":22.5,"tax":2,"total":27.5,"city":"Disney","country":"USA","email":"mickey@disney.com","firstname":"Mickey","lastname":"Mouse","ip":"0.0.0.0","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"aa5f5e44-8756-40ad-ad1e-b0d3b9fa710a","token":"dummyApiKey","distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","time":1579847342402,"$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', + '[{"event":"KM Order Completed","properties":{"affiliation":"Google Store","checkout_id":"fksdjfsdjfisjf9sdfjsd9f","coupon":"hasbros","currency":"USD","discount":2.5,"order_id":"50314b8e9bcf000000000000","products":[{"category":"Games","image_url":"https:///www.example.com/product/path.jpg","name":"Monopoly: 3rd Edition","price":19,"product_id":"507f1f77bcf86cd799439011","quantity":1,"sku":"45790-32","url":"https://www.example.com/product/path"},{"category":"Games","name":"Uno Card Game","price":3,"product_id":"505bd76785ebb509fc183733","quantity":2,"sku":"46493-32"}],"revenue":25,"shipping":3,"subtotal":22.5,"tax":2,"total":27.5,"city":"Disney","country":"USA","email":"mickey@disney.com","firstname":"Mickey","lastname":"Mouse","ip":"0.0.0.0","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"aa5f5e44-8756-40ad-ad1e-b0d3b9fa710a","token":"test_api_token","distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","time":1579847342402,"$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', }, XML: {}, FORM: {}, @@ -2129,7 +2165,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$carrier":"Android","$manufacturer":"Google","$model":"Android SDK built for x86","$screen_height":1794,"$screen_width":1080,"$wifi":true,"anonymousId":"5094f5704b9cf2b3","$android_devices":["test_device_token"],"$os":"Android","$android_model":"Android SDK built for x86","$android_os_version":"8.1.0","$android_manufacturer":"Google","$android_app_version":"1.0","$android_app_version_code":"1.0","$android_brand":"Google"},"$token":"dummyApiKey","$distinct_id":"5094f5704b9cf2b3","$time":1584003903421}]', + '[{"$set":{"$carrier":"Android","$manufacturer":"Google","$model":"Android SDK built for x86","$screen_height":1794,"$screen_width":1080,"$wifi":true,"anonymousId":"5094f5704b9cf2b3","$android_devices":["test_device_token"],"$os":"Android","$android_model":"Android SDK built for x86","$android_os_version":"8.1.0","$android_manufacturer":"Google","$android_app_version":"1.0","$android_app_version_code":"1.0","$android_brand":"Google"},"$token":"test_api_token","$distinct_id":"5094f5704b9cf2b3","$time":1584003903421}]', }, XML: {}, FORM: {}, @@ -2216,7 +2252,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$carrier":"Android","$manufacturer":"Google","$model":"Android SDK built for x86","$screen_height":1794,"$screen_width":1080,"$wifi":true,"anonymousId":"5094f5704b9cf2b3","userId":"test_user_id","$ios_devices":["test_device_token"],"$os":"iOS","$ios_device_model":"Android SDK built for x86","$ios_version":"8.1.0","$ios_app_release":"1","$ios_app_version":"1.0"},"$token":"dummyApiKey","$distinct_id":"test_user_id","$time":1584003903421}]', + '[{"$set":{"$carrier":"Android","$manufacturer":"Google","$model":"Android SDK built for x86","$screen_height":1794,"$screen_width":1080,"$wifi":true,"anonymousId":"5094f5704b9cf2b3","userId":"test_user_id","$ios_devices":["test_device_token"],"$os":"iOS","$ios_device_model":"Android SDK built for x86","$ios_version":"8.1.0","$ios_app_release":"1","$ios_app_version":"1.0"},"$token":"test_api_token","$distinct_id":"test_user_id","$time":1584003903421}]', }, XML: {}, FORM: {}, @@ -2233,7 +2269,7 @@ export const data = [ method: 'POST', endpoint: 'https://api-eu.mixpanel.com/import/', headers: { - Authorization: 'Basic c29tZV9hcGlfc2VjcmV0Og==', + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', 'Content-Type': 'application/json', }, params: { strict: 0 }, @@ -2241,7 +2277,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"event":"$merge","properties":{"$distinct_ids":["test_user_id","5094f5704b9cf2b3"],"token":"dummyApiKey"}}]', + '[{"event":"$merge","properties":{"$distinct_ids":["test_user_id","5094f5704b9cf2b3"],"token":"test_api_token"}}]', }, XML: {}, FORM: {}, @@ -2328,14 +2364,17 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/track/', - headers: {}, - params: {}, + endpoint: 'https://api.mixpanel.com/import/', + headers: { + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + 'Content-Type': 'application/json', + }, + params: { strict: 0 }, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"Loaded a Page","properties":{"path":"/tests/html/index2.html","referrer":"","search":"","title":"","url":"http://localhost/tests/html/index2.html","category":"communication","ip":"0.0.0.0","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"dd266c67-9199-4a52-ba32-f46ddde67312","token":"dummyApiKey","distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","time":1579847342402,"name":"Contact Us","$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', + '[{"event":"Loaded a Page","properties":{"path":"/tests/html/index2.html","referrer":"","search":"","title":"","url":"http://localhost/tests/html/index2.html","category":"communication","ip":"0.0.0.0","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"dd266c67-9199-4a52-ba32-f46ddde67312","token":"test_api_token","distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","time":1579847342402,"name":"Contact Us","$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', }, XML: {}, FORM: {}, @@ -2423,14 +2462,17 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/track/', - headers: {}, - params: {}, + endpoint: 'https://api.mixpanel.com/import/', + headers: { + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + 'Content-Type': 'application/json', + }, + params: { strict: 0 }, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"$create_alias","properties":{"distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","alias":"1234abc","token":"dummyApiKey"}}]', + '[{"event":"$create_alias","properties":{"distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","alias":"1234abc","token":"test_api_token"}}]', }, XML: {}, FORM: {}, @@ -2523,7 +2565,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$carrier":"Android","$manufacturer":"Google","$model":"Android SDK built for x86","$screen_height":1794,"$screen_width":1080,"$wifi":true,"anonymousId":"5094f5704b9cf2b3","userId":"test_user_id","createdat":"2020-01-23T08:54:02.362Z","$ios_devices":["test_device_token"],"$ios_device_model":"Android SDK built for x86","$ios_app_release":"1","$ios_app_version":"1.0"},"$token":"dummyApiKey","$distinct_id":"test_user_id","$time":1584003903421}]', + '[{"$set":{"$carrier":"Android","$manufacturer":"Google","$model":"Android SDK built for x86","$screen_height":1794,"$screen_width":1080,"$wifi":true,"anonymousId":"5094f5704b9cf2b3","userId":"test_user_id","createdat":"2020-01-23T08:54:02.362Z","$ios_devices":["test_device_token"],"$ios_device_model":"Android SDK built for x86","$ios_app_release":"1","$ios_app_version":"1.0"},"$token":"test_api_token","$distinct_id":"test_user_id","$time":1584003903421}]', }, XML: {}, FORM: {}, @@ -2540,7 +2582,7 @@ export const data = [ method: 'POST', endpoint: 'https://api-eu.mixpanel.com/import/', headers: { - Authorization: 'Basic c29tZV9hcGlfc2VjcmV0Og==', + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', 'Content-Type': 'application/json', }, params: { strict: 0 }, @@ -2548,7 +2590,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"event":"$merge","properties":{"$distinct_ids":["test_user_id","5094f5704b9cf2b3"],"token":"dummyApiKey"}}]', + '[{"event":"$merge","properties":{"$distinct_ids":["test_user_id","5094f5704b9cf2b3"],"token":"test_api_token"}}]', }, XML: {}, FORM: {}, @@ -2641,7 +2683,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$email":"mickey@disney.com","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$firstName":"Mickey","$lastName":"Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', + '[{"$set":{"$email":"mickey@disney.com","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$firstName":"Mickey","$lastName":"Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', }, XML: {}, FORM: {}, @@ -2733,7 +2775,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$email":"mickey@disney.com","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$firstName":"Mickey","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', + '[{"$set":{"$email":"mickey@disney.com","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$firstName":"Mickey","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', }, XML: {}, FORM: {}, @@ -2826,7 +2868,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$email":"mickey@disney.com","$name":"Mickey Mouse","$country_code":"USA","$city":"Disney","$region":"US","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$firstName":"Mickey","$lastName":"Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', + '[{"$set":{"$email":"mickey@disney.com","$name":"Mickey Mouse","$country_code":"USA","$city":"Disney","$region":"US","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$firstName":"Mickey","$lastName":"Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', }, XML: {}, FORM: {}, @@ -2924,7 +2966,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$email":"mickey@disney.com","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$firstName":"Mickey","$lastName":"Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', + '[{"$set":{"$email":"mickey@disney.com","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$firstName":"Mickey","$lastName":"Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', }, XML: {}, FORM: {}, @@ -3020,7 +3062,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$email":"mickey@disney.com","$name":"Mouse","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$firstName":"Mickey","$lastName":"Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', + '[{"$set":{"$email":"mickey@disney.com","$name":"Mouse","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$firstName":"Mickey","$lastName":"Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', }, XML: {}, FORM: {}, @@ -3115,7 +3157,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$email":"mickey@disney.com","$first_name":"Mickey","$last_name":"Mouse","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', + '[{"$set":{"$email":"mickey@disney.com","$first_name":"Mickey","$last_name":"Mouse","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', }, XML: {}, FORM: {}, @@ -3209,7 +3251,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$email":"mickey@disney.com","$first_name":"Mickey","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', + '[{"$set":{"$email":"mickey@disney.com","$first_name":"Mickey","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', }, XML: {}, FORM: {}, @@ -3304,7 +3346,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$email":"mickey@disney.com","$first_name":"Mickey","$last_name":"Mouse","$name":"Mickey Mouse","$country_code":"USA","$city":"Disney","$region":"US","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', + '[{"$set":{"$email":"mickey@disney.com","$first_name":"Mickey","$last_name":"Mouse","$name":"Mickey Mouse","$country_code":"USA","$city":"Disney","$region":"US","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', }, XML: {}, FORM: {}, @@ -3405,7 +3447,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$email":"mickey@disney.com","$first_name":"Mickey","$last_name":"Mouse","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', + '[{"$set":{"$email":"mickey@disney.com","$first_name":"Mickey","$last_name":"Mouse","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', }, XML: {}, FORM: {}, @@ -3502,17 +3544,29 @@ export const data = [ status: 200, body: [ { - error: - 'Event timestamp is older than 5 days and no API secret or service account credentials (i.e. username, secret and projectId) are provided in destination configuration', - statTags: { - destType: 'MP', - errorCategory: 'dataValidation', - errorType: 'instrumentation', - feature: 'processor', - implementation: 'native', - module: 'destination', + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.mixpanel.com/import/', + headers: { + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + 'Content-Type': 'application/json', + }, + params: { strict: 0 }, + body: { + JSON: {}, + JSON_ARRAY: { + batch: + '[{"event":"FirstTrackCall12","properties":{"foo":"bar","$deviceId":"nkasdnkasd","anonymousId":"ea776ad0-3136-44fb-9216-5b1578609a2b","userId":"as09sufa09usaf09as0f9uasf","id":"as09sufa09usaf09as0f9uasf","firstName":"Bob","lastName":"Marley","name":"Bob Marley","age":43,"email":"bob@marleymail.com","phone":"+447748544123","birthday":"1987-01-01T20:08:59+0000","createdAt":"2022-01-21T14:10:12+0000","address":"51,B.L.T road, Kolkata-700060","description":"I am great","gender":"male","title":"Founder","username":"bobm","website":"https://bobm.com","randomProperty":"randomValue","$user_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$current_url":"http://127.0.0.1:7307/Testing/App_for_testingTool/","$referrer":"http://127.0.0.1:7307/Testing/","$screen_height":900,"$screen_width":1440,"$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.1.18","$insert_id":"0d5c1a4a-27e4-41da-a246-4d01f44e74bd","token":"test_api_token","distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","time":1632986123523,"$browser":"Chrome","$browser_version":"93.0.4577.82"}}]', + }, + XML: {}, + FORM: {}, + }, + files: {}, + userId: 'e6ab2c5e-2cda-44a9-a962-e2f67df78bca', }, - statusCode: 400, + statusCode: 200, }, ], }, @@ -3686,7 +3740,7 @@ export const data = [ method: 'POST', endpoint: 'https://api-eu.mixpanel.com/import/', headers: { - Authorization: 'Basic c29tZV9hcGlfc2VjcmV0Og==', + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', 'Content-Type': 'application/json', }, params: { strict: 0 }, @@ -3694,7 +3748,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"event":"MainActivity","properties":{"name":"MainActivity","automatic":true,"anonymousId":"5094f5704b9cf2b3","userId":"test_user_id","$user_id":"test_user_id","$os":"iOS","$screen_height":1794,"$screen_width":1080,"$screen_dpi":420,"$carrier":"Android","$os_version":"8.1.0","$device":"generic_x86","$manufacturer":"Google","$model":"Android SDK built for x86","mp_device_model":"Android SDK built for x86","$wifi":true,"$bluetooth_enabled":false,"mp_lib":"com.rudderstack.android.sdk.core","$app_build_number":"1","$app_version_string":"1.0","$insert_id":"id2","token":"dummyApiKey","distinct_id":"test_user_id","time":1520845503421}}]', + '[{"event":"MainActivity","properties":{"name":"MainActivity","automatic":true,"anonymousId":"5094f5704b9cf2b3","userId":"test_user_id","$user_id":"test_user_id","$os":"iOS","$screen_height":1794,"$screen_width":1080,"$screen_dpi":420,"$carrier":"Android","$os_version":"8.1.0","$device":"generic_x86","$manufacturer":"Google","$model":"Android SDK built for x86","mp_device_model":"Android SDK built for x86","$wifi":true,"$bluetooth_enabled":false,"mp_lib":"com.rudderstack.android.sdk.core","$app_build_number":"1","$app_version_string":"1.0","$insert_id":"id2","token":"test_api_token","distinct_id":"test_user_id","time":1520845503421}}]', }, XML: {}, FORM: {}, @@ -3965,7 +4019,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$created":"2020-01-23T08:54:02.362Z","$email":"mickey@disney.com","$first_name":"Mickey","$last_name":"Mouse","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402,"$ignore_time":true}]', + '[{"$set":{"$created":"2020-01-23T08:54:02.362Z","$email":"mickey@disney.com","$first_name":"Mickey","$last_name":"Mouse","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402,"$ignore_time":true}]', }, XML: {}, FORM: {}, @@ -4071,7 +4125,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$created":"2020-01-23T08:54:02.362Z","$email":"mickey@disney.com","$first_name":"Mickey","$last_name":"Mouse","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', + '[{"$set":{"$created":"2020-01-23T08:54:02.362Z","$email":"mickey@disney.com","$first_name":"Mickey","$last_name":"Mouse","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', }, XML: {}, FORM: {}, @@ -4276,7 +4330,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$created":"2020-01-23T08:54:02.362Z","$email":"mickey@disney.com","$first_name":"Mickey","$last_name":"Mouse","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyApiKey","$distinct_id":"user1234","$ip":"0.0.0.0","$time":1579847342402}]', + '[{"$set":{"$created":"2020-01-23T08:54:02.362Z","$email":"mickey@disney.com","$first_name":"Mickey","$last_name":"Mouse","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"user1234","$ip":"0.0.0.0","$time":1579847342402}]', }, XML: {}, FORM: {}, @@ -4294,18 +4348,14 @@ export const data = [ endpoint: 'https://api.mixpanel.com/import/', headers: { 'Content-Type': 'application/json', - Authorization: - 'Basic cnVkZGVyLmQyYTNmMS5tcC1zZXJ2aWNlLWFjY291bnQ6amF0cFF4Y2pNaDhlZXRrMXhySDNLalFJYnp5NGlYOGI=', - }, - params: { - project_id: '123456', - strict: 0, + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', }, + params: { strict: 0 }, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"$merge","properties":{"$distinct_ids":["user1234","e6ab2c5e-2cda-44a9-a962-e2f67df78bca"],"token":"dummyApiKey"}}]', + '[{"event":"$merge","properties":{"$distinct_ids":["user1234","e6ab2c5e-2cda-44a9-a962-e2f67df78bca"],"token":"test_api_token"}}]', }, XML: {}, FORM: {}, @@ -4390,7 +4440,7 @@ export const data = [ method: 'POST', endpoint: 'https://api.mixpanel.com/import/', headers: { - Authorization: 'Basic ZHVtbXlBcGlLZXk6', + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', 'Content-Type': 'application/json', }, params: { strict: 0 }, @@ -4398,7 +4448,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"event":"Application Installed","properties":{"build":4,"version":"1.0","anonymousId":"39da706ec83d0e90","$os":"Android","$screen_height":2984,"$screen_width":1440,"$screen_dpi":560,"$carrier":"T-Mobile","$os_version":"12","$device":"emu64a","$manufacturer":"Google","$model":"sdk_gphone64_arm64","mp_device_model":"sdk_gphone64_arm64","$wifi":true,"$bluetooth_enabled":true,"mp_lib":"com.rudderstack.android.sdk.core","$app_build_number":"4","$app_version_string":"1.0","$insert_id":"168cf720-6227-4b56-a98e-c49bdc7279e9","$session_id":"1662363980","token":"dummyApiKey","distinct_id":"39da706ec83d0e90","time":1662363980290}}]', + '[{"event":"Application Installed","properties":{"build":4,"version":"1.0","anonymousId":"39da706ec83d0e90","$os":"Android","$screen_height":2984,"$screen_width":1440,"$screen_dpi":560,"$carrier":"T-Mobile","$os_version":"12","$device":"emu64a","$manufacturer":"Google","$model":"sdk_gphone64_arm64","mp_device_model":"sdk_gphone64_arm64","$wifi":true,"$bluetooth_enabled":true,"mp_lib":"com.rudderstack.android.sdk.core","$app_build_number":"4","$app_version_string":"1.0","$insert_id":"168cf720-6227-4b56-a98e-c49bdc7279e9","$session_id":"1662363980","token":"test_api_token","distinct_id":"39da706ec83d0e90","time":1662363980290}}]', }, XML: {}, FORM: {}, @@ -4480,7 +4530,7 @@ export const data = [ method: 'POST', endpoint: 'https://api.mixpanel.com/import/', headers: { - Authorization: 'Basic ZHVtbXlBcGlLZXk6', + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', 'Content-Type': 'application/json', }, params: { strict: 0 }, @@ -4488,7 +4538,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"event":"Application Opened","properties":{"build":4,"version":"1.0","anonymousId":"39da706ec83d0e90","$os":"Android","$screen_height":2984,"$screen_width":1440,"$screen_dpi":560,"$carrier":"T-Mobile","$os_version":"12","$device":"emu64a","$manufacturer":"Google","$model":"sdk_gphone64_arm64","mp_device_model":"sdk_gphone64_arm64","$wifi":true,"$bluetooth_enabled":true,"mp_lib":"com.rudderstack.android.sdk.core","$app_build_number":"4","$app_version_string":"1.0","$insert_id":"168cf720-6227-4b56-a98e-c49bdc7279e9","$session_id":"1662363980","token":"dummyApiKey","distinct_id":"39da706ec83d0e90","time":1662363980290}}]', + '[{"event":"Application Opened","properties":{"build":4,"version":"1.0","anonymousId":"39da706ec83d0e90","$os":"Android","$screen_height":2984,"$screen_width":1440,"$screen_dpi":560,"$carrier":"T-Mobile","$os_version":"12","$device":"emu64a","$manufacturer":"Google","$model":"sdk_gphone64_arm64","mp_device_model":"sdk_gphone64_arm64","$wifi":true,"$bluetooth_enabled":true,"mp_lib":"com.rudderstack.android.sdk.core","$app_build_number":"4","$app_version_string":"1.0","$insert_id":"168cf720-6227-4b56-a98e-c49bdc7279e9","$session_id":"1662363980","token":"test_api_token","distinct_id":"39da706ec83d0e90","time":1662363980290}}]', }, XML: {}, FORM: {}, @@ -4576,7 +4626,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$token":"dummyApiKey","$distinct_id":"hjikl","$set":{"groupId":["testGroupId"]},"$ip":"0.0.0.0"}]', + '[{"$token":"test_api_token","$distinct_id":"hjikl","$set":{"groupId":["testGroupId"]},"$ip":"0.0.0.0"}]', }, XML: {}, FORM: {}, @@ -4598,7 +4648,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$token":"dummyApiKey","$group_key":"groupId","$group_id":"testGroupId","$set":{"company":"testComp","groupId":"groupIdInTraits"}}]', + '[{"$token":"test_api_token","$group_key":"groupId","$group_id":"testGroupId","$set":{"company":"testComp","groupId":"groupIdInTraits"}}]', }, XML: {}, FORM: {}, @@ -4625,7 +4675,7 @@ export const data = [ description: 'Track: set device id and user id when simplified id merge api is selected', destination: overrideDestination(sampleDestination, { - token: 'dummyApiKey', + token: 'test_api_token', identityMergeApi: 'simplified', }), message: { @@ -4681,14 +4731,17 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/track/', - headers: {}, - params: {}, + endpoint: 'https://api.mixpanel.com/import/', + headers: { + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + 'Content-Type': 'application/json', + }, + params: { strict: 0 }, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"Product Viewed","properties":{"name":"T-Shirt","$user_id":"userId01","$os":"iOS","$screen_height":1794,"$screen_width":1080,"$screen_dpi":420,"$carrier":"Android","$os_version":"8.1.0","$device":"generic_x86","$manufacturer":"Google","$model":"Android SDK built for x86","mp_device_model":"Android SDK built for x86","$wifi":true,"$bluetooth_enabled":false,"mp_lib":"com.rudderstack.android.sdk.core","$app_build_number":"1","$app_version_string":"1.0","$insert_id":"id2","token":"dummyApiKey","distinct_id":"userId01","time":1579847342402,"$device_id":"anonId01"}}]', + '[{"event":"Product Viewed","properties":{"name":"T-Shirt","$user_id":"userId01","$os":"iOS","$screen_height":1794,"$screen_width":1080,"$screen_dpi":420,"$carrier":"Android","$os_version":"8.1.0","$device":"generic_x86","$manufacturer":"Google","$model":"Android SDK built for x86","mp_device_model":"Android SDK built for x86","$wifi":true,"$bluetooth_enabled":false,"mp_lib":"com.rudderstack.android.sdk.core","$app_build_number":"1","$app_version_string":"1.0","$insert_id":"id2","token":"test_api_token","distinct_id":"userId01","time":1579847342402,"$device_id":"anonId01"}}]', }, XML: {}, FORM: {}, @@ -4717,7 +4770,7 @@ export const data = [ { description: 'Identify: skip merge event when simplified id merge api is selected', destination: overrideDestination(sampleDestination, { - token: 'dummyApiKey', + token: 'test_api_token', identityMergeApi: 'simplified', }), message: { @@ -4798,7 +4851,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$created":"2020-01-23T08:54:02.362Z","$email":"mickey@disney.com","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$firstName":"Mickey","$lastName":"Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyApiKey","$distinct_id":"userId01","$ip":"0.0.0.0","$time":1579847342402}]', + '[{"$set":{"$created":"2020-01-23T08:54:02.362Z","$email":"mickey@disney.com","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$firstName":"Mickey","$lastName":"Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"userId01","$ip":"0.0.0.0","$time":1579847342402}]', }, XML: {}, FORM: {}, @@ -4826,7 +4879,7 @@ export const data = [ 'Identify: append $device: to deviceId while creating the user when simplified id merge api is selected', destination: overrideDestination(sampleDestination, { apiKey: 'apiKey123', - token: 'dummyApiKey', + token: 'test_api_token', identityMergeApi: 'simplified', }), message: { @@ -4906,7 +4959,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$created":"2020-01-23T08:54:02.362Z","$email":"mickey@disney.com","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$firstName":"Mickey","$lastName":"Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyApiKey","$distinct_id":"$device:anonId01","$ip":"0.0.0.0","$time":1579847342402}]', + '[{"$set":{"$created":"2020-01-23T08:54:02.362Z","$email":"mickey@disney.com","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$firstName":"Mickey","$lastName":"Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"$device:anonId01","$ip":"0.0.0.0","$time":1579847342402}]', }, XML: {}, FORM: {}, @@ -4933,7 +4986,7 @@ export const data = [ description: 'Unsupported alias call when simplified id merge api is selected', destination: overrideDestination(sampleDestination, { apiKey: 'apiKey123', - token: 'dummyApiKey', + token: 'test_api_token', identityMergeApi: 'simplified', }), message: { @@ -5022,7 +5075,7 @@ export const data = [ 'Track revenue event: set device id and user id when simplified id merge api is selected', destination: overrideDestination(sampleDestination, { apiKey: 'apiKey123', - token: 'dummyApiKey', + token: 'test_api_token', identityMergeApi: 'simplified', }), message: { @@ -5093,7 +5146,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$append":{"$transactions":{"$time":"2020-01-24T06:29:02.403Z","$amount":18.9}},"$token":"dummyApiKey","$distinct_id":"userId01"}]', + '[{"$append":{"$transactions":{"$time":"2020-01-24T06:29:02.403Z","$amount":18.9}},"$token":"test_api_token","$distinct_id":"userId01"}]', }, XML: {}, FORM: {}, @@ -5108,14 +5161,17 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/track/', - headers: {}, - params: {}, + endpoint: 'https://api.mixpanel.com/import/', + headers: { + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + 'Content-Type': 'application/json', + }, + params: { strict: 0 }, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"test revenue MIXPANEL","properties":{"currency":"USD","revenue":18.9,"city":"Disney","country":"USA","email":"mickey@disney.com","firstName":"Mickey","ip":"0.0.0.0","$user_id":"userId01","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"a6a0ad5a-bd26-4f19-8f75-38484e580fc7","token":"dummyApiKey","distinct_id":"userId01","time":1579847342403,"$device_id":"anonId01","$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', + '[{"event":"test revenue MIXPANEL","properties":{"currency":"USD","revenue":18.9,"city":"Disney","country":"USA","email":"mickey@disney.com","firstName":"Mickey","ip":"0.0.0.0","$user_id":"userId01","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"a6a0ad5a-bd26-4f19-8f75-38484e580fc7","token":"test_api_token","distinct_id":"userId01","time":1579847342403,"$device_id":"anonId01","$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', }, XML: {}, FORM: {}, @@ -5145,7 +5201,7 @@ export const data = [ description: 'Page with anonymous user when simplified api is selected', destination: overrideDestination(sampleDestination, { apiKey: 'apiKey123', - token: 'dummyApiKey', + token: 'test_api_token', identityMergeApi: 'simplified', }), message: { @@ -5212,14 +5268,17 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/track/', - headers: {}, - params: {}, + endpoint: 'https://api.mixpanel.com/import/', + headers: { + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + 'Content-Type': 'application/json', + }, + params: { strict: 0 }, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"Loaded a Page","properties":{"ip":"0.0.0.0","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"dd266c67-9199-4a52-ba32-f46ddde67312","token":"dummyApiKey","distinct_id":"$device:anonId01","time":1579847342402,"$device_id":"anonId01","name":"Contact Us","$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', + '[{"event":"Loaded a Page","properties":{"ip":"0.0.0.0","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"dd266c67-9199-4a52-ba32-f46ddde67312","token":"test_api_token","distinct_id":"$device:anonId01","time":1579847342402,"$device_id":"anonId01","name":"Contact Us","$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', }, XML: {}, FORM: {}, @@ -5249,7 +5308,7 @@ export const data = [ description: 'Group call with anonymous user when simplified api is selected', destination: overrideDestination(sampleDestination, { apiKey: 'apiKey123', - token: 'dummyApiKey', + token: 'test_api_token', identityMergeApi: 'simplified', groupKeySettings: [{ groupKey: 'company' }], }), @@ -5312,7 +5371,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$token":"dummyApiKey","$distinct_id":"$device:anonId01","$set":{"company":["testComp"]},"$ip":"0.0.0.0"}]', + '[{"$token":"test_api_token","$distinct_id":"$device:anonId01","$set":{"company":["testComp"]},"$ip":"0.0.0.0"}]', }, XML: {}, FORM: {}, @@ -5334,7 +5393,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$token":"dummyApiKey","$group_key":"company","$group_id":"testComp","$set":{"company":"testComp"}}]', + '[{"$token":"test_api_token","$group_key":"company","$group_id":"testComp","$set":{"company":"testComp"}}]', }, XML: {}, FORM: {}, @@ -5360,7 +5419,7 @@ export const data = [ { destination: overrideDestination(sampleDestination, { apiKey: 'apiKey123', - token: 'dummyApiKey', + token: 'test_api_token', identityMergeApi: 'simplified', groupKeySettings: [{ groupKey: 'company' }], }), @@ -5479,7 +5538,7 @@ export const data = [ }, destination: overrideDestination(sampleDestination, { apiKey: 'dummyApiKey', - token: 'dummyApiKey', + token: 'test_api_token', apiSecret: 'dummyApiKey', useNewMapping: true, }), @@ -5505,7 +5564,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$append":{"$transactions":{"$time":"2022-09-05T07:46:20.290Z","$amount":12.13}},"$token":"dummyApiKey","$distinct_id":"39da706ec83d0e90"}]', + '[{"$append":{"$transactions":{"$time":"2022-09-05T07:46:20.290Z","$amount":12.13}},"$token":"test_api_token","$distinct_id":"39da706ec83d0e90"}]', }, XML: {}, FORM: {}, @@ -5522,7 +5581,7 @@ export const data = [ method: 'POST', endpoint: 'https://api.mixpanel.com/import/', headers: { - Authorization: 'Basic ZHVtbXlBcGlLZXk6', + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', 'Content-Type': 'application/json', }, params: { strict: 0 }, @@ -5530,7 +5589,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"event":"Application Installed","properties":{"build":4,"version":"1.0","revenue":12.13,"anonymousId":"39da706ec83d0e90","$os":"Android","$screen_height":2984,"$screen_width":1440,"$screen_dpi":560,"$carrier":"T-Mobile","$os_version":"12","$device":"emu64a","$manufacturer":"Google","$model":"sdk_gphone64_arm64","mp_device_model":"sdk_gphone64_arm64","$wifi":true,"$bluetooth_enabled":true,"mp_lib":"com.rudderstack.android.sdk.core","$app_build_number":"4","$app_version_string":"1.0","$insert_id":"168cf720-6227-4b56-a98e-c49bdc7279e9","$session_id":"1662363980","token":"dummyApiKey","distinct_id":"39da706ec83d0e90","time":1662363980290}}]', + '[{"event":"Application Installed","properties":{"build":4,"version":"1.0","revenue":12.13,"anonymousId":"39da706ec83d0e90","$os":"Android","$screen_height":2984,"$screen_width":1440,"$screen_dpi":560,"$carrier":"T-Mobile","$os_version":"12","$device":"emu64a","$manufacturer":"Google","$model":"sdk_gphone64_arm64","mp_device_model":"sdk_gphone64_arm64","$wifi":true,"$bluetooth_enabled":true,"mp_lib":"com.rudderstack.android.sdk.core","$app_build_number":"4","$app_version_string":"1.0","$insert_id":"168cf720-6227-4b56-a98e-c49bdc7279e9","$session_id":"1662363980","token":"test_api_token","distinct_id":"39da706ec83d0e90","time":1662363980290}}]', }, XML: {}, FORM: {}, @@ -5594,7 +5653,7 @@ export const data = [ }, destination: overrideDestination(sampleDestination, { apiKey: 'dummyApiKey', - token: 'dummyApiKey', + token: 'test_api_token', apiSecret: 'dummyApiKey', useNewMapping: true, }), @@ -5620,7 +5679,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$append":{"$transactions":{"$time":"2022-09-05T07:46:20.290Z","$amount":23.45}},"$token":"dummyApiKey","$distinct_id":"39da706ec83d0e90"}]', + '[{"$append":{"$transactions":{"$time":"2022-09-05T07:46:20.290Z","$amount":23.45}},"$token":"test_api_token","$distinct_id":"39da706ec83d0e90"}]', }, XML: {}, FORM: {}, @@ -5637,7 +5696,7 @@ export const data = [ method: 'POST', endpoint: 'https://api.mixpanel.com/import/', headers: { - Authorization: 'Basic ZHVtbXlBcGlLZXk6', + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', 'Content-Type': 'application/json', }, params: { strict: 0 }, @@ -5645,7 +5704,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"event":"Application Installed","properties":{"build":4,"version":"1.0","revenue":23.45,"anonymousId":"39da706ec83d0e90","$os":"Android","$screen_height":2984,"$screen_width":1440,"$screen_dpi":560,"$carrier":"T-Mobile","$os_version":"12","$device":"emu64a","$manufacturer":"Google","$model":"sdk_gphone64_arm64","mp_device_model":"sdk_gphone64_arm64","$wifi":true,"$bluetooth_enabled":true,"mp_lib":"com.rudderstack.android.sdk.core","$app_build_number":"4","$app_version_string":"1.0","$insert_id":"168cf720-6227-4b56-a98e-c49bdc7279e9","$session_id":"1662363980","token":"dummyApiKey","distinct_id":"39da706ec83d0e90","time":null}}]', + '[{"event":"Application Installed","properties":{"build":4,"version":"1.0","revenue":23.45,"anonymousId":"39da706ec83d0e90","$os":"Android","$screen_height":2984,"$screen_width":1440,"$screen_dpi":560,"$carrier":"T-Mobile","$os_version":"12","$device":"emu64a","$manufacturer":"Google","$model":"sdk_gphone64_arm64","mp_device_model":"sdk_gphone64_arm64","$wifi":true,"$bluetooth_enabled":true,"mp_lib":"com.rudderstack.android.sdk.core","$app_build_number":"4","$app_version_string":"1.0","$insert_id":"168cf720-6227-4b56-a98e-c49bdc7279e9","$session_id":"1662363980","token":"test_api_token","distinct_id":"39da706ec83d0e90","time":null}}]', }, XML: {}, FORM: {}, @@ -5672,7 +5731,7 @@ export const data = [ description: 'Track: with strict mode enabled', destination: overrideDestination(sampleDestination, { apiKey: 'dummyApiKey', - token: 'dummyApiKey', + token: 'test_api_token', apiSecret: 'some_api_secret', dataResidency: 'eu', strictMode: true, @@ -5736,7 +5795,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$carrier":"Android","$manufacturer":"Google","$model":"Android SDK built for x86","$screen_height":1794,"$screen_width":1080,"$wifi":true,"anonymousId":"5094f5704b9cf2b3","userId":"test_user_id","$ios_devices":["test_device_token"],"$os":"iOS","$ios_device_model":"Android SDK built for x86","$ios_version":"8.1.0","$ios_app_release":"1","$ios_app_version":"1.0"},"$token":"dummyApiKey","$distinct_id":"test_user_id","$time":1584003903421}]', + '[{"$set":{"$carrier":"Android","$manufacturer":"Google","$model":"Android SDK built for x86","$screen_height":1794,"$screen_width":1080,"$wifi":true,"anonymousId":"5094f5704b9cf2b3","userId":"test_user_id","$ios_devices":["test_device_token"],"$os":"iOS","$ios_device_model":"Android SDK built for x86","$ios_version":"8.1.0","$ios_app_release":"1","$ios_app_version":"1.0"},"$token":"test_api_token","$distinct_id":"test_user_id","$time":1584003903421}]', }, XML: {}, FORM: {}, @@ -5753,7 +5812,7 @@ export const data = [ method: 'POST', endpoint: 'https://api-eu.mixpanel.com/import/', headers: { - Authorization: 'Basic c29tZV9hcGlfc2VjcmV0Og==', + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', 'Content-Type': 'application/json', }, params: { strict: 1 }, @@ -5761,7 +5820,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"event":"$merge","properties":{"$distinct_ids":["test_user_id","5094f5704b9cf2b3"],"token":"dummyApiKey"}}]', + '[{"event":"$merge","properties":{"$distinct_ids":["test_user_id","5094f5704b9cf2b3"],"token":"test_api_token"}}]', }, XML: {}, FORM: {}, diff --git a/test/integrations/destinations/mp/router/data.ts b/test/integrations/destinations/mp/router/data.ts index 059e222e92..8716c9daa0 100644 --- a/test/integrations/destinations/mp/router/data.ts +++ b/test/integrations/destinations/mp/router/data.ts @@ -442,7 +442,7 @@ export const data = [ endpoint: 'https://api.mixpanel.com/import/', headers: { 'Content-Type': 'application/json', - Authorization: 'Basic dGVzdF9hcGlfc2VjcmV0Og==', + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', }, params: { strict: 1 }, body: { @@ -509,7 +509,7 @@ export const data = [ endpoint: 'https://api.mixpanel.com/import/', headers: { 'Content-Type': 'application/json', - Authorization: 'Basic dGVzdF9hcGlfc2VjcmV0Og==', + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', }, params: { strict: 1 }, body: { @@ -577,7 +577,7 @@ export const data = [ endpoint: 'https://api.mixpanel.com/import/', headers: { 'Content-Type': 'application/json', - Authorization: 'Basic dGVzdF9hcGlfc2VjcmV0Og==', + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', }, params: { strict: 1 }, body: { @@ -1166,7 +1166,7 @@ export const data = [ endpoint: 'https://api.mixpanel.com/import/', headers: { 'Content-Type': 'application/json', - Authorization: 'Basic dGVzdF9hcGlfc2VjcmV0Og==', + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', }, params: { strict: 1 }, body: { @@ -1232,7 +1232,7 @@ export const data = [ endpoint: 'https://api.mixpanel.com/import/', headers: { 'Content-Type': 'application/json', - Authorization: 'Basic dGVzdF9hcGlfc2VjcmV0Og==', + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', }, params: { strict: 1 }, body: { @@ -1299,7 +1299,7 @@ export const data = [ endpoint: 'https://api.mixpanel.com/import/', headers: { 'Content-Type': 'application/json', - Authorization: 'Basic dGVzdF9hcGlfc2VjcmV0Og==', + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', }, params: { strict: 1 }, body: { From c249a694d735f6d241a35b6e21f493c54890ac84 Mon Sep 17 00:00:00 2001 From: Anant Jain <62471433+anantjain45823@users.noreply.github.com> Date: Wed, 22 May 2024 18:52:08 +0530 Subject: [PATCH 10/11] fix: standardise hashing for all CAPI integrations (#3379) * fix: standardize hashing for all CAPI integrations * fix: use trim before hashing for GAOC,GAEC,impact,YDSP,fb and fbconv --- .../v2/destinations/reddit/procWorkflow.yaml | 10 +++++----- .../facebook_offline_conversions/utils.js | 6 +++--- src/v0/destinations/fb/transform.js | 6 +++--- .../data/trackConfig.json | 10 +++++----- .../transform.js | 2 +- .../utils.js | 18 +++++++++++------- src/v0/destinations/impact/transform.js | 4 ++-- src/v0/destinations/pinterest_tag/utils.js | 6 +++--- src/v0/destinations/yahoo_dsp/util.js | 2 +- .../processor/data.ts | 2 +- .../destinations/fb/processor/data.ts | 2 +- .../processor/data.ts | 2 +- .../processor/data.ts | 2 +- .../destinations/impact/processor/data.ts | 2 +- .../pinterest_tag/processor/data.ts | 4 ++-- .../destinations/reddit/processor/data.ts | 8 ++++---- .../destinations/yahoo_dsp/processor/data.ts | 2 +- 17 files changed, 46 insertions(+), 42 deletions(-) diff --git a/src/cdk/v2/destinations/reddit/procWorkflow.yaml b/src/cdk/v2/destinations/reddit/procWorkflow.yaml index 7b989f15e4..06d2c95f25 100644 --- a/src/cdk/v2/destinations/reddit/procWorkflow.yaml +++ b/src/cdk/v2/destinations/reddit/procWorkflow.yaml @@ -36,13 +36,13 @@ steps: const os = (.message.context.os.name)? .message.context.os.name.toLowerCase(): null; const hashData = .destination.Config.hashData; let user = .message.().({ - "email": hashData ? $.SHA256({{{{$.getGenericPaths("email")}}}}) : ({{{{$.getGenericPaths("email")}}}}), - "external_id": hashData ? $.SHA256({{{{$.getGenericPaths("userId")}}}}) : ({{{{$.getGenericPaths("userId")}}}}), - "ip_address": hashData? $.SHA256(.context.ip || .request_ip) : (.context.ip || .request_ip), + "email": hashData ? $.SHA256({{{{$.getGenericPaths("email")}}}}.trim()) : ({{{{$.getGenericPaths("email")}}}}), + "external_id": hashData ? $.SHA256({{{{$.getGenericPaths("userId")}}}}.trim()) : ({{{{$.getGenericPaths("userId")}}}}), + "ip_address": hashData? $.SHA256(.context.ip.trim() || .request_ip.trim()) : (.context.ip || .request_ip), "uuid": .properties.uuid, "user_agent": .context.userAgent, - "idfa": $.isAppleFamily(os)? (hashData? $.SHA256(.context.device.advertisingId): .context.device.advertisingId): null, - "aaid": os === "android" && .context.device ? (hashData? $.SHA256(.context.device.advertisingId): .context.device.advertisingId): null, + "idfa": $.isAppleFamily(os)? (hashData? $.SHA256(.context.device.advertisingId.trim()): .context.device.advertisingId): null, + "aaid": os === "android" && .context.device ? (hashData? $.SHA256(.context.device.advertisingId.trim()): .context.device.advertisingId): null, "opt_out": .properties.optOut, "screen_dimensions": {"width": .context.screen.width, "height": .context.screen.height}, }); diff --git a/src/v0/destinations/facebook_offline_conversions/utils.js b/src/v0/destinations/facebook_offline_conversions/utils.js index c48de4e0b9..460ef71176 100644 --- a/src/v0/destinations/facebook_offline_conversions/utils.js +++ b/src/v0/destinations/facebook_offline_conversions/utils.js @@ -396,7 +396,7 @@ const preparePayload = (facebookOfflineConversionsPayload, destination) => { const keys = Object.keys(facebookOfflineConversionsPayload); keys.forEach((key) => { if (isHashRequired && HASHING_REQUIRED_KEYS.includes(key)) { - payload[key] = sha256(facebookOfflineConversionsPayload[key]); + payload[key] = sha256(facebookOfflineConversionsPayload[key].trim()); } else { payload[key] = facebookOfflineConversionsPayload[key]; } @@ -407,8 +407,8 @@ const preparePayload = (facebookOfflineConversionsPayload, destination) => { ? facebookOfflineConversionsPayload.name.split(' ') : null; if (split !== null && Array.isArray(split) && split.length === 2) { - payload.fn = isHashRequired ? sha256(split[0]) : split[0]; - payload.ln = isHashRequired ? sha256(split[1]) : split[1]; + payload.fn = isHashRequired ? sha256(split[0].trim()) : split[0]; + payload.ln = isHashRequired ? sha256(split[1].trim()) : split[1]; } delete payload.name; } diff --git a/src/v0/destinations/fb/transform.js b/src/v0/destinations/fb/transform.js index e6f8e986cf..1160cef407 100644 --- a/src/v0/destinations/fb/transform.js +++ b/src/v0/destinations/fb/transform.js @@ -90,7 +90,7 @@ function sanityCheckPayloadForTypesAndModifications(updatedEvent) { clonedUpdatedEvent[prop] !== '' ) { isUDSet = true; - clonedUpdatedEvent[prop] = sha256(clonedUpdatedEvent[prop].toLowerCase()); + clonedUpdatedEvent[prop] = sha256(clonedUpdatedEvent[prop].trim().toLowerCase()); } break; case 'ud[zp]': @@ -113,7 +113,7 @@ function sanityCheckPayloadForTypesAndModifications(updatedEvent) { } else { isUDSet = true; clonedUpdatedEvent[prop] = sha256( - clonedUpdatedEvent[prop].toLowerCase() === 'female' ? 'f' : 'm', + clonedUpdatedEvent[prop].trim().toLowerCase() === 'female' ? 'f' : 'm', ); } } @@ -128,7 +128,7 @@ function sanityCheckPayloadForTypesAndModifications(updatedEvent) { if (clonedUpdatedEvent[prop] && clonedUpdatedEvent[prop] !== '') { isUDSet = true; clonedUpdatedEvent[prop] = sha256( - clonedUpdatedEvent[prop].toLowerCase().replace(/ /g, ''), + clonedUpdatedEvent[prop].trim().toLowerCase().replace(/ /g, ''), ); } break; diff --git a/src/v0/destinations/google_adwords_enhanced_conversions/data/trackConfig.json b/src/v0/destinations/google_adwords_enhanced_conversions/data/trackConfig.json index bf5485270b..c38b24598d 100644 --- a/src/v0/destinations/google_adwords_enhanced_conversions/data/trackConfig.json +++ b/src/v0/destinations/google_adwords_enhanced_conversions/data/trackConfig.json @@ -55,7 +55,7 @@ "sourceFromGenericMap": true, "required": false, "metadata": { - "type": "hashToSha256" + "type": ["trim", "hashToSha256"] } }, { @@ -64,7 +64,7 @@ "sourceFromGenericMap": true, "required": false, "metadata": { - "type": "hashToSha256" + "type": ["trim", "hashToSha256"] } }, { @@ -73,7 +73,7 @@ "sourceFromGenericMap": true, "required": false, "metadata": { - "type": "hashToSha256" + "type": ["trim", "hashToSha256"] } }, { @@ -82,7 +82,7 @@ "sourceFromGenericMap": true, "required": false, "metadata": { - "type": "hashToSha256" + "type": ["trim", "hashToSha256"] } }, { @@ -127,7 +127,7 @@ "sourceKeys": ["context.traits.streetAddress", "context.traits.address"], "required": false, "metadata": { - "type": "hashToSha256" + "type": ["trim", "hashToSha256"] } } ] diff --git a/src/v0/destinations/google_adwords_enhanced_conversions/transform.js b/src/v0/destinations/google_adwords_enhanced_conversions/transform.js index 0be7c3f0ee..55d0c16c8c 100644 --- a/src/v0/destinations/google_adwords_enhanced_conversions/transform.js +++ b/src/v0/destinations/google_adwords_enhanced_conversions/transform.js @@ -24,7 +24,7 @@ const { JSON_MIME_TYPE } = require('../../util/constant'); const updateMappingJson = (mapping) => { const newMapping = []; mapping.forEach((element) => { - if (get(element, 'metadata.type') && element.metadata.type === 'hashToSha256') { + if (get(element, 'metadata.type') && element.metadata.type.includes('hashToSha256')) { element.metadata.type = 'toString'; } newMapping.push(element); diff --git a/src/v0/destinations/google_adwords_offline_conversions/utils.js b/src/v0/destinations/google_adwords_offline_conversions/utils.js index 70b42e2157..dfa892a769 100644 --- a/src/v0/destinations/google_adwords_offline_conversions/utils.js +++ b/src/v0/destinations/google_adwords_offline_conversions/utils.js @@ -140,17 +140,17 @@ const buildAndGetAddress = (message, hashUserIdentifier) => { const address = constructPayload(message, trackAddStoreAddressConversionsMapping); if (address.hashed_last_name) { address.hashed_last_name = hashUserIdentifier - ? sha256(address.hashed_last_name).toString() + ? sha256(address.hashed_last_name.trim()).toString() : address.hashed_last_name; } if (address.hashed_first_name) { address.hashed_first_name = hashUserIdentifier - ? sha256(address.hashed_first_name).toString() + ? sha256(address.hashed_first_name.trim()).toString() : address.hashed_first_name; } if (address.hashed_street_address) { address.hashed_street_address = hashUserIdentifier - ? sha256(address.hashed_street_address).toString() + ? sha256(address.hashed_street_address.trim()).toString() : address.hashed_street_address; } return Object.keys(address).length > 0 ? address : null; @@ -269,8 +269,10 @@ const getAddConversionPayload = (message, Config) => { const phone = getFieldValueFromMessage(message, 'phone'); const userIdentifierInfo = { - email: hashUserIdentifier && isDefinedAndNotNull(email) ? sha256(email).toString() : email, - phone: hashUserIdentifier && isDefinedAndNotNull(phone) ? sha256(phone).toString() : phone, + email: + hashUserIdentifier && isDefinedAndNotNull(email) ? sha256(email.trim()).toString() : email, + phone: + hashUserIdentifier && isDefinedAndNotNull(phone) ? sha256(phone.trim()).toString() : phone, address: buildAndGetAddress(message, hashUserIdentifier), }; @@ -363,8 +365,10 @@ const getClickConversionPayloadAndEndpoint = ( // Ref - https://developers.google.com/google-ads/api/rest/reference/rest/v11/customers/uploadClickConversions#ClickConversion const userIdentifierInfo = { - email: hashUserIdentifier && isDefinedAndNotNull(email) ? sha256(email).toString() : email, - phone: hashUserIdentifier && isDefinedAndNotNull(phone) ? sha256(phone).toString() : phone, + email: + hashUserIdentifier && isDefinedAndNotNull(email) ? sha256(email.trim()).toString() : email, + phone: + hashUserIdentifier && isDefinedAndNotNull(phone) ? sha256(phone.trim()).toString() : phone, }; const keyName = getExisitingUserIdentifier(userIdentifierInfo, defaultUserIdentifier); diff --git a/src/v0/destinations/impact/transform.js b/src/v0/destinations/impact/transform.js index 2eefdf7992..729f988938 100644 --- a/src/v0/destinations/impact/transform.js +++ b/src/v0/destinations/impact/transform.js @@ -59,7 +59,7 @@ const buildPageLoadPayload = (message, campaignId, impactAppId, enableEmailHashi let payload = constructPayload(message, MAPPING_CONFIG[CONFIG_CATEGORIES.PAGELOAD.name]); if (isDefinedAndNotNull(payload.CustomerEmail)) { payload.CustomerEmail = enableEmailHashing - ? sha1(payload?.CustomerEmail) + ? sha1(payload?.CustomerEmail.trim()) : payload?.CustomerEmail; } payload.CampaignId = campaignId; @@ -155,7 +155,7 @@ const processTrackEvent = (message, Config) => { payload.ImpactAppId = impactAppId; if (isDefinedAndNotNull(payload.CustomerEmail)) { payload.CustomerEmail = enableEmailHashing - ? sha1(payload?.CustomerEmail) + ? sha1(payload?.CustomerEmail.trim()) : payload?.CustomerEmail; } diff --git a/src/v0/destinations/pinterest_tag/utils.js b/src/v0/destinations/pinterest_tag/utils.js index 340fba498e..57d595571f 100644 --- a/src/v0/destinations/pinterest_tag/utils.js +++ b/src/v0/destinations/pinterest_tag/utils.js @@ -41,8 +41,8 @@ const getHashedValue = (key, value) => { case 'fn': case 'ge': value = Array.isArray(value) - ? value.map((val) => val.toString().toLowerCase()) - : value.toString().toLowerCase(); + ? value.map((val) => val.toString().trim().toLowerCase()) + : value.toString().trim().toLowerCase(); break; case 'ph': // phone numbers should only contain digits & should not contain leading zeros @@ -53,7 +53,7 @@ const getHashedValue = (key, value) => { case 'zp': // zip fields should only contain digits value = Array.isArray(value) - ? value.map((val) => val.toString().replace(/\D/g, '')) + ? value.map((val) => val.toString().trim().replace(/\D/g, '')) : value.toString().replace(/\D/g, ''); break; case 'hashed_maids': diff --git a/src/v0/destinations/yahoo_dsp/util.js b/src/v0/destinations/yahoo_dsp/util.js index 255f84d1c9..54002a3bce 100644 --- a/src/v0/destinations/yahoo_dsp/util.js +++ b/src/v0/destinations/yahoo_dsp/util.js @@ -51,7 +51,7 @@ const populateIdentifiers = (audienceList, Config) => { } // here, hashing the data if is not hashed and pushing in the seedList array. if (hashRequired) { - seedList.push(sha256(userTraits[audienceAttribute])); + seedList.push(sha256(userTraits[audienceAttribute].trim())); } else { seedList.push(userTraits[audienceAttribute]); } diff --git a/test/integrations/destinations/facebook_offline_conversions/processor/data.ts b/test/integrations/destinations/facebook_offline_conversions/processor/data.ts index 26d9a5e2f9..90709b67a2 100644 --- a/test/integrations/destinations/facebook_offline_conversions/processor/data.ts +++ b/test/integrations/destinations/facebook_offline_conversions/processor/data.ts @@ -1436,7 +1436,7 @@ export const data = [ traits: { email: 'test@rudderstack.com', birthday: '2005-01-01T23:28:56.782Z', - firstName: 'test', + firstName: ' test', name: 'test rudderlabs', address: { city: 'kalkata', diff --git a/test/integrations/destinations/fb/processor/data.ts b/test/integrations/destinations/fb/processor/data.ts index a437b90855..b0b4ba9ecf 100644 --- a/test/integrations/destinations/fb/processor/data.ts +++ b/test/integrations/destinations/fb/processor/data.ts @@ -497,7 +497,7 @@ export const data = [ traits: { email: 'abc@gmail.com', anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - firstName: 'test', + firstName: ' test', lastName: 'last', gender: 1234, phone: '+91-9831311135', diff --git a/test/integrations/destinations/google_adwords_enhanced_conversions/processor/data.ts b/test/integrations/destinations/google_adwords_enhanced_conversions/processor/data.ts index 0a9542a5d5..13b2609bf8 100644 --- a/test/integrations/destinations/google_adwords_enhanced_conversions/processor/data.ts +++ b/test/integrations/destinations/google_adwords_enhanced_conversions/processor/data.ts @@ -1255,7 +1255,7 @@ export const data = [ }, traits: { phone: '912382193', - firstName: 'John', + firstName: ' John', lastName: 'Gomes', city: 'London', state: 'UK', diff --git a/test/integrations/destinations/google_adwords_offline_conversions/processor/data.ts b/test/integrations/destinations/google_adwords_offline_conversions/processor/data.ts index decb1e58c7..ab3e19dc2f 100644 --- a/test/integrations/destinations/google_adwords_offline_conversions/processor/data.ts +++ b/test/integrations/destinations/google_adwords_offline_conversions/processor/data.ts @@ -321,7 +321,7 @@ export const data = [ advertisingId: '44c97318-9040-4361-8bc7-4eb30f665ca8', }, traits: { - email: 'alex@example.com', + email: ' alex@example.com', phone: '+1-202-555-0146', firstName: 'John', lastName: 'Gomes', diff --git a/test/integrations/destinations/impact/processor/data.ts b/test/integrations/destinations/impact/processor/data.ts index 1e4e91e7ad..0841f44c62 100644 --- a/test/integrations/destinations/impact/processor/data.ts +++ b/test/integrations/destinations/impact/processor/data.ts @@ -26,7 +26,7 @@ export const data = [ namespace: 'com.rudderlabs.javascript', }, traits: { - email: 'user123@email.com', + email: ' user123@email.com', phone: '+917836362334', userId: 'user123', }, diff --git a/test/integrations/destinations/pinterest_tag/processor/data.ts b/test/integrations/destinations/pinterest_tag/processor/data.ts index 65b33e7740..48b624645f 100644 --- a/test/integrations/destinations/pinterest_tag/processor/data.ts +++ b/test/integrations/destinations/pinterest_tag/processor/data.ts @@ -19,8 +19,8 @@ export const data = [ userAgent: 'chrome', traits: { anonymousId: '50be5c78-6c3f-4b60-be84-97805a316fb1', - email: 'abc@gmail.com', - phone: '+1234589947', + email: ' abc@gmail.com', + phone: '+1234589947 ', gender: 'non-binary', db: '19950715', lastname: 'Rudderlabs', diff --git a/test/integrations/destinations/reddit/processor/data.ts b/test/integrations/destinations/reddit/processor/data.ts index a97ae23d2a..e7b36f56ff 100644 --- a/test/integrations/destinations/reddit/processor/data.ts +++ b/test/integrations/destinations/reddit/processor/data.ts @@ -12,13 +12,13 @@ export const data = [ message: { context: { traits: { - email: 'testone@gmail.com', + email: 'testone@gmail.com ', }, userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', - ip: '54.100.200.255', + ip: ' 54.100.200.255', device: { - advertisingId: 'asfds7fdsihf734b34j43f', + advertisingId: ' asfds7fdsihf734b34j43f', }, os: { name: 'android', @@ -29,7 +29,7 @@ export const data = [ originalTimestamp: '2019-10-14T09:03:17.562Z', anonymousId: '123456', event: 'Order Completed', - userId: 'testuserId1', + userId: ' testuserId1', properties: { checkout_id: '12345', order_id: '1234', diff --git a/test/integrations/destinations/yahoo_dsp/processor/data.ts b/test/integrations/destinations/yahoo_dsp/processor/data.ts index eb607d60fb..3d04f9aa5c 100644 --- a/test/integrations/destinations/yahoo_dsp/processor/data.ts +++ b/test/integrations/destinations/yahoo_dsp/processor/data.ts @@ -51,7 +51,7 @@ export const data = [ }, { ipAddress: 'fdffddf', - email: 'van@abc.com', + email: 'van@abc.com ', deviceId: 'djfdjfkdjf', phone: '@09876543210', firstName: 'test', From 6e7b5a0d8bf2c859dfb15b9cad7ed6070bd0892b Mon Sep 17 00:00:00 2001 From: Anant Jain <62471433+anantjain45823@users.noreply.github.com> Date: Wed, 22 May 2024 19:15:05 +0530 Subject: [PATCH 11/11] fix: tiktok_v2 remove default value for content-type for custom events (#3383) --- .../tiktok_ads/data/TikTokTrackV2.json | 5 +---- src/v0/destinations/tiktok_ads/transformV2.js | 16 ++++++++++++---- .../destinations/tiktok_ads/processor/data.ts | 4 +--- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/v0/destinations/tiktok_ads/data/TikTokTrackV2.json b/src/v0/destinations/tiktok_ads/data/TikTokTrackV2.json index 530d6e392a..2910f1b44c 100644 --- a/src/v0/destinations/tiktok_ads/data/TikTokTrackV2.json +++ b/src/v0/destinations/tiktok_ads/data/TikTokTrackV2.json @@ -25,10 +25,7 @@ }, { "destKey": "properties.content_type", - "sourceKeys": ["properties.contentType", "properties.content_type"], - "metadata": { - "defaultValue": "product" - } + "sourceKeys": ["properties.contentType", "properties.content_type"] }, { "destKey": "properties.shop_id", diff --git a/src/v0/destinations/tiktok_ads/transformV2.js b/src/v0/destinations/tiktok_ads/transformV2.js index 3bd8699e3a..4624ec9181 100644 --- a/src/v0/destinations/tiktok_ads/transformV2.js +++ b/src/v0/destinations/tiktok_ads/transformV2.js @@ -31,7 +31,7 @@ const { JSON_MIME_TYPE } = require('../../util/constant'); * @param {*} event * @returns track payload */ -const getTrackResponsePayload = (message, destConfig, event) => { +const getTrackResponsePayload = (message, destConfig, event, setDefaultForContentType = true) => { const payload = constructPayload(message, trackMappingV2); // if contents is not an array converting it into array @@ -53,6 +53,10 @@ const getTrackResponsePayload = (message, destConfig, event) => { if (destConfig.hashUserProperties && isDefinedAndNotNullAndNotEmpty(payload.user)) { payload.user = hashUserField(payload.user); } + // setting content-type default value in case of all standard event except `page-view` + if (!payload.properties?.content_type && setDefaultForContentType) { + payload.properties.content_type = 'product'; + } payload.event = event; // add partner name and return payload return removeUndefinedAndNullValues(payload); @@ -90,13 +94,17 @@ const trackResponseBuilder = async (message, { Config }) => { }); } }); - } else { + } else if (!eventNameMapping[event]) { /* + Custom Event Case -> if there exists no event mapping we will build payload with custom event recieved For custom event we do not want to lower case the event or trim it we just want to send those as it is Doc https://ads.tiktok.com/help/article/standard-events-parameters?lang=en */ - event = eventNameMapping[event] || message.event; - // if there exists no event mapping we will build payload with custom event recieved + event = message.event; + responseList.push(getTrackResponsePayload(message, Config, event, false)); + } else { + // incoming event name is already a standard event name + event = eventNameMapping[event]; responseList.push(getTrackResponsePayload(message, Config, event)); } // set event source and event_source_id diff --git a/test/integrations/destinations/tiktok_ads/processor/data.ts b/test/integrations/destinations/tiktok_ads/processor/data.ts index 429024b8a9..af58b66302 100644 --- a/test/integrations/destinations/tiktok_ads/processor/data.ts +++ b/test/integrations/destinations/tiktok_ads/processor/data.ts @@ -5224,7 +5224,6 @@ export const data = [ event_id: '1616318632825_357', event_time: 1600372167, properties: { - content_type: 'product', contents: [ { price: 8, @@ -6872,7 +6871,7 @@ export const data = [ }, { name: 'tiktok_ads', - description: 'Test 46 -> V2 -> Event with no properties', + description: 'Test 46 -> V2 -> Custom Event with no properties', feature: 'processor', module: 'destination', version: 'v0', @@ -6947,7 +6946,6 @@ export const data = [ event: 'customEvent', event_id: '84e26acc-56a5-4835-8233-591137fca468', event_time: 1600372167, - properties: { content_type: 'product' }, user: { locale: 'en-US', email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f',