From 933b1fac6443a275d263e7855ca884ae4a0defd6 Mon Sep 17 00:00:00 2001 From: Gauravudia Date: Tue, 5 Sep 2023 18:27:33 +0530 Subject: [PATCH 1/3] feat(mixpanel): add incremental properties support --- src/v0/destinations/mp/transform.js | 31 +++++++++++++++++++++++++++++ test/__tests__/data/mp_input.json | 18 +++++++++++++++-- test/__tests__/data/mp_output.json | 20 ++++++++++++++++++- 3 files changed, 66 insertions(+), 3 deletions(-) diff --git a/src/v0/destinations/mp/transform.js b/src/v0/destinations/mp/transform.js index 0cb06aad93..f2401023cc 100644 --- a/src/v0/destinations/mp/transform.js +++ b/src/v0/destinations/mp/transform.js @@ -130,6 +130,29 @@ const processRevenueEvents = (message, destination, revenueValue) => { return responseBuilderSimple(payload, message, 'revenue', destination.Config); }; +const processIncrementalProperties = (message, destination, propIncrements) => { + const payload = { + $add: {}, + $token: destination.Config.token, + $distinct_id: message.userId || message.anonymousId, + }; + + if (destination?.Config.identityMergeApi === 'simplified') { + payload.$distinct_id = message.userId || `$device:${message.anonymousId}`; + } + + Object.keys(message.properties).forEach((prop) => { + const value = message.properties[prop]; + if (value && propIncrements.includes(prop)) { + payload.$add[prop] = value; + } + }); + + return Object.keys(payload.$add).length > 0 + ? responseBuilderSimple(payload, message, 'incremental_properties', destination.Config) + : null; +}; + const getEventValueForTrackEvent = (message, destination) => { const mappedProperties = constructPayload(message, mPEventPropertiesConfigJson); // This is to conform with SDKs sending timestamp component with messageId @@ -178,6 +201,14 @@ const processTrack = (message, destination) => { if (revenue) { returnValue.push(processRevenueEvents(message, destination, revenue)); } + + if (destination.Config.propIncrements) { + const propIncrements = destination.Config.propIncrements.map((item) => item.property); + const response = processIncrementalProperties(message, destination, propIncrements); + if (response) { + returnValue.push(response); + } + } returnValue.push(getEventValueForTrackEvent(message, destination)); return returnValue; }; diff --git a/test/__tests__/data/mp_input.json b/test/__tests__/data/mp_input.json index 394fc49b61..6fde212d7b 100644 --- a/test/__tests__/data/mp_input.json +++ b/test/__tests__/data/mp_input.json @@ -432,7 +432,18 @@ "apiKey": "dummyApiKey", "token": "dummyApiKey", "prefixProperties": true, - "useNativeSDK": false + "useNativeSDK": false, + "propIncrements": [ + { + "property": "counter" + }, + { + "property": "item_purchased" + }, + { + "property": "number_of_logins" + } + ] }, "DestinationDefinition": { "DisplayName": "Kiss Metrics", @@ -493,7 +504,10 @@ "originalTimestamp": "2020-01-24T06:29:02.364Z", "properties": { "currency": "USD", - "revenue": 45.89 + "revenue": 45.89, + "counter": 1, + "item_purchased": "2", + "number_of_logins": "" }, "receivedAt": "2020-01-24T11:59:02.403+05:30", "request_ip": "[::1]:53710", diff --git a/test/__tests__/data/mp_output.json b/test/__tests__/data/mp_output.json index fe54474dd8..61100a1b84 100644 --- a/test/__tests__/data/mp_output.json +++ b/test/__tests__/data/mp_output.json @@ -128,6 +128,24 @@ "files": {}, "userId": "e6ab2c5e-2cda-44a9-a962-e2f67df78bca" }, + { + "version": "1", + "type": "REST", + "method": "POST", + "endpoint": "https://api.mixpanel.com/engage/", + "headers": {}, + "params": {}, + "body": { + "JSON": {}, + "JSON_ARRAY": { + "batch": "[{\"$add\":{\"counter\":1,\"item_purchased\":\"2\"},\"$token\":\"dummyApiKey\",\"$distinct_id\":\"e6ab2c5e-2cda-44a9-a962-e2f67df78bca\"}]" + }, + "XML": {}, + "FORM": {} + }, + "files": {}, + "userId": "e6ab2c5e-2cda-44a9-a962-e2f67df78bca" + }, { "version": "1", "type": "REST", @@ -138,7 +156,7 @@ "body": { "JSON": {}, "JSON_ARRAY": { - "batch": "[{\"event\":\"test revenue MIXPANEL\",\"properties\":{\"currency\":\"USD\",\"revenue\":45.89,\"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\":\"a6a0ad5a-bd26-4f19-8f75-38484e580fc7\",\"token\":\"dummyApiKey\",\"distinct_id\":\"e6ab2c5e-2cda-44a9-a962-e2f67df78bca\",\"time\":1579847342,\"$browser\":\"Chrome\",\"$browser_version\":\"79.0.3945.117\"}}]" + "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\",\"$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\":1579847342,\"$browser\":\"Chrome\",\"$browser_version\":\"79.0.3945.117\"}}]" }, "XML": {}, "FORM": {} From ba11c923827e2f154d09c6a2b41637e3b4ed094a Mon Sep 17 00:00:00 2001 From: Gauravudia Date: Tue, 5 Sep 2023 18:39:36 +0530 Subject: [PATCH 2/3] docs: add comment --- src/v0/destinations/mp/transform.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/v0/destinations/mp/transform.js b/src/v0/destinations/mp/transform.js index f2401023cc..425b7a8249 100644 --- a/src/v0/destinations/mp/transform.js +++ b/src/v0/destinations/mp/transform.js @@ -130,6 +130,14 @@ const processRevenueEvents = (message, destination, revenueValue) => { return responseBuilderSimple(payload, message, 'revenue', destination.Config); }; +/** + * This function is used to process the incremental properties + * ref :- https://developer.mixpanel.com/reference/profile-numerical-add + * @param {*} message + * @param {*} destination + * @param {*} propIncrements + * @returns + */ const processIncrementalProperties = (message, destination, propIncrements) => { const payload = { $add: {}, @@ -202,7 +210,7 @@ const processTrack = (message, destination) => { returnValue.push(processRevenueEvents(message, destination, revenue)); } - if (destination.Config.propIncrements) { + if (Array.isArray(destination.Config.propIncrements)) { const propIncrements = destination.Config.propIncrements.map((item) => item.property); const response = processIncrementalProperties(message, destination, propIncrements); if (response) { From 693a20c429ad91e8a14eaaa7b8384b510efe276b Mon Sep 17 00:00:00 2001 From: Gauravudia Date: Sun, 10 Sep 2023 13:45:55 +0530 Subject: [PATCH 3/3] test: update testcase --- src/v0/destinations/mp/util.test.js | 5 +---- test/__tests__/data/mp_input.json | 7 ++++++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/v0/destinations/mp/util.test.js b/src/v0/destinations/mp/util.test.js index 2434564699..c5cd5b61e8 100644 --- a/src/v0/destinations/mp/util.test.js +++ b/src/v0/destinations/mp/util.test.js @@ -1,7 +1,4 @@ -const { - combineBatchRequestsWithSameJobIds, - combineBatchRequestsWithSameJobIds2, -} = require('./util'); +const { combineBatchRequestsWithSameJobIds } = require('./util'); const destinationMock = { Config: { diff --git a/test/__tests__/data/mp_input.json b/test/__tests__/data/mp_input.json index 6fde212d7b..6d456858c9 100644 --- a/test/__tests__/data/mp_input.json +++ b/test/__tests__/data/mp_input.json @@ -596,7 +596,12 @@ "apiKey": "dummyApiKey", "token": "dummyApiKey", "prefixProperties": true, - "useNativeSDK": false + "useNativeSDK": false, + "propIncrements": [ + { + "property": "" + } + ] }, "DestinationDefinition": { "DisplayName": "Kiss Metrics",