From 14c5e40284af7df9e4f5b262ad226dd3afef226e Mon Sep 17 00:00:00 2001 From: shrouti1507 <60211312+shrouti1507@users.noreply.github.com> Date: Mon, 30 Oct 2023 13:31:00 +0530 Subject: [PATCH 01/93] feat: onboard facebook custom audience to transformer proxy (#2769) * feat: error codes added in fbUtils * adding single test case * adding test cases in new format * adding test cases in new format * fix: fixing the test cases * fix: cleaning up files * fix: cleaning up files * fix: cleaning up files * fix: review comments addressed * fix: review comments addressed * Empty commit * fix: deleting wrongly spelled file * fix: add network handler for fb_custom_audience with correct spelling --------- Co-authored-by: Ujjwal Abhishek <63387036+ujjwal-ab@users.noreply.github.com> Co-authored-by: Sai Sankeerth --- .../fb_custom_audience/networkHandler.js | 6 + src/v0/util/facebookUtils/networkHandler.js | 46 +- .../data/facebook_pixel_proxy_output.json | 2 +- test/__tests__/data/fb_proxy_output.json | 2 +- .../facebook_pixel/dataDelivery/data.ts | 2 +- .../destinations/fb/dataDelivery/data.ts | 2 +- .../fb_custom_audience/dataDelivery/data.ts | 617 ++++++++++++++++++ .../fb_custom_audience/network.ts | 456 +++++++++++++ 8 files changed, 1128 insertions(+), 5 deletions(-) create mode 100644 src/v0/destinations/fb_custom_audience/networkHandler.js create mode 100644 test/integrations/destinations/fb_custom_audience/dataDelivery/data.ts create mode 100644 test/integrations/destinations/fb_custom_audience/network.ts diff --git a/src/v0/destinations/fb_custom_audience/networkHandler.js b/src/v0/destinations/fb_custom_audience/networkHandler.js new file mode 100644 index 0000000000..0ea7aff7da --- /dev/null +++ b/src/v0/destinations/fb_custom_audience/networkHandler.js @@ -0,0 +1,6 @@ +const { networkHandler, errorResponseHandler } = require('../../util/facebookUtils/networkHandler'); + +module.exports = { + networkHandler, + errorResponseHandler, +}; diff --git a/src/v0/util/facebookUtils/networkHandler.js b/src/v0/util/facebookUtils/networkHandler.js index d53d0f76f9..87c2ced2b4 100644 --- a/src/v0/util/facebookUtils/networkHandler.js +++ b/src/v0/util/facebookUtils/networkHandler.js @@ -75,7 +75,7 @@ const errorDetailsMap = { 33: new ErrorDetailsExtractorBuilder() .setStatus(400) .setMessage( - "Object with ID 'PIXEL_ID' does not exist, cannot be loaded due to missing permissions, or does not support this operation", + "Object with ID 'PIXEL_ID' / 'DATASET_ID' / 'AUDIENCE_ID' does not exist, cannot be loaded due to missing permissions, or does not support this operation", ) .build(), default: new ErrorDetailsExtractorBuilder() @@ -151,6 +151,50 @@ const errorDetailsMap = { .setMessage('API User Too Many Calls') .build(), }, + // facebook custom audience related error codes + // ref: + // https://developers.facebook.com/docs/marketing-api/reference/custom-audience/#error-codes-4 + // https://developers.facebook.com/docs/marketing-api/error-reference/ + 294: { + default: new ErrorDetailsExtractorBuilder() + .setStatus(400) + .setMessage( + 'Missing permission. Please make sure you have ads_management permission and the application is included in the allowlist', + ) + .build(), + }, + 1487301: { + default: new ErrorDetailsExtractorBuilder() + .setStatus(400) + .setMessage( + 'Custom Audience Unavailable: The custom audience you are trying to use has not been shared with your ad account', + ) + .build(), + }, + 1487366: { + default: new ErrorDetailsExtractorBuilder() + .setStatus(400) + .setMessage('Custom Audience Has Been Deleted') + .build(), + }, + 2650: { + default: new ErrorDetailsExtractorBuilder() + .setStatus(400) + .setMessage('Failed to update the custom audience') + .build(), + }, + 105: { + default: new ErrorDetailsExtractorBuilder() + .setStatus(400) + .setMessage('The number of parameters exceeded the maximum for this operation') + .build(), + }, + 80003: { + default: new ErrorDetailsExtractorBuilder() + .setStatus(429) + .setMessage('There have been too many calls to this ad-account.') + .build(), + }, }; const getErrorDetailsFromErrorMap = (error) => { diff --git a/test/__tests__/data/facebook_pixel_proxy_output.json b/test/__tests__/data/facebook_pixel_proxy_output.json index 607ac7804e..e0afb028d3 100644 --- a/test/__tests__/data/facebook_pixel_proxy_output.json +++ b/test/__tests__/data/facebook_pixel_proxy_output.json @@ -91,7 +91,7 @@ { "output": { "status": 400, - "message": "Object with ID 'PIXEL_ID' does not exist, cannot be loaded due to missing permissions, or does not support this operation", + "message": "Object with ID 'PIXEL_ID' / 'DATASET_ID' / 'AUDIENCE_ID' does not exist, cannot be loaded due to missing permissions, or does not support this operation", "destinationResponse": { "error": { "message": "Unsupported post request. Object with ID '1234567891234569' does not exist, cannot be loaded due to missing permissions, or does not support this operation. Please read the Graph API documentation at https://developers.facebook.com/docs/graph-api", diff --git a/test/__tests__/data/fb_proxy_output.json b/test/__tests__/data/fb_proxy_output.json index e9dbf0d128..12e06cff2c 100644 --- a/test/__tests__/data/fb_proxy_output.json +++ b/test/__tests__/data/fb_proxy_output.json @@ -91,7 +91,7 @@ { "output": { "status": 400, - "message": "Object with ID 'PIXEL_ID' does not exist, cannot be loaded due to missing permissions, or does not support this operation", + "message": "Object with ID 'PIXEL_ID' / 'DATASET_ID' / 'AUDIENCE_ID' does not exist, cannot be loaded due to missing permissions, or does not support this operation", "destinationResponse": { "error": { "message": "Unsupported post request. Object with ID '1234567891234569' does not exist, cannot be loaded due to missing permissions, or does not support this operation. Please read the Graph API documentation at https://developers.facebook.com/docs/graph-api", diff --git a/test/integrations/destinations/facebook_pixel/dataDelivery/data.ts b/test/integrations/destinations/facebook_pixel/dataDelivery/data.ts index e4e4a7d4c8..d560658341 100644 --- a/test/integrations/destinations/facebook_pixel/dataDelivery/data.ts +++ b/test/integrations/destinations/facebook_pixel/dataDelivery/data.ts @@ -290,7 +290,7 @@ export const data = [ output: { status: 400, message: - "Object with ID 'PIXEL_ID' does not exist, cannot be loaded due to missing permissions, or does not support this operation", + "Object with ID 'PIXEL_ID' / 'DATASET_ID' / 'AUDIENCE_ID' does not exist, cannot be loaded due to missing permissions, or does not support this operation", destinationResponse: { error: { message: diff --git a/test/integrations/destinations/fb/dataDelivery/data.ts b/test/integrations/destinations/fb/dataDelivery/data.ts index 70538a6ea0..c50cffee80 100644 --- a/test/integrations/destinations/fb/dataDelivery/data.ts +++ b/test/integrations/destinations/fb/dataDelivery/data.ts @@ -328,7 +328,7 @@ export const data = [ "body": { "output": { "status": 400, - "message": "Object with ID 'PIXEL_ID' does not exist, cannot be loaded due to missing permissions, or does not support this operation", + "message": "Object with ID 'PIXEL_ID' / 'DATASET_ID' / 'AUDIENCE_ID' does not exist, cannot be loaded due to missing permissions, or does not support this operation", "destinationResponse": { "error": { "message": "Unsupported post request. Object with ID '1234567891234569' does not exist, cannot be loaded due to missing permissions, or does not support this operation. Please read the Graph API documentation at https://developers.facebook.com/docs/graph-api", diff --git a/test/integrations/destinations/fb_custom_audience/dataDelivery/data.ts b/test/integrations/destinations/fb_custom_audience/dataDelivery/data.ts new file mode 100644 index 0000000000..ddb081ba87 --- /dev/null +++ b/test/integrations/destinations/fb_custom_audience/dataDelivery/data.ts @@ -0,0 +1,617 @@ +export const data = [ + { + name: 'fb_custom_audience', + description: 'successfully adding users to audience', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + version: '1', + type: 'REST', + method: 'DELETE', + endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + headers: { + "test-dest-response-key": "successResponse" + }, + params: { + access_token: 'ABC', + payload: { + is_raw: true, + data_source: { + sub_type: 'ANYTHING', + }, + schema: [ + 'EMAIL', + 'DOBM', + 'DOBD', + 'DOBY', + 'PHONE', + 'GEN', + 'FI', + 'MADID', + 'ZIP', + 'ST', + 'COUNTRY', + ], + data: [ + [ + 'shrouti@abc.com', + '2', + '13', + '2013', + '@09432457768', + 'f', + 'Ms.', + 'ABC', + 'ZIP ', + '123abc ', + 'IN', + ], + ], + }, + }, + userId: '', + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + } + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 200, + message: 'Request Processed Successfully', + destinationResponse: { + audience_id: 'aud1', + invalid_entry_samples: {}, + num_invalid_entries: 0, + num_received: 4, + session_id: '123' + } + } + } + }, + }, + }, + { + name: 'fb_custom_audience', + description: 'user addition failed due to missing permission', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + headers: { + "test-dest-response-key": "permissionMissingError" + }, + params: { + access_token: 'BCD', + payload: { + is_raw: true, + data_source: { + sub_type: 'ANYTHING', + }, + schema: [ + 'DOBM', + 'DOBD', + 'DOBY', + 'PHONE', + 'GEN', + 'FI', + 'MADID', + 'ZIP', + 'ST', + 'COUNTRY', + ], + data: [ + [ + '2', + '13', + '2013', + '@09432457768', + 'f', + 'Ms.', + 'ABC', + 'ZIP ', + '123abc ', + 'IN', + ], + ], + }, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + } + }, + }, + output: { + response: { + status: 400, + body: { + output: { + destinationResponse: { + error: { + code: 294, + message: "Missing permission. Please make sure you have ads_management permission and the application is included in the allowlist", + type: "GraphMethodException", + }, + status: 400, + + }, + message: "Missing permission. Please make sure you have ads_management permission and the application is included in the allowlist", + statTags: { + destType: "FB_CUSTOM_AUDIENCE", + destinationId: "Non-determininable", + errorCategory: "network", + errorType: "aborted", + feature: "dataDelivery", + implementation: "native", + module: "destination", + workspaceId: "Non-determininable", + }, + "status": 400, + }, + }, + }, + }, + }, + { + name: 'fb_custom_audience', + description: 'user addition failed due to unavailable audience error', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + version: '1', + type: 'REST', + method: 'DELETE', + endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + headers: { + "test-dest-response-key": "audienceUnavailableError" + }, + params: { + access_token: 'ABC', + payload: { + is_raw: true, + data_source: { + sub_type: 'ANYTHING', + }, + schema: [ + 'DOBY', + 'PHONE', + 'GEN', + 'FI', + 'MADID', + 'ZIP', + 'ST', + 'COUNTRY', + ], + data: [ + [ + '2013', + '@09432457768', + 'f', + 'Ms.', + 'ABC', + 'ZIP ', + '123abc ', + 'IN', + ], + ], + }, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + } + }, + }, + output: { + response: { + status: 400, + body: { + output: { + destinationResponse: { + error: { + code: 1487301, + message: "Custom Audience Unavailable: The custom audience you are trying to use has not been shared with your ad account", + type: "GraphMethodException", + }, + status: 400, + + }, + message: "Custom Audience Unavailable: The custom audience you are trying to use has not been shared with your ad account", + statTags: { + destType: "FB_CUSTOM_AUDIENCE", + destinationId: "Non-determininable", + errorCategory: "network", + errorType: "aborted", + feature: "dataDelivery", + implementation: "native", + module: "destination", + workspaceId: "Non-determininable", + }, + "status": 400, + }, + }, + }, + }, + }, + { + name: 'fb_custom_audience', + description: 'user addition failed because the custom audience has been deleted', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + version: '1', + type: 'REST', + method: 'DELETE', + endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + headers: { + "test-dest-response-key": "audienceDeletedError" + }, + params: { + access_token: 'ABC', + payload: { + is_raw: true, + data_source: { + sub_type: 'ANYTHING', + }, + schema: [ + 'DOBY', + 'PHONE', + 'GEN', + 'FI', + 'MADID', + 'ZIP', + 'ST', + 'COUNTRY', + ], + data: [ + [ + '2013', + '@09432457768', + 'f', + 'Ms.', + 'ABC', + 'ZIP ', + '123abc ', + 'IN', + ], + ], + }, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + } + }, + }, + output: { + response: { + status: 400, + body: { + output: { + destinationResponse: { + error: { + code: 1487366, + message: "Custom Audience Has Been Deleted", + type: "GraphMethodException", + }, + status: 400, + + }, + message: "Custom Audience Has Been Deleted", + statTags: { + destType: "FB_CUSTOM_AUDIENCE", + destinationId: "Non-determininable", + errorCategory: "network", + errorType: "aborted", + feature: "dataDelivery", + implementation: "native", + module: "destination", + workspaceId: "Non-determininable", + }, + "status": 400, + }, + }, + }, + }, + }, + { + name: 'fb_custom_audience', + description: 'Failed to update the custom audience for unknown reason', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + version: '1', + type: 'REST', + method: 'DELETE', + endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + headers: { + "test-dest-response-key": "failedToUpdateAudienceError" + }, + params: { + access_token: 'ABC', + payload: { + is_raw: true, + data_source: { + sub_type: 'ANYTHING', + }, + schema: [ + 'DOBY', + 'PHONE', + 'GEN', + 'FI', + 'MADID', + 'ZIP', + 'ST', + 'COUNTRY', + ], + data: [ + [ + '2013', + '@09432457768', + 'f', + 'Ms.', + 'ABC', + 'ZIP ', + '123abc ', + 'IN', + ], + ], + }, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + } + }, + }, + output: { + response: { + status: 400, + body: { + output: { + destinationResponse: { + error: { + code: 2650, + message: "Failed to update the custom audience", + type: "GraphMethodException", + }, + status: 400, + + }, + message: "Failed to update the custom audience", + statTags: { + destType: "FB_CUSTOM_AUDIENCE", + destinationId: "Non-determininable", + errorCategory: "network", + errorType: "aborted", + feature: "dataDelivery", + implementation: "native", + module: "destination", + workspaceId: "Non-determininable", + }, + "status": 400, + }, + }, + }, + }, + }, + { + name: 'fb_custom_audience', + description: 'Failed to update the custom audience as excessive number of parameters were passed in the request', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + version: '1', + type: 'REST', + method: 'DELETE', + endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + headers: { + "test-dest-response-key": "parameterExceededError" + }, + params: { + access_token: 'ABC', + payload: { + is_raw: true, + data_source: { + sub_type: 'ANYTHING', + }, + schema: [ + 'DOBY', + 'PHONE', + 'GEN', + 'FI', + 'MADID', + 'ZIP', + 'ST', + 'COUNTRY', + ], + data: [ + [ + '2013', + '@09432457768', + 'f', + 'Ms.', + 'ABC', + 'ZIP ', + '123abc ', + 'IN', + ], + ], + }, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + } + }, + }, + output: { + response: { + status: 400, + body: { + output: { + destinationResponse: { + error: { + code: 105, + message: "The number of parameters exceeded the maximum for this operation", + type: "GraphMethodException", + }, + status: 400, + + }, + message: "The number of parameters exceeded the maximum for this operation", + statTags: { + destType: "FB_CUSTOM_AUDIENCE", + destinationId: "Non-determininable", + errorCategory: "network", + errorType: "aborted", + feature: "dataDelivery", + implementation: "native", + module: "destination", + workspaceId: "Non-determininable", + }, + "status": 400, + }, + }, + }, + }, + }, + { + name: 'fb_custom_audience', + description: 'user update request is throttled due to too many calls to the ad account', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + version: '1', + type: 'REST', + method: 'DELETE', + endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + headers: { + "test-dest-response-key": "tooManyCallsError" + }, + params: { + access_token: 'ABC', + payload: { + is_raw: true, + data_source: { + sub_type: 'ANYTHING', + }, + schema: [ + 'DOBY', + 'PHONE', + 'GEN', + 'FI', + 'MADID', + 'ZIP', + 'ST', + 'COUNTRY', + ], + data: [ + [ + '2013', + '@09432457768', + 'f', + 'Ms.', + 'ABC', + 'ZIP ', + '123abc ', + 'IN', + ], + ], + }, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + } + }, + }, + output: { + response: { + status: 429, + body: { + output: { + destinationResponse: { + error: { + code: 80003, + message: "There have been too many calls to this ad-account.", + type: "GraphMethodException", + }, + status: 429, + + }, + message: "There have been too many calls to this ad-account.", + statTags: { + destType: "FB_CUSTOM_AUDIENCE", + destinationId: "Non-determininable", + errorCategory: "network", + errorType: "throttled", + feature: "dataDelivery", + implementation: "native", + module: "destination", + workspaceId: "Non-determininable", + }, + "status": 429, + }, + }, + }, + }, + } +] \ No newline at end of file diff --git a/test/integrations/destinations/fb_custom_audience/network.ts b/test/integrations/destinations/fb_custom_audience/network.ts new file mode 100644 index 0000000000..2c19a6fe0d --- /dev/null +++ b/test/integrations/destinations/fb_custom_audience/network.ts @@ -0,0 +1,456 @@ +export const networkCallsData = [ + { + httpReq: { + version: '1', + type: 'REST', + method: 'DELETE', + endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + headers: { + 'test-dest-response-key': 'successResponse' + }, + params: { + access_token: 'ABC', + payload: { + is_raw: true, + data_source: { + sub_type: 'ANYTHING', + }, + schema: [ + 'EMAIL', + 'DOBM', + 'DOBD', + 'DOBY', + 'PHONE', + 'GEN', + 'FI', + 'MADID', + 'ZIP', + 'ST', + 'COUNTRY', + ], + data: [ + [ + 'shrouti@abc.com', + '2', + '13', + '2013', + '@09432457768', + 'f', + 'Ms.', + 'ABC', + 'ZIP ', + '123abc ', + 'IN', + ], + ], + }, + }, + userId: '', + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + }, + httpRes: { + "data": { + "audience_id": "aud1", + "session_id": "123", + "num_received": 4, + "num_invalid_entries": 0, + "invalid_entry_samples": {} + }, + "status": 200 + } + }, + { + httpReq: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + headers: { + 'test-dest-response-key': 'permissionMissingError' + }, + params: { + access_token: 'BCD', + payload: { + is_raw: true, + data_source: { + sub_type: 'ANYTHING', + }, + schema: [ + 'DOBM', + 'DOBD', + 'DOBY', + 'PHONE', + 'GEN', + 'FI', + 'MADID', + 'ZIP', + 'ST', + 'COUNTRY', + ], + data: [ + [ + '2', + '13', + '2013', + '@09432457768', + 'f', + 'Ms.', + 'ABC', + 'ZIP ', + '123abc ', + 'IN', + ], + ], + }, + }, + userId: '', + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + }, + httpRes: { + data: { + error: { + code: 294, + message: "Missing permission. Please make sure you have ads_management permission and the application is included in the allowlist", + type: "GraphMethodException", + } + }, + "status": 400 + } + }, + { + httpReq: { + version: '1', + type: 'REST', + method: 'DELETE', + endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + headers: { + 'test-dest-response-key': 'audienceUnavailableError' + }, + params: { + access_token: 'ABC', + payload: { + is_raw: true, + data_source: { + sub_type: 'ANYTHING', + }, + schema: [ + 'DOBY', + 'PHONE', + 'GEN', + 'FI', + 'MADID', + 'ZIP', + 'ST', + 'COUNTRY', + ], + data: [ + [ + '2013', + '@09432457768', + 'f', + 'Ms.', + 'ABC', + 'ZIP ', + '123abc ', + 'IN', + ], + ], + }, + }, + userId: '', + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + }, + httpRes: { + data: { + error: { + code: 1487301, + message: "Custom Audience Unavailable: The custom audience you are trying to use has not been shared with your ad account", + type: "GraphMethodException", + } + }, + "status": 400 + } + }, + { + httpReq: { + version: '1', + type: 'REST', + method: 'DELETE', + endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + headers: { + 'test-dest-response-key': 'audienceDeletedError' + }, + params: { + access_token: 'ABC', + payload: { + is_raw: true, + data_source: { + sub_type: 'ANYTHING', + }, + schema: [ + 'EMAIL', + 'DOBM', + 'DOBD', + 'DOBY', + 'PHONE', + 'GEN', + 'FI', + 'MADID', + 'ZIP', + 'ST', + 'COUNTRY', + ], + data: [ + [ + 'shrouti@abc.com', + '2', + '13', + '2013', + '@09432457768', + 'f', + 'Ms.', + 'ABC', + 'ZIP ', + '123abc ', + 'IN', + ], + ], + }, + }, + userId: '', + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + }, + httpRes: { + data: { + error: { + code: 1487366, + message: "Custom Audience Has Been Deleted", + type: "GraphMethodException", + } + }, + "status": 400 + } + }, + { + httpReq: { + version: '1', + type: 'REST', + method: 'DELETE', + endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + headers: { + 'test-dest-response-key': 'failedToUpdateAudienceError' + }, + params: { + access_token: 'ABC', + payload: { + is_raw: true, + data_source: { + sub_type: 'ANYTHING', + }, + schema: [ + 'EMAIL', + 'DOBM', + 'DOBD', + 'DOBY', + 'PHONE', + 'GEN', + 'FI', + 'MADID', + 'ZIP', + 'ST', + 'COUNTRY', + ], + data: [ + [ + 'shrouti@abc.com', + '2', + '13', + '2013', + '@09432457768', + 'f', + 'Ms.', + 'ABC', + 'ZIP ', + '123abc ', + 'IN', + ], + ], + }, + }, + userId: '', + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + }, + httpRes: { + data: { + error: { + code: 2650, + message: "Failed to update the custom audience", + type: "GraphMethodException", + } + }, + "status": 400 + } + }, + { + httpReq: { + version: '1', + type: 'REST', + method: 'DELETE', + endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + headers: { + 'test-dest-response-key': 'parameterExceededError' + }, + params: { + access_token: 'ABC', + payload: { + is_raw: true, + data_source: { + sub_type: 'ANYTHING', + }, + schema: [ + 'EMAIL', + 'DOBM', + 'DOBD', + 'DOBY', + 'PHONE', + 'GEN', + 'FI', + 'MADID', + 'ZIP', + 'ST', + 'COUNTRY', + ], + data: [ + [ + 'shrouti@abc.com', + '2', + '13', + '2013', + '@09432457768', + 'f', + 'Ms.', + 'ABC', + 'ZIP ', + '123abc ', + 'IN', + ], + ], + }, + }, + userId: '', + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + }, + httpRes: { + data: { + error: { + code: 105, + message: "The number of parameters exceeded the maximum for this operation", + type: "GraphMethodException", + } + }, + "status": 400 + } + }, + { + httpReq: { + version: '1', + type: 'REST', + method: 'DELETE', + endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + headers: { + 'test-dest-response-key': 'tooManyCallsError' + }, + params: { + access_token: 'ABC', + payload: { + is_raw: true, + data_source: { + sub_type: 'ANYTHING', + }, + schema: [ + 'EMAIL', + 'DOBM', + 'DOBD', + 'DOBY', + 'PHONE', + 'GEN', + 'FI', + 'MADID', + 'ZIP', + 'ST', + 'COUNTRY', + ], + data: [ + [ + 'shrouti@abc.com', + '2', + '13', + '2013', + '@09432457768', + 'f', + 'Ms.', + 'ABC', + 'ZIP ', + '123abc ', + 'IN', + ], + ], + }, + }, + userId: '', + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + }, + httpRes: { + data: { + error: { + code: 80003, + message: "There have been too many calls to this ad-account.", + type: "GraphMethodException", + } + }, + "status": 429 + } + } +]; \ No newline at end of file From 748b6225cc71e04a69597067ca7c0fd2faf2a557 Mon Sep 17 00:00:00 2001 From: Yashasvi Bajpai <33063622+yashasvibajpai@users.noreply.github.com> Date: Mon, 30 Oct 2023 14:31:07 +0530 Subject: [PATCH 02/93] chore: add yashasvibajpai and sanpj2292 to release workflow actors (#2778) --- .github/workflows/draft-new-release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/draft-new-release.yml b/.github/workflows/draft-new-release.yml index 0657561f2b..a0a558440a 100644 --- a/.github/workflows/draft-new-release.yml +++ b/.github/workflows/draft-new-release.yml @@ -8,7 +8,7 @@ jobs: runs-on: ubuntu-latest # Only allow release stakeholders to initiate releases - if: (github.ref == 'refs/heads/develop' || startsWith(github.ref, 'refs/heads/hotfix/')) && (github.actor == 'ItsSudip' || github.actor == 'krishna2020' || github.actor == 'saikumarrs' || github.actor == 'sandeepdsvs' || github.actor == 'shrouti1507' || github.actor == 'anantjain45823' || github.actor == 'chandumlg' || github.actor == 'mihir-4116') && (github.triggering_actor == 'ItsSudip' || github.triggering_actor == 'krishna2020' || github.triggering_actor == 'saikumarrs' || github.triggering_actor == 'sandeepdsvs' || github.triggering_actor == 'shrouti1507' || github.triggering_actor == 'anantjain45823' || github.triggering_actor == 'chandumlg' || github.triggering_actor == 'mihir-4116') + if: (github.ref == 'refs/heads/develop' || startsWith(github.ref, 'refs/heads/hotfix/')) && (github.actor == 'ItsSudip' || github.actor == 'krishna2020' || github.actor == 'saikumarrs' || github.actor == 'sandeepdsvs' || github.actor == 'shrouti1507' || github.actor == 'anantjain45823' || github.actor == 'chandumlg' || github.actor == 'mihir-4116' || github.actor == 'yashasvibajpai' || github.actor == 'sanpj2292') && (github.triggering_actor == 'ItsSudip' || github.triggering_actor == 'krishna2020' || github.triggering_actor == 'saikumarrs' || github.triggering_actor == 'sandeepdsvs' || github.triggering_actor == 'shrouti1507' || github.triggering_actor == 'anantjain45823' || github.triggering_actor == 'chandumlg' || github.triggering_actor == 'mihir-4116' || github.triggering_actor == 'yashasvibajpai' || github.triggering_actor == 'sanpj2292') steps: - name: Checkout uses: actions/checkout@v3.5.3 From a210cbdbf88fbe8e0faaaa0fea2740ae3467df5c Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Mon, 30 Oct 2023 09:10:59 +0000 Subject: [PATCH 03/93] chore(release): 1.47.0 --- CHANGELOG.md | 17 +++++++++++++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c52759ab48..e0db65c3c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,23 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +## [1.47.0](https://github.com/rudderlabs/rudder-transformer/compare/v1.46.5...v1.47.0) (2023-10-30) + + +### Features + +* add custom utm parameters to mixpanel ([#2771](https://github.com/rudderlabs/rudder-transformer/issues/2771)) ([9c4fcd3](https://github.com/rudderlabs/rudder-transformer/commit/9c4fcd3595534a8b563df3467e23c94c580f08a6)) +* add support filtering component tests by feature and index ([#2748](https://github.com/rudderlabs/rudder-transformer/issues/2748)) ([146f1c6](https://github.com/rudderlabs/rudder-transformer/commit/146f1c63db4e895c7d5ce2848a1b60e7c5bb9fb6)) +* onboard destination ortto ([#2730](https://github.com/rudderlabs/rudder-transformer/issues/2730)) ([9be5740](https://github.com/rudderlabs/rudder-transformer/commit/9be5740d8670890b0318da3d37f258ddc5e35445)) +* onboard facebook custom audience to transformer proxy ([#2769](https://github.com/rudderlabs/rudder-transformer/issues/2769)) ([14c5e40](https://github.com/rudderlabs/rudder-transformer/commit/14c5e40284af7df9e4f5b262ad226dd3afef226e)) + + +### Bug Fixes + +* bugsnag error for salesforce ([#2753](https://github.com/rudderlabs/rudder-transformer/issues/2753)) ([a2ccdad](https://github.com/rudderlabs/rudder-transformer/commit/a2ccdad52a1fb88f962745800cb45d605b5e0bf3)) +* oom kill while stringifying large response json ([#2754](https://github.com/rudderlabs/rudder-transformer/issues/2754)) ([c8baf5b](https://github.com/rudderlabs/rudder-transformer/commit/c8baf5b2b6325d9e30200339055dcbefd780936c)) +* salesforce: handle ECONNABORTED error ([#2732](https://github.com/rudderlabs/rudder-transformer/issues/2732)) ([6b23a9b](https://github.com/rudderlabs/rudder-transformer/commit/6b23a9b33acd28fdacaa2390c1970a1fa4415ffa)) + ### [1.46.5](https://github.com/rudderlabs/rudder-transformer/compare/v1.46.4...v1.46.5) (2023-10-23) diff --git a/package-lock.json b/package-lock.json index d399b529f8..4643d1325d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "rudder-transformer", - "version": "1.46.5", + "version": "1.47.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "rudder-transformer", - "version": "1.46.5", + "version": "1.47.0", "license": "ISC", "dependencies": { "@amplitude/ua-parser-js": "^0.7.24", diff --git a/package.json b/package.json index 8714141981..adc5f0e8f5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rudder-transformer", - "version": "1.46.5", + "version": "1.47.0", "description": "", "homepage": "https://github.com/rudderlabs/rudder-transformer#readme", "bugs": { From a586a92bf410679d0f3aa7012d4d10f8e2f515d5 Mon Sep 17 00:00:00 2001 From: Gauravudia <60897972+Gauravudia@users.noreply.github.com> Date: Mon, 30 Oct 2023 20:30:33 +0530 Subject: [PATCH 04/93] feat: add custom event name support in pinterest v5 (#2773) --- .../pinterest_tag/procWorkflow.yaml | 6 +- src/v0/destinations/pinterest_tag/utils.js | 18 ++--- test/__tests__/data/pinterest_tag_output.json | 65 +++++++++++++++++-- .../pinterest_tag/processor/data.ts | 60 ++++++++++++++--- .../destinations/pinterest_tag/step/data.ts | 61 ++++++++++++++--- 5 files changed, 169 insertions(+), 41 deletions(-) diff --git a/src/cdk/v2/destinations/pinterest_tag/procWorkflow.yaml b/src/cdk/v2/destinations/pinterest_tag/procWorkflow.yaml index 6854573cfa..e0b81e0afe 100644 --- a/src/cdk/v2/destinations/pinterest_tag/procWorkflow.yaml +++ b/src/cdk/v2/destinations/pinterest_tag/procWorkflow.yaml @@ -179,10 +179,8 @@ steps: eventNames = $.convertToSnakeCase(eventNames); eventNames.length === 0 ? eventNames = $.ecomEventMaps.(){eventInLowerCase in .src}.dest[] ?? []; (eventNames.length === 0 && .destination.Config.sendAsCustomEvent) ? eventNames = ["custom"]; - (eventNames.length === 0 && $.outputs.apiVersion === {{$.API_VERSION.v3}}) ? eventNames = [event]; - $.assertConfig(eventNames.length > 0, - event + " is not mapped in UI. Make sure to map the event in UI or enable the 'send as custom event' setting") - eventNames + eventNames.length === 0 ? eventNames = [event]; + eventNames; - name: payload template: | diff --git a/src/v0/destinations/pinterest_tag/utils.js b/src/v0/destinations/pinterest_tag/utils.js index c8ca8dabad..c6822636dc 100644 --- a/src/v0/destinations/pinterest_tag/utils.js +++ b/src/v0/destinations/pinterest_tag/utils.js @@ -165,7 +165,7 @@ const convertToSnakeCase = (eventName) => const deduceTrackScreenEventName = (message, Config) => { let eventName; const { event, name } = message; - const { apiVersion = API_VERSION.v3, eventsMapping, sendAsCustomEvent } = Config; + const { eventsMapping, sendAsCustomEvent } = Config; const trackEventOrScreenName = event || name; if (!trackEventOrScreenName) { throw new InstrumentationError('event_name could not be mapped. Aborting'); @@ -209,17 +209,11 @@ const deduceTrackScreenEventName = (message, Config) => { return ['custom']; } - if (apiVersion === API_VERSION.v3) { - /* - Step 4: In case both of the above stated cases fail, will send the event name as it is. - This is going to be reflected as "unknown" event in conversion API dashboard. - */ - return [trackEventOrScreenName]; - } - - throw new ConfigurationError( - `${event} is not mapped in UI. Make sure to map the event in UI or enable the 'send as custom event' setting`, - ); + /* + Step 4: In case all of the above stated cases failed, will send the event name as it is. + This is going to be reflected as "unknown" event in conversion API dashboard. + */ + return [trackEventOrScreenName]; }; /** diff --git a/test/__tests__/data/pinterest_tag_output.json b/test/__tests__/data/pinterest_tag_output.json index d09e534f4b..9fb809d112 100644 --- a/test/__tests__/data/pinterest_tag_output.json +++ b/test/__tests__/data/pinterest_tag_output.json @@ -671,7 +671,12 @@ "advertiser_id": "123456", "app_id": "429047995", "custom_data": { - "contents": [{ "item_price": "undefined", "quantity": 1 }], + "contents": [ + { + "item_price": "undefined", + "quantity": 1 + } + ], "currency": "USD", "num_items": 0, "order_id": "50314b8e9bcf000000000000", @@ -698,7 +703,9 @@ }, "endpoint": "https://ct.pinterest.com/events/v3", "files": {}, - "headers": { "Content-Type": "application/json" }, + "headers": { + "Content-Type": "application/json" + }, "method": "POST", "params": {}, "type": "REST", @@ -906,8 +913,54 @@ "statusCode": 400, "error": "Conversion Token not found. Aborting" }, - { - "statusCode": 400, - "error": "custom event is not mapped in UI. Make sure to map the event in UI or enable the 'send as custom event' setting" - } + [ + { + "version": "1", + "type": "REST", + "method": "POST", + "endpoint": "https://api.pinterest.com/v5/ad_accounts/accountId123/events", + "headers": { + "Content-Type": "application/json", + "Authorization": "Bearer conversionToken123" + }, + "params": {}, + "body": { + "JSON": { + "event_name": "custom event", + "event_time": 1597383030, + "action_source": "web", + "event_id": "7208bbb6-2c4e-45bb-bf5b-ad426f3593e9", + "app_id": "429047995", + "user_data": { + "em": ["48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08"], + "ph": ["d164bbe036663cb5c96835e9ccc6501e9a521127ea62f6359744928ba932413b"], + "ln": ["dcf000c2386fb76d22cefc0d118a8511bb75999019cd373df52044bccd1bd251"], + "fn": ["9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"], + "ct": ["6689106ca7922c30b2fd2c175c85bc7fc2d52cc4941bdd7bb622c6cdc6284a85"], + "st": ["3b45022ab36728cdae12e709e945bba267c50ee8a91e6e4388539a8e03a3fdcd"], + "zp": ["1a4292e00780e18d00e76fde9850aee5344e939ba593333cd5e4b4aa2cd33b0c"], + "country": ["582967534d0f909d196b97f9e6921342777aea87b46fa52df165389db1fb8ccf"], + "hashed_maids": ["6ca13d52ca70c883e0f0bb101e425a89e8624de51db2d2392593af6a84118090"], + "client_user_agent": "chrome" + }, + "custom_data": { + "currency": "USD", + "value": "27.5", + "order_id": "50314b8e9bcf000000000000", + "num_items": 0, + "contents": [ + { + "quantity": 1, + "item_price": "undefined" + } + ] + } + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "files": {} + } + ] ] diff --git a/test/integrations/destinations/pinterest_tag/processor/data.ts b/test/integrations/destinations/pinterest_tag/processor/data.ts index 344d4ff507..c7f482aadd 100644 --- a/test/integrations/destinations/pinterest_tag/processor/data.ts +++ b/test/integrations/destinations/pinterest_tag/processor/data.ts @@ -3417,16 +3417,58 @@ export const data = [ body: [ { metadata: { destintionId: '1pYpzzvcn7AQ2W9GGIAZSsN6Mfq' }, - error: - "custom event is not mapped in UI. Make sure to map the event in UI or enable the 'send as custom event' setting: Workflow: procWorkflow, Step: eventNames, ChildStep: undefined, OriginalError: custom event is not mapped in UI. Make sure to map the event in UI or enable the 'send as custom event' setting", - statTags: { - destType: 'PINTEREST_TAG', - errorCategory: 'platform', - feature: 'processor', - implementation: 'cdkV2', - module: 'destination', + output: { + body: { + JSON: { + event_time: 1597383030, + action_source: 'web', + event_id: '7208bbb6-2c4e-45bb-bf5b-ad426f3593e9', + app_id: '429047995', + user_data: { + em: ['48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08'], + ph: ['d164bbe036663cb5c96835e9ccc6501e9a521127ea62f6359744928ba932413b'], + ln: ['dcf000c2386fb76d22cefc0d118a8511bb75999019cd373df52044bccd1bd251'], + fn: ['9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08'], + ct: ['6689106ca7922c30b2fd2c175c85bc7fc2d52cc4941bdd7bb622c6cdc6284a85'], + st: ['3b45022ab36728cdae12e709e945bba267c50ee8a91e6e4388539a8e03a3fdcd'], + zp: ['1a4292e00780e18d00e76fde9850aee5344e939ba593333cd5e4b4aa2cd33b0c'], + country: ['582967534d0f909d196b97f9e6921342777aea87b46fa52df165389db1fb8ccf'], + hashed_maids: [ + '6ca13d52ca70c883e0f0bb101e425a89e8624de51db2d2392593af6a84118090', + ], + client_user_agent: 'chrome', + }, + custom_data: { + num_items: 0, + contents: [ + { + quantity: 1, + item_price: 'undefined', + }, + ], + currency: 'USD', + value: '27.5', + order_id: '50314b8e9bcf000000000000', + }, + event_name: 'custom event', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.pinterest.com/v5/ad_accounts/accountId123/events', + headers: { + 'Content-Type': 'application/json', + Authorization: 'Bearer conversionToken123', + }, + params: {}, + files: {}, + userId: '', }, - statusCode: 400, + statusCode: 200, }, ], }, diff --git a/test/integrations/destinations/pinterest_tag/step/data.ts b/test/integrations/destinations/pinterest_tag/step/data.ts index b5d6f5186f..cbd0b243bb 100644 --- a/test/integrations/destinations/pinterest_tag/step/data.ts +++ b/test/integrations/destinations/pinterest_tag/step/data.ts @@ -3339,17 +3339,58 @@ export const data = [ status: 200, body: [ { - error: - "custom event is not mapped in UI. Make sure to map the event in UI or enable the 'send as custom event' setting", - statTags: { - destType: 'PINTEREST_TAG', - errorCategory: 'dataValidation', - errorType: 'configuration', - feature: 'processor', - implementation: 'native', - module: 'destination', + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.pinterest.com/v5/ad_accounts/accountId123/events', + headers: { + 'Content-Type': 'application/json', + Authorization: 'Bearer conversionToken123', + }, + params: {}, + body: { + JSON: { + event_name: 'custom event', + event_time: 1597383030, + action_source: 'web', + event_id: '7208bbb6-2c4e-45bb-bf5b-ad426f3593e9', + app_id: '429047995', + user_data: { + em: ['48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08'], + ph: ['d164bbe036663cb5c96835e9ccc6501e9a521127ea62f6359744928ba932413b'], + ln: ['dcf000c2386fb76d22cefc0d118a8511bb75999019cd373df52044bccd1bd251'], + fn: ['9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08'], + ct: ['6689106ca7922c30b2fd2c175c85bc7fc2d52cc4941bdd7bb622c6cdc6284a85'], + st: ['3b45022ab36728cdae12e709e945bba267c50ee8a91e6e4388539a8e03a3fdcd'], + zp: ['1a4292e00780e18d00e76fde9850aee5344e939ba593333cd5e4b4aa2cd33b0c'], + country: ['582967534d0f909d196b97f9e6921342777aea87b46fa52df165389db1fb8ccf'], + hashed_maids: [ + '6ca13d52ca70c883e0f0bb101e425a89e8624de51db2d2392593af6a84118090', + ], + client_user_agent: 'chrome', + }, + custom_data: { + currency: 'USD', + value: '27.5', + order_id: '50314b8e9bcf000000000000', + num_items: 0, + contents: [ + { + quantity: 1, + item_price: 'undefined', + }, + ], + }, + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', }, - statusCode: 400, + statusCode: 200, }, ], }, From f641a1e18355e84215981f905870bc6d7c4bc9ea Mon Sep 17 00:00:00 2001 From: Gauravudia <60897972+Gauravudia@users.noreply.github.com> Date: Tue, 31 Oct 2023 12:09:04 +0530 Subject: [PATCH 05/93] chore: update changelog for pinterest custom event name support (#2781) --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e0db65c3c2..e7d295645f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ All notable changes to this project will be documented in this file. See [standa * add support filtering component tests by feature and index ([#2748](https://github.com/rudderlabs/rudder-transformer/issues/2748)) ([146f1c6](https://github.com/rudderlabs/rudder-transformer/commit/146f1c63db4e895c7d5ce2848a1b60e7c5bb9fb6)) * onboard destination ortto ([#2730](https://github.com/rudderlabs/rudder-transformer/issues/2730)) ([9be5740](https://github.com/rudderlabs/rudder-transformer/commit/9be5740d8670890b0318da3d37f258ddc5e35445)) * onboard facebook custom audience to transformer proxy ([#2769](https://github.com/rudderlabs/rudder-transformer/issues/2769)) ([14c5e40](https://github.com/rudderlabs/rudder-transformer/commit/14c5e40284af7df9e4f5b262ad226dd3afef226e)) +* add custom event name support in pinterest v5 ([#2773](https://github.com/rudderlabs/rudder-transformer/pull/2773)) ([a586a92](https://github.com/rudderlabs/rudder-transformer/commit/a586a92bf410679d0f3aa7012d4d10f8e2f515d5)) ### Bug Fixes From 57fee0496f718837768f493eb4e204e948c34554 Mon Sep 17 00:00:00 2001 From: Anant Jain <62471433+anantjain45823@users.noreply.github.com> Date: Thu, 2 Nov 2023 11:25:09 +0530 Subject: [PATCH 06/93] chore: refactoring amplitude using optional chaining (#2645) * chore: refactoring amplitude using optional chaining * test cases added for source endpoint * chore: minor fixes * chore: comment addressed * chore: solve sonar issues 1 * chore: solve sonar issues 2 * chore: solve sonar issues 3 * chore: resolve sonar hotspot * chore: resolve sonar * chore: solve sonar issues 4 * chore: small fixes and test cases addition * chore: small fixes and test cases addition+1 * chore: merge develop issue fix * Update src/v0/destinations/am/transform.js Co-authored-by: Sankeerth * Update src/v0/destinations/am/transform.js Co-authored-by: Sankeerth * chore: addressed comments * chore: reduce cognitive complexity+1 * chore: add test cases * chore: addressed comments * chore: addressed comments+1 * chore: comments addressed * chore: comments addressed+1 * chore: resolve sonar * chore: comments addressed+2 * sonarcloud fix+1 --------- Co-authored-by: Sai Sankeerth Co-authored-by: Sankeerth --- src/v0/destinations/am/config.js | 5 +- src/v0/destinations/am/transform.js | 742 ++++++++++++---------- src/v0/destinations/am/utils.js | 32 +- src/v0/util/index.js | 11 + src/v0/util/index.test.js | 1 + src/v0/util/testdata/isValidInteger.json | 31 + test/__tests__/data/am_batch_input.json | 63 ++ test/__tests__/data/am_batch_output.json | 59 +- test/__tests__/data/am_input.json | 376 ++++++++++- test/__tests__/data/am_output.json | 323 +++++++++- test/__tests__/data/am_router_output.json | 4 +- 11 files changed, 1224 insertions(+), 423 deletions(-) create mode 100644 src/v0/util/testdata/isValidInteger.json diff --git a/src/v0/destinations/am/config.js b/src/v0/destinations/am/config.js index 5e6fc06c27..3e51a67137 100644 --- a/src/v0/destinations/am/config.js +++ b/src/v0/destinations/am/config.js @@ -122,7 +122,8 @@ events.forEach((event) => { const DELETE_MAX_BATCH_SIZE = 100; const DESTINATION = 'amplitude'; const IDENTIFY_AM = '$identify'; - +const AMBatchSizeLimit = 20 * 1024 * 1024; // 20 MB +const AMBatchEventLimit = 500; // event size limit from sdk is 32KB => 15MB module.exports = { DESTINATION, Event, @@ -134,4 +135,6 @@ module.exports = { DELETE_MAX_BATCH_SIZE, batchEventsWithUserIdLengthLowerThanFive, IDENTIFY_AM, + AMBatchSizeLimit, + AMBatchEventLimit }; diff --git a/src/v0/destinations/am/transform.js b/src/v0/destinations/am/transform.js index e6ccf585df..b74625e273 100644 --- a/src/v0/destinations/am/transform.js +++ b/src/v0/destinations/am/transform.js @@ -1,6 +1,7 @@ /* eslint-disable no-lonely-if */ /* eslint-disable no-nested-ternary */ /* eslint-disable no-param-reassign */ +const cloneDeep = require('lodash/cloneDeep'); const get = require('get-value'); const set = require('set-value'); const { @@ -26,6 +27,7 @@ const { isAppleFamily, isDefinedAndNotNullAndNotEmpty, simpleProcessRouterDest, + isValidInteger, } = require('../../util'); const { BASE_URL, @@ -34,18 +36,17 @@ const { mappingConfig, batchEventsWithUserIdLengthLowerThanFive, IDENTIFY_AM, + AMBatchSizeLimit, + AMBatchEventLimit, } = require('./config'); const tags = require('../../util/tags'); const AMUtils = require('./utils'); const logger = require('../../../logger'); -const { InstrumentationError } = require('../../util/errorTypes'); +const { InstrumentationError, ConfigurationError } = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); -const AMBatchSizeLimit = 20 * 1024 * 1024; // 20 MB -const AMBatchEventLimit = 500; // event size limit from sdk is 32KB => 15MB - const EVENTS_KEY_PATH = 'body.JSON.events'; const baseEndpoint = (destConfig) => { @@ -79,82 +80,96 @@ const aliasEndpoint = (destConfig) => { return retVal; }; -function handleSessionIdUnderRoot(message) { - const sessionId = get(message, 'session_id'); +const handleSessionIdUnderRoot = (sessionId) => { if (typeof sessionId === 'string') { - return sessionId.substr(sessionId.lastIndexOf(':') + 1, sessionId.length); + const extractedPart = sessionId.split(':').reverse(); + if (!isValidInteger(extractedPart[0])) return -1; + return Number(extractedPart[0]); } - return sessionId; -} + return Number(sessionId); +}; -function handleSessionIdUnderContext(message) { - let sessionId = get(message, 'context.sessionId'); - sessionId = Number(sessionId); - if (Number.isNaN(sessionId)) return -1; - return sessionId; -} +const handleSessionIdUnderContext = (sessionId) => { + if (!isValidInteger(sessionId)) return -1; + return Number(sessionId); +}; -function getSessionId(message) { - return get(message, 'session_id') - ? handleSessionIdUnderRoot(message) - : get(message, 'context.sessionId') - ? handleSessionIdUnderContext(message) - : -1; -} +const checkForJSONAndUserIdLengthAndDeviceId = (jsonBody, userId, deviceId) => + Object.keys(jsonBody).length === 0 || + (userId && + userId.length < 5 && + (!batchEventsWithUserIdLengthLowerThanFive || + (batchEventsWithUserIdLengthLowerThanFive && !deviceId))); +const getSessionId = (message) => { + let sessionId = -1; + const rootSessionId = get(message, 'session_id'); + if (rootSessionId) { + sessionId = handleSessionIdUnderRoot(rootSessionId); + if (sessionId !== -1) { + return sessionId; + } + } + const contextSessionId = get(message, 'context.sessionId'); + if (contextSessionId) { + sessionId = handleSessionIdUnderContext(contextSessionId); + } + return sessionId; +}; -function addMinIdlength() { - return { min_id_length: 1 }; -} +const addMinIdlength = () => ({ min_id_length: 1 }); -function setPriceQuanityInPayload(message, rawPayload) { +const setPriceQuanityInPayload = (message, rawPayload) => { let price; let quantity; - if (isDefinedAndNotNull(message.properties.price)) { + if (isDefinedAndNotNull(message.properties?.price)) { price = message.properties.price; - quantity = message.properties.quantity || 1; + quantity = message.properties?.quantity || 1; } else { - price = message.properties.revenue; + price = message.properties?.revenue; quantity = 1; } rawPayload.price = price; rawPayload.quantity = quantity; - rawPayload.revenue = message.properties.revenue; + rawPayload.revenue = message.properties?.revenue; return rawPayload; -} +}; -function createRevenuePayload(message, rawPayload) { - rawPayload.productId = message.properties.product_id; +const createRevenuePayload = (message, rawPayload) => { + rawPayload.productId = message.properties?.product_id; rawPayload.revenueType = - message.properties.revenueType || message.properties.revenue_type || 'Purchased'; + message.properties?.revenueType || message.properties?.revenue_type || 'Purchased'; rawPayload = setPriceQuanityInPayload(message, rawPayload); return rawPayload; -} +}; -function updateTraitsObject(property, traitsObject, actionKey) { +const updateTraitsObject = (property, traitsObject, actionKey) => { const propertyToUpdate = getValueFromMessage(traitsObject, property); if (traitsObject[actionKey] && property && typeof property === 'string') { traitsObject[actionKey][property] = propertyToUpdate; deleteObjectProperty(traitsObject, property); } return traitsObject; -} +}; -function prepareTraitsConfig(configPropertyTrait, actionKey, traitsObject) { +const prepareTraitsConfig = (configPropertyTrait, actionKey, traitsObject) => { traitsObject[actionKey] = {}; configPropertyTrait.forEach((traitsElement) => { - const property = traitsElement.traits; + const property = traitsElement?.traits; traitsObject = updateTraitsObject(property, traitsObject, actionKey); }); - if (Object.keys(traitsObject[actionKey]).length === 0) { + if ( + typeof traitsObject?.[actionKey] === 'object' && + Object.keys(traitsObject?.[actionKey] || {})?.length === 0 + ) { delete traitsObject[actionKey]; } return traitsObject; -} +}; -function handleTraits(messageTrait, destination) { +const handleTraits = (messageTrait, destination) => { let traitsObject = JSON.parse(JSON.stringify(messageTrait)); - if (destination.Config.traitsToIncrement) { + if (destination.Config?.traitsToIncrement) { const actionKey = '$add'; traitsObject = prepareTraitsConfig( destination.Config.traitsToIncrement, @@ -162,29 +177,41 @@ function handleTraits(messageTrait, destination) { traitsObject, ); } - if (destination.Config.traitsToSetOnce) { + if (destination.Config?.traitsToSetOnce) { const actionKey = '$setOnce'; traitsObject = prepareTraitsConfig(destination.Config.traitsToSetOnce, actionKey, traitsObject); } - if (destination.Config.traitsToAppend) { + if (destination.Config?.traitsToAppend) { const actionKey = '$append'; traitsObject = prepareTraitsConfig(destination.Config.traitsToAppend, actionKey, traitsObject); } - if (destination.Config.traitsToPrepend) { + if (destination.Config?.traitsToPrepend) { const actionKey = '$prepend'; traitsObject = prepareTraitsConfig(destination.Config.traitsToPrepend, actionKey, traitsObject); } return traitsObject; -} +}; + +const getScreenevTypeAndUpdatedProperties = (message, CATEGORY_KEY) => { + const name = message.name || message.event || get(message, CATEGORY_KEY); + const updatedName = name ? `${name} ` : ''; + return { + evType: `Viewed ${updatedName}Screen`, + updatedProperties: { + ...message.properties, + name, + }, + }; +}; -function handleMappingJsonObject( +const handleMappingJsonObject = ( mappingJson, sourceKey, validatePayload, payload, message, Config, -) { +) => { const { isFunc, funcName, outKey } = mappingJson[sourceKey]; if (isFunc) { if (validatePayload) { @@ -203,150 +230,242 @@ function handleMappingJsonObject( if (isDefinedAndNotNull(data)) { set(payload, outKey, data); delete message.traits[outKey]; - } else { - // get the destKey/outKey value from calling the util function - set(payload, outKey, AMUtils[funcName](message, sourceKey, Config)); + return; } + // get the destKey/outKey value from calling the util function + set(payload, outKey, AMUtils[funcName](message, sourceKey, Config)); } } -} +}; -function updateConfigProperty(message, payload, mappingJson, validatePayload, Config) { +const updateConfigProperty = (message, payload, mappingJson, validatePayload, Config) => { const sourceKeys = Object.keys(mappingJson); sourceKeys.forEach((sourceKey) => { // check if custom processing is required on the payload sourceKey ==> destKey if (typeof mappingJson[sourceKey] === 'object') { handleMappingJsonObject(mappingJson, sourceKey, validatePayload, payload, message, Config); - } else { - // For common config - if (validatePayload) { - // if data is present in traits assign - const messageData = get(message.traits, mappingJson[sourceKey]); - if (isDefinedAndNotNull(messageData)) { - set(payload, mappingJson[sourceKey], messageData); - } else { - const data = get(payload, mappingJson[sourceKey]); - if (!isDefinedAndNotNull(data)) { - const val = get(message, sourceKey); - if (val || val === false || val === 0) { - set(payload, mappingJson[sourceKey], val); - } + } else if (validatePayload) { + // if data is present in traits assign + const messageData = get(message.traits, mappingJson[sourceKey]); + if (isDefinedAndNotNull(messageData)) { + set(payload, mappingJson[sourceKey], messageData); + } else { + const data = get(payload, mappingJson[sourceKey]); + if (!isDefinedAndNotNull(data)) { + const val = get(message, sourceKey); + if (val || val === false || val === 0) { + set(payload, mappingJson[sourceKey], val); } } + } + } else { + const data = get(message.traits, mappingJson[sourceKey]); + if (isDefinedAndNotNull(data)) { + set(payload, mappingJson[sourceKey], data); } else { - const data = get(message.traits, mappingJson[sourceKey]); - if (isDefinedAndNotNull(data)) { - set(payload, mappingJson[sourceKey], data); - } else { - set(payload, mappingJson[sourceKey], get(message, sourceKey)); - } + set(payload, mappingJson[sourceKey], get(message, sourceKey)); } } }); -} +}; +const identifyBuilder = (message, destination, rawPayload) => { + // update payload user_properties from userProperties/traits/context.traits/nested traits of Rudder message + // traits like address converted to top level user properties (think we can skip this extra processing as AM supports nesting upto 40 levels) + let traits = getFieldValueFromMessage(message, 'traits'); + if (traits) { + traits = handleTraits(traits, destination); + } + rawPayload.user_properties = { + ...rawPayload.user_properties, + ...message.userProperties, + }; + if (traits) { + Object.keys(traits).forEach((trait) => { + if (SpecedTraits.includes(trait)) { + const mapping = TraitsMapping[trait]; + Object.keys(mapping).forEach((key) => { + const checkKey = get(rawPayload.user_properties, key); + // this is done only if we want to add default values under address to the user_properties + // these values are also sent to the destination at the top level. + if (!isDefinedAndNotNull(checkKey)) { + set(rawPayload, `user_properties.${key}`, get(traits, mapping[key])); + } + }); + } else { + set(rawPayload, `user_properties.${trait}`, get(traits, trait)); + } + }); + } + return rawPayload; +}; -function getResponseData(evType, destination, rawPayload, message, groupInfo) { - let endpoint = defaultEndpoint(destination.Config); - let traits; +const getDefaultResponseData = (message, rawPayload, evType, groupInfo) => { + const traits = getFieldValueFromMessage(message, 'traits'); + set(rawPayload, 'event_properties', message.properties); + + if (traits) { + rawPayload.user_properties = { + ...rawPayload.user_properties, + ...traits, + }; + } + + rawPayload.event_type = evType; + rawPayload.user_id = message.userId; + if (message.isRevenue) { + // making the revenue payload + rawPayload = createRevenuePayload(message, rawPayload); + // deleting the properties price, product_id, quantity and revenue from event_properties since it is already in root + if (rawPayload.event_properties) { + delete rawPayload.event_properties.price; + delete rawPayload.event_properties.product_id; + delete rawPayload.event_properties.quantity; + delete rawPayload.event_properties.revenue; + } + } + const groups = groupInfo && cloneDeep(groupInfo); + return { groups, rawPayload }; +}; +const getResponseData = (evType, destination, rawPayload, message, groupInfo) => { let groups; switch (evType) { case EventType.IDENTIFY: + // event_type for identify event is $identify + rawPayload.event_type = IDENTIFY_AM; + identifyBuilder(message, destination, rawPayload); + break; case EventType.GROUP: - endpoint = defaultEndpoint(destination.Config); // event_type for identify event is $identify rawPayload.event_type = IDENTIFY_AM; - - if (evType === EventType.IDENTIFY) { - // update payload user_properties from userProperties/traits/context.traits/nested traits of Rudder message - // traits like address converted to top level user properties (think we can skip this extra processing as AM supports nesting upto 40 levels) - traits = getFieldValueFromMessage(message, 'traits'); - if (traits) { - traits = handleTraits(traits, destination); - } - rawPayload.user_properties = { - ...rawPayload.user_properties, - ...message.userProperties, - }; - if (traits) { - Object.keys(traits).forEach((trait) => { - if (SpecedTraits.includes(trait)) { - const mapping = TraitsMapping[trait]; - Object.keys(mapping).forEach((key) => { - const checkKey = get(rawPayload.user_properties, key); - // this is done only if we want to add default values under address to the user_properties - // these values are also sent to the destination at the top level. - if (!isDefinedAndNotNull(checkKey)) { - set(rawPayload, `user_properties.${key}`, get(traits, mapping[key])); - } - }); - } else { - set(rawPayload, `user_properties.${trait}`, get(traits, trait)); - } - }); - } - } - - if ( - evType === EventType.GROUP && // for Rudder group call, update the user_properties with group info - // Refer (1.) - groupInfo && - groupInfo.group_type && - groupInfo.group_value - ) { + // for Rudder group call, update the user_properties with group info + if (groupInfo?.group_type && groupInfo?.group_value) { groups = {}; groups[groupInfo.group_type] = groupInfo.group_value; set(rawPayload, `user_properties.${[groupInfo.group_type]}`, groupInfo.group_value); } break; case EventType.ALIAS: - endpoint = aliasEndpoint(destination.Config); break; default: - traits = getFieldValueFromMessage(message, 'traits'); - set(rawPayload, 'event_properties', message.properties); - - if (traits) { - rawPayload.user_properties = { - ...rawPayload.user_properties, - ...traits, - }; - } + ({ groups, rawPayload } = getDefaultResponseData(message, rawPayload, evType, groupInfo)); + } + return { rawPayload, groups }; +}; - rawPayload.event_type = evType; - rawPayload.user_id = message.userId; - if (message.isRevenue) { - // making the revenue payload - rawPayload = createRevenuePayload(message, rawPayload); - // deleting the properties price, product_id, quantity and revenue from event_properties since it is already in root - if (rawPayload.event_properties) { - delete rawPayload.event_properties.price; - delete rawPayload.event_properties.product_id; - delete rawPayload.event_properties.quantity; - delete rawPayload.event_properties.revenue; - } - } - groups = groupInfo && Object.assign(groupInfo); +const buildPayloadForMobileChannel = (message, destination, payload) => { + if (!destination.Config.mapDeviceBrand) { + set(payload, 'device_brand', get(message, 'context.device.manufacturer')); } - return { endpoint, rawPayload, groups }; -} -function responseBuilderSimple( + const deviceId = get(message, 'context.device.id'); + const platform = get(message, 'context.device.type'); + const advertId = get(message, 'context.device.advertisingId'); + + if (platform) { + if (isAppleFamily(platform)) { + set(payload, 'idfa', advertId); + set(payload, 'idfv', deviceId); + } else if (platform.toLowerCase() === 'android') { + set(payload, 'adid', advertId); + } + } +}; +const nonAliasResponsebuilder = ( + message, + payload, + destination, + evType, + groupInfo, + rootElementName, +) => { + const respList = []; + const addOptions = 'options'; + const response = defaultRequestConfig(); + const groupResponse = defaultRequestConfig(); + const endpoint = defaultEndpoint(destination.Config); + if (message.channel === 'mobile') { + buildPayloadForMobileChannel(message, destination, payload); + } + payload.time = new Date(getFieldValueFromMessage(message, 'timestamp')).getTime(); + + // send user_id only when present, for anonymous users not required + if (message.userId && message.userId !== null) { + payload.user_id = message.userId; + } + payload.session_id = getSessionId(message); + + updateConfigProperty( + message, + payload, + mappingConfig[ConfigCategory.COMMON_CONFIG.name], + true, + destination.Config, + ); + + // we are not fixing the verson for android specifically any more because we've put a fix in iOS SDK + // for correct versionName + // ==================== + // fixVersion(payload, message); + + if (payload.user_properties) { + delete payload.user_properties.city; + delete payload.user_properties.country; + if (payload.user_properties.address) { + delete payload.user_properties.address.city; + delete payload.user_properties.address.country; + } + } + + if (!payload.user_id && !payload.device_id) { + logger.debug('Either of user ID or device ID fields must be specified'); + throw new InstrumentationError('Either of user ID or device ID fields must be specified'); + } + + payload.ip = getParsedIP(message); + payload.library = 'rudderstack'; + payload = removeUndefinedAndNullValues(payload); + response.endpoint = endpoint; + response.method = defaultPostRequestConfig.requestMethod; + response.headers = { + 'Content-Type': JSON_MIME_TYPE, + }; + response.userId = message.anonymousId; + response.body.JSON = { + api_key: destination.Config.apiKey, + [rootElementName]: [payload], + [addOptions]: addMinIdlength(), + }; + respList.push(response); + + // https://developers.amplitude.com/docs/group-identify-api + // Refer (1.), Rudder group call updates group propertiees. + if (evType === EventType.GROUP && groupInfo) { + groupResponse.method = defaultPostRequestConfig.requestMethod; + groupResponse.endpoint = groupEndpoint(destination.Config); + let groupPayload = cloneDeep(groupInfo); + groupResponse.userId = message.anonymousId; + groupPayload = removeUndefinedValues(groupPayload); + groupResponse.body.FORM = { + api_key: destination.Config.apiKey, + identification: [JSON.stringify(groupPayload)], + }; + respList.push(groupResponse); + } + return respList; +}; + +const responseBuilderSimple = ( groupInfo, rootElementName, message, evType, mappingJson, destination, -) { - let rawPayload = {}; - const addOptions = 'options'; +) => { + const rawPayload = {}; const respList = []; - const response = defaultRequestConfig(); - const groupResponse = defaultRequestConfig(); const aliasResponse = defaultRequestConfig(); - let endpoint = defaultEndpoint(destination.Config); - if ( EventType.IDENTIFY && // If mapped to destination, Add externalId to traits get(message, MappedToDestinationKey) @@ -375,7 +494,7 @@ function responseBuilderSimple( const oldKeys = Object.keys(campaign); // appends utm_ prefix to all the keys of campaign object. For example the `name` key in campaign object will be changed to `utm_name` oldKeys.forEach((oldKey) => { - Object.assign(campaign, { [`utm_${oldKey}`]: campaign[oldKey] }); + campaign[`utm_${oldKey}`] = campaign[oldKey]; delete campaign[oldKey]; }); @@ -390,14 +509,13 @@ function responseBuilderSimple( }; const respData = getResponseData(evType, destination, rawPayload, message, groupInfo); - const { groups } = respData; - ({ endpoint, rawPayload } = respData); + const { groups, rawPayload: updatedRawPayload } = respData; // for https://api.amplitude.com/2/httpapi , pass the "groups" key // refer (1.) for passing "groups" for Rudder group call // https://developers.amplitude.com/docs/http-api-v2#schemaevent - set(rawPayload, 'groups', groups); - let payload = removeUndefinedValues(rawPayload); + set(updatedRawPayload, 'groups', groups); + let payload = removeUndefinedValues(updatedRawPayload); let unmapUserId; if (evType === EventType.ALIAS) { // By default (1.), Alias config file populates user_id and global_user_id @@ -419,113 +537,60 @@ function responseBuilderSimple( }; respList.push(aliasResponse); } else { - if (message.channel === 'mobile') { - if (!destination.Config.mapDeviceBrand) { - set(payload, 'device_brand', get(message, 'context.device.manufacturer')); - } - - const deviceId = get(message, 'context.device.id'); - const platform = get(message, 'context.device.type'); - const advertId = get(message, 'context.device.advertisingId'); - - if (platform) { - if (isAppleFamily(platform)) { - set(payload, 'idfa', advertId); - set(payload, 'idfv', deviceId); - } else if (platform.toLowerCase() === 'android') { - set(payload, 'adid', advertId); - } - } - } - - payload.time = new Date(getFieldValueFromMessage(message, 'timestamp')).getTime(); - - // send user_id only when present, for anonymous users not required - if ( - message.userId && - message.userId !== '' && - message.userId !== 'null' && - message.userId !== null - ) { - payload.user_id = message.userId; - } - payload.session_id = getSessionId(message); - - updateConfigProperty( + return nonAliasResponsebuilder( message, payload, - mappingConfig[ConfigCategory.COMMON_CONFIG.name], - true, - destination.Config, + destination, + evType, + groupInfo, + rootElementName, ); + } + return respList; +}; - // we are not fixing the verson for android specifically any more because we've put a fix in iOS SDK - // for correct versionName - // ==================== - // fixVersion(payload, message); - - if (payload.user_properties) { - delete payload.user_properties.city; - delete payload.user_properties.country; - if (payload.user_properties.address) { - delete payload.user_properties.address.city; - delete payload.user_properties.address.country; - } - } - - if (!payload.user_id && !payload.device_id) { - logger.debug('Either of user ID or device ID fields must be specified'); - throw new InstrumentationError('Either of user ID or device ID fields must be specified'); - } - - payload.ip = getParsedIP(message); - payload.library = 'rudderstack'; - payload = removeUndefinedAndNullValues(payload); - response.endpoint = endpoint; - response.method = defaultPostRequestConfig.requestMethod; - response.headers = { - 'Content-Type': JSON_MIME_TYPE, - }; - response.userId = message.anonymousId; - response.body.JSON = { - api_key: destination.Config.apiKey, - [rootElementName]: [payload], - [addOptions]: addMinIdlength(), - }; - respList.push(response); - - // https://developers.amplitude.com/docs/group-identify-api - // Refer (1.), Rudder group call updates group propertiees. - if (evType === EventType.GROUP && groupInfo) { - groupResponse.method = defaultPostRequestConfig.requestMethod; - groupResponse.endpoint = groupEndpoint(destination.Config); - let groupPayload = Object.assign(groupInfo); - groupResponse.userId = message.anonymousId; - groupPayload = removeUndefinedValues(groupPayload); - groupResponse.body.FORM = { - api_key: destination.Config.apiKey, - identification: [JSON.stringify(groupPayload)], - }; - respList.push(groupResponse); +const getGroupInfo = (destination, groupInfo, groupTraits) => { + const { groupTypeTrait, groupValueTrait } = destination.Config; + if (groupTypeTrait && groupValueTrait) { + let updatedGroupInfo = { ...groupInfo }; + const groupTypeValue = get(groupTraits, groupTypeTrait); + const groupNameValue = get(groupTraits, groupValueTrait); + // since the property updates on group at https://api2.amplitude.com/groupidentify + // expects a string group name and value , so error out if the keys are not primitive + // Note: This different for groups object at https://api.amplitude.com/2/httpapi where the + // group value can be array of strings as well. + if ( + groupTypeValue && + typeof groupTypeValue === 'string' && + groupNameValue && + (typeof groupNameValue === 'string' || typeof groupNameValue === 'number') + ) { + updatedGroupInfo = {}; + updatedGroupInfo.group_type = groupTypeValue; + updatedGroupInfo.group_value = groupNameValue; + // passing the entire group traits without deleting the above keys + updatedGroupInfo.group_properties = groupTraits; + return updatedGroupInfo; } + logger.debug('Group call parameters are not valid'); + throw new InstrumentationError('Group call parameters are not valid'); } - - return respList; -} + return groupInfo; +}; +const getUpdatedPageNameWithoutUserDefinedPageEventName = (name, message, CATEGORY_KEY) => + name || get(message, CATEGORY_KEY) ? `${name || get(message, CATEGORY_KEY)} ` : undefined; // Generic process function which invokes specific handler functions depending on message type // and event type where applicable -function processSingleMessage(message, destination) { +const processSingleMessage = (message, destination) => { let payloadObjectName = 'events'; let evType; - let groupTraits; - let groupTypeTrait; - let groupValueTrait; // It is expected that Rudder alias. identify group calls won't have this set // To be used for track/page calls to associate the event to a group in AM let groupInfo = get(message, 'integrations.Amplitude.groups') || undefined; let category = ConfigCategory.DEFAULT; - + let { properties } = message; + const { name, event } = message; const messageType = message.type.toLowerCase(); const CATEGORY_KEY = 'properties.category'; const { useUserDefinedPageEventName, userProvidedPageEventString } = destination.Config; @@ -545,26 +610,30 @@ function processSingleMessage(message, destination) { .trim(); evType = userProvidedPageEventString.trim() === '' - ? message.name + ? name : userProvidedPageEventString .trim() .replaceAll(/{{([^{}]+)}}/g, get(message, getMessagePath)); } else { - evType = `Viewed ${message.name || get(message, CATEGORY_KEY) || ''} Page`; + const updatedName = getUpdatedPageNameWithoutUserDefinedPageEventName( + name, + message, + CATEGORY_KEY, + ); + evType = `Viewed ${updatedName || ''}Page`; } - message.properties = { ...message.properties, - name: message.name || get(message, CATEGORY_KEY), + name: name || get(message, CATEGORY_KEY), }; category = ConfigCategory.PAGE; break; case EventType.SCREEN: - evType = `Viewed ${message.name || message.event || get(message, CATEGORY_KEY) || ''} Screen`; - message.properties = { - ...message.properties, - name: message.name || message.event || get(message, CATEGORY_KEY), - }; + ({ evType, updatedProperties: properties } = getScreenevTypeAndUpdatedProperties( + message, + CATEGORY_KEY, + )); + message.properties = properties; category = ConfigCategory.SCREEN; break; case EventType.GROUP: @@ -574,34 +643,13 @@ function processSingleMessage(message, destination) { // read from group traits from message // groupTraits => top level "traits" for JS SDK // groupTraits => "context.traits" for mobile SDKs - groupTraits = getFieldValueFromMessage(message, 'groupTraits'); + groupInfo = getGroupInfo( + destination, + groupInfo, + getFieldValueFromMessage(message, 'groupTraits'), + ); // read destination config related group settings // https://developers.amplitude.com/docs/group-identify-api - groupTypeTrait = get(destination, 'Config.groupTypeTrait'); - groupValueTrait = get(destination, 'Config.groupValueTrait'); - if (groupTypeTrait && groupValueTrait) { - const groupTypeValue = get(groupTraits, groupTypeTrait); - const groupNameValue = get(groupTraits, groupValueTrait); - // since the property updates on group at https://api2.amplitude.com/groupidentify - // expects a string group name and value , so error out if the keys are not primitive - // Note: This different for groups object at https://api.amplitude.com/2/httpapi where the - // group value can be array of strings as well. - if ( - groupTypeValue && - typeof groupTypeValue === 'string' && - groupNameValue && - (typeof groupNameValue === 'string' || typeof groupNameValue === 'number') - ) { - groupInfo = {}; - groupInfo.group_type = groupTypeValue; - groupInfo.group_value = groupNameValue; - // passing the entire group traits without deleting the above keys - groupInfo.group_properties = groupTraits; - } else { - logger.debug('Group call parameters are not valid'); - throw new InstrumentationError('Group call parameters are not valid'); - } - } break; case EventType.ALIAS: evType = 'alias'; @@ -611,21 +659,19 @@ function processSingleMessage(message, destination) { category = ConfigCategory.ALIAS; break; case EventType.TRACK: - evType = message.event; + evType = event; if (!isDefinedAndNotNullAndNotEmpty(evType)) { - throw new InstrumentationError('message type not defined'); + throw new InstrumentationError('Event not present. Please send event field'); } if ( message.properties && - isDefinedAndNotNull(message.properties.revenue) && - isDefinedAndNotNull(message.properties.revenue_type) + isDefinedAndNotNull(message.properties?.revenue) && + isDefinedAndNotNull(message.properties?.revenue_type) ) { // if properties has revenue and revenue_type fields // consider the event as revenue event directly category = ConfigCategory.REVENUE; - break; } - break; default: logger.debug('could not determine type'); @@ -639,10 +685,10 @@ function processSingleMessage(message, destination) { mappingConfig[category.name], destination, ); -} +}; -function createProductPurchasedEvent(message, destination, product, counter) { - const eventClonePurchaseProduct = JSON.parse(JSON.stringify(message)); +const createProductPurchasedEvent = (message, destination, product, counter) => { + const eventClonePurchaseProduct = cloneDeep(message); eventClonePurchaseProduct.event = 'Product Purchased'; // In product purchased event event properties consists of the details of each product @@ -654,17 +700,17 @@ function createProductPurchasedEvent(message, destination, product, counter) { // need to modify the message id of each newly created event, as it is mapped to insert_id and that is used by Amplitude for dedup. eventClonePurchaseProduct.messageId = `${message.messageId}-${counter}`; return eventClonePurchaseProduct; -} +}; -function isProductArrayInPayload(message) { +const isProductArrayInPayload = (message) => { const isProductArray = - (message.properties.products && + (message.properties?.products && Array.isArray(message.properties.products) && message.properties.products.length > 0) === true; return isProductArray; -} +}; -function getProductPurchasedEvents(message, destination) { +const getProductPurchasedEvents = (message, destination) => { const productPurchasedEvents = []; if (isProductArrayInPayload(message)) { let counter = 0; @@ -682,16 +728,16 @@ function getProductPurchasedEvents(message, destination) { }); } return productPurchasedEvents; -} +}; -function trackRevenueEvent(message, destination) { +const trackRevenueEvent = (message, destination) => { let sendEvents = []; - const originalEvent = JSON.parse(JSON.stringify(message)); + const originalEvent = cloneDeep(message); if (destination.Config.trackProductsOnce === false) { if (isProductArrayInPayload(message)) { // when trackProductsOnce false no product array present - delete originalEvent.properties.products; + delete originalEvent.properties?.products; } else { // when product array is not there in payload, will track the revenue of the original event. originalEvent.isRevenue = true; @@ -719,16 +765,19 @@ function trackRevenueEvent(message, destination) { } } return sendEvents; -} +}; -function process(event) { +const process = (event) => { const respList = []; const { message, destination } = event; - const messageType = message.type.toLowerCase(); + const messageType = message.type?.toLowerCase(); const toSendEvents = []; + if (!destination?.Config?.apiKey) { + throw new ConfigurationError('No API Key is Found. Please Configure API key from dashbaord'); + } if (messageType === EventType.TRACK) { const { properties } = message; - if (properties && isDefinedAndNotNull(properties.revenue)) { + if (isDefinedAndNotNull(properties?.revenue)) { const revenueEvents = trackRevenueEvent(message, destination); revenueEvents.forEach((revenueEvent) => { toSendEvents.push(revenueEvent); @@ -744,9 +793,9 @@ function process(event) { respList.push(...processSingleMessage(sendEvent, destination)); }); return respList; -} +}; -function getBatchEvents(message, destination, metadata, batchEventResponse) { +const getBatchEvents = (message, destination, metadata, batchEventResponse) => { let batchComplete = false; const batchEventArray = get(batchEventResponse, 'batchedRequest.body.JSON.events') || []; const batchEventJobs = get(batchEventResponse, 'metadata') || []; @@ -760,18 +809,19 @@ function getBatchEvents(message, destination, metadata, batchEventResponse) { : incomingMessageEvent; const userId = incomingMessageEvent.user_id; - // delete the userId as it is less than 5 as AM is giving 400 - // that is not a documented behviour where it states if either deviceid or userid is present - // batch request won't return 400 - // { - // "code": 400, - // "events_with_invalid_id_lengths": { - // "user_id": [ - // 0 - // ] - // }, - // "error": "Invalid id length for user_id or device_id" - // } + /* delete the userId as it is less than 5 as AM is giving 400 + that is not a documented behviour where it states if either deviceid or userid is present + batch request won't return 400 + { + "code": 400, + "events_with_invalid_id_lengths": { + "user_id": [ + 0 + ] + }, + "error": "Invalid id length for user_id or device_id" + } + */ if (batchEventsWithUserIdLengthLowerThanFive && userId && userId.length < 5) { delete incomingMessageEvent.user_id; } @@ -782,10 +832,7 @@ function getBatchEvents(message, destination, metadata, batchEventResponse) { if (batchEventArray.length === 0) { if (JSON.stringify(incomingMessageJSON).length < AMBatchSizeLimit) { delete message.body.JSON.options; - batchEventResponse = Object.assign(batchEventResponse, { - batchedRequest: message, - }); - + batchEventResponse.batchedRequest = message; set(batchEventResponse, 'batchedRequest.endpoint', BATCH_ENDPOINT); batchEventResponse.metadata = [metadata]; } @@ -807,16 +854,16 @@ function getBatchEvents(message, destination, metadata, batchEventResponse) { } } return batchComplete; -} +}; -function batch(destEvents) { +const getFirstEvent = (messageEvent) => + messageEvent && Array.isArray(messageEvent) ? messageEvent[0] : messageEvent; +const batch = (destEvents) => { const respList = []; let batchEventResponse = defaultBatchRequestConfig(); let response; let isBatchComplete; let jsonBody; - let userId; - let deviceId; let messageEvent; let destinationObject; destEvents.forEach((ev) => { @@ -824,18 +871,11 @@ function batch(destEvents) { destinationObject = { ...destination }; jsonBody = get(message, 'body.JSON'); messageEvent = get(message, EVENTS_KEY_PATH); - userId = - messageEvent && Array.isArray(messageEvent) - ? messageEvent[0].user_id - : messageEvent - ? messageEvent.user_id - : undefined; - deviceId = - messageEvent && Array.isArray(messageEvent) - ? messageEvent[0].device_id - : messageEvent - ? messageEvent.device_id - : undefined; + const firstEvent = getFirstEvent(messageEvent); + + const userId = firstEvent?.user_id ?? undefined; + const deviceId = firstEvent?.device_id ?? undefined; + // this case shold not happen and should be filtered already // by the first pass of single event transformation if (messageEvent && !userId && !deviceId) { @@ -851,16 +891,13 @@ function batch(destEvents) { respList.push(errorResponse); return; } - // check if not a JSON body or (userId length < 5 && batchEventsWithUserIdLengthLowerThanFive is false) or - // (batchEventsWithUserIdLengthLowerThanFive is true and userId is less than 5 but deviceId not present) - // , send the event as is after batching - if ( - Object.keys(jsonBody).length === 0 || - (!batchEventsWithUserIdLengthLowerThanFive && userId && userId.length < 5) || - (batchEventsWithUserIdLengthLowerThanFive && userId && userId.length < 5 && !deviceId) - ) { + /* check if not a JSON body or (userId length < 5 && batchEventsWithUserIdLengthLowerThanFive is false) or + (batchEventsWithUserIdLengthLowerThanFive is true and userId is less than 5 but deviceId not present), + send the event as is after batching + */ + if (checkForJSONAndUserIdLengthAndDeviceId(jsonBody, userId, deviceId)) { response = defaultBatchRequestConfig(); - response = Object.assign(response, { batchedRequest: message }); + response.batchedRequest = message; response.metadata = [metadata]; response.destination = destinationObject; respList.push(response); @@ -868,8 +905,9 @@ function batch(destEvents) { // check if the event can be pushed to an existing batch isBatchComplete = getBatchEvents(message, destination, metadata, batchEventResponse); if (isBatchComplete) { - // if the batch is already complete, push it to response list - // and push the event to a new batch + /* if the batch is already complete, push it to response list + and push the event to a new batch + */ batchEventResponse.destination = destinationObject; respList.push({ ...batchEventResponse }); batchEventResponse = defaultBatchRequestConfig(); @@ -879,12 +917,12 @@ function batch(destEvents) { } }); // if there is some unfinished batch push it to response list - if (isBatchComplete !== undefined && isBatchComplete === false) { + if (isDefinedAndNotNull(isBatchComplete) && !isBatchComplete) { batchEventResponse.destination = destinationObject; respList.push(batchEventResponse); } return respList; -} +}; const processRouterDest = async (inputs, reqMetadata) => { const respList = await simpleProcessRouterDest(inputs, process, reqMetadata); diff --git a/src/v0/destinations/am/utils.js b/src/v0/destinations/am/utils.js index 33040c2146..b9925c20d8 100644 --- a/src/v0/destinations/am/utils.js +++ b/src/v0/destinations/am/utils.js @@ -13,65 +13,65 @@ const uaParser = require('@amplitude/ua-parser-js'); const logger = require('../../../logger'); const { isDefinedAndNotNull } = require('../../util'); -function getInfoFromUA(path, payload, defaultVal) { +const getInfoFromUA = (path, payload, defaultVal) => { const ua = get(payload, 'context.userAgent'); const devInfo = ua ? uaParser(ua) : {}; return get(devInfo, path) || defaultVal; -} +}; -function getOSName(payload, sourceKey) { +const getOSName = (payload, sourceKey) => { const payloadVal = get(payload, sourceKey); if (payload.channel && payload.channel.toLowerCase() === 'web') { return getInfoFromUA('browser.name', payload, payloadVal); } return payloadVal; -} +}; -function getOSVersion(payload, sourceKey) { +const getOSVersion = (payload, sourceKey) => { const payloadVal = get(payload, sourceKey); if (payload.channel && payload.channel.toLowerCase() === 'web') { return getInfoFromUA('browser.version', payload, payloadVal); } return payloadVal; -} +}; -function getDeviceModel(payload, sourceKey) { +const getDeviceModel = (payload, sourceKey) => { const payloadVal = get(payload, sourceKey); if (payload.channel && payload.channel.toLowerCase() === 'web') { return getInfoFromUA('os.name', payload, payloadVal); } return payloadVal; -} +}; -function getDeviceManufacturer(payload, sourceKey) { +const getDeviceManufacturer = (payload, sourceKey) => { const payloadVal = get(payload, sourceKey); if (payload.channel && payload.channel.toLowerCase() === 'web') { return getInfoFromUA('device.vendor', payload, payloadVal); } return payloadVal; -} +}; -function getPlatform(payload, sourceKey) { +const getPlatform = (payload, sourceKey) => { const payloadVal = get(payload, sourceKey); return payload.channel ? payload.channel.toLowerCase() === 'web' ? 'Web' : payloadVal : payloadVal; -} +}; -function getBrand(payload, sourceKey, Config) { +const getBrand = (payload, sourceKey, Config) => { if (Config.mapDeviceBrand) { const payloadVal = get(payload, sourceKey); return payloadVal; } return undefined; -} +}; -function getEventId(payload, sourceKey) { +const getEventId = (payload, sourceKey) => { const eventId = get(payload, sourceKey); if (isDefinedAndNotNull(eventId)) { @@ -80,7 +80,7 @@ function getEventId(payload, sourceKey) { } else return eventId; } return undefined; -} +}; module.exports = { getOSName, diff --git a/src/v0/util/index.js b/src/v0/util/index.js index 4ea3d3783d..ea08d08c8a 100644 --- a/src/v0/util/index.js +++ b/src/v0/util/index.js @@ -2053,6 +2053,16 @@ const getAuthErrCategoryFromStCode = (status) => { return ''; }; +const isValidInteger = (value) => { + if (Number.isNaN(value) || !isDefinedAndNotNull(value)) { + return false; + } + if (typeof value === 'number' && value % 1 === 0) { + return true; + } + // Use a regular expression to check if the string is a valid integer or a valid floating-point number + return typeof value === 'string' ? /^-?\d+$/.test(value) : false; +}; const validateEventType = (event) => { if (!event || typeof event !== 'string') { throw new InstrumentationError('Event is a required field and should be a string'); @@ -2172,6 +2182,7 @@ module.exports = { hasCircularReference, getAuthErrCategoryFromErrDetailsAndStCode, getAuthErrCategoryFromStCode, + isValidInteger, isNewStatusCodesAccepted, IsGzipSupported, }; diff --git a/src/v0/util/index.test.js b/src/v0/util/index.test.js index ce341e8187..e39c583aab 100644 --- a/src/v0/util/index.test.js +++ b/src/v0/util/index.test.js @@ -13,6 +13,7 @@ const functionNames = [ 'batchMultiplexedEvents', 'removeUndefinedNullValuesAndEmptyObjectArray', 'groupEventsByType', + 'isValidInteger', ]; // Names of the utility functions to test which expects multiple arguments as values and not objects diff --git a/src/v0/util/testdata/isValidInteger.json b/src/v0/util/testdata/isValidInteger.json new file mode 100644 index 0000000000..be7be936a6 --- /dev/null +++ b/src/v0/util/testdata/isValidInteger.json @@ -0,0 +1,31 @@ +[ + { + "description": "Number is undefined", + "output": false + }, + { + "description": "Number in string format", + "input": "123", + "output": true + }, + { + "description": "Normal Integer", + "input": 123, + "output": true + }, + { + "description": "Float", + "input": 123.91, + "output": false + }, + { + "description": "Float string", + "input": "123.00", + "output": false + }, + { + "description": "Alphanumeric String", + "input": "abcd1234", + "output": false + } +] diff --git a/test/__tests__/data/am_batch_input.json b/test/__tests__/data/am_batch_input.json index 64fe0b4ec7..5b0440babf 100644 --- a/test/__tests__/data/am_batch_input.json +++ b/test/__tests__/data/am_batch_input.json @@ -1,4 +1,67 @@ [ + [ + { + "message": { + "body": { + "XML": {}, + "JSON_ARRAY": {}, + "FORM": {}, + "JSON": { + "events": [ + { + "ip": "0.0.0.0", + "time": 1603132665557, + "os_name": "", + "app_name": "RudderLabs JavaScript SDK", + "language": "en-US", + "library": "rudderstack", + "event_type": "$identify", + "os_version": "", + "session_id": -1, + "app_version": "1.1.5", + "user_properties": { + "name": "some campaign", + "plan": "Open source", + "term": "keyword", + "test": "other value", + "email": "test@rudderstack.com", + "logins": 5, + "medium": "medium", + "source": "google", + "content": "some content", + "category": "SampleIdentify", + "createdAt": 1599264000 + } + } + ], + "api_key": "4c7ed7573eb73517ee4c26ed4bde9a85", + "options": { + "min_id_length": 1 + } + } + }, + "type": "REST", + "files": {}, + "method": "POST", + "params": {}, + "headers": { + "Content-Type": "application/json" + }, + "version": "1", + "endpoint": "https://api.eu.amplitude.com/2/httpapi" + }, + "metadata": { + "job_id": 1 + }, + "destination": { + "ID": "a", + "url": "a", + "Config": { + "residencyServer": "EU" + } + } + } + ], [ { "message": { diff --git a/test/__tests__/data/am_batch_output.json b/test/__tests__/data/am_batch_output.json index dac6400585..32735b000f 100644 --- a/test/__tests__/data/am_batch_output.json +++ b/test/__tests__/data/am_batch_output.json @@ -1,4 +1,18 @@ [ + [ + { + "batched": false, + "error": "Both userId and deviceId cannot be undefined", + "metadata": { + "job_id": 1 + }, + "statTags": { + "errorCategory": "dataValidation", + "errorType": "instrumentation" + }, + "statusCode": 400 + } + ], [ { "batchedRequest": { @@ -108,7 +122,9 @@ "JSON_ARRAY": {}, "FORM": { "api_key": "4c7ed7573eb73517ee4c26ed4bde9a85", - "mapping": ["{\"global_user_id\":\"newUserIdAlias\",\"user_id\":\"sampleusrRudder3\"}"] + "mapping": [ + "{\"global_user_id\":\"newUserIdAlias\",\"user_id\":\"sampleusrRudder3\"}" + ] }, "JSON": {} }, @@ -361,7 +377,9 @@ "JSON_ARRAY": {}, "FORM": { "api_key": "4c7ed7573eb73517ee4c26ed4bde9a85", - "mapping": ["{\"global_user_id\":\"newUserIdAlias\",\"user_id\":\"sampleusrRudder3\"}"] + "mapping": [ + "{\"global_user_id\":\"newUserIdAlias\",\"user_id\":\"sampleusrRudder3\"}" + ] }, "JSON": {} }, @@ -687,14 +705,29 @@ "DisplayName": "Braze", "Config": { "destConfig": { - "android": ["useNativeSDK"], - "defaultConfig": ["appKey", "dataCenter", "restApiKey"], - "ios": ["useNativeSDK"], - "web": ["useNativeSDK"] + "android": [ + "useNativeSDK" + ], + "defaultConfig": [ + "appKey", + "dataCenter", + "restApiKey" + ], + "ios": [ + "useNativeSDK" + ], + "web": [ + "useNativeSDK" + ] }, "excludeKeys": [], - "includeKeys": ["appKey", "dataCenter"], - "secretKeys": ["restApiKey"], + "includeKeys": [ + "appKey", + "dataCenter" + ], + "secretKeys": [ + "restApiKey" + ], "supportedSourceTypes": [ "android", "ios", @@ -760,7 +793,9 @@ "JSON_ARRAY": {}, "FORM": { "api_key": "4c7ed7573eb73517ee4c26ed4bde9a85", - "mapping": ["{\"global_user_id\":\"newUserIdAlias\",\"user_id\":\"sampleusrRudder3\"}"] + "mapping": [ + "{\"global_user_id\":\"newUserIdAlias\",\"user_id\":\"sampleusrRudder3\"}" + ] }, "JSON": {} }, @@ -1043,7 +1078,9 @@ "JSON_ARRAY": {}, "FORM": { "api_key": "4c7ed7573eb73517ee4c26ed4bde9a85", - "mapping": ["{\"global_user_id\":\"newUserIdAlias\",\"user_id\":\"sampleusrRudder3\"}"] + "mapping": [ + "{\"global_user_id\":\"newUserIdAlias\",\"user_id\":\"sampleusrRudder3\"}" + ] }, "JSON": {} }, @@ -1189,4 +1226,4 @@ } } ] -] +] \ No newline at end of file diff --git a/test/__tests__/data/am_input.json b/test/__tests__/data/am_input.json index 664894f7f5..3e5cde2cca 100644 --- a/test/__tests__/data/am_input.json +++ b/test/__tests__/data/am_input.json @@ -1,4 +1,214 @@ [ + { + "message": { + "type": "track", + "sentAt": "2020-08-14T05:30:30.118Z", + "context": { + "source": "test", + "traits": { + "anonymousId": "50be5c78-6c3f-4b60-be84-97805a316fb1" + }, + "library": { + "name": "rudder-sdk-ruby-sync", + "version": "1.0.6" + } + }, + "messageId": "7208bbb6-2c4e-45bb-bf5b-ad426f3593e9", + "timestamp": "2020-08-14T05:30:30.118Z", + "properties": { + "tax": 2, + "total": 27.5, + "coupon": "hasbros", + "revenue": 48, + "revenue_type": "Purchased", + "quantity": 2, + "currency": "USD", + "discount": 2.5, + "order_id": "50314b8e9bcf000000000000", + "shipping": 3, + "subtotal": 22.5, + "affiliation": "Google Store", + "checkout_id": "fksdjfsdjfisjf9sdfjsd9f" + }, + "anonymousId": "50be5c78-6c3f-4b60-be84-97805a316fb1", + "integrations": { + "S3": false, + "All": true + } + }, + "destination": { + "Config": { + "apiKey": "abcde", + "groupTypeTrait": "email", + "groupValueTrait": "age", + "trackProductsOnce": true, + "trackRevenuePerProduct": false + } + } + }, + { + "message": { + "type": "UNSUPPORTED-TYPE", + "event": "Order Completed", + "sentAt": "2020-08-14T05:30:30.118Z", + "context": {}, + "messageId": "7208bbb6-2c4e-45bb-bf5b-ad426f3593e9", + "timestamp": "2020-08-14T05:30:30.118Z", + "properties": {}, + "anonymousId": "50be5c78-6c3f-4b60-be84-97805a316fb1", + "integrations": { + "S3": false, + "All": true + } + }, + "destination": { + "Config": { + "groupTypeTrait": "email", + "apiKey": "abcde", + "groupValueTrait": "age", + "trackProductsOnce": true, + "trackRevenuePerProduct": false + } + } + }, + { + "message": { + "event": "Order Completed", + "sentAt": "2020-08-14T05:30:30.118Z", + "context": {}, + "messageId": "7208bbb6-2c4e-45bb-bf5b-ad426f3593e9", + "timestamp": "2020-08-14T05:30:30.118Z", + "properties": {}, + "anonymousId": "50be5c78-6c3f-4b60-be84-97805a316fb1", + "integrations": { + "S3": false, + "All": true + } + }, + "destination": { + "Config": { + "groupTypeTrait": "email", + "groupValueTrait": "age", + "trackProductsOnce": true, + "trackRevenuePerProduct": false + } + } + }, + { + "message": { + "type": "track", + "event": "Order Completed", + "sentAt": "2020-08-14T05:30:30.118Z", + "context": { + "source": "test", + "traits": { + "anonymousId": "50be5c78-6c3f-4b60-be84-97805a316fb1" + }, + "library": { + "name": "rudder-sdk-ruby-sync", + "version": "1.0.6" + } + }, + "messageId": "7208bbb6-2c4e-45bb-bf5b-ad426f3593e9", + "timestamp": "2020-08-14T05:30:30.118Z", + "properties": { + "tax": 2, + "total": 27.5, + "coupon": "hasbros", + "revenue": 48, + "revenue_type": "Purchased", + "quantity": 2, + "currency": "USD", + "discount": 2.5, + "order_id": "50314b8e9bcf000000000000", + "shipping": 3, + "subtotal": 22.5, + "affiliation": "Google Store", + "checkout_id": "fksdjfsdjfisjf9sdfjsd9f" + }, + "anonymousId": "50be5c78-6c3f-4b60-be84-97805a316fb1", + "integrations": { + "S3": false, + "All": true + } + }, + "destination": { + "Config": { + "apiKey": "abcde", + "groupTypeTrait": "email", + "groupValueTrait": "age", + "trackProductsOnce": true, + "trackRevenuePerProduct": false + } + } + }, + { + "message": { + "type": "track", + "event": "Order Completed", + "sentAt": "2020-08-14T05:30:30.118Z", + "context": { + "source": "test", + "traits": { + "anonymousId": "50be5c78-6c3f-4b60-be84-97805a316fb1" + }, + "library": { + "name": "rudder-sdk-ruby-sync", + "version": "1.0.6" + } + }, + "messageId": "7208bbb6-2c4e-45bb-bf5b-ad426f3593e9", + "timestamp": "2020-08-14T05:30:30.118Z", + "properties": { + "tax": 2, + "total": 27.5, + "coupon": "hasbros", + "revenue": 48, + "quantity": 2, + "currency": "USD", + "discount": 2.5, + "order_id": "50314b8e9bcf000000000000", + "products": [ + { + "sku": "45790-32", + "url": "https://www.example.com/product/path", + "name": "Monopoly: 3rd Edition", + "price": 19, + "category": "Games", + "quantity": 1, + "image_url": "https:///www.example.com/product/path.jpg", + "product_id": "507f1f77bcf86cd799439011" + }, + { + "sku": "46493-32", + "name": "Uno Card Game", + "price": 3, + "category": "Games", + "quantity": 2, + "product_id": "505bd76785ebb509fc183733" + } + ], + "shipping": 3, + "subtotal": 22.5, + "affiliation": "Google Store", + "checkout_id": "fksdjfsdjfisjf9sdfjsd9f" + }, + "anonymousId": "50be5c78-6c3f-4b60-be84-97805a316fb1", + "integrations": { + "S3": false, + "All": true + } + }, + "destination": { + "Config": { + "apiKey": "abcde", + "groupTypeTrait": "email", + "groupValueTrait": "age", + "trackProductsOnce": true, + "trackRevenuePerProduct": false + } + } + }, { "message": { "channel": "web", @@ -629,6 +839,91 @@ } } }, + { + "message": { + "channel": "web", + "context": { + "app": { + "build": "1.0.0", + "name": "RudderLabs JavaScript SDK", + "namespace": "com.rudderlabs.javascript", + "version": "1.1.5" + }, + "traits": { + "name": "Shehan Study", + "category": "SampleIdentify", + "email": "test@rudderstack.com", + "plan": "Open source", + "logins": 5, + "createdAt": 1599264000 + }, + "library": { + "name": "RudderLabs JavaScript SDK", + "version": "1.1.5" + }, + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36", + "locale": "en-US", + "os": { + "name": "", + "version": "" + }, + "screen": { + "density": 0.8999999761581421 + }, + "campaign": { + "source": "google", + "medium": "medium", + "term": "keyword", + "content": "some content", + "name": "some campaign", + "test": "other value" + }, + "page": { + "path": "/destinations/amplitude", + "referrer": "", + "search": "", + "title": "", + "url": "https://docs.rudderstack.com/destinations/amplitude", + "category": "destination", + "initial_referrer": "https://docs.rudderstack.com", + "initial_referring_domain": "docs.rudderstack.com" + } + }, + "type": "group", + "messageId": "e5034df0-a404-47b4-a463-76df99934fea", + "originalTimestamp": "2020-10-20T07:54:58.983Z", + "anonymousId": "my-anonymous-id-new", + "userId": "sampleusrRudder3", + "integrations": { + "All": true, + "Amplitude": { + "groups": { + "group_type": "Company", + "group_value": "ABC" + } + } + }, + "groupId": "Sample_groupId23", + "traits": { + "KEY_3": { + "CHILD_KEY_92": "value_95", + "CHILD_KEY_102": "value_103" + }, + "KEY_2": { + "CHILD_KEY_92": "value_95", + "CHILD_KEY_102": "value_103" + }, + "name_trait": "Company", + "value_trait": "ABC" + }, + "sentAt": "2020-10-20T07:54:58.983Z" + }, + "destination": { + "Config": { + "apiKey": "abcde" + } + } + }, { "message": { "channel": "web", @@ -698,7 +993,7 @@ "CHILD_KEY_102": "value_103" }, "name_trait": "Company", - "value_trait": "Comapny-ABC" + "value_trait": "ABC" }, "sentAt": "2020-10-20T07:54:58.983Z" }, @@ -779,7 +1074,9 @@ "CHILD_KEY_102": "value_103" }, "name_trait": "Company", - "value_trait": ["Comapny-ABC"] + "value_trait": [ + "ABC" + ] }, "sentAt": "2020-10-20T07:54:58.983Z" }, @@ -3173,7 +3470,7 @@ "CHILD_KEY_102": "value_103" }, "name_trait": "Company", - "value_trait": "Comapny-ABC" + "value_trait": "ABC" }, "sentAt": "2020-10-20T07:54:58.983Z" }, @@ -3718,7 +4015,7 @@ "CHILD_KEY_102": "value_103" }, "name_trait": "Company", - "value_trait": "Comapny-ABC" + "value_trait": "ABC" }, "sentAt": "2020-10-20T07:54:58.983Z" }, @@ -3965,6 +4262,69 @@ } } }, + { + "message": { + "anonymousId": "5d205961641ee6c5", + "channel": "mobile", + "context": { + "app": { + "build": "6", + "name": "Sample Kotlin", + "namespace": "com.example.testapp1mg", + "version": "1.2" + }, + "device": { + "id": "5d205961641ee6c5", + "manufacturer": "Google", + "model": "Android SDK built for x86", + "name": "generic_x86", + "type": "Android" + }, + "library": { + "name": "com.rudderstack.android.sdk.core", + "version": "1.7.0" + }, + "locale": "en-US", + "network": { + "carrier": "Android", + "bluetooth": false, + "cellular": true, + "wifi": true + }, + "os": { + "name": "Android", + "version": "7.1.1" + }, + "screen": { + "density": 440, + "height": 2148, + "width": 1080 + }, + "sessionId": "1662393792", + "timezone": "Asia/Kolkata", + "traits": { + "anonymousId": "5d205961641ee6c5", + "id": "User Android", + "userId": "User Android" + }, + "userAgent": "Dalvik/2.1.0 (Linux; U; Android 7.1.1; Android SDK built for x86 Build/NYC)" + }, + "integrations": { + "All": true + }, + "messageId": "1662393883248-509420bf-b812-4f8d-bdb2-8c811bfde87f", + "properties": { + }, + "originalTimestamp": "2022-09-05T16:04:43.250Z", + "type": "screen", + "userId": "User Android" + }, + "destination": { + "Config": { + "apiKey": "abcde" + } + } + }, { "message": { "channel": "web", @@ -4185,7 +4545,7 @@ "CHILD_KEY_102": "value_103" }, "name_trait": "Company", - "value_trait": "Comapny-ABC" + "value_trait": "ABC" }, "sentAt": "2020-10-20T07:54:58.983Z" }, @@ -4464,7 +4824,6 @@ "search": "", "title": "", "url": "https://docs.rudderstack.com/destinations/amplitude", - "category": "destination", "initial_referrer": "https://docs.rudderstack.com", "initial_referring_domain": "docs.rudderstack.com" }, @@ -4474,15 +4833,14 @@ "event_id": 2 } }, - "name": "ApplicationLoaded", "sentAt": "2019-10-14T11:15:53.296Z" }, "destination": { "Config": { "apiKey": "abcde", - "useUserDefinedPageEventName": true, + "useUserDefinedPageEventName": false, "userProvidedPageEventString": "Viewed {{context.page.title}} event." } } } -] +] \ No newline at end of file diff --git a/test/__tests__/data/am_output.json b/test/__tests__/data/am_output.json index b82df8ae0d..34471f4922 100644 --- a/test/__tests__/data/am_output.json +++ b/test/__tests__/data/am_output.json @@ -1,4 +1,138 @@ [ + { + "error": "Event not present. Please send event field" + }, + { + "error": "message type not supported" + }, + { + "error": "No API Key is Found. Please Configure API key from dashbaord" + }, + { + "version": "1", + "type": "REST", + "method": "POST", + "endpoint": "https://api2.amplitude.com/2/httpapi", + "headers": { + "Content-Type": "application/json" + }, + "params": {}, + "body": { + "JSON": { + "api_key": "abcde", + "events": [ + { + "device_id": "50be5c78-6c3f-4b60-be84-97805a316fb1", + "library": "rudderstack", + "event_type": "Order Completed", + "insert_id": "7208bbb6-2c4e-45bb-bf5b-ad426f3593e9", + "event_properties": { + "tax": 2, + "total": 27.5, + "coupon": "hasbros", + "currency": "USD", + "discount": 2.5, + "order_id": "50314b8e9bcf000000000000", + "revenue_type": "Purchased", + "shipping": 3, + "subtotal": 22.5, + "affiliation": "Google Store", + "checkout_id": "fksdjfsdjfisjf9sdfjsd9f" + }, + "revenueType": "Purchased", + "price": 48, + "quantity": 1, + "revenue": 48, + "time": 1597383030118, + "user_properties": { + "anonymousId": "50be5c78-6c3f-4b60-be84-97805a316fb1" + }, + "session_id": -1 + } + ], + "options": { + "min_id_length": 1 + } + }, + "XML": {}, + "JSON_ARRAY": {}, + "FORM": {} + }, + "files": {}, + "userId": "50be5c78-6c3f-4b60-be84-97805a316fb1" + }, + { + "version": "1", + "type": "REST", + "method": "POST", + "endpoint": "https://api2.amplitude.com/2/httpapi", + "headers": { + "Content-Type": "application/json" + }, + "params": {}, + "body": { + "JSON": { + "api_key": "abcde", + "events": [ + { + "device_id": "50be5c78-6c3f-4b60-be84-97805a316fb1", + "library": "rudderstack", + "event_type": "Order Completed", + "insert_id": "7208bbb6-2c4e-45bb-bf5b-ad426f3593e9", + "event_properties": { + "tax": 2, + "total": 27.5, + "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" + } + ], + "shipping": 3, + "subtotal": 22.5, + "affiliation": "Google Store", + "checkout_id": "fksdjfsdjfisjf9sdfjsd9f" + }, + "revenueType": "Purchased", + "price": 48, + "quantity": 1, + "revenue": 48, + "time": 1597383030118, + "user_properties": { + "anonymousId": "50be5c78-6c3f-4b60-be84-97805a316fb1" + }, + "session_id": -1 + } + ], + "options": { + "min_id_length": 1 + } + }, + "XML": {}, + "JSON_ARRAY": {}, + "FORM": {} + }, + "files": {}, + "userId": "50be5c78-6c3f-4b60-be84-97805a316fb1" + }, { "version": "1", "type": "REST", @@ -21,7 +155,7 @@ "app_name": "RudderLabs JavaScript SDK", "app_version": "1.0.0", "language": "en-US", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", + "session_id": -1, "insert_id": "84e26acc-56a5-4835-8233-591137fca468", "ip": "0.0.0.0", "user_properties": { @@ -77,7 +211,7 @@ "app_name": "RudderLabs JavaScript SDK", "app_version": "1.0.0", "language": "en-US", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", + "session_id": -1, "insert_id": "84e26acc-56a5-4835-8233-591137fca468", "ip": "0.0.0.0", "user_properties": { @@ -137,7 +271,7 @@ "app_name": "RudderLabs JavaScript SDK", "app_version": "1.0.0", "language": "en-US", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", + "session_id": -1, "event_type": "$identify", "user_properties": { "anonymousId": "123456", @@ -202,7 +336,7 @@ "initial_referring_domain": "docs.rudderstack.com", "initial_referrer": "https://docs.rudderstack.com" }, - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", + "session_id": -1, "ip": "1.1.1.1", "time": 1571051718299, "user_id": "12345", @@ -261,7 +395,7 @@ "initial_referring_domain": "docs.rudderstack.com", "initial_referrer": "https://docs.rudderstack.com" }, - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", + "session_id": -1, "ip": "1.1.1.1", "groups": { "Company": "ABC" @@ -312,7 +446,7 @@ "app_version": "1.0.0", "language": "en-US", "event_type": "test track event", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", + "session_id": -1, "event_properties": { "user_actual_role": "system_admin", "user_actual_id": 12345, @@ -366,7 +500,7 @@ "app_name": "RudderLabs JavaScript SDK", "app_version": "1.0.0", "language": "en-US", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", + "session_id": -1, "event_type": "$identify", "user_properties": { "anonymousId": "123456", @@ -419,7 +553,7 @@ "timestamp": "2020-08-28 09:00:00" }, "event_type": "$identify", - "session_id": "1598597129", + "session_id": 1598597129, "time": 0, "user_id": "ubcdfghi0001" } @@ -450,7 +584,7 @@ "events": [ { "device_id": "123456", - "session_id": "1598597129", + "session_id": 1598597129, "event_type": "$identify", "library": "rudderstack", "user_properties": { @@ -555,6 +689,83 @@ "files": {}, "userId": "123456" }, + [ + { + "version": "1", + "type": "REST", + "method": "POST", + "endpoint": "https://api2.amplitude.com/2/httpapi", + "headers": { + "Content-Type": "application/json" + }, + "params": {}, + "body": { + "JSON": { + "api_key": "abcde", + "events": [ + { + "os_name": "Chrome", + "os_version": "85.0.4183.121", + "platform": "Web", + "library": "rudderstack", + "device_model": "Mac", + "device_id": "my-anonymous-id-new", + "app_name": "RudderLabs JavaScript SDK", + "app_version": "1.1.5", + "language": "en-US", + "event_type": "$identify", + "groups": { + "Company": "ABC" + }, + "user_properties": { + "Company": "ABC", + "utm_content": "some content", + "utm_medium": "medium", + "utm_name": "some campaign", + "utm_source": "google", + "utm_term": "keyword", + "utm_test": "other value", + "initial_referring_domain": "docs.rudderstack.com", + "initial_referrer": "https://docs.rudderstack.com" + }, + "time": 1603180498983, + "user_id": "sampleusrRudder3", + "session_id": -1 + } + ], + "options": { + "min_id_length": 1 + } + }, + "XML": {}, + "JSON_ARRAY": {}, + "FORM": {} + }, + "files": {}, + "userId": "my-anonymous-id-new" + }, + { + "version": "1", + "type": "REST", + "method": "POST", + "endpoint": "https://api2.amplitude.com/groupidentify", + "headers": {}, + "params": {}, + "body": { + "JSON": {}, + "XML": {}, + "JSON_ARRAY": {}, + "FORM": { + "api_key": "abcde", + "identification": [ + "{\"group_type\":\"Company\",\"group_value\":\"ABC\"}" + ] + } + }, + "files": {}, + "userId": "my-anonymous-id-new" + } + ], [ { "version": "1", @@ -581,7 +792,7 @@ "language": "en-US", "event_type": "$identify", "user_properties": { - "Company": "Comapny-ABC", + "Company": "ABC", "utm_content": "some content", "utm_medium": "medium", "utm_name": "some campaign", @@ -592,7 +803,7 @@ "initial_referrer": "https://docs.rudderstack.com" }, "groups": { - "Company": "Comapny-ABC" + "Company": "ABC" }, "time": 1603180498983, "user_id": "sampleusrRudder3", @@ -624,7 +835,7 @@ "FORM": { "api_key": "abcde", "identification": [ - "{\"group_type\":\"Company\",\"group_value\":\"Comapny-ABC\",\"group_properties\":{\"KEY_3\":{\"CHILD_KEY_92\":\"value_95\",\"CHILD_KEY_102\":\"value_103\"},\"KEY_2\":{\"CHILD_KEY_92\":\"value_95\",\"CHILD_KEY_102\":\"value_103\"},\"name_trait\":\"Company\",\"value_trait\":\"Comapny-ABC\"}}" + "{\"group_type\":\"Company\",\"group_value\":\"ABC\",\"group_properties\":{\"KEY_3\":{\"CHILD_KEY_92\":\"value_95\",\"CHILD_KEY_102\":\"value_103\"},\"KEY_2\":{\"CHILD_KEY_92\":\"value_95\",\"CHILD_KEY_102\":\"value_103\"},\"name_trait\":\"Company\",\"value_trait\":\"ABC\"}}" ] } }, @@ -2244,7 +2455,7 @@ "event_type": "Order Completed", "user_id": "userID123", "revenueType": "Purchased", - "price": 25, + "price": 25.0, "quantity": 2, "revenue": 48, "time": 1597383030118, @@ -2886,7 +3097,7 @@ "app_name": "RudderLabs JavaScript SDK", "app_version": "1.0.0", "language": "en-US", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", + "session_id": -1, "event_type": "$identify", "device_brand": "testBrand", "device_manufacturer": "testManufacturer", @@ -3031,7 +3242,7 @@ "app_name": "RudderLabs JavaScript SDK", "app_version": "1.0.0", "language": "en-US", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", + "session_id": -1, "insert_id": "84e26acc-56a5-4835-8233-591137fca468", "ip": "0.0.0.0", "user_properties": { @@ -3091,7 +3302,7 @@ "language": "en-US", "event_type": "$identify", "user_properties": { - "Company": "Comapny-ABC", + "Company": "ABC", "utm_content": "some content", "utm_medium": "medium", "utm_name": "some campaign", @@ -3102,7 +3313,7 @@ "initial_referrer": "https://docs.rudderstack.com" }, "groups": { - "Company": "Comapny-ABC" + "Company": "ABC" }, "time": 1603180498983, "user_id": "sampleusrRudder3", @@ -3134,7 +3345,7 @@ "FORM": { "api_key": "abcde", "identification": [ - "{\"group_type\":\"Company\",\"group_value\":\"Comapny-ABC\",\"group_properties\":{\"KEY_3\":{\"CHILD_KEY_92\":\"value_95\",\"CHILD_KEY_102\":\"value_103\"},\"KEY_2\":{\"CHILD_KEY_92\":\"value_95\",\"CHILD_KEY_102\":\"value_103\"},\"name_trait\":\"Company\",\"value_trait\":\"Comapny-ABC\"}}" + "{\"group_type\":\"Company\",\"group_value\":\"ABC\",\"group_properties\":{\"KEY_3\":{\"CHILD_KEY_92\":\"value_95\",\"CHILD_KEY_102\":\"value_103\"},\"KEY_2\":{\"CHILD_KEY_92\":\"value_95\",\"CHILD_KEY_102\":\"value_103\"},\"name_trait\":\"Company\",\"value_trait\":\"ABC\"}}" ] } }, @@ -3483,11 +3694,11 @@ "utm_content": "some content", "utm_name": "some campaign", "utm_test": "other value", - "Company": "Comapny-ABC" + "Company": "ABC" }, "event_type": "$identify", "groups": { - "Company": "Comapny-ABC" + "Company": "ABC" }, "time": 1603180498983, "user_id": "sampleusrRudder3", @@ -3520,7 +3731,7 @@ "FORM": { "api_key": "abcde", "identification": [ - "{\"group_type\":\"Company\",\"group_value\":\"Comapny-ABC\",\"group_properties\":{\"KEY_3\":{\"CHILD_KEY_92\":\"value_95\",\"CHILD_KEY_102\":\"value_103\"},\"KEY_2\":{\"CHILD_KEY_92\":\"value_95\",\"CHILD_KEY_102\":\"value_103\"},\"name_trait\":\"Company\",\"value_trait\":\"Comapny-ABC\"}}" + "{\"group_type\":\"Company\",\"group_value\":\"ABC\",\"group_properties\":{\"KEY_3\":{\"CHILD_KEY_92\":\"value_95\",\"CHILD_KEY_102\":\"value_103\"},\"KEY_2\":{\"CHILD_KEY_92\":\"value_95\",\"CHILD_KEY_102\":\"value_103\"},\"name_trait\":\"Company\",\"value_trait\":\"ABC\"}}" ] } }, @@ -3603,7 +3814,7 @@ "initial_referring_domain": "docs.rudderstack.com", "name": "ApplicationLoaded" }, - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", + "session_id": -1, "insert_id": "5e10d13a-bf9a-44bf-b884-43a9e591ea71", "ip": "1.1.1.1", "event_id": 2, @@ -3702,6 +3913,56 @@ "files": {}, "userId": "5d205961641ee6c5" }, + { + "version": "1", + "type": "REST", + "method": "POST", + "endpoint": "https://api2.amplitude.com/2/httpapi", + "headers": { + "Content-Type": "application/json" + }, + "params": {}, + "body": { + "JSON": { + "api_key": "abcde", + "events": [ + { + "os_name": "Android", + "os_version": "7.1.1", + "device_model": "Android SDK built for x86", + "device_manufacturer": "Google", + "device_id": "5d205961641ee6c5", + "carrier": "Android", + "app_name": "Sample Kotlin", + "app_version": "1.2", + "platform": "Android", + "language": "en-US", + "event_properties": {}, + "insert_id": "1662393883248-509420bf-b812-4f8d-bdb2-8c811bfde87f", + "user_properties": { + "anonymousId": "5d205961641ee6c5", + "id": "User Android", + "userId": "User Android" + }, + "event_type": "Viewed Screen", + "user_id": "User Android", + "device_brand": "Google", + "time": 1662393883250, + "session_id": 1662393792, + "library": "rudderstack" + } + ], + "options": { + "min_id_length": 1 + } + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "files": {}, + "userId": "5d205961641ee6c5" + }, { "version": "1", "type": "REST", @@ -3741,7 +4002,7 @@ "event_type": "$identify", "time": 1571043797562, "user_id": "123456", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", + "session_id": 1662393792, "country": "India", "city": "kolkata", "library": "rudderstack" @@ -3847,7 +4108,7 @@ "initial_referring_domain": "docs.rudderstack.com", "name": "ApplicationLoaded" }, - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", + "session_id": -1, "insert_id": "5e10d13a-bf9a-44bf-b884-43a9e591ea71", "ip": "1.1.1.1", "event_id": 2, @@ -3907,7 +4168,7 @@ "initial_referring_domain": "docs.rudderstack.com", "name": "ApplicationLoaded" }, - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", + "session_id": -1, "insert_id": "5e10d13a-bf9a-44bf-b884-43a9e591ea71", "ip": "1.1.1.1", "event_id": 2, @@ -3967,7 +4228,7 @@ "initial_referring_domain": "docs.rudderstack.com", "name": "ApplicationLoaded" }, - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", + "session_id": -1, "insert_id": "5e10d13a-bf9a-44bf-b884-43a9e591ea71", "ip": "1.1.1.1", "event_id": 2, @@ -4015,19 +4276,17 @@ "app_name": "RudderLabs JavaScript SDK", "app_version": "1.0.0", "language": "en-US", - "event_type": "Viewed Home Page event.", + "event_type": "Viewed Page", "event_properties": { "path": "/destinations/amplitude", "referrer": "", "search": "", "title": "", "url": "https://docs.rudderstack.com/destinations/amplitude", - "category": "destination", "initial_referrer": "https://docs.rudderstack.com", - "initial_referring_domain": "docs.rudderstack.com", - "name": "ApplicationLoaded" + "initial_referring_domain": "docs.rudderstack.com" }, - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", + "session_id": -1, "insert_id": "5e10d13a-bf9a-44bf-b884-43a9e591ea71", "ip": "1.1.1.1", "event_id": 2, @@ -4053,4 +4312,4 @@ "files": {}, "userId": "00000000000000000000000000" } -] +] \ No newline at end of file diff --git a/test/__tests__/data/am_router_output.json b/test/__tests__/data/am_router_output.json index 5c9e23840a..bfccb478b3 100644 --- a/test/__tests__/data/am_router_output.json +++ b/test/__tests__/data/am_router_output.json @@ -24,7 +24,7 @@ "app_name": "RudderLabs JavaScript SDK", "app_version": "1.0.0", "language": "en-US", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", + "session_id": -1, "insert_id": "84e26acc-56a5-4835-8233-591137fca468", "city": "kolkata", "country": "India", @@ -109,7 +109,7 @@ "initial_referring_domain": "docs.rudderstack.com", "name": "ApplicationLoaded" }, - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", + "session_id": -1, "insert_id": "5e10d13a-bf9a-44bf-b884-43a9e591ea71", "ip": "1.1.1.1", "user_properties": { From 9bc0fd8efcee44871a190bd6cb9e89c5cf035ff8 Mon Sep 17 00:00:00 2001 From: Sudip Paul <67197965+ItsSudip@users.noreply.github.com> Date: Thu, 2 Nov 2023 19:31:33 +0530 Subject: [PATCH 07/93] feat: add new destination tiktok_audience (#2710) * feat: add new destination tiktok_audience * remove log * refactor code * chore: refactor workflows * add test cases * chore: refactore code * refactor code and add negative test case --------- Co-authored-by: Dilip Kola Co-authored-by: mihir-4116 Co-authored-by: Mihir Bhalala <77438541+mihir-4116@users.noreply.github.com> --- src/cdk/v2/bindings/default.js | 6 + .../v2/destinations/tiktok_audience/config.js | 9 + .../tiktok_audience/procWorkflow.yaml | 67 ++ .../tiktok_audience/rtWorkflow.yaml | 32 + src/features.json | 1 + .../tiktok_audience/processor/data.ts | 854 ++++++++++++++++++ .../tiktok_audience/router/data.ts | 833 +++++++++++++++++ 7 files changed, 1802 insertions(+) create mode 100644 src/cdk/v2/destinations/tiktok_audience/config.js create mode 100644 src/cdk/v2/destinations/tiktok_audience/procWorkflow.yaml create mode 100644 src/cdk/v2/destinations/tiktok_audience/rtWorkflow.yaml create mode 100644 test/integrations/destinations/tiktok_audience/processor/data.ts create mode 100644 test/integrations/destinations/tiktok_audience/router/data.ts diff --git a/src/cdk/v2/bindings/default.js b/src/cdk/v2/bindings/default.js index 0bba7210f0..b86b6d2b63 100644 --- a/src/cdk/v2/bindings/default.js +++ b/src/cdk/v2/bindings/default.js @@ -1,3 +1,4 @@ +const crypto = require('crypto'); const { InstrumentationError, ConfigurationError, @@ -47,7 +48,12 @@ function assertHttpResp(processedResponse, message) { } } +function MD5(data) { + return crypto.createHash('md5').update(data).digest('hex'); +} + module.exports = { + MD5, isValidEventType, assert, assertConfig, diff --git a/src/cdk/v2/destinations/tiktok_audience/config.js b/src/cdk/v2/destinations/tiktok_audience/config.js new file mode 100644 index 0000000000..853f372505 --- /dev/null +++ b/src/cdk/v2/destinations/tiktok_audience/config.js @@ -0,0 +1,9 @@ +const ACTION_MAP = { + add: 'add', + remove: 'delete', +}; +const SHA256_TRAITS = ['IDFA_SHA256', 'AAID_SHA256', 'EMAIL_SHA256', 'PHONE_SHA256']; +module.exports = { + ACTION_MAP, + SHA256_TRAITS, +}; diff --git a/src/cdk/v2/destinations/tiktok_audience/procWorkflow.yaml b/src/cdk/v2/destinations/tiktok_audience/procWorkflow.yaml new file mode 100644 index 0000000000..cd84ecbc87 --- /dev/null +++ b/src/cdk/v2/destinations/tiktok_audience/procWorkflow.yaml @@ -0,0 +1,67 @@ + +bindings: + - name: EventType + path: ../../../../constants + - path: ../../bindings/jsontemplate + exportAll: true + - path: ./config + - name: removeUndefinedAndNullValues + path: ../../../../v0/util + - name: defaultRequestConfig + path: ../../../../v0/util + +steps: + - name: validateInput + template: | + let messageType = .message.type; + $.assert(.message.type, "message Type is not present. Aborting message."); + $.assert(.message.type.toLowerCase() ==='audiencelist', "Event type " + .message.type.toLowerCase() + " is not supported. Aborting message."); + $.assert(.message.properties, "Message properties is not present. Aborting message."); + $.assert(.message.properties.listData, "listData is not present inside properties. Aborting message."); + $.assert($.containsAll(Object.keys(.message.properties.listData), ["add", "remove"]), "unsupported action type. Aborting message.") + + - name: prepareIdentifiersList + description: | + Populate list of identifiers to be updated + template: | + const destinationFields = .message.context.destinationFields.split(", ") + const audienceId = .message.context.externalId[0].type.split("-")[1]; + const isHashRequired = .destination.Config.isHashRequired; + const advertiserIds = .metadata.secret.advertiserIds; + const hashTraits = function(traits) { + traits@trait.(destinationFields@destinationField.( + trait[destinationField] ? { + id: isHashRequired ? + destinationField in $.SHA256_TRAITS ? + $.SHA256(trait[destinationField]) : $.MD5(trait[destinationField]) + : trait[destinationField], + audience_ids:[audienceId] + } : {} + )[]) + }; + const listData = .message.properties.listData; + const actions = Object.keys(listData) + actions@action.({ + "batch_data": hashTraits(listData[action]), + "id_schema": destinationFields, + "advertiser_ids": advertiserIds, + "action": $.ACTION_MAP[action], + })[] + + + - name: buildResponseForProcessTransformation + description: build response + template: | + const accessToken = .metadata.secret.accessToken + const anonymousId = .message.anonymousId; + $.outputs.prepareIdentifiersList@body.( + let response = $.defaultRequestConfig(); + response.body.JSON = body; + response.userId = anonymousId; + response.endpoint = "https://business-api.tiktok.com/open_api/v1.3/segment/mapping/"; + response.headers = { + "Access-Token": accessToken, + "Content-Type": "application/json" + }; + response + ) diff --git a/src/cdk/v2/destinations/tiktok_audience/rtWorkflow.yaml b/src/cdk/v2/destinations/tiktok_audience/rtWorkflow.yaml new file mode 100644 index 0000000000..3db4c405ad --- /dev/null +++ b/src/cdk/v2/destinations/tiktok_audience/rtWorkflow.yaml @@ -0,0 +1,32 @@ +bindings: + - name: handleRtTfSingleEventError + path: ../../../../v0/util/index + +steps: + - name: validateInput + template: | + $.assert(Array.isArray(^) && ^.length > 0, "Invalid event array") + + - name: transform + externalWorkflow: + path: ./procWorkflow.yaml + loopOverInput: true + + - name: successfulEvents + debug: true + template: | + $.outputs.transform#idx{"output" in .}.({ + "batchedRequest": .output, + "batched": true, + "destination": ^[idx].destination, + "metadata": ^[idx].metadata[], + "statusCode": 200 + })[] + - name: failedEvents + template: | + $.outputs.transform#idx.error.( + $.handleRtTfSingleEventError(^[idx], .originalError ?? ., {}) + )[] + - name: finalPayload + template: | + [...$.outputs.failedEvents, ...$.outputs.successfulEvents] diff --git a/src/features.json b/src/features.json index 7de214ab39..fb5b0735f0 100644 --- a/src/features.json +++ b/src/features.json @@ -58,6 +58,7 @@ "OPTIMIZELY_FULLSTACK": true, "TWITTER_ADS": true, "CLEVERTAP": true, + "TIKTOK_AUDIENCE": true, "ORTTO": true } } diff --git a/test/integrations/destinations/tiktok_audience/processor/data.ts b/test/integrations/destinations/tiktok_audience/processor/data.ts new file mode 100644 index 0000000000..a715aa2f72 --- /dev/null +++ b/test/integrations/destinations/tiktok_audience/processor/data.ts @@ -0,0 +1,854 @@ +export const data = [ + { + "name": "tiktok_audience", + "description": "Test 1: Containing SHA256 traits only", + "feature": "processor", + "module": "destination", + "version": "v0", + "input": { + "request": { + "body": [ + { + "message": { + "userId": "user 1", + "type": "audiencelist", + "properties": { + "listData": { + "add": [ + { + "EMAIL_SHA256": "alex@email.com" + }, + { + "EMAIL_SHA256": "amy@abc.com" + }, + { + "EMAIL_SHA256": "van@abc.com" + } + ], + "remove": [ + { + "EMAIL_SHA256": "alex@email.com" + }, + { + "EMAIL_SHA256": "amy@abc.com" + }, + { + "EMAIL_SHA256": "van@abc.com" + } + ] + } + }, + "context": { + "ip": "14.5.67.21", + "library": { + "name": "http" + }, + "externalId": [ + { + "type": "TIKTOK_AUDIENCE-23856594064540489", + "identifierType": "EMAIL_SHA256" + } + ], + "destinationFields": "EMAIL_SHA256" + }, + "timestamp": "2020-02-02T00:23:09.544Z" + }, + "metadata": { + "jobId": 1, + "secret": { + "accessToken": "dummyAccessToken", + "advertiserIds": [ + "dummyAdverTiserID" + ] + } + }, + "destination": { + "DestinationDefinition": { + "Config": { + "cdkV2Enabled": true + } + }, + "Config": { + "isHashRequired": true, + "registerDeviceOrBrowserApiKey": true, + "apiKey": "intercomApiKey", + "appId": "9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0", + "collectContext": false + } + } + } + ] + } + }, + "output": { + "response": { + "status": 200, + "body": [ + { + "output": { + "version": "1", + "type": "REST", + "method": "POST", + "endpoint": "https://business-api.tiktok.com/open_api/v1.3/segment/mapping/", + "headers": { + "Access-Token": "dummyAccessToken", + "Content-Type": "application/json" + }, + "params": {}, + "body": { + "JSON": { + "batch_data": [ + [ + { + "id": "ac0f1baec38a9ef3cfcb56db981df7d9bab2568c7f53ef3776d1c059ec58e72b", + "audience_ids": [ + "23856594064540489" + ] + } + ], + [ + { + "id": "49eaeca26c878f268ad33af8cfa8194ca5b8b8e448b1c775bf9153a2de734579", + "audience_ids": [ + "23856594064540489" + ] + } + ], + [ + { + "id": "2048acfa84a01121060ca2fc8a673a76d427176dc37224d4408c21973bd90e5c", + "audience_ids": [ + "23856594064540489" + ] + } + ] + ], + "id_schema": [ + "EMAIL_SHA256" + ], + "advertiser_ids": [ + "dummyAdverTiserID" + ], + "action": "add" + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "files": {}, + "userId": "" + }, + "metadata": { + "jobId": 1, + "secret": { + "accessToken": "dummyAccessToken", + "advertiserIds": [ + "dummyAdverTiserID" + ] + } + }, + "statusCode": 200 + }, + { + "output": { + "version": "1", + "type": "REST", + "method": "POST", + "endpoint": "https://business-api.tiktok.com/open_api/v1.3/segment/mapping/", + "headers": { + "Access-Token": "dummyAccessToken", + "Content-Type": "application/json" + }, + "params": {}, + "body": { + "JSON": { + "batch_data": [ + [ + { + "id": "ac0f1baec38a9ef3cfcb56db981df7d9bab2568c7f53ef3776d1c059ec58e72b", + "audience_ids": [ + "23856594064540489" + ] + } + ], + [ + { + "id": "49eaeca26c878f268ad33af8cfa8194ca5b8b8e448b1c775bf9153a2de734579", + "audience_ids": [ + "23856594064540489" + ] + } + ], + [ + { + "id": "2048acfa84a01121060ca2fc8a673a76d427176dc37224d4408c21973bd90e5c", + "audience_ids": [ + "23856594064540489" + ] + } + ] + ], + "id_schema": [ + "EMAIL_SHA256" + ], + "advertiser_ids": [ + "dummyAdverTiserID" + ], + "action": "delete" + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "files": {}, + "userId": "" + }, + "metadata": { + "jobId": 1, + "secret": { + "accessToken": "dummyAccessToken", + "advertiserIds": [ + "dummyAdverTiserID" + ] + } + }, + "statusCode": 200 + } + ] + } + } + }, + { + "name": "tiktok_audience", + "description": "Test 2: Containing SHA256 and MD5 traits", + "feature": "processor", + "module": "destination", + "version": "v0", + "input": { + "request": { + "body": [ + { + "message": { + "userId": "user 1", + "type": "audiencelist", + "properties": { + "listData": { + "add": [ + { + "EMAIL_SHA256": "alex@email.com", + "AAID_MD5": "1234567" + }, + { + "EMAIL_SHA256": "amy@abc.com", + "AAID_MD5": "1234568" + }, + { + "EMAIL_SHA256": "van@abc.com", + "AAID_MD5": "1234569" + } + ], + "remove": [ + { + "EMAIL_SHA256": "alex@email.com", + "AAID_MD5": "1234570" + }, + { + "EMAIL_SHA256": "amy@abc.com", + "AAID_MD5": "1234571" + }, + { + "EMAIL_SHA256": "van@abc.com", + "AAID_MD5": "1234572" + } + ] + } + }, + "context": { + "ip": "14.5.67.21", + "library": { + "name": "http" + }, + "externalId": [ + { + "type": "TIKTOK_AUDIENCE-23856594064540489", + "identifierType": "EMAIL_SHA256" + } + ], + "destinationFields": "EMAIL_SHA256, AAID_MD5" + }, + "timestamp": "2020-02-02T00:23:09.544Z" + }, + "metadata": { + "jobId": 1, + "secret": { + "accessToken": "dummyAccessToken", + "advertiserIds": [ + "dummyAdverTiserID" + ] + } + }, + "destination": { + "DestinationDefinition": { + "Config": { + "cdkV2Enabled": true + } + }, + "Config": { + "isHashRequired": true, + "registerDeviceOrBrowserApiKey": true, + "apiKey": "intercomApiKey", + "appId": "9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0", + "collectContext": false + } + } + } + ] + } + }, + "output": { + "response": { + "status": 200, + "body": [ + { + "output": { + "version": "1", + "type": "REST", + "method": "POST", + "endpoint": "https://business-api.tiktok.com/open_api/v1.3/segment/mapping/", + "headers": { + "Access-Token": "dummyAccessToken", + "Content-Type": "application/json" + }, + "params": {}, + "body": { + "JSON": { + "batch_data": [ + [ + { + "id": "ac0f1baec38a9ef3cfcb56db981df7d9bab2568c7f53ef3776d1c059ec58e72b", + "audience_ids": [ + "23856594064540489" + ] + }, + { + "id": "fcea920f7412b5da7be0cf42b8c93759", + "audience_ids": [ + "23856594064540489" + ] + } + ], + [ + { + "id": "49eaeca26c878f268ad33af8cfa8194ca5b8b8e448b1c775bf9153a2de734579", + "audience_ids": [ + "23856594064540489" + ] + }, + { + "id": "fe743d8d97aa7dfc6c93ccdc2e749513", + "audience_ids": [ + "23856594064540489" + ] + } + ], + [ + { + "id": "2048acfa84a01121060ca2fc8a673a76d427176dc37224d4408c21973bd90e5c", + "audience_ids": [ + "23856594064540489" + ] + }, + { + "id": "e36a2f90240e9e84483504fd4a704452", + "audience_ids": [ + "23856594064540489" + ] + } + ] + ], + "id_schema": [ + "EMAIL_SHA256", + "AAID_MD5" + ], + "advertiser_ids": [ + "dummyAdverTiserID" + ], + "action": "add" + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "files": {}, + "userId": "" + }, + "metadata": { + "jobId": 1, + "secret": { + "accessToken": "dummyAccessToken", + "advertiserIds": [ + "dummyAdverTiserID" + ] + } + }, + "statusCode": 200 + }, + { + "output": { + "version": "1", + "type": "REST", + "method": "POST", + "endpoint": "https://business-api.tiktok.com/open_api/v1.3/segment/mapping/", + "headers": { + "Access-Token": "dummyAccessToken", + "Content-Type": "application/json" + }, + "params": {}, + "body": { + "JSON": { + "batch_data": [ + [ + { + "id": "ac0f1baec38a9ef3cfcb56db981df7d9bab2568c7f53ef3776d1c059ec58e72b", + "audience_ids": [ + "23856594064540489" + ] + }, + { + "id": "c1abd65fea29d573ddef1bce925e3276", + "audience_ids": [ + "23856594064540489" + ] + } + ], + [ + { + "id": "49eaeca26c878f268ad33af8cfa8194ca5b8b8e448b1c775bf9153a2de734579", + "audience_ids": [ + "23856594064540489" + ] + }, + { + "id": "7298110702a080dfc6903f13333eb04a", + "audience_ids": [ + "23856594064540489" + ] + } + ], + [ + { + "id": "2048acfa84a01121060ca2fc8a673a76d427176dc37224d4408c21973bd90e5c", + "audience_ids": [ + "23856594064540489" + ] + }, + { + "id": "d9cb68b1fd3b9d32abc5f4cab8b42b68", + "audience_ids": [ + "23856594064540489" + ] + } + ] + ], + "id_schema": [ + "EMAIL_SHA256", + "AAID_MD5" + ], + "advertiser_ids": [ + "dummyAdverTiserID" + ], + "action": "delete" + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "files": {}, + "userId": "" + }, + "metadata": { + "jobId": 1, + "secret": { + "accessToken": "dummyAccessToken", + "advertiserIds": [ + "dummyAdverTiserID" + ] + } + }, + "statusCode": 200 + } + ] + } + } + }, + { + "name": "tiktok_audience", + "description": "Test 3: Containing all possible traits", + "feature": "processor", + "module": "destination", + "version": "v0", + "input": { + "request": { + "body": [ + { + "message": { + "userId": "user 1", + "type": "audiencelist", + "properties": { + "listData": { + "add": [ + { + "EMAIL_SHA256": "alex@email.com", + "PHONE_SHA256": "+129988776655", + "IDFA_SHA256": "1234lkasfjdalj12321", + "AAID_SHA256": "000999OOOQQQQ", + "AAID_MD5": "000999OOOQQQQ", + "IDFA_MD5": "1234lkasfjdalj12321" + }, + { + "EMAIL_SHA256": "amy@abc.com", + "PHONE_SHA256": "+129988776677", + "IDFA_SHA256": "1234lkasfjdalj114455", + "AAID_SHA256": "000999OOOPPPP", + "AAID_MD5": "000999OOOPPPP", + "IDFA_MD5": "1234lkasfjdalj114455" + } + ] + } + }, + "context": { + "ip": "14.5.67.21", + "library": { + "name": "http" + }, + "externalId": [ + { + "type": "TIKTOK_AUDIENCE-23856594064540489", + "identifierType": "EMAIL_SHA256" + } + ], + "destinationFields": "EMAIL_SHA256, PHONE_SHA256, IDFA_SHA256, AAID_SHA256, AAID_MD, IDFA_MD5" + }, + "timestamp": "2020-02-02T00:23:09.544Z" + }, + "metadata": { + "jobId": 1, + "secret": { + "accessToken": "dummyAccessToken", + "advertiserIds": [ + "dummyAdverTiserID" + ] + } + }, + "destination": { + "DestinationDefinition": { + "Config": { + "cdkV2Enabled": true + } + }, + "Config": { + "isHashRequired": true, + "registerDeviceOrBrowserApiKey": true, + "apiKey": "intercomApiKey", + "appId": "9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0", + "collectContext": false + } + } + } + ] + } + }, + "output": { + "response": { + "status": 200, + "body": [ + { + "output": { + "version": "1", + "type": "REST", + "method": "POST", + "endpoint": "https://business-api.tiktok.com/open_api/v1.3/segment/mapping/", + "headers": { + "Access-Token": "dummyAccessToken", + "Content-Type": "application/json" + }, + "params": {}, + "body": { + "JSON": { + "batch_data": [ + [ + { + "id": "ac0f1baec38a9ef3cfcb56db981df7d9bab2568c7f53ef3776d1c059ec58e72b", + "audience_ids": [ + "23856594064540489" + ] + }, + { + "id": "31e78a3bf9ce2b43316f64fe883a531d6266938091e94e2f2480272481163dee", + "audience_ids": [ + "23856594064540489" + ] + }, + { + "id": "0259f595f7172c8dd692a5c37b4d296939555f862aae8adb964391bdb65006ab", + "audience_ids": [ + "23856594064540489" + ] + }, + { + "id": "b06fbe7a29f33576a792ba3df3c9bf838cd26ea88cf574285fa60dc0234a8485", + "audience_ids": [ + "23856594064540489" + ] + }, + {}, + { + "id": "32ee3d063320815a13e0058c2498ff76", + "audience_ids": [ + "23856594064540489" + ] + } + ], + [ + { + "id": "49eaeca26c878f268ad33af8cfa8194ca5b8b8e448b1c775bf9153a2de734579", + "audience_ids": [ + "23856594064540489" + ] + }, + { + "id": "fb40adc7debbf40e7b45b0a4a91886785dff1a28809276f95f1c44f7045f9b4d", + "audience_ids": [ + "23856594064540489" + ] + }, + { + "id": "e6bbdf34c5f3472f31b2923a26811560a599233f3dea4c9971595c3bb7b1e8dc", + "audience_ids": [ + "23856594064540489" + ] + }, + { + "id": "661125f7d337811256c5b55996b22c89047804dcec494db72659e4be71e03091", + "audience_ids": [ + "23856594064540489" + ] + }, + {}, + { + "id": "94162773066d6ae88b2658dc58ca2317", + "audience_ids": [ + "23856594064540489" + ] + } + ] + ], + "id_schema": [ + "EMAIL_SHA256", + "PHONE_SHA256", + "IDFA_SHA256", + "AAID_SHA256", + "AAID_MD", + "IDFA_MD5" + ], + "advertiser_ids": [ + "dummyAdverTiserID" + ], + "action": "add" + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "files": {}, + "userId": "" + }, + "metadata": { + "jobId": 1, + "secret": { + "accessToken": "dummyAccessToken", + "advertiserIds": [ + "dummyAdverTiserID" + ] + } + }, + "statusCode": 200 + } + ] + } + } + }, + { + "name": "tiktok_audience", + "description": "Test 4: Considering some null values", + "feature": "processor", + "module": "destination", + "version": "v0", + "input": { + "request": { + "body": [ + { + "message": { + "userId": "user 1", + "type": "audiencelist", + "properties": { + "listData": { + "add": [ + { + "EMAIL_SHA256": "alex@email.com", + "PHONE_SHA256": "+129988776655", + "AAID_MD5": "000999OOOQQQQ", + "IDFA_MD5": "1234lkasfjdalj12321" + }, + { + "EMAIL_SHA256": "amy@abc.com", + "AAID_SHA256": "000999OOOPPPP", + "AAID_MD5": "000999OOOPPPP", + "IDFA_MD5": "1234lkasfjdalj114455" + } + ] + } + }, + "context": { + "ip": "14.5.67.21", + "library": { + "name": "http" + }, + "externalId": [ + { + "type": "TIKTOK_AUDIENCE-23856594064540489", + "identifierType": "EMAIL_SHA256" + } + ], + "destinationFields": "EMAIL_SHA256, PHONE_SHA256, IDFA_SHA256, AAID_SHA256, AAID_MD, IDFA_MD5" + }, + "timestamp": "2020-02-02T00:23:09.544Z" + }, + "metadata": { + "jobId": 1, + "secret": { + "accessToken": "dummyAccessToken", + "advertiserIds": [ + "dummyAdverTiserID" + ] + } + }, + "destination": { + "DestinationDefinition": { + "Config": { + "cdkV2Enabled": true + } + }, + "Config": { + "isHashRequired": true, + "registerDeviceOrBrowserApiKey": true, + "apiKey": "intercomApiKey", + "appId": "9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0", + "collectContext": false + } + } + } + ] + } + }, + "output": { + "response": { + "status": 200, + "body": [ + { + "output": { + "version": "1", + "type": "REST", + "method": "POST", + "endpoint": "https://business-api.tiktok.com/open_api/v1.3/segment/mapping/", + "headers": { + "Access-Token": "dummyAccessToken", + "Content-Type": "application/json" + }, + "params": {}, + "body": { + "JSON": { + "batch_data": [ + [ + { + "id": "ac0f1baec38a9ef3cfcb56db981df7d9bab2568c7f53ef3776d1c059ec58e72b", + "audience_ids": [ + "23856594064540489" + ] + }, + { + "id": "31e78a3bf9ce2b43316f64fe883a531d6266938091e94e2f2480272481163dee", + "audience_ids": [ + "23856594064540489" + ] + }, + {}, + {}, + {}, + { + "id": "32ee3d063320815a13e0058c2498ff76", + "audience_ids": [ + "23856594064540489" + ] + } + ], + [ + { + "id": "49eaeca26c878f268ad33af8cfa8194ca5b8b8e448b1c775bf9153a2de734579", + "audience_ids": [ + "23856594064540489" + ] + }, + {}, + {}, + { + "id": "661125f7d337811256c5b55996b22c89047804dcec494db72659e4be71e03091", + "audience_ids": [ + "23856594064540489" + ] + }, + {}, + { + "id": "94162773066d6ae88b2658dc58ca2317", + "audience_ids": [ + "23856594064540489" + ] + } + ] + ], + "id_schema": [ + "EMAIL_SHA256", + "PHONE_SHA256", + "IDFA_SHA256", + "AAID_SHA256", + "AAID_MD", + "IDFA_MD5" + ], + "advertiser_ids": [ + "dummyAdverTiserID" + ], + "action": "add" + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "files": {}, + "userId": "" + }, + "metadata": { + "jobId": 1, + "secret": { + "accessToken": "dummyAccessToken", + "advertiserIds": [ + "dummyAdverTiserID" + ] + } + }, + "statusCode": 200 + } + ] + } + } + } +] \ No newline at end of file diff --git a/test/integrations/destinations/tiktok_audience/router/data.ts b/test/integrations/destinations/tiktok_audience/router/data.ts new file mode 100644 index 0000000000..c8a8b93d30 --- /dev/null +++ b/test/integrations/destinations/tiktok_audience/router/data.ts @@ -0,0 +1,833 @@ +export const data = [ + { + name: 'tiktok_audience', + description: 'Multiple jobs with different metadata', + feature: 'router', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + input: [ + { + message: { + userId: 'user 1', + type: 'audiencelist', + properties: { + listData: { + add: [ + { + EMAIL_SHA256: 'alex@email.com', + }, + { + EMAIL_SHA256: 'amy@abc.com', + }, + { + EMAIL_SHA256: 'van@abc.com', + }, + ], + remove: [ + { + EMAIL_SHA256: 'alex@email.com', + }, + { + EMAIL_SHA256: 'amy@abc.com', + }, + { + EMAIL_SHA256: 'van@abc.com', + }, + ], + }, + }, + context: { + ip: '14.5.67.21', + library: { + name: 'http', + }, + externalId: [ + { + type: 'TIKTOK_AUDIENCE-23856594064540489', + identifierType: 'EMAIL_SHA256', + }, + ], + destinationFields: 'EMAIL_SHA256', + }, + timestamp: '2020-02-02T00:23:09.544Z', + }, + metadata: { + jobId: 1, + secret: { + accessToken: 'dummyAccessToken', + advertiserIds: ['dummyAdverTiserID'], + }, + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + isHashRequired: true, + registerDeviceOrBrowserApiKey: true, + apiKey: 'intercomApiKey', + appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', + collectContext: false, + }, + }, + }, + { + message: { + userId: 'user 1', + type: 'audiencelist', + properties: { + listData: { + add: [ + { + EMAIL_SHA256: 'alex@email.com', + AAID_MD5: '1234567', + }, + { + EMAIL_SHA256: 'amy@abc.com', + AAID_MD5: '1234568', + }, + { + EMAIL_SHA256: 'van@abc.com', + AAID_MD5: '1234569', + }, + ], + remove: [ + { + EMAIL_SHA256: 'alex@email.com', + AAID_MD5: '1234570', + }, + { + EMAIL_SHA256: 'amy@abc.com', + AAID_MD5: '1234571', + }, + { + EMAIL_SHA256: 'van@abc.com', + AAID_MD5: '1234572', + }, + ], + }, + }, + context: { + ip: '14.5.67.21', + library: { + name: 'http', + }, + externalId: [ + { + type: 'TIKTOK_AUDIENCE-23856594064540489', + identifierType: 'EMAIL_SHA256', + }, + ], + destinationFields: 'EMAIL_SHA256, AAID_MD5', + }, + timestamp: '2020-02-02T00:23:09.544Z', + }, + metadata: { + jobId: 2, + secret: { + accessToken: 'dummyAccessToken', + advertiserIds: ['dummyAdverTiserID'], + }, + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + isHashRequired: true, + registerDeviceOrBrowserApiKey: true, + apiKey: 'intercomApiKey', + appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', + collectContext: false, + }, + }, + }, + { + message: { + userId: 'user 1', + type: 'audiencelist', + properties: { + listData: { + add: [ + { + EMAIL_SHA256: 'alex@email.com', + PHONE_SHA256: '+129988776655', + IDFA_SHA256: '1234lkasfjdalj12321', + AAID_SHA256: '000999OOOQQQQ', + AAID_MD5: '000999OOOQQQQ', + IDFA_MD5: '1234lkasfjdalj12321', + }, + { + EMAIL_SHA256: 'amy@abc.com', + PHONE_SHA256: '+129988776677', + IDFA_SHA256: '1234lkasfjdalj114455', + AAID_SHA256: '000999OOOPPPP', + AAID_MD5: '000999OOOPPPP', + IDFA_MD5: '1234lkasfjdalj114455', + }, + ], + }, + }, + context: { + ip: '14.5.67.21', + library: { + name: 'http', + }, + externalId: [ + { + type: 'TIKTOK_AUDIENCE-23856594064540489', + identifierType: 'EMAIL_SHA256', + }, + ], + destinationFields: + 'EMAIL_SHA256, PHONE_SHA256, IDFA_SHA256, AAID_SHA256, AAID_MD, IDFA_MD5', + }, + timestamp: '2020-02-02T00:23:09.544Z', + }, + metadata: { + jobId: 3, + secret: { + accessToken: 'dummyAccessToken', + advertiserIds: ['dummyAdverTiserID'], + }, + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + isHashRequired: true, + registerDeviceOrBrowserApiKey: true, + apiKey: 'intercomApiKey', + appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', + collectContext: false, + }, + }, + }, + { + message: { + userId: 'user 1', + type: 'audiencelist', + properties: { + listData: { + add: [ + { + EMAIL_SHA256: 'alex@email.com', + PHONE_SHA256: '+129988776655', + AAID_MD5: '000999OOOQQQQ', + IDFA_MD5: '1234lkasfjdalj12321', + }, + { + EMAIL_SHA256: 'amy@abc.com', + AAID_SHA256: '000999OOOPPPP', + AAID_MD5: '000999OOOPPPP', + IDFA_MD5: '1234lkasfjdalj114455', + }, + ], + }, + }, + context: { + ip: '14.5.67.21', + library: { + name: 'http', + }, + externalId: [ + { + type: 'TIKTOK_AUDIENCE-23856594064540489', + identifierType: 'EMAIL_SHA256', + }, + ], + destinationFields: + 'EMAIL_SHA256, PHONE_SHA256, IDFA_SHA256, AAID_SHA256, AAID_MD, IDFA_MD5', + }, + timestamp: '2020-02-02T00:23:09.544Z', + }, + metadata: { + jobId: 4, + secret: { + accessToken: 'dummyAccessToken', + advertiserIds: ['dummyAdverTiserID'], + }, + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + isHashRequired: true, + registerDeviceOrBrowserApiKey: true, + apiKey: 'intercomApiKey', + appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', + collectContext: false, + }, + }, + }, + { + message: { + userId: 'user 1', + properties: { + listData: { + add: [ + { + EMAIL_SHA256: 'alex@email.com', + PHONE_SHA256: '+129988776655', + AAID_MD5: '000999OOOQQQQ', + IDFA_MD5: '1234lkasfjdalj12321', + }, + { + EMAIL_SHA256: 'amy@abc.com', + AAID_SHA256: '000999OOOPPPP', + AAID_MD5: '000999OOOPPPP', + IDFA_MD5: '1234lkasfjdalj114455', + }, + ], + }, + }, + context: { + ip: '14.5.67.21', + library: { + name: 'http', + }, + externalId: [ + { + type: 'TIKTOK_AUDIENCE-23856594064540489', + identifierType: 'EMAIL_SHA256', + }, + ], + destinationFields: + 'EMAIL_SHA256, PHONE_SHA256, IDFA_SHA256, AAID_SHA256, AAID_MD, IDFA_MD5', + }, + timestamp: '2020-02-02T00:23:09.544Z', + }, + metadata: { + jobId: 1524545, + secret: { + accessToken: 'dummyAccessToken', + advertiserIds: ['dummyAdverTiserID'], + }, + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + isHashRequired: true, + registerDeviceOrBrowserApiKey: true, + apiKey: 'intercomApiKey', + appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', + collectContext: false, + }, + }, + }, + ], + destType: 'tiktok_audience', + }, + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: [ + { + error: 'message Type is not present. Aborting message.', + batched: false, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + isHashRequired: true, + registerDeviceOrBrowserApiKey: true, + apiKey: 'intercomApiKey', + appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', + collectContext: false, + }, + }, + metadata: [ + { + jobId: 1524545, + secret: { + accessToken: 'dummyAccessToken', + advertiserIds: ['dummyAdverTiserID'], + }, + }, + ], + statTags: { + destType: 'TIKTOK_AUDIENCE', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'router', + implementation: 'cdkV2', + module: 'destination', + }, + statusCode: 400, + }, + { + batchedRequest: [ + { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://business-api.tiktok.com/open_api/v1.3/segment/mapping/', + headers: { + 'Access-Token': 'dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + batch_data: [ + [ + { + id: 'ac0f1baec38a9ef3cfcb56db981df7d9bab2568c7f53ef3776d1c059ec58e72b', + audience_ids: ['23856594064540489'], + }, + ], + [ + { + id: '49eaeca26c878f268ad33af8cfa8194ca5b8b8e448b1c775bf9153a2de734579', + audience_ids: ['23856594064540489'], + }, + ], + [ + { + id: '2048acfa84a01121060ca2fc8a673a76d427176dc37224d4408c21973bd90e5c', + audience_ids: ['23856594064540489'], + }, + ], + ], + id_schema: ['EMAIL_SHA256'], + advertiser_ids: ['dummyAdverTiserID'], + action: 'add', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + }, + { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://business-api.tiktok.com/open_api/v1.3/segment/mapping/', + headers: { + 'Access-Token': 'dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + batch_data: [ + [ + { + id: 'ac0f1baec38a9ef3cfcb56db981df7d9bab2568c7f53ef3776d1c059ec58e72b', + audience_ids: ['23856594064540489'], + }, + ], + [ + { + id: '49eaeca26c878f268ad33af8cfa8194ca5b8b8e448b1c775bf9153a2de734579', + audience_ids: ['23856594064540489'], + }, + ], + [ + { + id: '2048acfa84a01121060ca2fc8a673a76d427176dc37224d4408c21973bd90e5c', + audience_ids: ['23856594064540489'], + }, + ], + ], + id_schema: ['EMAIL_SHA256'], + advertiser_ids: ['dummyAdverTiserID'], + action: 'delete', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + }, + ], + batched: true, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + isHashRequired: true, + registerDeviceOrBrowserApiKey: true, + apiKey: 'intercomApiKey', + appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', + collectContext: false, + }, + }, + metadata: [ + { + jobId: 1, + secret: { + accessToken: 'dummyAccessToken', + advertiserIds: ['dummyAdverTiserID'], + }, + }, + ], + statusCode: 200, + }, + { + batchedRequest: [ + { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://business-api.tiktok.com/open_api/v1.3/segment/mapping/', + headers: { + 'Access-Token': 'dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + batch_data: [ + [ + { + id: 'ac0f1baec38a9ef3cfcb56db981df7d9bab2568c7f53ef3776d1c059ec58e72b', + audience_ids: ['23856594064540489'], + }, + { + id: 'fcea920f7412b5da7be0cf42b8c93759', + audience_ids: ['23856594064540489'], + }, + ], + [ + { + id: '49eaeca26c878f268ad33af8cfa8194ca5b8b8e448b1c775bf9153a2de734579', + audience_ids: ['23856594064540489'], + }, + { + id: 'fe743d8d97aa7dfc6c93ccdc2e749513', + audience_ids: ['23856594064540489'], + }, + ], + [ + { + id: '2048acfa84a01121060ca2fc8a673a76d427176dc37224d4408c21973bd90e5c', + audience_ids: ['23856594064540489'], + }, + { + id: 'e36a2f90240e9e84483504fd4a704452', + audience_ids: ['23856594064540489'], + }, + ], + ], + id_schema: ['EMAIL_SHA256', 'AAID_MD5'], + advertiser_ids: ['dummyAdverTiserID'], + action: 'add', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + }, + { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://business-api.tiktok.com/open_api/v1.3/segment/mapping/', + headers: { + 'Access-Token': 'dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + batch_data: [ + [ + { + id: 'ac0f1baec38a9ef3cfcb56db981df7d9bab2568c7f53ef3776d1c059ec58e72b', + audience_ids: ['23856594064540489'], + }, + { + id: 'c1abd65fea29d573ddef1bce925e3276', + audience_ids: ['23856594064540489'], + }, + ], + [ + { + id: '49eaeca26c878f268ad33af8cfa8194ca5b8b8e448b1c775bf9153a2de734579', + audience_ids: ['23856594064540489'], + }, + { + id: '7298110702a080dfc6903f13333eb04a', + audience_ids: ['23856594064540489'], + }, + ], + [ + { + id: '2048acfa84a01121060ca2fc8a673a76d427176dc37224d4408c21973bd90e5c', + audience_ids: ['23856594064540489'], + }, + { + id: 'd9cb68b1fd3b9d32abc5f4cab8b42b68', + audience_ids: ['23856594064540489'], + }, + ], + ], + id_schema: ['EMAIL_SHA256', 'AAID_MD5'], + advertiser_ids: ['dummyAdverTiserID'], + action: 'delete', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + }, + ], + batched: true, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + isHashRequired: true, + registerDeviceOrBrowserApiKey: true, + apiKey: 'intercomApiKey', + appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', + collectContext: false, + }, + }, + metadata: [ + { + jobId: 2, + secret: { + accessToken: 'dummyAccessToken', + advertiserIds: ['dummyAdverTiserID'], + }, + }, + ], + statusCode: 200, + }, + { + batchedRequest: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://business-api.tiktok.com/open_api/v1.3/segment/mapping/', + headers: { + 'Access-Token': 'dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + batch_data: [ + [ + { + id: 'ac0f1baec38a9ef3cfcb56db981df7d9bab2568c7f53ef3776d1c059ec58e72b', + audience_ids: ['23856594064540489'], + }, + { + id: '31e78a3bf9ce2b43316f64fe883a531d6266938091e94e2f2480272481163dee', + audience_ids: ['23856594064540489'], + }, + { + id: '0259f595f7172c8dd692a5c37b4d296939555f862aae8adb964391bdb65006ab', + audience_ids: ['23856594064540489'], + }, + { + id: 'b06fbe7a29f33576a792ba3df3c9bf838cd26ea88cf574285fa60dc0234a8485', + audience_ids: ['23856594064540489'], + }, + {}, + { + id: '32ee3d063320815a13e0058c2498ff76', + audience_ids: ['23856594064540489'], + }, + ], + [ + { + id: '49eaeca26c878f268ad33af8cfa8194ca5b8b8e448b1c775bf9153a2de734579', + audience_ids: ['23856594064540489'], + }, + { + id: 'fb40adc7debbf40e7b45b0a4a91886785dff1a28809276f95f1c44f7045f9b4d', + audience_ids: ['23856594064540489'], + }, + { + id: 'e6bbdf34c5f3472f31b2923a26811560a599233f3dea4c9971595c3bb7b1e8dc', + audience_ids: ['23856594064540489'], + }, + { + id: '661125f7d337811256c5b55996b22c89047804dcec494db72659e4be71e03091', + audience_ids: ['23856594064540489'], + }, + {}, + { + id: '94162773066d6ae88b2658dc58ca2317', + audience_ids: ['23856594064540489'], + }, + ], + ], + id_schema: [ + 'EMAIL_SHA256', + 'PHONE_SHA256', + 'IDFA_SHA256', + 'AAID_SHA256', + 'AAID_MD', + 'IDFA_MD5', + ], + advertiser_ids: ['dummyAdverTiserID'], + action: 'add', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + }, + batched: true, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + isHashRequired: true, + registerDeviceOrBrowserApiKey: true, + apiKey: 'intercomApiKey', + appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', + collectContext: false, + }, + }, + metadata: [ + { + jobId: 3, + secret: { + accessToken: 'dummyAccessToken', + advertiserIds: ['dummyAdverTiserID'], + }, + }, + ], + statusCode: 200, + }, + { + batchedRequest: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://business-api.tiktok.com/open_api/v1.3/segment/mapping/', + headers: { + 'Access-Token': 'dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + batch_data: [ + [ + { + id: 'ac0f1baec38a9ef3cfcb56db981df7d9bab2568c7f53ef3776d1c059ec58e72b', + audience_ids: ['23856594064540489'], + }, + { + id: '31e78a3bf9ce2b43316f64fe883a531d6266938091e94e2f2480272481163dee', + audience_ids: ['23856594064540489'], + }, + {}, + {}, + {}, + { + id: '32ee3d063320815a13e0058c2498ff76', + audience_ids: ['23856594064540489'], + }, + ], + [ + { + id: '49eaeca26c878f268ad33af8cfa8194ca5b8b8e448b1c775bf9153a2de734579', + audience_ids: ['23856594064540489'], + }, + {}, + {}, + { + id: '661125f7d337811256c5b55996b22c89047804dcec494db72659e4be71e03091', + audience_ids: ['23856594064540489'], + }, + {}, + { + id: '94162773066d6ae88b2658dc58ca2317', + audience_ids: ['23856594064540489'], + }, + ], + ], + id_schema: [ + 'EMAIL_SHA256', + 'PHONE_SHA256', + 'IDFA_SHA256', + 'AAID_SHA256', + 'AAID_MD', + 'IDFA_MD5', + ], + advertiser_ids: ['dummyAdverTiserID'], + action: 'add', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + }, + batched: true, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + isHashRequired: true, + registerDeviceOrBrowserApiKey: true, + apiKey: 'intercomApiKey', + appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', + collectContext: false, + }, + }, + metadata: [ + { + jobId: 4, + secret: { + accessToken: 'dummyAccessToken', + advertiserIds: ['dummyAdverTiserID'], + }, + }, + ], + statusCode: 200, + }, + ], + }, + }, + }, + }, +]; From bc1a76066c0aeb43776ded0b266ec48f5e69aa16 Mon Sep 17 00:00:00 2001 From: Jayc Date: Tue, 31 Oct 2023 20:29:55 +0530 Subject: [PATCH 08/93] feat: add support to add custom network policies for specific workspaces in faas pods --- src/util/customTransformer-faas.js | 16 ++++++-- src/util/openfaas/index.js | 62 +++++++++++++++++++++++++----- src/v0/util/index.js | 7 ++++ 3 files changed, 71 insertions(+), 14 deletions(-) diff --git a/src/util/customTransformer-faas.js b/src/util/customTransformer-faas.js index d1fa48d2d1..54d2410313 100644 --- a/src/util/customTransformer-faas.js +++ b/src/util/customTransformer-faas.js @@ -1,7 +1,7 @@ const { v4: uuidv4 } = require('uuid'); const crypto = require('crypto'); const NodeCache = require('node-cache'); -const { getMetadata } = require('../v0/util'); +const { getMetadata, getTransformationMetadata } = require('../v0/util'); const stats = require('./stats'); const { setupFaasFunction, @@ -82,10 +82,10 @@ async function setOpenFaasUserTransform( libraryVersionIds, pregeneratedFnName, testMode = false, + trMetadata = {}, ) { const tags = { transformerVersionId: userTransformation.versionId, - language: userTransformation.language, identifier: 'openfaas', testMode, }; @@ -106,6 +106,7 @@ async function setOpenFaasUserTransform( testMode, ), testMode, + trMetadata, ); stats.timing('creation_time', setupTime, tags); @@ -129,16 +130,22 @@ async function runOpenFaasUserTransform( const metaTags = events[0].metadata ? getMetadata(events[0].metadata) : {}; const tags = { transformerVersionId: userTransformation.versionId, - language: userTransformation.language, identifier: 'openfaas', testMode, ...metaTags, }; + const trMetadata = events[0].metadata ? getTransformationMetadata(events[0].metadata) : {}; // check and deploy faas function if not exists const functionName = generateFunctionName(userTransformation, libraryVersionIds, testMode); if (testMode) { - await setOpenFaasUserTransform(userTransformation, libraryVersionIds, functionName, testMode); + await setOpenFaasUserTransform( + userTransformation, + libraryVersionIds, + functionName, + testMode, + trMetadata, + ); } const invokeTime = new Date(); @@ -156,6 +163,7 @@ async function runOpenFaasUserTransform( testMode, ), testMode, + trMetadata, ); stats.timing('run_time', invokeTime, tags); return result; diff --git a/src/util/openfaas/index.js b/src/util/openfaas/index.js index 60ad316e1b..f80aa01c23 100644 --- a/src/util/openfaas/index.js +++ b/src/util/openfaas/index.js @@ -23,6 +23,8 @@ const CONFIG_BACKEND_URL = process.env.CONFIG_BACKEND_URL || 'https://api.rudder const GEOLOCATION_URL = process.env.GEOLOCATION_URL || ''; const FAAS_AST_VID = 'ast'; const FAAS_AST_FN_NAME = 'fn-ast'; +const CUSTOM_NETWORK_POLICY_WORKSPACE_IDS = process.env.CUSTOM_NETWORK_POLICY_WORKSPACE_IDS || ''; +const customNetworkPolicyWorkspaceIds = CUSTOM_NETWORK_POLICY_WORKSPACE_IDS.split(','); // Initialise node cache const functionListCache = new NodeCache(); @@ -111,7 +113,14 @@ const invalidateFnCache = () => { functionListCache.set(FUNC_LIST_KEY, []); }; -const deployFaasFunction = async (functionName, code, versionId, libraryVersionIDs, testMode) => { +const deployFaasFunction = async ( + functionName, + code, + versionId, + libraryVersionIDs, + testMode, + trMetadata = {}, +) => { try { logger.debug('[Faas] Deploying a faas function'); let envProcess = 'python index.py'; @@ -132,6 +141,22 @@ const deployFaasFunction = async (functionName, code, versionId, libraryVersionI if (GEOLOCATION_URL) { envVars.geolocation_url = GEOLOCATION_URL; } + // labels + const labels = { + 'openfaas-fn': 'true', + 'parent-component': 'openfaas', + 'com.openfaas.scale.max': FAAS_MAX_PODS_IN_TEXT, + 'com.openfaas.scale.min': FAAS_MIN_PODS_IN_TEXT, + transformationId: trMetadata.transformationId, + workspaceId: trMetadata.workspaceId, + }; + if ( + trMetadata.workspaceId && + customNetworkPolicyWorkspaceIds.includes(trMetadata.workspaceId) + ) { + labels['custom-network-policy'] = 'true'; + } + // TODO: investigate and add more required labels and annotations const payload = { service: functionName, @@ -139,12 +164,7 @@ const deployFaasFunction = async (functionName, code, versionId, libraryVersionI image: FAAS_BASE_IMG, envProcess, envVars, - labels: { - 'openfaas-fn': 'true', - 'parent-component': 'openfaas', - 'com.openfaas.scale.max': FAAS_MAX_PODS_IN_TEXT, - 'com.openfaas.scale.min': FAAS_MIN_PODS_IN_TEXT, - }, + labels, annotations: { 'prometheus.io.scrape': 'true', }, @@ -175,14 +195,28 @@ const deployFaasFunction = async (functionName, code, versionId, libraryVersionI } }; -async function setupFaasFunction(functionName, code, versionId, libraryVersionIDs, testMode) { +async function setupFaasFunction( + functionName, + code, + versionId, + libraryVersionIDs, + testMode, + trMetadata = {}, +) { try { if (!testMode && isFunctionDeployed(functionName)) { logger.debug(`[Faas] Function ${functionName} already deployed`); return; } // deploy faas function - await deployFaasFunction(functionName, code, versionId, libraryVersionIDs, testMode); + await deployFaasFunction( + functionName, + code, + versionId, + libraryVersionIDs, + testMode, + trMetadata, + ); // This api call is only used to check if function is spinned correctly await awaitFunctionReadiness(functionName); @@ -201,6 +235,7 @@ const executeFaasFunction = async ( versionId, libraryVersionIDs, testMode, + trMetadata = {}, ) => { try { logger.debug('[Faas] Invoking faas function'); @@ -217,7 +252,14 @@ const executeFaasFunction = async ( error.message.includes(`error finding function ${functionName}`) ) { removeFunctionFromCache(functionName); - await setupFaasFunction(functionName, null, versionId, libraryVersionIDs, testMode); + await setupFaasFunction( + functionName, + null, + versionId, + libraryVersionIDs, + testMode, + trMetadata, + ); throw new RetryRequestError(`${functionName} not found`); } diff --git a/src/v0/util/index.js b/src/v0/util/index.js index 4ea3d3783d..bed515624c 100644 --- a/src/v0/util/index.js +++ b/src/v0/util/index.js @@ -1403,6 +1403,12 @@ const getMetadata = (metadata) => ({ destinationType: metadata.destinationType, k8_namespace: metadata.namespace, }); + +const getTransformationMetadata = (metadata) => ({ + transformationId: metadata.transformationId, + workspaceId: metadata.workspaceId, +}); + // checks if array 2 is a subset of array 1 function checkSubsetOfArray(array1, array2) { const result = array2.every((val) => array1.includes(val)); @@ -2113,6 +2119,7 @@ module.exports = { getIntegrationsObj, getMappingConfig, getMetadata, + getTransformationMetadata, getParsedIP, getStringValueOfJSON, getSuccessRespEvents, From 3e1fb26422f4e274a48df129e74600374669a0a6 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Thu, 2 Nov 2023 23:50:11 +0000 Subject: [PATCH 09/93] chore(release): 1.48.0 --- CHANGELOG.md | 7 +++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e7d295645f..01631435d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +## [1.48.0](https://github.com/rudderlabs/rudder-transformer/compare/v1.47.0...v1.48.0) (2023-11-02) + + +### Features + +* add support to add custom network policies for specific workspaces in faas pods ([bc1a760](https://github.com/rudderlabs/rudder-transformer/commit/bc1a76066c0aeb43776ded0b266ec48f5e69aa16)) + ## [1.47.0](https://github.com/rudderlabs/rudder-transformer/compare/v1.46.5...v1.47.0) (2023-10-30) diff --git a/package-lock.json b/package-lock.json index 4643d1325d..0822a9b42b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "rudder-transformer", - "version": "1.47.0", + "version": "1.48.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "rudder-transformer", - "version": "1.47.0", + "version": "1.48.0", "license": "ISC", "dependencies": { "@amplitude/ua-parser-js": "^0.7.24", diff --git a/package.json b/package.json index adc5f0e8f5..46f728664d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rudder-transformer", - "version": "1.47.0", + "version": "1.48.0", "description": "", "homepage": "https://github.com/rudderlabs/rudder-transformer#readme", "bugs": { From 570532ce790c05a69621d9289758a1b1a7acda8c Mon Sep 17 00:00:00 2001 From: Yashasvi Bajpai <33063622+yashasvibajpai@users.noreply.github.com> Date: Fri, 3 Nov 2023 17:41:02 +0530 Subject: [PATCH 10/93] fix: allow support for full url from UI in freshsales and freshmarketer (#2780) * fix: allow support for full url from UI in freshsales * fix: allow support for full url from UI in freshmarketer * fix: tests * fix: testsx2 --- src/v0/destinations/freshmarketer/config.js | 14 ++--- src/v0/destinations/freshmarketer/utils.js | 2 +- src/v0/destinations/freshsales/config.js | 10 +-- test/__tests__/data/freshmarketer.json | 62 +++++++++---------- .../data/freshmarketer_router_input.json | 6 +- .../data/freshmarketer_router_output.json | 6 +- test/__tests__/data/freshsales.json | 50 +++++++-------- .../data/freshsales_router_input.json | 2 +- .../data/freshsales_router_output.json | 2 +- 9 files changed, 77 insertions(+), 77 deletions(-) diff --git a/src/v0/destinations/freshmarketer/config.js b/src/v0/destinations/freshmarketer/config.js index f1018d439c..a0d6449c3a 100644 --- a/src/v0/destinations/freshmarketer/config.js +++ b/src/v0/destinations/freshmarketer/config.js @@ -4,23 +4,23 @@ const CONFIG_CATEGORIES = { IDENTIFY: { name: 'FRESHMARKETERIdentifyConfig', type: 'identify', - baseUrl: '.myfreshworks.com/crm/sales/api/contacts/upsert', + baseUrl: '/crm/sales/api/contacts/upsert', }, GROUP: { name: 'FRESHMARKETERGroupConfig', type: 'group', - baseUrlAccount: '.myfreshworks.com/crm/sales/api/sales_accounts/upsert', - baseUrlList: '.myfreshworks.com/crm/sales/api/lists', + baseUrlAccount: '/crm/sales/api/sales_accounts/upsert', + baseUrlList: '/crm/sales/api/lists', }, SALES_ACTIVITY: { name: 'SalesActivityConfig', - baseUrlCreate: '.myfreshworks.com/crm/sales/api/sales_activities', - baseUrlListAll: '.myfreshworks.com/crm/sales/api/selector/sales_activity_types', + baseUrlCreate: '/crm/sales/api/sales_activities', + baseUrlListAll: '/crm/sales/api/selector/sales_activity_types', }, }; -const DELETE_ENDPOINT = '.myfreshworks.com/crm/sales/api/contacts/'; -const LIFECYCLE_STAGE_ENDPOINT = '.myfreshworks.com/crm/sales/api/selector/lifecycle_stages'; +const DELETE_ENDPOINT = '/crm/sales/api/contacts/'; +const LIFECYCLE_STAGE_ENDPOINT = '/crm/sales/api/selector/lifecycle_stages'; const MAPPING_CONFIG = getMappingConfig(CONFIG_CATEGORIES, __dirname); module.exports = { diff --git a/src/v0/destinations/freshmarketer/utils.js b/src/v0/destinations/freshmarketer/utils.js index 5b47bb9170..f7dcc46b06 100644 --- a/src/v0/destinations/freshmarketer/utils.js +++ b/src/v0/destinations/freshmarketer/utils.js @@ -203,7 +203,7 @@ const updateAccountWOContact = (payload, Config) => { */ const updateContactWithList = (userId, listId, Config) => { const response = defaultRequestConfig(); - response.endpoint = `https://${Config.domain}.myfreshworks.com/crm/sales/api/lists/${listId}/add_contacts`; + response.endpoint = `https://${Config.domain}/crm/sales/api/lists/${listId}/add_contacts`; response.headers = getHeaders(Config.apiKey); response.body.JSON = { ids: [userId], diff --git a/src/v0/destinations/freshsales/config.js b/src/v0/destinations/freshsales/config.js index c6ae4b8165..62f54c1297 100644 --- a/src/v0/destinations/freshsales/config.js +++ b/src/v0/destinations/freshsales/config.js @@ -4,23 +4,23 @@ const CONFIG_CATEGORIES = { IDENTIFY: { name: 'identifyConfig', type: 'identify', - baseUrl: '.myfreshworks.com/crm/sales/api/contacts/upsert', + baseUrl: '/crm/sales/api/contacts/upsert', method: 'POST', }, GROUP: { name: 'groupConfig', type: 'group', - baseUrlAccount: '.myfreshworks.com/crm/sales/api/sales_accounts/upsert', + baseUrlAccount: '/crm/sales/api/sales_accounts/upsert', method: 'POST', }, SALES_ACTIVITY: { name: 'SalesActivityConfig', - baseUrlCreate: '.myfreshworks.com/crm/sales/api/sales_activities', - baseUrlListAll: '.myfreshworks.com/crm/sales/api/selector/sales_activity_types', + baseUrlCreate: '/crm/sales/api/sales_activities', + baseUrlListAll: '/crm/sales/api/selector/sales_activity_types', }, }; -const LIFECYCLE_STAGE_ENDPOINT = '.myfreshworks.com/crm/sales/api/selector/lifecycle_stages'; +const LIFECYCLE_STAGE_ENDPOINT = '/crm/sales/api/selector/lifecycle_stages'; const MAPPING_CONFIG = getMappingConfig(CONFIG_CATEGORIES, __dirname); module.exports = { diff --git a/test/__tests__/data/freshmarketer.json b/test/__tests__/data/freshmarketer.json index 3d30841b30..390c0fb44e 100644 --- a/test/__tests__/data/freshmarketer.json +++ b/test/__tests__/data/freshmarketer.json @@ -5,7 +5,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "rudderstack-476952domain3105" + "domain": "rudderstack-476952domain3105.myfreshworks.com" } }, "message": { @@ -94,7 +94,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "rudderstack-476952domain3105" + "domain": "rudderstack-476952domain3105.myfreshworks.com" } }, "message": { @@ -183,7 +183,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "rudderstack-476952domain3105" + "domain": "rudderstack-476952domain3105.myfreshworks.com" } }, "message": { @@ -248,7 +248,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "rudderstack-476952domain3105" + "domain": "rudderstack-476952domain3105.myfreshworks.com" } }, "message": { @@ -312,7 +312,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } }, "message": { @@ -422,7 +422,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } }, "message": { @@ -491,7 +491,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } }, "message": { @@ -558,7 +558,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } }, "message": { @@ -627,7 +627,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } }, "message": { @@ -760,7 +760,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } } }, @@ -843,7 +843,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } } }, @@ -927,7 +927,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } } }, @@ -1019,7 +1019,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } } }, @@ -1127,7 +1127,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } } }, @@ -1228,7 +1228,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } } }, @@ -1315,7 +1315,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } } }, @@ -1406,7 +1406,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } } }, @@ -1496,7 +1496,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } } }, @@ -1586,7 +1586,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } } }, @@ -1696,7 +1696,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } } }, @@ -1757,7 +1757,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } } }, @@ -1788,7 +1788,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } } }, @@ -1825,7 +1825,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } } }, @@ -1892,7 +1892,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } } }, @@ -1937,7 +1937,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } } }, @@ -1976,7 +1976,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } } }, @@ -2043,7 +2043,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } } }, @@ -2145,7 +2145,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } } }, @@ -2232,7 +2232,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } } }, @@ -2334,7 +2334,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } } }, @@ -2427,7 +2427,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder", + "domain": "domain-rudder.myfreshworks.com", "rudderEventsToFreshmarketerEvents": [ { "from": "test_activity", diff --git a/test/__tests__/data/freshmarketer_router_input.json b/test/__tests__/data/freshmarketer_router_input.json index 0e05c7f5f8..2cc5ce58de 100644 --- a/test/__tests__/data/freshmarketer_router_input.json +++ b/test/__tests__/data/freshmarketer_router_input.json @@ -3,7 +3,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "rudderstack-476952domain3105" + "domain": "rudderstack-476952domain3105.myfreshworks.com" } }, "metadata": { @@ -59,7 +59,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "rudderstack-476952domain3105" + "domain": "rudderstack-476952domain3105.myfreshworks.com" } }, "metadata": { @@ -115,7 +115,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } }, "metadata": { diff --git a/test/__tests__/data/freshmarketer_router_output.json b/test/__tests__/data/freshmarketer_router_output.json index 01740cb626..3525e4bb16 100644 --- a/test/__tests__/data/freshmarketer_router_output.json +++ b/test/__tests__/data/freshmarketer_router_output.json @@ -43,7 +43,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "rudderstack-476952domain3105" + "domain": "rudderstack-476952domain3105.myfreshworks.com" } } }, @@ -91,7 +91,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "rudderstack-476952domain3105" + "domain": "rudderstack-476952domain3105.myfreshworks.com" } } }, @@ -156,7 +156,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } } } diff --git a/test/__tests__/data/freshsales.json b/test/__tests__/data/freshsales.json index 2527e37b90..55193532f4 100644 --- a/test/__tests__/data/freshsales.json +++ b/test/__tests__/data/freshsales.json @@ -69,7 +69,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } } }, @@ -90,7 +90,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "rudderstack-476952domain3105" + "domain": "rudderstack-476952domain3105.myfreshworks.com" } }, "message": { @@ -179,7 +179,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "rudderstack-476952domain3105" + "domain": "rudderstack-476952domain3105.myfreshworks.com" } }, "message": { @@ -268,7 +268,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "rudderstack-476952domain3105" + "domain": "rudderstack-476952domain3105.myfreshworks.com" } }, "message": { @@ -356,7 +356,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "rudderstack-476952domain3105" + "domain": "rudderstack-476952domain3105.myfreshworks.com" } }, "message": { @@ -421,7 +421,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } }, "message": { @@ -531,7 +531,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } }, "message": { @@ -600,7 +600,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } }, "message": { @@ -667,7 +667,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } }, "message": { @@ -736,7 +736,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } }, "message": { @@ -869,7 +869,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } } }, @@ -952,7 +952,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } } }, @@ -1036,7 +1036,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } } }, @@ -1128,7 +1128,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder", + "domain": "domain-rudder.myfreshworks.com", "rudderEventsToFreshsalesEvents": [ { "from": "test", @@ -1244,7 +1244,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } } }, @@ -1345,7 +1345,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } } }, @@ -1432,7 +1432,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } } }, @@ -1523,7 +1523,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } } }, @@ -1613,7 +1613,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } } }, @@ -1703,7 +1703,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } } }, @@ -1813,7 +1813,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } } }, @@ -1874,7 +1874,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } } }, @@ -1966,7 +1966,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } } }, @@ -2053,7 +2053,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } } }, @@ -2155,7 +2155,7 @@ "destination": { "Config": { "apiKey": "dummyApiKey", - "domain": "domain-rudder" + "domain": "domain-rudder.myfreshworks.com" } } }, diff --git a/test/__tests__/data/freshsales_router_input.json b/test/__tests__/data/freshsales_router_input.json index 856a127f51..ea4b9887dd 100644 --- a/test/__tests__/data/freshsales_router_input.json +++ b/test/__tests__/data/freshsales_router_input.json @@ -66,7 +66,7 @@ }, "Config": { "apiKey": "hrkjfergeferf", - "domain": "rudderstack-479541159204968909" + "domain": "rudderstack-479541159204968909.myfreshworks.com" }, "Enabled": true, "Transformations": [], diff --git a/test/__tests__/data/freshsales_router_output.json b/test/__tests__/data/freshsales_router_output.json index 449d6eb45a..69d259ff00 100644 --- a/test/__tests__/data/freshsales_router_output.json +++ b/test/__tests__/data/freshsales_router_output.json @@ -72,7 +72,7 @@ }, "Config": { "apiKey": "hrkjfergeferf", - "domain": "rudderstack-479541159204968909" + "domain": "rudderstack-479541159204968909.myfreshworks.com" }, "Enabled": true, "Transformations": [], From 818858e046ce5f9735bbb97715c43a959ad3aa3c Mon Sep 17 00:00:00 2001 From: shrouti1507 <60211312+shrouti1507@users.noreply.github.com> Date: Mon, 6 Nov 2023 11:04:36 +0530 Subject: [PATCH 11/93] feat: onboard one signal to router transform (#2785) --- src/features.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/features.json b/src/features.json index fb5b0735f0..9793f667e3 100644 --- a/src/features.json +++ b/src/features.json @@ -58,7 +58,8 @@ "OPTIMIZELY_FULLSTACK": true, "TWITTER_ADS": true, "CLEVERTAP": true, - "TIKTOK_AUDIENCE": true, - "ORTTO": true + "ORTTO": true, + "ONE_SIGNAL": true, + "TIKTOK_AUDIENCE": true } } From 0947c58948a8192ac16f1a7e9b5b7520d5dc7530 Mon Sep 17 00:00:00 2001 From: Ujjwal Abhishek <63387036+ujjwal-ab@users.noreply.github.com> Date: Mon, 6 Nov 2023 11:32:34 +0530 Subject: [PATCH 12/93] chore: update release owner (#2794) * chore: update release owner * chore: update release-owners --- .github/workflows/create-hotfix-branch.yml | 2 +- .github/workflows/draft-new-release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/create-hotfix-branch.yml b/.github/workflows/create-hotfix-branch.yml index d1397cb608..97611f1eee 100644 --- a/.github/workflows/create-hotfix-branch.yml +++ b/.github/workflows/create-hotfix-branch.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest # Only allow these users to create new hotfix branch from 'main' - if: github.ref == 'refs/heads/main' && (github.actor == 'ItsSudip' || github.actor == 'krishna2020' || github.actor == 'saikumarrs' || github.actor == 'sandeepdsvs' || github.actor == 'shrouti1507' || github.actor == 'anantjain45823' || github.actor == 'chandumlg' || github.actor == 'mihir-4116') && (github.triggering_actor == 'ItsSudip' || github.triggering_actor == 'krishna2020' || github.triggering_actor == 'saikumarrs' || github.triggering_actor == 'sandeepdsvs' || github.triggering_actor == 'shrouti1507' || github.triggering_actor == 'anantjain45823' || github.triggering_actor == 'chandumlg' || github.triggering_actor == 'mihir-4116') + if: github.ref == 'refs/heads/main' && (github.actor == 'ItsSudip' || github.actor == 'krishna2020' || github.actor == 'saikumarrs' || github.actor == 'sandeepdsvs' || github.actor == 'shrouti1507' || github.actor == 'anantjain45823' || github.actor == 'chandumlg' || github.actor == 'mihir-4116' || github.actor == 'ujjwal-ab') && (github.triggering_actor == 'ItsSudip' || github.triggering_actor == 'krishna2020' || github.triggering_actor == 'saikumarrs' || github.triggering_actor == 'sandeepdsvs' || github.triggering_actor == 'shrouti1507' || github.triggering_actor == 'anantjain45823' || github.triggering_actor == 'chandumlg' || github.triggering_actor == 'mihir-4116' || github.triggering_actor == 'ujjwal-ab) steps: - name: Create Branch uses: peterjgrainger/action-create-branch@v2.4.0 diff --git a/.github/workflows/draft-new-release.yml b/.github/workflows/draft-new-release.yml index a0a558440a..23e243918f 100644 --- a/.github/workflows/draft-new-release.yml +++ b/.github/workflows/draft-new-release.yml @@ -8,7 +8,7 @@ jobs: runs-on: ubuntu-latest # Only allow release stakeholders to initiate releases - if: (github.ref == 'refs/heads/develop' || startsWith(github.ref, 'refs/heads/hotfix/')) && (github.actor == 'ItsSudip' || github.actor == 'krishna2020' || github.actor == 'saikumarrs' || github.actor == 'sandeepdsvs' || github.actor == 'shrouti1507' || github.actor == 'anantjain45823' || github.actor == 'chandumlg' || github.actor == 'mihir-4116' || github.actor == 'yashasvibajpai' || github.actor == 'sanpj2292') && (github.triggering_actor == 'ItsSudip' || github.triggering_actor == 'krishna2020' || github.triggering_actor == 'saikumarrs' || github.triggering_actor == 'sandeepdsvs' || github.triggering_actor == 'shrouti1507' || github.triggering_actor == 'anantjain45823' || github.triggering_actor == 'chandumlg' || github.triggering_actor == 'mihir-4116' || github.triggering_actor == 'yashasvibajpai' || github.triggering_actor == 'sanpj2292') + if: (github.ref == 'refs/heads/develop' || startsWith(github.ref, 'refs/heads/hotfix/')) && (github.actor == 'ItsSudip' || github.actor == 'krishna2020' || github.actor == 'saikumarrs' || github.actor == 'sandeepdsvs' || github.actor == 'shrouti1507' || github.actor == 'anantjain45823' || github.actor == 'chandumlg' || github.actor == 'mihir-4116' || github.actor == 'yashasvibajpai' || github.actor == 'sanpj2292' || github.actor == 'ujjwal-ab') && (github.triggering_actor == 'ItsSudip' || github.triggering_actor == 'krishna2020' || github.triggering_actor == 'saikumarrs' || github.triggering_actor == 'sandeepdsvs' || github.triggering_actor == 'shrouti1507' || github.triggering_actor == 'anantjain45823' || github.triggering_actor == 'chandumlg' || github.triggering_actor == 'mihir-4116' || github.triggering_actor == 'yashasvibajpai' || github.triggering_actor == 'sanpj2292' || github.triggering_actor == 'ujjwal-ab') steps: - name: Checkout uses: actions/checkout@v3.5.3 From 55f96374b4d73db7013c1d5e72bfc9c8257b224b Mon Sep 17 00:00:00 2001 From: Yashasvi Bajpai <33063622+yashasvibajpai@users.noreply.github.com> Date: Mon, 6 Nov 2023 12:48:38 +0530 Subject: [PATCH 13/93] feat: onboard revenuecat as a source (#2774) * refactor: revenuecat source code * chore: refactor, address comments --- src/v0/sources/revenuecat/mapping.json | 10 + src/v0/sources/revenuecat/transform.js | 47 +++ test/integrations/sources/revenuecat/data.ts | 286 +++++++++++++++++++ 3 files changed, 343 insertions(+) create mode 100644 src/v0/sources/revenuecat/mapping.json create mode 100644 src/v0/sources/revenuecat/transform.js create mode 100644 test/integrations/sources/revenuecat/data.ts diff --git a/src/v0/sources/revenuecat/mapping.json b/src/v0/sources/revenuecat/mapping.json new file mode 100644 index 0000000000..541568b71b --- /dev/null +++ b/src/v0/sources/revenuecat/mapping.json @@ -0,0 +1,10 @@ +[ + { + "sourceKeys": "event.type", + "destKeys": "event" + }, + { + "sourceKeys": "event.id", + "destKeys": "messageId" + } +] diff --git a/src/v0/sources/revenuecat/transform.js b/src/v0/sources/revenuecat/transform.js new file mode 100644 index 0000000000..36944e10fa --- /dev/null +++ b/src/v0/sources/revenuecat/transform.js @@ -0,0 +1,47 @@ +const { camelCase } = require('lodash'); +const moment = require('moment'); +const { removeUndefinedAndNullValues, isDefinedAndNotNull } = require('../../util'); +const Message = require('../message'); + +function process(event) { + const message = new Message(`RevenueCat`); + + // we are setting event type as track always + message.setEventType('track'); + + const properties = {}; + // dump all event properties to message.properties after converting them to camelCase + if (event.event) { + Object.keys(event.event).forEach((key) => { + properties[camelCase(key)] = event.event[key]; + }); + message.setProperty('properties', properties); + } + + // setting up app_user_id to externalId : revenuecatAppUserId + if (event?.event?.app_user_id) { + message.context.externalId = [ + { + type: 'revenuecatAppUserId', + id: event?.event?.app_user_id, + }, + ]; + } + + if ( + isDefinedAndNotNull(event?.event?.event_timestamp_ms) && + moment(event?.event?.event_timestamp_ms).isValid() + ) { + const validTimestamp = new Date(event.event.event_timestamp_ms).toISOString(); + message.setProperty('originalTimestamp', validTimestamp); + message.setProperty('sentAt', validTimestamp); + } + message.event = event?.event?.type; + message.messageId = event?.event?.id; + + // removing undefined and null values from message + removeUndefinedAndNullValues(message); + return message; +} + +module.exports = { process }; diff --git a/test/integrations/sources/revenuecat/data.ts b/test/integrations/sources/revenuecat/data.ts new file mode 100644 index 0000000000..4963781763 --- /dev/null +++ b/test/integrations/sources/revenuecat/data.ts @@ -0,0 +1,286 @@ +export const data = [ + { + name: 'revenuecat', + description: 'Simple track call', + module: 'source', + version: 'v0', + input: { + request: { + body: [ + { + api_version: '1.0', + event: { + aliases: [ + 'f8e14f51-0c76-49ba-8d67-c229f1875dd9', + '389ad6dd-bb40-4c03-9471-1353da2d55ec', + ], + app_user_id: 'f8e14f51-0c76-49ba-8d67-c229f1875dd9', + commission_percentage: null, + country_code: 'US', + currency: null, + entitlement_id: null, + entitlement_ids: null, + environment: 'SANDBOX', + event_timestamp_ms: 1698617217232, + expiration_at_ms: 1698624417232, + id: '8CF0CD6C-CAF3-41FB-968A-661938235AF0', + is_family_share: null, + offer_code: null, + original_app_user_id: 'f8e14f51-0c76-49ba-8d67-c229f1875dd9', + original_transaction_id: null, + period_type: 'NORMAL', + presented_offering_id: null, + price: null, + price_in_purchased_currency: null, + product_id: 'test_product', + purchased_at_ms: 1698617217232, + store: 'APP_STORE', + subscriber_attributes: { + $displayName: { + updated_at_ms: 1698617217232, + value: 'Mister Mistoffelees', + }, + $email: { + updated_at_ms: 1698617217232, + value: 'tuxedo@revenuecat.com', + }, + $phoneNumber: { + updated_at_ms: 1698617217232, + value: '+19795551234', + }, + my_custom_attribute_1: { + updated_at_ms: 1698617217232, + value: 'catnip', + }, + }, + takehome_percentage: null, + tax_percentage: null, + transaction_id: null, + type: 'TEST', + }, + }, + ], + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + }, + pathSuffix: '', + }, + output: { + response: { + status: 200, + body: [ + { + output: { + batch: [ + { + context: { + library: { + name: 'unknown', + version: 'unknown', + }, + integration: { + name: 'RevenueCat', + }, + externalId: [ + { + type: 'revenuecatAppUserId', + id: 'f8e14f51-0c76-49ba-8d67-c229f1875dd9', + }, + ], + }, + integrations: { + RevenueCat: false, + }, + type: 'track', + properties: { + aliases: [ + 'f8e14f51-0c76-49ba-8d67-c229f1875dd9', + '389ad6dd-bb40-4c03-9471-1353da2d55ec', + ], + appUserId: 'f8e14f51-0c76-49ba-8d67-c229f1875dd9', + commissionPercentage: null, + countryCode: 'US', + currency: null, + entitlementId: null, + entitlementIds: null, + environment: 'SANDBOX', + eventTimestampMs: 1698617217232, + expirationAtMs: 1698624417232, + id: '8CF0CD6C-CAF3-41FB-968A-661938235AF0', + isFamilyShare: null, + offerCode: null, + originalAppUserId: 'f8e14f51-0c76-49ba-8d67-c229f1875dd9', + originalTransactionId: null, + periodType: 'NORMAL', + presentedOfferingId: null, + price: null, + priceInPurchasedCurrency: null, + productId: 'test_product', + purchasedAtMs: 1698617217232, + store: 'APP_STORE', + subscriberAttributes: { + $displayName: { + updated_at_ms: 1698617217232, + value: 'Mister Mistoffelees', + }, + $email: { + updated_at_ms: 1698617217232, + value: 'tuxedo@revenuecat.com', + }, + $phoneNumber: { + updated_at_ms: 1698617217232, + value: '+19795551234', + }, + my_custom_attribute_1: { + updated_at_ms: 1698617217232, + value: 'catnip', + }, + }, + takehomePercentage: null, + taxPercentage: null, + transactionId: null, + type: 'TEST', + }, + event: 'TEST', + messageId: '8CF0CD6C-CAF3-41FB-968A-661938235AF0', + originalTimestamp: '2023-10-29T22:06:57.232Z', + sentAt: '2023-10-29T22:06:57.232Z', + }, + ], + }, + }, + ], + }, + }, + }, + { + name: 'revenuecat', + description: 'Initial purchase event', + module: 'source', + version: 'v0', + input: { + request: { + body: [ + { + api_version: '1.0', + event: { + aliases: ['yourCustomerAliasedID', 'yourCustomerAliasedID'], + app_id: 'yourAppID', + app_user_id: 'yourCustomerAppUserID', + commission_percentage: 0.3, + country_code: 'US', + currency: 'USD', + entitlement_id: 'pro_cat', + entitlement_ids: ['pro_cat'], + environment: 'PRODUCTION', + event_timestamp_ms: 1591121855319, + expiration_at_ms: 1591726653000, + id: 'UniqueIdentifierOfEvent', + is_family_share: false, + offer_code: 'free_month', + original_app_user_id: 'OriginalAppUserID', + original_transaction_id: '1530648507000', + period_type: 'NORMAL', + presented_offering_id: 'OfferingID', + price: 2.49, + price_in_purchased_currency: 2.49, + product_id: 'onemonth_no_trial', + purchased_at_ms: 1591121853000, + store: 'APP_STORE', + subscriber_attributes: { + '$Favorite Cat': { + updated_at_ms: 1581121853000, + value: 'Garfield', + }, + }, + takehome_percentage: 0.7, + tax_percentage: 0.3, + transaction_id: '170000869511114', + type: 'INITIAL_PURCHASE', + }, + }, + ], + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + }, + pathSuffix: '', + }, + output: { + response: { + status: 200, + body: [ + { + output: { + batch: [ + { + context: { + library: { + name: 'unknown', + version: 'unknown', + }, + integration: { + name: 'RevenueCat', + }, + externalId: [ + { + type: 'revenuecatAppUserId', + id: 'yourCustomerAppUserID', + }, + ], + }, + integrations: { + RevenueCat: false, + }, + type: 'track', + properties: { + aliases: ['yourCustomerAliasedID', 'yourCustomerAliasedID'], + appId: 'yourAppID', + appUserId: 'yourCustomerAppUserID', + commissionPercentage: 0.3, + countryCode: 'US', + currency: 'USD', + entitlementId: 'pro_cat', + entitlementIds: ['pro_cat'], + environment: 'PRODUCTION', + eventTimestampMs: 1591121855319, + expirationAtMs: 1591726653000, + id: 'UniqueIdentifierOfEvent', + isFamilyShare: false, + offerCode: 'free_month', + originalAppUserId: 'OriginalAppUserID', + originalTransactionId: '1530648507000', + periodType: 'NORMAL', + presentedOfferingId: 'OfferingID', + price: 2.49, + priceInPurchasedCurrency: 2.49, + productId: 'onemonth_no_trial', + purchasedAtMs: 1591121853000, + store: 'APP_STORE', + subscriberAttributes: { + '$Favorite Cat': { + updated_at_ms: 1581121853000, + value: 'Garfield', + }, + }, + takehomePercentage: 0.7, + taxPercentage: 0.3, + transactionId: '170000869511114', + type: 'INITIAL_PURCHASE', + }, + event: 'INITIAL_PURCHASE', + messageId: 'UniqueIdentifierOfEvent', + originalTimestamp: '2020-06-02T18:17:35.319Z', + sentAt: '2020-06-02T18:17:35.319Z', + }, + ], + }, + }, + ], + }, + }, + }, +]; From 6e89cd3f67ea887ba17c1cd5ffbca6675f54d96c Mon Sep 17 00:00:00 2001 From: Yashasvi Bajpai <33063622+yashasvibajpai@users.noreply.github.com> Date: Mon, 6 Nov 2023 12:55:19 +0530 Subject: [PATCH 14/93] fix: add check to remove null and undefined properties before sending (#2796) * fix: add check to remove null and undefined properties before sending * chore: fix test --- src/v0/destinations/adobe_analytics/transform.js | 3 ++- test/__tests__/data/adobe_analytics.json | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/v0/destinations/adobe_analytics/transform.js b/src/v0/destinations/adobe_analytics/transform.js index 54806bf578..67bb66310a 100644 --- a/src/v0/destinations/adobe_analytics/transform.js +++ b/src/v0/destinations/adobe_analytics/transform.js @@ -11,6 +11,7 @@ const { isDefinedAndNotNull, isDefinedAndNotNullAndNotEmpty, getIntegrationsObj, + removeUndefinedAndNullValues, simpleProcessRouterDest, } = require('../../util'); const { @@ -394,7 +395,7 @@ const handleTrack = (message, destinationConfig) => { break; } - return payload; + return removeUndefinedAndNullValues(payload); }; const process = async (event) => { diff --git a/test/__tests__/data/adobe_analytics.json b/test/__tests__/data/adobe_analytics.json index cfffccb8da..6361f92640 100644 --- a/test/__tests__/data/adobe_analytics.json +++ b/test/__tests__/data/adobe_analytics.json @@ -1010,7 +1010,6 @@ }, "messageId": "1578564113557-af022c68-429e-4af4-b99b-2b9174056383", "properties": { - "order_id": "1234", "affiliation": "Apple Store", "value": 20, "revenue": 15.0, @@ -1019,6 +1018,7 @@ "discount": 1.5, "coupon": "ImagePro", "currency": "USD", + "purchaseId": "p101", "products": [ { "product_id": "123", @@ -1205,7 +1205,7 @@ "JSON": {}, "JSON_ARRAY": {}, "XML": { - "payload": "17941080sales campaignwebUSD127.0.0.1en-US12341234Dalvik/2.1.0 (Linux; U; Android 9; Android SDK built for x86 Build/PSR1.180720.075)https://www.google.com/search?q=estore+bestsellerroottval001RudderLabs JavaScript SDKocheckout startedhttps://www.estore.com/best-seller/12020-01-09T10:01:53.558Zmktcloudid001scCheckoutGames;Monopoly;1;14.00,Games;UNO;2;6.90footlockerrudderstackpoc" + "payload": "17941080sales campaignwebUSD127.0.0.1en-USDalvik/2.1.0 (Linux; U; Android 9; Android SDK built for x86 Build/PSR1.180720.075)https://www.google.com/search?q=estore+bestsellerroottval001RudderLabs JavaScript SDKocheckout startedhttps://www.estore.com/best-seller/12020-01-09T10:01:53.558Zmktcloudid001p101scCheckoutGames;Monopoly;1;14.00,Games;UNO;2;6.90footlockerrudderstackpoc" }, "FORM": {} }, From 11fb7c47910681833e37d25a1573d2005e62742b Mon Sep 17 00:00:00 2001 From: Ujjwal Abhishek <63387036+ujjwal-ab@users.noreply.github.com> Date: Mon, 6 Nov 2023 14:28:51 +0530 Subject: [PATCH 15/93] fix: busgnag issues for klaviyo, freshsales, customeio (#2795) * chore(klaviyo): remove error notifier * fix(freshsales): stringify event before lowercase * fix(customerio): convert eventName to string for truncate * fix: add validation for event Name type and update function name * fix: remove unrequired validation --- src/v0/destinations/customerio/transform.js | 3 +++ src/v0/destinations/customerio/util.js | 2 -- src/v0/destinations/freshsales/transform.js | 7 ++----- src/v0/destinations/klaviyo/util.js | 6 ------ src/v0/destinations/monday/transform.js | 4 ++-- src/v0/util/index.js | 4 ++-- 6 files changed, 9 insertions(+), 17 deletions(-) diff --git a/src/v0/destinations/customerio/transform.js b/src/v0/destinations/customerio/transform.js index 5f953ee2f0..984fb7e67f 100644 --- a/src/v0/destinations/customerio/transform.js +++ b/src/v0/destinations/customerio/transform.js @@ -12,6 +12,7 @@ const { adduserIdFromExternalId, getFieldValueFromMessage, handleRtTfSingleEventError, + validateEventName, } = require('../../util'); const logger = require('../../../logger'); @@ -101,6 +102,7 @@ function processSingleMessage(message, destination) { break; case EventType.TRACK: evType = 'event'; + validateEventName(message.event); evName = message.event; break; case EventType.ALIAS: @@ -113,6 +115,7 @@ function processSingleMessage(message, destination) { logger.error(`could not determine type ${messageType}`); throw new InstrumentationError(`could not determine type ${messageType}`); } + evName = evName ? String(evName) : evName; const response = responseBuilder(message, evType, evName, destination, messageType); // replace default domain with EU data center domainc for EU based account diff --git a/src/v0/destinations/customerio/util.js b/src/v0/destinations/customerio/util.js index 2e7f000fba..6b4dbc0e11 100644 --- a/src/v0/destinations/customerio/util.js +++ b/src/v0/destinations/customerio/util.js @@ -10,7 +10,6 @@ const { defaultDeleteRequestConfig, isAppleFamily, validateEmail, - validateEventType, } = require('../../util'); const { EventType, SpecedTraits, TraitsMapping } = require('../../../constants'); @@ -288,7 +287,6 @@ const defaultResponseBuilder = (message, evName, userId, evType, destination, me // 100 - len(`Viewed Screen`) = 86 trimmedEvName = `Viewed ${truncate(message.event || message.properties.name, 86)} Screen`; } else { - validateEventType(evName); trimmedEvName = truncate(evName, 100); } // anonymous_id needs to be sent for anon track calls to provide information on which anon user is being tracked diff --git a/src/v0/destinations/freshsales/transform.js b/src/v0/destinations/freshsales/transform.js index cd7518a101..c1e18482ed 100644 --- a/src/v0/destinations/freshsales/transform.js +++ b/src/v0/destinations/freshsales/transform.js @@ -8,7 +8,7 @@ const { defaultPostRequestConfig, getValidDynamicFormConfig, simpleProcessRouterDest, - validateEventType, + validateEventName, } = require('../../util'); const { InstrumentationError, TransformationError } = require('../../util/errorTypes'); const { CONFIG_CATEGORIES, MAPPING_CONFIG } = require('./config'); @@ -67,7 +67,6 @@ const identifyResponseBuilder = (message, { Config }) => { * @returns */ const trackResponseBuilder = async (message, { Config }, event) => { - validateEventType(event); let payload; const response = defaultRequestConfig(); @@ -125,9 +124,6 @@ const groupResponseBuilder = async (message, { Config }) => { // Checks if there are any mapping events for the track event and returns them function eventMappingHandler(message, destination) { const event = get(message, 'event'); - if (!event) { - throw new InstrumentationError('Event name is required'); - } let { rudderEventsToFreshsalesEvents } = destination.Config; const mappedEvents = new Set(); @@ -161,6 +157,7 @@ const processEvent = async (message, destination) => { response = identifyResponseBuilder(message, destination); break; case EventType.TRACK: { + validateEventName(message.event); const mappedEvents = eventMappingHandler(message, destination); if (mappedEvents.length > 0) { const respList = await Promise.all( diff --git a/src/v0/destinations/klaviyo/util.js b/src/v0/destinations/klaviyo/util.js index 4304edd78f..b31dafd78b 100644 --- a/src/v0/destinations/klaviyo/util.js +++ b/src/v0/destinations/klaviyo/util.js @@ -17,7 +17,6 @@ const { handleHttpRequest } = require('../../../adapters/network'); const { JSON_MIME_TYPE, HTTP_STATUS_CODES } = require('../../util/constant'); const { NetworkError, InstrumentationError } = require('../../util/errorTypes'); const { getDynamicErrorType } = require('../../../adapters/utils/networkUtils'); -const { client: errNotificationClient } = require('../../../util/errorNotifier'); const { BASE_ENDPOINT, MAPPING_CONFIG, CONFIG_CATEGORIES, MAX_BATCH_SIZE } = require('./config'); const REVISION_CONSTANT = '2023-02-22'; @@ -69,11 +68,6 @@ const getIdFromNewOrExistingProfile = async (endpoint, payload, requestOptions) let statusCode = resp.status; if (resp.status === 201 || resp.status === 409) { // retryable error if the profile id is not found in the response - errNotificationClient.notify( - new Error('Klaviyo: ProfileId not found'), - 'Profile Id not Found in the response', - JSON.stringify(resp.response), - ); statusCode = 500; } diff --git a/src/v0/destinations/monday/transform.js b/src/v0/destinations/monday/transform.js index 34ada34780..37ee835e50 100644 --- a/src/v0/destinations/monday/transform.js +++ b/src/v0/destinations/monday/transform.js @@ -8,7 +8,7 @@ const { removeUndefinedAndNullValues, simpleProcessRouterDest, getDestinationExternalID, - validateEventType, + validateEventName, } = require('../../util'); const { ConfigurationError, @@ -42,7 +42,7 @@ const trackResponseBuilder = async (message, { Config }) => { const { apiToken } = Config; let boardId = getDestinationExternalID(message, 'boardId'); const event = get(message, 'event'); - validateEventType(event); + validateEventName(event); if (!boardId) { boardId = Config.boardId; } diff --git a/src/v0/util/index.js b/src/v0/util/index.js index e5ec1642b4..d6f6621220 100644 --- a/src/v0/util/index.js +++ b/src/v0/util/index.js @@ -2069,7 +2069,7 @@ const isValidInteger = (value) => { // Use a regular expression to check if the string is a valid integer or a valid floating-point number return typeof value === 'string' ? /^-?\d+$/.test(value) : false; }; -const validateEventType = (event) => { +const validateEventName = (event) => { if (!event || typeof event !== 'string') { throw new InstrumentationError('Event is a required field and should be a string'); } @@ -2177,7 +2177,7 @@ module.exports = { getDestAuthCacheInstance, refinePayload, validateEmail, - validateEventType, + validateEventName, validatePhoneWithCountryCode, getEventReqMetadata, isHybridModeEnabled, From 373535524c9c88f38cfbe558ec38e028221117fb Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Mon, 6 Nov 2023 10:17:13 +0000 Subject: [PATCH 16/93] chore(release): 1.49.0 --- CHANGELOG.md | 16 ++++++++++++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 01631435d2..b9256fa915 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,22 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +## [1.49.0](https://github.com/rudderlabs/rudder-transformer/compare/v1.48.0...v1.49.0) (2023-11-06) + + +### Features + +* add new destination tiktok_audience ([#2710](https://github.com/rudderlabs/rudder-transformer/issues/2710)) ([9bc0fd8](https://github.com/rudderlabs/rudder-transformer/commit/9bc0fd8efcee44871a190bd6cb9e89c5cf035ff8)) +* onboard one signal to router transform ([#2785](https://github.com/rudderlabs/rudder-transformer/issues/2785)) ([818858e](https://github.com/rudderlabs/rudder-transformer/commit/818858e046ce5f9735bbb97715c43a959ad3aa3c)) +* onboard revenuecat as a source ([#2774](https://github.com/rudderlabs/rudder-transformer/issues/2774)) ([55f9637](https://github.com/rudderlabs/rudder-transformer/commit/55f96374b4d73db7013c1d5e72bfc9c8257b224b)) + + +### Bug Fixes + +* add check to remove null and undefined properties before sending ([#2796](https://github.com/rudderlabs/rudder-transformer/issues/2796)) ([6e89cd3](https://github.com/rudderlabs/rudder-transformer/commit/6e89cd3f67ea887ba17c1cd5ffbca6675f54d96c)) +* allow support for full url from UI in freshsales and freshmarketer ([#2780](https://github.com/rudderlabs/rudder-transformer/issues/2780)) ([570532c](https://github.com/rudderlabs/rudder-transformer/commit/570532ce790c05a69621d9289758a1b1a7acda8c)) +* busgnag issues for klaviyo, freshsales, customeio ([#2795](https://github.com/rudderlabs/rudder-transformer/issues/2795)) ([11fb7c4](https://github.com/rudderlabs/rudder-transformer/commit/11fb7c47910681833e37d25a1573d2005e62742b)) + ## [1.48.0](https://github.com/rudderlabs/rudder-transformer/compare/v1.47.0...v1.48.0) (2023-11-02) diff --git a/package-lock.json b/package-lock.json index 0822a9b42b..5e857f6bb9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "rudder-transformer", - "version": "1.48.0", + "version": "1.49.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "rudder-transformer", - "version": "1.48.0", + "version": "1.49.0", "license": "ISC", "dependencies": { "@amplitude/ua-parser-js": "^0.7.24", diff --git a/package.json b/package.json index 46f728664d..ac0ae2bbeb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rudder-transformer", - "version": "1.48.0", + "version": "1.49.0", "description": "", "homepage": "https://github.com/rudderlabs/rudder-transformer#readme", "bugs": { From c99361b951960224b8220c854f9c509ec2844b52 Mon Sep 17 00:00:00 2001 From: Anant Jain Date: Tue, 7 Nov 2023 12:20:39 +0530 Subject: [PATCH 17/93] chore: comments addressed --- src/v0/destinations/am/transform.js | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/v0/destinations/am/transform.js b/src/v0/destinations/am/transform.js index b74625e273..d7d8f95565 100644 --- a/src/v0/destinations/am/transform.js +++ b/src/v0/destinations/am/transform.js @@ -589,8 +589,8 @@ const processSingleMessage = (message, destination) => { // To be used for track/page calls to associate the event to a group in AM let groupInfo = get(message, 'integrations.Amplitude.groups') || undefined; let category = ConfigCategory.DEFAULT; - let { properties } = message; - const { name, event } = message; + let updatedProperties; + const { name, event, properties } = message; const messageType = message.type.toLowerCase(); const CATEGORY_KEY = 'properties.category'; const { useUserDefinedPageEventName, userProvidedPageEventString } = destination.Config; @@ -623,17 +623,14 @@ const processSingleMessage = (message, destination) => { evType = `Viewed ${updatedName || ''}Page`; } message.properties = { - ...message.properties, + ...properties, name: name || get(message, CATEGORY_KEY), }; category = ConfigCategory.PAGE; break; case EventType.SCREEN: - ({ evType, updatedProperties: properties } = getScreenevTypeAndUpdatedProperties( - message, - CATEGORY_KEY, - )); - message.properties = properties; + ({ evType, updatedProperties } = getScreenevTypeAndUpdatedProperties(message, CATEGORY_KEY)); + message.properties = updatedProperties; category = ConfigCategory.SCREEN; break; case EventType.GROUP: @@ -664,9 +661,9 @@ const processSingleMessage = (message, destination) => { throw new InstrumentationError('Event not present. Please send event field'); } if ( - message.properties && - isDefinedAndNotNull(message.properties?.revenue) && - isDefinedAndNotNull(message.properties?.revenue_type) + properties && + isDefinedAndNotNull(properties?.revenue) && + isDefinedAndNotNull(properties?.revenue_type) ) { // if properties has revenue and revenue_type fields // consider the event as revenue event directly From 54120233ab07bb8c095f91a2dcb90a7d8e5fdf8e Mon Sep 17 00:00:00 2001 From: Anant Jain Date: Tue, 7 Nov 2023 12:49:08 +0530 Subject: [PATCH 18/93] chore: refactor screen code for evType and properties --- src/v0/destinations/am/transform.js | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/v0/destinations/am/transform.js b/src/v0/destinations/am/transform.js index d7d8f95565..04a1c5a107 100644 --- a/src/v0/destinations/am/transform.js +++ b/src/v0/destinations/am/transform.js @@ -196,7 +196,7 @@ const getScreenevTypeAndUpdatedProperties = (message, CATEGORY_KEY) => { const name = message.name || message.event || get(message, CATEGORY_KEY); const updatedName = name ? `${name} ` : ''; return { - evType: `Viewed ${updatedName}Screen`, + eventType: `Viewed ${updatedName}Screen`, updatedProperties: { ...message.properties, name, @@ -589,7 +589,6 @@ const processSingleMessage = (message, destination) => { // To be used for track/page calls to associate the event to a group in AM let groupInfo = get(message, 'integrations.Amplitude.groups') || undefined; let category = ConfigCategory.DEFAULT; - let updatedProperties; const { name, event, properties } = message; const messageType = message.type.toLowerCase(); const CATEGORY_KEY = 'properties.category'; @@ -629,9 +628,15 @@ const processSingleMessage = (message, destination) => { category = ConfigCategory.PAGE; break; case EventType.SCREEN: - ({ evType, updatedProperties } = getScreenevTypeAndUpdatedProperties(message, CATEGORY_KEY)); - message.properties = updatedProperties; - category = ConfigCategory.SCREEN; + { + const { eventType, updatedProperties } = getScreenevTypeAndUpdatedProperties( + message, + CATEGORY_KEY, + ); + evType = eventType; + message.properties = updatedProperties; + category = ConfigCategory.SCREEN; + } break; case EventType.GROUP: evType = 'group'; From b41aebf5f06800dceaf6ededce033b756c385559 Mon Sep 17 00:00:00 2001 From: Abhimanyu Babbar Date: Wed, 8 Nov 2023 11:38:30 +0530 Subject: [PATCH 19/93] chore(dm): added stats for the user transformation batch request (#2788) * added stats for user transform on openfaas * added stats for user transform to ivm --- src/legacy/router.js | 11 ---- src/services/userTransform.ts | 3 - src/util/customTransformer-faas.js | 17 +----- src/util/customTransformer-v1.js | 89 ++++++++++++---------------- src/util/customTransformer.js | 21 ++++--- src/util/customTransformerFactory.js | 28 +++++++-- src/util/openfaas/index.js | 54 +++++++++++------ src/util/prometheus.js | 67 ++++++++++----------- src/util/stats.js | 21 ++++--- 9 files changed, 156 insertions(+), 155 deletions(-) diff --git a/src/legacy/router.js b/src/legacy/router.js index a8c2b49a1a..99fb8570fb 100644 --- a/src/legacy/router.js +++ b/src/legacy/router.js @@ -571,14 +571,9 @@ if (startDestTransformer) { destEvents.length > 0 && destEvents[0].metadata ? getMetadata(destEvents[0].metadata) : {}; - const userFuncStartTime = new Date(); if (transformationVersionId) { let destTransformedEvents; try { - stats.counter('user_transform_function_input_events', destEvents.length, { - processSessions, - ...metaTags, - }); destTransformedEvents = await userTransformHandler()( destEvents, transformationVersionId, @@ -630,12 +625,6 @@ if (startDestTransformer) { processSessions, ...metaTags, }); - } finally { - stats.timing('user_transform_function_latency', userFuncStartTime, { - transformationVersionId, - processSessions, - ...metaTags, - }); } } else { const errorMessage = 'Transformation VersionID not found'; diff --git a/src/services/userTransform.ts b/src/services/userTransform.ts index 18165615a8..4fe1ad0b52 100644 --- a/src/services/userTransform.ts +++ b/src/services/userTransform.ts @@ -85,9 +85,6 @@ export default class UserTransformService { } const userFuncStartTime = new Date(); try { - stats.counter('user_transform_function_input_events', eventsToProcess.length, { - ...metaTags, - }); const destTransformedEvents: UserTransformationResponse[] = await userTransformHandler()( eventsToProcess, transformationVersionId, diff --git a/src/util/customTransformer-faas.js b/src/util/customTransformer-faas.js index 54d2410313..2c0bbfd8c0 100644 --- a/src/util/customTransformer-faas.js +++ b/src/util/customTransformer-faas.js @@ -24,8 +24,8 @@ function generateFunctionName(userTransformation, libraryVersionIds, testMode) { const ids = [userTransformation.workspaceId, userTransformation.versionId].concat( (libraryVersionIds || []).sort(), ); - const hash = crypto.createHash('md5').update(`${ids}`).digest('hex'); + const hash = crypto.createHash('md5').update(`${ids}`).digest('hex'); return `fn-${userTransformation.workspaceId}-${hash}`.substring(0, 63).toLowerCase(); } @@ -127,15 +127,8 @@ async function runOpenFaasUserTransform( if (events.length === 0) { throw new Error('Invalid payload. No events'); } - const metaTags = events[0].metadata ? getMetadata(events[0].metadata) : {}; - const tags = { - transformerVersionId: userTransformation.versionId, - identifier: 'openfaas', - testMode, - ...metaTags, - }; - const trMetadata = events[0].metadata ? getTransformationMetadata(events[0].metadata) : {}; + const trMetadata = events[0].metadata ? getTransformationMetadata(events[0].metadata) : {}; // check and deploy faas function if not exists const functionName = generateFunctionName(userTransformation, libraryVersionIds, testMode); if (testMode) { @@ -148,9 +141,7 @@ async function runOpenFaasUserTransform( ); } - const invokeTime = new Date(); - stats.counter('events_to_process', events.length, tags); - const result = await executeFaasFunction( + return await executeFaasFunction( functionName, events, userTransformation.versionId, @@ -165,8 +156,6 @@ async function runOpenFaasUserTransform( testMode, trMetadata, ); - stats.timing('run_time', invokeTime, tags); - return result; } module.exports = { diff --git a/src/util/customTransformer-v1.js b/src/util/customTransformer-v1.js index 397281d8d9..60f8e493fa 100644 --- a/src/util/customTransformer-v1.js +++ b/src/util/customTransformer-v1.js @@ -1,7 +1,7 @@ const ivm = require('isolated-vm'); const { getFactory } = require('./ivmFactory'); -const { getMetadata } = require('../v0/util'); +const { getMetadata, getTransformationMetadata } = require('../v0/util'); const logger = require('../logger'); const stats = require('./stats'); @@ -54,63 +54,48 @@ async function userTransformHandlerV1( libraryVersionIds, testMode = false, ) { - /* - Removing pool usage to address memory leaks - Env variable ON_DEMAND_ISOLATE_VM is not being used anymore - */ - if (userTransformation.versionId) { - const metaTags = events.length && events[0].metadata ? getMetadata(events[0].metadata) : {}; - const tags = { - transformerVersionId: userTransformation.versionId, - identifier: 'v1', - ...metaTags, - }; - - logger.debug(`Isolate VM being created... `); - const isolatevmFactory = await getFactory( - userTransformation.code, - libraryVersionIds, - userTransformation.versionId, - userTransformation.secrets || {}, - testMode, - ); - const isolatevm = await isolatevmFactory.create(); - logger.debug(`Isolate VM created... `); + if (!userTransformation.versionId) { + return { transformedEvents : events }; + } - // Transform the event... - stats.counter('events_to_process', events.length, tags); - const isolateStartWallTime = calculateMsFromIvmTime(isolatevm.isolateStartWallTime); - const isolateStartCPUTime = calculateMsFromIvmTime(isolatevm.isolateStartCPUTime); + const isolatevmFactory = await getFactory( + userTransformation.code, + libraryVersionIds, + userTransformation.versionId, + userTransformation.secrets || {}, + testMode, + ); - const invokeTime = new Date(); - let transformedEvents; - // Destroy isolatevm in case of execution errors - try { - transformedEvents = await transform(isolatevm, events); - } catch (err) { - logger.error(`Error encountered while executing transformation: ${err.message}`); - isolatevmFactory.destroy(isolatevm); - throw err; - } - const { logs } = isolatevm; - stats.timing('run_time', invokeTime, tags); - const isolateEndWallTime = calculateMsFromIvmTime(isolatevm.isolate.wallTime); - const isolateEndCPUTime = calculateMsFromIvmTime(isolatevm.isolate.cpuTime); + logger.debug(`Creating IsolateVM`); + const isolatevm = await isolatevmFactory.create(); - //TODO: fix "Value is not a valid number: NaN" error and uncomment - //stats.timing('isolate_wall_time', isolateEndWallTime - isolateStartWallTime, tags); - //stats.timing('isolate_cpu_time', isolateEndCPUTime - isolateStartCPUTime, tags); + const invokeTime = new Date(); + let transformedEvents; + let logs; + let transformationError; - // Destroy the isolated vm resources created - logger.debug(`Isolate VM being destroyed... `); + try { + transformedEvents = await transform(isolatevm, events); + logs = isolatevm.logs; + } catch (err) { + logger.error(`Error encountered while executing transformation: ${err.message}`); + transformationError = err; + throw err; + } finally { + logger.debug(`Destroying IsolateVM`); isolatevmFactory.destroy(isolatevm); - logger.debug(`Isolate VM destroyed... `); - - return { transformedEvents, logs }; - // Events contain message and destination. We take the message part of event and run transformation on it. - // And put back the destination after transforrmation + // send the observability stats + const tags = { + identifier: 'v1', + errored: transformationError ? true : false, + ...events.length && events[0].metadata ? getMetadata(events[0].metadata) : {}, + ...events.length && events[0].metadata ? getTransformationMetadata(events[0].metadata) : {} + } + stats.counter('user_transform_function_input_events', events.length, tags); + stats.timing('user_transform_function_latency', invokeTime, tags); } - return { transformedEvents: events }; + + return { transformedEvents, logs }; } async function setUserTransformHandlerV1() { diff --git a/src/util/customTransformer.js b/src/util/customTransformer.js index 90dcea61b2..001fe3216c 100644 --- a/src/util/customTransformer.js +++ b/src/util/customTransformer.js @@ -7,6 +7,7 @@ const { UserTransformHandlerFactory } = require('./customTransformerFactory'); const { parserForImport } = require('./parser'); const stats = require('./stats'); const { fetchWithDnsWrapper } = require('./utils'); +const { getMetadata, getTransformationMetadata } = require('../v0/util'); const ISOLATE_VM_MEMORY = parseInt(process.env.ISOLATE_VM_MEMORY || '128', 10); const GEOLOCATION_TIMEOUT_IN_MS = parseInt(process.env.GEOLOCATION_TIMEOUT_IN_MS || '1000', 10); @@ -19,10 +20,6 @@ async function runUserTransform( versionId, testMode = false, ) { - const tags = { - transformerVersionId: versionId, - identifier: 'v0', - }; // TODO: Decide on the right value for memory limit const isolate = new ivm.Isolate({ memoryLimit: ISOLATE_VM_MEMORY }); const context = await isolate.createContext(); @@ -214,9 +211,6 @@ async function runUserTransform( const customScript = await isolate.compileScript(`${code}`); await customScript.run(context); const fnRef = await jail.get('transform', { reference: true }); - // stat - stats.counter('events_to_process', events.length, tags); - // TODO : check if we can resolve this // eslint-disable-next-line no-async-promise-executor const executionPromise = new Promise(async (resolve, reject) => { const sharedMessagesList = new ivm.ExternalCopy(events).copyInto({ @@ -233,6 +227,7 @@ async function runUserTransform( } }); let result; + let transformationError; const invokeTime = new Date(); try { const timeoutPromise = new Promise((resolve) => { @@ -245,8 +240,8 @@ async function runUserTransform( if (result === 'Timedout') { throw new Error('Timed out'); } - stats.timing('run_time', invokeTime, tags); } catch (error) { + transformationError = error; throw error; } finally { // release function, script, context and isolate @@ -255,6 +250,16 @@ async function runUserTransform( bootstrapScriptResult.release(); context.release(); isolate.dispose(); + + const tags = { + identifier: 'v0', + errored: transformationError ? true : false, + ...events.length && events[0].metadata ? getMetadata(events[0].metadata) : {}, + ...events.length && events[0].metadata ? getTransformationMetadata(events[0].metadata) : {} + } + + stats.counter('user_transform_function_input_events', events.length, tags); + stats.timing('user_transform_function_latency', invokeTime, tags); } return { diff --git a/src/util/customTransformerFactory.js b/src/util/customTransformerFactory.js index 66268db286..1bf10e5d45 100644 --- a/src/util/customTransformerFactory.js +++ b/src/util/customTransformerFactory.js @@ -1,9 +1,15 @@ -const { setOpenFaasUserTransform, runOpenFaasUserTransform } = require('./customTransformer-faas'); +const { + setOpenFaasUserTransform, + runOpenFaasUserTransform, +} = require('./customTransformer-faas'); -const { userTransformHandlerV1, setUserTransformHandlerV1 } = require('./customTransformer-v1'); +const { + userTransformHandlerV1, + setUserTransformHandlerV1, +} = require('./customTransformer-v1'); const UserTransformHandlerFactory = (userTransformation) => { - const transformHandler = { + return { setUserTransform: async (libraryVersionIds) => { switch (userTransformation.language) { case 'pythonfaas': @@ -17,13 +23,23 @@ const UserTransformHandlerFactory = (userTransformation) => { switch (userTransformation.language) { case 'pythonfaas': case 'python': - return runOpenFaasUserTransform(events, userTransformation, libraryVersionIds, testMode); + return runOpenFaasUserTransform( + events, + userTransformation, + libraryVersionIds, + testMode + ); + default: - return userTransformHandlerV1(events, userTransformation, libraryVersionIds, testMode); + return userTransformHandlerV1( + events, + userTransformation, + libraryVersionIds, + testMode + ); } }, }; - return transformHandler; }; exports.UserTransformHandlerFactory = UserTransformHandlerFactory; diff --git a/src/util/openfaas/index.js b/src/util/openfaas/index.js index f80aa01c23..47a69aeb18 100644 --- a/src/util/openfaas/index.js +++ b/src/util/openfaas/index.js @@ -1,6 +1,5 @@ const NodeCache = require('node-cache'); const { - getFunction, deleteFunction, deployFunction, invokeFunction, @@ -8,6 +7,9 @@ const { } = require('./faasApi'); const logger = require('../../logger'); const { RetryRequestError, RespStatusError } = require('../utils'); +const stats = require('../stats'); +const { getMetadata, getTransformationMetadata } = require('../../v0/util'); +const { HTTP_STATUS_CODES } = require('../../v0/util/constant'); const FAAS_BASE_IMG = process.env.FAAS_BASE_IMG || 'rudderlabs/openfaas-flask:main'; const FAAS_MAX_PODS_IN_TEXT = process.env.FAAS_MAX_PODS_IN_TEXT || '40'; @@ -230,41 +232,44 @@ async function setupFaasFunction( } const executeFaasFunction = async ( - functionName, + name, events, versionId, libraryVersionIDs, testMode, trMetadata = {}, ) => { - try { - logger.debug('[Faas] Invoking faas function'); + logger.debug(`Executing faas function: ${name}`); - if (testMode) await awaitFunctionReadiness(functionName); + const startTime = new Date(); + let errorRaised; + + try { + if (testMode) await awaitFunctionReadiness(name); + return await invokeFunction(name, events); - const res = await invokeFunction(functionName, events); - logger.debug('[Faas] Invoked faas function'); - return res; } catch (error) { - logger.error(`[Faas] Error while invoking ${functionName}: ${error.message}`); + logger.error(`Error while invoking ${name}: ${error.message}`); + errorRaised = error; + if ( error.statusCode === 404 && - error.message.includes(`error finding function ${functionName}`) + error.message.includes(`error finding function ${name}`) ) { - removeFunctionFromCache(functionName); + removeFunctionFromCache(name); await setupFaasFunction( - functionName, + name, null, versionId, libraryVersionIDs, testMode, trMetadata, ); - throw new RetryRequestError(`${functionName} not found`); + throw new RetryRequestError(`${name} not found`); } if (error.statusCode === 429) { - throw new RetryRequestError(`Rate limit exceeded for ${functionName}`); + throw new RetryRequestError(`Rate limit exceeded for ${name}`); } if (error.statusCode === 500 || error.statusCode === 503) { @@ -272,16 +277,29 @@ const executeFaasFunction = async ( } if (error.statusCode === 504) { - throw new RespStatusError('Timed out'); + throw new RespStatusError(`${name} timed out`); } throw error; } finally { + // delete the function created, if it's called as part of testMode if (testMode) { - deleteFunction(functionName).catch((err) => { - logger.error(`[Faas] Error while deleting ${functionName}: ${err.message}`); - }); + deleteFunction(name).catch((err) => + logger.error(`[Faas] Error while deleting ${name}: ${err.message}`)) + } + + // setup the tags for observability and then fire the stats + const tags = { + identifier: "openfaas", + testMode: testMode, + errored: errorRaised ? true : false, + statusCode: errorRaised ? errorRaised.statusCode : HTTP_STATUS_CODES.OK, // default statuscode is 200OK + ...events.length && events[0].metadata ? getMetadata(events[0].metadata) : {}, + ...events.length && events[0].metadata ? getTransformationMetadata(events[0].metadata) : {}, } + + stats.counter('user_transform_function_input_events', events.length, tags) + stats.timing('user_transform_function_latency', startTime, tags) } }; diff --git a/src/util/prometheus.js b/src/util/prometheus.js index 9f3255a05d..116f77d214 100644 --- a/src/util/prometheus.js +++ b/src/util/prometheus.js @@ -249,12 +249,6 @@ class Prometheus { type: 'counter', labelNames: ['processSessions'], }, - { - name: 'user_transform_function_input_events', - help: 'user_transform_function_input_events', - type: 'counter', - labelNames: ['processSessions', 'sourceType', 'destinationType', 'k8_namespace'], - }, { name: 'user_transform_errors', help: 'user_transform_errors', @@ -505,20 +499,6 @@ class Prometheus { type: 'counter', labelNames: ['writeKey', 'source'], }, - { - name: 'events_to_process', - help: 'events_to_process', - type: 'counter', - labelNames: [ - 'transformerVersionId', - 'language', - 'identifier', - 'testMode', - 'sourceType', - 'destinationType', - 'k8_namespace', - ], - }, { name: 'get_transformation_code', help: 'get_transformation_code', @@ -668,21 +648,6 @@ class Prometheus { type: 'histogram', labelNames: ['transformerVersionId', 'language', 'identifier', 'publish', 'testMode'], }, - { - name: 'run_time', - help: 'run_time', - type: 'histogram', - labelNames: [ - 'transformerVersionId', - 'language', - 'identifier', - 'publish', - 'testMode', - 'sourceType', - 'destinationType', - 'k8_namespace', - ], - }, { name: 'get_tracking_plan', help: 'get_tracking_plan', type: 'histogram', labelNames: [] }, { name: 'createivm_duration', help: 'createivm_duration', type: 'histogram', labelNames: [] }, { @@ -940,6 +905,38 @@ class Prometheus { type: 'histogram', labelNames: [], }, + { + name: 'user_transform_function_input_events', + help: 'user_transform_function_input_events', + type: 'counter', + labelNames: [ + 'identifier', + 'testMode', + 'sourceType', + 'destinationType', + 'k8_namespace', + 'errored', + 'statusCode', + 'transformationId', + 'workspaceId' + ], + }, + { + name: 'user_transform_function_latency', + help: 'user_transform_function_latency', + type: 'histogram', + labelNames: [ + 'identifier', + 'testMode', + 'sourceType', + 'destinationType', + 'k8_namespace', + 'errored', + 'statusCode', + 'transformationId', + 'workspaceId' + ], + } ]; metrics.forEach((metric) => { diff --git a/src/util/stats.js b/src/util/stats.js index de77362ac1..e57ab85731 100644 --- a/src/util/stats.js +++ b/src/util/stats.js @@ -11,14 +11,19 @@ function init() { return; } - if (statsClientType === 'statsd') { - statsClient = new statsd.Statsd(); - logger.info('created statsd client'); - } else if (statsClientType === 'prometheus') { - statsClient = new prometheus.Prometheus(); - logger.info('created prometheus client'); - } else { - logger.info("Invalid stats client type. Valid values are 'statsd' and 'prometheus'."); + switch (statsClientType) { + case 'statsd': + logger.info("setting up statsd client") + statsClient = new statsd.Statsd(); + break; + + case 'prometheus': + logger.info("setting up prometheus client") + statsClient = new prometheus.Prometheus(); + break; + + default: + logger.error(`invalid stats client type: ${statsClientType}, supported values are 'statsd' and 'prometheues'`) } } From 8be8294b79c3f3ba2a804a30648f047e0a6331c4 Mon Sep 17 00:00:00 2001 From: Mihir Bhalala <77438541+mihir-4116@users.noreply.github.com> Date: Wed, 8 Nov 2023 12:00:05 +0530 Subject: [PATCH 20/93] chore: security upgrade crypto-js from 4.1.1 to 4.2.0 (#2768) fix: package.json & package-lock.json to reduce vulnerabilities The following vulnerabilities are fixed with an upgrade: - https://snyk.io/vuln/SNYK-JS-CRYPTOJS-6028119 Co-authored-by: snyk-bot --- package-lock.json | 7 ++++--- package.json | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5e857f6bb9..f85f4c0516 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,7 +26,7 @@ "axios": "^1.4.0", "btoa": "^1.2.1", "component-each": "^0.2.6", - "crypto-js": "^4.1.1", + "crypto-js": "^4.2.0", "dotenv": "^16.0.3", "flat": "^5.0.2", "form-data": "^4.0.0", @@ -10608,8 +10608,9 @@ } }, "node_modules/crypto-js": { - "version": "4.1.1", - "license": "MIT" + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", + "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==" }, "node_modules/currently-unhandled": { "version": "0.4.1", diff --git a/package.json b/package.json index ac0ae2bbeb..4b57da4d5f 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,7 @@ "axios": "^1.4.0", "btoa": "^1.2.1", "component-each": "^0.2.6", - "crypto-js": "^4.1.1", + "crypto-js": "^4.2.0", "dotenv": "^16.0.3", "flat": "^5.0.2", "form-data": "^4.0.0", From c14b68997d90205d59f30a61723b937a2e88fb43 Mon Sep 17 00:00:00 2001 From: ktgowtham Date: Wed, 8 Nov 2023 12:00:39 +0530 Subject: [PATCH 21/93] chore: security upgrade axios from 1.4.0 to 1.6.0 (#2772) fix: package.json & package-lock.json to reduce vulnerabilities The following vulnerabilities are fixed with an upgrade: - https://snyk.io/vuln/SNYK-JS-AXIOS-6032459 Co-authored-by: snyk-bot --- package-lock.json | 7 ++++--- package.json | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index f85f4c0516..c16855ccfd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,7 +23,7 @@ "ajv": "^8.12.0", "ajv-draft-04": "^1.0.0", "ajv-formats": "^2.1.1", - "axios": "^1.4.0", + "axios": "^1.6.0", "btoa": "^1.2.1", "component-each": "^0.2.6", "crypto-js": "^4.2.0", @@ -8171,8 +8171,9 @@ "license": "MIT" }, "node_modules/axios": { - "version": "1.4.0", - "license": "MIT", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.0.tgz", + "integrity": "sha512-EZ1DYihju9pwVB+jg67ogm+Tmqc6JmhamRN6I4Zt8DfZu5lbcQGw3ozH9lFejSJgs/ibaef3A9PMXPLeefFGJg==", "dependencies": { "follow-redirects": "^1.15.0", "form-data": "^4.0.0", diff --git a/package.json b/package.json index 4b57da4d5f..f0746c9aaf 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,7 @@ "ajv": "^8.12.0", "ajv-draft-04": "^1.0.0", "ajv-formats": "^2.1.1", - "axios": "^1.4.0", + "axios": "^1.6.0", "btoa": "^1.2.1", "component-each": "^0.2.6", "crypto-js": "^4.2.0", From c02370e38fabb581698baa00e1ddd3da93dc07fa Mon Sep 17 00:00:00 2001 From: Anant Jain <62471433+anantjain45823@users.noreply.github.com> Date: Thu, 9 Nov 2023 20:26:15 +0530 Subject: [PATCH 22/93] fix: shopify redis metric when there is no data returned for a key (#2811) fix: shopfify redis metric when there is no data returned for a key --- src/v0/sources/shopify/util.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/v0/sources/shopify/util.js b/src/v0/sources/shopify/util.js index 0d81ddc185..2521e9cb9d 100644 --- a/src/v0/sources/shopify/util.js +++ b/src/v0/sources/shopify/util.js @@ -32,7 +32,7 @@ const getDataFromRedis = async (key, metricMetadata) => { ...metricMetadata, }); const redisData = await RedisDB.getVal(key); - if (redisData === null) { + if (redisData === null || (typeof redisData === "object" && Object.keys(redisData).length === 0)) { stats.increment('shopify_redis_no_val', { ...metricMetadata, }); From 8eb1e1d482923004e2f3357e4163a8ea95b9e183 Mon Sep 17 00:00:00 2001 From: Gauravudia <60897972+Gauravudia@users.noreply.github.com> Date: Fri, 10 Nov 2023 12:16:32 +0530 Subject: [PATCH 23/93] chore: import error classes from integrations lib (#2719) --- package-lock.json | 35 ++++++-- package.json | 1 + .../networkhandler/genericNetworkHandler.js | 2 +- src/adapters/utils/networkUtils.js | 2 +- src/cdk/v1/autopilot/transform.js | 2 +- src/cdk/v1/dcm_floodlight/transform.js | 2 +- src/cdk/v1/handler.js | 8 +- src/cdk/v2/bindings/default.js | 2 +- .../v2/destinations/dcm_floodlight/utils.js | 2 +- src/cdk/v2/utils.ts | 2 +- src/helpers/serviceSelector.ts | 2 +- src/services/destination/cdkV1Integration.ts | 2 +- src/services/destination/cdkV2Integration.ts | 2 +- src/util/errorNotifier/bugsnag.js | 9 +- src/util/redis/redisConnector.js | 2 +- .../destinations/active_campaign/transform.js | 10 +-- src/v0/destinations/active_campaign/util.js | 2 +- src/v0/destinations/adj/transform.js | 10 +-- .../destinations/adobe_analytics/transform.js | 10 +-- src/v0/destinations/adobe_analytics/utils.js | 8 +- src/v0/destinations/af/deleteUsers.js | 6 +- src/v0/destinations/af/transform.js | 2 +- src/v0/destinations/airship/transform.js | 2 +- src/v0/destinations/algolia/transform.js | 4 +- src/v0/destinations/algolia/util.js | 2 +- src/v0/destinations/am/deleteUsers.js | 2 +- src/v0/destinations/am/transform.js | 3 +- src/v0/destinations/appcues/transform.js | 2 +- .../destinations/attentive_tag/transform.js | 2 +- src/v0/destinations/attentive_tag/util.js | 2 +- src/v0/destinations/attribution/transform.js | 2 +- src/v0/destinations/autopilot/transform.js | 2 +- src/v0/destinations/awin/transform.js | 2 +- .../destinations/azure_event_hub/transform.js | 1 - src/v0/destinations/blueshift/transform.js | 10 +-- src/v0/destinations/bqstream/transform.js | 2 +- src/v0/destinations/branch/transform.js | 2 +- src/v0/destinations/braze/deleteUsers.js | 2 +- src/v0/destinations/braze/networkHandler.js | 2 +- src/v0/destinations/braze/transform.js | 7 +- src/v0/destinations/braze/util.js | 2 +- .../campaign_manager/networkHandler.js | 2 +- .../campaign_manager/transform.js | 3 +- src/v0/destinations/candu/transform.js | 2 +- src/v0/destinations/canny/transform.js | 2 +- src/v0/destinations/canny/util.js | 2 +- src/v0/destinations/clevertap/deleteUsers.js | 2 +- .../destinations/clevertap/networkHandler.js | 2 +- src/v0/destinations/clevertap/transform.js | 2 +- src/v0/destinations/clickup/transform.js | 2 +- src/v0/destinations/clickup/util.js | 2 +- .../destinations/confluent_cloud/transform.js | 1 - src/v0/destinations/courier/transform.js | 10 +-- .../criteo_audience/networkHandler.js | 14 +-- .../destinations/criteo_audience/transform.js | 2 +- src/v0/destinations/criteo_audience/util.js | 2 +- src/v0/destinations/custify/deleteUsers.js | 6 +- src/v0/destinations/custify/transform.js | 2 +- src/v0/destinations/custify/util.js | 2 +- src/v0/destinations/customerio/transform.js | 2 +- src/v0/destinations/customerio/util.js | 3 +- src/v0/destinations/delighted/transform.js | 10 +-- src/v0/destinations/delighted/util.js | 8 +- src/v0/destinations/discord/transform.js | 2 +- src/v0/destinations/drip/transform.js | 10 +-- src/v0/destinations/drip/util.js | 2 +- src/v0/destinations/engage/deleteUsers.js | 2 +- src/v0/destinations/engage/transform.js | 2 +- src/v0/destinations/eventbridge/transform.js | 2 +- .../facebook_offline_conversions/transform.js | 2 +- .../facebook_offline_conversions/utils.js | 2 +- .../destinations/facebook_pixel/transform.js | 3 +- src/v0/destinations/facebook_pixel/utils.js | 2 +- src/v0/destinations/factorsai/transform.js | 2 +- src/v0/destinations/fb/transform.js | 2 +- .../fb_custom_audience/transform.js | 10 +-- .../destinations/fb_custom_audience/util.js | 2 +- src/v0/destinations/firehose/transform.js | 2 +- .../destinations/freshmarketer/transform.js | 10 +-- src/v0/destinations/freshmarketer/utils.js | 10 +-- src/v0/destinations/freshsales/transform.js | 2 +- src/v0/destinations/freshsales/utils.js | 10 +-- src/v0/destinations/ga/deleteUsers.js | 2 +- src/v0/destinations/ga/networkHandler.js | 2 +- src/v0/destinations/ga/transform.js | 2 +- src/v0/destinations/ga/utils.js | 2 +- src/v0/destinations/ga360/transform.js | 2 +- src/v0/destinations/ga4/networkHandler.js | 2 +- src/v0/destinations/ga4/transform.js | 10 +-- src/v0/destinations/ga4/utils.js | 2 +- src/v0/destinations/gainsight/transform.js | 2 +- src/v0/destinations/gainsight/util.js | 6 +- src/v0/destinations/gainsight_px/transform.js | 2 +- src/v0/destinations/gainsight_px/util.js | 2 +- .../networkHandler.js | 3 +- .../transform.js | 3 +- .../networkHandler.js | 10 +-- .../transform.js | 2 +- .../utils.js | 6 +- .../networkHandler.js | 2 +- .../transform.js | 2 +- .../google_cloud_function/util.js | 2 +- src/v0/destinations/googlepubsub/transform.js | 2 +- src/v0/destinations/googlesheets/transform.js | 2 +- src/v0/destinations/heap/transform.js | 2 +- src/v0/destinations/hs/HSTransform-v1.js | 10 +-- src/v0/destinations/hs/HSTransform-v2.js | 10 +-- src/v0/destinations/hs/transform.js | 2 +- src/v0/destinations/hs/util.js | 12 +-- src/v0/destinations/impact/transform.js | 10 +-- src/v0/destinations/indicative/transform.js | 2 +- src/v0/destinations/intercom/deleteUsers.js | 2 +- .../destinations/intercom/networkHandler.js | 3 +- src/v0/destinations/intercom/transform.js | 2 +- src/v0/destinations/iterable/deleteUsers.js | 2 +- src/v0/destinations/iterable/transform.js | 2 +- src/v0/destinations/iterable/util.js | 2 +- src/v0/destinations/june/transform.js | 2 +- src/v0/destinations/kafka/transform.js | 1 - src/v0/destinations/keen/transform.js | 2 +- src/v0/destinations/kissmetrics/transform.js | 2 +- src/v0/destinations/klaviyo/transform.js | 7 +- src/v0/destinations/klaviyo/util.js | 2 +- src/v0/destinations/kochava/transform.js | 2 +- src/v0/destinations/kustomer/transform.js | 2 +- src/v0/destinations/kustomer/util.js | 2 +- src/v0/destinations/lambda/transform.js | 2 +- src/v0/destinations/leanplum/transform.js | 2 +- src/v0/destinations/lemnisk/transform.js | 10 +-- src/v0/destinations/lemnisk/utils.js | 2 +- src/v0/destinations/lytics/transform.js | 2 +- src/v0/destinations/mailchimp/transform.js | 2 +- src/v0/destinations/mailchimp/utils.js | 2 +- src/v0/destinations/mailjet/transform.js | 2 +- src/v0/destinations/mailmodo/transform.js | 2 +- src/v0/destinations/marketo/transform.js | 10 +-- src/v0/destinations/marketo/util.js | 14 +-- .../marketo_bulk_upload/fetchJobStatus.js | 2 +- .../marketo_bulk_upload/fileUpload.js | 12 +-- .../marketo_bulk_upload.util.test.js | 2 +- .../destinations/marketo_bulk_upload/poll.js | 2 +- .../marketo_bulk_upload/transform.js | 2 +- .../destinations/marketo_bulk_upload/util.js | 4 +- .../marketo_static_list/transform.js | 2 +- .../destinations/marketo_static_list/util.js | 2 +- src/v0/destinations/mautic/transform.js | 10 +-- src/v0/destinations/mautic/utils.js | 6 +- src/v0/destinations/moengage/transform.js | 10 +-- src/v0/destinations/monday/transform.js | 10 +-- src/v0/destinations/monday/util.js | 6 +- src/v0/destinations/monetate/transform.js | 2 +- src/v0/destinations/monetate/utils.js | 2 +- src/v0/destinations/mp/deleteUsers.js | 2 +- src/v0/destinations/mp/transform.js | 2 +- src/v0/destinations/mp/util.js | 2 +- .../ometria/networkResponseHandler.js | 2 +- src/v0/destinations/ometria/transform.js | 2 +- src/v0/destinations/one_signal/transform.js | 10 +-- src/v0/destinations/one_signal/util.js | 2 +- src/v0/destinations/pagerduty/transform.js | 10 +-- src/v0/destinations/pagerduty/util.js | 2 +- src/v0/destinations/pardot/networkHandler.js | 2 +- src/v0/destinations/pardot/transform.js | 2 +- src/v0/destinations/persistiq/transform.js | 2 +- src/v0/destinations/persistiq/util.js | 2 +- src/v0/destinations/personalize/transform.js | 2 +- .../destinations/pinterest_tag/transform.js | 2 +- src/v0/destinations/pinterest_tag/utils.js | 2 +- src/v0/destinations/posthog/transform.js | 2 +- src/v0/destinations/profitwell/transform.js | 6 +- src/v0/destinations/profitwell/utils.js | 5 +- src/v0/destinations/redis/transform.js | 2 +- src/v0/destinations/refiner/transform.js | 2 +- src/v0/destinations/refiner/utils.js | 2 +- src/v0/destinations/revenue_cat/transform.js | 10 +-- src/v0/destinations/rockerbox/transform.js | 2 +- src/v0/destinations/salesforce/transform.js | 5 +- src/v0/destinations/salesforce/utils.js | 2 +- src/v0/destinations/sendgrid/deleteUsers.js | 2 +- src/v0/destinations/sendgrid/transform.js | 10 +-- src/v0/destinations/sendgrid/util.js | 6 +- src/v0/destinations/sendinblue/transform.js | 2 +- src/v0/destinations/sendinblue/util.js | 2 +- src/v0/destinations/serenytics/transform.js | 10 +-- src/v0/destinations/serenytics/utils.js | 2 +- src/v0/destinations/sfmc/transform.js | 6 +- src/v0/destinations/shynet/transform.js | 2 +- src/v0/destinations/signl4/transform.js | 10 +-- src/v0/destinations/singular/transform.js | 2 +- src/v0/destinations/singular/util.js | 2 +- src/v0/destinations/slack/transform.js | 2 +- .../snapchat_conversion/transform.js | 2 +- .../networkHandler.js | 2 +- .../snapchat_custom_audience/transform.js | 2 +- .../snapchat_custom_audience/utils.js | 2 +- src/v0/destinations/splitio/transform.js | 2 +- src/v0/destinations/statsig/transform.js | 2 +- src/v0/destinations/stormly/transform.js | 5 +- .../destinations/tiktok_ads/networkHandler.js | 2 +- src/v0/destinations/tiktok_ads/transform.js | 2 +- .../tiktok_ads_offline_events/transform.js | 2 +- src/v0/destinations/trengo/transform.js | 14 +-- src/v0/destinations/twitter_ads/transform.js | 10 +-- src/v0/destinations/user/transform.js | 10 +-- src/v0/destinations/user/utils.js | 5 +- src/v0/destinations/userlist/transform.js | 2 +- src/v0/destinations/vero/transform.js | 2 +- src/v0/destinations/webengage/transform.js | 2 +- src/v0/destinations/webhook/transform.js | 2 +- src/v0/destinations/woopra/transform.js | 2 +- src/v0/destinations/wootric/transform.js | 2 +- src/v0/destinations/wootric/util.js | 2 +- src/v0/destinations/yahoo_dsp/transform.js | 2 +- src/v0/destinations/yahoo_dsp/util.js | 2 +- src/v0/destinations/zendesk/transform.js | 10 +-- src/v0/destinations/zendesk/util.js | 2 +- src/v0/sources/appsflyer/transform.js | 2 +- src/v0/sources/braze/transform.js | 2 +- src/v0/sources/canny/transform.js | 2 +- src/v0/sources/canny/util.js | 2 +- src/v0/sources/customerio/transform.js | 2 - src/v0/sources/gainsightpx/transform.js | 2 +- src/v0/sources/iterable/transform.js | 2 +- src/v0/sources/mailmodo/transform.js | 2 +- src/v0/sources/monday/transform.js | 2 +- src/v0/sources/shopify/util.js | 2 +- src/v0/util/errorTypes/abortedError.js | 15 ---- src/v0/util/errorTypes/configurationError.js | 16 ---- src/v0/util/errorTypes/index.js | 32 ------- .../util/errorTypes/instrumentationError.js | 15 ---- .../util/errorTypes/invalidAuthTokenError.js | 16 ---- src/v0/util/errorTypes/networkError.js | 29 ------- .../errorTypes/networkInstrumentationError.js | 16 ---- src/v0/util/errorTypes/oAuthSecretError.js | 15 ---- src/v0/util/errorTypes/platformError.js | 14 --- src/v0/util/errorTypes/redisError.js | 15 ---- src/v0/util/errorTypes/retryableError.js | 15 ---- src/v0/util/errorTypes/throttledError.js | 15 ---- src/v0/util/errorTypes/transformationError.js | 14 --- src/v0/util/errorTypes/unauthorizedError.js | 16 ---- .../errorTypes/unhandledStatusCodeError.js | 16 ---- .../util/errorTypes/unsupportedEventError.js | 14 --- src/v0/util/facebookUtils/index.js | 2 +- src/v0/util/facebookUtils/networkHandler.js | 2 +- src/v0/util/index.js | 8 +- src/v0/util/regulation-api.js | 2 +- src/warehouse/identity.js | 2 +- src/warehouse/index.js | 2 +- src/warehouse/util.js | 2 +- src/warehouse/v1/util.js | 2 +- .../pinterest_tag/processor/data.ts | 85 +++++++++++++++++++ 251 files changed, 562 insertions(+), 689 deletions(-) delete mode 100644 src/v0/util/errorTypes/abortedError.js delete mode 100644 src/v0/util/errorTypes/configurationError.js delete mode 100644 src/v0/util/errorTypes/instrumentationError.js delete mode 100644 src/v0/util/errorTypes/invalidAuthTokenError.js delete mode 100644 src/v0/util/errorTypes/networkError.js delete mode 100644 src/v0/util/errorTypes/networkInstrumentationError.js delete mode 100644 src/v0/util/errorTypes/oAuthSecretError.js delete mode 100644 src/v0/util/errorTypes/platformError.js delete mode 100644 src/v0/util/errorTypes/redisError.js delete mode 100644 src/v0/util/errorTypes/retryableError.js delete mode 100644 src/v0/util/errorTypes/throttledError.js delete mode 100644 src/v0/util/errorTypes/transformationError.js delete mode 100644 src/v0/util/errorTypes/unauthorizedError.js delete mode 100644 src/v0/util/errorTypes/unhandledStatusCodeError.js delete mode 100644 src/v0/util/errorTypes/unsupportedEventError.js diff --git a/package-lock.json b/package-lock.json index c16855ccfd..91f984e22c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,7 @@ "@koa/router": "^12.0.0", "@ndhoule/extend": "^2.0.0", "@pyroscope/nodejs": "^0.2.6", + "@rudderstack/integrations-lib": "^0.1.8", "@rudderstack/workflow-engine": "^0.5.7", "ajv": "^8.12.0", "ajv-draft-04": "^1.0.0", @@ -6637,6 +6638,25 @@ "node": ">= 8" } }, + "node_modules/@rudderstack/integrations-lib": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/@rudderstack/integrations-lib/-/integrations-lib-0.1.8.tgz", + "integrity": "sha512-f8GX78RFma3XAWPNEI6QjGk4avbE8r9aspHNaYE+YyRKsJGWrl8gw/k+Jso36C0juOGas79GWPSiypbXLu8Q/g==", + "dependencies": { + "@rudderstack/workflow-engine": "^0.5.7", + "axios": "^1.4.0", + "axios-mock-adapter": "^1.22.0", + "crypto": "^1.0.1", + "get-value": "^3.0.1", + "handlebars": "^4.7.8", + "lodash": "^4.17.21", + "moment": "^2.29.4", + "moment-timezone": "^0.5.43", + "set-value": "^4.1.0", + "sha256": "^0.2.0", + "tslib": "^2.4.0" + } + }, "node_modules/@rudderstack/json-template-engine": { "version": "0.5.5", "license": "MIT" @@ -8184,7 +8204,6 @@ "version": "1.22.0", "resolved": "https://registry.npmjs.org/axios-mock-adapter/-/axios-mock-adapter-1.22.0.tgz", "integrity": "sha512-dmI0KbkyAhntUR05YY96qg2H6gg0XMl2+qTW0xmYg6Up+BFBAJYRLROMXRdDEL06/Wqwa0TJThAYvFtSFdRCZw==", - "dev": true, "dependencies": { "fast-deep-equal": "^3.1.3", "is-buffer": "^2.0.5" @@ -8197,7 +8216,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", - "dev": true, "funding": [ { "type": "github", @@ -10608,6 +10626,12 @@ "node": "*" } }, + "node_modules/crypto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/crypto/-/crypto-1.0.1.tgz", + "integrity": "sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==", + "deprecated": "This package is no longer supported. It's now a built-in Node module. If you've depended on crypto, you should switch to the one that's built-in." + }, "node_modules/crypto-js": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", @@ -13104,11 +13128,12 @@ "license": "MIT" }, "node_modules/handlebars": { - "version": "4.7.7", - "license": "MIT", + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", "dependencies": { "minimist": "^1.2.5", - "neo-async": "^2.6.0", + "neo-async": "^2.6.2", "source-map": "^0.6.1", "wordwrap": "^1.0.0" }, diff --git a/package.json b/package.json index f0746c9aaf..bfa2630971 100644 --- a/package.json +++ b/package.json @@ -63,6 +63,7 @@ "@koa/router": "^12.0.0", "@ndhoule/extend": "^2.0.0", "@pyroscope/nodejs": "^0.2.6", + "@rudderstack/integrations-lib": "^0.1.8", "@rudderstack/workflow-engine": "^0.5.7", "ajv": "^8.12.0", "ajv-draft-04": "^1.0.0", diff --git a/src/adapters/networkhandler/genericNetworkHandler.js b/src/adapters/networkhandler/genericNetworkHandler.js index 23bdc1d7a2..bcbcb21259 100644 --- a/src/adapters/networkhandler/genericNetworkHandler.js +++ b/src/adapters/networkhandler/genericNetworkHandler.js @@ -1,7 +1,7 @@ +const { NetworkError } = require('@rudderstack/integrations-lib'); const { isHttpStatusSuccess } = require('../../v0/util/index'); const { proxyRequest, prepareProxyRequest } = require('../network'); const { getDynamicErrorType, processAxiosResponse } = require('../utils/networkUtils'); -const { NetworkError } = require('../../v0/util/errorTypes'); const tags = require('../../v0/util/tags'); /** diff --git a/src/adapters/utils/networkUtils.js b/src/adapters/utils/networkUtils.js index 7f830f5a4b..0dcb9931e9 100644 --- a/src/adapters/utils/networkUtils.js +++ b/src/adapters/utils/networkUtils.js @@ -1,6 +1,7 @@ /* eslint-disable eqeqeq */ const lodash = require('lodash'); const { isEmpty } = require('lodash'); +const { AbortedError } = require('@rudderstack/integrations-lib'); const { isHttpStatusRetryable, isDefinedAndNotNullAndNotEmpty, @@ -9,7 +10,6 @@ const { isHttpStatusSuccess, getErrorStatusCode, } = require('../../v0/util'); -const { AbortedError } = require('../../v0/util/errorTypes'); const tags = require('../../v0/util/tags'); const { HTTP_STATUS_CODES } = require('../../v0/util/constant'); diff --git a/src/cdk/v1/autopilot/transform.js b/src/cdk/v1/autopilot/transform.js index 613b985c0d..b27e50f096 100644 --- a/src/cdk/v1/autopilot/transform.js +++ b/src/cdk/v1/autopilot/transform.js @@ -1,5 +1,5 @@ const { Utils } = require('rudder-transformer-cdk'); -const { InstrumentationError } = require('../../../v0/util/errorTypes'); +const { InstrumentationError } = require('@rudderstack/integrations-lib'); function identifyPostMapper(event, mappedPayload) { const { message } = event; diff --git a/src/cdk/v1/dcm_floodlight/transform.js b/src/cdk/v1/dcm_floodlight/transform.js index d5835d3e2b..bb93333745 100644 --- a/src/cdk/v1/dcm_floodlight/transform.js +++ b/src/cdk/v1/dcm_floodlight/transform.js @@ -5,6 +5,7 @@ const { removeUndefinedAndNullValues, isDefinedAndNotNull, } = require('rudder-transformer-cdk/build/utils'); +const { ConfigurationError, InstrumentationError } = require('@rudderstack/integrations-lib'); const { getIntegrationsObj, isEmpty, @@ -14,7 +15,6 @@ const { } = require('../../../v0/util'); const { GENERIC_TRUE_VALUES, GENERIC_FALSE_VALUES } = require('../../../constants'); const { BASE_URL, BLACKLISTED_CHARACTERS } = require('./config'); -const { ConfigurationError, InstrumentationError } = require('../../../v0/util/errorTypes'); // append properties to endpoint // eg: ${BASE_URL}key1=value1;key2=value2;.... diff --git a/src/cdk/v1/handler.js b/src/cdk/v1/handler.js index a7dfe85a9f..0af0859f49 100644 --- a/src/cdk/v1/handler.js +++ b/src/cdk/v1/handler.js @@ -6,13 +6,13 @@ const path = require('path'); const basePath = path.resolve(__dirname); ConfigFactory.init({ basePath, loggingMode: 'production' }); -const tags = require('../../v0/util/tags'); -const { generateErrorObject } = require('../../v0/util'); const { + InstrumentationError, TransformationError, ConfigurationError, - InstrumentationError, -} = require('../../v0/util/errorTypes'); +} = require('@rudderstack/integrations-lib'); +const tags = require('../../v0/util/tags'); +const { generateErrorObject } = require('../../v0/util'); const defTags = { [tags.TAG_NAMES.IMPLEMENTATION]: tags.IMPLEMENTATIONS.CDK_V1, diff --git a/src/cdk/v2/bindings/default.js b/src/cdk/v2/bindings/default.js index b86b6d2b63..a447370aca 100644 --- a/src/cdk/v2/bindings/default.js +++ b/src/cdk/v2/bindings/default.js @@ -3,7 +3,7 @@ const { InstrumentationError, ConfigurationError, NetworkError, -} = require('../../../v0/util/errorTypes'); +} = require('@rudderstack/integrations-lib'); const { isHttpStatusSuccess } = require('../../../v0/util'); const { getDynamicErrorType } = require('../../../adapters/utils/networkUtils'); const tags = require('../../../v0/util/tags'); diff --git a/src/cdk/v2/destinations/dcm_floodlight/utils.js b/src/cdk/v2/destinations/dcm_floodlight/utils.js index bee45bdea3..07b158efa3 100644 --- a/src/cdk/v2/destinations/dcm_floodlight/utils.js +++ b/src/cdk/v2/destinations/dcm_floodlight/utils.js @@ -1,7 +1,7 @@ const lodash = require('lodash'); +const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { getValueFromPropertiesOrTraits, getHashFromArray } = require('../../../../v0/util'); const { GENERIC_TRUE_VALUES, GENERIC_FALSE_VALUES } = require('../../../../constants'); -const { InstrumentationError } = require('../../../../v0/util/errorTypes'); // valid flag should be provided [1|true] or [0|false] const mapFlagValue = (key, value) => { diff --git a/src/cdk/v2/utils.ts b/src/cdk/v2/utils.ts index 3fb26c07e0..f9a5c66937 100644 --- a/src/cdk/v2/utils.ts +++ b/src/cdk/v2/utils.ts @@ -1,9 +1,9 @@ import path from 'path'; import fs from 'fs/promises'; import { WorkflowExecutionError, WorkflowCreationError } from '@rudderstack/workflow-engine'; +import { PlatformError } from '@rudderstack/integrations-lib'; import logger from '../../logger'; import { generateErrorObject } from '../../v0/util'; -import { PlatformError } from '../../v0/util/errorTypes'; import tags from '../../v0/util/tags'; import { CatchErr } from '../../util/types'; diff --git a/src/helpers/serviceSelector.ts b/src/helpers/serviceSelector.ts index bac1a17c16..891c21313d 100644 --- a/src/helpers/serviceSelector.ts +++ b/src/helpers/serviceSelector.ts @@ -1,3 +1,4 @@ +import { PlatformError } from '@rudderstack/integrations-lib'; import { ProcessorTransformationRequest, RouterTransformationRequestData } from '../types/index'; import { INTEGRATION_SERVICE } from '../routes/utils/constants'; import CDKV1DestinationService from '../services/destination/cdkV1Integration'; @@ -6,7 +7,6 @@ import DestinationService from '../interfaces/DestinationService'; import NativeIntegrationDestinationService from '../services/destination/nativeIntegration'; import SourceService from '../interfaces/SourceService'; import NativeIntegrationSourceService from '../services/source/nativeIntegration'; -import { PlatformError } from '../v0/util/errorTypes'; import ComparatorService from '../services/comparator'; import { FixMe } from '../util/types'; diff --git a/src/services/destination/cdkV1Integration.ts b/src/services/destination/cdkV1Integration.ts index a016665afb..2f655fca9b 100644 --- a/src/services/destination/cdkV1Integration.ts +++ b/src/services/destination/cdkV1Integration.ts @@ -1,6 +1,7 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ import { ConfigFactory, Executor, RudderBaseConfig } from 'rudder-transformer-cdk'; import path from 'path'; +import { TransformationError } from '@rudderstack/integrations-lib'; import IntegrationDestinationService from '../../interfaces/DestinationService'; import { DeliveryResponse, @@ -14,7 +15,6 @@ import { UserDeletionRequest, UserDeletionResponse, } from '../../types/index'; -import { TransformationError } from '../../v0/util/errorTypes'; import DestinationPostTransformationService from './postTransformation'; import tags from '../../v0/util/tags'; import { getErrorInfo } from '../../cdk/v1/handler'; diff --git a/src/services/destination/cdkV2Integration.ts b/src/services/destination/cdkV2Integration.ts index b4c0a15e87..bc5a1126a8 100644 --- a/src/services/destination/cdkV2Integration.ts +++ b/src/services/destination/cdkV2Integration.ts @@ -1,6 +1,7 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ /* eslint-disable class-methods-use-this */ import groupBy from 'lodash/groupBy'; +import { TransformationError } from '@rudderstack/integrations-lib'; import { processCdkV2Workflow } from '../../cdk/v2/handler'; import IntegrationDestinationService from '../../interfaces/DestinationService'; import { @@ -15,7 +16,6 @@ import { UserDeletionRequest, UserDeletionResponse, } from '../../types/index'; -import { TransformationError } from '../../v0/util/errorTypes'; import tags from '../../v0/util/tags'; import DestinationPostTransformationService from './postTransformation'; import stats from '../../util/stats'; diff --git a/src/util/errorNotifier/bugsnag.js b/src/util/errorNotifier/bugsnag.js index a88432f23d..ef01c58730 100644 --- a/src/util/errorNotifier/bugsnag.js +++ b/src/util/errorNotifier/bugsnag.js @@ -5,9 +5,6 @@ const { DataValidationError, } = require('rudder-transformer-cdk/build/error/index'); const stackTraceParser = require('stacktrace-parser'); -const { logger } = require('../../logger'); -const pkg = require('../../../package.json'); - const { BaseError, TransformationError, @@ -23,8 +20,10 @@ const { UnhandledStatusCodeError, UnauthorizedError, NetworkInstrumentationError, - FilteredEventsError, -} = require('../../v0/util/errorTypes'); +} = require('@rudderstack/integrations-lib'); +const { FilteredEventsError } = require('../../v0/util/errorTypes'); +const { logger } = require('../../logger'); +const pkg = require('../../../package.json'); const { BUGSNAG_API_KEY: apiKey, diff --git a/src/util/redis/redisConnector.js b/src/util/redis/redisConnector.js index 749e23ff83..84d578d3b3 100644 --- a/src/util/redis/redisConnector.js +++ b/src/util/redis/redisConnector.js @@ -1,5 +1,5 @@ const Redis = require('ioredis'); -const { RedisError } = require('../../v0/util/errorTypes'); +const { RedisError } = require('@rudderstack/integrations-lib'); const log = require('../../logger'); const stats = require('../stats'); diff --git a/src/v0/destinations/active_campaign/transform.js b/src/v0/destinations/active_campaign/transform.js index 9c6643ebc3..e00808622d 100644 --- a/src/v0/destinations/active_campaign/transform.js +++ b/src/v0/destinations/active_campaign/transform.js @@ -1,6 +1,11 @@ /* eslint-disable array-callback-return */ /* eslint-disable no-empty */ const get = require('get-value'); +const { + InstrumentationError, + TransformationError, + NetworkError, +} = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { CONFIG_CATEGORIES, MAPPING_CONFIG, getHeader } = require('./config'); const { @@ -12,11 +17,6 @@ const { } = require('../../util'); const { errorHandler } = require('./util'); const { httpGET, httpPOST } = require('../../../adapters/network'); -const { - InstrumentationError, - TransformationError, - NetworkError, -} = require('../../util/errorTypes'); const { getDynamicErrorType } = require('../../../adapters/utils/networkUtils'); const tags = require('../../util/tags'); diff --git a/src/v0/destinations/active_campaign/util.js b/src/v0/destinations/active_campaign/util.js index c508618336..6e1f5a3683 100644 --- a/src/v0/destinations/active_campaign/util.js +++ b/src/v0/destinations/active_campaign/util.js @@ -1,8 +1,8 @@ +const { NetworkError } = require('@rudderstack/integrations-lib'); const { nodeSysErrorToStatus, getDynamicErrorType, } = require('../../../adapters/utils/networkUtils'); -const { NetworkError } = require('../../util/errorTypes'); const tags = require('../../util/tags'); const errorHandler = (err, message) => { diff --git a/src/v0/destinations/adj/transform.js b/src/v0/destinations/adj/transform.js index 695654e58a..8248e731c9 100644 --- a/src/v0/destinations/adj/transform.js +++ b/src/v0/destinations/adj/transform.js @@ -1,4 +1,9 @@ const get = require('get-value'); +const { + InstrumentationError, + TransformationError, + ConfigurationError, +} = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { CONFIG_CATEGORIES, MAPPING_CONFIG, baseEndpoint } = require('./config'); const { @@ -11,11 +16,6 @@ const { isAppleFamily, simpleProcessRouterDest, } = require('../../util'); -const { - InstrumentationError, - TransformationError, - ConfigurationError, -} = require('../../util/errorTypes'); const rejectParams = ['revenue', 'currency']; diff --git a/src/v0/destinations/adobe_analytics/transform.js b/src/v0/destinations/adobe_analytics/transform.js index 67bb66310a..a805e379ff 100644 --- a/src/v0/destinations/adobe_analytics/transform.js +++ b/src/v0/destinations/adobe_analytics/transform.js @@ -1,5 +1,10 @@ const jsonxml = require('jsontoxml'); const get = require('get-value'); +const { + InstrumentationError, + TransformationError, + ConfigurationError, +} = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { ECOM_PRODUCT_EVENTS, commonConfig, formatDestinationConfig } = require('./config'); const { @@ -14,11 +19,6 @@ const { removeUndefinedAndNullValues, simpleProcessRouterDest, } = require('../../util'); -const { - InstrumentationError, - TransformationError, - ConfigurationError, -} = require('../../util/errorTypes'); const { handleContextData, diff --git a/src/v0/destinations/adobe_analytics/utils.js b/src/v0/destinations/adobe_analytics/utils.js index 55059884b1..cbd4f51c23 100644 --- a/src/v0/destinations/adobe_analytics/utils.js +++ b/src/v0/destinations/adobe_analytics/utils.js @@ -4,8 +4,8 @@ /* eslint-disable unicorn/no-for-loop */ /* eslint-disable no-restricted-syntax */ const get = require('get-value'); +const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { isDefinedAndNotNull, getValueFromMessage } = require('../../util'); -const { InstrumentationError } = require('../../util/errorTypes'); const SOURCE_KEYS = ['properties', 'traits', 'context.traits', 'context']; @@ -147,13 +147,13 @@ function rudderPropToDestMapWithDelimitter(mapping, delimMapping, message, prefi `${prefix} mapping properties variable is neither a string nor an array`, ); } - + if (typeof val === 'string') { /* following regex is used to find the one or more commas separated/padded by white spaces. Example: val = 'r15,faze90R' , 'r1v, bvp, pol' */ - val = val.replace(/\s*,+\s*/g, delimMapping[key]); - // Above regex is good as for every comma with whitespace padding the no. of steps will increase by 4. + val = val.replace(/\s*,+\s*/g, delimMapping[key]); + // Above regex is good as for every comma with whitespace padding the no. of steps will increase by 4. } else { val = val.join(delimMapping[key]); } diff --git a/src/v0/destinations/af/deleteUsers.js b/src/v0/destinations/af/deleteUsers.js index 7970d02c20..2d68549fcc 100644 --- a/src/v0/destinations/af/deleteUsers.js +++ b/src/v0/destinations/af/deleteUsers.js @@ -1,12 +1,16 @@ /* eslint-disable no-await-in-loop */ /* eslint-disable no-param-reassign */ +const { + ConfigurationError, + InstrumentationError, + NetworkError, +} = require('@rudderstack/integrations-lib'); const { httpPOST } = require('../../../adapters/network'); const { processAxiosResponse, getDynamicErrorType, } = require('../../../adapters/utils/networkUtils'); const { generateUUID, isHttpStatusSuccess } = require('../../util'); -const { ConfigurationError, InstrumentationError, NetworkError } = require('../../util/errorTypes'); const tags = require('../../util/tags'); const { executeCommonValidations } = require('../../util/regulation-api'); diff --git a/src/v0/destinations/af/transform.js b/src/v0/destinations/af/transform.js index 858adce147..4d7ed7e635 100644 --- a/src/v0/destinations/af/transform.js +++ b/src/v0/destinations/af/transform.js @@ -1,6 +1,7 @@ const get = require('get-value'); const set = require('set-value'); +const { InstrumentationError, ConfigurationError } = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { removeUndefinedValues, @@ -15,7 +16,6 @@ const { isDefinedAndNotNullAndNotEmpty, simpleProcessRouterDest, } = require('../../util'); -const { InstrumentationError, ConfigurationError } = require('../../util/errorTypes'); const { Event, ENDPOINT, ConfigCategory, mappingConfig, nameToEventMap } = require('./config'); const { JSON_MIME_TYPE } = require('../../util/constant'); diff --git a/src/v0/destinations/airship/transform.js b/src/v0/destinations/airship/transform.js index a390ec8060..091c9b7f39 100644 --- a/src/v0/destinations/airship/transform.js +++ b/src/v0/destinations/airship/transform.js @@ -1,3 +1,4 @@ +const { InstrumentationError, ConfigurationError } = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { @@ -22,7 +23,6 @@ const { isEmptyObject, simpleProcessRouterDest, } = require('../../util'); -const { InstrumentationError, ConfigurationError } = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); const DEFAULT_ACCEPT_HEADER = 'application/vnd.urbanairship+json; version=3'; diff --git a/src/v0/destinations/algolia/transform.js b/src/v0/destinations/algolia/transform.js index c8b9be28dd..8e9cd57e8b 100644 --- a/src/v0/destinations/algolia/transform.js +++ b/src/v0/destinations/algolia/transform.js @@ -1,10 +1,10 @@ const set = require('set-value'); -const { EventType } = require('../../../constants'); const { InstrumentationError, ConfigurationError, PlatformError, -} = require('../../util/errorTypes'); +} = require('@rudderstack/integrations-lib'); +const { EventType } = require('../../../constants'); const { getValueFromMessage, constructPayload, diff --git a/src/v0/destinations/algolia/util.js b/src/v0/destinations/algolia/util.js index 89048f0e43..eddb4dc16d 100644 --- a/src/v0/destinations/algolia/util.js +++ b/src/v0/destinations/algolia/util.js @@ -1,5 +1,5 @@ +const { InstrumentationError } = require('@rudderstack/integrations-lib'); const logger = require('../../../logger'); -const { InstrumentationError } = require('../../util/errorTypes'); const { EVENT_TYPES } = require('./config'); /** diff --git a/src/v0/destinations/am/deleteUsers.js b/src/v0/destinations/am/deleteUsers.js index c0402284b4..578c58fb5c 100644 --- a/src/v0/destinations/am/deleteUsers.js +++ b/src/v0/destinations/am/deleteUsers.js @@ -1,4 +1,5 @@ const btoa = require('btoa'); +const { ConfigurationError, NetworkError } = require('@rudderstack/integrations-lib'); const { httpPOST } = require('../../../adapters/network'); const tags = require('../../util/tags'); const { @@ -6,7 +7,6 @@ const { getDynamicErrorType, } = require('../../../adapters/utils/networkUtils'); const { isHttpStatusSuccess } = require('../../util'); -const { ConfigurationError, NetworkError } = require('../../util/errorTypes'); const { executeCommonValidations } = require('../../util/regulation-api'); const { DELETE_MAX_BATCH_SIZE } = require('./config'); const { getUserIdBatches } = require('../../util/deleteUserUtils'); diff --git a/src/v0/destinations/am/transform.js b/src/v0/destinations/am/transform.js index 04a1c5a107..d7101982a7 100644 --- a/src/v0/destinations/am/transform.js +++ b/src/v0/destinations/am/transform.js @@ -4,6 +4,7 @@ const cloneDeep = require('lodash/cloneDeep'); const get = require('get-value'); const set = require('set-value'); +const { InstrumentationError, ConfigurationError } = require('@rudderstack/integrations-lib'); const { EventType, SpecedTraits, @@ -44,7 +45,7 @@ const tags = require('../../util/tags'); const AMUtils = require('./utils'); const logger = require('../../../logger'); -const { InstrumentationError, ConfigurationError } = require('../../util/errorTypes'); + const { JSON_MIME_TYPE } = require('../../util/constant'); const EVENTS_KEY_PATH = 'body.JSON.events'; diff --git a/src/v0/destinations/appcues/transform.js b/src/v0/destinations/appcues/transform.js index 095256cc4e..57a54bce33 100644 --- a/src/v0/destinations/appcues/transform.js +++ b/src/v0/destinations/appcues/transform.js @@ -1,4 +1,5 @@ /* eslint-disable no-underscore-dangle */ +const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { @@ -9,7 +10,6 @@ const { simpleProcessRouterDest, } = require('../../util'); const { JSON_MIME_TYPE } = require('../../util/constant'); -const { InstrumentationError } = require('../../util/errorTypes'); const { ConfigCategory, mappingConfig, getEndpoint } = require('./config'); diff --git a/src/v0/destinations/attentive_tag/transform.js b/src/v0/destinations/attentive_tag/transform.js index 231beec143..fa05eb6c21 100644 --- a/src/v0/destinations/attentive_tag/transform.js +++ b/src/v0/destinations/attentive_tag/transform.js @@ -1,4 +1,5 @@ const get = require('get-value'); +const { InstrumentationError, ConfigurationError } = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { ConfigCategory, mappingConfig, BASE_URL } = require('./config'); const { @@ -18,7 +19,6 @@ const { getPropertiesKeyValidation, validateTimestamp, } = require('./util'); -const { InstrumentationError, ConfigurationError } = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); const responseBuilder = (payload, apiKey, endpoint) => { diff --git a/src/v0/destinations/attentive_tag/util.js b/src/v0/destinations/attentive_tag/util.js index 890f73cdc9..c96d03028f 100644 --- a/src/v0/destinations/attentive_tag/util.js +++ b/src/v0/destinations/attentive_tag/util.js @@ -1,13 +1,13 @@ /* eslint-disable no-restricted-syntax */ const get = require('get-value'); const moment = require('moment'); +const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { constructPayload, isDefinedAndNotNull, getDestinationExternalID, isDefinedAndNotNullAndNotEmpty, } = require('../../util'); -const { InstrumentationError } = require('../../util/errorTypes'); const { mappingConfig, ConfigCategory } = require('./config'); /** diff --git a/src/v0/destinations/attribution/transform.js b/src/v0/destinations/attribution/transform.js index 712f3e5e5d..fa42a6238a 100644 --- a/src/v0/destinations/attribution/transform.js +++ b/src/v0/destinations/attribution/transform.js @@ -1,3 +1,4 @@ +const { InstrumentationError, ConfigurationError } = require('@rudderstack/integrations-lib'); const { batchEndpoint } = require('./config'); const { defaultPostRequestConfig, @@ -5,7 +6,6 @@ const { removeUndefinedAndNullValues, getFieldValueFromMessage, } = require('../../util'); -const { InstrumentationError, ConfigurationError } = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); function responseBuilderSimple(payload, attributionConfig) { diff --git a/src/v0/destinations/autopilot/transform.js b/src/v0/destinations/autopilot/transform.js index e0fe9aa400..e4a2c408af 100644 --- a/src/v0/destinations/autopilot/transform.js +++ b/src/v0/destinations/autopilot/transform.js @@ -1,3 +1,4 @@ +const { InstrumentationError, TransformationError } = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { CONFIG_CATEGORIES, MAPPING_CONFIG } = require('./config'); const { @@ -9,7 +10,6 @@ const { simpleProcessRouterDest, } = require('../../util'); -const { InstrumentationError, TransformationError } = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); const identifyFields = [ diff --git a/src/v0/destinations/awin/transform.js b/src/v0/destinations/awin/transform.js index f6070fccd5..49a115c1ff 100644 --- a/src/v0/destinations/awin/transform.js +++ b/src/v0/destinations/awin/transform.js @@ -1,8 +1,8 @@ +const { InstrumentationError, ConfigurationError } = require('@rudderstack/integrations-lib'); const { BASE_URL, ConfigCategory, mappingConfig } = require('./config'); const { defaultRequestConfig, constructPayload, simpleProcessRouterDest } = require('../../util'); const { getParams } = require('./utils'); -const { InstrumentationError, ConfigurationError } = require('../../util/errorTypes'); const responseBuilder = (message, { Config }) => { const { advertiserId, eventsToTrack } = Config; diff --git a/src/v0/destinations/azure_event_hub/transform.js b/src/v0/destinations/azure_event_hub/transform.js index 6200e32ce7..98180b55b4 100644 --- a/src/v0/destinations/azure_event_hub/transform.js +++ b/src/v0/destinations/azure_event_hub/transform.js @@ -1,6 +1,5 @@ const cloneDeep = require('lodash/cloneDeep'); const { getIntegrationsObj } = require('../../util'); -// const { InstrumentationError } = require("../../util/errorTypes"); function process(event) { const { message, destination } = event; diff --git a/src/v0/destinations/blueshift/transform.js b/src/v0/destinations/blueshift/transform.js index b79af327d2..cdfbfe32e1 100644 --- a/src/v0/destinations/blueshift/transform.js +++ b/src/v0/destinations/blueshift/transform.js @@ -1,3 +1,8 @@ +const { + TransformationError, + InstrumentationError, + ConfigurationError, +} = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { constructPayload, @@ -10,11 +15,6 @@ const { simpleProcessRouterDest, } = require('../../util'); const { JSON_MIME_TYPE } = require('../../util/constant'); -const { - TransformationError, - InstrumentationError, - ConfigurationError, -} = require('../../util/errorTypes'); const { MAPPING_CONFIG, diff --git a/src/v0/destinations/bqstream/transform.js b/src/v0/destinations/bqstream/transform.js index 55679b08a8..598a97946d 100644 --- a/src/v0/destinations/bqstream/transform.js +++ b/src/v0/destinations/bqstream/transform.js @@ -1,5 +1,6 @@ /* eslint-disable no-console */ const lodash = require('lodash'); +const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { defaultBatchRequestConfig, @@ -9,7 +10,6 @@ const { groupEventsByType, } = require('../../util'); const { MAX_ROWS_PER_REQUEST, DESTINATION } = require('./config'); -const { InstrumentationError } = require('../../util/errorTypes'); const { getRearrangedEvents } = require('./util'); const getInsertIdColValue = (properties, insertIdCol) => { diff --git a/src/v0/destinations/branch/transform.js b/src/v0/destinations/branch/transform.js index 0d47fbd791..23dcd6c8db 100644 --- a/src/v0/destinations/branch/transform.js +++ b/src/v0/destinations/branch/transform.js @@ -1,4 +1,5 @@ const get = require('get-value'); +const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { endpoints } = require('./config'); const { categoriesList } = require('./data/eventMapping'); @@ -11,7 +12,6 @@ const { isAppleFamily, simpleProcessRouterDest, } = require('../../util'); -const { InstrumentationError } = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); function responseBuilder(payload, message, destination, category) { diff --git a/src/v0/destinations/braze/deleteUsers.js b/src/v0/destinations/braze/deleteUsers.js index 799aa3f9b4..b94d901138 100644 --- a/src/v0/destinations/braze/deleteUsers.js +++ b/src/v0/destinations/braze/deleteUsers.js @@ -1,3 +1,4 @@ +const { NetworkError, ConfigurationError } = require('@rudderstack/integrations-lib'); const { httpPOST } = require('../../../adapters/network'); const { processAxiosResponse, @@ -8,7 +9,6 @@ const { isHttpStatusSuccess } = require('../../util'); const { executeCommonValidations } = require('../../util/regulation-api'); const { DEL_MAX_BATCH_SIZE } = require('./config'); const { getUserIdBatches } = require('../../util/deleteUserUtils'); -const { NetworkError, ConfigurationError } = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); const userDeletionHandler = async (userAttributes, config) => { diff --git a/src/v0/destinations/braze/networkHandler.js b/src/v0/destinations/braze/networkHandler.js index a141607fe9..c6cf7222ea 100644 --- a/src/v0/destinations/braze/networkHandler.js +++ b/src/v0/destinations/braze/networkHandler.js @@ -1,4 +1,5 @@ /* eslint-disable no-unused-vars */ +const { NetworkError } = require('@rudderstack/integrations-lib'); const { isHttpStatusSuccess } = require('../../util/index'); const { proxyRequest, prepareProxyRequest } = require('../../../adapters/network'); const { @@ -6,7 +7,6 @@ const { processAxiosResponse, } = require('../../../adapters/utils/networkUtils'); const { DESTINATION } = require('./config'); -const { NetworkError } = require('../../util/errorTypes'); const tags = require('../../util/tags'); const stats = require('../../../util/stats'); diff --git a/src/v0/destinations/braze/transform.js b/src/v0/destinations/braze/transform.js index 26fd86b3dd..b939e1f414 100644 --- a/src/v0/destinations/braze/transform.js +++ b/src/v0/destinations/braze/transform.js @@ -1,6 +1,8 @@ /* eslint-disable no-nested-ternary,no-param-reassign */ const lodash = require('lodash'); const get = require('get-value'); +const { InstrumentationError, NetworkError } = require('@rudderstack/integrations-lib'); +const { FilteredEventsError } = require('../../util/errorTypes'); const { BrazeDedupUtility, CustomAttributeOperationUtil, @@ -24,11 +26,6 @@ const { simpleProcessRouterDest, isNewStatusCodesAccepted, } = require('../../util'); -const { - InstrumentationError, - NetworkError, - FilteredEventsError, -} = require('../../util/errorTypes'); const { ConfigCategory, mappingConfig, diff --git a/src/v0/destinations/braze/util.js b/src/v0/destinations/braze/util.js index b3e60f2c6a..9b5d57d6bc 100644 --- a/src/v0/destinations/braze/util.js +++ b/src/v0/destinations/braze/util.js @@ -25,7 +25,7 @@ const { const { JSON_MIME_TYPE, HTTP_STATUS_CODES } = require('../../util/constant'); const { isObject } = require('../../util'); const { removeUndefinedValues, getIntegrationsObj } = require('../../util'); -const { InstrumentationError } = require('../../util/errorTypes'); +const { InstrumentationError } = require('@rudderstack/integrations-lib'); const getEndpointFromConfig = (destination) => { // Init -- mostly for test cases diff --git a/src/v0/destinations/campaign_manager/networkHandler.js b/src/v0/destinations/campaign_manager/networkHandler.js index cd98de253e..0683b0c55c 100644 --- a/src/v0/destinations/campaign_manager/networkHandler.js +++ b/src/v0/destinations/campaign_manager/networkHandler.js @@ -1,3 +1,4 @@ +const { AbortedError, RetryableError, NetworkError } = require('@rudderstack/integrations-lib'); const { prepareProxyRequest, proxyRequest } = require('../../../adapters/network'); const { isHttpStatusSuccess, getAuthErrCategoryFromStCode } = require('../../util/index'); @@ -5,7 +6,6 @@ const { processAxiosResponse, getDynamicErrorType, } = require('../../../adapters/utils/networkUtils'); -const { AbortedError, RetryableError, NetworkError } = require('../../util/errorTypes'); const tags = require('../../util/tags'); function checkIfFailuresAreRetryable(response) { diff --git a/src/v0/destinations/campaign_manager/transform.js b/src/v0/destinations/campaign_manager/transform.js index af097e5b4c..7b6d6cba4c 100644 --- a/src/v0/destinations/campaign_manager/transform.js +++ b/src/v0/destinations/campaign_manager/transform.js @@ -1,3 +1,4 @@ +const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { @@ -19,8 +20,6 @@ const { } = require('./config'); const { convertToMicroseconds } = require('./util'); - -const { InstrumentationError } = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); function isEmptyObject(obj) { diff --git a/src/v0/destinations/candu/transform.js b/src/v0/destinations/candu/transform.js index 659af36540..d114998484 100644 --- a/src/v0/destinations/candu/transform.js +++ b/src/v0/destinations/candu/transform.js @@ -1,3 +1,4 @@ +const { InstrumentationError, ConfigurationError } = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { defaultRequestConfig, @@ -6,7 +7,6 @@ const { simpleProcessRouterDest, } = require('../../util'); const { JSON_MIME_TYPE } = require('../../util/constant'); -const { InstrumentationError, ConfigurationError } = require('../../util/errorTypes'); const { endpoint, identifyDataMapping, trackDataMapping } = require('./config'); const responseBuilder = (body, { Config }) => { diff --git a/src/v0/destinations/canny/transform.js b/src/v0/destinations/canny/transform.js index d837a8ddd3..f4364e1fb7 100644 --- a/src/v0/destinations/canny/transform.js +++ b/src/v0/destinations/canny/transform.js @@ -1,3 +1,4 @@ +const { InstrumentationError, ConfigurationError } = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { ConfigCategory, mappingConfig, BASE_URL } = require('./config'); const { @@ -14,7 +15,6 @@ const { validateCreatePostFields, validateEventMapping, } = require('./util'); -const { InstrumentationError, ConfigurationError } = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); const responseBuilder = (responseConfgs) => { diff --git a/src/v0/destinations/canny/util.js b/src/v0/destinations/canny/util.js index 002d9aa69f..59644bcd6b 100644 --- a/src/v0/destinations/canny/util.js +++ b/src/v0/destinations/canny/util.js @@ -1,8 +1,8 @@ const qs = require('qs'); +const { InstrumentationError, NetworkError } = require('@rudderstack/integrations-lib'); const { httpPOST } = require('../../../adapters/network'); const { getDynamicErrorType } = require('../../../adapters/utils/networkUtils'); const { getDestinationExternalID } = require('../../util'); -const { InstrumentationError, NetworkError } = require('../../util/errorTypes'); const tags = require('../../util/tags'); const logger = require('../../../logger'); const { JSON_MIME_TYPE } = require('../../util/constant'); diff --git a/src/v0/destinations/clevertap/deleteUsers.js b/src/v0/destinations/clevertap/deleteUsers.js index 826c6c6939..3c07a63d93 100644 --- a/src/v0/destinations/clevertap/deleteUsers.js +++ b/src/v0/destinations/clevertap/deleteUsers.js @@ -1,3 +1,4 @@ +const { NetworkError, ConfigurationError } = require('@rudderstack/integrations-lib'); const { httpPOST } = require('../../../adapters/network'); const { getEndpoint, DEL_MAX_BATCH_SIZE } = require('./config'); const { @@ -6,7 +7,6 @@ const { } = require('../../../adapters/utils/networkUtils'); const { isHttpStatusSuccess } = require('../../util'); const { executeCommonValidations } = require('../../util/regulation-api'); -const { NetworkError, ConfigurationError } = require('../../util/errorTypes'); const tags = require('../../util/tags'); const { getUserIdBatches } = require('../../util/deleteUserUtils'); const { JSON_MIME_TYPE } = require('../../util/constant'); diff --git a/src/v0/destinations/clevertap/networkHandler.js b/src/v0/destinations/clevertap/networkHandler.js index 35c972e502..e17afb57d1 100644 --- a/src/v0/destinations/clevertap/networkHandler.js +++ b/src/v0/destinations/clevertap/networkHandler.js @@ -1,10 +1,10 @@ +const { NetworkError, AbortedError } = require('@rudderstack/integrations-lib'); const { isHttpStatusSuccess } = require('../../util/index'); const { proxyRequest, prepareProxyRequest } = require('../../../adapters/network'); const { processAxiosResponse, getDynamicErrorType, } = require('../../../adapters/utils/networkUtils'); -const { NetworkError, AbortedError } = require('../../util/errorTypes'); const tags = require('../../util/tags'); const responseHandler = (destinationResponse) => { diff --git a/src/v0/destinations/clevertap/transform.js b/src/v0/destinations/clevertap/transform.js index 5c1e28c086..efcd101668 100644 --- a/src/v0/destinations/clevertap/transform.js +++ b/src/v0/destinations/clevertap/transform.js @@ -1,6 +1,7 @@ /* eslint-disable no-param-reassign */ /* eslint-disable no-nested-ternary */ const get = require('get-value'); +const { InstrumentationError, TransformationError } = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { getEndpoint, @@ -25,7 +26,6 @@ const { } = require('../../util'); const { generateClevertapBatchedPayload } = require('./utils'); -const { InstrumentationError, TransformationError } = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); const TIMESTAMP_KEY_PATH = 'context.traits.ts'; diff --git a/src/v0/destinations/clickup/transform.js b/src/v0/destinations/clickup/transform.js index d93e53b349..0637d65bd4 100644 --- a/src/v0/destinations/clickup/transform.js +++ b/src/v0/destinations/clickup/transform.js @@ -1,3 +1,4 @@ +const { TransformationError, InstrumentationError } = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { defaultRequestConfig, @@ -14,7 +15,6 @@ const { checkEventIfUIMapped, } = require('./util'); const { CONFIG_CATEGORIES, MAPPING_CONFIG, createTaskEndPoint } = require('./config'); -const { TransformationError, InstrumentationError } = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); const responseBuilder = async (payload, listId, apiToken) => { diff --git a/src/v0/destinations/clickup/util.js b/src/v0/destinations/clickup/util.js index 7b17f83bb6..148fe1bd07 100644 --- a/src/v0/destinations/clickup/util.js +++ b/src/v0/destinations/clickup/util.js @@ -1,3 +1,4 @@ +const { NetworkError, InstrumentationError } = require('@rudderstack/integrations-lib'); const { httpGET } = require('../../../adapters/network'); const { processAxiosResponse, @@ -9,7 +10,6 @@ const { formatTimeStamp, } = require('../../util'); const { getCustomFieldsEndPoint } = require('./config'); -const { NetworkError, InstrumentationError } = require('../../util/errorTypes'); const tags = require('../../util/tags'); const { JSON_MIME_TYPE } = require('../../util/constant'); diff --git a/src/v0/destinations/confluent_cloud/transform.js b/src/v0/destinations/confluent_cloud/transform.js index e8f0f4d2e2..b33abc90cf 100644 --- a/src/v0/destinations/confluent_cloud/transform.js +++ b/src/v0/destinations/confluent_cloud/transform.js @@ -1,6 +1,5 @@ const cloneDeep = require('lodash/cloneDeep'); const { getIntegrationsObj } = require('../../util'); -// const { InstrumentationError } = require("../../util/errorTypes"); function process(event) { const { message, destination } = event; diff --git a/src/v0/destinations/courier/transform.js b/src/v0/destinations/courier/transform.js index 7d52b503d9..d5e25434ec 100644 --- a/src/v0/destinations/courier/transform.js +++ b/src/v0/destinations/courier/transform.js @@ -1,3 +1,8 @@ +const { + TransformationError, + InstrumentationError, + ConfigurationError, +} = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { defaultRequestConfig, @@ -6,11 +11,6 @@ const { simpleProcessRouterDest, } = require('../../util'); const { JSON_MIME_TYPE } = require('../../util/constant'); -const { - TransformationError, - InstrumentationError, - ConfigurationError, -} = require('../../util/errorTypes'); const { API_URL } = require('./config'); const responseBuilder = (payload, endpoint, destination) => { diff --git a/src/v0/destinations/criteo_audience/networkHandler.js b/src/v0/destinations/criteo_audience/networkHandler.js index f4369cdc9e..18bd9a93a0 100644 --- a/src/v0/destinations/criteo_audience/networkHandler.js +++ b/src/v0/destinations/criteo_audience/networkHandler.js @@ -1,3 +1,10 @@ +const { + NetworkError, + ThrottledError, + NetworkInstrumentationError, + AbortedError, + RetryableError, +} = require('@rudderstack/integrations-lib'); const { prepareProxyRequest, proxyRequest } = require('../../../adapters/network'); const { isHttpStatusSuccess } = require('../../util/index'); const { REFRESH_TOKEN } = require('../../../adapters/networkhandler/authConstants'); @@ -6,13 +13,6 @@ const { getDynamicErrorType, processAxiosResponse, } = require('../../../adapters/utils/networkUtils'); -const { - NetworkError, - ThrottledError, - NetworkInstrumentationError, - AbortedError, - RetryableError, -} = require('../../util/errorTypes'); // https://developers.criteo.com/marketing-solutions/v2021.01/docs/how-to-handle-api-errors#:~:text=the%20response%20body.-,401,-Authentication%20error // Following fucntion tells us if there is a particular error code in the response. diff --git a/src/v0/destinations/criteo_audience/transform.js b/src/v0/destinations/criteo_audience/transform.js index 7ddbdbef20..25e53cc305 100644 --- a/src/v0/destinations/criteo_audience/transform.js +++ b/src/v0/destinations/criteo_audience/transform.js @@ -1,4 +1,5 @@ const get = require('get-value'); +const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { BASE_ENDPOINT, operation } = require('./config'); const { defaultRequestConfig, @@ -9,7 +10,6 @@ const { getEventType, getDestinationExternalIDInfoForRetl, } = require('../../util'); -const { InstrumentationError } = require('../../util/errorTypes'); const { MappedToDestinationKey } = require('../../../constants'); const { preparePayload } = require('./util'); diff --git a/src/v0/destinations/criteo_audience/util.js b/src/v0/destinations/criteo_audience/util.js index a7541f7911..d9d37bc331 100644 --- a/src/v0/destinations/criteo_audience/util.js +++ b/src/v0/destinations/criteo_audience/util.js @@ -1,6 +1,6 @@ const lodash = require('lodash'); +const { ConfigurationError, InstrumentationError } = require('@rudderstack/integrations-lib'); const { isDefinedAndNotNullAndNotEmpty } = require('../../util'); -const { ConfigurationError, InstrumentationError } = require('../../util/errorTypes'); const { MAX_IDENTIFIERS } = require('./config'); const populateIdentifiers = (audienceList, audienceType) => { diff --git a/src/v0/destinations/custify/deleteUsers.js b/src/v0/destinations/custify/deleteUsers.js index e90abe7abb..147fcc602c 100644 --- a/src/v0/destinations/custify/deleteUsers.js +++ b/src/v0/destinations/custify/deleteUsers.js @@ -1,9 +1,13 @@ +const { + ConfigurationError, + InstrumentationError, + NetworkError, +} = require('@rudderstack/integrations-lib'); const { httpDELETE } = require('../../../adapters/network'); const { processAxiosResponse, getDynamicErrorType, } = require('../../../adapters/utils/networkUtils'); -const { ConfigurationError, InstrumentationError, NetworkError } = require('../../util/errorTypes'); const { executeCommonValidations } = require('../../util/regulation-api'); const tags = require('../../util/tags'); diff --git a/src/v0/destinations/custify/transform.js b/src/v0/destinations/custify/transform.js index fd81511982..6b08be1c56 100644 --- a/src/v0/destinations/custify/transform.js +++ b/src/v0/destinations/custify/transform.js @@ -1,4 +1,5 @@ const get = require('get-value'); +const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { EventType, MappedToDestinationKey } = require('../../../constants'); const { ConfigCategory } = require('./config'); const { @@ -9,7 +10,6 @@ const { simpleProcessRouterDest, } = require('../../util'); const { processIdentify, processTrack, processGroup } = require('./util'); -const { InstrumentationError } = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); /** diff --git a/src/v0/destinations/custify/util.js b/src/v0/destinations/custify/util.js index d943b5c8bf..ae6f21fe20 100644 --- a/src/v0/destinations/custify/util.js +++ b/src/v0/destinations/custify/util.js @@ -1,4 +1,5 @@ const get = require('get-value'); +const { InstrumentationError, NetworkError } = require('@rudderstack/integrations-lib'); const { ConfigCategory, MappingConfig, @@ -16,7 +17,6 @@ const { constructPayload, isHttpStatusSuccess, } = require('../../util'); -const { InstrumentationError, NetworkError } = require('../../util/errorTypes'); const tags = require('../../util/tags'); const { JSON_MIME_TYPE } = require('../../util/constant'); diff --git a/src/v0/destinations/customerio/transform.js b/src/v0/destinations/customerio/transform.js index 984fb7e67f..be4486717c 100644 --- a/src/v0/destinations/customerio/transform.js +++ b/src/v0/destinations/customerio/transform.js @@ -1,6 +1,7 @@ const get = require('get-value'); const btoa = require('btoa'); +const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { EventType, MappedToDestinationKey } = require('../../../constants'); const { @@ -24,7 +25,6 @@ const { defaultResponseBuilder, validateConfigFields, } = require('./util'); -const { InstrumentationError } = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); function responseBuilder(message, evType, evName, destination, messageType) { diff --git a/src/v0/destinations/customerio/util.js b/src/v0/destinations/customerio/util.js index 6b4dbc0e11..ef983748a5 100644 --- a/src/v0/destinations/customerio/util.js +++ b/src/v0/destinations/customerio/util.js @@ -1,6 +1,7 @@ const get = require('get-value'); const set = require('set-value'); const truncate = require('truncate-utf8-bytes'); +const { InstrumentationError, ConfigurationError } = require('@rudderstack/integrations-lib'); const { MAX_BATCH_SIZE, configFieldsToCheck } = require('./config'); const { constructPayload, @@ -28,8 +29,6 @@ const { DEVICE_REGISTER_ENDPOINT, } = require('./config'); -const { InstrumentationError, ConfigurationError } = require('../../util/errorTypes'); - const deviceRelatedEventNames = [ 'Application Installed', 'Application Opened', diff --git a/src/v0/destinations/delighted/transform.js b/src/v0/destinations/delighted/transform.js index f5a2afdcaf..cf80dc878d 100644 --- a/src/v0/destinations/delighted/transform.js +++ b/src/v0/destinations/delighted/transform.js @@ -1,3 +1,8 @@ +const { + InstrumentationError, + ConfigurationError, + NetworkInstrumentationError, +} = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { getFieldValueFromMessage, @@ -20,11 +25,6 @@ const { userValidity, } = require('./util'); const { ENDPOINT, TRACKING_EXCLUSION_FIELDS, identifyMapping } = require('./config'); -const { - InstrumentationError, - ConfigurationError, - NetworkInstrumentationError, -} = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); const identifyResponseBuilder = (message, { Config }) => { diff --git a/src/v0/destinations/delighted/util.js b/src/v0/destinations/delighted/util.js index 3cf26a3697..2c92685fd7 100644 --- a/src/v0/destinations/delighted/util.js +++ b/src/v0/destinations/delighted/util.js @@ -1,11 +1,11 @@ -const myAxios = require('../../../util/myAxios'); -const { getDynamicErrorType } = require('../../../adapters/utils/networkUtils'); -const { getValueFromMessage } = require('../../util'); const { NetworkInstrumentationError, InstrumentationError, NetworkError, -} = require('../../util/errorTypes'); +} = require('@rudderstack/integrations-lib'); +const myAxios = require('../../../util/myAxios'); +const { getDynamicErrorType } = require('../../../adapters/utils/networkUtils'); +const { getValueFromMessage } = require('../../util'); const { ENDPOINT } = require('./config'); const tags = require('../../util/tags'); const { JSON_MIME_TYPE } = require('../../util/constant'); diff --git a/src/v0/destinations/discord/transform.js b/src/v0/destinations/discord/transform.js index 4eb2f79235..714ee4f52b 100644 --- a/src/v0/destinations/discord/transform.js +++ b/src/v0/destinations/discord/transform.js @@ -1,6 +1,7 @@ /* eslint-disable no-nested-ternary */ /* eslint-disable no-prototype-builtins */ const Handlebars = require('handlebars'); +const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { @@ -9,7 +10,6 @@ const { getFieldValueFromMessage, simpleProcessRouterDest, } = require('../../util'); -const { InstrumentationError } = require('../../util/errorTypes'); const { stringifyJSON, getName, diff --git a/src/v0/destinations/drip/transform.js b/src/v0/destinations/drip/transform.js index 9abe3e3f77..4ccba076d0 100644 --- a/src/v0/destinations/drip/transform.js +++ b/src/v0/destinations/drip/transform.js @@ -1,3 +1,8 @@ +const { + InstrumentationError, + ConfigurationError, + NetworkInstrumentationError, +} = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { getDestinationExternalID, @@ -31,11 +36,6 @@ const { createUpdateUser, createList, } = require('./util'); -const { - InstrumentationError, - ConfigurationError, - NetworkInstrumentationError, -} = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); const identifyResponseBuilder = async (message, { Config }) => { diff --git a/src/v0/destinations/drip/util.js b/src/v0/destinations/drip/util.js index dbb59fc6af..a502cf0d20 100644 --- a/src/v0/destinations/drip/util.js +++ b/src/v0/destinations/drip/util.js @@ -1,8 +1,8 @@ +const { NetworkError, AbortedError } = require('@rudderstack/integrations-lib'); const myAxios = require('../../../util/myAxios'); const { getDynamicErrorType } = require('../../../adapters/utils/networkUtils'); const logger = require('../../../logger'); const { constructPayload, isDefinedAndNotNull } = require('../../util'); -const { NetworkError, AbortedError } = require('../../util/errorTypes'); const { ENDPOINT, productMapping } = require('./config'); const tags = require('../../util/tags'); const { JSON_MIME_TYPE } = require('../../util/constant'); diff --git a/src/v0/destinations/engage/deleteUsers.js b/src/v0/destinations/engage/deleteUsers.js index 940529ea0c..a3c3055c7d 100644 --- a/src/v0/destinations/engage/deleteUsers.js +++ b/src/v0/destinations/engage/deleteUsers.js @@ -1,3 +1,4 @@ +const { ConfigurationError, NetworkError } = require('@rudderstack/integrations-lib'); const { httpDELETE } = require('../../../adapters/network'); const { processAxiosResponse, @@ -5,7 +6,6 @@ const { } = require('../../../adapters/utils/networkUtils'); const { isHttpStatusSuccess } = require('../../util'); const tags = require('../../util/tags'); -const { ConfigurationError, NetworkError } = require('../../util/errorTypes'); const { executeCommonValidations } = require('../../util/regulation-api'); const { JSON_MIME_TYPE } = require('../../util/constant'); diff --git a/src/v0/destinations/engage/transform.js b/src/v0/destinations/engage/transform.js index 98b8bb2bb9..f5daafb98c 100644 --- a/src/v0/destinations/engage/transform.js +++ b/src/v0/destinations/engage/transform.js @@ -1,4 +1,5 @@ const { set } = require('lodash'); +const { TransformationError, InstrumentationError } = require('@rudderstack/integrations-lib'); const { defaultRequestConfig, constructPayload, @@ -14,7 +15,6 @@ const { getDestinationExternalID } = require('../../util'); const { EventType } = require('../../../constants'); const { mappingConfig, ConfigCategories } = require('./config'); const { refinePayload, generatePageName, getLists } = require('./utils'); -const { TransformationError, InstrumentationError } = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); const UID_ERROR_MSG = 'Neither externalId nor userId is available'; diff --git a/src/v0/destinations/eventbridge/transform.js b/src/v0/destinations/eventbridge/transform.js index 71c7731074..53c74d0f88 100644 --- a/src/v0/destinations/eventbridge/transform.js +++ b/src/v0/destinations/eventbridge/transform.js @@ -1,5 +1,5 @@ +const { ConfigurationError } = require('@rudderstack/integrations-lib'); const { removeUndefinedAndNullValues, simpleProcessRouterDest } = require('../../util'); -const { ConfigurationError } = require('../../util/errorTypes'); function getResouceList(config) { let resource; diff --git a/src/v0/destinations/facebook_offline_conversions/transform.js b/src/v0/destinations/facebook_offline_conversions/transform.js index e30bc2fa9a..cc95270fcc 100644 --- a/src/v0/destinations/facebook_offline_conversions/transform.js +++ b/src/v0/destinations/facebook_offline_conversions/transform.js @@ -1,3 +1,4 @@ +const { InstrumentationError, TransformationError } = require('@rudderstack/integrations-lib'); const { defaultRequestConfig, simpleProcessRouterDest, @@ -7,7 +8,6 @@ const { const { offlineConversionResponseBuilder, prepareUrls } = require('./utils'); const { EventType } = require('../../../constants'); -const { InstrumentationError, TransformationError } = require('../../util/errorTypes'); const responseBuilder = (endpoint) => { if (endpoint) { diff --git a/src/v0/destinations/facebook_offline_conversions/utils.js b/src/v0/destinations/facebook_offline_conversions/utils.js index 819bf8056d..c48de4e0b9 100644 --- a/src/v0/destinations/facebook_offline_conversions/utils.js +++ b/src/v0/destinations/facebook_offline_conversions/utils.js @@ -1,5 +1,6 @@ const sha256 = require('sha256'); const get = require('get-value'); +const { ConfigurationError } = require('@rudderstack/integrations-lib'); const { isObject, formatTimeStamp, @@ -22,7 +23,6 @@ const { eventToStandardMapping, MATCH_KEY_FIELD_TYPE_DICTIONARY, } = require('./config'); -const { ConfigurationError } = require('../../util/errorTypes'); /** * @param {*} message diff --git a/src/v0/destinations/facebook_pixel/transform.js b/src/v0/destinations/facebook_pixel/transform.js index 02c416cfde..7c55b61302 100644 --- a/src/v0/destinations/facebook_pixel/transform.js +++ b/src/v0/destinations/facebook_pixel/transform.js @@ -1,6 +1,7 @@ /* eslint-disable no-param-reassign */ const get = require('get-value'); const moment = require('moment'); +const { InstrumentationError, ConfigurationError } = require('@rudderstack/integrations-lib'); const stats = require('../../../util/stats'); const { CONFIG_CATEGORIES, @@ -36,8 +37,6 @@ const { formingFinalResponse, } = require('../../util/facebookUtils'); -const { InstrumentationError, ConfigurationError } = require('../../util/errorTypes'); - const responseBuilderSimple = (message, category, destination) => { const { Config, ID } = destination; const { pixelId, accessToken } = Config; diff --git a/src/v0/destinations/facebook_pixel/utils.js b/src/v0/destinations/facebook_pixel/utils.js index d642c446fd..1901edf306 100644 --- a/src/v0/destinations/facebook_pixel/utils.js +++ b/src/v0/destinations/facebook_pixel/utils.js @@ -1,7 +1,7 @@ +const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { isObject } = require('../../util'); const { ACTION_SOURCES_VALUES, CONFIG_CATEGORIES, OTHER_STANDARD_EVENTS } = require('./config'); const { getContentType, getContentCategory } = require('../../util/facebookUtils'); -const { InstrumentationError } = require('../../util/errorTypes'); /** format revenue according to fb standards with max two decimal places. * @param revenue diff --git a/src/v0/destinations/factorsai/transform.js b/src/v0/destinations/factorsai/transform.js index dd2dad42fc..9824b73bbf 100644 --- a/src/v0/destinations/factorsai/transform.js +++ b/src/v0/destinations/factorsai/transform.js @@ -1,3 +1,4 @@ +const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { @@ -9,7 +10,6 @@ const { simpleProcessRouterDest, } = require('../../util'); const { JSON_MIME_TYPE } = require('../../util/constant'); -const { InstrumentationError } = require('../../util/errorTypes'); const { ConfigCategories, mappingConfig, BASE_URL } = require('./config'); diff --git a/src/v0/destinations/fb/transform.js b/src/v0/destinations/fb/transform.js index 756c74ba83..c0d78a2b3f 100644 --- a/src/v0/destinations/fb/transform.js +++ b/src/v0/destinations/fb/transform.js @@ -1,6 +1,7 @@ const get = require('get-value'); const set = require('set-value'); const sha256 = require('sha256'); +const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { removeUndefinedValues, @@ -20,7 +21,6 @@ const { eventPropToTypeMapping, } = require('./config'); const logger = require('../../../logger'); -const { InstrumentationError } = require('../../util/errorTypes'); // const funcMap = { // integer: parseInt, diff --git a/src/v0/destinations/fb_custom_audience/transform.js b/src/v0/destinations/fb_custom_audience/transform.js index f31a3dd42e..9320a3476b 100644 --- a/src/v0/destinations/fb_custom_audience/transform.js +++ b/src/v0/destinations/fb_custom_audience/transform.js @@ -1,5 +1,10 @@ const lodash = require('lodash'); const get = require('get-value'); +const { + InstrumentationError, + TransformationError, + ConfigurationError, +} = require('@rudderstack/integrations-lib'); const { defaultRequestConfig, defaultPostRequestConfig, @@ -26,11 +31,6 @@ const { } = require('./config'); const { MappedToDestinationKey } = require('../../../constants'); -const { - InstrumentationError, - TransformationError, - ConfigurationError, -} = require('../../util/errorTypes'); const responseBuilderSimple = (payload, audienceId) => { if (payload) { diff --git a/src/v0/destinations/fb_custom_audience/util.js b/src/v0/destinations/fb_custom_audience/util.js index 9e7198e393..47ccb9bf7d 100644 --- a/src/v0/destinations/fb_custom_audience/util.js +++ b/src/v0/destinations/fb_custom_audience/util.js @@ -2,11 +2,11 @@ const lodash = require('lodash'); const sha256 = require('sha256'); const get = require('get-value'); const jsonSize = require('json-size'); +const { InstrumentationError, ConfigurationError } = require('@rudderstack/integrations-lib'); const stats = require('../../../util/stats'); const { isDefinedAndNotNull } = require('../../util'); const { maxPayloadSize } = require('./config'); -const { InstrumentationError, ConfigurationError } = require('../../util/errorTypes'); /** * Example payload ={ diff --git a/src/v0/destinations/firehose/transform.js b/src/v0/destinations/firehose/transform.js index b0dc841579..81e2a1ebc8 100644 --- a/src/v0/destinations/firehose/transform.js +++ b/src/v0/destinations/firehose/transform.js @@ -1,6 +1,6 @@ const isString = require('lodash/isString'); +const { ConfigurationError } = require('@rudderstack/integrations-lib'); const { getHashFromArray, simpleProcessRouterDest } = require('../../util'); -const { ConfigurationError } = require('../../util/errorTypes'); function getDeliveryStreamMapTo(event) { const { message, destination } = event; diff --git a/src/v0/destinations/freshmarketer/transform.js b/src/v0/destinations/freshmarketer/transform.js index 41c604d407..aa0e03811d 100644 --- a/src/v0/destinations/freshmarketer/transform.js +++ b/src/v0/destinations/freshmarketer/transform.js @@ -1,4 +1,9 @@ const get = require('get-value'); +const { + InstrumentationError, + NetworkInstrumentationError, + TransformationError, +} = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { defaultRequestConfig, @@ -9,11 +14,6 @@ const { getValidDynamicFormConfig, simpleProcessRouterDest, } = require('../../util'); -const { - InstrumentationError, - NetworkInstrumentationError, - TransformationError, -} = require('../../util/errorTypes'); const { CONFIG_CATEGORIES, MAPPING_CONFIG } = require('./config'); const { diff --git a/src/v0/destinations/freshmarketer/utils.js b/src/v0/destinations/freshmarketer/utils.js index f7dcc46b06..6fa1fe9976 100644 --- a/src/v0/destinations/freshmarketer/utils.js +++ b/src/v0/destinations/freshmarketer/utils.js @@ -1,5 +1,10 @@ /* eslint-disable no-param-reassign */ const get = require('get-value'); +const { + InstrumentationError, + NetworkInstrumentationError, + NetworkError, +} = require('@rudderstack/integrations-lib'); const logger = require('../../../logger'); const { httpPOST, httpGET } = require('../../../adapters/network'); const { @@ -13,11 +18,6 @@ const { getFieldValueFromMessage, } = require('../../util'); const { CONFIG_CATEGORIES, LIFECYCLE_STAGE_ENDPOINT } = require('./config'); -const { - InstrumentationError, - NetworkInstrumentationError, - NetworkError, -} = require('../../util/errorTypes'); const tags = require('../../util/tags'); const { JSON_MIME_TYPE } = require('../../util/constant'); diff --git a/src/v0/destinations/freshsales/transform.js b/src/v0/destinations/freshsales/transform.js index c1e18482ed..096a2d749c 100644 --- a/src/v0/destinations/freshsales/transform.js +++ b/src/v0/destinations/freshsales/transform.js @@ -1,4 +1,5 @@ const get = require('get-value'); +const { InstrumentationError, TransformationError } = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { defaultRequestConfig, @@ -10,7 +11,6 @@ const { simpleProcessRouterDest, validateEventName, } = require('../../util'); -const { InstrumentationError, TransformationError } = require('../../util/errorTypes'); const { CONFIG_CATEGORIES, MAPPING_CONFIG } = require('./config'); const { getUserAccountDetails, diff --git a/src/v0/destinations/freshsales/utils.js b/src/v0/destinations/freshsales/utils.js index b30d9fa16b..96acabb037 100644 --- a/src/v0/destinations/freshsales/utils.js +++ b/src/v0/destinations/freshsales/utils.js @@ -1,5 +1,10 @@ /* eslint-disable no-param-reassign */ const get = require('get-value'); +const { + NetworkInstrumentationError, + InstrumentationError, + NetworkError, +} = require('@rudderstack/integrations-lib'); const { httpPOST, httpGET } = require('../../../adapters/network'); const { processAxiosResponse, @@ -10,11 +15,6 @@ const { defaultPostRequestConfig, getFieldValueFromMessage, } = require('../../util'); -const { - NetworkInstrumentationError, - InstrumentationError, - NetworkError, -} = require('../../util/errorTypes'); const { CONFIG_CATEGORIES, LIFECYCLE_STAGE_ENDPOINT } = require('./config'); const tags = require('../../util/tags'); const { JSON_MIME_TYPE } = require('../../util/constant'); diff --git a/src/v0/destinations/ga/deleteUsers.js b/src/v0/destinations/ga/deleteUsers.js index cf4694f44a..bb909a0053 100644 --- a/src/v0/destinations/ga/deleteUsers.js +++ b/src/v0/destinations/ga/deleteUsers.js @@ -1,7 +1,7 @@ const { isEmpty } = require('lodash'); +const { InstrumentationError, OAuthSecretError } = require('@rudderstack/integrations-lib'); const { httpPOST } = require('../../../adapters/network'); -const { InstrumentationError, OAuthSecretError } = require('../../util/errorTypes'); const { executeCommonValidations } = require('../../util/regulation-api'); const { GA_USER_DELETION_ENDPOINT } = require('./config'); const { gaResponseHandler } = require('./networkHandler'); diff --git a/src/v0/destinations/ga/networkHandler.js b/src/v0/destinations/ga/networkHandler.js index a12f9594cd..57db1cb7af 100644 --- a/src/v0/destinations/ga/networkHandler.js +++ b/src/v0/destinations/ga/networkHandler.js @@ -1,3 +1,4 @@ +const { NetworkError, InvalidAuthTokenError } = require('@rudderstack/integrations-lib'); const { REFRESH_TOKEN, AUTH_STATUS_INACTIVE, @@ -7,7 +8,6 @@ const { getDynamicErrorType, } = require('../../../adapters/utils/networkUtils'); -const { NetworkError, InvalidAuthTokenError } = require('../../util/errorTypes'); const tags = require('../../util/tags'); /** diff --git a/src/v0/destinations/ga/transform.js b/src/v0/destinations/ga/transform.js index c10697c4e1..32e94bdd41 100644 --- a/src/v0/destinations/ga/transform.js +++ b/src/v0/destinations/ga/transform.js @@ -1,6 +1,7 @@ /* eslint-disable no-nested-ternary */ const get = require('get-value'); const md5 = require('md5'); +const { InstrumentationError, ConfigurationError } = require('@rudderstack/integrations-lib'); const { EventType, MappedToDestinationKey } = require('../../../constants'); const { Event, GA_ENDPOINT, ConfigCategory, mappingConfig, nameToEventMap } = require('./config'); const { setContextualFields } = require('./utils'); @@ -19,7 +20,6 @@ const { } = require('../../util'); const { isDefinedAndNotNull } = require('../../util'); -const { InstrumentationError, ConfigurationError } = require('../../util/errorTypes'); const gaDisplayName = 'Google Analytics'; diff --git a/src/v0/destinations/ga/utils.js b/src/v0/destinations/ga/utils.js index 0d3a2f9798..617f2522a0 100644 --- a/src/v0/destinations/ga/utils.js +++ b/src/v0/destinations/ga/utils.js @@ -1,4 +1,4 @@ -const { InstrumentationError } = require('../../util/errorTypes'); +const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { GA_ENDPOINT } = require('./config'); /** diff --git a/src/v0/destinations/ga360/transform.js b/src/v0/destinations/ga360/transform.js index c60ea47551..3655c330d5 100644 --- a/src/v0/destinations/ga360/transform.js +++ b/src/v0/destinations/ga360/transform.js @@ -1,5 +1,6 @@ const get = require('get-value'); const md5 = require('md5'); +const { ConfigurationError, InstrumentationError } = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { Event, GA_ENDPOINT, ConfigCategory, mappingConfig, nameToEventMap } = require('./config'); const { @@ -12,7 +13,6 @@ const { getDestinationExternalID, simpleProcessRouterDest, } = require('../../util'); -const { ConfigurationError, InstrumentationError } = require('../../util/errorTypes'); const gaDisplayName = 'Google Analytics'; diff --git a/src/v0/destinations/ga4/networkHandler.js b/src/v0/destinations/ga4/networkHandler.js index e90d2c3095..b62fcc8d3b 100644 --- a/src/v0/destinations/ga4/networkHandler.js +++ b/src/v0/destinations/ga4/networkHandler.js @@ -1,3 +1,4 @@ +const { NetworkError } = require('@rudderstack/integrations-lib'); const { proxyRequest, prepareProxyRequest } = require('../../../adapters/network'); const { getDynamicErrorType, @@ -5,7 +6,6 @@ const { } = require('../../../adapters/utils/networkUtils'); const { isDefinedAndNotNull, isDefined, isHttpStatusSuccess } = require('../../util'); -const { NetworkError } = require('../../util/errorTypes'); const tags = require('../../util/tags'); const responseHandler = (destinationResponse, dest) => { diff --git a/src/v0/destinations/ga4/transform.js b/src/v0/destinations/ga4/transform.js index d1d0790fa9..d8fc531e92 100644 --- a/src/v0/destinations/ga4/transform.js +++ b/src/v0/destinations/ga4/transform.js @@ -1,4 +1,9 @@ const get = require('get-value'); +const { + ConfigurationError, + InstrumentationError, + UnsupportedEventError, +} = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { isEmptyObject, @@ -11,11 +16,6 @@ const { getDestinationExternalID, removeUndefinedAndNullValues, } = require('../../util'); -const { - ConfigurationError, - InstrumentationError, - UnsupportedEventError, -} = require('../../util/errorTypes'); const { ENDPOINT, mappingConfig, diff --git a/src/v0/destinations/ga4/utils.js b/src/v0/destinations/ga4/utils.js index d356300ff7..e4db494727 100644 --- a/src/v0/destinations/ga4/utils.js +++ b/src/v0/destinations/ga4/utils.js @@ -1,4 +1,5 @@ const get = require('get-value'); +const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { isEmpty, constructPayload, @@ -7,7 +8,6 @@ const { extractCustomFields, isDefinedAndNotNull, } = require('../../util'); -const { InstrumentationError } = require('../../util/errorTypes'); const { mappingConfig, ConfigCategory } = require('./config'); /** diff --git a/src/v0/destinations/gainsight/transform.js b/src/v0/destinations/gainsight/transform.js index f58fc0d566..f47296f066 100644 --- a/src/v0/destinations/gainsight/transform.js +++ b/src/v0/destinations/gainsight/transform.js @@ -1,6 +1,7 @@ /* eslint-disable no-nested-ternary */ const set = require('set-value'); const get = require('get-value'); +const { InstrumentationError, ConfigurationError } = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { identifyMapping, @@ -28,7 +29,6 @@ const { renameCustomFieldsFromMap, getConfigOrThrowError, } = require('./util'); -const { InstrumentationError, ConfigurationError } = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); /** diff --git a/src/v0/destinations/gainsight/util.js b/src/v0/destinations/gainsight/util.js index 3c986b420d..39e666c1a5 100644 --- a/src/v0/destinations/gainsight/util.js +++ b/src/v0/destinations/gainsight/util.js @@ -1,7 +1,11 @@ +const { + ConfigurationError, + RetryableError, + NetworkError, +} = require('@rudderstack/integrations-lib'); const myAxios = require('../../../util/myAxios'); const { getDynamicErrorType } = require('../../../adapters/utils/networkUtils'); const logger = require('../../../logger'); -const { ConfigurationError, RetryableError, NetworkError } = require('../../util/errorTypes'); const { ENDPOINTS, getLookupPayload } = require('./config'); const tags = require('../../util/tags'); const { JSON_MIME_TYPE } = require('../../util/constant'); diff --git a/src/v0/destinations/gainsight_px/transform.js b/src/v0/destinations/gainsight_px/transform.js index ab66b87c5a..4d91980f11 100644 --- a/src/v0/destinations/gainsight_px/transform.js +++ b/src/v0/destinations/gainsight_px/transform.js @@ -1,4 +1,5 @@ /* eslint-disable no-nested-ternary */ +const { InstrumentationError, ConfigurationError } = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { isEmptyObject, @@ -29,7 +30,6 @@ const { groupMapping, identifyMapping, } = require('./config'); -const { InstrumentationError, ConfigurationError } = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); /** diff --git a/src/v0/destinations/gainsight_px/util.js b/src/v0/destinations/gainsight_px/util.js index 6900180ab5..5109286b3f 100644 --- a/src/v0/destinations/gainsight_px/util.js +++ b/src/v0/destinations/gainsight_px/util.js @@ -1,6 +1,6 @@ +const { NetworkError } = require('@rudderstack/integrations-lib'); const myAxios = require('../../../util/myAxios'); const { ENDPOINTS } = require('./config'); -const { NetworkError } = require('../../util/errorTypes'); const tags = require('../../util/tags'); const { getDynamicErrorType } = require('../../../adapters/utils/networkUtils'); const { JSON_MIME_TYPE } = require('../../util/constant'); diff --git a/src/v0/destinations/google_adwords_enhanced_conversions/networkHandler.js b/src/v0/destinations/google_adwords_enhanced_conversions/networkHandler.js index e25349dfdc..8ac432935f 100644 --- a/src/v0/destinations/google_adwords_enhanced_conversions/networkHandler.js +++ b/src/v0/destinations/google_adwords_enhanced_conversions/networkHandler.js @@ -1,5 +1,6 @@ const { get, set } = require('lodash'); const sha256 = require('sha256'); +const { NetworkError, NetworkInstrumentationError } = require('@rudderstack/integrations-lib'); const { prepareProxyRequest, handleHttpRequest } = require('../../../adapters/network'); const { isHttpStatusSuccess, getAuthErrCategoryFromStCode } = require('../../util/index'); const { CONVERSION_ACTION_ID_CACHE_TTL } = require('./config'); @@ -12,7 +13,7 @@ const { getDynamicErrorType, } = require('../../../adapters/utils/networkUtils'); const { BASE_ENDPOINT } = require('./config'); -const { NetworkError, NetworkInstrumentationError } = require('../../util/errorTypes'); + const tags = require('../../util/tags'); const ERROR_MSG_PATH = 'response[0].error.message'; diff --git a/src/v0/destinations/google_adwords_enhanced_conversions/transform.js b/src/v0/destinations/google_adwords_enhanced_conversions/transform.js index 898c3f95b0..0be7c3f0ee 100644 --- a/src/v0/destinations/google_adwords_enhanced_conversions/transform.js +++ b/src/v0/destinations/google_adwords_enhanced_conversions/transform.js @@ -2,6 +2,7 @@ const get = require('get-value'); const { cloneDeep } = require('lodash'); +const { InstrumentationError, ConfigurationError } = require('@rudderstack/integrations-lib'); const { constructPayload, defaultRequestConfig, @@ -11,8 +12,6 @@ const { getAccessToken, } = require('../../util'); -const { InstrumentationError, ConfigurationError } = require('../../util/errorTypes'); - const { trackMapping, BASE_ENDPOINT } = require('./config'); const { JSON_MIME_TYPE } = require('../../util/constant'); diff --git a/src/v0/destinations/google_adwords_offline_conversions/networkHandler.js b/src/v0/destinations/google_adwords_offline_conversions/networkHandler.js index 71fdccff20..a87a2431f2 100644 --- a/src/v0/destinations/google_adwords_offline_conversions/networkHandler.js +++ b/src/v0/destinations/google_adwords_offline_conversions/networkHandler.js @@ -1,6 +1,11 @@ const set = require('set-value'); const get = require('get-value'); const sha256 = require('sha256'); +const { + AbortedError, + NetworkInstrumentationError, + NetworkError, +} = require('@rudderstack/integrations-lib'); const { prepareProxyRequest, httpSend, httpPOST } = require('../../../adapters/network'); const { isHttpStatusSuccess, @@ -15,11 +20,6 @@ const { processAxiosResponse, getDynamicErrorType, } = require('../../../adapters/utils/networkUtils'); -const { - AbortedError, - NetworkInstrumentationError, - NetworkError, -} = require('../../util/errorTypes'); const tags = require('../../util/tags'); const conversionCustomVariableCache = new Cache(CONVERSION_CUSTOM_VARIABLE_CACHE_TTL); diff --git a/src/v0/destinations/google_adwords_offline_conversions/transform.js b/src/v0/destinations/google_adwords_offline_conversions/transform.js index 0186739d37..397895c603 100644 --- a/src/v0/destinations/google_adwords_offline_conversions/transform.js +++ b/src/v0/destinations/google_adwords_offline_conversions/transform.js @@ -1,4 +1,5 @@ const { set, get } = require('lodash'); +const { InstrumentationError, ConfigurationError } = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { getHashFromArrayWithDuplicate, @@ -21,7 +22,6 @@ const { requestBuilder, getClickConversionPayloadAndEndpoint, } = require('./utils'); -const { InstrumentationError, ConfigurationError } = require('../../util/errorTypes'); const helper = require('./helper'); /** diff --git a/src/v0/destinations/google_adwords_offline_conversions/utils.js b/src/v0/destinations/google_adwords_offline_conversions/utils.js index 7fa5eb29af..c69c5a436f 100644 --- a/src/v0/destinations/google_adwords_offline_conversions/utils.js +++ b/src/v0/destinations/google_adwords_offline_conversions/utils.js @@ -1,5 +1,10 @@ const sha256 = require('sha256'); const { get, set, cloneDeep } = require('lodash'); +const { + AbortedError, + ConfigurationError, + InstrumentationError, +} = require('@rudderstack/integrations-lib'); const { httpPOST } = require('../../../adapters/network'); const { isHttpStatusSuccess, @@ -24,7 +29,6 @@ const { } = require('./config'); const { processAxiosResponse } = require('../../../adapters/utils/networkUtils'); const Cache = require('../../util/cache'); -const { AbortedError, ConfigurationError, InstrumentationError } = require('../../util/errorTypes'); const helper = require('./helper'); const conversionActionIdCache = new Cache(CONVERSION_ACTION_ID_CACHE_TTL); diff --git a/src/v0/destinations/google_adwords_remarketing_lists/networkHandler.js b/src/v0/destinations/google_adwords_remarketing_lists/networkHandler.js index b8470f9d28..5be8597bdb 100644 --- a/src/v0/destinations/google_adwords_remarketing_lists/networkHandler.js +++ b/src/v0/destinations/google_adwords_remarketing_lists/networkHandler.js @@ -1,3 +1,4 @@ +const { NetworkError } = require('@rudderstack/integrations-lib'); const { httpSend, prepareProxyRequest } = require('../../../adapters/network'); const { isHttpStatusSuccess, getAuthErrCategoryFromStCode } = require('../../util/index'); @@ -5,7 +6,6 @@ const { processAxiosResponse, getDynamicErrorType, } = require('../../../adapters/utils/networkUtils'); -const { NetworkError } = require('../../util/errorTypes'); const tags = require('../../util/tags'); /** * This function helps to create a offlineUserDataJobs diff --git a/src/v0/destinations/google_adwords_remarketing_lists/transform.js b/src/v0/destinations/google_adwords_remarketing_lists/transform.js index f8cd7c7037..884fcd71f6 100644 --- a/src/v0/destinations/google_adwords_remarketing_lists/transform.js +++ b/src/v0/destinations/google_adwords_remarketing_lists/transform.js @@ -1,5 +1,6 @@ const sha256 = require('sha256'); const get = require('get-value'); +const { InstrumentationError, ConfigurationError } = require('@rudderstack/integrations-lib'); const logger = require('../../../logger'); const { isDefinedAndNotNullAndNotEmpty, @@ -14,7 +15,6 @@ const { getAccessToken, } = require('../../util'); -const { InstrumentationError, ConfigurationError } = require('../../util/errorTypes'); const { offlineDataJobsMapping, addressInfoMapping, diff --git a/src/v0/destinations/google_cloud_function/util.js b/src/v0/destinations/google_cloud_function/util.js index 0a4fb9f4de..8f85460902 100644 --- a/src/v0/destinations/google_cloud_function/util.js +++ b/src/v0/destinations/google_cloud_function/util.js @@ -1,4 +1,4 @@ -const { ConfigurationError } = require('../../util/errorTypes'); +const { ConfigurationError } = require('@rudderstack/integrations-lib'); /** * validate destination config diff --git a/src/v0/destinations/googlepubsub/transform.js b/src/v0/destinations/googlepubsub/transform.js index 44208735e0..7a022d6c29 100644 --- a/src/v0/destinations/googlepubsub/transform.js +++ b/src/v0/destinations/googlepubsub/transform.js @@ -1,5 +1,5 @@ +const { ConfigurationError } = require('@rudderstack/integrations-lib'); const { simpleProcessRouterDest } = require('../../util'); -const { ConfigurationError } = require('../../util/errorTypes'); const { getTopic, createAttributesMetadata } = require('./util'); diff --git a/src/v0/destinations/googlesheets/transform.js b/src/v0/destinations/googlesheets/transform.js index 6cfb3f1d1e..6e27f6192c 100644 --- a/src/v0/destinations/googlesheets/transform.js +++ b/src/v0/destinations/googlesheets/transform.js @@ -1,12 +1,12 @@ /* eslint-disable no-nested-ternary */ const get = require('get-value'); +const { ConfigurationError } = require('@rudderstack/integrations-lib'); const { getValueFromMessage, getSuccessRespEvents, handleRtTfSingleEventError, checkInvalidRtTfEvents, } = require('../../util'); -const { ConfigurationError } = require('../../util/errorTypes'); const SOURCE_KEYS = ['properties', 'traits', 'context.traits']; diff --git a/src/v0/destinations/heap/transform.js b/src/v0/destinations/heap/transform.js index 32196eb7be..4256324165 100644 --- a/src/v0/destinations/heap/transform.js +++ b/src/v0/destinations/heap/transform.js @@ -1,3 +1,4 @@ +const { InstrumentationError, TransformationError } = require('@rudderstack/integrations-lib'); const { CONFIG_CATEGORIES, MAPPING_CONFIG } = require('./config'); const { EventType } = require('../../../constants'); const { @@ -8,7 +9,6 @@ const { flattenJson, simpleProcessRouterDest, } = require('../../util'); -const { InstrumentationError, TransformationError } = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); function responseBuilderSimple(message, category, destination) { diff --git a/src/v0/destinations/hs/HSTransform-v1.js b/src/v0/destinations/hs/HSTransform-v1.js index 30546ad8f6..51feebea74 100644 --- a/src/v0/destinations/hs/HSTransform-v1.js +++ b/src/v0/destinations/hs/HSTransform-v1.js @@ -1,5 +1,10 @@ const get = require('get-value'); const lodash = require('lodash'); +const { + InstrumentationError, + ConfigurationError, + TransformationError, +} = require('@rudderstack/integrations-lib'); const { MappedToDestinationKey, GENERIC_TRUE_VALUES } = require('../../../constants'); const { defaultGetRequestConfig, @@ -14,11 +19,6 @@ const { getDestinationExternalID, getDestinationExternalIDInfoForRetl, } = require('../../util'); -const { - InstrumentationError, - ConfigurationError, - TransformationError, -} = require('../../util/errorTypes'); const { BATCH_CONTACT_ENDPOINT, MAX_BATCH_SIZE, diff --git a/src/v0/destinations/hs/HSTransform-v2.js b/src/v0/destinations/hs/HSTransform-v2.js index 26c12d3eea..2acdd82152 100644 --- a/src/v0/destinations/hs/HSTransform-v2.js +++ b/src/v0/destinations/hs/HSTransform-v2.js @@ -1,5 +1,10 @@ const get = require('get-value'); const lodash = require('lodash'); +const { + TransformationError, + ConfigurationError, + InstrumentationError, +} = require('@rudderstack/integrations-lib'); const { MappedToDestinationKey, GENERIC_TRUE_VALUES } = require('../../../constants'); const { defaultPostRequestConfig, @@ -16,11 +21,6 @@ const { getDestinationExternalIDInfoForRetl, getDestinationExternalIDObjectForRetl, } = require('../../util'); -const { - TransformationError, - ConfigurationError, - InstrumentationError, -} = require('../../util/errorTypes'); const { IDENTIFY_CRM_UPDATE_CONTACT, IDENTIFY_CRM_CREATE_NEW_CONTACT, diff --git a/src/v0/destinations/hs/transform.js b/src/v0/destinations/hs/transform.js index a2326e0395..c26e024a6c 100644 --- a/src/v0/destinations/hs/transform.js +++ b/src/v0/destinations/hs/transform.js @@ -1,4 +1,5 @@ const get = require('get-value'); +const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { checkInvalidRtTfEvents, @@ -19,7 +20,6 @@ const { getProperties, validateDestinationConfig, } = require('./util'); -const { InstrumentationError } = require('../../util/errorTypes'); const processSingleMessage = async (message, destination, propertyMap) => { if (!message.type) { diff --git a/src/v0/destinations/hs/util.js b/src/v0/destinations/hs/util.js index eb062b0c39..72025997d2 100644 --- a/src/v0/destinations/hs/util.js +++ b/src/v0/destinations/hs/util.js @@ -1,4 +1,10 @@ const get = require('get-value'); +const { + NetworkInstrumentationError, + InstrumentationError, + ConfigurationError, + NetworkError, +} = require('@rudderstack/integrations-lib'); const { httpGET, httpPOST } = require('../../../adapters/network'); const { processAxiosResponse, @@ -12,12 +18,6 @@ const { getDestinationExternalIDInfoForRetl, getValueFromMessage, } = require('../../util'); -const { - NetworkInstrumentationError, - InstrumentationError, - ConfigurationError, - NetworkError, -} = require('../../util/errorTypes'); const { CONTACT_PROPERTY_MAP_ENDPOINT, IDENTIFY_CRM_SEARCH_CONTACT, diff --git a/src/v0/destinations/impact/transform.js b/src/v0/destinations/impact/transform.js index 026318cec7..2eefdf7992 100644 --- a/src/v0/destinations/impact/transform.js +++ b/src/v0/destinations/impact/transform.js @@ -1,5 +1,10 @@ const sha1 = require('js-sha1'); const btoa = require('btoa'); +const { + ConfigurationError, + TransformationError, + InstrumentationError, +} = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { CONFIG_CATEGORIES, MAPPING_CONFIG } = require('./config'); const { @@ -17,11 +22,6 @@ const { removeUndefinedAndNullValues, isDefinedAndNotNullAndNotEmpty, } = require('../../util'); -const { - ConfigurationError, - TransformationError, - InstrumentationError, -} = require('../../util/errorTypes'); /** * This function takes the transformed payload, endpoint and destination Config as input and returns the prepared response. diff --git a/src/v0/destinations/indicative/transform.js b/src/v0/destinations/indicative/transform.js index 81eb19f320..000998c3b8 100644 --- a/src/v0/destinations/indicative/transform.js +++ b/src/v0/destinations/indicative/transform.js @@ -1,4 +1,5 @@ const get = require('get-value'); +const { InstrumentationError, TransformationError } = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { CONFIG_CATEGORIES, MAPPING_CONFIG } = require('./config'); const { @@ -9,7 +10,6 @@ const { simpleProcessRouterDest, } = require('../../util'); const { getUAInfo } = require('./utils'); -const { InstrumentationError, TransformationError } = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); const handleProperties = (properties) => { diff --git a/src/v0/destinations/intercom/deleteUsers.js b/src/v0/destinations/intercom/deleteUsers.js index 9241a22906..e11d352117 100644 --- a/src/v0/destinations/intercom/deleteUsers.js +++ b/src/v0/destinations/intercom/deleteUsers.js @@ -1,8 +1,8 @@ +const { NetworkError, ConfigurationError } = require('@rudderstack/integrations-lib'); const { httpPOST } = require('../../../adapters/network'); const { processAxiosResponse } = require('../../../adapters/utils/networkUtils'); const { isHttpStatusSuccess } = require('../../util'); const { getDynamicErrorType } = require('../../../adapters/utils/networkUtils'); -const { NetworkError, ConfigurationError } = require('../../util/errorTypes'); const { executeCommonValidations } = require('../../util/regulation-api'); const tags = require('../../util/tags'); const { JSON_MIME_TYPE } = require('../../util/constant'); diff --git a/src/v0/destinations/intercom/networkHandler.js b/src/v0/destinations/intercom/networkHandler.js index 33f78e8cf6..a4106257b3 100644 --- a/src/v0/destinations/intercom/networkHandler.js +++ b/src/v0/destinations/intercom/networkHandler.js @@ -1,8 +1,7 @@ +const { RetryableError } = require('@rudderstack/integrations-lib'); const { proxyRequest, prepareProxyRequest } = require('../../../adapters/network'); const { processAxiosResponse } = require('../../../adapters/utils/networkUtils'); -const { RetryableError } = require('../../util/errorTypes'); - const errorResponseHandler = (destinationResponse, dest) => { const { status } = destinationResponse; if (status === 408) { diff --git a/src/v0/destinations/intercom/transform.js b/src/v0/destinations/intercom/transform.js index 552c80527c..212eaba13b 100644 --- a/src/v0/destinations/intercom/transform.js +++ b/src/v0/destinations/intercom/transform.js @@ -1,5 +1,6 @@ const md5 = require('md5'); const get = require('get-value'); +const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { EventType, MappedToDestinationKey } = require('../../../constants'); const { ConfigCategory, @@ -18,7 +19,6 @@ const { flattenJson, } = require('../../util'); const { separateReservedAndRestMetadata } = require('./util'); -const { InstrumentationError } = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); function getCompanyAttribute(company) { diff --git a/src/v0/destinations/iterable/deleteUsers.js b/src/v0/destinations/iterable/deleteUsers.js index 834cccd4cb..a179a8930f 100644 --- a/src/v0/destinations/iterable/deleteUsers.js +++ b/src/v0/destinations/iterable/deleteUsers.js @@ -1,8 +1,8 @@ +const { NetworkError, ConfigurationError } = require('@rudderstack/integrations-lib'); const { httpDELETE } = require('../../../adapters/network'); const { processAxiosResponse } = require('../../../adapters/utils/networkUtils'); const { isHttpStatusSuccess } = require('../../util'); const { getDynamicErrorType } = require('../../../adapters/utils/networkUtils'); -const { NetworkError, ConfigurationError } = require('../../util/errorTypes'); const { executeCommonValidations } = require('../../util/regulation-api'); const tags = require('../../util/tags'); const { JSON_MIME_TYPE } = require('../../util/constant'); diff --git a/src/v0/destinations/iterable/transform.js b/src/v0/destinations/iterable/transform.js index c54b579a52..64bdcfcfa4 100644 --- a/src/v0/destinations/iterable/transform.js +++ b/src/v0/destinations/iterable/transform.js @@ -1,5 +1,6 @@ const lodash = require('lodash'); const get = require('get-value'); +const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { getCatalogEndpoint, hasMultipleResponses, @@ -26,7 +27,6 @@ const { } = require('../../util'); const { JSON_MIME_TYPE } = require('../../util/constant'); const { mappingConfig, ConfigCategory } = require('./config'); -const { InstrumentationError } = require('../../util/errorTypes'); const { EventType, MappedToDestinationKey } = require('../../../constants'); /** diff --git a/src/v0/destinations/iterable/util.js b/src/v0/destinations/iterable/util.js index 0b7e402f01..7c1509c2b7 100644 --- a/src/v0/destinations/iterable/util.js +++ b/src/v0/destinations/iterable/util.js @@ -1,6 +1,7 @@ const lodash = require('lodash'); const get = require('get-value'); const jsonSize = require('json-size'); +const { InstrumentationError, ConfigurationError } = require('@rudderstack/integrations-lib'); const { isAppleFamily, constructPayload, @@ -20,7 +21,6 @@ const { } = require('./config'); const { JSON_MIME_TYPE } = require('../../util/constant'); const { EventType, MappedToDestinationKey } = require('../../../constants'); -const { InstrumentationError, ConfigurationError } = require('../../util/errorTypes'); const MESSAGE_JSON_PATH = 'message.body.JSON'; diff --git a/src/v0/destinations/june/transform.js b/src/v0/destinations/june/transform.js index f85cb0fd3d..c8f3206903 100644 --- a/src/v0/destinations/june/transform.js +++ b/src/v0/destinations/june/transform.js @@ -1,3 +1,4 @@ +const { TransformationError, InstrumentationError } = require('@rudderstack/integrations-lib'); const { isEmptyObject, constructPayload, @@ -10,7 +11,6 @@ const { const { EventType } = require('../../../constants'); const { JSON_MIME_TYPE } = require('../../util/constant'); const { CONFIG_CATEGORIES, MAPPING_CONFIG } = require('./config'); -const { TransformationError, InstrumentationError } = require('../../util/errorTypes'); const responseBuilder = (payload, endpoint, destination) => { const destPayload = payload; diff --git a/src/v0/destinations/kafka/transform.js b/src/v0/destinations/kafka/transform.js index 39334b5f52..b08c717475 100644 --- a/src/v0/destinations/kafka/transform.js +++ b/src/v0/destinations/kafka/transform.js @@ -8,7 +8,6 @@ const { getSuccessRespEvents, getErrorRespEvents, } = require('../../util'); -// const { InstrumentationError } = require("../../util/errorTypes"); const filterConfigTopics = (message, destination) => { const { Config } = destination; diff --git a/src/v0/destinations/keen/transform.js b/src/v0/destinations/keen/transform.js index 6d99c90dcc..b68b5e5e1d 100644 --- a/src/v0/destinations/keen/transform.js +++ b/src/v0/destinations/keen/transform.js @@ -2,6 +2,7 @@ /* eslint-disable no-nested-ternary */ const isIp = require('is-ip'); const validUrl = require('valid-url'); +const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { defaultPostRequestConfig, @@ -10,7 +11,6 @@ const { getFieldValueFromMessage, simpleProcessRouterDest, } = require('../../util'); -const { InstrumentationError } = require('../../util/errorTypes'); const { ENDPOINT } = require('./config'); const { JSON_MIME_TYPE } = require('../../util/constant'); diff --git a/src/v0/destinations/kissmetrics/transform.js b/src/v0/destinations/kissmetrics/transform.js index 3e2c5593de..b24395076c 100644 --- a/src/v0/destinations/kissmetrics/transform.js +++ b/src/v0/destinations/kissmetrics/transform.js @@ -9,6 +9,7 @@ const is = require('is'); const extend = require('@ndhoule/extend'); const each = require('component-each'); +const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { defaultGetRequestConfig, @@ -17,7 +18,6 @@ const { simpleProcessRouterDest, } = require('../../util'); const { ENDPOINT } = require('./config'); -const { InstrumentationError } = require('../../util/errorTypes'); // source : https://github.com/segment-integrations/analytics.js-integration-kissmetrics/blob/master/lib/index.js function toUnixTimestamp(date) { diff --git a/src/v0/destinations/klaviyo/transform.js b/src/v0/destinations/klaviyo/transform.js index 5ad9b1869d..7c9061fc41 100644 --- a/src/v0/destinations/klaviyo/transform.js +++ b/src/v0/destinations/klaviyo/transform.js @@ -2,6 +2,7 @@ /* eslint-disable no-underscore-dangle */ /* eslint-disable array-callback-return */ const get = require('get-value'); +const { ConfigurationError, InstrumentationError } = require('@rudderstack/integrations-lib'); const { EventType, WhiteListedTraits, MappedToDestinationKey } = require('../../../constants'); const { CONFIG_CATEGORIES, @@ -36,7 +37,6 @@ const { flattenJson, isNewStatusCodesAccepted, } = require('../../util'); -const { ConfigurationError, InstrumentationError } = require('../../util/errorTypes'); const { JSON_MIME_TYPE, HTTP_STATUS_CODES } = require('../../util/constant'); /** @@ -373,8 +373,9 @@ const processRouterDest = async (inputs, reqMetadata) => { eventDestination, false, HTTP_STATUS_CODES.SUPPRESS_EVENTS, - ), error - } + ), + error, + }; } return getSuccessRespEvents(message, [metadata], eventDestination); }); diff --git a/src/v0/destinations/klaviyo/util.js b/src/v0/destinations/klaviyo/util.js index b31dafd78b..60b334f3a2 100644 --- a/src/v0/destinations/klaviyo/util.js +++ b/src/v0/destinations/klaviyo/util.js @@ -1,5 +1,6 @@ const { defaultRequestConfig } = require('rudder-transformer-cdk/build/utils'); const lodash = require('lodash'); +const { NetworkError, InstrumentationError } = require('@rudderstack/integrations-lib'); const { WhiteListedTraits } = require('../../../constants'); const { @@ -15,7 +16,6 @@ const { const tags = require('../../util/tags'); const { handleHttpRequest } = require('../../../adapters/network'); const { JSON_MIME_TYPE, HTTP_STATUS_CODES } = require('../../util/constant'); -const { NetworkError, InstrumentationError } = require('../../util/errorTypes'); const { getDynamicErrorType } = require('../../../adapters/utils/networkUtils'); const { BASE_ENDPOINT, MAPPING_CONFIG, CONFIG_CATEGORIES, MAX_BATCH_SIZE } = require('./config'); diff --git a/src/v0/destinations/kochava/transform.js b/src/v0/destinations/kochava/transform.js index c5a4fec81f..e9cf2eb1a0 100644 --- a/src/v0/destinations/kochava/transform.js +++ b/src/v0/destinations/kochava/transform.js @@ -1,4 +1,5 @@ const get = require('get-value'); +const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { KOCHAVA_ENDPOINT, @@ -11,7 +12,6 @@ const { formatTimeStamp, isAppleFamily, } = require('../../util'); -const { InstrumentationError } = require('../../util/errorTypes'); // build final response // -------------------- diff --git a/src/v0/destinations/kustomer/transform.js b/src/v0/destinations/kustomer/transform.js index 2898f0dfc2..e5010f55e0 100644 --- a/src/v0/destinations/kustomer/transform.js +++ b/src/v0/destinations/kustomer/transform.js @@ -1,5 +1,6 @@ /* eslint-disable no-nested-ternary */ const get = require('get-value'); +const { TransformationError, InstrumentationError } = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { CONFIG_CATEGORIES, MAPPING_CONFIG, DEFAULT_BASE_ENDPOINT } = require('./config'); const { @@ -13,7 +14,6 @@ const { simpleProcessRouterDest, } = require('../../util'); const { fetchKustomer, handleAdvancedtransformations } = require('./util'); -const { TransformationError, InstrumentationError } = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); // Function responsible for constructing the Kustomer (User) Payload for identify diff --git a/src/v0/destinations/kustomer/util.js b/src/v0/destinations/kustomer/util.js index 31157b2738..571a03f139 100644 --- a/src/v0/destinations/kustomer/util.js +++ b/src/v0/destinations/kustomer/util.js @@ -2,11 +2,11 @@ const lodash = require('lodash'); const set = require('set-value'); const get = require('get-value'); +const { NetworkError, AbortedError } = require('@rudderstack/integrations-lib'); const myAxios = require('../../../util/myAxios'); const { DEFAULT_BASE_ENDPOINT } = require('./config'); const { getType, isDefinedAndNotNull, isObject } = require('../../util'); const { getDynamicErrorType } = require('../../../adapters/utils/networkUtils'); -const { NetworkError, AbortedError } = require('../../util/errorTypes'); const tags = require('../../util/tags'); /** diff --git a/src/v0/destinations/lambda/transform.js b/src/v0/destinations/lambda/transform.js index 221ef18186..1570a69ec3 100644 --- a/src/v0/destinations/lambda/transform.js +++ b/src/v0/destinations/lambda/transform.js @@ -1,6 +1,6 @@ const _ = require('lodash'); const { getErrorRespEvents, getSuccessRespEvents } = require('../../util'); -const { ConfigurationError } = require('../../util/errorTypes'); +const { ConfigurationError } = require('@rudderstack/integrations-lib'); const DEFAULT_INVOCATION_TYPE = 'Event'; // asynchronous invocation const MAX_PAYLOAD_SIZE_IN_KB = 256; // only for asynchronous invocation diff --git a/src/v0/destinations/leanplum/transform.js b/src/v0/destinations/leanplum/transform.js index 9a5462f2e5..df075dd631 100644 --- a/src/v0/destinations/leanplum/transform.js +++ b/src/v0/destinations/leanplum/transform.js @@ -1,3 +1,4 @@ +const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { ConfigCategory, mappingConfig, ENDPOINT, API_VERSION } = require('./config'); const { @@ -7,7 +8,6 @@ const { constructPayload, simpleProcessRouterDest, } = require('../../util'); -const { InstrumentationError } = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); function preparePayload(message, name, destination) { diff --git a/src/v0/destinations/lemnisk/transform.js b/src/v0/destinations/lemnisk/transform.js index 1d6d9a89fb..905199079b 100644 --- a/src/v0/destinations/lemnisk/transform.js +++ b/src/v0/destinations/lemnisk/transform.js @@ -1,3 +1,8 @@ +const { + ConfigurationError, + TransformationError, + InstrumentationError, +} = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { CONFIG_CATEGORIES, @@ -14,11 +19,6 @@ const { isDefinedAndNotNullAndNotEmpty, } = require('../../util'); const { fetchPlatform } = require('./utils'); -const { - ConfigurationError, - TransformationError, - InstrumentationError, -} = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); const responseBuilder = (message, category, destination, platform) => { diff --git a/src/v0/destinations/lemnisk/utils.js b/src/v0/destinations/lemnisk/utils.js index 207122153d..28de9ab354 100644 --- a/src/v0/destinations/lemnisk/utils.js +++ b/src/v0/destinations/lemnisk/utils.js @@ -1,4 +1,4 @@ -const { ConfigurationError } = require('../../util/errorTypes'); +const { ConfigurationError } = require('@rudderstack/integrations-lib'); /** * Fetches the platform type from the destination Config diff --git a/src/v0/destinations/lytics/transform.js b/src/v0/destinations/lytics/transform.js index a8d489fa5f..c3a971adba 100644 --- a/src/v0/destinations/lytics/transform.js +++ b/src/v0/destinations/lytics/transform.js @@ -1,3 +1,4 @@ +const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { CONFIG_CATEGORIES, @@ -14,7 +15,6 @@ const { flattenJson, simpleProcessRouterDest, } = require('../../util'); -const { InstrumentationError } = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); const responseBuilderSimple = (message, category, destination) => { diff --git a/src/v0/destinations/mailchimp/transform.js b/src/v0/destinations/mailchimp/transform.js index ced92ddea1..894f70672a 100644 --- a/src/v0/destinations/mailchimp/transform.js +++ b/src/v0/destinations/mailchimp/transform.js @@ -1,4 +1,5 @@ const lodash = require('lodash'); +const { InstrumentationError, ConfigurationError } = require('@rudderstack/integrations-lib'); const { defaultPutRequestConfig, handleRtTfSingleEventError, @@ -23,7 +24,6 @@ const { stringifyPropertiesValues, } = require('./utils'); const { MAX_BATCH_SIZE, VALID_STATUSES, TRACK_CONFIG } = require('./config'); -const { InstrumentationError, ConfigurationError } = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); const responseBuilderSimple = (finalPayload, endpoint, Config, audienceId) => { diff --git a/src/v0/destinations/mailchimp/utils.js b/src/v0/destinations/mailchimp/utils.js index 5a6d62c72c..e1e2e9883b 100644 --- a/src/v0/destinations/mailchimp/utils.js +++ b/src/v0/destinations/mailchimp/utils.js @@ -1,5 +1,6 @@ const get = require('get-value'); const md5 = require('md5'); +const { InstrumentationError, NetworkError } = require('@rudderstack/integrations-lib'); const myAxios = require('../../../util/myAxios'); const { MappedToDestinationKey } = require('../../../constants'); const logger = require('../../../logger'); @@ -15,7 +16,6 @@ const { defaultBatchRequestConfig, constructPayload, } = require('../../util'); -const { InstrumentationError, NetworkError } = require('../../util/errorTypes'); const { MERGE_CONFIG, MERGE_ADDRESS, SUBSCRIPTION_STATUS, VALID_STATUSES } = require('./config'); const { getDynamicErrorType } = require('../../../adapters/utils/networkUtils'); const tags = require('../../util/tags'); diff --git a/src/v0/destinations/mailjet/transform.js b/src/v0/destinations/mailjet/transform.js index 3e3cfe5c81..9156bf45e9 100644 --- a/src/v0/destinations/mailjet/transform.js +++ b/src/v0/destinations/mailjet/transform.js @@ -1,4 +1,5 @@ const lodash = require('lodash'); +const { TransformationError, InstrumentationError } = require('@rudderstack/integrations-lib'); const { getErrorRespEvents, getSuccessRespEvents, @@ -12,7 +13,6 @@ const { const { MAX_BATCH_SIZE } = require('./config'); const { EventType } = require('../../../constants'); const { createOrUpdateContactResponseBuilder } = require('./utils'); -const { TransformationError, InstrumentationError } = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); const responseBuilder = (payload) => { diff --git a/src/v0/destinations/mailmodo/transform.js b/src/v0/destinations/mailmodo/transform.js index 39783c864f..756522939d 100644 --- a/src/v0/destinations/mailmodo/transform.js +++ b/src/v0/destinations/mailmodo/transform.js @@ -1,6 +1,7 @@ const lodash = require('lodash'); const get = require('get-value'); const { isEmpty } = require('lodash'); +const { ConfigurationError, InstrumentationError } = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { ConfigCategory, IDENTIFY_MAX_BATCH_SIZE, mappingConfig, BASE_URL } = require('./config'); const { @@ -14,7 +15,6 @@ const { handleRtTfSingleEventError, } = require('../../util'); const { deduceAddressFields, extractCustomProperties } = require('./utils'); -const { ConfigurationError, InstrumentationError } = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); const responseBuilder = (responseConfgs) => { diff --git a/src/v0/destinations/marketo/transform.js b/src/v0/destinations/marketo/transform.js index b23d992b64..5000ef506b 100644 --- a/src/v0/destinations/marketo/transform.js +++ b/src/v0/destinations/marketo/transform.js @@ -3,6 +3,11 @@ /* eslint-disable no-use-before-define */ const get = require('get-value'); const cloneDeep = require('lodash/cloneDeep'); +const { + InstrumentationError, + ConfigurationError, + UnauthorizedError, +} = require('@rudderstack/integrations-lib'); const stats = require('../../../util/stats'); const { EventType, MappedToDestinationKey } = require('../../../constants'); const { @@ -38,11 +43,6 @@ const { getResponseHandlerData, } = require('./util'); const logger = require('../../../logger'); -const { - InstrumentationError, - ConfigurationError, - UnauthorizedError, -} = require('../../util/errorTypes'); const userIdLeadCache = new Cache(USER_LEAD_CACHE_TTL); // 1 day const emailLeadCache = new Cache(USER_LEAD_CACHE_TTL); // 1 day diff --git a/src/v0/destinations/marketo/util.js b/src/v0/destinations/marketo/util.js index 0de14e2072..203e0bf859 100644 --- a/src/v0/destinations/marketo/util.js +++ b/src/v0/destinations/marketo/util.js @@ -1,9 +1,3 @@ -const { httpGET, httpPOST } = require('../../../adapters/network'); -const { - getDynamicErrorType, - processAxiosResponse, -} = require('../../../adapters/utils/networkUtils'); -const { isHttpStatusSuccess } = require('../../util/index'); const { NetworkError, AbortedError, @@ -11,7 +5,13 @@ const { RetryableError, UnhandledStatusCodeError, InstrumentationError, -} = require('../../util/errorTypes'); +} = require('@rudderstack/integrations-lib'); +const { httpGET, httpPOST } = require('../../../adapters/network'); +const { + getDynamicErrorType, + processAxiosResponse, +} = require('../../../adapters/utils/networkUtils'); +const { isHttpStatusSuccess } = require('../../util/index'); const tags = require('../../util/tags'); /** diff --git a/src/v0/destinations/marketo_bulk_upload/fetchJobStatus.js b/src/v0/destinations/marketo_bulk_upload/fetchJobStatus.js index 04eadc4c51..e6f5662000 100644 --- a/src/v0/destinations/marketo_bulk_upload/fetchJobStatus.js +++ b/src/v0/destinations/marketo_bulk_upload/fetchJobStatus.js @@ -1,8 +1,8 @@ /* eslint-disable no-restricted-syntax */ /* eslint-disable no-prototype-builtins */ +const { PlatformError } = require('@rudderstack/integrations-lib'); const { getAccessToken } = require('./util'); const { handleHttpRequest } = require('../../../adapters/network'); -const { PlatformError } = require('../../util/errorTypes'); const stats = require('../../../util/stats'); const { JSON_MIME_TYPE } = require('../../util/constant'); const { diff --git a/src/v0/destinations/marketo_bulk_upload/fileUpload.js b/src/v0/destinations/marketo_bulk_upload/fileUpload.js index 2c77cd6e29..c7212ff9cb 100644 --- a/src/v0/destinations/marketo_bulk_upload/fileUpload.js +++ b/src/v0/destinations/marketo_bulk_upload/fileUpload.js @@ -1,6 +1,12 @@ /* eslint-disable no-plusplus */ const FormData = require('form-data'); const fs = require('fs'); +const { + NetworkError, + ConfigurationError, + RetryableError, + TransformationError, +} = require('@rudderstack/integrations-lib'); const { getAccessToken, getMarketoFilePath, @@ -16,12 +22,6 @@ const { isDefinedAndNotNullAndNotEmpty, } = require('../../util'); const { handleHttpRequest } = require('../../../adapters/network'); -const { - NetworkError, - ConfigurationError, - RetryableError, - TransformationError, -} = require('../../util/errorTypes'); const { client } = require('../../../util/errorNotifier'); const stats = require('../../../util/stats'); diff --git a/src/v0/destinations/marketo_bulk_upload/marketo_bulk_upload.util.test.js b/src/v0/destinations/marketo_bulk_upload/marketo_bulk_upload.util.test.js index 777301b6c3..78ac7c9e48 100644 --- a/src/v0/destinations/marketo_bulk_upload/marketo_bulk_upload.util.test.js +++ b/src/v0/destinations/marketo_bulk_upload/marketo_bulk_upload.util.test.js @@ -4,7 +4,7 @@ const { handleFileUploadResponse, } = require('./util'); -const { AbortedError, RetryableError } = require('../../util/errorTypes'); +const { AbortedError, RetryableError } = require('@rudderstack/integrations-lib'); describe('handleCommonErrorResponse', () => { test('should throw AbortedError for abortable error codes', () => { diff --git a/src/v0/destinations/marketo_bulk_upload/poll.js b/src/v0/destinations/marketo_bulk_upload/poll.js index 5e37fd7c0e..3ad458c545 100644 --- a/src/v0/destinations/marketo_bulk_upload/poll.js +++ b/src/v0/destinations/marketo_bulk_upload/poll.js @@ -1,8 +1,8 @@ +const { NetworkError } = require('@rudderstack/integrations-lib'); const { removeUndefinedValues, isHttpStatusSuccess } = require('../../util'); const { getAccessToken, handlePollResponse, hydrateStatusForServer } = require('./util'); const { handleHttpRequest } = require('../../../adapters/network'); const stats = require('../../../util/stats'); -const { NetworkError } = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); const { POLL_ACTIVITY } = require('./config'); diff --git a/src/v0/destinations/marketo_bulk_upload/transform.js b/src/v0/destinations/marketo_bulk_upload/transform.js index d5764ee6c3..5431e67d38 100644 --- a/src/v0/destinations/marketo_bulk_upload/transform.js +++ b/src/v0/destinations/marketo_bulk_upload/transform.js @@ -1,3 +1,4 @@ +const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { getHashFromArray, getFieldValueFromMessage, @@ -5,7 +6,6 @@ const { defaultRequestConfig, } = require('../../util'); const { EventType } = require('../../../constants'); -const { InstrumentationError } = require('../../util/errorTypes'); function responseBuilderSimple(message, destination) { const payload = {}; diff --git a/src/v0/destinations/marketo_bulk_upload/util.js b/src/v0/destinations/marketo_bulk_upload/util.js index a60f57e50b..7b329a3441 100644 --- a/src/v0/destinations/marketo_bulk_upload/util.js +++ b/src/v0/destinations/marketo_bulk_upload/util.js @@ -1,10 +1,10 @@ -const { handleHttpRequest } = require('../../../adapters/network'); const { AbortedError, RetryableError, NetworkError, TransformationError, -} = require('../../util/errorTypes'); +} = require('@rudderstack/integrations-lib'); +const { handleHttpRequest } = require('../../../adapters/network'); const tags = require('../../util/tags'); const { isHttpStatusSuccess, generateUUID } = require('../../util'); const { getDynamicErrorType } = require('../../../adapters/utils/networkUtils'); diff --git a/src/v0/destinations/marketo_static_list/transform.js b/src/v0/destinations/marketo_static_list/transform.js index 156e26270b..856947c33c 100644 --- a/src/v0/destinations/marketo_static_list/transform.js +++ b/src/v0/destinations/marketo_static_list/transform.js @@ -1,5 +1,6 @@ const lodash = require('lodash'); const cloneDeep = require('lodash/cloneDeep'); +const { InstrumentationError, UnauthorizedError } = require('@rudderstack/integrations-lib'); const { defaultPostRequestConfig, defaultDeleteRequestConfig, @@ -16,7 +17,6 @@ const { const { formatConfig, MAX_LEAD_IDS_SIZE } = require('./config'); const Cache = require('../../util/cache'); const { getAuthToken } = require('../marketo/transform'); -const { InstrumentationError, UnauthorizedError } = require('../../util/errorTypes'); const authCache = new Cache(AUTH_CACHE_TTL); // 1 hr diff --git a/src/v0/destinations/marketo_static_list/util.js b/src/v0/destinations/marketo_static_list/util.js index 2d4fe493a0..3db6180d24 100644 --- a/src/v0/destinations/marketo_static_list/util.js +++ b/src/v0/destinations/marketo_static_list/util.js @@ -1,4 +1,4 @@ -const { InstrumentationError } = require('../../util/errorTypes'); +const { InstrumentationError } = require('@rudderstack/integrations-lib'); /** * Fetches the ids from the array of objects diff --git a/src/v0/destinations/mautic/transform.js b/src/v0/destinations/mautic/transform.js index 12b0d06b6f..13808f6e3c 100644 --- a/src/v0/destinations/mautic/transform.js +++ b/src/v0/destinations/mautic/transform.js @@ -1,3 +1,8 @@ +const { + TransformationError, + InstrumentationError, + ConfigurationError, +} = require('@rudderstack/integrations-lib'); const { defaultRequestConfig, constructPayload, @@ -20,11 +25,6 @@ const { const { EventType } = require('../../../constants'); const { mappingConfig, ConfigCategories } = require('./config'); -const { - TransformationError, - InstrumentationError, - ConfigurationError, -} = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); const responseBuilder = async (payload, endpoint, method, messageType, Config) => { diff --git a/src/v0/destinations/mautic/utils.js b/src/v0/destinations/mautic/utils.js index f9dd787d9d..d8ad8dbffc 100644 --- a/src/v0/destinations/mautic/utils.js +++ b/src/v0/destinations/mautic/utils.js @@ -1,5 +1,10 @@ /* eslint-disable no-return-assign, no-param-reassign, no-restricted-syntax */ const get = require('get-value'); +const { + NetworkError, + InstrumentationError, + ConfigurationError, +} = require('@rudderstack/integrations-lib'); const { getFieldValueFromMessage } = require('../../util'); const { BASE_URL, lookupFieldMap } = require('./config'); const { httpGET } = require('../../../adapters/network'); @@ -7,7 +12,6 @@ const { processAxiosResponse, getDynamicErrorType, } = require('../../../adapters/utils/networkUtils'); -const { NetworkError, InstrumentationError, ConfigurationError } = require('../../util/errorTypes'); const tags = require('../../util/tags'); const { JSON_MIME_TYPE } = require('../../util/constant'); diff --git a/src/v0/destinations/moengage/transform.js b/src/v0/destinations/moengage/transform.js index d87d931817..ea7db24406 100644 --- a/src/v0/destinations/moengage/transform.js +++ b/src/v0/destinations/moengage/transform.js @@ -1,4 +1,9 @@ const btoa = require('btoa'); +const { + ConfigurationError, + TransformationError, + InstrumentationError, +} = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { CONFIG_CATEGORIES, @@ -16,11 +21,6 @@ const { simpleProcessRouterDest, isAppleFamily, } = require('../../util'); -const { - ConfigurationError, - TransformationError, - InstrumentationError, -} = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); function responseBuilderSimple(message, category, destination) { diff --git a/src/v0/destinations/monday/transform.js b/src/v0/destinations/monday/transform.js index 37ee835e50..152b42f8d0 100644 --- a/src/v0/destinations/monday/transform.js +++ b/src/v0/destinations/monday/transform.js @@ -1,4 +1,9 @@ const get = require('get-value'); +const { + ConfigurationError, + TransformationError, + InstrumentationError, +} = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { ENDPOINT } = require('./config'); const { populatePayload, getBoardDetails, checkAllowedEventNameFromUI } = require('./util'); @@ -10,11 +15,6 @@ const { getDestinationExternalID, validateEventName, } = require('../../util'); -const { - ConfigurationError, - TransformationError, - InstrumentationError, -} = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); const responseBuilder = (payload, endpoint, apiToken) => { diff --git a/src/v0/destinations/monday/util.js b/src/v0/destinations/monday/util.js index 5f260aabae..a66dd63dff 100644 --- a/src/v0/destinations/monday/util.js +++ b/src/v0/destinations/monday/util.js @@ -1,8 +1,12 @@ const { isNumber } = require('lodash'); +const { + NetworkError, + ConfigurationError, + InstrumentationError, +} = require('@rudderstack/integrations-lib'); const { httpPOST } = require('../../../adapters/network'); const { processAxiosResponse } = require('../../../adapters/utils/networkUtils'); const { getDestinationExternalID, isDefinedAndNotNull } = require('../../util'); -const { NetworkError, ConfigurationError, InstrumentationError } = require('../../util/errorTypes'); const { getDynamicErrorType } = require('../../../adapters/utils/networkUtils'); const tags = require('../../util/tags'); const { JSON_MIME_TYPE } = require('../../util/constant'); diff --git a/src/v0/destinations/monetate/transform.js b/src/v0/destinations/monetate/transform.js index e4d1f28b61..26a88e686b 100644 --- a/src/v0/destinations/monetate/transform.js +++ b/src/v0/destinations/monetate/transform.js @@ -1,4 +1,5 @@ const get = require('get-value'); +const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { removeUndefinedValues, simpleProcessRouterDest } = require('../../util'); const { handleProductViewed, @@ -11,7 +12,6 @@ const { } = require('./utils'); const { EventType } = require('../../../constants'); const { mappingConfig } = require('./config'); -const { InstrumentationError } = require('../../util/errorTypes'); function track(message, destination) { const rawPayload = constructPayload(message, mappingConfig.MONETATETrack); diff --git a/src/v0/destinations/monetate/utils.js b/src/v0/destinations/monetate/utils.js index 7facc2617d..1fe899f120 100644 --- a/src/v0/destinations/monetate/utils.js +++ b/src/v0/destinations/monetate/utils.js @@ -1,6 +1,6 @@ const set = require('set-value'); const get = require('get-value'); -const { InstrumentationError } = require('../../util/errorTypes'); +const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { isDefinedAndNotNull, defaultRequestConfig, getValueFromMessage } = require('../../util'); const { ENDPOINT } = require('./config'); const { JSON_MIME_TYPE } = require('../../util/constant'); diff --git a/src/v0/destinations/mp/deleteUsers.js b/src/v0/destinations/mp/deleteUsers.js index 5b86cae6ae..f01475ef2b 100644 --- a/src/v0/destinations/mp/deleteUsers.js +++ b/src/v0/destinations/mp/deleteUsers.js @@ -1,4 +1,5 @@ const lodash = require('lodash'); +const { ConfigurationError, NetworkError } = require('@rudderstack/integrations-lib'); const { handleHttpRequest } = require('../../../adapters/network'); const { isHttpStatusSuccess } = require('../../util'); const { @@ -7,7 +8,6 @@ const { DISTINCT_ID_MAX_BATCH_SIZE, } = require('./config'); const { executeCommonValidations } = require('../../util/regulation-api'); -const { ConfigurationError, NetworkError } = require('../../util/errorTypes'); const { getDynamicErrorType } = require('../../../adapters/utils/networkUtils'); const tags = require('../../util/tags'); const { JSON_MIME_TYPE } = require('../../util/constant'); diff --git a/src/v0/destinations/mp/transform.js b/src/v0/destinations/mp/transform.js index a5f1bf2d9d..bb8d3e5756 100644 --- a/src/v0/destinations/mp/transform.js +++ b/src/v0/destinations/mp/transform.js @@ -1,5 +1,6 @@ const lodash = require('lodash'); const get = require('get-value'); +const { InstrumentationError, ConfigurationError } = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { base64Convertor, @@ -35,7 +36,6 @@ const { groupEventsByEndpoint, batchEvents, } = require('./util'); -const { InstrumentationError, ConfigurationError } = require('../../util/errorTypes'); const { CommonUtils } = require('../../../util/common'); // ref: https://help.mixpanel.com/hc/en-us/articles/115004613766-Default-Properties-Collected-by-Mixpanel diff --git a/src/v0/destinations/mp/util.js b/src/v0/destinations/mp/util.js index 30173fd514..bb4c23f1b4 100644 --- a/src/v0/destinations/mp/util.js +++ b/src/v0/destinations/mp/util.js @@ -1,5 +1,6 @@ const set = require('set-value'); const get = require('get-value'); +const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { isDefined, constructPayload, @@ -20,7 +21,6 @@ const { GEO_SOURCE_ALLOWED_VALUES, mappingConfig, } = require('./config'); -const { InstrumentationError } = require('../../util/errorTypes'); const { CommonUtils } = require('../../../util/common'); const mPIdentifyConfigJson = mappingConfig[ConfigCategory.IDENTIFY.name]; diff --git a/src/v0/destinations/ometria/networkResponseHandler.js b/src/v0/destinations/ometria/networkResponseHandler.js index 2020ab0343..501b67f176 100644 --- a/src/v0/destinations/ometria/networkResponseHandler.js +++ b/src/v0/destinations/ometria/networkResponseHandler.js @@ -1,8 +1,8 @@ +const { NetworkError } = require('@rudderstack/integrations-lib'); const { getDynamicErrorType, trimResponse } = require('../../../adapters/utils/networkUtils'); const { isDefinedAndNotNull } = require('../../util'); const { isEmpty } = require('../../util/index'); const tags = require('../../util/tags'); -const { NetworkError } = require('../../util/errorTypes'); const responseTransform = (destResponse) => { let respBody; diff --git a/src/v0/destinations/ometria/transform.js b/src/v0/destinations/ometria/transform.js index 6d3c2ab174..55038e10b8 100644 --- a/src/v0/destinations/ometria/transform.js +++ b/src/v0/destinations/ometria/transform.js @@ -1,7 +1,7 @@ /* eslint-disable one-var, @typescript-eslint/naming-convention */ /* eslint-disable camelcase */ +const { ConfigurationError, InstrumentationError } = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); -const { ConfigurationError, InstrumentationError } = require('../../util/errorTypes'); const { constructPayload, extractCustomFields, diff --git a/src/v0/destinations/one_signal/transform.js b/src/v0/destinations/one_signal/transform.js index db699935f4..a072aef0e4 100644 --- a/src/v0/destinations/one_signal/transform.js +++ b/src/v0/destinations/one_signal/transform.js @@ -1,4 +1,9 @@ const get = require('get-value'); +const { + ConfigurationError, + TransformationError, + InstrumentationError, +} = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { ConfigCategory, mappingConfig, BASE_URL, ENDPOINTS } = require('./config'); const { @@ -13,11 +18,6 @@ const { defaultPutRequestConfig, } = require('../../util'); const { populateDeviceType, populateTags } = require('./util'); -const { - ConfigurationError, - TransformationError, - InstrumentationError, -} = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); const responseBuilder = (payload, endpoint, eventType) => { diff --git a/src/v0/destinations/one_signal/util.js b/src/v0/destinations/one_signal/util.js index 4b53949e55..2de57de1b4 100644 --- a/src/v0/destinations/one_signal/util.js +++ b/src/v0/destinations/one_signal/util.js @@ -1,5 +1,5 @@ +const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { getIntegrationsObj, getFieldValueFromMessage, getBrowserInfo } = require('../../util'); -const { InstrumentationError } = require('../../util/errorTypes'); // For mapping device_type value const deviceTypeMapping = { diff --git a/src/v0/destinations/pagerduty/transform.js b/src/v0/destinations/pagerduty/transform.js index d7a8848ace..fb862d2553 100644 --- a/src/v0/destinations/pagerduty/transform.js +++ b/src/v0/destinations/pagerduty/transform.js @@ -1,3 +1,8 @@ +const { + ConfigurationError, + TransformationError, + InstrumentationError, +} = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { defaultRequestConfig, @@ -6,11 +11,6 @@ const { removeUndefinedAndNullValues, } = require('../../util'); const { JSON_MIME_TYPE } = require('../../util/constant'); -const { - ConfigurationError, - TransformationError, - InstrumentationError, -} = require('../../util/errorTypes'); const { trackEventPayloadBuilder } = require('./util'); const responseBuilder = (payload, endpoint) => { diff --git a/src/v0/destinations/pagerduty/util.js b/src/v0/destinations/pagerduty/util.js index 42030aa2e7..5b768704ed 100644 --- a/src/v0/destinations/pagerduty/util.js +++ b/src/v0/destinations/pagerduty/util.js @@ -1,5 +1,6 @@ const get = require('get-value'); const moment = require('moment'); +const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { SEVERITIES, EVENT_ACTIONS, @@ -9,7 +10,6 @@ const { DEFAULT_EVENT_ACTION, } = require('./config'); const { constructPayload, getIntegrationsObj } = require('../../util'); -const { InstrumentationError } = require('../../util/errorTypes'); /** * Validates the timestamp diff --git a/src/v0/destinations/pardot/networkHandler.js b/src/v0/destinations/pardot/networkHandler.js index 4cec03ebf8..12b4abbc53 100644 --- a/src/v0/destinations/pardot/networkHandler.js +++ b/src/v0/destinations/pardot/networkHandler.js @@ -1,3 +1,4 @@ +const { NetworkError } = require('@rudderstack/integrations-lib'); const { removeUndefinedValues } = require('../../util'); const { prepareProxyRequest, getPayloadData, httpSend } = require('../../../adapters/network'); const { @@ -7,7 +8,6 @@ const { const { isHttpStatusSuccess } = require('../../util/index'); const { REFRESH_TOKEN } = require('../../../adapters/networkhandler/authConstants'); const tags = require('../../util/tags'); -const { NetworkError } = require('../../util/errorTypes'); /** * Example Response from pardot diff --git a/src/v0/destinations/pardot/transform.js b/src/v0/destinations/pardot/transform.js index bfc7386ef9..b32b8967bd 100644 --- a/src/v0/destinations/pardot/transform.js +++ b/src/v0/destinations/pardot/transform.js @@ -34,6 +34,7 @@ */ const get = require('get-value'); +const { ConfigurationError, InstrumentationError } = require('@rudderstack/integrations-lib'); const { identifyConfig, DESTINATION } = require('./config'); const logger = require('../../../logger'); const { @@ -48,7 +49,6 @@ const { getAccessToken, } = require('../../util'); const { CONFIG_CATEGORIES } = require('./config'); -const { ConfigurationError, InstrumentationError } = require('../../util/errorTypes'); const buildResponse = (payload, url, destination, token) => { const responseBody = removeUndefinedValues(payload); diff --git a/src/v0/destinations/persistiq/transform.js b/src/v0/destinations/persistiq/transform.js index 195f8d6567..3b4fd6cadc 100644 --- a/src/v0/destinations/persistiq/transform.js +++ b/src/v0/destinations/persistiq/transform.js @@ -1,4 +1,5 @@ const { set } = require('lodash'); +const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { defaultRequestConfig, removeUndefinedAndNullValues, @@ -8,7 +9,6 @@ const { const { configCategories } = require('./config'); const { buildLeadPayload, getIdentifyTraits } = require('./util'); const { EventType } = require('../../../constants'); -const { InstrumentationError } = require('../../util/errorTypes'); const responseBuilder = (payload, endpoint, method, Config) => { const { apiKey } = Config; diff --git a/src/v0/destinations/persistiq/util.js b/src/v0/destinations/persistiq/util.js index 7e1986e9b3..f37a9d1886 100644 --- a/src/v0/destinations/persistiq/util.js +++ b/src/v0/destinations/persistiq/util.js @@ -1,4 +1,5 @@ const { get } = require('lodash'); +const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { getFieldValueFromMessage, getHashFromArray, @@ -6,7 +7,6 @@ const { flattenMultilevelPayload, } = require('../../util'); const { identifySourceKeys, fileConfigCategories, mappingConfig } = require('./config'); -const { InstrumentationError } = require('../../util/errorTypes'); /** * Returns the remaining keys from traits diff --git a/src/v0/destinations/personalize/transform.js b/src/v0/destinations/personalize/transform.js index 3523987a89..dcfaae755c 100644 --- a/src/v0/destinations/personalize/transform.js +++ b/src/v0/destinations/personalize/transform.js @@ -1,4 +1,5 @@ const lodash = require('lodash'); +const { ConfigurationError, InstrumentationError } = require('@rudderstack/integrations-lib'); const { KEY_CHECK_LIST, MANDATORY_PROPERTIES } = require('./config'); const { EventType } = require('../../../constants'); const { @@ -9,7 +10,6 @@ const { isDefined, simpleProcessRouterDest, } = require('../../util'); -const { ConfigurationError, InstrumentationError } = require('../../util/errorTypes'); const putEventsHandler = (message, destination) => { const { properties, anonymousId, event, messageId, context } = message; diff --git a/src/v0/destinations/pinterest_tag/transform.js b/src/v0/destinations/pinterest_tag/transform.js index 15efd63436..ee7e2e5b19 100644 --- a/src/v0/destinations/pinterest_tag/transform.js +++ b/src/v0/destinations/pinterest_tag/transform.js @@ -1,4 +1,5 @@ const { get } = require('lodash'); +const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { defaultRequestConfig, @@ -28,7 +29,6 @@ const { getV5EventsEndpoint, API_VERSION, } = require('./config'); -const { InstrumentationError } = require('../../util/errorTypes'); const responseBuilderSimple = (finalPayload, { Config }) => { const { apiVersion = API_VERSION.v3, adAccountId, conversionToken, sendAsTestEvent } = Config; diff --git a/src/v0/destinations/pinterest_tag/utils.js b/src/v0/destinations/pinterest_tag/utils.js index c6822636dc..c1493e9dbd 100644 --- a/src/v0/destinations/pinterest_tag/utils.js +++ b/src/v0/destinations/pinterest_tag/utils.js @@ -1,5 +1,6 @@ /* eslint-disable no-param-reassign */ const sha256 = require('sha256'); +const { InstrumentationError, ConfigurationError } = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { constructPayload, @@ -8,7 +9,6 @@ const { getHashFromArrayWithDuplicate, removeUndefinedAndNullValues, } = require('../../util'); -const { InstrumentationError, ConfigurationError } = require('../../util/errorTypes'); const { COMMON_CONFIGS, CUSTOM_CONFIGS, API_VERSION } = require('./config'); const VALID_ACTION_SOURCES = ['app_android', 'app_ios', 'web', 'offline']; diff --git a/src/v0/destinations/posthog/transform.js b/src/v0/destinations/posthog/transform.js index 9f639b59de..62a2f26783 100644 --- a/src/v0/destinations/posthog/transform.js +++ b/src/v0/destinations/posthog/transform.js @@ -1,4 +1,5 @@ const get = require('get-value'); +const { InstrumentationError, TransformationError } = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { DEFAULT_BASE_ENDPOINT, CONFIG_CATEGORIES, MAPPING_CONFIG } = require('./config'); const { @@ -14,7 +15,6 @@ const { removeUndefinedAndNullValues, simpleProcessRouterDest, } = require('../../util'); -const { InstrumentationError, TransformationError } = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); // Logic To match destination Property key that is in Rudder Stack Properties Object. diff --git a/src/v0/destinations/profitwell/transform.js b/src/v0/destinations/profitwell/transform.js index 70de193fbd..58449fd9c1 100644 --- a/src/v0/destinations/profitwell/transform.js +++ b/src/v0/destinations/profitwell/transform.js @@ -1,3 +1,8 @@ +const { + NetworkError, + ConfigurationError, + InstrumentationError, +} = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { getSubscriptionHistory, @@ -15,7 +20,6 @@ const { simpleProcessRouterDest, } = require('../../util'); const { BASE_ENDPOINT, createPayloadMapping } = require('./config'); -const { NetworkError, ConfigurationError, InstrumentationError } = require('../../util/errorTypes'); const { getDynamicErrorType } = require('../../../adapters/utils/networkUtils'); const tags = require('../../util/tags'); const { JSON_MIME_TYPE } = require('../../util/constant'); diff --git a/src/v0/destinations/profitwell/utils.js b/src/v0/destinations/profitwell/utils.js index d7a3562126..acc4db2035 100644 --- a/src/v0/destinations/profitwell/utils.js +++ b/src/v0/destinations/profitwell/utils.js @@ -1,4 +1,8 @@ const get = require('get-value'); +const { + InstrumentationError, + NetworkInstrumentationError, +} = require('@rudderstack/integrations-lib'); const { httpGET } = require('../../../adapters/network'); const { toUnixTimestamp, @@ -11,7 +15,6 @@ const { constructPayload, } = require('../../util'); const { BASE_ENDPOINT, createPayloadMapping, updatePayloadMapping } = require('./config'); -const { InstrumentationError, NetworkInstrumentationError } = require('../../util/errorTypes'); const CURRENCY_CODES = [ 'aed', diff --git a/src/v0/destinations/redis/transform.js b/src/v0/destinations/redis/transform.js index ffc4a33c43..23c73f0ba4 100644 --- a/src/v0/destinations/redis/transform.js +++ b/src/v0/destinations/redis/transform.js @@ -1,9 +1,9 @@ const lodash = require('lodash'); const flatten = require('flat'); +const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { isEmpty, isObject } = require('../../util'); const { EventType } = require('../../../constants'); -const { InstrumentationError } = require('../../util/errorTypes'); // processValues: // 1. removes keys with empty values or still an object(empty) after flattening diff --git a/src/v0/destinations/refiner/transform.js b/src/v0/destinations/refiner/transform.js index def685b597..b891945f7f 100644 --- a/src/v0/destinations/refiner/transform.js +++ b/src/v0/destinations/refiner/transform.js @@ -1,3 +1,4 @@ +const { TransformationError, InstrumentationError } = require('@rudderstack/integrations-lib'); const { ErrorMessage, defaultRequestConfig, @@ -13,7 +14,6 @@ const { identifyUserPayloadBuilder, } = require('./utils'); const { EventType } = require('../../../constants'); -const { TransformationError, InstrumentationError } = require('../../util/errorTypes'); const responseBuilder = (payload, endpoint, destination) => { if (payload) { diff --git a/src/v0/destinations/refiner/utils.js b/src/v0/destinations/refiner/utils.js index 109f6ff656..5e788352ca 100644 --- a/src/v0/destinations/refiner/utils.js +++ b/src/v0/destinations/refiner/utils.js @@ -1,7 +1,7 @@ const get = require('get-value'); +const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { CONFIG_CATEGORIES } = require('./config'); const { getHashFromArray, getFieldValueFromMessage } = require('../../util'); -const { InstrumentationError } = require('../../util/errorTypes'); /** * Validation for userId and an email diff --git a/src/v0/destinations/revenue_cat/transform.js b/src/v0/destinations/revenue_cat/transform.js index 5f165a9278..407cb91608 100644 --- a/src/v0/destinations/revenue_cat/transform.js +++ b/src/v0/destinations/revenue_cat/transform.js @@ -1,5 +1,10 @@ const set = require('set-value'); const { defaultRequestConfig } = require('rudder-transformer-cdk/build/utils'); +const { + ConfigurationError, + TransformationError, + InstrumentationError, +} = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { constructPayload, @@ -15,11 +20,6 @@ const { REVENUE_CAT_IDENTIFY_EXCLUSION, BASE_URL, } = require('./config'); -const { - ConfigurationError, - TransformationError, - InstrumentationError, -} = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); const trackResponseBuilder = async (message, category, { Config }) => { diff --git a/src/v0/destinations/rockerbox/transform.js b/src/v0/destinations/rockerbox/transform.js index 5369afa7e5..3ac806e5ee 100644 --- a/src/v0/destinations/rockerbox/transform.js +++ b/src/v0/destinations/rockerbox/transform.js @@ -1,4 +1,5 @@ const get = require('get-value'); +const { ConfigurationError, InstrumentationError } = require('@rudderstack/integrations-lib'); const { defaultRequestConfig, removeUndefinedAndNullValues, @@ -9,7 +10,6 @@ const { } = require('../../util'); const { EventType } = require('../../../constants'); const { CONFIG_CATEGORIES, MAPPING_CONFIG, ROCKERBOX_DEFINED_PROPERTIES } = require('./config'); -const { ConfigurationError, InstrumentationError } = require('../../util/errorTypes'); const responseBuilderSimple = (message, category, destination) => { const payload = constructPayload(message, MAPPING_CONFIG[category.name]); diff --git a/src/v0/destinations/salesforce/transform.js b/src/v0/destinations/salesforce/transform.js index 95e41ccd98..ab06a16d07 100644 --- a/src/v0/destinations/salesforce/transform.js +++ b/src/v0/destinations/salesforce/transform.js @@ -1,5 +1,9 @@ const get = require('get-value'); const cloneDeep = require('lodash/cloneDeep'); +const { + InstrumentationError, + NetworkInstrumentationError, +} = require('@rudderstack/integrations-lib'); const { EventType, MappedToDestinationKey } = require('../../../constants'); const { SF_API_VERSION, @@ -25,7 +29,6 @@ const { } = require('../../util'); const { getAccessToken, salesforceResponseHandler } = require('./utils'); const { handleHttpRequest } = require('../../../adapters/network'); -const { InstrumentationError, NetworkInstrumentationError } = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); // Basic response builder diff --git a/src/v0/destinations/salesforce/utils.js b/src/v0/destinations/salesforce/utils.js index 3ffa4e56d8..9429e12e8d 100644 --- a/src/v0/destinations/salesforce/utils.js +++ b/src/v0/destinations/salesforce/utils.js @@ -1,7 +1,7 @@ +const { RetryableError, ThrottledError, AbortedError } = require('@rudderstack/integrations-lib'); const { handleHttpRequest } = require('../../../adapters/network'); const { isHttpStatusSuccess } = require('../../util'); const Cache = require('../../util/cache'); -const { RetryableError, ThrottledError, AbortedError } = require('../../util/errorTypes'); const { ACCESS_TOKEN_CACHE_TTL, SF_TOKEN_REQUEST_URL_SANDBOX, diff --git a/src/v0/destinations/sendgrid/deleteUsers.js b/src/v0/destinations/sendgrid/deleteUsers.js index e93fefa59e..8410f41296 100644 --- a/src/v0/destinations/sendgrid/deleteUsers.js +++ b/src/v0/destinations/sendgrid/deleteUsers.js @@ -1,3 +1,4 @@ +const { NetworkError, ConfigurationError } = require('@rudderstack/integrations-lib'); const { httpDELETE } = require('../../../adapters/network'); const { delIdUrlLimit, DELETE_CONTACTS_ENDPOINT } = require('./config'); const { @@ -5,7 +6,6 @@ const { getDynamicErrorType, } = require('../../../adapters/utils/networkUtils'); const { isHttpStatusSuccess } = require('../../util'); -const { NetworkError, ConfigurationError } = require('../../util/errorTypes'); const tags = require('../../util/tags'); const { executeCommonValidations } = require('../../util/regulation-api'); diff --git a/src/v0/destinations/sendgrid/transform.js b/src/v0/destinations/sendgrid/transform.js index d2f5b38b70..5038fedf7b 100644 --- a/src/v0/destinations/sendgrid/transform.js +++ b/src/v0/destinations/sendgrid/transform.js @@ -1,4 +1,9 @@ const lodash = require('lodash'); +const { + ConfigurationError, + TransformationError, + InstrumentationError, +} = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { ErrorMessage, @@ -34,11 +39,6 @@ const { generatePayloadFromConfig, createOrUpdateContactPayloadBuilder, } = require('./util'); -const { - ConfigurationError, - TransformationError, - InstrumentationError, -} = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); const responseBuilder = (payload, method, endpoint, apiKey) => { diff --git a/src/v0/destinations/sendgrid/util.js b/src/v0/destinations/sendgrid/util.js index fad227a65b..1df34bfe69 100644 --- a/src/v0/destinations/sendgrid/util.js +++ b/src/v0/destinations/sendgrid/util.js @@ -1,4 +1,9 @@ const get = require('get-value'); +const { + NetworkError, + ConfigurationError, + InstrumentationError, +} = require('@rudderstack/integrations-lib'); const logger = require('../../../logger'); const { isEmpty, @@ -21,7 +26,6 @@ const { processAxiosResponse, } = require('../../../adapters/utils/networkUtils'); const { httpGET } = require('../../../adapters/network'); -const { NetworkError, ConfigurationError, InstrumentationError } = require('../../util/errorTypes'); const { AUTH_CACHE_TTL, JSON_MIME_TYPE } = require('../../util/constant'); const { MAPPING_CONFIG, CONFIG_CATEGORIES } = require('./config'); diff --git a/src/v0/destinations/sendinblue/transform.js b/src/v0/destinations/sendinblue/transform.js index 151304db22..7663672f12 100644 --- a/src/v0/destinations/sendinblue/transform.js +++ b/src/v0/destinations/sendinblue/transform.js @@ -1,5 +1,6 @@ /* eslint-disable camelcase */ /* eslint-disable @typescript-eslint/naming-convention */ +const { TransformationError, InstrumentationError } = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { defaultRequestConfig, @@ -25,7 +26,6 @@ const { prepareTrackEventData, getListIds, } = require('./util'); -const { TransformationError, InstrumentationError } = require('../../util/errorTypes'); const responseBuilder = ( payload, diff --git a/src/v0/destinations/sendinblue/util.js b/src/v0/destinations/sendinblue/util.js index f184ee1ac1..9ad37fc9b7 100644 --- a/src/v0/destinations/sendinblue/util.js +++ b/src/v0/destinations/sendinblue/util.js @@ -1,3 +1,4 @@ +const { NetworkError, InstrumentationError } = require('@rudderstack/integrations-lib'); const { EMAIL_SUFFIX, getContactDetailsEndpoint } = require('./config'); const { getHashFromArray, @@ -12,7 +13,6 @@ const { processAxiosResponse, getDynamicErrorType, } = require('../../../adapters/utils/networkUtils'); -const { NetworkError, InstrumentationError } = require('../../util/errorTypes'); const tags = require('../../util/tags'); const { JSON_MIME_TYPE } = require('../../util/constant'); diff --git a/src/v0/destinations/serenytics/transform.js b/src/v0/destinations/serenytics/transform.js index ee7279e288..ee38f7d1a1 100644 --- a/src/v0/destinations/serenytics/transform.js +++ b/src/v0/destinations/serenytics/transform.js @@ -1,14 +1,14 @@ +const { + ConfigurationError, + TransformationError, + InstrumentationError, +} = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { ErrorMessage, simpleProcessRouterDest, getHashFromArrayWithDuplicate, } = require('../../util'); -const { - ConfigurationError, - TransformationError, - InstrumentationError, -} = require('../../util/errorTypes'); const { CONFIG_CATEGORIES, diff --git a/src/v0/destinations/serenytics/utils.js b/src/v0/destinations/serenytics/utils.js index bccce2585d..90ce374d5a 100644 --- a/src/v0/destinations/serenytics/utils.js +++ b/src/v0/destinations/serenytics/utils.js @@ -1,10 +1,10 @@ +const { ConfigurationError } = require('@rudderstack/integrations-lib'); const { constructPayload, extractCustomFields, defaultRequestConfig, defaultPostRequestConfig, } = require('../../util'); -const { ConfigurationError } = require('../../util/errorTypes'); const { MAPPING_CONFIG } = require('./config'); const checkStorageUrl = (STORAGE_URL, messageType) => { diff --git a/src/v0/destinations/sfmc/transform.js b/src/v0/destinations/sfmc/transform.js index 161720b2cc..879ca1989a 100644 --- a/src/v0/destinations/sfmc/transform.js +++ b/src/v0/destinations/sfmc/transform.js @@ -1,4 +1,9 @@ /* eslint-disable no-nested-ternary */ +const { + NetworkError, + ConfigurationError, + InstrumentationError, +} = require('@rudderstack/integrations-lib'); const myAxios = require('../../../util/myAxios'); const { EventType } = require('../../../constants'); const { CONFIG_CATEGORIES, MAPPING_CONFIG, ENDPOINTS } = require('./config'); @@ -19,7 +24,6 @@ const { getDynamicErrorType, nodeSysErrorToStatus, } = require('../../../adapters/utils/networkUtils'); -const { NetworkError, ConfigurationError, InstrumentationError } = require('../../util/errorTypes'); const tags = require('../../util/tags'); const { JSON_MIME_TYPE } = require('../../util/constant'); diff --git a/src/v0/destinations/shynet/transform.js b/src/v0/destinations/shynet/transform.js index 833616a11f..565c0790d5 100644 --- a/src/v0/destinations/shynet/transform.js +++ b/src/v0/destinations/shynet/transform.js @@ -1,4 +1,5 @@ /* eslint-disable no-underscore-dangle */ +const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { @@ -9,7 +10,6 @@ const { generateUUID, } = require('../../util'); const { JSON_MIME_TYPE } = require('../../util/constant'); -const { InstrumentationError } = require('../../util/errorTypes'); const { ConfigCategory, mappingConfig } = require('./config'); diff --git a/src/v0/destinations/signl4/transform.js b/src/v0/destinations/signl4/transform.js index 63dc10d73c..3a8b23b630 100644 --- a/src/v0/destinations/signl4/transform.js +++ b/src/v0/destinations/signl4/transform.js @@ -1,3 +1,8 @@ +const { + ConfigurationError, + TransformationError, + InstrumentationError, +} = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { BASE_URL } = require('./config'); const { populatePayload } = require('./utils'); @@ -7,11 +12,6 @@ const { simpleProcessRouterDest, removeUndefinedAndNullAndEmptyValues, } = require('../../util'); -const { - ConfigurationError, - TransformationError, - InstrumentationError, -} = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); const responseBuilder = (payload, endpoint) => { diff --git a/src/v0/destinations/singular/transform.js b/src/v0/destinations/singular/transform.js index 749debb0b0..ff5d18db9a 100644 --- a/src/v0/destinations/singular/transform.js +++ b/src/v0/destinations/singular/transform.js @@ -1,3 +1,4 @@ +const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { BASE_URL } = require('./config'); const { defaultRequestConfig, @@ -10,7 +11,6 @@ const { generateRevenuePayloadArray, isSessionEvent, } = require('./util'); -const { InstrumentationError } = require('../../util/errorTypes'); const responseBuilderSimple = (message, { Config }) => { const eventName = message.event; diff --git a/src/v0/destinations/singular/util.js b/src/v0/destinations/singular/util.js index 542b049a2e..4c5aeb8964 100644 --- a/src/v0/destinations/singular/util.js +++ b/src/v0/destinations/singular/util.js @@ -1,4 +1,5 @@ const lodash = require('lodash'); +const { TransformationError, InstrumentationError } = require('@rudderstack/integrations-lib'); const { CONFIG_CATEGORIES, MAPPING_CONFIG, @@ -20,7 +21,6 @@ const { isDefinedAndNotNull, isAppleFamily, } = require('../../util'); -const { TransformationError, InstrumentationError } = require('../../util/errorTypes'); /* All the fields listed inside properties which are not directly mapped, will be sent to 'e' as custom event attributes diff --git a/src/v0/destinations/slack/transform.js b/src/v0/destinations/slack/transform.js index 8db934d71f..41282c6887 100644 --- a/src/v0/destinations/slack/transform.js +++ b/src/v0/destinations/slack/transform.js @@ -1,5 +1,6 @@ /* eslint-disable no-nested-ternary, no-restricted-syntax, no-prototype-builtins */ const Handlebars = require('handlebars'); +const { InstrumentationError, ConfigurationError } = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { stringifyJSON, @@ -17,7 +18,6 @@ const { simpleProcessRouterDest, isDefinedAndNotNull, } = require('../../util'); -const { InstrumentationError, ConfigurationError } = require('../../util/errorTypes'); // build the response to be sent to backend, url encoded header is required as slack accepts payload in this format // add the username and image for Rudder diff --git a/src/v0/destinations/snapchat_conversion/transform.js b/src/v0/destinations/snapchat_conversion/transform.js index 49776935de..37d321a468 100644 --- a/src/v0/destinations/snapchat_conversion/transform.js +++ b/src/v0/destinations/snapchat_conversion/transform.js @@ -1,5 +1,6 @@ const get = require('get-value'); const moment = require('moment'); +const { InstrumentationError, ConfigurationError } = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { @@ -33,7 +34,6 @@ const { channelMapping, generateBatchedPayloadForArray, } = require('./util'); -const { InstrumentationError, ConfigurationError } = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); function buildResponse(apiKey, payload) { diff --git a/src/v0/destinations/snapchat_custom_audience/networkHandler.js b/src/v0/destinations/snapchat_custom_audience/networkHandler.js index 196f9a87fb..db36f6f518 100644 --- a/src/v0/destinations/snapchat_custom_audience/networkHandler.js +++ b/src/v0/destinations/snapchat_custom_audience/networkHandler.js @@ -1,3 +1,4 @@ +const { NetworkError, RetryableError, AbortedError } = require('@rudderstack/integrations-lib'); const { removeUndefinedValues, getAuthErrCategoryFromErrDetailsAndStCode } = require('../../util'); const { prepareProxyRequest, getPayloadData, httpSend } = require('../../../adapters/network'); const { isHttpStatusSuccess } = require('../../util/index'); @@ -7,7 +8,6 @@ const { getDynamicErrorType, processAxiosResponse, } = require('../../../adapters/utils/networkUtils'); -const { NetworkError, RetryableError, AbortedError } = require('../../util/errorTypes'); const { HTTP_STATUS_CODES } = require('../../util/constant'); const prepareProxyReq = (request) => { diff --git a/src/v0/destinations/snapchat_custom_audience/transform.js b/src/v0/destinations/snapchat_custom_audience/transform.js index 7938236594..f4cbeafb56 100644 --- a/src/v0/destinations/snapchat_custom_audience/transform.js +++ b/src/v0/destinations/snapchat_custom_audience/transform.js @@ -1,4 +1,5 @@ const sha256 = require('sha256'); +const { ConfigurationError } = require('@rudderstack/integrations-lib'); const { defaultRequestConfig, removeUndefinedAndNullValues, @@ -6,7 +7,6 @@ const { isDefinedAndNotNullAndNotEmpty, getAccessToken, } = require('../../util'); -const { ConfigurationError } = require('../../util/errorTypes'); const { BASE_URL, schemaType } = require('./config'); const { validatePayload, validateFields } = require('./utils'); const { JSON_MIME_TYPE } = require('../../util/constant'); diff --git a/src/v0/destinations/snapchat_custom_audience/utils.js b/src/v0/destinations/snapchat_custom_audience/utils.js index 4d20b27a09..bc4a2292da 100644 --- a/src/v0/destinations/snapchat_custom_audience/utils.js +++ b/src/v0/destinations/snapchat_custom_audience/utils.js @@ -1,4 +1,4 @@ -const { InstrumentationError } = require('../../util/errorTypes'); +const { InstrumentationError } = require('@rudderstack/integrations-lib'); /** * Verifies whether the input payload is in right format or not diff --git a/src/v0/destinations/splitio/transform.js b/src/v0/destinations/splitio/transform.js index 012c73a8b6..6641a62fe8 100644 --- a/src/v0/destinations/splitio/transform.js +++ b/src/v0/destinations/splitio/transform.js @@ -1,3 +1,4 @@ +const { TransformationError, InstrumentationError } = require('@rudderstack/integrations-lib'); const { CONFIG_CATEGORIES, MAPPING_CONFIG, @@ -18,7 +19,6 @@ const { simpleProcessRouterDest, ErrorMessage, } = require('../../util'); -const { TransformationError, InstrumentationError } = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); function responseBuilderSimple(payload, category, destination) { diff --git a/src/v0/destinations/statsig/transform.js b/src/v0/destinations/statsig/transform.js index 1be72d4095..81658a255a 100644 --- a/src/v0/destinations/statsig/transform.js +++ b/src/v0/destinations/statsig/transform.js @@ -1,7 +1,7 @@ +const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { defaultPostRequestConfig, defaultRequestConfig } = require('../../util'); const { ENDPOINT } = require('./config'); -const { InstrumentationError } = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); function process(event) { diff --git a/src/v0/destinations/stormly/transform.js b/src/v0/destinations/stormly/transform.js index 756bfb8024..dc7a256583 100644 --- a/src/v0/destinations/stormly/transform.js +++ b/src/v0/destinations/stormly/transform.js @@ -1,6 +1,7 @@ /* eslint-disable no-nested-ternary */ const get = require('get-value'); const set = require('set-value'); +const { TransformationError, InstrumentationError } = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { defaultRequestConfig, @@ -12,7 +13,6 @@ const { getDestinationExternalID, } = require('../../util'); const { CONFIG_CATEGORIES, MAPPING_CONFIG } = require('./config'); -const { TransformationError, InstrumentationError } = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); const responseBuilder = (payload, endpoint, destination) => { @@ -40,7 +40,8 @@ const identifyResponseBuilder = (message, destination) => { const trackResponseBuilder = (message, destination) => { const { endpoint, name } = CONFIG_CATEGORIES.TRACK; - const groupId = getDestinationExternalID(message, 'stormlyGroupId') || message.properties?.groupId; + const groupId = + getDestinationExternalID(message, 'stormlyGroupId') || message.properties?.groupId; let payload = constructPayload(message, MAPPING_CONFIG[name]); if (groupId) { diff --git a/src/v0/destinations/tiktok_ads/networkHandler.js b/src/v0/destinations/tiktok_ads/networkHandler.js index 1ec31e982a..ae93b1ec15 100644 --- a/src/v0/destinations/tiktok_ads/networkHandler.js +++ b/src/v0/destinations/tiktok_ads/networkHandler.js @@ -1,10 +1,10 @@ +const { NetworkError, ThrottledError, AbortedError } = require('@rudderstack/integrations-lib'); const { proxyRequest, prepareProxyRequest } = require('../../../adapters/network'); const { processAxiosResponse, getDynamicErrorType, } = require('../../../adapters/utils/networkUtils'); const { DESTINATION } = require('./config'); -const { NetworkError, ThrottledError, AbortedError } = require('../../util/errorTypes'); const { TAG_NAMES } = require('../../util/tags'); const { HTTP_STATUS_CODES } = require('../../util/constant'); diff --git a/src/v0/destinations/tiktok_ads/transform.js b/src/v0/destinations/tiktok_ads/transform.js index 4e99d83575..f0ed04a120 100644 --- a/src/v0/destinations/tiktok_ads/transform.js +++ b/src/v0/destinations/tiktok_ads/transform.js @@ -4,6 +4,7 @@ const _ = require('lodash'); const { SHA256 } = require('crypto-js'); const get = require('get-value'); const set = require('set-value'); +const { ConfigurationError, InstrumentationError } = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { constructPayload, @@ -29,7 +30,6 @@ const { MAX_BATCH_SIZE, PARTNER_NAME, } = require('./config'); -const { ConfigurationError, InstrumentationError } = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); const USER_EMAIL_KEY_PATH = 'context.user.email'; diff --git a/src/v0/destinations/tiktok_ads_offline_events/transform.js b/src/v0/destinations/tiktok_ads_offline_events/transform.js index 3539c856a3..945c31ea63 100644 --- a/src/v0/destinations/tiktok_ads_offline_events/transform.js +++ b/src/v0/destinations/tiktok_ads_offline_events/transform.js @@ -1,6 +1,7 @@ const { SHA256 } = require('crypto-js'); const set = require('set-value'); const lodash = require('lodash'); +const { ConfigurationError, InstrumentationError } = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { constructPayload, @@ -21,7 +22,6 @@ const { EVENT_NAME_MAPPING, PARTNER_NAME, } = require('./config'); -const { ConfigurationError, InstrumentationError } = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); const getContents = (message) => { diff --git a/src/v0/destinations/trengo/transform.js b/src/v0/destinations/trengo/transform.js index 14d1d8c84c..06e5496a1e 100644 --- a/src/v0/destinations/trengo/transform.js +++ b/src/v0/destinations/trengo/transform.js @@ -2,6 +2,13 @@ /* eslint-disable no-prototype-builtins */ const Handlebars = require('handlebars'); const get = require('get-value'); +const { + NetworkError, + ConfigurationError, + TransformationError, + InstrumentationError, + NetworkInstrumentationError, +} = require('@rudderstack/integrations-lib'); const myAxios = require('../../../util/myAxios'); const { EventType } = require('../../../constants'); const { EndPoints, BASE_URL } = require('./config'); @@ -17,13 +24,6 @@ const { getStringValueOfJSON, ErrorMessage, } = require('../../util'); -const { - NetworkError, - ConfigurationError, - TransformationError, - InstrumentationError, - NetworkInstrumentationError, -} = require('../../util/errorTypes'); const tags = require('../../util/tags'); const { getDynamicErrorType } = require('../../../adapters/utils/networkUtils'); const { JSON_MIME_TYPE } = require('../../util/constant'); diff --git a/src/v0/destinations/twitter_ads/transform.js b/src/v0/destinations/twitter_ads/transform.js index 363e61072e..268dca3636 100644 --- a/src/v0/destinations/twitter_ads/transform.js +++ b/src/v0/destinations/twitter_ads/transform.js @@ -1,5 +1,10 @@ const sha256 = require('sha256'); +const { + InstrumentationError, + OAuthSecretError, + ConfigurationError, +} = require('@rudderstack/integrations-lib'); const { constructPayload, defaultRequestConfig, @@ -11,11 +16,6 @@ const { const { EventType } = require('../../../constants'); const { ConfigCategories, mappingConfig, BASE_URL } = require('./config'); -const { - InstrumentationError, - OAuthSecretError, - ConfigurationError, -} = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); const { getAuthHeaderForRequest } = require('./util'); diff --git a/src/v0/destinations/user/transform.js b/src/v0/destinations/user/transform.js index 6cde9c9b80..ed04f5ccd4 100644 --- a/src/v0/destinations/user/transform.js +++ b/src/v0/destinations/user/transform.js @@ -1,3 +1,8 @@ +const { + TransformationError, + InstrumentationError, + NetworkInstrumentationError, +} = require('@rudderstack/integrations-lib'); const { defaultRequestConfig, simpleProcessRouterDest, @@ -17,11 +22,6 @@ const { createOrUpdateUserPayloadBuilder, createEventOccurrencePayloadBuilder, } = require('./utils'); -const { - TransformationError, - InstrumentationError, - NetworkInstrumentationError, -} = require('../../util/errorTypes'); const { EventType } = require('../../../constants'); const { JSON_MIME_TYPE } = require('../../util/constant'); diff --git a/src/v0/destinations/user/utils.js b/src/v0/destinations/user/utils.js index 23dd74a30f..41ad173583 100644 --- a/src/v0/destinations/user/utils.js +++ b/src/v0/destinations/user/utils.js @@ -1,4 +1,8 @@ const get = require('get-value'); +const { + InstrumentationError, + NetworkInstrumentationError, +} = require('@rudderstack/integrations-lib'); const { getHashFromArray, constructPayload, @@ -19,7 +23,6 @@ const { groupSourceKeys, identifySourceKeys, } = require('./config'); -const { InstrumentationError, NetworkInstrumentationError } = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); const ACCEPT_HEADER_VAL = '*/*;version=2'; diff --git a/src/v0/destinations/userlist/transform.js b/src/v0/destinations/userlist/transform.js index 20b47c6a35..45d58edbbf 100644 --- a/src/v0/destinations/userlist/transform.js +++ b/src/v0/destinations/userlist/transform.js @@ -1,3 +1,4 @@ +const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { defaultRequestConfig, @@ -9,7 +10,6 @@ const { const { endpoint } = require('./config'); -const { InstrumentationError } = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); // ------------------------------------------------ diff --git a/src/v0/destinations/vero/transform.js b/src/v0/destinations/vero/transform.js index 7115ea425d..f489056681 100644 --- a/src/v0/destinations/vero/transform.js +++ b/src/v0/destinations/vero/transform.js @@ -1,5 +1,6 @@ const set = require('set-value'); const get = require('get-value'); +const { InstrumentationError, ConfigurationError } = require('@rudderstack/integrations-lib'); const { defaultRequestConfig, constructPayload, @@ -11,7 +12,6 @@ const { } = require('../../util'); const { EventType } = require('../../../constants'); const { CONFIG_CATEGORIES, MAPPING_CONFIG } = require('./config'); -const { InstrumentationError, ConfigurationError } = require('../../util/errorTypes'); // This function handles the common response payload for the supported calls const responseBuilderSimple = (message, category, destination) => { diff --git a/src/v0/destinations/webengage/transform.js b/src/v0/destinations/webengage/transform.js index 835a486eff..f18a7399ff 100644 --- a/src/v0/destinations/webengage/transform.js +++ b/src/v0/destinations/webengage/transform.js @@ -1,4 +1,5 @@ /* eslint-disable no-param-reassign */ +const { InstrumentationError, TransformationError } = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { CONFIG_CATEGORIES, @@ -15,7 +16,6 @@ const { simpleProcessRouterDest, extractCustomFields, } = require('../../util'); -const { InstrumentationError, TransformationError } = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); const responseBuilder = (message, category, { Config }) => { diff --git a/src/v0/destinations/webhook/transform.js b/src/v0/destinations/webhook/transform.js index a4a7617f68..6a115f1c63 100644 --- a/src/v0/destinations/webhook/transform.js +++ b/src/v0/destinations/webhook/transform.js @@ -1,6 +1,7 @@ /* eslint-disable no-nested-ternary */ const get = require('get-value'); const set = require('set-value'); +const { ConfigurationError } = require('@rudderstack/integrations-lib'); const { defaultPostRequestConfig, defaultPutRequestConfig, @@ -17,7 +18,6 @@ const { } = require('../../util'); const { EventType } = require('../../../constants'); -const { ConfigurationError } = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); const getPropertyParams = (message) => { diff --git a/src/v0/destinations/woopra/transform.js b/src/v0/destinations/woopra/transform.js index 1414cbac23..9104884416 100644 --- a/src/v0/destinations/woopra/transform.js +++ b/src/v0/destinations/woopra/transform.js @@ -1,5 +1,6 @@ /* eslint-disable no-param-reassign */ const { set, get } = require('lodash'); +const { TransformationError, InstrumentationError } = require('@rudderstack/integrations-lib'); const { defaultRequestConfig, constructPayload, @@ -12,7 +13,6 @@ const { const { EventType } = require('../../../constants'); const { BASE_URL, mappingConfig, ConfigCategories } = require('./config'); const { refinePayload, getEvent } = require('./utils'); -const { TransformationError, InstrumentationError } = require('../../util/errorTypes'); const responseBuilder = (payload, endpoint, method, projectName) => { if (!payload) { diff --git a/src/v0/destinations/wootric/transform.js b/src/v0/destinations/wootric/transform.js index f89e63a5ed..f8b4274af7 100644 --- a/src/v0/destinations/wootric/transform.js +++ b/src/v0/destinations/wootric/transform.js @@ -1,3 +1,4 @@ +const { TransformationError, InstrumentationError } = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { defaultRequestConfig, @@ -19,7 +20,6 @@ const { createDeclinePayloadBuilder, } = require('./util'); const { PROPERTIES, END_USER_PROPERTIES } = require('./config'); -const { TransformationError, InstrumentationError } = require('../../util/errorTypes'); const responseBuilder = async (payload, endpoint, method, accessToken) => { if (payload) { diff --git a/src/v0/destinations/wootric/util.js b/src/v0/destinations/wootric/util.js index 207a0994bb..fce8a66586 100644 --- a/src/v0/destinations/wootric/util.js +++ b/src/v0/destinations/wootric/util.js @@ -1,4 +1,5 @@ const qs = require('qs'); +const { InstrumentationError, NetworkError } = require('@rudderstack/integrations-lib'); const { httpGET, httpPOST } = require('../../../adapters/network'); const { getDynamicErrorType, @@ -8,7 +9,6 @@ const { BASE_ENDPOINT, VERSION, ACCESS_TOKEN_CACHE_TTL_SECONDS } = require('./co const { constructPayload, isDefinedAndNotNullAndNotEmpty } = require('../../util'); const { CONFIG_CATEGORIES, MAPPING_CONFIG } = require('./config'); const Cache = require('../../util/cache'); -const { InstrumentationError, NetworkError } = require('../../util/errorTypes'); const tags = require('../../util/tags'); const { JSON_MIME_TYPE } = require('../../util/constant'); diff --git a/src/v0/destinations/yahoo_dsp/transform.js b/src/v0/destinations/yahoo_dsp/transform.js index 8b0875f1a0..4cd1eee73d 100644 --- a/src/v0/destinations/yahoo_dsp/transform.js +++ b/src/v0/destinations/yahoo_dsp/transform.js @@ -1,3 +1,4 @@ +const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { BASE_ENDPOINT, ENDPOINTS, @@ -12,7 +13,6 @@ const { } = require('../../util'); const { getAccessToken, createPayload } = require('./util'); -const { InstrumentationError } = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); /** diff --git a/src/v0/destinations/yahoo_dsp/util.js b/src/v0/destinations/yahoo_dsp/util.js index a069660bde..d41716935f 100644 --- a/src/v0/destinations/yahoo_dsp/util.js +++ b/src/v0/destinations/yahoo_dsp/util.js @@ -1,12 +1,12 @@ const qs = require('qs'); const sha256 = require('sha256'); +const { InstrumentationError, NetworkError } = require('@rudderstack/integrations-lib'); const { generateJWTToken } = require('../../../util/jwtTokenGenerator'); const { httpSend } = require('../../../adapters/network'); const { isDefinedAndNotNullAndNotEmpty } = require('../../util'); const { getDynamicErrorType } = require('../../../adapters/utils/networkUtils'); const { ACCESS_TOKEN_CACHE_TTL, AUDIENCE_ATTRIBUTE, DSP_SUPPORTED_OPERATION } = require('./config'); const Cache = require('../../util/cache'); -const { InstrumentationError, NetworkError } = require('../../util/errorTypes'); const tags = require('../../util/tags'); const { JSON_MIME_TYPE } = require('../../util/constant'); diff --git a/src/v0/destinations/zendesk/transform.js b/src/v0/destinations/zendesk/transform.js index 869e54c220..bf2bc01ed2 100644 --- a/src/v0/destinations/zendesk/transform.js +++ b/src/v0/destinations/zendesk/transform.js @@ -1,5 +1,10 @@ const get = require('get-value'); const set = require('set-value'); +const { + NetworkInstrumentationError, + InstrumentationError, + NetworkError, +} = require('@rudderstack/integrations-lib'); const myAxios = require('../../../util/myAxios'); const { EventType } = require('../../../constants'); @@ -26,11 +31,6 @@ const { const { getSourceName } = require('./util'); const logger = require('../../../logger'); const { httpGET } = require('../../../adapters/network'); -const { - NetworkInstrumentationError, - InstrumentationError, - NetworkError, -} = require('../../util/errorTypes'); const { getDynamicErrorType } = require('../../../adapters/utils/networkUtils'); const tags = require('../../util/tags'); const { JSON_MIME_TYPE } = require('../../util/constant'); diff --git a/src/v0/destinations/zendesk/util.js b/src/v0/destinations/zendesk/util.js index 0d03f73c19..29f3fc0602 100644 --- a/src/v0/destinations/zendesk/util.js +++ b/src/v0/destinations/zendesk/util.js @@ -1,4 +1,4 @@ -const { ConfigurationError } = require('../../util/errorTypes'); +const { ConfigurationError } = require('@rudderstack/integrations-lib'); /** * Get source name from config or return 'Rudder' as default source name diff --git a/src/v0/sources/appsflyer/transform.js b/src/v0/sources/appsflyer/transform.js index 862e19acd0..1f21392b67 100644 --- a/src/v0/sources/appsflyer/transform.js +++ b/src/v0/sources/appsflyer/transform.js @@ -1,8 +1,8 @@ const path = require('path'); const fs = require('fs'); +const { TransformationError } = require('@rudderstack/integrations-lib'); const Message = require('../message'); const { generateUUID } = require('../../util'); -const { TransformationError } = require('../../util/errorTypes'); const mappingJson = JSON.parse(fs.readFileSync(path.resolve(__dirname, './mapping.json'), 'utf-8')); diff --git a/src/v0/sources/braze/transform.js b/src/v0/sources/braze/transform.js index 34158c8e68..e3d7200023 100644 --- a/src/v0/sources/braze/transform.js +++ b/src/v0/sources/braze/transform.js @@ -2,9 +2,9 @@ const set = require('set-value'); const get = require('get-value'); const path = require('path'); const fs = require('fs'); +const { TransformationError } = require('@rudderstack/integrations-lib'); const { formatTimeStamp, removeUndefinedAndNullValues } = require('../../util'); const Message = require('../message'); -const { TransformationError } = require('../../util/errorTypes'); // import mapping json using JSON.parse to preserve object key order const mapping = JSON.parse(fs.readFileSync(path.resolve(__dirname, './mapping.json'), 'utf-8')); diff --git a/src/v0/sources/canny/transform.js b/src/v0/sources/canny/transform.js index abc6f491b8..9188f5ac34 100644 --- a/src/v0/sources/canny/transform.js +++ b/src/v0/sources/canny/transform.js @@ -1,8 +1,8 @@ const sha256 = require('sha256'); +const { TransformationError } = require('@rudderstack/integrations-lib'); const Message = require('../message'); const { voterMapping, authorMapping, checkForRequiredFields } = require('./util'); const { logger } = require('../../../logger'); -const { TransformationError } = require('../../util/errorTypes'); const CannyOperation = { VOTE_CREATED: 'vote.created', diff --git a/src/v0/sources/canny/util.js b/src/v0/sources/canny/util.js index cd92c0c2af..549b7dcbbc 100644 --- a/src/v0/sources/canny/util.js +++ b/src/v0/sources/canny/util.js @@ -1,6 +1,6 @@ const path = require('path'); const fs = require('fs'); -const { TransformationError } = require('../../util/errorTypes'); +const { TransformationError } = require('@rudderstack/integrations-lib'); // import mapping json using JSON.parse to preserve object key order const voterMapping = JSON.parse( diff --git a/src/v0/sources/customerio/transform.js b/src/v0/sources/customerio/transform.js index 51c353dd3b..a2e69388b9 100644 --- a/src/v0/sources/customerio/transform.js +++ b/src/v0/sources/customerio/transform.js @@ -8,7 +8,6 @@ const Message = require('../message'); const { mappingConfig } = require('./config'); const { isDefinedAndNotNull } = require('../../util'); -// const { TransformationError } = require("../../util/errorTypes"); function process(event) { const message = new Message(`Customer.io`); @@ -35,7 +34,6 @@ function process(event) { message.setProperty('sentAt', validTimestamp); } - // when customer.io does not pass an associated userId, set the email address as anonymousId if ( (message.userId === null || message.userId === undefined) && diff --git a/src/v0/sources/gainsightpx/transform.js b/src/v0/sources/gainsightpx/transform.js index ca91765fa6..92f0a07456 100644 --- a/src/v0/sources/gainsightpx/transform.js +++ b/src/v0/sources/gainsightpx/transform.js @@ -1,4 +1,5 @@ const md5 = require('md5'); +const { TransformationError } = require('@rudderstack/integrations-lib'); const Message = require('../message'); const customMapping = require('./data/customMapping.json'); const identifyMapping = require('./data/identifyMapping.json'); @@ -9,7 +10,6 @@ const surveyMapping = require('./data/surveyMapping.json'); const featureMatchMapping = require('./data/featureMatchMapping.json'); const segmentIoMapping = require('./data/segmentIOMapping.json'); const { refinePayload, refineTraitPayload } = require('./utils'); -const { TransformationError } = require('../../util/errorTypes'); const buildIdentifyPayload = (event) => { let message = new Message(`GAINSIGHTPX`); diff --git a/src/v0/sources/iterable/transform.js b/src/v0/sources/iterable/transform.js index 275051815b..dc3fc72c3c 100644 --- a/src/v0/sources/iterable/transform.js +++ b/src/v0/sources/iterable/transform.js @@ -1,8 +1,8 @@ const path = require('path'); const fs = require('fs'); const md5 = require('md5'); +const { TransformationError } = require('@rudderstack/integrations-lib'); const Message = require('../message'); -const { TransformationError } = require('../../util/errorTypes'); // import mapping json using JSON.parse to preserve object key order const mapping = JSON.parse(fs.readFileSync(path.resolve(__dirname, './mapping.json'), 'utf-8')); diff --git a/src/v0/sources/mailmodo/transform.js b/src/v0/sources/mailmodo/transform.js index 8b36eafa1a..a4383fb440 100644 --- a/src/v0/sources/mailmodo/transform.js +++ b/src/v0/sources/mailmodo/transform.js @@ -1,9 +1,9 @@ const path = require('path'); const fs = require('fs'); const sha256 = require('sha256'); +const { TransformationError } = require('@rudderstack/integrations-lib'); const { flattenJson, removeUndefinedAndNullAndEmptyValues } = require('../../util'); const Message = require('../message'); -const { TransformationError } = require('../../util/errorTypes'); // import mapping json using JSON.parse to preserve object key order const mapping = JSON.parse(fs.readFileSync(path.resolve(__dirname, './mapping.json'), 'utf-8')); diff --git a/src/v0/sources/monday/transform.js b/src/v0/sources/monday/transform.js index 48cddec301..d63323605b 100644 --- a/src/v0/sources/monday/transform.js +++ b/src/v0/sources/monday/transform.js @@ -1,7 +1,7 @@ const sha256 = require('sha256'); +const { TransformationError } = require('@rudderstack/integrations-lib'); const Message = require('../message'); const { mapping, formEventName } = require('./util'); -const { TransformationError } = require('../../util/errorTypes'); const { generateUUID, removeUndefinedAndNullValues } = require('../../util'); const { JSON_MIME_TYPE } = require('../../util/constant'); diff --git a/src/v0/sources/shopify/util.js b/src/v0/sources/shopify/util.js index 2521e9cb9d..1da75cba3d 100644 --- a/src/v0/sources/shopify/util.js +++ b/src/v0/sources/shopify/util.js @@ -2,6 +2,7 @@ /* eslint-disable @typescript-eslint/naming-convention */ const { v5 } = require('uuid'); const sha256 = require('sha256'); +const { TransformationError } = require('@rudderstack/integrations-lib'); const stats = require('../../../util/stats'); const { constructPayload, @@ -22,7 +23,6 @@ const { useRedisDatabase, maxTimeToIdentifyRSGeneratedCall, } = require('./config'); -const { TransformationError } = require('../../util/errorTypes'); const getDataFromRedis = async (key, metricMetadata) => { try { diff --git a/src/v0/util/errorTypes/abortedError.js b/src/v0/util/errorTypes/abortedError.js deleted file mode 100644 index bf5896c8be..0000000000 --- a/src/v0/util/errorTypes/abortedError.js +++ /dev/null @@ -1,15 +0,0 @@ -const tags = require('../tags'); -const { BaseError } = require('./base'); - -class AbortedError extends BaseError { - constructor(message, statusCode, destResponse, authErrorCategory) { - const finalStatTags = { - [tags.TAG_NAMES.ERROR_CATEGORY]: tags.ERROR_CATEGORIES.NETWORK, - [tags.TAG_NAMES.ERROR_TYPE]: tags.ERROR_TYPES.ABORTED, - }; - - super(message, statusCode || 400, finalStatTags, destResponse, authErrorCategory); - } -} - -module.exports = AbortedError; diff --git a/src/v0/util/errorTypes/configurationError.js b/src/v0/util/errorTypes/configurationError.js deleted file mode 100644 index 59df3718e7..0000000000 --- a/src/v0/util/errorTypes/configurationError.js +++ /dev/null @@ -1,16 +0,0 @@ -const tags = require('../tags'); -const { BaseError } = require('./base'); - -class ConfigurationError extends BaseError { - constructor(message) { - const finalStatTags = { - [tags.TAG_NAMES.ERROR_CATEGORY]: tags.ERROR_CATEGORIES.DATA_VALIDATION, - [tags.TAG_NAMES.ERROR_TYPE]: tags.ERROR_TYPES.CONFIGURATION, - }; - - // TODO: Change this to a retryable error - super(message, 400, finalStatTags); - } -} - -module.exports = ConfigurationError; diff --git a/src/v0/util/errorTypes/index.js b/src/v0/util/errorTypes/index.js index 2926306dcd..80268c3e77 100644 --- a/src/v0/util/errorTypes/index.js +++ b/src/v0/util/errorTypes/index.js @@ -1,37 +1,5 @@ -const { BaseError } = require('./base'); -const TransformationError = require('./transformationError'); -const ConfigurationError = require('./configurationError'); -const InstrumentationError = require('./instrumentationError'); -const PlatformError = require('./platformError'); -const OAuthSecretError = require('./oAuthSecretError'); -const NetworkError = require('./networkError'); -const ThrottledError = require('./throttledError'); -const RedisError = require('./redisError'); -const RetryableError = require('./retryableError'); -const InvalidAuthTokenError = require('./invalidAuthTokenError'); -const AbortedError = require('./abortedError'); -const UnhandledStatusCodeError = require('./unhandledStatusCodeError'); -const UnauthorizedError = require('./unauthorizedError'); -const NetworkInstrumentationError = require('./networkInstrumentationError'); -const UnsupportedEventError = require('./unsupportedEventError'); const FilteredEventsError = require('./filteredEventsError'); module.exports = { - BaseError, - TransformationError, - ConfigurationError, - InstrumentationError, - PlatformError, - OAuthSecretError, - NetworkError, - ThrottledError, - RetryableError, - InvalidAuthTokenError, - AbortedError, - UnhandledStatusCodeError, - UnauthorizedError, - NetworkInstrumentationError, - UnsupportedEventError, - RedisError, FilteredEventsError, }; diff --git a/src/v0/util/errorTypes/instrumentationError.js b/src/v0/util/errorTypes/instrumentationError.js deleted file mode 100644 index 74df966260..0000000000 --- a/src/v0/util/errorTypes/instrumentationError.js +++ /dev/null @@ -1,15 +0,0 @@ -const tags = require('../tags'); -const { BaseError } = require('./base'); - -class InstrumentationError extends BaseError { - constructor(message) { - const finalStatTags = { - [tags.TAG_NAMES.ERROR_CATEGORY]: tags.ERROR_CATEGORIES.DATA_VALIDATION, - [tags.TAG_NAMES.ERROR_TYPE]: tags.ERROR_TYPES.INSTRUMENTATION, - }; - - super(message, 400, finalStatTags); - } -} - -module.exports = InstrumentationError; diff --git a/src/v0/util/errorTypes/invalidAuthTokenError.js b/src/v0/util/errorTypes/invalidAuthTokenError.js deleted file mode 100644 index 6a78996c6e..0000000000 --- a/src/v0/util/errorTypes/invalidAuthTokenError.js +++ /dev/null @@ -1,16 +0,0 @@ -const tags = require('../tags'); -const { BaseError } = require('./base'); - -class InvalidAuthTokenError extends BaseError { - constructor(message, statusCode, destResponse, authErrorCategory) { - const finalStatTags = { - [tags.TAG_NAMES.ERROR_CATEGORY]: tags.ERROR_CATEGORIES.NETWORK, - [tags.TAG_NAMES.ERROR_TYPE]: tags.ERROR_TYPES.RETRYABLE, - [tags.TAG_NAMES.META]: tags.METADATA.INVALID_AUTH_TOKEN, - }; - - super(message, statusCode || 500, finalStatTags, destResponse, authErrorCategory); - } -} - -module.exports = InvalidAuthTokenError; diff --git a/src/v0/util/errorTypes/networkError.js b/src/v0/util/errorTypes/networkError.js deleted file mode 100644 index 3461efbbdd..0000000000 --- a/src/v0/util/errorTypes/networkError.js +++ /dev/null @@ -1,29 +0,0 @@ -const tags = require('../tags'); -const { BaseError } = require('./base'); - -const errorTypes = Object.values(tags.ERROR_TYPES); -const metaTypes = Object.values(tags.METADATA); -// To throw error when error type (abort, retry or throttle) has to be dynamically deduced -class NetworkError extends BaseError { - constructor(message, statusCode, statTags, destResponse, authErrorCategory) { - const finalStatTags = { - [tags.TAG_NAMES.ERROR_CATEGORY]: tags.ERROR_CATEGORIES.NETWORK, - [tags.TAG_NAMES.ERROR_TYPE]: tags.ERROR_TYPES.ABORTED, - }; - - // Allow specifying only error type and meta tags - if (statTags && typeof statTags === 'object' && !Array.isArray(statTags)) { - if (errorTypes.includes(statTags[tags.TAG_NAMES.ERROR_TYPE])) { - finalStatTags[tags.TAG_NAMES.ERROR_TYPE] = statTags[tags.TAG_NAMES.ERROR_TYPE]; - } - - if (metaTypes.includes(statTags[tags.TAG_NAMES.META])) { - finalStatTags[tags.TAG_NAMES.META] = statTags[tags.TAG_NAMES.META]; - } - } - - super(message, statusCode || 400, finalStatTags, destResponse, authErrorCategory); - } -} - -module.exports = NetworkError; diff --git a/src/v0/util/errorTypes/networkInstrumentationError.js b/src/v0/util/errorTypes/networkInstrumentationError.js deleted file mode 100644 index fb9acdfeb4..0000000000 --- a/src/v0/util/errorTypes/networkInstrumentationError.js +++ /dev/null @@ -1,16 +0,0 @@ -const tags = require('../tags'); -const { BaseError } = require('./base'); - -class NetworkInstrumentationError extends BaseError { - constructor(message, destResponse) { - const finalStatTags = { - [tags.TAG_NAMES.ERROR_CATEGORY]: tags.ERROR_CATEGORIES.NETWORK, - [tags.TAG_NAMES.ERROR_TYPE]: tags.ERROR_TYPES.ABORTED, - [tags.TAG_NAMES.META]: tags.METADATA.INSTRUMENTATION, - }; - - super(message, 400, finalStatTags, destResponse); - } -} - -module.exports = NetworkInstrumentationError; diff --git a/src/v0/util/errorTypes/oAuthSecretError.js b/src/v0/util/errorTypes/oAuthSecretError.js deleted file mode 100644 index dd8c51eaac..0000000000 --- a/src/v0/util/errorTypes/oAuthSecretError.js +++ /dev/null @@ -1,15 +0,0 @@ -const tags = require('../tags'); -const { BaseError } = require('./base'); - -class OAuthSecretError extends BaseError { - constructor(message) { - const finalStatTags = { - [tags.TAG_NAMES.ERROR_CATEGORY]: tags.ERROR_CATEGORIES.PLATFORM, - [tags.TAG_NAMES.ERROR_TYPE]: tags.ERROR_TYPES.OAUTH_SECRET, - }; - - super(message, 500, finalStatTags); - } -} - -module.exports = OAuthSecretError; diff --git a/src/v0/util/errorTypes/platformError.js b/src/v0/util/errorTypes/platformError.js deleted file mode 100644 index b04ef50c16..0000000000 --- a/src/v0/util/errorTypes/platformError.js +++ /dev/null @@ -1,14 +0,0 @@ -const tags = require('../tags'); -const { BaseError } = require('./base'); - -class PlatformError extends BaseError { - constructor(message) { - const finalStatTags = { - [tags.TAG_NAMES.ERROR_CATEGORY]: tags.ERROR_CATEGORIES.PLATFORM, - }; - - super(message, 400, finalStatTags); - } -} - -module.exports = PlatformError; diff --git a/src/v0/util/errorTypes/redisError.js b/src/v0/util/errorTypes/redisError.js deleted file mode 100644 index ec3d49ff2b..0000000000 --- a/src/v0/util/errorTypes/redisError.js +++ /dev/null @@ -1,15 +0,0 @@ -const tags = require('../tags'); -const { BaseError } = require('./base'); - -class RedisError extends BaseError { - constructor(message, statusCode) { - const finalStatTags = { - [tags.TAG_NAMES.ERROR_CATEGORY]: tags.ERROR_CATEGORIES.TRANSFORMATION, - [tags.TAG_NAMES.ERROR_TYPE]: tags.ERROR_TYPES.REDIS, - }; - - super(message, statusCode || 500, finalStatTags); - } -} - -module.exports = RedisError; diff --git a/src/v0/util/errorTypes/retryableError.js b/src/v0/util/errorTypes/retryableError.js deleted file mode 100644 index ba18424c76..0000000000 --- a/src/v0/util/errorTypes/retryableError.js +++ /dev/null @@ -1,15 +0,0 @@ -const tags = require('../tags'); -const { BaseError } = require('./base'); - -class RetryableError extends BaseError { - constructor(message, statusCode, destResponse, authErrorCategory) { - const finalStatTags = { - [tags.TAG_NAMES.ERROR_CATEGORY]: tags.ERROR_CATEGORIES.NETWORK, - [tags.TAG_NAMES.ERROR_TYPE]: tags.ERROR_TYPES.RETRYABLE, - }; - - super(message, statusCode || 500, finalStatTags, destResponse, authErrorCategory); - } -} - -module.exports = RetryableError; diff --git a/src/v0/util/errorTypes/throttledError.js b/src/v0/util/errorTypes/throttledError.js deleted file mode 100644 index 0e873c7892..0000000000 --- a/src/v0/util/errorTypes/throttledError.js +++ /dev/null @@ -1,15 +0,0 @@ -const tags = require('../tags'); -const { BaseError } = require('./base'); - -class ThrottledError extends BaseError { - constructor(message, destResponse) { - const finalStatTags = { - [tags.TAG_NAMES.ERROR_CATEGORY]: tags.ERROR_CATEGORIES.NETWORK, - [tags.TAG_NAMES.ERROR_TYPE]: tags.ERROR_TYPES.THROTTLED, - }; - - super(message, 429, finalStatTags, destResponse); - } -} - -module.exports = ThrottledError; diff --git a/src/v0/util/errorTypes/transformationError.js b/src/v0/util/errorTypes/transformationError.js deleted file mode 100644 index 0b28b61984..0000000000 --- a/src/v0/util/errorTypes/transformationError.js +++ /dev/null @@ -1,14 +0,0 @@ -const tags = require('../tags'); -const { BaseError } = require('./base'); - -class TransformationError extends BaseError { - constructor(message, statusCode, destResponse, authErrorCategory) { - const finalStatTags = { - [tags.TAG_NAMES.ERROR_CATEGORY]: tags.ERROR_CATEGORIES.TRANSFORMATION, - }; - - super(message, statusCode || 400, finalStatTags, destResponse, authErrorCategory); - } -} - -module.exports = TransformationError; diff --git a/src/v0/util/errorTypes/unauthorizedError.js b/src/v0/util/errorTypes/unauthorizedError.js deleted file mode 100644 index c9c35795b8..0000000000 --- a/src/v0/util/errorTypes/unauthorizedError.js +++ /dev/null @@ -1,16 +0,0 @@ -const tags = require('../tags'); -const { BaseError } = require('./base'); - -class UnauthorizedError extends BaseError { - constructor(message, statusCode, destResponse, authErrorCategory) { - const finalStatTags = { - [tags.TAG_NAMES.ERROR_CATEGORY]: tags.ERROR_CATEGORIES.NETWORK, - [tags.TAG_NAMES.ERROR_TYPE]: tags.ERROR_TYPES.ABORTED, - [tags.TAG_NAMES.META]: tags.METADATA.UNAUTHORIZED, - }; - - super(message, statusCode || 400, finalStatTags, destResponse, authErrorCategory); - } -} - -module.exports = UnauthorizedError; diff --git a/src/v0/util/errorTypes/unhandledStatusCodeError.js b/src/v0/util/errorTypes/unhandledStatusCodeError.js deleted file mode 100644 index fe35c01c1a..0000000000 --- a/src/v0/util/errorTypes/unhandledStatusCodeError.js +++ /dev/null @@ -1,16 +0,0 @@ -const tags = require('../tags'); -const { BaseError } = require('./base'); - -class UnhandledStatusCodeError extends BaseError { - constructor(message, destResponse) { - const finalStatTags = { - [tags.TAG_NAMES.ERROR_CATEGORY]: tags.ERROR_CATEGORIES.NETWORK, - [tags.TAG_NAMES.ERROR_TYPE]: tags.ERROR_TYPES.ABORTED, - [tags.TAG_NAMES.META]: tags.METADATA.UNHANDLED_STATUS_CODE, - }; - - super(message, 400, finalStatTags, destResponse); - } -} - -module.exports = UnhandledStatusCodeError; diff --git a/src/v0/util/errorTypes/unsupportedEventError.js b/src/v0/util/errorTypes/unsupportedEventError.js deleted file mode 100644 index c2e965b620..0000000000 --- a/src/v0/util/errorTypes/unsupportedEventError.js +++ /dev/null @@ -1,14 +0,0 @@ -const tags = require('../tags'); -const { BaseError } = require('./base'); - -class UnsupportedEventError extends BaseError { - constructor(message) { - const finalStatTags = { - [tags.TAG_NAMES.ERROR_CATEGORY]: tags.ERROR_CATEGORIES.PLATFORM, - [tags.TAG_NAMES.ERROR_TYPE]: tags.ERROR_TYPES.UNSUPPORTED, - }; - super(message, 400, finalStatTags); - } -} - -module.exports = UnsupportedEventError; diff --git a/src/v0/util/facebookUtils/index.js b/src/v0/util/facebookUtils/index.js index d39d1c4ce9..4c09518559 100644 --- a/src/v0/util/facebookUtils/index.js +++ b/src/v0/util/facebookUtils/index.js @@ -1,4 +1,5 @@ const sha256 = require('sha256'); +const { InstrumentationError, TransformationError } = require('@rudderstack/integrations-lib'); const { isObject, getIntegrationsObj, @@ -9,7 +10,6 @@ const { getFieldValueFromMessage, formatTimeStamp, } = require('../index'); -const { InstrumentationError, TransformationError } = require('../errorTypes'); /** This function transforms the payloads according to the config settings and adds, removes or hashes pii data. @param message --> the rudder payload diff --git a/src/v0/util/facebookUtils/networkHandler.js b/src/v0/util/facebookUtils/networkHandler.js index 87c2ced2b4..9589d17255 100644 --- a/src/v0/util/facebookUtils/networkHandler.js +++ b/src/v0/util/facebookUtils/networkHandler.js @@ -1,11 +1,11 @@ const { isEmpty } = require('lodash'); const get = require('get-value'); +const { NetworkError } = require('@rudderstack/integrations-lib'); const { processAxiosResponse, getDynamicErrorType, } = require('../../../adapters/utils/networkUtils'); const { prepareProxyRequest, proxyRequest } = require('../../../adapters/network'); -const { NetworkError } = require('../errorTypes'); const tags = require('../tags'); const { ErrorDetailsExtractorBuilder } = require('../../../util/error-extractor'); diff --git a/src/v0/util/index.js b/src/v0/util/index.js index d6f6621220..0296895662 100644 --- a/src/v0/util/index.js +++ b/src/v0/util/index.js @@ -16,16 +16,16 @@ const uaParser = require('ua-parser-js'); const moment = require('moment-timezone'); const sha256 = require('sha256'); const crypto = require('crypto'); -const logger = require('../../logger'); -const stats = require('../../util/stats'); -const { DestCanonicalNames, DestHandlerMap } = require('../../constants/destinationCanonicalNames'); const { InstrumentationError, BaseError, PlatformError, TransformationError, OAuthSecretError, -} = require('./errorTypes'); +} = require('@rudderstack/integrations-lib'); +const logger = require('../../logger'); +const stats = require('../../util/stats'); +const { DestCanonicalNames, DestHandlerMap } = require('../../constants/destinationCanonicalNames'); const { client: errNotificationClient } = require('../../util/errorNotifier'); const { HTTP_STATUS_CODES } = require('./constant'); const { diff --git a/src/v0/util/regulation-api.js b/src/v0/util/regulation-api.js index 8a557858e0..238993ee81 100644 --- a/src/v0/util/regulation-api.js +++ b/src/v0/util/regulation-api.js @@ -1,4 +1,4 @@ -const { PlatformError } = require('./errorTypes'); +const { PlatformError } = require('@rudderstack/integrations-lib'); const RegulationApiUtils = { /** diff --git a/src/warehouse/identity.js b/src/warehouse/identity.js index 4326dddfc6..c34a66a481 100644 --- a/src/warehouse/identity.js +++ b/src/warehouse/identity.js @@ -1,5 +1,5 @@ const _ = require('lodash'); -const { InstrumentationError } = require('../v0/util/errorTypes'); +const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { getVersionedUtils } = require('./util'); const identityEnabledWarehouses = ['snowflake', 'bq']; diff --git a/src/warehouse/index.js b/src/warehouse/index.js index c12239c440..d88904b4a8 100644 --- a/src/warehouse/index.js +++ b/src/warehouse/index.js @@ -25,7 +25,7 @@ const whScreenColumnMappingRules = require('./config/WHScreenConfig.js'); const whGroupColumnMappingRules = require('./config/WHGroupConfig.js'); const whAliasColumnMappingRules = require('./config/WHAliasConfig.js'); const { isDataLakeProvider } = require('./config/helpers'); -const { InstrumentationError } = require('../v0/util/errorTypes'); +const { InstrumentationError } = require('@rudderstack/integrations-lib'); const whExtractEventTableColumnMappingRules = require('./config/WHExtractEventTableConfig.js'); const maxColumnsInEvent = parseInt(process.env.WH_MAX_COLUMNS_IN_EVENT || '200', 10); diff --git a/src/warehouse/util.js b/src/warehouse/util.js index 91b49039f1..79981249e7 100644 --- a/src/warehouse/util.js +++ b/src/warehouse/util.js @@ -3,7 +3,7 @@ const get = require('get-value'); const v0 = require('./v0/util'); const v1 = require('./v1/util'); -const { PlatformError, InstrumentationError } = require('../v0/util/errorTypes'); +const { PlatformError, InstrumentationError } = require('@rudderstack/integrations-lib'); const minTimeInMs = Date.parse('0001-01-01T00:00:00Z'); const maxTimeInMs = Date.parse('9999-12-31T23:59:59.999Z'); diff --git a/src/warehouse/v1/util.js b/src/warehouse/v1/util.js index 8f44a17b8e..1c44a2385e 100644 --- a/src/warehouse/v1/util.js +++ b/src/warehouse/v1/util.js @@ -2,7 +2,7 @@ const _ = require('lodash'); const reservedANSIKeywordsMap = require('../config/ReservedKeywords.json'); const { isDataLakeProvider } = require('../config/helpers'); -const { TransformationError } = require('../../v0/util/errorTypes'); +const { TransformationError } = require('@rudderstack/integrations-lib'); function safeTableName(options, name = '') { const { provider } = options; diff --git a/test/integrations/destinations/pinterest_tag/processor/data.ts b/test/integrations/destinations/pinterest_tag/processor/data.ts index c7f482aadd..045ba53cd1 100644 --- a/test/integrations/destinations/pinterest_tag/processor/data.ts +++ b/test/integrations/destinations/pinterest_tag/processor/data.ts @@ -3474,4 +3474,89 @@ export const data = [ }, }, }, + { + name: 'pinterest_tag', + description: 'Test 26', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + type: 'track', + channel: 'web', + sentAt: '2020-08-14T05:30:30.118Z', + context: { + source: 'test', + userAgent: 'chrome', + traits: { + anonymousId: '50be5c78-6c3f-4b60-be84-97805a316fb1', + email: 'abc@gmail.com', + phone: '+1234589947', + ge: 'male', + db: '19950715', + lastname: 'Rudderlabs', + firstName: 'Test', + address: { city: 'Kolkata', state: 'WB', zip: '700114', country: 'IN' }, + }, + device: { advertisingId: 'abc123' }, + library: { name: 'rudder-sdk-ruby-sync', version: '1.0.6' }, + }, + messageId: '7208bbb6-2c4e-45bb-bf5b-ad426f3593e9', + timestamp: '2020-08-14T05:30:30.118Z', + anonymousId: '50be5c78-6c3f-4b60-be84-97805a316fb1', + integrations: { All: true }, + }, + destination: { + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + ID: '1pYpzzvcn7AQ2W9GGIAZSsN6Mfq', + Name: 'PINTEREST_TAG', + Config: { + sendAsTestEvent: false, + tagId: '123456789', + apiVersion: 'newApi', + adAccountId: 'accountId123', + conversionToken: 'conversionToken123', + appId: '429047995', + enhancedMatch: true, + enableDeduplication: true, + deduplicationKey: 'messageId', + sendingUnHashedData: true, + sendAsCustomEvent: false, + customProperties: [{ properties: 'presentclass' }, { properties: 'presentgrade' }], + eventsMapping: [{ from: 'ABC Searched', to: 'WatchVideo' }], + }, + Enabled: true, + Transformations: [], + }, + metadata: { destintionId: '1pYpzzvcn7AQ2W9GGIAZSsN6Mfq' }, + }, + ], + method: 'POST', + }, + pathSuffix: '', + }, + output: { + response: { + status: 200, + body: [ + { + error: + 'event_name could not be mapped. Aborting.: Workflow: procWorkflow, Step: validateInputForTrack, ChildStep: undefined, OriginalError: event_name could not be mapped. Aborting.', + metadata: { destintionId: '1pYpzzvcn7AQ2W9GGIAZSsN6Mfq' }, + statTags: { + destType: 'PINTEREST_TAG', + errorCategory: 'platform', + feature: 'processor', + implementation: 'cdkV2', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, ]; From dd884ddc78898bd7de155ec4f05ce8fe6e2c4b80 Mon Sep 17 00:00:00 2001 From: Anant Jain <62471433+anantjain45823@users.noreply.github.com> Date: Fri, 10 Nov 2023 12:20:23 +0530 Subject: [PATCH 24/93] fix: update create-hotfix-branch.yml (#2815) Update create-hotfix-branch.yml There is a missing <'> due which we are unable to create a hotfix branch --- .github/workflows/create-hotfix-branch.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/create-hotfix-branch.yml b/.github/workflows/create-hotfix-branch.yml index 97611f1eee..03c79e0df1 100644 --- a/.github/workflows/create-hotfix-branch.yml +++ b/.github/workflows/create-hotfix-branch.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest # Only allow these users to create new hotfix branch from 'main' - if: github.ref == 'refs/heads/main' && (github.actor == 'ItsSudip' || github.actor == 'krishna2020' || github.actor == 'saikumarrs' || github.actor == 'sandeepdsvs' || github.actor == 'shrouti1507' || github.actor == 'anantjain45823' || github.actor == 'chandumlg' || github.actor == 'mihir-4116' || github.actor == 'ujjwal-ab') && (github.triggering_actor == 'ItsSudip' || github.triggering_actor == 'krishna2020' || github.triggering_actor == 'saikumarrs' || github.triggering_actor == 'sandeepdsvs' || github.triggering_actor == 'shrouti1507' || github.triggering_actor == 'anantjain45823' || github.triggering_actor == 'chandumlg' || github.triggering_actor == 'mihir-4116' || github.triggering_actor == 'ujjwal-ab) + if: github.ref == 'refs/heads/main' && (github.actor == 'ItsSudip' || github.actor == 'krishna2020' || github.actor == 'saikumarrs' || github.actor == 'sandeepdsvs' || github.actor == 'shrouti1507' || github.actor == 'anantjain45823' || github.actor == 'chandumlg' || github.actor == 'mihir-4116' || github.actor == 'ujjwal-ab') && (github.triggering_actor == 'ItsSudip' || github.triggering_actor == 'krishna2020' || github.triggering_actor == 'saikumarrs' || github.triggering_actor == 'sandeepdsvs' || github.triggering_actor == 'shrouti1507' || github.triggering_actor == 'anantjain45823' || github.triggering_actor == 'chandumlg' || github.triggering_actor == 'mihir-4116' || github.triggering_actor == 'ujjwal-ab') steps: - name: Create Branch uses: peterjgrainger/action-create-branch@v2.4.0 From 084c6fb6d390d5f4a64f121a79e0cab2abf1c66a Mon Sep 17 00:00:00 2001 From: Anant Jain <62471433+anantjain45823@users.noreply.github.com> Date: Fri, 10 Nov 2023 12:50:24 +0530 Subject: [PATCH 25/93] revert: fix: amplitude page and screen call containg double spaces (#2814) * revert: fix: amplitude page and screen call containg double spaces * chore: fix for undefined names --- src/v0/destinations/am/transform.js | 13 +++---------- test/__tests__/data/am_output.json | 4 ++-- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/src/v0/destinations/am/transform.js b/src/v0/destinations/am/transform.js index 04a1c5a107..48d9d0cd9b 100644 --- a/src/v0/destinations/am/transform.js +++ b/src/v0/destinations/am/transform.js @@ -194,9 +194,9 @@ const handleTraits = (messageTrait, destination) => { const getScreenevTypeAndUpdatedProperties = (message, CATEGORY_KEY) => { const name = message.name || message.event || get(message, CATEGORY_KEY); - const updatedName = name ? `${name} ` : ''; + return { - eventType: `Viewed ${updatedName}Screen`, + eventType: `Viewed ${message.name || message.event || get(message, CATEGORY_KEY) || ''} Screen`, updatedProperties: { ...message.properties, name, @@ -577,8 +577,6 @@ const getGroupInfo = (destination, groupInfo, groupTraits) => { } return groupInfo; }; -const getUpdatedPageNameWithoutUserDefinedPageEventName = (name, message, CATEGORY_KEY) => - name || get(message, CATEGORY_KEY) ? `${name || get(message, CATEGORY_KEY)} ` : undefined; // Generic process function which invokes specific handler functions depending on message type // and event type where applicable @@ -614,12 +612,7 @@ const processSingleMessage = (message, destination) => { .trim() .replaceAll(/{{([^{}]+)}}/g, get(message, getMessagePath)); } else { - const updatedName = getUpdatedPageNameWithoutUserDefinedPageEventName( - name, - message, - CATEGORY_KEY, - ); - evType = `Viewed ${updatedName || ''}Page`; + evType = `Viewed ${name || get(message, CATEGORY_KEY) || ''} Page`; } message.properties = { ...properties, diff --git a/test/__tests__/data/am_output.json b/test/__tests__/data/am_output.json index 34471f4922..ea4b8b908d 100644 --- a/test/__tests__/data/am_output.json +++ b/test/__tests__/data/am_output.json @@ -3944,7 +3944,7 @@ "id": "User Android", "userId": "User Android" }, - "event_type": "Viewed Screen", + "event_type": "Viewed Screen", "user_id": "User Android", "device_brand": "Google", "time": 1662393883250, @@ -4276,7 +4276,7 @@ "app_name": "RudderLabs JavaScript SDK", "app_version": "1.0.0", "language": "en-US", - "event_type": "Viewed Page", + "event_type": "Viewed Page", "event_properties": { "path": "/destinations/amplitude", "referrer": "", From 608a4d520bcc5ef5333bbb05e8d9cf5414150e69 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Fri, 10 Nov 2023 07:22:59 +0000 Subject: [PATCH 26/93] chore(release): 1.49.1 --- CHANGELOG.md | 7 +++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b9256fa915..97a3a2c226 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +### [1.49.1](https://github.com/rudderlabs/rudder-transformer/compare/v1.49.0...v1.49.1) (2023-11-10) + + +### Bug Fixes + +* update create-hotfix-branch.yml ([#2815](https://github.com/rudderlabs/rudder-transformer/issues/2815)) ([dd884dd](https://github.com/rudderlabs/rudder-transformer/commit/dd884ddc78898bd7de155ec4f05ce8fe6e2c4b80)) + ## [1.49.0](https://github.com/rudderlabs/rudder-transformer/compare/v1.48.0...v1.49.0) (2023-11-06) diff --git a/package-lock.json b/package-lock.json index 5e857f6bb9..a73ba099c4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "rudder-transformer", - "version": "1.49.0", + "version": "1.49.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "rudder-transformer", - "version": "1.49.0", + "version": "1.49.1", "license": "ISC", "dependencies": { "@amplitude/ua-parser-js": "^0.7.24", diff --git a/package.json b/package.json index ac0ae2bbeb..130fc840e1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rudder-transformer", - "version": "1.49.0", + "version": "1.49.1", "description": "", "homepage": "https://github.com/rudderlabs/rudder-transformer#readme", "bugs": { From 0996e816d3671c3e25561f76e3219be99225f24b Mon Sep 17 00:00:00 2001 From: Anant Jain <62471433+anantjain45823@users.noreply.github.com> Date: Fri, 10 Nov 2023 14:23:57 +0530 Subject: [PATCH 27/93] feat: introduce v1/source/sourceType endpoint (#2722) * source routing handle * migrate webhook to v1 * using folder structure to fetch varsionMap dynamically * small fix * update feature.json for v1 support boolean * temp commit * chore: comments addressed * chore: add test cases * chore: use map to store source version mapping * chore: resolve conflicts * chore: fix test cases and adressed comments * chore: fix test cases and adressed comments * chore: removed unnecessary types for source * chore: add test case for version v1 for webhook source means no alters in payload --- src/controllers/source.ts | 9 +- src/controllers/util/index.test.ts | 149 ++++++++++++++++++ src/controllers/util/index.ts | 48 ++++++ src/features.json | 3 +- src/types/index.ts | 29 ++++ src/{v0 => v1}/sources/webhook/transform.js | 5 +- .../source/{ => v0}/failure.json | 0 .../source/{ => v0}/response_to_caller.json | 0 .../source/{ => v0}/successful.json | 0 .../data_scenarios/source/v1/failure.json | 27 ++++ .../data_scenarios/source/v1/pipedream.json | 49 ++++++ .../data_scenarios/source/v1/successful.json | 38 +++++ test/apitests/service.api.test.ts | 38 ++++- 13 files changed, 387 insertions(+), 8 deletions(-) create mode 100644 src/controllers/util/index.test.ts rename src/{v0 => v1}/sources/webhook/transform.js (81%) rename test/apitests/data_scenarios/source/{ => v0}/failure.json (100%) rename test/apitests/data_scenarios/source/{ => v0}/response_to_caller.json (100%) rename test/apitests/data_scenarios/source/{ => v0}/successful.json (100%) create mode 100644 test/apitests/data_scenarios/source/v1/failure.json create mode 100644 test/apitests/data_scenarios/source/v1/pipedream.json create mode 100644 test/apitests/data_scenarios/source/v1/successful.json diff --git a/src/controllers/source.ts b/src/controllers/source.ts index efb6dc746e..b1e7e8fe12 100644 --- a/src/controllers/source.ts +++ b/src/controllers/source.ts @@ -16,10 +16,15 @@ export default class SourceController { const { version, source }: { version: string; source: string } = ctx.params; const integrationService = ServiceSelector.getNativeSourceService(); try { - const resplist = await integrationService.sourceTransformRoutine( - events, + const { implementationVersion, input } = ControllerUtility.adaptInputToVersion( source, version, + events, + ); + const resplist = await integrationService.sourceTransformRoutine( + input, + source, + implementationVersion, requestMetadata, ); ctx.body = resplist; diff --git a/src/controllers/util/index.test.ts b/src/controllers/util/index.test.ts new file mode 100644 index 0000000000..0bc5f174b0 --- /dev/null +++ b/src/controllers/util/index.test.ts @@ -0,0 +1,149 @@ +import ControllerUtility from './index'; + +describe('adaptInputToVersion', () => { + it('should return the input unchanged when the implementation version is not found', () => { + const sourceType = 'NA_SOURCE'; + const requestVersion = 'v0'; + const input = [ + { key1: 'val1', key2: 'val2' }, + { key1: 'val1', key2: 'val2' }, + { key1: 'val1', key2: 'val2' }, + ]; + const expected = { + implementationVersion: undefined, + input: [ + { key1: 'val1', key2: 'val2' }, + { key1: 'val1', key2: 'val2' }, + { key1: 'val1', key2: 'val2' }, + ], + }; + + const result = ControllerUtility.adaptInputToVersion(sourceType, requestVersion, input); + + expect(result).toEqual(expected); + }); + it('should return the input unchanged when the implementation version and request version are the same i.e. v0', () => { + const sourceType = 'pipedream'; + const requestVersion = 'v0'; + const input = [ + { key1: 'val1', key2: 'val2' }, + { key1: 'val1', key2: 'val2' }, + { key1: 'val1', key2: 'val2' }, + ]; + const expected = { + implementationVersion: 'v0', + input: [ + { key1: 'val1', key2: 'val2' }, + { key1: 'val1', key2: 'val2' }, + { key1: 'val1', key2: 'val2' }, + ], + }; + + const result = ControllerUtility.adaptInputToVersion(sourceType, requestVersion, input); + + expect(result).toEqual(expected); + }); + it('should return the input unchanged when the implementation version and request version are the same i.e. v1', () => { + const sourceType = 'webhook'; + const requestVersion = 'v1'; + const input = [ + { + event: { key1: 'val1', key2: 'val2' }, + source: { id: 'source_id', config: { configField1: 'configVal1' } }, + }, + { + event: { key1: 'val1', key2: 'val2' }, + source: { id: 'source_id', config: { configField1: 'configVal1' } }, + }, + { + event: { key1: 'val1', key2: 'val2' }, + source: { id: 'source_id', config: { configField1: 'configVal1' } }, + }, + ]; + const expected = { + implementationVersion: 'v1', + input: [ + { + event: { key1: 'val1', key2: 'val2' }, + source: { id: 'source_id', config: { configField1: 'configVal1' } }, + }, + { + event: { key1: 'val1', key2: 'val2' }, + source: { id: 'source_id', config: { configField1: 'configVal1' } }, + }, + { + event: { key1: 'val1', key2: 'val2' }, + source: { id: 'source_id', config: { configField1: 'configVal1' } }, + }, + ], + }; + + const result = ControllerUtility.adaptInputToVersion(sourceType, requestVersion, input); + + expect(result).toEqual(expected); + }); + it('should convert input from v0 to v1 when the request version is v0 and the implementation version is v1', () => { + const sourceType = 'webhook'; + const requestVersion = 'v0'; + const input = [ + { key1: 'val1', key2: 'val2' }, + { key1: 'val1', key2: 'val2' }, + { key1: 'val1', key2: 'val2' }, + ]; + const expected = { + implementationVersion: 'v1', + input: [ + { event: { key1: 'val1', key2: 'val2' }, source: undefined }, + { event: { key1: 'val1', key2: 'val2' }, source: undefined }, + { event: { key1: 'val1', key2: 'val2' }, source: undefined }, + ], + }; + + const result = ControllerUtility.adaptInputToVersion(sourceType, requestVersion, input); + + expect(result).toEqual(expected); + }); + + it('should convert input from v1 to v0 format when the request version is v1 and the implementation version is v0', () => { + const sourceType = 'pipedream'; + const requestVersion = 'v1'; + const input = [ + { + event: { key1: 'val1', key2: 'val2' }, + source: { id: 'source_id', config: { configField1: 'configVal1' } }, + }, + { + event: { key1: 'val1', key2: 'val2' }, + source: { id: 'source_id', config: { configField1: 'configVal1' } }, + }, + { + event: { key1: 'val1', key2: 'val2' }, + source: { id: 'source_id', config: { configField1: 'configVal1' } }, + }, + ]; + const expected = { + implementationVersion: 'v0', + input: [ + { key1: 'val1', key2: 'val2' }, + { key1: 'val1', key2: 'val2' }, + { key1: 'val1', key2: 'val2' }, + ], + }; + + const result = ControllerUtility.adaptInputToVersion(sourceType, requestVersion, input); + + expect(result).toEqual(expected); + }); + + // Should return an empty array when the input is an empty array + it('should return an empty array when the input is an empty array', () => { + const sourceType = 'pipedream'; + const requestVersion = 'v1'; + const input = []; + const expected = { implementationVersion: 'v0', input: [] }; + + const result = ControllerUtility.adaptInputToVersion(sourceType, requestVersion, input); + + expect(result).toEqual(expected); + }); +}); diff --git a/src/controllers/util/index.ts b/src/controllers/util/index.ts index e2071968d7..c52eb6899e 100644 --- a/src/controllers/util/index.ts +++ b/src/controllers/util/index.ts @@ -1,3 +1,5 @@ +import fs = require('fs'); +import path = require('path'); import { Context } from 'koa'; import isEmpty from 'lodash/isEmpty'; import get from 'get-value'; @@ -7,12 +9,15 @@ import { ProcessorTransformationRequest, RouterTransformationRequestData, RudderMessage, + SourceInput, } from '../../types'; import { getValueFromMessage } from '../../v0/util'; import genericFieldMap from '../../v0/util/data/GenericFieldMapping.json'; import { EventType, MappedToDestinationKey } from '../../constants'; export default class ControllerUtility { + private static sourceVersionMap: Map = new Map(); + public static timestampValsMap: Record = { [EventType.IDENTIFY]: [ `context.${RETL_TIMESTAMP}`, @@ -23,6 +28,49 @@ export default class ControllerUtility { [EventType.TRACK]: [`properties.${RETL_TIMESTAMP}`, ...genericFieldMap.timestamp], }; + private static getSourceVersionsMap(): Map { + if (this.sourceVersionMap?.size > 0) { + return this.sourceVersionMap; + } + const versions = ['v0', 'v1']; + versions.forEach((version) => { + const files = fs.readdirSync(path.resolve(__dirname, `../../${version}/sources`), { + withFileTypes: true, + }); + const sources = files.filter((file) => file.isDirectory()).map((folder) => folder.name); + sources.forEach((source) => { + this.sourceVersionMap.set(source, version); + }); + }); + return this.sourceVersionMap; + } + + private static convertSourceInputv1Tov0(sourceEvents: SourceInput[]): NonNullable[] { + return sourceEvents.map((sourceEvent) => sourceEvent.event); + } + + private static convertSourceInputv0Tov1(sourceEvents: unknown[]): SourceInput[] { + return sourceEvents.map( + (sourceEvent) => ({ event: sourceEvent, source: undefined } as SourceInput), + ); + } + + public static adaptInputToVersion( + sourceType: string, + requestVersion: string, + input: NonNullable[], + ): { implementationVersion: string; input: NonNullable[] } { + const sourceToVersionMap = this.getSourceVersionsMap(); + const implementationVersion = sourceToVersionMap.get(sourceType); + let updatedInput: NonNullable[] = input; + if (requestVersion === 'v0' && implementationVersion === 'v1') { + updatedInput = this.convertSourceInputv0Tov1(input); + } else if (requestVersion === 'v1' && implementationVersion === 'v0') { + updatedInput = this.convertSourceInputv1Tov0(input as SourceInput[]); + } + return { implementationVersion, input: updatedInput }; + } + private static getCompatibleStatusCode(status: number): number { return getCompatibleStatusCode(status); } diff --git a/src/features.json b/src/features.json index 9793f667e3..d3ea3e98a6 100644 --- a/src/features.json +++ b/src/features.json @@ -61,5 +61,6 @@ "ORTTO": true, "ONE_SIGNAL": true, "TIKTOK_AUDIENCE": true - } + }, + "supportSourceTransformV1": true } diff --git a/src/types/index.ts b/src/types/index.ts index 79efaecb40..9292fe2cc2 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -224,7 +224,34 @@ type ComparatorInput = { requestMetadata: object; feature: string; }; +type SourceDefinition = { + ID: string; + Name: string; + Category: string; + Type: string; +}; + +type Source = { + ID: string; + OriginalID: string; + Name: string; + SourceDefinition: SourceDefinition; + Config: object; + Enabled: boolean; + WorkspaceID: string; + WriteKey: string; + Transformations?: UserTransformationInput[]; + RevisionID?: string; + Destinations?: Destination[]; + Transient: boolean; + EventSchemasEnabled: boolean; + DgSourceTrackingPlanConfig: object; +}; +type SourceInput = { + event: NonNullable[]; + source?: Source; +}; export { Metadata, MessageIdMetadataMap, @@ -246,4 +273,6 @@ export { UserDeletionResponse, Destination, ComparatorInput, + SourceInput, + Source, }; diff --git a/src/v0/sources/webhook/transform.js b/src/v1/sources/webhook/transform.js similarity index 81% rename from src/v0/sources/webhook/transform.js rename to src/v1/sources/webhook/transform.js index 3a756ef63b..fc13424b8a 100644 --- a/src/v0/sources/webhook/transform.js +++ b/src/v1/sources/webhook/transform.js @@ -1,4 +1,4 @@ -const { removeUndefinedAndNullValues, generateUUID } = require('../../util'); +const { removeUndefinedAndNullValues, generateUUID } = require('../../../v0/util'); function processEvent(event) { const payload = { @@ -10,7 +10,8 @@ function processEvent(event) { return payload; } -function process(event) { +function process(inputEvent) { + const { event } = inputEvent; const response = processEvent(event); return removeUndefinedAndNullValues(response); } diff --git a/test/apitests/data_scenarios/source/failure.json b/test/apitests/data_scenarios/source/v0/failure.json similarity index 100% rename from test/apitests/data_scenarios/source/failure.json rename to test/apitests/data_scenarios/source/v0/failure.json diff --git a/test/apitests/data_scenarios/source/response_to_caller.json b/test/apitests/data_scenarios/source/v0/response_to_caller.json similarity index 100% rename from test/apitests/data_scenarios/source/response_to_caller.json rename to test/apitests/data_scenarios/source/v0/response_to_caller.json diff --git a/test/apitests/data_scenarios/source/successful.json b/test/apitests/data_scenarios/source/v0/successful.json similarity index 100% rename from test/apitests/data_scenarios/source/successful.json rename to test/apitests/data_scenarios/source/v0/successful.json diff --git a/test/apitests/data_scenarios/source/v1/failure.json b/test/apitests/data_scenarios/source/v1/failure.json new file mode 100644 index 0000000000..9bf77f9b53 --- /dev/null +++ b/test/apitests/data_scenarios/source/v1/failure.json @@ -0,0 +1,27 @@ +{ + "input": [ + { + "event": { + "anonymousId": "63767499ca6fb1b7c988d5bb", + "artist": "Gautam", + "genre": "Jazz", + "song": "Take Five" + }, + "source": { + "id": "source_id", + "config": { + "configField1": "configVal1" + } + } + } + ], + "output": [ + { + "statusCode": 500, + "error": "Cannot find module '../undefined/sources/NA_SOURCE/transform' from 'src/services/misc.ts'", + "statTags": { + "errorCategory": "transformation" + } + } + ] +} diff --git a/test/apitests/data_scenarios/source/v1/pipedream.json b/test/apitests/data_scenarios/source/v1/pipedream.json new file mode 100644 index 0000000000..4219f3f6b1 --- /dev/null +++ b/test/apitests/data_scenarios/source/v1/pipedream.json @@ -0,0 +1,49 @@ +{ + "input": [ + { + "event": { + "anonymousId": "63767499ca6fb1b7c988d5bb", + "artist": "Gautam", + "genre": "Jazz", + "song": "Take Five" + }, + "source": { + "id": "source_id", + "config": { + "configField1": "configVal1" + } + } + } + ], + "output": [ + { + "output": { + "batch": [ + { + "event": "pipedream_source_event", + "anonymousId": "63767499ca6fb1b7c988d5bb", + "context": { + "integration": { + "name": "PIPEDREAM" + }, + "library": { + "name": "unknown", + "version": "unknown" + } + }, + "integrations": { + "PIPEDREAM": false + }, + "type": "track", + "properties": { + "anonymousId": "63767499ca6fb1b7c988d5bb", + "artist": "Gautam", + "genre": "Jazz", + "song": "Take Five" + } + } + ] + } + } + ] +} \ No newline at end of file diff --git a/test/apitests/data_scenarios/source/v1/successful.json b/test/apitests/data_scenarios/source/v1/successful.json new file mode 100644 index 0000000000..c42d723800 --- /dev/null +++ b/test/apitests/data_scenarios/source/v1/successful.json @@ -0,0 +1,38 @@ +{ + "input": [ + { + "event": { + "event": "Fulfillments Update", + "data": { + "fulfillment_id": "1234567890", + "status": "pending" + } + }, + "source": { + "id": "source_id", + "config": { + "configField1": "configVal1" + } + } + } + ], + "output": [ + { + "output": { + "batch": [ + { + "type": "track", + "event": "webhook_source_event", + "properties": { + "event": "Fulfillments Update", + "data": { + "fulfillment_id": "1234567890", + "status": "pending" + } + } + } + ] + } + } + ] +} diff --git a/test/apitests/service.api.test.ts b/test/apitests/service.api.test.ts index dfe7e10dd6..ee534d7b37 100644 --- a/test/apitests/service.api.test.ts +++ b/test/apitests/service.api.test.ts @@ -177,7 +177,7 @@ describe('Destination api tests', () => { describe('Source api tests', () => { test('(shopify) successful source transform', async () => { - const data = getDataFromPath('./data_scenarios/source/successful.json'); + const data = getDataFromPath('./data_scenarios/source/v0/successful.json'); const response = await request(server) .post('/v0/sources/shopify') .set('Accept', 'application/json') @@ -189,7 +189,7 @@ describe('Source api tests', () => { }); test('(shopify) failure source transform (shopify)', async () => { - const data = getDataFromPath('./data_scenarios/source/failure.json'); + const data = getDataFromPath('./data_scenarios/source/v0/failure.json'); const response = await request(server) .post('/v0/sources/shopify') .set('Accept', 'application/json') @@ -199,7 +199,7 @@ describe('Source api tests', () => { }); test('(shopify) success source transform (monday)', async () => { - const data = getDataFromPath('./data_scenarios/source/response_to_caller.json'); + const data = getDataFromPath('./data_scenarios/source/v0/response_to_caller.json'); const response = await request(server) .post('/v0/sources/monday') .set('Accept', 'application/json') @@ -207,6 +207,38 @@ describe('Source api tests', () => { expect(response.status).toEqual(200); expect(JSON.parse(response.text)).toEqual(data.output); }); + + test('(webhook) successful source transform for source present in v1 and server providing v0 endpoint', async () => { + const data = getDataFromPath('./data_scenarios/source/v1/successful.json'); + const response = await request(server) + .post('/v1/sources/webhook') + .set('Accept', 'application/json') + .send(data.input); + const parsedResp = JSON.parse(response.text); + delete parsedResp[0].output.batch[0].anonymousId; + expect(response.status).toEqual(200); + expect(parsedResp).toEqual(data.output); + }); + + test('(NA_SOURCE) failure source transform ', async () => { + const data = getDataFromPath('./data_scenarios/source/v1/failure.json'); + const response = await request(server) + .post('/v0/sources/NA_SOURCE') + .set('Accept', 'application/json') + .send(data.input); + expect(response.status).toEqual(200); + expect(JSON.parse(response.text)).toEqual(data.output); + }); + + test('(pipedream) success source transform for source present in v0 and server providing v1 endpoint', async () => { + const data = getDataFromPath('./data_scenarios/source/v1/pipedream.json'); + const response = await request(server) + .post('/v1/sources/pipedream') + .set('Accept', 'application/json') + .send(data.input); + expect(response.status).toEqual(200); + expect(JSON.parse(response.text)).toEqual(data.output); + }); }); describe('CDK V1 api tests', () => { From 42bec546cc9159a8cc496a7b01a08a9171c02aff Mon Sep 17 00:00:00 2001 From: Gauravudia <60897972+Gauravudia@users.noreply.github.com> Date: Fri, 10 Nov 2023 15:46:08 +0530 Subject: [PATCH 28/93] chore: add error import from lib for missing integrations (#2818) --- src/legacy/router.js | 2 +- src/v0/destinations/facebook_conversions/transform.js | 3 +-- src/v0/destinations/facebook_conversions/utils.js | 2 +- src/v0/sources/appcenter/transform.js | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/legacy/router.js b/src/legacy/router.js index 99fb8570fb..f8deb3fe62 100644 --- a/src/legacy/router.js +++ b/src/legacy/router.js @@ -7,6 +7,7 @@ const Router = require('@koa/router'); const lodash = require('lodash'); const fs = require('fs'); const path = require('path'); +const { PlatformError } = require('@rudderstack/integrations-lib'); const logger = require('../logger'); const stats = require('../util/stats'); const { SUPPORTED_VERSIONS, API_VERSION } = require('../routes/utils/constants'); @@ -35,7 +36,6 @@ const { sendViolationMetrics, constructValidationErrors, } = require('../util/utils'); -const { PlatformError } = require('../v0/util/errorTypes'); const { processCdkV1 } = require('../cdk/v1/handler'); const { extractLibraries } = require('../util/customTransformer'); const { getCompatibleStatusCode } = require('../adapters/utils/networkUtils'); diff --git a/src/v0/destinations/facebook_conversions/transform.js b/src/v0/destinations/facebook_conversions/transform.js index dec1ef2e6c..cf11795605 100644 --- a/src/v0/destinations/facebook_conversions/transform.js +++ b/src/v0/destinations/facebook_conversions/transform.js @@ -1,6 +1,7 @@ /* eslint-disable no-param-reassign */ const get = require('get-value'); const moment = require('moment'); +const { InstrumentationError, ConfigurationError } = require('@rudderstack/integrations-lib'); const { CONFIG_CATEGORIES, MAPPING_CONFIG, @@ -34,8 +35,6 @@ const { formingFinalResponse, } = require('../../util/facebookUtils'); -const { InstrumentationError, ConfigurationError } = require('../../util/errorTypes'); - const responseBuilderSimple = (message, category, destination) => { const { Config, ID } = destination; let { categoryToContent } = Config; diff --git a/src/v0/destinations/facebook_conversions/utils.js b/src/v0/destinations/facebook_conversions/utils.js index 270fac8c45..32fafae3d0 100644 --- a/src/v0/destinations/facebook_conversions/utils.js +++ b/src/v0/destinations/facebook_conversions/utils.js @@ -1,3 +1,4 @@ +const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { CONFIG_CATEGORIES, OTHER_STANDARD_EVENTS, @@ -8,7 +9,6 @@ const { } = require('./config'); const { constructPayload, isObject, isAppleFamily } = require('../../util'); const { getContentType, getContentCategory } = require('../../util/facebookUtils'); -const { InstrumentationError } = require('../../util/errorTypes'); const getActionSource = (payload, fallbackActionSource) => { let actionSource = fallbackActionSource; diff --git a/src/v0/sources/appcenter/transform.js b/src/v0/sources/appcenter/transform.js index 3a98a6db3e..40399d92e2 100644 --- a/src/v0/sources/appcenter/transform.js +++ b/src/v0/sources/appcenter/transform.js @@ -1,5 +1,6 @@ const path = require('path'); const fs = require('fs'); +const { TransformationError } = require('@rudderstack/integrations-lib'); const { generateUUID } = require('../../util'); const Message = require('../message'); @@ -7,7 +8,6 @@ const mappingJson = JSON.parse(fs.readFileSync(path.resolve(__dirname, './mappin const { removeUndefinedAndNullValues } = require('../../util'); -const { TransformationError } = require('../../util/errorTypes'); const { JSON_MIME_TYPE } = require('../../util/constant'); const processNormalEvent = (event) => { From 0e1429663d167a2c5cded0d9130374eb586a18c0 Mon Sep 17 00:00:00 2001 From: Ujjwal Abhishek <63387036+ujjwal-ab@users.noreply.github.com> Date: Fri, 10 Nov 2023 20:19:52 +0530 Subject: [PATCH 29/93] feat: add clickId support for tiktok and pinterest destination (#2784) * feat: add clickId support for tiktok * feat: add clickId support for pinterest * chore: add clickId in tests * chore: correct mapping for tiktok * chore: remove instances of callback in input * fix: add clickId in tests * fix: revert context.page mapping --- .../pinterest_tag/procWorkflow.yaml | 8 +- .../tiktok_ads/data/TikTokTrack.json | 5 + .../pinterest_tag/processor/data.ts | 2 + .../destinations/tiktok_ads/processor/data.ts | 9351 ++++++++--------- .../destinations/tiktok_ads/router/data.ts | 30 +- 5 files changed, 4675 insertions(+), 4721 deletions(-) diff --git a/src/cdk/v2/destinations/pinterest_tag/procWorkflow.yaml b/src/cdk/v2/destinations/pinterest_tag/procWorkflow.yaml index e0b81e0afe..7bcb804126 100644 --- a/src/cdk/v2/destinations/pinterest_tag/procWorkflow.yaml +++ b/src/cdk/v2/destinations/pinterest_tag/procWorkflow.yaml @@ -100,7 +100,8 @@ steps: "hashed_maids": .context.device.advertisingId, "client_ip_address": .context.ip ?? .request_ip, "client_user_agent": .context.userAgent, - "external_id": {{{{$.getGenericPaths("userId")}}}} + "external_id": {{{{$.getGenericPaths("userId")}}}}, + "click_id": .properties.clickId }); !.destination.Config.sendExternalId ? userFields = userFields{~["external_id"]} : null; userFields = $.removeUndefinedAndNullAndEmptyValues(userFields); @@ -185,14 +186,13 @@ steps: - name: payload template: | $.outputs.eventNames.().({...$.outputs.basePayload, event_name: .})[] - + - name: checkSendTestEventConfig description: | If sendTestEvent is enabled, we send test event to the destination ref: https://help.pinterest.com/en/business/article/track-conversions-with-the-conversions-api template: | - ^.destination.Config.sendAsTestEvent ? {"test": true} : {} - + ^.destination.Config.sendAsTestEvent ? {"test": true} : {} - name: buildResponseForBatchMode description: In batchMode we return payload directly diff --git a/src/v0/destinations/tiktok_ads/data/TikTokTrack.json b/src/v0/destinations/tiktok_ads/data/TikTokTrack.json index b15223b999..cc5f4886e0 100644 --- a/src/v0/destinations/tiktok_ads/data/TikTokTrack.json +++ b/src/v0/destinations/tiktok_ads/data/TikTokTrack.json @@ -72,6 +72,11 @@ "sourceKeys": ["properties.context.ad", "context.ad"], "required": false }, + { + "destKey": "context.ad.callback", + "sourceKeys": "properties.clickId", + "required": false + }, { "destKey": "context.page", "sourceKeys": ["properties.context.page", "context.page"], diff --git a/test/integrations/destinations/pinterest_tag/processor/data.ts b/test/integrations/destinations/pinterest_tag/processor/data.ts index 045ba53cd1..2887ee8cb9 100644 --- a/test/integrations/destinations/pinterest_tag/processor/data.ts +++ b/test/integrations/destinations/pinterest_tag/processor/data.ts @@ -44,6 +44,7 @@ export const data = [ order_id: '50314b8e9bcf000000000000', requestIP: '123.0.0.0', optOutType: 'LDP', + clickId: 'dummy_clickId', products: [ { sku: '45790-32', @@ -132,6 +133,7 @@ export const data = [ '6ca13d52ca70c883e0f0bb101e425a89e8624de51db2d2392593af6a84118090', ], client_user_agent: 'chrome', + click_id: 'dummy_clickId', ge: ['1b16b1df538ba12dc3f97edbb85caa7050d46c148134290feba80f8236c83db9'], }, custom_data: { diff --git a/test/integrations/destinations/tiktok_ads/processor/data.ts b/test/integrations/destinations/tiktok_ads/processor/data.ts index 38fec1e1e0..453a875af2 100644 --- a/test/integrations/destinations/tiktok_ads/processor/data.ts +++ b/test/integrations/destinations/tiktok_ads/processor/data.ts @@ -1,4690 +1,4663 @@ export const data = [ - { - "name": "tiktok_ads", - "description": "Test 0", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "anonymousId": "21e13f4bc7ceddad", - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion", - "ip": "13.57.97.131", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - }, - "externalId": [ - { - "type": "tiktokExternalId", - "id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - } - ] - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "timestamp": "2020-09-17T19:49:27Z", - "type": "track", - "event": "checkout step completed", - "properties": { - "eventId": "1616318632825_357", - "contents": [ - { - "price": 8, - "quantity": 2, - "content_type": "socks", - "content_id": "1077218" - }, - { - "price": 30, - "quantity": 1, - "content_type": "dress", - "content_id": "1197218" - } - ], - "currency": "USD", - "value": 46, - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea", - "email": "dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f" - } - } - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - }, - "destination": { - "Config": { - "accessToken": "dummyAccessToken", - "pixelCode": "A1T8T4UYGVIQA8ORZMX9", - "hashUserProperties": false - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://business-api.tiktok.com/open_api/v1.3/pixel/track/", - "headers": { - "Access-Token": "dummyAccessToken", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "pixel_code": "A1T8T4UYGVIQA8ORZMX9", - "event": "CompletePayment", - "event_id": "1616318632825_357", - "timestamp": "2020-09-17T19:49:27Z", - "properties": { - "contents": [ - { - "price": 8, - "quantity": 2, - "content_type": "socks", - "content_id": "1077218" - }, - { - "price": 30, - "quantity": 1, - "content_type": "dress", - "content_id": "1197218" - } - ], - "currency": "USD", - "value": 46 - }, - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea", - "email": "dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f", - "external_id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - }, - "ip": "13.57.97.131", - "user_agent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion" - }, - "partner_name": "RudderStack" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "tiktok_ads", - "description": "Test 1", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "anonymousId": "21e13f4bc7ceddad", - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion", - "locale": "en-US", - "ip": "13.57.97.131", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - }, - "externalId": [ - { - "type": "tiktokExternalId", - "id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - } - ] - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "timestamp": "2020-09-17T19:49:27Z", - "type": "track", - "event": "checkout started", - "properties": { - "eventId": "1616318632825_357", - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea", - "email": "dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f" - } - }, - "contents": [ - { - "price": 8, - "quantity": 2, - "content_type": "socks", - "content_id": "1077218" - }, - { - "price": 30, - "quantity": 1, - "content_type": "dress", - "content_id": "1197218" - } - ], - "currency": "USD", - "value": 46 - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - }, - "destination": { - "Config": { - "accessToken": "dummyAccessToken", - "pixelCode": "A1T8T4UYGVIQA8ORZMX9", - "hashUserProperties": false - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://business-api.tiktok.com/open_api/v1.3/pixel/track/", - "headers": { - "Access-Token": "dummyAccessToken", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "pixel_code": "A1T8T4UYGVIQA8ORZMX9", - "event": "InitiateCheckout", - "event_id": "1616318632825_357", - "timestamp": "2020-09-17T19:49:27Z", - "properties": { - "contents": [ - { - "price": 8, - "quantity": 2, - "content_type": "socks", - "content_id": "1077218" - }, - { - "price": 30, - "quantity": 1, - "content_type": "dress", - "content_id": "1197218" - } - ], - "currency": "USD", - "value": 46 - }, - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea", - "email": "dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f", - "external_id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - }, - "ip": "13.57.97.131", - "user_agent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion" - }, - "partner_name": "RudderStack" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "tiktok_ads", - "description": "Test 2", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "anonymousId": "21e13f4bc7ceddad", - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - }, - "externalId": [ - { - "type": "tiktokExternalId", - "id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - } - ] - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "timestamp": "2020-09-17T19:49:27Z", - "type": "track", - "event": "Product Added to Wishlist", - "properties": { - "eventId": "1616318632825_357", - "testEventCode": "sample rudder test_event_code", - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea", - "email": "dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f" - } - }, - "contents": [ - { - "price": 8, - "quantity": 2, - "content_type": "socks", - "content_id": "1077218" - }, - { - "price": 30, - "quantity": 1, - "content_type": "dress", - "content_id": "1197218" - } - ], - "currency": "USD", - "value": 46 - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - }, - "destination": { - "Config": { - "accessToken": "dummyAccessToken", - "pixelCode": "A1T8T4UYGVIQA8ORZMX9", - "hashUserProperties": false - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://business-api.tiktok.com/open_api/v1.3/pixel/track/", - "headers": { - "Access-Token": "dummyAccessToken", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "pixel_code": "A1T8T4UYGVIQA8ORZMX9", - "event": "AddToWishlist", - "event_id": "1616318632825_357", - "timestamp": "2020-09-17T19:49:27Z", - "test_event_code": "sample rudder test_event_code", - "properties": { - "contents": [ - { - "price": 8, - "quantity": 2, - "content_type": "socks", - "content_id": "1077218" - }, - { - "price": 30, - "quantity": 1, - "content_type": "dress", - "content_id": "1197218" - } - ], - "currency": "USD", - "value": 46 - }, - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea", - "email": "dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f", - "external_id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - } - }, - "partner_name": "RudderStack" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "tiktok_ads", - "description": "Test 3", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "anonymousId": "21e13f4bc7ceddad", - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion", - "locale": "en-US", - "ip": "13.57.97.131", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - }, - "externalId": [ - { - "type": "tiktokExternalId", - "id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - } - ] - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "timestamp": "2020-09-17T19:49:27Z", - "type": "track", - "event": "Product Added to Wishlist1", - "properties": { - "eventId": "1616318632825_357", - "testEventCode": "sample rudder test_event_code", - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea", - "email": "dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f" - } - }, - "contents": [ - { - "price": 8, - "quantity": 2, - "content_type": "socks", - "content_id": "1077218" - }, - { - "price": 30, - "quantity": 1, - "content_type": "dress", - "content_id": "1197218" - } - ], - "currency": "USD", - "value": 46 - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - }, - "destination": { - "Config": { - "accessToken": "dummyAccessToken", - "pixelCode": "A1T8T4UYGVIQA8ORZMX9", - "hashUserProperties": false - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "statusCode": 400, - "error": "Event name (product added to wishlist1) is not valid, must be mapped to one of standard events", - "statTags": { - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "destType": "TIKTOK_ADS", - "module": "destination", - "implementation": "native", - "feature": "processor" - } - } - ] - } - } - }, - { - "name": "tiktok_ads", - "description": "Test 4", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "anonymousId": "21e13f4bc7ceddad", - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion", - "locale": "en-US", - "ip": "13.57.97.131", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - }, - "externalId": [ - { - "type": "tiktokExternalId", - "id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - } - ] - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "timestamp": "2020-09-17T19:49:27Z", - "type": "track", - "event": "Product Added to Wishlist", - "properties": { - "eventId": "1616318632825_357", - "testEventCode": "sample rudder test_event_code", - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea", - "email": "dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f" - } - }, - "contents": [ - { - "price": 8, - "quantity": 2, - "content_type": "socks", - "content_id": "1077218" - }, - { - "price": 30, - "quantity": 1, - "content_type": "dress", - "content_id": "1197218" - } - ], - "currency": "USD", - "value": 46 - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - }, - "destination": { - "Config": { - "accessToken": "dummyAccessToken", - "pixelCode": "A1T8T4UYGVIQA8ORZMX9", - "hashUserProperties": false - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://business-api.tiktok.com/open_api/v1.3/pixel/track/", - "headers": { - "Access-Token": "dummyAccessToken", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "pixel_code": "A1T8T4UYGVIQA8ORZMX9", - "event": "AddToWishlist", - "event_id": "1616318632825_357", - "timestamp": "2020-09-17T19:49:27Z", - "test_event_code": "sample rudder test_event_code", - "properties": { - "contents": [ - { - "price": 8, - "quantity": 2, - "content_type": "socks", - "content_id": "1077218" - }, - { - "price": 30, - "quantity": 1, - "content_type": "dress", - "content_id": "1197218" - } - ], - "currency": "USD", - "value": 46 - }, - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea", - "email": "dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f", - "external_id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - }, - "ip": "13.57.97.131", - "user_agent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion" - }, - "partner_name": "RudderStack" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "tiktok_ads", - "description": "Test 5", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "anonymousId": "21e13f4bc7ceddad", - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion", - "locale": "en-US", - "ip": "13.57.97.131", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - }, - "externalId": [ - { - "type": "tiktokExternalId", - "id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - } - ] - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "timestamp": "2020-09-17T19:49:27Z", - "type": "track", - "event": "Product Added to Wishlist", - "properties": { - "eventId": "1616318632825_357", - "testEventCode": "sample rudder test_event_code", - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea", - "email": "dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f" - } - }, - "contents": [ - { - "price": 8, - "quantity": 2, - "content_type": "socks", - "content_id": "1077218" - }, - { - "price": 30, - "quantity": 1, - "content_type": "dress", - "content_id": "1197218" - } - ], - "currency": "USD", - "value": 46 - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - }, - "destination": { - "Config": { - "accessToken": "dummyAccessToken", - "pixelCode": "A1T8T4UYGVIQA8ORZMX9", - "hashUserProperties": false - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://business-api.tiktok.com/open_api/v1.3/pixel/track/", - "headers": { - "Access-Token": "dummyAccessToken", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "pixel_code": "A1T8T4UYGVIQA8ORZMX9", - "event": "AddToWishlist", - "event_id": "1616318632825_357", - "timestamp": "2020-09-17T19:49:27Z", - "test_event_code": "sample rudder test_event_code", - "properties": { - "contents": [ - { - "price": 8, - "quantity": 2, - "content_type": "socks", - "content_id": "1077218" - }, - { - "price": 30, - "quantity": 1, - "content_type": "dress", - "content_id": "1197218" - } - ], - "currency": "USD", - "value": 46 - }, - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea", - "email": "dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f", - "external_id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - }, - "ip": "13.57.97.131", - "user_agent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion" - }, - "partner_name": "RudderStack" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "tiktok_ads", - "description": "Test 6", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "anonymousId": "21e13f4bc7ceddad", - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion", - "locale": "en-US", - "ip": "13.57.97.131", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - }, - "externalId": [ - { - "type": "tiktokExternalId", - "id": "1234" - } - ] - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "timestamp": "2020-09-17T19:49:27Z", - "type": "track", - "event": "SubscriBe", - "properties": { - "eventId": "1616318632825_357", - "testEventCode": "", - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "+868987675687", - "email": "sample@sample.com" - } - }, - "contents": [ - { - "price": 8, - "quantity": 2, - "content_type": "socks", - "content_id": "1077218" - }, - { - "price": 30, - "quantity": 1, - "content_type": "dress", - "content_id": "1197218" - } - ], - "currency": "USD", - "value": 46 - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - }, - "destination": { - "Config": { - "accessToken": "dummyAccessToken", - "pixelCode": "A1T8T4UYGVIQA8ORZMX9", - "hashUserProperties": true - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://business-api.tiktok.com/open_api/v1.3/pixel/track/", - "headers": { - "Access-Token": "dummyAccessToken", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "pixel_code": "A1T8T4UYGVIQA8ORZMX9", - "event": "Subscribe", - "event_id": "1616318632825_357", - "timestamp": "2020-09-17T19:49:27Z", - "properties": { - "contents": [ - { - "price": 8, - "quantity": 2, - "content_type": "socks", - "content_id": "1077218" - }, - { - "price": 30, - "quantity": 1, - "content_type": "dress", - "content_id": "1197218" - } - ], - "currency": "USD", - "value": 46 - }, - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "1d96e70d2bf54087e33586457cde2790825bee7b1a3b05d26481cb12ec8e63fd", - "email": "774efc08cebab8c50c0f0eb2d3a2d2e560872a64f6c1617314c4f03b1c3d4dfa", - "external_id": "03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4" - }, - "ip": "13.57.97.131", - "user_agent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion" - }, - "partner_name": "RudderStack" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "tiktok_ads", - "description": "Test 7", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "anonymousId": "21e13f4bc7ceddad", - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion", - "locale": "en-US", - "ip": "13.57.97.131", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - }, - "externalId": [ - { - "type": "tiktokExternalId", - "id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - } - ] - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "timestamp": "2020-09-17T19:49:27Z", - "type": "track", - "event": "payment info entered", - "properties": { - "eventId": "1616318632825_357", - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea", - "email": "dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f" - } - }, - "contents": [ - { - "price": 8, - "quantity": 2, - "content_type": "socks", - "content_id": "1077218" - }, - { - "price": 30, - "quantity": 1, - "content_type": "dress", - "content_id": "1197218" - } - ], - "currency": "USD", - "value": 46 - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - }, - "destination": { - "Config": { - "accessToken": "dummyAccessToken", - "pixelCode": "A1T8T4UYGVIQA8ORZMX9", - "hashUserProperties": false - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://business-api.tiktok.com/open_api/v1.3/pixel/track/", - "headers": { - "Access-Token": "dummyAccessToken", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "pixel_code": "A1T8T4UYGVIQA8ORZMX9", - "event": "AddPaymentInfo", - "event_id": "1616318632825_357", - "timestamp": "2020-09-17T19:49:27Z", - "properties": { - "contents": [ - { - "price": 8, - "quantity": 2, - "content_type": "socks", - "content_id": "1077218" - }, - { - "price": 30, - "quantity": 1, - "content_type": "dress", - "content_id": "1197218" - } - ], - "currency": "USD", - "value": 46 - }, - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea", - "email": "dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f", - "external_id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - }, - "ip": "13.57.97.131", - "user_agent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion" - }, - "partner_name": "RudderStack" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "tiktok_ads", - "description": "Test 8", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "anonymousId": "21e13f4bc7ceddad", - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion", - "locale": "en-US", - "ip": "13.57.97.131", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - }, - "externalId": [ - { - "type": "tiktokExternalId", - "id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - } - ] - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "timestamp": "2020-09-17T19:49:27Z", - "type": "track", - "properties": { - "eventId": "1616318632825_357", - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea", - "email": "dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f" - } - }, - "contents": [ - { - "price": 8, - "quantity": 2, - "content_type": "socks", - "content_id": "1077218" - }, - { - "price": 30, - "quantity": 1, - "content_type": "dress", - "content_id": "1197218" - } - ], - "currency": "USD", - "value": 46 - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - }, - "destination": { - "Config": { - "accessToken": "dummyAccessToken", - "pixelCode": "A1T8T4UYGVIQA8ORZMX9", - "hashUserProperties": false - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "statusCode": 400, - "error": "Event name is required", - "statTags": { - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "destType": "TIKTOK_ADS", - "module": "destination", - "implementation": "native", - "feature": "processor" - } - } - ] - } - } - }, - { - "name": "tiktok_ads", - "description": "Test 9", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "anonymousId": "21e13f4bc7ceddad", - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion", - "locale": "en-US", - "ip": "13.57.97.131", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - }, - "externalId": [ - { - "type": "tiktokExternalId", - "id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - } - ] - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "timestamp": "2020-09-17T19:49:27Z", - "properties": { - "eventId": "1616318632825_357", - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea", - "email": "dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f" - } - }, - "contents": [ - { - "price": 8, - "quantity": 2, - "content_type": "socks", - "content_id": "1077218" - }, - { - "price": 30, - "quantity": 1, - "content_type": "dress", - "content_id": "1197218" - } - ], - "currency": "USD", - "value": 46 - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - }, - "destination": { - "Config": { - "accessToken": "dummyAccessToken", - "pixelCode": "A1T8T4UYGVIQA8ORZMX9", - "hashUserProperties": false - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "statusCode": 400, - "error": "Event type is required", - "statTags": { - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "destType": "TIKTOK_ADS", - "module": "destination", - "implementation": "native", - "feature": "processor" - } - } - ] - } - } - }, - { - "name": "tiktok_ads", - "description": "Test 10", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "anonymousId": "21e13f4bc7ceddad", - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion", - "locale": "en-US", - "ip": "13.57.97.131", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - }, - "externalId": [ - { - "type": "tiktokExternalId", - "id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - } - ] - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "type": "track", - "event": "payment info entered", - "properties": { - "eventId": "1616318632825_357", - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea", - "email": "dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f" - } - }, - "contents": [ - { - "price": 8, - "quantity": 2, - "content_type": "socks", - "content_id": "1077218" - }, - { - "price": 30, - "quantity": 1, - "content_type": "dress", - "content_id": "1197218" - } - ], - "currency": "USD", - "value": 46 - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - }, - "destination": { - "Config": { - "accessToken": "dummyAccessToken", - "pixelCode": "A1T8T4UYGVIQA8ORZMX9", - "hashUserProperties": false - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://business-api.tiktok.com/open_api/v1.3/pixel/track/", - "headers": { - "Access-Token": "dummyAccessToken", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "pixel_code": "A1T8T4UYGVIQA8ORZMX9", - "event": "AddPaymentInfo", - "event_id": "1616318632825_357", - "properties": { - "contents": [ - { - "price": 8, - "quantity": 2, - "content_type": "socks", - "content_id": "1077218" - }, - { - "price": 30, - "quantity": 1, - "content_type": "dress", - "content_id": "1197218" - } - ], - "currency": "USD", - "value": 46 - }, - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea", - "email": "dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f", - "external_id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - }, - "ip": "13.57.97.131", - "user_agent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion" - }, - "partner_name": "RudderStack" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "tiktok_ads", - "description": "Test 11", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "anonymousId": "21e13f4bc7ceddad", - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion", - "locale": "en-US", - "ip": "13.57.97.131", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - }, - "externalId": [ - { - "type": "tiktokExternalId", - "id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - } - ] - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "timestamp": "2020-09-17T19:49:27Z", - "type": "track", - "event": "submitform", - "properties": { - "eventId": "16163186328257", - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea", - "email": "dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f" - } - }, - "contents": [ - { - "price": 8, - "quantity": 2, - "content_type": "socks", - "content_id": "1077218" - }, - { - "price": 30, - "quantity": 1, - "content_type": "dress", - "content_id": "1197218" - } - ], - "currency": "USD", - "value": 46 - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - }, - "destination": { - "Config": { - "accessToken": "dummyAccessToken", - "pixelCode": "A1T8T4UYGVIQA8ORZMX9", - "hashUserProperties": false - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://business-api.tiktok.com/open_api/v1.3/pixel/track/", - "headers": { - "Access-Token": "dummyAccessToken", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "pixel_code": "A1T8T4UYGVIQA8ORZMX9", - "event": "SubmitForm", - "event_id": "16163186328257", - "timestamp": "2020-09-17T19:49:27Z", - "properties": { - "contents": [ - { - "price": 8, - "quantity": 2, - "content_type": "socks", - "content_id": "1077218" - }, - { - "price": 30, - "quantity": 1, - "content_type": "dress", - "content_id": "1197218" - } - ], - "currency": "USD", - "value": 46 - }, - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea", - "email": "dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f", - "external_id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - }, - "ip": "13.57.97.131", - "user_agent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion" - }, - "partner_name": "RudderStack" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "tiktok_ads", - "description": "Test 12", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "anonymousId": "21e13f4bc7ceddad", - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion", - "locale": "en-US", - "ip": "13.57.97.131", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - }, - "externalId": [ - { - "type": "tiktokExternalId", - "id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - } - ] - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "timestamp": "2020-09-17T19:49:27Z", - "type": "track", - "event": "submitform", - "properties": { - "eventId": "16163186328257", - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea", - "email": "dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f" - }, - "userAgent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion", - "ip": "13.57.97.131" - } - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - }, - "destination": { - "Config": { - "accessToken": "dummyAccessToken", - "pixelCode": "A1T8T4UYGVIQA8ORZMX9", - "hashUserProperties": false - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://business-api.tiktok.com/open_api/v1.3/pixel/track/", - "headers": { - "Access-Token": "dummyAccessToken", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "pixel_code": "A1T8T4UYGVIQA8ORZMX9", - "event": "SubmitForm", - "event_id": "16163186328257", - "timestamp": "2020-09-17T19:49:27Z", - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea", - "email": "dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f", - "external_id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - }, - "ip": "13.57.97.131", - "user_agent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion" - }, - "partner_name": "RudderStack" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "tiktok_ads", - "description": "Test 13", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "anonymousId": "21e13f4bc7ceddad", - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion", - "locale": "en-US", - "ip": "13.57.97.131", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - }, - "externalId": [ - { - "type": "tiktokExternalId", - "id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - } - ] - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "timestamp": "2020-09-17T19:49:27Z", - "type": "track", - "event": "contact", - "properties": { - "eventId": "16163186328257", - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea", - "email": "dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f" - } - }, - "contents": [ - { - "price": 8, - "quantity": 2, - "content_type": "socks", - "content_id": "1077218" - }, - { - "price": 30, - "quantity": 1, - "content_type": "dress", - "content_id": "1197218" - } - ], - "currency": "USD", - "value": 46 - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - }, - "destination": { - "Config": { - "accessToken": "dummyAccessToken", - "pixelCode": "A1T8T4UYGVIQA8ORZMX9", - "hashUserProperties": false - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://business-api.tiktok.com/open_api/v1.3/pixel/track/", - "headers": { - "Access-Token": "dummyAccessToken", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "pixel_code": "A1T8T4UYGVIQA8ORZMX9", - "event": "Contact", - "event_id": "16163186328257", - "timestamp": "2020-09-17T19:49:27Z", - "properties": { - "contents": [ - { - "price": 8, - "quantity": 2, - "content_type": "socks", - "content_id": "1077218" - }, - { - "price": 30, - "quantity": 1, - "content_type": "dress", - "content_id": "1197218" - } - ], - "currency": "USD", - "value": 46 - }, - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea", - "email": "dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f", - "external_id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - }, - "ip": "13.57.97.131", - "user_agent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion" - }, - "partner_name": "RudderStack" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "tiktok_ads", - "description": "Test 14", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "anonymousId": "21e13f4bc7ceddad", - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion", - "locale": "en-US", - "ip": "13.57.97.131", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - }, - "externalId": [ - { - "type": "tiktokExternalId", - "id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - } - ] - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "timestamp": "2020-09-17T19:49:27Z", - "type": "identify", - "event": "contact", - "properties": { - "eventId": "16163186328257", - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea", - "email": "dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f" - } - }, - "contents": [ - { - "price": 8, - "quantity": 2, - "content_type": "socks", - "content_id": "1077218" - }, - { - "price": 30, - "quantity": 1, - "content_type": "dress", - "content_id": "1197218" - } - ], - "currency": "USD", - "value": 46 - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - }, - "destination": { - "Config": { - "accessToken": "dummyAccessToken", - "pixelCode": "A1T8T4UYGVIQA8ORZMX9", - "hashUserProperties": false - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "statusCode": 400, - "error": "Event type identify is not supported", - "statTags": { - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "destType": "TIKTOK_ADS", - "module": "destination", - "implementation": "native", - "feature": "processor" - } - } - ] - } - } - }, - { - "name": "tiktok_ads", - "description": "Test 15", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "anonymousId": "21e13f4bc7ceddad", - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion", - "locale": "en-US", - "ip": "13.57.97.131", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - }, - "externalId": [ - { - "type": "tiktokExternalId", - "id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - } - ] - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "timestamp": "2020-09-17T19:49:27Z", - "type": "track", - "event": "checkout step completed", - "properties": { - "eventId": "1616318632825_357", - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea", - "email": "dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f" - } - }, - "contents": [ - { - "price": 8, - "quantity": 2, - "content_type": "socks", - "content_id": "1077218" - }, - { - "price": 30, - "quantity": 1, - "content_type": "dress", - "content_id": "1197218" - } - ], - "currency": "USD", - "value": 46 - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - }, - "destination": { - "Config": { - "accessToken": "dummyAccessToken", - "pixelCode": "A1T8T4UYGVIQA8ORZMX9", - "hashUserProperties": false - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://business-api.tiktok.com/open_api/v1.3/pixel/track/", - "headers": { - "Access-Token": "dummyAccessToken", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "pixel_code": "A1T8T4UYGVIQA8ORZMX9", - "event": "CompletePayment", - "event_id": "1616318632825_357", - "timestamp": "2020-09-17T19:49:27Z", - "properties": { - "contents": [ - { - "price": 8, - "quantity": 2, - "content_type": "socks", - "content_id": "1077218" - }, - { - "price": 30, - "quantity": 1, - "content_type": "dress", - "content_id": "1197218" - } - ], - "currency": "USD", - "value": 46 - }, - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea", - "email": "dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f", - "external_id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - }, - "ip": "13.57.97.131", - "user_agent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion" - }, - "partner_name": "RudderStack" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "tiktok_ads", - "description": "Test 16", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "anonymousId": "21e13f4bc7ceddad", - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion", - "locale": "en-US", - "ip": "13.57.97.131", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - }, - "externalId": [ - { - "type": "tiktokExternalId", - "id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - } - ] - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "timestamp": "2020-09-17T19:49:27Z", - "type": "track", - "event": "order completed", - "properties": { - "eventId": "1616318632825_357", - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea", - "email": "dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f" - } - }, - "contents": [ - { - "price": 8, - "quantity": 2, - "content_type": "socks", - "content_id": "1077218" - }, - { - "price": 30, - "quantity": 1, - "content_type": "dress", - "content_id": "1197218" - } - ], - "currency": "USD", - "value": 46 - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - }, - "destination": { - "Config": { - "accessToken": "dummyAccessToken", - "pixelCode": "A1T8T4UYGVIQA8ORZMX9", - "hashUserProperties": false - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://business-api.tiktok.com/open_api/v1.3/pixel/track/", - "headers": { - "Access-Token": "dummyAccessToken", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "pixel_code": "A1T8T4UYGVIQA8ORZMX9", - "event": "PlaceAnOrder", - "event_id": "1616318632825_357", - "timestamp": "2020-09-17T19:49:27Z", - "properties": { - "contents": [ - { - "price": 8, - "quantity": 2, - "content_type": "socks", - "content_id": "1077218" - }, - { - "price": 30, - "quantity": 1, - "content_type": "dress", - "content_id": "1197218" - } - ], - "currency": "USD", - "value": 46 - }, - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea", - "email": "dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f", - "external_id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - }, - "ip": "13.57.97.131", - "user_agent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion" - }, - "partner_name": "RudderStack" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "tiktok_ads", - "description": "Test 17", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "anonymousId": "21e13f4bc7ceddad", - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "user@sample.com", - "phone": "+919912345678" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion", - "locale": "en-US", - "ip": "13.57.97.131", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - }, - "externalId": [ - { - "type": "tiktokExternalId", - "id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - } - ] - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "timestamp": "2020-09-17T19:49:27Z", - "type": "track", - "event": "SubscriBe", - "properties": { - "eventId": "1616318632825_357", - "testEventCode": "TEST0000000011", - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "+918987674657", - "email": "sample@rudder.com" - } - }, - "contents": [ - { - "price": 8, - "quantity": 2, - "content_type": "socks", - "content_id": "1077218" - }, - { - "price": 30, - "quantity": 1, - "content_type": "dress", - "content_id": "1197218" - } - ], - "currency": "USD", - "value": 46 - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - }, - "destination": { - "Config": { - "accessToken": "dummyAccessToken", - "pixelCode": "A1T8T4UYGVIQA8ORZMX9", - "hashUserProperties": true - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://business-api.tiktok.com/open_api/v1.3/pixel/track/", - "headers": { - "Access-Token": "dummyAccessToken", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "pixel_code": "A1T8T4UYGVIQA8ORZMX9", - "event": "Subscribe", - "event_id": "1616318632825_357", - "timestamp": "2020-09-17T19:49:27Z", - "test_event_code": "TEST0000000011", - "properties": { - "contents": [ - { - "price": 8, - "quantity": 2, - "content_type": "socks", - "content_id": "1077218" - }, - { - "price": 30, - "quantity": 1, - "content_type": "dress", - "content_id": "1197218" - } - ], - "currency": "USD", - "value": 46 - }, - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "1b6abcebb79b2208929967160ba291656f3fcd4f00e93b6a846c1e56c0e177c6", - "email": "02e47a94635c1ffd6f6a69fe2c7a92dbfbb9d5e2ebddb54810520b34989b66a7", - "external_id": "f0f3ec74bbef8580d7de80624dea93c05d828c748715199fe71bc7f5a67aa8b3" - }, - "ip": "13.57.97.131", - "user_agent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion" - }, - "partner_name": "RudderStack" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "tiktok_ads", - "description": "Test 18", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "anonymousId": "21e13f4bc7ceddad", - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "traits": { - "email": "user@sample.com", - "phone": "+919912345678" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion", - "locale": "en-US", - "ip": "13.57.97.131", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - }, - "externalId": [ - { - "type": "tiktokExternalId", - "id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - } - ] - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "timestamp": "2020-09-17T19:49:27Z", - "type": "track", - "event": "SubscriBe", - "properties": { - "eventId": "1616318632825_357", - "testEventCode": "TEST0000000011", - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "", - "email": "" - } - }, - "contents": [ - { - "price": 8, - "quantity": 2, - "content_type": "socks", - "content_id": "1077218" - }, - { - "price": 30, - "quantity": 1, - "content_type": "dress", - "content_id": "1197218" - } - ], - "currency": "USD", - "value": 46 - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - }, - "destination": { - "Config": { - "accessToken": "dummyAccessToken", - "pixelCode": "A1T8T4UYGVIQA8ORZMX9", - "hashUserProperties": true - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://business-api.tiktok.com/open_api/v1.3/pixel/track/", - "headers": { - "Access-Token": "dummyAccessToken", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "pixel_code": "A1T8T4UYGVIQA8ORZMX9", - "event": "Subscribe", - "event_id": "1616318632825_357", - "timestamp": "2020-09-17T19:49:27Z", - "test_event_code": "TEST0000000011", - "properties": { - "contents": [ - { - "price": 8, - "quantity": 2, - "content_type": "socks", - "content_id": "1077218" - }, - { - "price": 30, - "quantity": 1, - "content_type": "dress", - "content_id": "1197218" - } - ], - "currency": "USD", - "value": 46 - }, - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "241102c24fa8a642e3d1346a31fbce3dd312563c015ae577a2253cb8652581eb", - "email": "a344da1fac6201ed1c1f20a07e1b55bb896a5ac0abd269c1e9daf1afbbffca3b", - "external_id": "f0f3ec74bbef8580d7de80624dea93c05d828c748715199fe71bc7f5a67aa8b3" - }, - "ip": "13.57.97.131", - "user_agent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion" - }, - "partner_name": "RudderStack" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "tiktok_ads", - "description": "Test 19", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "anonymousId": "21e13f4bc7ceddad", - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion", - "ip": "13.57.97.131", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - }, - "ad": { - "callback": "999ATXSfe" - }, - "page": { - "url": "http://rudder.mywebsite.com/purchase", - "referrer": "http://rudder.mywebsite.com" - }, - "externalId": [ - { - "type": "tiktokExternalId", - "id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - } - ] - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "timestamp": "2020-09-17T19:49:27Z", - "type": "track", - "event": "checkout step completed", - "properties": { - "eventId": "1616318632825_357", - "contents": [ - { - "price": 8, - "quantity": 2, - "content_type": "socks", - "content_id": "1077218" - }, - { - "price": 30, - "quantity": 1, - "content_type": "dress", - "content_id": "1197218" - } - ], - "currency": "USD", - "value": 46, - "context": { - "user": { - "phone_number": "2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea", - "email": "dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f" - } - } - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - }, - "destination": { - "Config": { - "accessToken": "dummyAccessToken", - "pixelCode": "A1T8T4UYGVIQA8ORZMX9", - "hashUserProperties": false - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://business-api.tiktok.com/open_api/v1.3/pixel/track/", - "headers": { - "Access-Token": "dummyAccessToken", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "pixel_code": "A1T8T4UYGVIQA8ORZMX9", - "event": "CompletePayment", - "event_id": "1616318632825_357", - "timestamp": "2020-09-17T19:49:27Z", - "properties": { - "contents": [ - { - "price": 8, - "quantity": 2, - "content_type": "socks", - "content_id": "1077218" - }, - { - "price": 30, - "quantity": 1, - "content_type": "dress", - "content_id": "1197218" - } - ], - "currency": "USD", - "value": 46 - }, - "context": { - "ad": { - "callback": "999ATXSfe" - }, - "page": { - "url": "http://rudder.mywebsite.com/purchase", - "referrer": "http://rudder.mywebsite.com" - }, - "user": { - "phone_number": "2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea", - "email": "dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f", - "external_id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - }, - "ip": "13.57.97.131", - "user_agent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion" - }, - "partner_name": "RudderStack" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "tiktok_ads", - "description": "Test 20", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "anonymousId": "21e13f4bc7ceddad", - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion", - "ip": "13.57.97.131", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - }, - "externalId": [ - { - "type": "tiktokExternalId", - "id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - } - ] - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "timestamp": "2020-09-17T19:49:27Z", - "type": "track", - "event": "abc", - "properties": { - "eventId": "1616318632825_357", - "contents": [ - { - "price": 8, - "quantity": 2, - "content_type": "socks", - "content_id": "1077218" - }, - { - "price": 30, - "quantity": 1, - "content_type": "dress", - "content_id": "1197218" - } - ], - "currency": "USD", - "value": 46, - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea", - "email": "dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f" - } - } - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - }, - "destination": { - "Config": { - "accessToken": "dummyAccessToken", - "pixelCode": "A1T8T4UYGVIQA8ORZMX9", - "hashUserProperties": false, - "eventsToStandard": [ - { - "from": "abc", - "to": "download" - }, - { - "from": "abc", - "to": "search" - }, - { - "from": "def", - "to": "search" - } - ] - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://business-api.tiktok.com/open_api/v1.3/pixel/track/", - "headers": { - "Access-Token": "dummyAccessToken", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "pixel_code": "A1T8T4UYGVIQA8ORZMX9", - "event": "download", - "event_id": "1616318632825_357", - "timestamp": "2020-09-17T19:49:27Z", - "properties": { - "contents": [ - { - "price": 8, - "quantity": 2, - "content_type": "socks", - "content_id": "1077218" - }, - { - "price": 30, - "quantity": 1, - "content_type": "dress", - "content_id": "1197218" - } - ], - "currency": "USD", - "value": 46 - }, - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea", - "email": "dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f", - "external_id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - }, - "ip": "13.57.97.131", - "user_agent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion" - }, - "partner_name": "RudderStack" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - }, - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://business-api.tiktok.com/open_api/v1.3/pixel/track/", - "headers": { - "Access-Token": "dummyAccessToken", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "pixel_code": "A1T8T4UYGVIQA8ORZMX9", - "event": "search", - "event_id": "1616318632825_357", - "timestamp": "2020-09-17T19:49:27Z", - "properties": { - "contents": [ - { - "price": 8, - "quantity": 2, - "content_type": "socks", - "content_id": "1077218" - }, - { - "price": 30, - "quantity": 1, - "content_type": "dress", - "content_id": "1197218" - } - ], - "currency": "USD", - "value": 46 - }, - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea", - "email": "dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f", - "external_id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - }, - "ip": "13.57.97.131", - "user_agent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion" - }, - "partner_name": "RudderStack" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "tiktok_ads", - "description": "Test 21", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "anonymousId": "21e13f4bc7ceddad", - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion", - "ip": "13.57.97.131", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - }, - "externalId": [ - { - "type": "tiktokExternalId", - "id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - } - ] - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "timestamp": "2020-09-17T19:49:27Z", - "type": "track", - "event": "abc", - "properties": { - "eventId": "1616318632825_357", - "contents": [ - { - "price": 8, - "quantity": 2, - "content_type": "socks", - "content_id": "1077218" - }, - { - "price": 30, - "quantity": 1, - "content_type": "dress", - "content_id": "1197218" - } - ], - "currency": "USD", - "value": 46, - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea", - "email": "dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f" - } - } - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - }, - "destination": { - "Config": { - "accessToken": "dummyAccessToken", - "pixelCode": "A1T8T4UYGVIQA8ORZMX9", - "hashUserProperties": false, - "eventsToStandard": [ - { - "from": "def", - "to": "download" - } - ] - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "statusCode": 400, - "error": "Event name (abc) is not valid, must be mapped to one of standard events", - "statTags": { - "errorCategory": "dataValidation", - "errorType": "instrumentation", - "destType": "TIKTOK_ADS", - "module": "destination", - "implementation": "native", - "feature": "processor" - } - } - ] - } - } - }, - { - "name": "tiktok_ads", - "description": "Test 22", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "anonymousId": "21e13f4bc7ceddad", - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion", - "ip": "13.57.97.131", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - }, - "externalId": [ - { - "type": "tiktokExternalId", - "id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - } - ] - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "timestamp": "2020-09-17T19:49:27Z", - "type": "track", - "event": "abc", - "properties": { - "eventId": "1616318632825_357", - "contents": [ - { - "price": 8, - "quantity": 2, - "content_type": "socks", - "content_id": "1077218" - }, - { - "price": 30, - "quantity": 1, - "content_type": "dress", - "content_id": "1197218" - } - ], - "currency": "USD", - "value": 46, - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea", - "email": "dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f" - } - } - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - }, - "destination": { - "Config": { - "accessToken": "dummyAccessToken", - "pixelCode": "A1T8T4UYGVIQA8ORZMX9", - "hashUserProperties": false, - "eventsToStandard": [ - { - "from": "abc", - "to": "download" - }, - { - "from": "def", - "to": "download" - } - ] - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://business-api.tiktok.com/open_api/v1.3/pixel/track/", - "headers": { - "Access-Token": "dummyAccessToken", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "pixel_code": "A1T8T4UYGVIQA8ORZMX9", - "event": "download", - "event_id": "1616318632825_357", - "timestamp": "2020-09-17T19:49:27Z", - "properties": { - "contents": [ - { - "price": 8, - "quantity": 2, - "content_type": "socks", - "content_id": "1077218" - }, - { - "price": 30, - "quantity": 1, - "content_type": "dress", - "content_id": "1197218" - } - ], - "currency": "USD", - "value": 46 - }, - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea", - "email": "dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f", - "external_id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - }, - "ip": "13.57.97.131", - "user_agent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion" - }, - "partner_name": "RudderStack" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "tiktok_ads", - "description": "Test 23", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "anonymousId": "21e13f4bc7ceddad", - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion", - "ip": "13.57.97.131", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - }, - "externalId": [ - { - "type": "tiktokExternalId", - "id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - } - ] - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "timestamp": "2020-09-17T19:49:27Z", - "type": "track", - "event": "abc", - "properties": { - "eventId": "1616318632825_357", - "contents": [ - { - "price": 8, - "quantity": 2, - "content_type": "socks", - "content_id": "1077218" - }, - { - "price": 30, - "quantity": 1, - "content_type": "dress", - "content_id": "1197218" - } - ], - "currency": "USD", - "value": 46, - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "+371234567890123", - "email": "sample@sample.com" - } - } - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - }, - "destination": { - "Config": { - "accessToken": "dummyAccessToken", - "pixelCode": "A1T8T4UYGVIQA8ORZMX9", - "hashUserProperties": true, - "eventsToStandard": [ - { - "from": "abc", - "to": "download" - }, - { - "from": "def", - "to": "download" - } - ] - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://business-api.tiktok.com/open_api/v1.3/pixel/track/", - "headers": { - "Access-Token": "dummyAccessToken", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "pixel_code": "A1T8T4UYGVIQA8ORZMX9", - "event": "download", - "event_id": "1616318632825_357", - "timestamp": "2020-09-17T19:49:27Z", - "properties": { - "contents": [ - { - "price": 8, - "quantity": 2, - "content_type": "socks", - "content_id": "1077218" - }, - { - "price": 30, - "quantity": 1, - "content_type": "dress", - "content_id": "1197218" - } - ], - "currency": "USD", - "value": 46 - }, - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "6080191ec608e10062e9257702cbca694cfe1bfa53944ba5701119d8f8b99ad6", - "email": "774efc08cebab8c50c0f0eb2d3a2d2e560872a64f6c1617314c4f03b1c3d4dfa", - "external_id": "f0f3ec74bbef8580d7de80624dea93c05d828c748715199fe71bc7f5a67aa8b3" - }, - "ip": "13.57.97.131", - "user_agent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion" - }, - "partner_name": "RudderStack" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "tiktok_ads", - "description": "Test 24", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "anonymousId": "21e13f4bc7ceddad", - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion", - "ip": "13.57.97.131", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - }, - "externalId": [ - { - "type": "tiktokExternalId", - "id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - } - ] - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "timestamp": "2020-09-17T19:49:27Z", - "type": "track", - "event": "abc", - "properties": { - "eventId": "1616318632825_357", - "contents": [ - { - "price": 8, - "quantity": 2, - "content_type": "socks", - "content_id": "1077218" - }, - { - "price": 30, - "quantity": 1, - "content_type": "dress", - "content_id": "1197218" - } - ], - "currency": "USD", - "value": 46, - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "+3712345678", - "email": "sample@sample.com" - } - } - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - }, - "destination": { - "Config": { - "accessToken": "dummyAccessToken", - "pixelCode": "A1T8T4UYGVIQA8ORZMX9", - "hashUserProperties": true, - "eventsToStandard": [ - { - "from": "abc", - "to": "download" - }, - { - "from": "def", - "to": "download" - } - ] - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://business-api.tiktok.com/open_api/v1.3/pixel/track/", - "headers": { - "Access-Token": "dummyAccessToken", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "pixel_code": "A1T8T4UYGVIQA8ORZMX9", - "event": "download", - "event_id": "1616318632825_357", - "timestamp": "2020-09-17T19:49:27Z", - "properties": { - "contents": [ - { - "price": 8, - "quantity": 2, - "content_type": "socks", - "content_id": "1077218" - }, - { - "price": 30, - "quantity": 1, - "content_type": "dress", - "content_id": "1197218" - } - ], - "currency": "USD", - "value": 46 - }, - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "6e6c1bb39126b3ecf537e62847909b1372a1a22de9b28d85960e12c78f322035", - "email": "774efc08cebab8c50c0f0eb2d3a2d2e560872a64f6c1617314c4f03b1c3d4dfa", - "external_id": "f0f3ec74bbef8580d7de80624dea93c05d828c748715199fe71bc7f5a67aa8b3" - }, - "ip": "13.57.97.131", - "user_agent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion" - }, - "partner_name": "RudderStack" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "tiktok_ads", - "description": "Test 25", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "anonymousId": "21e13f4bc7ceddad", - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion", - "ip": "13.57.97.131", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - }, - "externalId": [ - { - "type": "tiktokExternalId", - "id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - } - ] - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "timestamp": "2020-09-17T19:49:27Z", - "type": "track", - "event": "checkout step completed", - "properties": { - "eventId": "1616318632825_357", - "contents": [ - { - "price": 8, - "quantity": 2, - "content_type": "socks", - "content_id": "1077218" - }, - { - "price": 30, - "quantity": 1, - "content_type": "dress", - "content_id": "1197218" - } - ], - "products": [ - { - "product_id": 123, - "sku": "G-32", - "name": "Monopoly", - "price": 14, - "quantity": 1, - "category": "Games", - "url": "https://www.website.com/product/path", - "image_url": "https://www.website.com/product/path.jpg" - }, - { - "product_id": "345", - "sku": "F-32", - "name": "UNO", - "price": 3.45, - "quantity": 2, - "category": "Games" - } - ], - "currency": "USD", - "value": 46, - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea", - "email": "dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f" - } - } - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - }, - "destination": { - "Config": { - "accessToken": "dummyAccessToken", - "pixelCode": "A1T8T4UYGVIQA8ORZMX9", - "hashUserProperties": false - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://business-api.tiktok.com/open_api/v1.3/pixel/track/", - "headers": { - "Access-Token": "dummyAccessToken", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "pixel_code": "A1T8T4UYGVIQA8ORZMX9", - "event": "CompletePayment", - "event_id": "1616318632825_357", - "timestamp": "2020-09-17T19:49:27Z", - "properties": { - "contents": [ - { - "price": 8, - "quantity": 2, - "content_type": "socks", - "content_id": "1077218" - }, - { - "price": 30, - "quantity": 1, - "content_type": "dress", - "content_id": "1197218" - } - ], - "currency": "USD", - "value": 46 - }, - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea", - "email": "dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f", - "external_id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - }, - "ip": "13.57.97.131", - "user_agent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion" - }, - "partner_name": "RudderStack" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "tiktok_ads", - "description": "Test 26", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "anonymousId": "21e13f4bc7ceddad", - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion", - "ip": "13.57.97.131", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - }, - "externalId": [ - { - "type": "tiktokExternalId", - "id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - } - ] - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "timestamp": "2020-09-17T19:49:27Z", - "type": "track", - "event": "checkout step completed", - "properties": { - "eventId": "1616318632825_357", - "products": [ - { - "product_id": 123, - "sku": "G-32", - "name": "Monopoly", - "price": 14, - "quantity": 1, - "contentType": "product_group", - "category": "Games", - "url": "https://www.website.com/product/path", - "image_url": "https://www.website.com/product/path.jpg" - }, - { - "product_id": 345, - "sku": "F-32", - "name": "UNO", - "price": 3.45, - "contentType": "product_group", - "quantity": 2 - } - ], - "currency": "USD", - "value": 46, - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea", - "email": "dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f" - } - } - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - }, - "destination": { - "Config": { - "accessToken": "dummyAccessToken", - "pixelCode": "A1T8T4UYGVIQA8ORZMX9", - "hashUserProperties": false - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://business-api.tiktok.com/open_api/v1.3/pixel/track/", - "headers": { - "Access-Token": "dummyAccessToken", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "pixel_code": "A1T8T4UYGVIQA8ORZMX9", - "event": "CompletePayment", - "event_id": "1616318632825_357", - "timestamp": "2020-09-17T19:49:27Z", - "properties": { - "currency": "USD", - "value": 46, - "contents": [ - { - "content_type": "product_group", - "content_id": "123", - "content_category": "Games", - "content_name": "Monopoly", - "price": 14, - "quantity": 1 - }, - { - "content_type": "product_group", - "content_id": "345", - "content_name": "UNO", - "price": 3.45, - "quantity": 2 - } - ] - }, - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea", - "email": "dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f", - "external_id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - }, - "ip": "13.57.97.131", - "user_agent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion" - }, - "partner_name": "RudderStack" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "tiktok_ads", - "description": "Test 27", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "anonymousId": "21e13f4bc7ceddad", - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion", - "ip": "13.57.97.131", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - }, - "externalId": [ - { - "type": "tiktokExternalId", - "id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - } - ] - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "timestamp": "2020-09-17T19:49:27Z", - "type": "track", - "event": "checkout step completed", - "properties": { - "eventId": "1616318632825_357", - "products": [ - { - "contentType": "product_group", - "product_id": "123", - "sku": "G-32", - "name": "Monopoly", - "price": 14, - "quantity": 1, - "category": "Games", - "url": "https://www.website.com/product/path", - "image_url": "https://www.website.com/product/path.jpg" - }, - { - "contentType": "product_group", - "product_id": "345", - "sku": "F-32", - "name": "UNO", - "price": 3.45, - "quantity": 2, - "category": "Games" - } - ], - "currency": "USD", - "value": 46, - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea", - "email": "dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f" - } - } - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - }, - "destination": { - "Config": { - "accessToken": "dummyAccessToken", - "pixelCode": "A1T8T4UYGVIQA8ORZMX9", - "hashUserProperties": false - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://business-api.tiktok.com/open_api/v1.3/pixel/track/", - "headers": { - "Access-Token": "dummyAccessToken", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "pixel_code": "A1T8T4UYGVIQA8ORZMX9", - "event": "CompletePayment", - "event_id": "1616318632825_357", - "timestamp": "2020-09-17T19:49:27Z", - "properties": { - "currency": "USD", - "value": 46, - "contents": [ - { - "content_type": "product_group", - "content_id": "123", - "content_category": "Games", - "content_name": "Monopoly", - "price": 14, - "quantity": 1 - }, - { - "content_type": "product_group", - "content_id": "345", - "content_category": "Games", - "content_name": "UNO", - "price": 3.45, - "quantity": 2 - } - ] - }, - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea", - "email": "dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f", - "external_id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - }, - "ip": "13.57.97.131", - "user_agent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion" - }, - "partner_name": "RudderStack" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "tiktok_ads", - "description": "Test 28", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "anonymousId": "21e13f4bc7ceddad", - "channel": "web", - "context": { - "app": { - "build": "1.0.0", - "name": "RudderLabs JavaScript SDK", - "namespace": "com.rudderlabs.javascript", - "version": "1.0.0" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.0.0" - }, - "userAgent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion", - "ip": "13.57.97.131", - "locale": "en-US", - "os": { - "name": "", - "version": "" - }, - "screen": { - "density": 2 - }, - "externalId": [ - { - "type": "tiktokExternalId", - "id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - } - ] - }, - "messageId": "84e26acc-56a5-4835-8233-591137fca468", - "session_id": "3049dc4c-5a95-4ccd-a3e7-d74a7e411f22", - "originalTimestamp": "2019-10-14T09:03:17.562Z", - "timestamp": "2020-09-17T19:49:27Z", - "type": "track", - "event": "checkout step completed", - "properties": { - "category": "Urban", - "status": "processed", - "name": "games", - "contentType": "product_group", - "productId": "qqw21221341234", - "eventId": "1616318632825_357", - "products": [ - { - "product_id": "123", - "sku": "G-32", - "name": "Monopoly", - "price": 14, - "quantity": 1, - "category": "Games", - "url": "https://www.website.com/product/path", - "image_url": "https://www.website.com/product/path.jpg" - }, - { - "product_id": "345", - "sku": "F-32", - "name": "UNO", - "price": 3.45, - "quantity": 2, - "category": "Games" - } - ], - "currency": "USD", - "value": 46, - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea", - "email": "dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f" - } - } - }, - "integrations": { - "All": true - }, - "sentAt": "2019-10-14T09:03:22.563Z" - }, - "destination": { - "Config": { - "accessToken": "dummyAccessToken", - "pixelCode": "A1T8T4UYGVIQA8ORZMX9", - "hashUserProperties": false - } - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://business-api.tiktok.com/open_api/v1.3/pixel/track/", - "headers": { - "Access-Token": "dummyAccessToken", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "pixel_code": "A1T8T4UYGVIQA8ORZMX9", - "event": "CompletePayment", - "event_id": "1616318632825_357", - "timestamp": "2020-09-17T19:49:27Z", - "properties": { - "content_category": "Urban", - "status": "processed", - "content_name": "games", - "content_id": "qqw21221341234", - "content_type": "product_group", - "currency": "USD", - "value": 46, - "contents": [ - { - "content_type": "product_group", - "content_id": "123", - "content_category": "Games", - "content_name": "Monopoly", - "price": 14, - "quantity": 1 - }, - { - "content_type": "product_group", - "content_id": "345", - "content_category": "Games", - "content_name": "UNO", - "price": 3.45, - "quantity": 2 - } - ] - }, - "context": { - "ad": { - "callback": "123ATXSfe" - }, - "page": { - "url": "http://demo.mywebsite.com/purchase", - "referrer": "http://demo.mywebsite.com" - }, - "user": { - "phone_number": "2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea", - "email": "dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f", - "external_id": "f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc" - }, - "ip": "13.57.97.131", - "user_agent": "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion" - }, - "partner_name": "RudderStack" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {}, - "userId": "" - }, - "statusCode": 200 - } - ] - } - } - } -] \ No newline at end of file + { + name: 'tiktok_ads', + description: 'Test 0', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: '21e13f4bc7ceddad', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + ip: '13.57.97.131', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + externalId: [ + { + type: 'tiktokExternalId', + id: 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ], + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + timestamp: '2020-09-17T19:49:27Z', + type: 'track', + event: 'checkout step completed', + properties: { + eventId: '1616318632825_357', + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + clickId: 'dummyclickId', + currency: 'USD', + value: 46, + context: { + ad: { + callback: '123ATXSfe', + }, + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + }, + }, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + accessToken: 'dummyAccessToken', + pixelCode: 'A1T8T4UYGVIQA8ORZMX9', + hashUserProperties: false, + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://business-api.tiktok.com/open_api/v1.3/pixel/track/', + headers: { + 'Access-Token': 'dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + pixel_code: 'A1T8T4UYGVIQA8ORZMX9', + event: 'CompletePayment', + event_id: '1616318632825_357', + timestamp: '2020-09-17T19:49:27Z', + properties: { + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + currency: 'USD', + value: 46, + }, + context: { + ad: { + callback: 'dummyclickId', + }, + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + external_id: + 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ip: '13.57.97.131', + user_agent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + }, + partner_name: 'RudderStack', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'tiktok_ads', + description: 'Test 1', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: '21e13f4bc7ceddad', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + locale: 'en-US', + ip: '13.57.97.131', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + externalId: [ + { + type: 'tiktokExternalId', + id: 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ], + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + timestamp: '2020-09-17T19:49:27Z', + type: 'track', + event: 'checkout started', + properties: { + eventId: '1616318632825_357', + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + }, + }, + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + currency: 'USD', + value: 46, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + accessToken: 'dummyAccessToken', + pixelCode: 'A1T8T4UYGVIQA8ORZMX9', + hashUserProperties: false, + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://business-api.tiktok.com/open_api/v1.3/pixel/track/', + headers: { + 'Access-Token': 'dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + pixel_code: 'A1T8T4UYGVIQA8ORZMX9', + event: 'InitiateCheckout', + event_id: '1616318632825_357', + timestamp: '2020-09-17T19:49:27Z', + properties: { + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + currency: 'USD', + value: 46, + }, + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + external_id: + 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ip: '13.57.97.131', + user_agent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + }, + partner_name: 'RudderStack', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'tiktok_ads', + description: 'Test 2', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: '21e13f4bc7ceddad', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + externalId: [ + { + type: 'tiktokExternalId', + id: 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ], + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + timestamp: '2020-09-17T19:49:27Z', + type: 'track', + event: 'Product Added to Wishlist', + properties: { + eventId: '1616318632825_357', + testEventCode: 'sample rudder test_event_code', + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + }, + }, + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + currency: 'USD', + value: 46, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + accessToken: 'dummyAccessToken', + pixelCode: 'A1T8T4UYGVIQA8ORZMX9', + hashUserProperties: false, + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://business-api.tiktok.com/open_api/v1.3/pixel/track/', + headers: { + 'Access-Token': 'dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + pixel_code: 'A1T8T4UYGVIQA8ORZMX9', + event: 'AddToWishlist', + event_id: '1616318632825_357', + timestamp: '2020-09-17T19:49:27Z', + test_event_code: 'sample rudder test_event_code', + properties: { + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + currency: 'USD', + value: 46, + }, + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + external_id: + 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + }, + partner_name: 'RudderStack', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'tiktok_ads', + description: 'Test 3', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: '21e13f4bc7ceddad', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + locale: 'en-US', + ip: '13.57.97.131', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + externalId: [ + { + type: 'tiktokExternalId', + id: 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ], + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + timestamp: '2020-09-17T19:49:27Z', + type: 'track', + event: 'Product Added to Wishlist1', + properties: { + eventId: '1616318632825_357', + testEventCode: 'sample rudder test_event_code', + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + }, + }, + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + currency: 'USD', + value: 46, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + accessToken: 'dummyAccessToken', + pixelCode: 'A1T8T4UYGVIQA8ORZMX9', + hashUserProperties: false, + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + statusCode: 400, + error: + 'Event name (product added to wishlist1) is not valid, must be mapped to one of standard events', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'TIKTOK_ADS', + module: 'destination', + implementation: 'native', + feature: 'processor', + }, + }, + ], + }, + }, + }, + { + name: 'tiktok_ads', + description: 'Test 4', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: '21e13f4bc7ceddad', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + locale: 'en-US', + ip: '13.57.97.131', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + externalId: [ + { + type: 'tiktokExternalId', + id: 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ], + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + timestamp: '2020-09-17T19:49:27Z', + type: 'track', + event: 'Product Added to Wishlist', + properties: { + eventId: '1616318632825_357', + testEventCode: 'sample rudder test_event_code', + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + }, + }, + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + currency: 'USD', + value: 46, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + accessToken: 'dummyAccessToken', + pixelCode: 'A1T8T4UYGVIQA8ORZMX9', + hashUserProperties: false, + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://business-api.tiktok.com/open_api/v1.3/pixel/track/', + headers: { + 'Access-Token': 'dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + pixel_code: 'A1T8T4UYGVIQA8ORZMX9', + event: 'AddToWishlist', + event_id: '1616318632825_357', + timestamp: '2020-09-17T19:49:27Z', + test_event_code: 'sample rudder test_event_code', + properties: { + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + currency: 'USD', + value: 46, + }, + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + external_id: + 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ip: '13.57.97.131', + user_agent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + }, + partner_name: 'RudderStack', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'tiktok_ads', + description: 'Test 5', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: '21e13f4bc7ceddad', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + locale: 'en-US', + ip: '13.57.97.131', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + externalId: [ + { + type: 'tiktokExternalId', + id: 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ], + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + timestamp: '2020-09-17T19:49:27Z', + type: 'track', + event: 'Product Added to Wishlist', + properties: { + eventId: '1616318632825_357', + testEventCode: 'sample rudder test_event_code', + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + }, + }, + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + currency: 'USD', + value: 46, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + accessToken: 'dummyAccessToken', + pixelCode: 'A1T8T4UYGVIQA8ORZMX9', + hashUserProperties: false, + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://business-api.tiktok.com/open_api/v1.3/pixel/track/', + headers: { + 'Access-Token': 'dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + pixel_code: 'A1T8T4UYGVIQA8ORZMX9', + event: 'AddToWishlist', + event_id: '1616318632825_357', + timestamp: '2020-09-17T19:49:27Z', + test_event_code: 'sample rudder test_event_code', + properties: { + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + currency: 'USD', + value: 46, + }, + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + external_id: + 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ip: '13.57.97.131', + user_agent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + }, + partner_name: 'RudderStack', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'tiktok_ads', + description: 'Test 6', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: '21e13f4bc7ceddad', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + locale: 'en-US', + ip: '13.57.97.131', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + externalId: [ + { + type: 'tiktokExternalId', + id: '1234', + }, + ], + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + timestamp: '2020-09-17T19:49:27Z', + type: 'track', + event: 'SubscriBe', + properties: { + eventId: '1616318632825_357', + testEventCode: '', + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: '+868987675687', + email: 'sample@sample.com', + }, + }, + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + currency: 'USD', + value: 46, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + accessToken: 'dummyAccessToken', + pixelCode: 'A1T8T4UYGVIQA8ORZMX9', + hashUserProperties: true, + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://business-api.tiktok.com/open_api/v1.3/pixel/track/', + headers: { + 'Access-Token': 'dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + pixel_code: 'A1T8T4UYGVIQA8ORZMX9', + event: 'Subscribe', + event_id: '1616318632825_357', + timestamp: '2020-09-17T19:49:27Z', + properties: { + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + currency: 'USD', + value: 46, + }, + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '1d96e70d2bf54087e33586457cde2790825bee7b1a3b05d26481cb12ec8e63fd', + email: '774efc08cebab8c50c0f0eb2d3a2d2e560872a64f6c1617314c4f03b1c3d4dfa', + external_id: + '03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4', + }, + ip: '13.57.97.131', + user_agent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + }, + partner_name: 'RudderStack', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'tiktok_ads', + description: 'Test 7', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: '21e13f4bc7ceddad', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + locale: 'en-US', + ip: '13.57.97.131', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + externalId: [ + { + type: 'tiktokExternalId', + id: 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ], + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + timestamp: '2020-09-17T19:49:27Z', + type: 'track', + event: 'payment info entered', + properties: { + eventId: '1616318632825_357', + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + }, + }, + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + currency: 'USD', + value: 46, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + accessToken: 'dummyAccessToken', + pixelCode: 'A1T8T4UYGVIQA8ORZMX9', + hashUserProperties: false, + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://business-api.tiktok.com/open_api/v1.3/pixel/track/', + headers: { + 'Access-Token': 'dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + pixel_code: 'A1T8T4UYGVIQA8ORZMX9', + event: 'AddPaymentInfo', + event_id: '1616318632825_357', + timestamp: '2020-09-17T19:49:27Z', + properties: { + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + currency: 'USD', + value: 46, + }, + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + external_id: + 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ip: '13.57.97.131', + user_agent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + }, + partner_name: 'RudderStack', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'tiktok_ads', + description: 'Test 8', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: '21e13f4bc7ceddad', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + locale: 'en-US', + ip: '13.57.97.131', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + externalId: [ + { + type: 'tiktokExternalId', + id: 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ], + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + timestamp: '2020-09-17T19:49:27Z', + type: 'track', + properties: { + eventId: '1616318632825_357', + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + }, + }, + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + currency: 'USD', + value: 46, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + accessToken: 'dummyAccessToken', + pixelCode: 'A1T8T4UYGVIQA8ORZMX9', + hashUserProperties: false, + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + statusCode: 400, + error: 'Event name is required', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'TIKTOK_ADS', + module: 'destination', + implementation: 'native', + feature: 'processor', + }, + }, + ], + }, + }, + }, + { + name: 'tiktok_ads', + description: 'Test 9', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: '21e13f4bc7ceddad', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + locale: 'en-US', + ip: '13.57.97.131', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + externalId: [ + { + type: 'tiktokExternalId', + id: 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ], + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + timestamp: '2020-09-17T19:49:27Z', + properties: { + eventId: '1616318632825_357', + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + }, + }, + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + currency: 'USD', + value: 46, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + accessToken: 'dummyAccessToken', + pixelCode: 'A1T8T4UYGVIQA8ORZMX9', + hashUserProperties: false, + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + statusCode: 400, + error: 'Event type is required', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'TIKTOK_ADS', + module: 'destination', + implementation: 'native', + feature: 'processor', + }, + }, + ], + }, + }, + }, + { + name: 'tiktok_ads', + description: 'Test 10', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: '21e13f4bc7ceddad', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + locale: 'en-US', + ip: '13.57.97.131', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + externalId: [ + { + type: 'tiktokExternalId', + id: 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ], + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + type: 'track', + event: 'payment info entered', + properties: { + eventId: '1616318632825_357', + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + }, + }, + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + currency: 'USD', + value: 46, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + accessToken: 'dummyAccessToken', + pixelCode: 'A1T8T4UYGVIQA8ORZMX9', + hashUserProperties: false, + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://business-api.tiktok.com/open_api/v1.3/pixel/track/', + headers: { + 'Access-Token': 'dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + pixel_code: 'A1T8T4UYGVIQA8ORZMX9', + event: 'AddPaymentInfo', + event_id: '1616318632825_357', + properties: { + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + currency: 'USD', + value: 46, + }, + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + external_id: + 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ip: '13.57.97.131', + user_agent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + }, + partner_name: 'RudderStack', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'tiktok_ads', + description: 'Test 11', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: '21e13f4bc7ceddad', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + locale: 'en-US', + ip: '13.57.97.131', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + externalId: [ + { + type: 'tiktokExternalId', + id: 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ], + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + timestamp: '2020-09-17T19:49:27Z', + type: 'track', + event: 'submitform', + properties: { + eventId: '16163186328257', + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + }, + }, + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + currency: 'USD', + value: 46, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + accessToken: 'dummyAccessToken', + pixelCode: 'A1T8T4UYGVIQA8ORZMX9', + hashUserProperties: false, + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://business-api.tiktok.com/open_api/v1.3/pixel/track/', + headers: { + 'Access-Token': 'dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + pixel_code: 'A1T8T4UYGVIQA8ORZMX9', + event: 'SubmitForm', + event_id: '16163186328257', + timestamp: '2020-09-17T19:49:27Z', + properties: { + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + currency: 'USD', + value: 46, + }, + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + external_id: + 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ip: '13.57.97.131', + user_agent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + }, + partner_name: 'RudderStack', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'tiktok_ads', + description: 'Test 12', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: '21e13f4bc7ceddad', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + locale: 'en-US', + ip: '13.57.97.131', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + externalId: [ + { + type: 'tiktokExternalId', + id: 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ], + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + timestamp: '2020-09-17T19:49:27Z', + type: 'track', + event: 'submitform', + properties: { + eventId: '16163186328257', + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + }, + userAgent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + ip: '13.57.97.131', + }, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + accessToken: 'dummyAccessToken', + pixelCode: 'A1T8T4UYGVIQA8ORZMX9', + hashUserProperties: false, + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://business-api.tiktok.com/open_api/v1.3/pixel/track/', + headers: { + 'Access-Token': 'dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + pixel_code: 'A1T8T4UYGVIQA8ORZMX9', + event: 'SubmitForm', + event_id: '16163186328257', + timestamp: '2020-09-17T19:49:27Z', + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + external_id: + 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ip: '13.57.97.131', + user_agent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + }, + partner_name: 'RudderStack', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'tiktok_ads', + description: 'Test 13', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: '21e13f4bc7ceddad', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + locale: 'en-US', + ip: '13.57.97.131', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + externalId: [ + { + type: 'tiktokExternalId', + id: 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ], + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + timestamp: '2020-09-17T19:49:27Z', + type: 'track', + event: 'contact', + properties: { + eventId: '16163186328257', + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + }, + }, + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + currency: 'USD', + value: 46, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + accessToken: 'dummyAccessToken', + pixelCode: 'A1T8T4UYGVIQA8ORZMX9', + hashUserProperties: false, + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://business-api.tiktok.com/open_api/v1.3/pixel/track/', + headers: { + 'Access-Token': 'dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + pixel_code: 'A1T8T4UYGVIQA8ORZMX9', + event: 'Contact', + event_id: '16163186328257', + timestamp: '2020-09-17T19:49:27Z', + properties: { + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + currency: 'USD', + value: 46, + }, + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + external_id: + 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ip: '13.57.97.131', + user_agent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + }, + partner_name: 'RudderStack', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'tiktok_ads', + description: 'Test 14', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: '21e13f4bc7ceddad', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + locale: 'en-US', + ip: '13.57.97.131', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + externalId: [ + { + type: 'tiktokExternalId', + id: 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ], + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + timestamp: '2020-09-17T19:49:27Z', + type: 'identify', + event: 'contact', + properties: { + eventId: '16163186328257', + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + }, + }, + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + currency: 'USD', + value: 46, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + accessToken: 'dummyAccessToken', + pixelCode: 'A1T8T4UYGVIQA8ORZMX9', + hashUserProperties: false, + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + statusCode: 400, + error: 'Event type identify is not supported', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'TIKTOK_ADS', + module: 'destination', + implementation: 'native', + feature: 'processor', + }, + }, + ], + }, + }, + }, + { + name: 'tiktok_ads', + description: 'Test 15', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: '21e13f4bc7ceddad', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + locale: 'en-US', + ip: '13.57.97.131', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + externalId: [ + { + type: 'tiktokExternalId', + id: 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ], + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + timestamp: '2020-09-17T19:49:27Z', + type: 'track', + event: 'checkout step completed', + properties: { + eventId: '1616318632825_357', + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + }, + }, + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + currency: 'USD', + value: 46, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + accessToken: 'dummyAccessToken', + pixelCode: 'A1T8T4UYGVIQA8ORZMX9', + hashUserProperties: false, + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://business-api.tiktok.com/open_api/v1.3/pixel/track/', + headers: { + 'Access-Token': 'dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + pixel_code: 'A1T8T4UYGVIQA8ORZMX9', + event: 'CompletePayment', + event_id: '1616318632825_357', + timestamp: '2020-09-17T19:49:27Z', + properties: { + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + currency: 'USD', + value: 46, + }, + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + external_id: + 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ip: '13.57.97.131', + user_agent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + }, + partner_name: 'RudderStack', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'tiktok_ads', + description: 'Test 16', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: '21e13f4bc7ceddad', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + locale: 'en-US', + ip: '13.57.97.131', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + externalId: [ + { + type: 'tiktokExternalId', + id: 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ], + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + timestamp: '2020-09-17T19:49:27Z', + type: 'track', + event: 'order completed', + properties: { + eventId: '1616318632825_357', + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + }, + }, + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + currency: 'USD', + value: 46, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + accessToken: 'dummyAccessToken', + pixelCode: 'A1T8T4UYGVIQA8ORZMX9', + hashUserProperties: false, + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://business-api.tiktok.com/open_api/v1.3/pixel/track/', + headers: { + 'Access-Token': 'dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + pixel_code: 'A1T8T4UYGVIQA8ORZMX9', + event: 'PlaceAnOrder', + event_id: '1616318632825_357', + timestamp: '2020-09-17T19:49:27Z', + properties: { + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + currency: 'USD', + value: 46, + }, + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + external_id: + 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ip: '13.57.97.131', + user_agent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + }, + partner_name: 'RudderStack', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'tiktok_ads', + description: 'Test 17', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: '21e13f4bc7ceddad', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'user@sample.com', + phone: '+919912345678', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + locale: 'en-US', + ip: '13.57.97.131', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + externalId: [ + { + type: 'tiktokExternalId', + id: 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ], + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + timestamp: '2020-09-17T19:49:27Z', + type: 'track', + event: 'SubscriBe', + properties: { + eventId: '1616318632825_357', + testEventCode: 'TEST0000000011', + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: '+918987674657', + email: 'sample@rudder.com', + }, + }, + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + currency: 'USD', + value: 46, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + accessToken: 'dummyAccessToken', + pixelCode: 'A1T8T4UYGVIQA8ORZMX9', + hashUserProperties: true, + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://business-api.tiktok.com/open_api/v1.3/pixel/track/', + headers: { + 'Access-Token': 'dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + pixel_code: 'A1T8T4UYGVIQA8ORZMX9', + event: 'Subscribe', + event_id: '1616318632825_357', + timestamp: '2020-09-17T19:49:27Z', + test_event_code: 'TEST0000000011', + properties: { + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + currency: 'USD', + value: 46, + }, + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '1b6abcebb79b2208929967160ba291656f3fcd4f00e93b6a846c1e56c0e177c6', + email: '02e47a94635c1ffd6f6a69fe2c7a92dbfbb9d5e2ebddb54810520b34989b66a7', + external_id: + 'f0f3ec74bbef8580d7de80624dea93c05d828c748715199fe71bc7f5a67aa8b3', + }, + ip: '13.57.97.131', + user_agent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + }, + partner_name: 'RudderStack', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'tiktok_ads', + description: 'Test 18', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: '21e13f4bc7ceddad', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'user@sample.com', + phone: '+919912345678', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + locale: 'en-US', + ip: '13.57.97.131', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + externalId: [ + { + type: 'tiktokExternalId', + id: 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ], + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + timestamp: '2020-09-17T19:49:27Z', + type: 'track', + event: 'SubscriBe', + properties: { + eventId: '1616318632825_357', + testEventCode: 'TEST0000000011', + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: '', + email: '', + }, + }, + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + currency: 'USD', + value: 46, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + accessToken: 'dummyAccessToken', + pixelCode: 'A1T8T4UYGVIQA8ORZMX9', + hashUserProperties: true, + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://business-api.tiktok.com/open_api/v1.3/pixel/track/', + headers: { + 'Access-Token': 'dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + pixel_code: 'A1T8T4UYGVIQA8ORZMX9', + event: 'Subscribe', + event_id: '1616318632825_357', + timestamp: '2020-09-17T19:49:27Z', + test_event_code: 'TEST0000000011', + properties: { + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + currency: 'USD', + value: 46, + }, + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '241102c24fa8a642e3d1346a31fbce3dd312563c015ae577a2253cb8652581eb', + email: 'a344da1fac6201ed1c1f20a07e1b55bb896a5ac0abd269c1e9daf1afbbffca3b', + external_id: + 'f0f3ec74bbef8580d7de80624dea93c05d828c748715199fe71bc7f5a67aa8b3', + }, + ip: '13.57.97.131', + user_agent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + }, + partner_name: 'RudderStack', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'tiktok_ads', + description: 'Test 19', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: '21e13f4bc7ceddad', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + ip: '13.57.97.131', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + page: { + url: 'http://rudder.mywebsite.com/purchase', + referrer: 'http://rudder.mywebsite.com', + }, + externalId: [ + { + type: 'tiktokExternalId', + id: 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ], + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + timestamp: '2020-09-17T19:49:27Z', + type: 'track', + event: 'checkout step completed', + properties: { + eventId: '1616318632825_357', + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + currency: 'USD', + value: 46, + context: { + user: { + phone_number: + '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + }, + }, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + accessToken: 'dummyAccessToken', + pixelCode: 'A1T8T4UYGVIQA8ORZMX9', + hashUserProperties: false, + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://business-api.tiktok.com/open_api/v1.3/pixel/track/', + headers: { + 'Access-Token': 'dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + pixel_code: 'A1T8T4UYGVIQA8ORZMX9', + event: 'CompletePayment', + event_id: '1616318632825_357', + timestamp: '2020-09-17T19:49:27Z', + properties: { + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + currency: 'USD', + value: 46, + }, + context: { + page: { + url: 'http://rudder.mywebsite.com/purchase', + referrer: 'http://rudder.mywebsite.com', + }, + user: { + phone_number: + '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + external_id: + 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ip: '13.57.97.131', + user_agent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + }, + partner_name: 'RudderStack', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'tiktok_ads', + description: 'Test 20', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: '21e13f4bc7ceddad', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + ip: '13.57.97.131', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + externalId: [ + { + type: 'tiktokExternalId', + id: 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ], + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + timestamp: '2020-09-17T19:49:27Z', + type: 'track', + event: 'abc', + properties: { + eventId: '1616318632825_357', + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + currency: 'USD', + value: 46, + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + }, + }, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + accessToken: 'dummyAccessToken', + pixelCode: 'A1T8T4UYGVIQA8ORZMX9', + hashUserProperties: false, + eventsToStandard: [ + { + from: 'abc', + to: 'download', + }, + { + from: 'abc', + to: 'search', + }, + { + from: 'def', + to: 'search', + }, + ], + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://business-api.tiktok.com/open_api/v1.3/pixel/track/', + headers: { + 'Access-Token': 'dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + pixel_code: 'A1T8T4UYGVIQA8ORZMX9', + event: 'download', + event_id: '1616318632825_357', + timestamp: '2020-09-17T19:49:27Z', + properties: { + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + currency: 'USD', + value: 46, + }, + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + external_id: + 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ip: '13.57.97.131', + user_agent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + }, + partner_name: 'RudderStack', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://business-api.tiktok.com/open_api/v1.3/pixel/track/', + headers: { + 'Access-Token': 'dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + pixel_code: 'A1T8T4UYGVIQA8ORZMX9', + event: 'search', + event_id: '1616318632825_357', + timestamp: '2020-09-17T19:49:27Z', + properties: { + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + currency: 'USD', + value: 46, + }, + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + external_id: + 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ip: '13.57.97.131', + user_agent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + }, + partner_name: 'RudderStack', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'tiktok_ads', + description: 'Test 21', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: '21e13f4bc7ceddad', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + ip: '13.57.97.131', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + externalId: [ + { + type: 'tiktokExternalId', + id: 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ], + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + timestamp: '2020-09-17T19:49:27Z', + type: 'track', + event: 'abc', + properties: { + eventId: '1616318632825_357', + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + currency: 'USD', + value: 46, + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + }, + }, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + accessToken: 'dummyAccessToken', + pixelCode: 'A1T8T4UYGVIQA8ORZMX9', + hashUserProperties: false, + eventsToStandard: [ + { + from: 'def', + to: 'download', + }, + ], + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + statusCode: 400, + error: 'Event name (abc) is not valid, must be mapped to one of standard events', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'TIKTOK_ADS', + module: 'destination', + implementation: 'native', + feature: 'processor', + }, + }, + ], + }, + }, + }, + { + name: 'tiktok_ads', + description: 'Test 22', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: '21e13f4bc7ceddad', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + ip: '13.57.97.131', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + externalId: [ + { + type: 'tiktokExternalId', + id: 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ], + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + timestamp: '2020-09-17T19:49:27Z', + type: 'track', + event: 'abc', + properties: { + eventId: '1616318632825_357', + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + currency: 'USD', + value: 46, + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + }, + }, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + accessToken: 'dummyAccessToken', + pixelCode: 'A1T8T4UYGVIQA8ORZMX9', + hashUserProperties: false, + eventsToStandard: [ + { + from: 'abc', + to: 'download', + }, + { + from: 'def', + to: 'download', + }, + ], + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://business-api.tiktok.com/open_api/v1.3/pixel/track/', + headers: { + 'Access-Token': 'dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + pixel_code: 'A1T8T4UYGVIQA8ORZMX9', + event: 'download', + event_id: '1616318632825_357', + timestamp: '2020-09-17T19:49:27Z', + properties: { + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + currency: 'USD', + value: 46, + }, + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + external_id: + 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ip: '13.57.97.131', + user_agent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + }, + partner_name: 'RudderStack', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'tiktok_ads', + description: 'Test 23', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: '21e13f4bc7ceddad', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + ip: '13.57.97.131', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + externalId: [ + { + type: 'tiktokExternalId', + id: 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ], + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + timestamp: '2020-09-17T19:49:27Z', + type: 'track', + event: 'abc', + properties: { + eventId: '1616318632825_357', + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + currency: 'USD', + value: 46, + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: '+371234567890123', + email: 'sample@sample.com', + }, + }, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + accessToken: 'dummyAccessToken', + pixelCode: 'A1T8T4UYGVIQA8ORZMX9', + hashUserProperties: true, + eventsToStandard: [ + { + from: 'abc', + to: 'download', + }, + { + from: 'def', + to: 'download', + }, + ], + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://business-api.tiktok.com/open_api/v1.3/pixel/track/', + headers: { + 'Access-Token': 'dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + pixel_code: 'A1T8T4UYGVIQA8ORZMX9', + event: 'download', + event_id: '1616318632825_357', + timestamp: '2020-09-17T19:49:27Z', + properties: { + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + currency: 'USD', + value: 46, + }, + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '6080191ec608e10062e9257702cbca694cfe1bfa53944ba5701119d8f8b99ad6', + email: '774efc08cebab8c50c0f0eb2d3a2d2e560872a64f6c1617314c4f03b1c3d4dfa', + external_id: + 'f0f3ec74bbef8580d7de80624dea93c05d828c748715199fe71bc7f5a67aa8b3', + }, + ip: '13.57.97.131', + user_agent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + }, + partner_name: 'RudderStack', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'tiktok_ads', + description: 'Test 24', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: '21e13f4bc7ceddad', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + ip: '13.57.97.131', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + externalId: [ + { + type: 'tiktokExternalId', + id: 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ], + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + timestamp: '2020-09-17T19:49:27Z', + type: 'track', + event: 'abc', + properties: { + eventId: '1616318632825_357', + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + currency: 'USD', + value: 46, + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: '+3712345678', + email: 'sample@sample.com', + }, + }, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + accessToken: 'dummyAccessToken', + pixelCode: 'A1T8T4UYGVIQA8ORZMX9', + hashUserProperties: true, + eventsToStandard: [ + { + from: 'abc', + to: 'download', + }, + { + from: 'def', + to: 'download', + }, + ], + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://business-api.tiktok.com/open_api/v1.3/pixel/track/', + headers: { + 'Access-Token': 'dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + pixel_code: 'A1T8T4UYGVIQA8ORZMX9', + event: 'download', + event_id: '1616318632825_357', + timestamp: '2020-09-17T19:49:27Z', + properties: { + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + currency: 'USD', + value: 46, + }, + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '6e6c1bb39126b3ecf537e62847909b1372a1a22de9b28d85960e12c78f322035', + email: '774efc08cebab8c50c0f0eb2d3a2d2e560872a64f6c1617314c4f03b1c3d4dfa', + external_id: + 'f0f3ec74bbef8580d7de80624dea93c05d828c748715199fe71bc7f5a67aa8b3', + }, + ip: '13.57.97.131', + user_agent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + }, + partner_name: 'RudderStack', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'tiktok_ads', + description: 'Test 25', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: '21e13f4bc7ceddad', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + ip: '13.57.97.131', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + externalId: [ + { + type: 'tiktokExternalId', + id: 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ], + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + timestamp: '2020-09-17T19:49:27Z', + type: 'track', + event: 'checkout step completed', + properties: { + eventId: '1616318632825_357', + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + products: [ + { + product_id: 123, + sku: 'G-32', + name: 'Monopoly', + price: 14, + quantity: 1, + category: 'Games', + url: 'https://www.website.com/product/path', + image_url: 'https://www.website.com/product/path.jpg', + }, + { + product_id: '345', + sku: 'F-32', + name: 'UNO', + price: 3.45, + quantity: 2, + category: 'Games', + }, + ], + currency: 'USD', + value: 46, + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + }, + }, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + accessToken: 'dummyAccessToken', + pixelCode: 'A1T8T4UYGVIQA8ORZMX9', + hashUserProperties: false, + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://business-api.tiktok.com/open_api/v1.3/pixel/track/', + headers: { + 'Access-Token': 'dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + pixel_code: 'A1T8T4UYGVIQA8ORZMX9', + event: 'CompletePayment', + event_id: '1616318632825_357', + timestamp: '2020-09-17T19:49:27Z', + properties: { + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + currency: 'USD', + value: 46, + }, + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + external_id: + 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ip: '13.57.97.131', + user_agent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + }, + partner_name: 'RudderStack', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'tiktok_ads', + description: 'Test 26', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: '21e13f4bc7ceddad', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + ip: '13.57.97.131', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + externalId: [ + { + type: 'tiktokExternalId', + id: 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ], + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + timestamp: '2020-09-17T19:49:27Z', + type: 'track', + event: 'checkout step completed', + properties: { + eventId: '1616318632825_357', + products: [ + { + product_id: 123, + sku: 'G-32', + name: 'Monopoly', + price: 14, + quantity: 1, + contentType: 'product_group', + category: 'Games', + url: 'https://www.website.com/product/path', + image_url: 'https://www.website.com/product/path.jpg', + }, + { + product_id: 345, + sku: 'F-32', + name: 'UNO', + price: 3.45, + contentType: 'product_group', + quantity: 2, + }, + ], + currency: 'USD', + value: 46, + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + }, + }, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + accessToken: 'dummyAccessToken', + pixelCode: 'A1T8T4UYGVIQA8ORZMX9', + hashUserProperties: false, + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://business-api.tiktok.com/open_api/v1.3/pixel/track/', + headers: { + 'Access-Token': 'dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + pixel_code: 'A1T8T4UYGVIQA8ORZMX9', + event: 'CompletePayment', + event_id: '1616318632825_357', + timestamp: '2020-09-17T19:49:27Z', + properties: { + currency: 'USD', + value: 46, + contents: [ + { + content_type: 'product_group', + content_id: '123', + content_category: 'Games', + content_name: 'Monopoly', + price: 14, + quantity: 1, + }, + { + content_type: 'product_group', + content_id: '345', + content_name: 'UNO', + price: 3.45, + quantity: 2, + }, + ], + }, + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + external_id: + 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ip: '13.57.97.131', + user_agent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + }, + partner_name: 'RudderStack', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'tiktok_ads', + description: 'Test 27', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: '21e13f4bc7ceddad', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + ip: '13.57.97.131', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + externalId: [ + { + type: 'tiktokExternalId', + id: 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ], + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + timestamp: '2020-09-17T19:49:27Z', + type: 'track', + event: 'checkout step completed', + properties: { + eventId: '1616318632825_357', + products: [ + { + contentType: 'product_group', + product_id: '123', + sku: 'G-32', + name: 'Monopoly', + price: 14, + quantity: 1, + category: 'Games', + url: 'https://www.website.com/product/path', + image_url: 'https://www.website.com/product/path.jpg', + }, + { + contentType: 'product_group', + product_id: '345', + sku: 'F-32', + name: 'UNO', + price: 3.45, + quantity: 2, + category: 'Games', + }, + ], + currency: 'USD', + value: 46, + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + }, + }, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + accessToken: 'dummyAccessToken', + pixelCode: 'A1T8T4UYGVIQA8ORZMX9', + hashUserProperties: false, + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://business-api.tiktok.com/open_api/v1.3/pixel/track/', + headers: { + 'Access-Token': 'dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + pixel_code: 'A1T8T4UYGVIQA8ORZMX9', + event: 'CompletePayment', + event_id: '1616318632825_357', + timestamp: '2020-09-17T19:49:27Z', + properties: { + currency: 'USD', + value: 46, + contents: [ + { + content_type: 'product_group', + content_id: '123', + content_category: 'Games', + content_name: 'Monopoly', + price: 14, + quantity: 1, + }, + { + content_type: 'product_group', + content_id: '345', + content_category: 'Games', + content_name: 'UNO', + price: 3.45, + quantity: 2, + }, + ], + }, + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + external_id: + 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ip: '13.57.97.131', + user_agent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + }, + partner_name: 'RudderStack', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'tiktok_ads', + description: 'Test 28', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: '21e13f4bc7ceddad', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + ip: '13.57.97.131', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + externalId: [ + { + type: 'tiktokExternalId', + id: 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ], + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + timestamp: '2020-09-17T19:49:27Z', + type: 'track', + event: 'checkout step completed', + properties: { + category: 'Urban', + status: 'processed', + name: 'games', + contentType: 'product_group', + productId: 'qqw21221341234', + eventId: '1616318632825_357', + products: [ + { + product_id: '123', + sku: 'G-32', + name: 'Monopoly', + price: 14, + quantity: 1, + category: 'Games', + url: 'https://www.website.com/product/path', + image_url: 'https://www.website.com/product/path.jpg', + }, + { + product_id: '345', + sku: 'F-32', + name: 'UNO', + price: 3.45, + quantity: 2, + category: 'Games', + }, + ], + currency: 'USD', + value: 46, + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + }, + }, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + accessToken: 'dummyAccessToken', + pixelCode: 'A1T8T4UYGVIQA8ORZMX9', + hashUserProperties: false, + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://business-api.tiktok.com/open_api/v1.3/pixel/track/', + headers: { + 'Access-Token': 'dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + pixel_code: 'A1T8T4UYGVIQA8ORZMX9', + event: 'CompletePayment', + event_id: '1616318632825_357', + timestamp: '2020-09-17T19:49:27Z', + properties: { + content_category: 'Urban', + status: 'processed', + content_name: 'games', + content_id: 'qqw21221341234', + content_type: 'product_group', + currency: 'USD', + value: 46, + contents: [ + { + content_type: 'product_group', + content_id: '123', + content_category: 'Games', + content_name: 'Monopoly', + price: 14, + quantity: 1, + }, + { + content_type: 'product_group', + content_id: '345', + content_category: 'Games', + content_name: 'UNO', + price: 3.45, + quantity: 2, + }, + ], + }, + context: { + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + external_id: + 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ip: '13.57.97.131', + user_agent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + }, + partner_name: 'RudderStack', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/tiktok_ads/router/data.ts b/test/integrations/destinations/tiktok_ads/router/data.ts index 60bb5628ca..a8c233c7a8 100644 --- a/test/integrations/destinations/tiktok_ads/router/data.ts +++ b/test/integrations/destinations/tiktok_ads/router/data.ts @@ -52,6 +52,7 @@ export const data = [ event: 'checkout step completed', properties: { eventId: '1616318632825_357', + clickId: 'dummyClickId', contents: [ { price: 8, @@ -69,9 +70,6 @@ export const data = [ currency: 'USD', value: 46.0, context: { - ad: { - callback: '123ATXSfe', - }, page: { url: 'http://demo.mywebsite.com/purchase', referrer: 'http://demo.mywebsite.com', @@ -141,9 +139,6 @@ export const data = [ properties: { eventId: '1616318632825_357', context: { - ad: { - callback: '123ATXSfe', - }, page: { url: 'http://demo.mywebsite.com/purchase', referrer: 'http://demo.mywebsite.com', @@ -229,9 +224,6 @@ export const data = [ properties: { eventId: '1616318632825_357', context: { - ad: { - callback: '123ATXSfe', - }, page: { url: 'http://demo.mywebsite.com/purchase', referrer: 'http://demo.mywebsite.com', @@ -320,9 +312,6 @@ export const data = [ properties: { eventId: '1616318632825_357', context: { - ad: { - callback: '123ATXSfe', - }, page: { url: 'http://demo.mywebsite.com/purchase', referrer: 'http://demo.mywebsite.com', @@ -421,7 +410,7 @@ export const data = [ }, context: { ad: { - callback: '123ATXSfe', + callback: 'dummyClickId', }, page: { url: 'http://demo.mywebsite.com/purchase', @@ -446,9 +435,6 @@ export const data = [ type: 'track', timestamp: '2020-09-17T19:49:27Z', context: { - ad: { - callback: '123ATXSfe', - }, ip: '13.57.97.131', page: { url: 'http://demo.mywebsite.com/purchase', @@ -490,9 +476,6 @@ export const data = [ type: 'track', timestamp: '2020-09-17T19:49:27Z', context: { - ad: { - callback: '123ATXSfe', - }, ip: '13.57.97.131', page: { url: 'http://demo.mywebsite.com/purchase', @@ -534,9 +517,6 @@ export const data = [ type: 'track', timestamp: '2020-09-17T19:49:27Z', context: { - ad: { - callback: '123ATXSfe', - }, ip: '13.57.97.131', page: { url: 'http://demo.mywebsite.com/purchase', @@ -662,9 +642,6 @@ export const data = [ eventId: '1616318632825_357', testEventCode: 'sample rudder test_event_code', context: { - ad: { - callback: '123ATXSfe', - }, page: { url: 'http://demo.mywebsite.com/purchase', referrer: 'http://demo.mywebsite.com', @@ -729,9 +706,6 @@ export const data = [ FORM: {}, JSON: { context: { - ad: { - callback: '123ATXSfe', - }, ip: '13.57.97.131', page: { referrer: 'http://demo.mywebsite.com', From 195b48ac0f438a200933e4bbb956fcc3941b7aed Mon Sep 17 00:00:00 2001 From: AASHISH MALIK Date: Fri, 10 Nov 2023 20:35:31 +0530 Subject: [PATCH 30/93] feat: move cdkV1 to cdkv2 component tests (#2804) * feat: move cdkV1 to cdkv2 component test --- src/cdk/v2/handler.ts | 10 +- .../data_scenarios/cdk_v2/failure.json | 3 +- .../destinations/algolia/processor/data.ts | 220 +- .../destinations/autopilot/processor/data.ts | 78 +- .../dcm_floodlight/processor/data.ts | 5003 +++++++++++++++++ .../dynamic_yield/processor/data.ts | 1041 ++++ .../destinations/eloqua/processor/data.ts | 460 ++ .../destinations/fullstory/processor/data.ts | 462 ++ .../destinations/heap/processor/data.ts | 84 +- .../destinations/kochava/processor/data.ts | 136 +- .../launchdarkly_audience/processor/data.ts | 611 ++ .../destinations/lytics/processor/data.ts | 117 +- .../destinations/new_relic/processor/data.ts | 882 +++ .../optimizely_fullstack/processor/data.ts | 37 +- .../destinations/ortto/processor/data.ts | 15 +- .../pinterest_tag/processor/data.ts | 24 +- .../destinations/userlist/processor/data.ts | 894 +++ .../destinations/vitally/processor/data.ts | 300 + test/integrations/destinations/zapier/data.ts | 50 +- 19 files changed, 10302 insertions(+), 125 deletions(-) create mode 100644 test/integrations/destinations/dcm_floodlight/processor/data.ts create mode 100644 test/integrations/destinations/dynamic_yield/processor/data.ts create mode 100644 test/integrations/destinations/eloqua/processor/data.ts create mode 100644 test/integrations/destinations/fullstory/processor/data.ts create mode 100644 test/integrations/destinations/launchdarkly_audience/processor/data.ts create mode 100644 test/integrations/destinations/new_relic/processor/data.ts create mode 100644 test/integrations/destinations/userlist/processor/data.ts create mode 100644 test/integrations/destinations/vitally/processor/data.ts diff --git a/src/cdk/v2/handler.ts b/src/cdk/v2/handler.ts index 4b3868b85b..3058d62e51 100644 --- a/src/cdk/v2/handler.ts +++ b/src/cdk/v2/handler.ts @@ -65,13 +65,9 @@ export function getCachedWorkflowEngine( } export async function executeWorkflow(workflowEngine: WorkflowEngine, parsedEvent: FixMe) { - try { - const result = await workflowEngine.execute(parsedEvent); - // TODO: Handle remaining output scenarios - return result.output; - } catch (error) { - throw getErrorInfo(error, isCdkV2Destination(parsedEvent), defTags); - } + const result = await workflowEngine.execute(parsedEvent); + // TODO: Handle remaining output scenarios + return result.output; } export async function processCdkV2Workflow( diff --git a/test/apitests/data_scenarios/cdk_v2/failure.json b/test/apitests/data_scenarios/cdk_v2/failure.json index f39d351b2d..1635a3f0db 100644 --- a/test/apitests/data_scenarios/cdk_v2/failure.json +++ b/test/apitests/data_scenarios/cdk_v2/failure.json @@ -646,7 +646,8 @@ "statusCode": 400, "error": "Action source must be one of app_android, app_ios, web, offline: Workflow: procWorkflow, Step: validateCommonFields, ChildStep: undefined, OriginalError: Action source must be one of app_android, app_ios, web, offline", "statTags": { - "errorCategory": "platform", + "errorCategory": "dataValidation", + "errorType": "instrumentation", "implementation": "cdkV2", "destType": "PINTEREST_TAG", "module": "destination", diff --git a/test/integrations/destinations/algolia/processor/data.ts b/test/integrations/destinations/algolia/processor/data.ts index f5c01e47e5..0cbdd8b31b 100644 --- a/test/integrations/destinations/algolia/processor/data.ts +++ b/test/integrations/destinations/algolia/processor/data.ts @@ -66,6 +66,13 @@ export const data = [ sentAt: '2019-10-14T09:03:22.563Z', }, destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + excludeKeys: [], + includeKeys: [], + }, + }, Config: { apiKey: 'dummyApiKey', applicationId: 'O2YARRI15I', @@ -77,6 +84,10 @@ export const data = [ ], }, }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, @@ -116,6 +127,10 @@ export const data = [ version: '1', }, statusCode: 200, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, @@ -197,7 +212,18 @@ export const data = [ }, sentAt: '2019-10-14T09:03:22.563Z', }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + excludeKeys: [], + includeKeys: [], + }, + }, Config: { apiKey: 'dummyApiKey', applicationId: 'O2YARRI15I', @@ -250,6 +276,10 @@ export const data = [ version: '1', }, statusCode: 200, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, @@ -322,7 +352,18 @@ export const data = [ }, sentAt: '2019-10-14T09:03:22.563Z', }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + excludeKeys: [], + includeKeys: [], + }, + }, Config: { apiKey: 'dummyApiKey', applicationId: 'O2YARRI15I', @@ -338,16 +379,23 @@ export const data = [ status: 200, body: [ { - error: 'Either filters or objectIds is required.', + error: + 'Either filters or objectIds is required.: Workflow: procWorkflow, Step: validateDestPayload, ChildStep: undefined, OriginalError: Either filters or objectIds is required.', statTags: { destType: 'ALGOLIA', errorCategory: 'dataValidation', errorType: 'instrumentation', feature: 'processor', - implementation: 'native', + implementation: 'cdkV2', module: 'destination', + destinationId: 'destId', + workspaceId: 'wspId', }, statusCode: 400, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, @@ -419,7 +467,18 @@ export const data = [ }, sentAt: '2019-10-14T09:03:22.563Z', }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + excludeKeys: [], + includeKeys: [], + }, + }, Config: { apiKey: 'dummyApiKey', applicationId: 'O2YARRI15I', @@ -435,16 +494,23 @@ export const data = [ status: 200, body: [ { - error: 'eventType is mandatory for track call', + error: + 'eventType is mandatory for track call: Workflow: procWorkflow, Step: preparePayload, ChildStep: undefined, OriginalError: eventType is mandatory for track call', statTags: { destType: 'ALGOLIA', errorCategory: 'dataValidation', errorType: 'instrumentation', feature: 'processor', - implementation: 'native', + implementation: 'cdkV2', module: 'destination', + destinationId: 'destId', + workspaceId: 'wspId', }, statusCode: 400, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, @@ -526,7 +592,18 @@ export const data = [ }, sentAt: '2019-10-14T09:03:22.563Z', }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + excludeKeys: [], + includeKeys: [], + }, + }, Config: { apiKey: 'dummyApiKey', applicationId: 'O2YARRI15I', @@ -548,16 +625,22 @@ export const data = [ body: [ { error: - 'for click eventType either both positions and queryId should be present or none', + 'for click eventType either both positions and queryId should be present or none: Workflow: procWorkflow, Step: validatePayloadForClickEvent, ChildStep: undefined, OriginalError: for click eventType either both positions and queryId should be present or none', statTags: { destType: 'ALGOLIA', errorCategory: 'dataValidation', errorType: 'instrumentation', feature: 'processor', - implementation: 'native', + implementation: 'cdkV2', module: 'destination', + destinationId: 'destId', + workspaceId: 'wspId', }, statusCode: 400, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, @@ -639,7 +722,18 @@ export const data = [ }, sentAt: '2019-10-14T09:03:22.563Z', }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + excludeKeys: [], + includeKeys: [], + }, + }, Config: { apiKey: 'dummyApiKey', applicationId: 'O2YARRI15I', @@ -691,6 +785,10 @@ export const data = [ version: '1', }, statusCode: 200, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, @@ -772,7 +870,18 @@ export const data = [ }, sentAt: '2019-10-14T09:03:22.563Z', }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + excludeKeys: [], + includeKeys: [], + }, + }, Config: { apiKey: 'dummyApiKey', applicationId: 'O2YARRI15I', @@ -794,16 +903,22 @@ export const data = [ body: [ { error: - 'for click eventType either both positions and queryId should be present or none', + 'for click eventType either both positions and queryId should be present or none: Workflow: procWorkflow, Step: validatePayloadForClickEvent, ChildStep: undefined, OriginalError: for click eventType either both positions and queryId should be present or none', statTags: { destType: 'ALGOLIA', errorCategory: 'dataValidation', errorType: 'instrumentation', feature: 'processor', - implementation: 'native', + implementation: 'cdkV2', module: 'destination', + destinationId: 'destId', + workspaceId: 'wspId', }, statusCode: 400, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, @@ -885,7 +1000,18 @@ export const data = [ }, sentAt: '2019-10-14T09:03:22.563Z', }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + excludeKeys: [], + includeKeys: [], + }, + }, Config: { apiKey: 'dummyApiKey', applicationId: 'O2YARRI15I', @@ -906,16 +1032,23 @@ export const data = [ status: 200, body: [ { - error: 'eventType can be either click, view or conversion', + error: + 'eventType can be either click, view or conversion: Workflow: procWorkflow, Step: preparePayload, ChildStep: undefined, OriginalError: eventType can be either click, view or conversion', statTags: { destType: 'ALGOLIA', errorCategory: 'dataValidation', errorType: 'instrumentation', feature: 'processor', - implementation: 'native', + implementation: 'cdkV2', module: 'destination', + destinationId: 'destId', + workspaceId: 'wspId', }, statusCode: 400, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, @@ -997,7 +1130,18 @@ export const data = [ }, sentAt: '2019-10-14T09:03:22.563Z', }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + excludeKeys: [], + includeKeys: [], + }, + }, Config: { apiKey: 'dummyApiKey', applicationId: 'O2YARRI15I', @@ -1012,16 +1156,23 @@ export const data = [ status: 200, body: [ { - error: 'eventType is mandatory for track call', + error: + 'eventType is mandatory for track call: Workflow: procWorkflow, Step: preparePayload, ChildStep: undefined, OriginalError: eventType is mandatory for track call', statTags: { destType: 'ALGOLIA', errorCategory: 'dataValidation', errorType: 'instrumentation', feature: 'processor', - implementation: 'native', + implementation: 'cdkV2', module: 'destination', + destinationId: 'destId', + workspaceId: 'wspId', }, statusCode: 400, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, @@ -1092,7 +1243,18 @@ export const data = [ }, sentAt: '2019-10-14T09:03:22.563Z', }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + excludeKeys: [], + includeKeys: [], + }, + }, Config: { apiKey: 'dummyApiKey', applicationId: 'O2YARRI15I', @@ -1113,16 +1275,24 @@ export const data = [ status: 200, body: [ { - error: 'Missing required value from "properties.index"', + error: + 'Missing required value from "properties.index": Workflow: procWorkflow, Step: preparePayload, ChildStep: undefined, OriginalError: Missing required value from "properties.index"', statTags: { destType: 'ALGOLIA', errorCategory: 'dataValidation', errorType: 'instrumentation', feature: 'processor', - implementation: 'native', + implementation: 'cdkV2', module: 'destination', + + destinationId: 'destId', + workspaceId: 'wspId', }, statusCode: 400, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, @@ -1193,7 +1363,18 @@ export const data = [ }, sentAt: '2019-10-14T09:03:22.563Z', }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + excludeKeys: [], + includeKeys: [], + }, + }, Config: { apiKey: 'dummyApiKey', applicationId: 'O2YARRI15I', @@ -1214,16 +1395,23 @@ export const data = [ status: 200, body: [ { - error: 'event name should be a string', + error: + 'event name should be a string: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: event name should be a string', statTags: { destType: 'ALGOLIA', errorCategory: 'dataValidation', errorType: 'instrumentation', feature: 'processor', - implementation: 'native', + implementation: 'cdkV2', module: 'destination', + destinationId: 'destId', + workspaceId: 'wspId', }, statusCode: 400, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, diff --git a/test/integrations/destinations/autopilot/processor/data.ts b/test/integrations/destinations/autopilot/processor/data.ts index 8ae3e28671..135e3e22f7 100644 --- a/test/integrations/destinations/autopilot/processor/data.ts +++ b/test/integrations/destinations/autopilot/processor/data.ts @@ -17,7 +17,7 @@ export const data = [ Name: 'AUTOPILOT', DisplayName: 'Autopilot', Config: { - cdkEnabled: true, + cdkV2Enabled: true, excludeKeys: [], includeKeys: [], }, @@ -85,6 +85,10 @@ export const data = [ type: 'identify', userId: 'user12345', }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, @@ -123,6 +127,10 @@ export const data = [ userId: 'ac7722c2-ccb6-4ae2-baf6-1effe861f4cd', }, statusCode: 200, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, @@ -146,7 +154,7 @@ export const data = [ Name: 'AUTOPILOT', DisplayName: 'Autopilot', Config: { - cdkEnabled: true, + cdkV2Enabled: true, excludeKeys: [], includeKeys: [], }, @@ -219,6 +227,10 @@ export const data = [ type: 'track', userId: 'user12345', }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, @@ -255,6 +267,10 @@ export const data = [ userId: 'ac7722c2-ccb6-4ae2-baf6-1effe861f4cd', }, statusCode: 200, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, @@ -278,7 +294,7 @@ export const data = [ Name: 'AUTOPILOT', DisplayName: 'Autopilot', Config: { - cdkEnabled: true, + cdkV2Enabled: true, excludeKeys: [], includeKeys: [], }, @@ -365,7 +381,8 @@ export const data = [ body: [ { statusCode: 400, - error: 'Bad event. Original error: message type "page" not supported for "autopilot"', + error: + 'message type page is not supported: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: message type page is not supported', metadata: { destinationId: 'destId', workspaceId: 'wspId', @@ -375,7 +392,7 @@ export const data = [ errorType: 'instrumentation', destType: 'AUTOPILOT', module: 'destination', - implementation: 'cdkV1', + implementation: 'cdkV2', feature: 'processor', destinationId: 'destId', workspaceId: 'wspId', @@ -403,7 +420,7 @@ export const data = [ Name: 'AUTOPILOT', DisplayName: 'Autopilot', Config: { - cdkEnabled: true, + cdkV2Enabled: true, excludeKeys: [], includeKeys: [], }, @@ -489,16 +506,18 @@ export const data = [ body: [ { statusCode: 400, - error: 'Unknown error occurred. Original error: Email is required for track calls', + error: + 'Email is required for track calls: Workflow: procWorkflow, Step: preparePayloadForTrack, ChildStep: undefined, OriginalError: Email is required for track calls', metadata: { destinationId: 'destId', workspaceId: 'wspId', }, statTags: { - errorCategory: 'transformation', + errorCategory: 'dataValidation', + errorType: 'instrumentation', destType: 'AUTOPILOT', module: 'destination', - implementation: 'cdkV1', + implementation: 'cdkV2', feature: 'processor', destinationId: 'destId', workspaceId: 'wspId', @@ -526,7 +545,7 @@ export const data = [ Name: 'AUTOPILOT', DisplayName: 'Autopilot', Config: { - cdkEnabled: true, + cdkV2Enabled: true, excludeKeys: [], includeKeys: [], }, @@ -612,16 +631,17 @@ export const data = [ { statusCode: 400, error: - 'Unknown error occurred. Original error: "type" is a required field and it must be a string', + 'message Type is not present. Aborting message.: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: message Type is not present. Aborting message.', metadata: { destinationId: 'destId', workspaceId: 'wspId', }, statTags: { - errorCategory: 'transformation', + errorCategory: 'dataValidation', + errorType: 'instrumentation', destType: 'AUTOPILOT', module: 'destination', - implementation: 'cdkV1', + implementation: 'cdkV2', destinationId: 'destId', workspaceId: 'wspId', feature: 'processor', @@ -649,7 +669,7 @@ export const data = [ Name: 'AUTOPILOT', DisplayName: 'Autopilot', Config: { - cdkEnabled: true, + cdkV2Enabled: true, excludeKeys: [], includeKeys: [], }, @@ -736,7 +756,8 @@ export const data = [ body: [ { statusCode: 400, - error: 'Bad event. Original error: message type "group" not supported for "autopilot"', + error: + 'message type group is not supported: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: message type group is not supported', metadata: { destinationId: 'destId', workspaceId: 'wspId', @@ -746,7 +767,7 @@ export const data = [ errorType: 'instrumentation', destType: 'AUTOPILOT', module: 'destination', - implementation: 'cdkV1', + implementation: 'cdkV2', destinationId: 'destId', workspaceId: 'wspId', feature: 'processor', @@ -774,7 +795,7 @@ export const data = [ Name: 'AUTOPILOT', DisplayName: 'Autopilot', Config: { - cdkEnabled: true, + cdkV2Enabled: true, excludeKeys: [], includeKeys: [], }, @@ -906,7 +927,7 @@ export const data = [ Name: 'AUTOPILOT', DisplayName: 'Autopilot', Config: { - cdkEnabled: true, + cdkV2Enabled: true, excludeKeys: [], includeKeys: [], }, @@ -993,16 +1014,17 @@ export const data = [ { statusCode: 400, error: - 'Unknown error occurred. Original error: "type" is a required field and it must be a string', + 'message Type is not present. Aborting message.: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: message Type is not present. Aborting message.', metadata: { destinationId: 'destId', workspaceId: 'wspId', }, statTags: { - errorCategory: 'transformation', + errorCategory: 'dataValidation', + errorType: 'instrumentation', destType: 'AUTOPILOT', module: 'destination', - implementation: 'cdkV1', + implementation: 'cdkV2', destinationId: 'destId', workspaceId: 'wspId', feature: 'processor', @@ -1030,7 +1052,7 @@ export const data = [ Name: 'AUTOPILOT', DisplayName: 'Autopilot', Config: { - cdkEnabled: true, + cdkV2Enabled: true, excludeKeys: [], includeKeys: [], }, @@ -1110,7 +1132,8 @@ export const data = [ body: [ { statusCode: 400, - error: 'Bad event. Original error: message type "group" not supported for "autopilot"', + error: + 'message type group is not supported: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: message type group is not supported', metadata: { destinationId: 'destId', workspaceId: 'wspId', @@ -1120,7 +1143,7 @@ export const data = [ errorType: 'instrumentation', destType: 'AUTOPILOT', module: 'destination', - implementation: 'cdkV1', + implementation: 'cdkV2', destinationId: 'destId', workspaceId: 'wspId', feature: 'processor', @@ -1148,7 +1171,7 @@ export const data = [ Name: 'AUTOPILOT', DisplayName: 'Autopilot', Config: { - cdkEnabled: true, + cdkV2Enabled: true, excludeKeys: [], includeKeys: [], }, @@ -1228,7 +1251,8 @@ export const data = [ body: [ { statusCode: 400, - error: 'Bad event. Original error: message type "Tals" not supported for "autopilot"', + error: + 'message type Tals is not supported: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: message type Tals is not supported', metadata: { destinationId: 'destId', workspaceId: 'wspId', @@ -1238,7 +1262,7 @@ export const data = [ errorType: 'instrumentation', destType: 'AUTOPILOT', module: 'destination', - implementation: 'cdkV1', + implementation: 'cdkV2', destinationId: 'destId', workspaceId: 'wspId', feature: 'processor', diff --git a/test/integrations/destinations/dcm_floodlight/processor/data.ts b/test/integrations/destinations/dcm_floodlight/processor/data.ts new file mode 100644 index 0000000000..e4b582a3f7 --- /dev/null +++ b/test/integrations/destinations/dcm_floodlight/processor/data.ts @@ -0,0 +1,5003 @@ +export const data = [ + { + name: 'dcm_floodlight', + description: 'Test 0', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + advertiserId: '22448662', + activityTag: '', + groupTag: '', + conversionEvents: [ + { + customVariables: [ + { + from: 'rudder1', + to: '1', + }, + { + from: 'rudder2', + to: '2', + }, + ], + eventName: 'Product viewed', + floodlightActivityTag: 'signu01', + floodlightGroupTag: 'conv01', + salesTag: false, + }, + { + customVariables: [ + { + from: '', + to: '', + }, + ], + eventName: 'Order Complete', + floodlightActivityTag: 'signu01', + floodlightGroupTag: 'conv02', + salesTag: false, + }, + ], + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + message: { + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99090', + userId: '1234', + type: 'track', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + adTrackingEnabled: 'true', + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + ip: '0.0.0.0', + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + event: 'Product viewed', + properties: { + orderId: 111, + quantity: 2, + revenue: 800, + rudder1: 'rudder-v1', + rudder2: 'rudder-v2', + }, + integrations: { + All: true, + 'DCM Floodlight': { + COPPA: 'false', + GDPR: '1', + npa: true, + }, + }, + messageId: 'ea5cfab2-3961-4d8a-8187-3d1858c90a9f', + originalTimestamp: '2020-01-17T04:53:51.185Z', + receivedAt: '2020-01-17T10:23:52.688+05:30', + sentAt: '2020-01-17T04:53:52.667Z', + timestamp: '2020-01-17T10:23:51.206+05:30', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'GET', + endpoint: + 'https://ad.doubleclick.net/ddm/activity/src=22448662;cat=signu01;type=conv01;dc_rdid=T0T0T072-5e28-45a1-9eda-ce22a3e36d1a;ord=ea5cfab2-3961-4d8a-8187-3d1858c90a9f;dc_lat=1;tag_for_child_directed_treatment=0;tfua=1;npa=1;u1=rudder-v1;u2=rudder-v2', + headers: { + 'User-Agent': + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'dcm_floodlight', + description: 'Test 1', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + activityTag: '', + advertiserId: '12649566', + conversionEvents: [ + { + customVariables: [ + { + from: '', + to: '', + }, + ], + eventName: 'Sign up Completed', + floodlightActivityTag: 'signu0', + floodlightGroupTag: 'conv01', + salesTag: false, + }, + { + customVariables: [ + { + from: 'rudder1', + to: '1', + }, + { + from: 'akash2', + to: '2', + }, + ], + eventName: 'Order Complete', + floodlightActivityTag: 'order0', + floodlightGroupTag: 'conv000', + salesTag: false, + }, + { + customVariables: [ + { + from: '', + to: '', + }, + ], + eventName: 'Checkout Started', + floodlightActivityTag: 'check0', + floodlightGroupTag: 'conv00', + salesTag: true, + }, + ], + groupTag: '', + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + message: { + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99090', + userId: '1234', + type: 'track', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + adTrackingEnabled: 'true', + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + ip: '0.0.0.0', + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + event: 'Sign up Completed', + properties: { + orderId: 111, + quantity: 2, + revenue: 800, + }, + integrations: { + All: true, + 'DCM Floodlight': { + COPPA: 'false', + GDPR: '1', + npa: true, + }, + }, + messageId: 'ea5cfab2-3961-4d8a-8187-3d1858c90a9f', + originalTimestamp: '2020-01-17T04:53:51.185Z', + receivedAt: '2020-01-17T10:23:52.688+05:30', + sentAt: '2020-01-17T04:53:52.667Z', + timestamp: '2020-01-17T10:23:51.206+05:30', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'GET', + endpoint: + 'https://ad.doubleclick.net/ddm/activity/src=12649566;cat=signu0;type=conv01;dc_rdid=T0T0T072-5e28-45a1-9eda-ce22a3e36d1a;ord=ea5cfab2-3961-4d8a-8187-3d1858c90a9f;dc_lat=1;tag_for_child_directed_treatment=0;tfua=1;npa=1', + headers: { + 'User-Agent': + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'dcm_floodlight', + description: 'Test 2', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + activityTag: '', + advertiserId: '12649566', + conversionEvents: [ + { + customVariables: [ + { + from: '', + to: '', + }, + ], + eventName: 'Sign up Completed', + floodlightActivityTag: 'signu0', + floodlightGroupTag: 'conv01', + salesTag: false, + }, + { + customVariables: [ + { + from: 'rudder1', + to: '1', + }, + { + from: 'akash2', + to: '2', + }, + ], + eventName: 'Order Complete', + floodlightActivityTag: 'order0', + floodlightGroupTag: 'conv000', + salesTag: false, + }, + { + customVariables: [ + { + from: '', + to: '', + }, + ], + eventName: 'Checkout Started', + floodlightActivityTag: 'check0', + floodlightGroupTag: 'conv00', + salesTag: true, + }, + ], + groupTag: '', + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + message: { + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99090', + userId: '1234', + type: 'track', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + adTrackingEnabled: 'true', + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + ip: '0.0.0.0', + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + event: 'Order Complete', + properties: { + orderId: 111, + quantity: 2, + revenue: 800, + rudder1: 'rudder-v1', + akash2: 'akash-v2', + }, + integrations: { + All: true, + 'DCM Floodlight': { + COPPA: 'false', + GDPR: '1', + npa: true, + }, + }, + messageId: 'ea5cfab2-3961-4d8a-8187-3d1858c90a9f', + originalTimestamp: '2020-01-17T04:53:51.185Z', + receivedAt: '2020-01-17T10:23:52.688+05:30', + sentAt: '2020-01-17T04:53:52.667Z', + timestamp: '2020-01-17T10:23:51.206+05:30', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'GET', + endpoint: + 'https://ad.doubleclick.net/ddm/activity/src=12649566;cat=order0;type=conv000;dc_rdid=T0T0T072-5e28-45a1-9eda-ce22a3e36d1a;ord=ea5cfab2-3961-4d8a-8187-3d1858c90a9f;dc_lat=1;tag_for_child_directed_treatment=0;tfua=1;npa=1;u1=rudder-v1;u2=akash-v2', + headers: { + 'User-Agent': + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'dcm_floodlight', + description: 'Test 3', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + activityTag: '', + advertiserId: '12649566', + conversionEvents: [ + { + customVariables: [ + { + from: '', + to: '', + }, + ], + eventName: 'Sign up Completed', + floodlightActivityTag: 'signu0', + floodlightGroupTag: 'conv01', + salesTag: false, + }, + { + customVariables: [ + { + from: 'rudder1', + to: '1', + }, + { + from: 'akash2', + to: '2', + }, + ], + eventName: 'Order Complete', + floodlightActivityTag: 'order0', + floodlightGroupTag: 'conv000', + salesTag: false, + }, + { + customVariables: [ + { + from: '', + to: '', + }, + ], + eventName: 'Checkout Started', + floodlightActivityTag: 'check0', + floodlightGroupTag: 'conv00', + salesTag: true, + }, + ], + groupTag: '', + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + message: { + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99090', + userId: '1234', + type: 'track', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + adTrackingEnabled: 'true', + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + ip: '0.0.0.0', + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + event: 'Checkout Started', + properties: { + orderId: 111, + quantity: 2, + revenue: 800, + }, + integrations: { + All: true, + 'DCM Floodlight': { + COPPA: 'false', + GDPR: '1', + npa: true, + }, + }, + messageId: 'ea5cfab2-3961-4d8a-8187-3d1858c90a9f', + originalTimestamp: '2020-01-17T04:53:51.185Z', + receivedAt: '2020-01-17T10:23:52.688+05:30', + sentAt: '2020-01-17T04:53:52.667Z', + timestamp: '2020-01-17T10:23:51.206+05:30', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'GET', + endpoint: + 'https://ad.doubleclick.net/ddm/activity/src=12649566;cat=check0;type=conv00;dc_rdid=T0T0T072-5e28-45a1-9eda-ce22a3e36d1a;ord=111;qty=2;cost=800;dc_lat=1;tag_for_child_directed_treatment=0;tfua=1;npa=1', + headers: { + 'User-Agent': + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'dcm_floodlight', + description: 'Test 4', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + activityTag: '', + advertiserId: '12649566', + conversionEvents: [ + { + customVariables: [ + { + from: '', + to: '', + }, + ], + eventName: 'Sign up Completed', + floodlightActivityTag: 'signu0', + floodlightGroupTag: 'conv01', + salesTag: false, + }, + { + customVariables: [ + { + from: 'rudder1', + to: '1', + }, + { + from: 'akash1', + to: '2', + }, + ], + eventName: 'Order Complete', + floodlightActivityTag: 'order0', + floodlightGroupTag: 'conv000', + salesTag: false, + }, + { + customVariables: [ + { + from: '', + to: '', + }, + ], + eventName: 'Checkout Started', + floodlightActivityTag: 'check0', + floodlightGroupTag: 'conv00', + salesTag: true, + }, + { + customVariables: [ + { + from: 'rudder2', + to: '1', + }, + { + from: 'akash2', + to: '2', + }, + { + from: 'friendlyName2', + to: '3', + }, + { + from: 'name2', + to: '4', + }, + ], + eventName: 'Purchase', + floodlightActivityTag: 'Pur0', + floodlightGroupTag: 'conv111', + salesTag: false, + }, + ], + groupTag: '', + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + message: { + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99090', + userId: '1234', + type: 'track', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + adTrackingEnabled: 'true', + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + ip: '0.0.0.0', + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + event: 'Purchase', + properties: { + orderId: 111, + quantity: 999999, + revenue: 800, + products: [ + { + sku: '45790-32', + url: 'https://www.example.com/product/path', + name: 'Monopoly: 3rd Edition', + price: 19, + category: 'Games', + quantity: 1, + image_url: 'https:///www.example.com/product/path.jpg', + product_id: '507f1f77bcf86cd799439011', + }, + { + sku: '46493-32', + name: 'Uno Card Game', + price: 3, + category: 'Games', + quantity: 2, + product_id: '505bd76785ebb509fc183733', + }, + ], + rudder2: 'rudder2', + akash2: 'akash2', + friendlyName2: 'friendlyName2', + name2: 'name2', + }, + integrations: { + All: true, + 'DCM Floodlight': { + COPPA: 'false', + GDPR: '1', + npa: true, + }, + }, + messageId: 'ea5cfab2-3961-4d8a-8187-3d1858c90a9f', + originalTimestamp: '2020-01-17T04:53:51.185Z', + receivedAt: '2020-01-17T10:23:52.688+05:30', + sentAt: '2020-01-17T04:53:52.667Z', + timestamp: '2020-01-17T10:23:51.206+05:30', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'GET', + endpoint: + 'https://ad.doubleclick.net/ddm/activity/src=12649566;cat=Pur0;type=conv111;dc_rdid=T0T0T072-5e28-45a1-9eda-ce22a3e36d1a;ord=ea5cfab2-3961-4d8a-8187-3d1858c90a9f;dc_lat=1;tag_for_child_directed_treatment=0;tfua=1;npa=1;u1=rudder2;u2=akash2;u3=friendlyName2;u4=name2', + headers: { + 'User-Agent': + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'dcm_floodlight', + description: 'Test 5', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + activityTag: '', + advertiserId: '12649566', + conversionEvents: [ + { + customVariables: [ + { + from: '', + to: '', + }, + ], + eventName: 'Sign up Completed', + floodlightActivityTag: 'signu0', + floodlightGroupTag: 'conv01', + salesTag: false, + }, + { + customVariables: [ + { + from: 'rudder1', + to: '1', + }, + { + from: 'akash1', + to: '2', + }, + ], + eventName: 'Order Complete', + floodlightActivityTag: 'order0', + floodlightGroupTag: 'conv000', + salesTag: false, + }, + { + customVariables: [ + { + from: '', + to: '', + }, + ], + eventName: 'Checkout Started', + floodlightActivityTag: 'check0', + floodlightGroupTag: 'conv00', + salesTag: true, + }, + { + customVariables: [ + { + from: 'rudder2', + to: '1', + }, + { + from: 'akash2', + to: '2', + }, + { + from: 'friendlyName2', + to: '3', + }, + { + from: 'name2', + to: '4', + }, + ], + eventName: 'Purchase', + floodlightActivityTag: 'Pur0', + floodlightGroupTag: 'conv111', + salesTag: false, + }, + ], + groupTag: '', + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + message: { + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99090', + userId: '1234', + type: 'track', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + adTrackingEnabled: 'true', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + ip: '0.0.0.0', + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + event: 'Sign up Completed', + properties: { + orderId: 111, + quantity: 999999, + revenue: 800, + products: [ + { + sku: '45790-32', + url: 'https://www.example.com/product/path', + name: 'Monopoly: 3rd Edition', + price: 19, + category: 'Games', + quantity: 1, + image_url: 'https:///www.example.com/product/path.jpg', + product_id: '507f1f77bcf86cd799439011', + }, + { + sku: '46493-32', + name: 'Uno Card Game', + price: 3, + category: 'Games', + quantity: 2, + product_id: '505bd76785ebb509fc183733', + }, + ], + }, + integrations: { + All: true, + 'DCM Floodlight': { + COPPA: 'false', + GDPR: '1', + npa: true, + }, + }, + messageId: 'ea5cfab2-3961-4d8a-8187-3d1858c90a9f', + originalTimestamp: '2020-01-17T04:53:51.185Z', + receivedAt: '2020-01-17T10:23:52.688+05:30', + sentAt: '2020-01-17T04:53:52.667Z', + timestamp: '2020-01-17T10:23:51.206+05:30', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 400, + error: + 'advertisingId is required: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: advertisingId is required', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + implementation: 'cdkV2', + destType: 'DCM_FLOODLIGHT', + module: 'destination', + feature: 'processor', + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + }, + { + name: 'dcm_floodlight', + description: 'Test 6', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + activityTag: '', + advertiserId: '12649566', + conversionEvents: [ + { + customVariables: [ + { + to: '', + from: '', + }, + ], + eventName: 'Sign up Completed', + floodlightActivityTag: 'signu0', + floodlightGroupTag: 'conv01', + salesTag: false, + }, + { + customVariables: [ + { + from: 'rudder1', + to: '1', + }, + { + from: 'akash1', + to: '2', + }, + ], + eventName: 'Order Complete', + floodlightActivityTag: 'order0', + floodlightGroupTag: 'conv000', + salesTag: false, + }, + { + customVariables: [ + { + from: '', + to: '', + }, + ], + eventName: 'Checkout Started', + floodlightActivityTag: 'check0', + floodlightGroupTag: 'conv00', + salesTag: true, + }, + { + customVariables: [ + { + to: '1', + from: 'rudder2', + }, + { + to: '2', + from: 'akash2', + }, + { + to: '3', + from: 'friendlyName2', + }, + { + to: '4', + from: 'name2', + }, + ], + eventName: 'Purchase', + floodlightActivityTag: 'Pur0', + floodlightGroupTag: 'conv111', + salesTag: false, + }, + ], + groupTag: '', + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + message: { + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99090', + userId: '1234', + type: 'track', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + adTrackingEnabled: 'true', + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + ip: '0.0.0.0', + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + }, + event: 'Sign up Completed', + properties: { + orderId: 111, + quantity: 999999, + revenue: 800, + products: [ + { + sku: '45790-32', + url: 'https://www.example.com/product/path', + name: 'Monopoly: 3rd Edition', + price: 19, + category: 'Games', + quantity: 1, + image_url: 'https:///www.example.com/product/path.jpg', + product_id: '507f1f77bcf86cd799439011', + }, + { + sku: '46493-32', + name: 'Uno Card Game', + price: 3, + category: 'Games', + quantity: 2, + product_id: '505bd76785ebb509fc183733', + }, + ], + }, + integrations: { + All: true, + 'DCM Floodlight': { + COPPA: 'false', + GDPR: '1', + npa: true, + }, + }, + messageId: 'ea5cfab2-3961-4d8a-8187-3d1858c90a9f', + originalTimestamp: '2020-01-17T04:53:51.185Z', + receivedAt: '2020-01-17T10:23:52.688+05:30', + sentAt: '2020-01-17T04:53:52.667Z', + timestamp: '2020-01-17T10:23:51.206+05:30', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 400, + error: + 'track:: userAgent is required: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: track:: userAgent is required', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + implementation: 'cdkV2', + destType: 'DCM_FLOODLIGHT', + module: 'destination', + feature: 'processor', + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + }, + { + name: 'dcm_floodlight', + description: 'Test 7', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + advertiserId: '12649566', + activityTag: 'check0', + groupTag: 'conv00', + conversionEvents: [ + { + customVariables: [ + { + to: '', + from: '', + }, + ], + eventName: 'Sign up Completed', + floodlightActivityTag: 'signu0', + floodlightGroupTag: 'conv01', + salesTag: false, + }, + { + customVariables: [ + { + to: '1', + from: 'rudder1', + }, + { + to: '2', + from: 'akash1', + }, + ], + eventName: 'Order Complete', + floodlightActivityTag: 'order0', + floodlightGroupTag: 'conv000', + salesTag: false, + }, + { + customVariables: [ + { + to: '1', + from: 'akash1', + }, + ], + eventName: 'Checkout Started', + floodlightActivityTag: '', + floodlightGroupTag: '', + salesTag: true, + }, + { + customVariables: [ + { + to: '1', + from: 'rudder2', + }, + { + to: '2', + from: 'akash2', + }, + { + to: '3', + from: 'friendlyName2', + }, + { + to: '4', + from: 'name2', + }, + ], + eventName: 'Purchase', + floodlightActivityTag: 'Pur0', + floodlightGroupTag: 'conv111', + salesTag: false, + }, + ], + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + message: { + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99090', + userId: '1234', + type: 'track', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + adTrackingEnabled: 'true', + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + ip: '0.0.0.0', + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + event: 'Checkout Started', + properties: { + orderId: 111, + quantity: 999999, + revenue: 800, + products: [ + { + sku: '45790-32', + url: 'https://www.example.com/product/path', + name: 'Monopoly: 3rd Edition', + price: 19, + category: 'Games', + quantity: 1, + image_url: 'https:///www.example.com/product/path.jpg', + product_id: '507f1f77bcf86cd799439011', + }, + { + sku: '46493-32', + name: 'Uno Card Game', + price: 3, + category: 'Games', + quantity: 2, + product_id: '505bd76785ebb509fc183733', + }, + ], + akash1: 'akash-v1', + }, + integrations: { + All: true, + 'DCM Floodlight': { + COPPA: 'false', + GDPR: '1', + npa: true, + }, + }, + messageId: 'ea5cfab2-3961-4d8a-8187-3d1858c90a9f', + originalTimestamp: '2020-01-17T04:53:51.185Z', + receivedAt: '2020-01-17T10:23:52.688+05:30', + sentAt: '2020-01-17T04:53:52.667Z', + timestamp: '2020-01-17T10:23:51.206+05:30', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'GET', + endpoint: + 'https://ad.doubleclick.net/ddm/activity/src=12649566;cat=check0;type=conv00;dc_rdid=T0T0T072-5e28-45a1-9eda-ce22a3e36d1a;ord=111;qty=3;cost=800;dc_lat=1;tag_for_child_directed_treatment=0;tfua=1;npa=1;u1=akash-v1', + headers: { + 'User-Agent': + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'dcm_floodlight', + description: 'Test 8', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + advertiserId: '12649566', + activityTag: 'check0', + groupTag: 'conv00', + conversionEvents: [ + { + customVariables: [ + { + to: '', + from: '', + }, + ], + eventName: 'Sign up Completed', + floodlightActivityTag: 'signu0', + floodlightGroupTag: 'conv01', + salesTag: false, + }, + { + customVariables: [ + { + to: '1', + from: 'rudder1', + }, + { + to: '2', + from: 'akash1', + }, + ], + eventName: 'Order Complete', + floodlightActivityTag: 'order0', + floodlightGroupTag: 'conv000', + salesTag: false, + }, + { + eventName: 'Checkout Started', + floodlightActivityTag: '', + floodlightGroupTag: '', + salesTag: true, + }, + { + customVariables: [ + { + to: '1', + from: 'rudder2', + }, + { + to: '2', + from: 'akash2', + }, + { + to: '3', + from: 'friendlyName2', + }, + { + to: '4', + from: 'name2', + }, + ], + eventName: 'Purchase', + floodlightActivityTag: 'Pur0', + floodlightGroupTag: 'conv111', + salesTag: false, + }, + ], + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + message: { + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99090', + userId: '1234', + type: 'track', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + adTrackingEnabled: 'true', + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + ip: '0.0.0.0', + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + event: 'Checkout Started', + properties: { + orderId: 111, + quantity: 999999, + revenue: 800, + products: [ + { + sku: '45790-32', + url: 'https://www.example.com/product/path', + name: 'Monopoly: 3rd Edition', + price: 19, + category: 'Games', + quantity: 1, + image_url: 'https:///www.example.com/product/path.jpg', + product_id: '507f1f77bcf86cd799439011', + }, + { + sku: '46493-32', + name: 'Uno Card Game', + price: 3, + category: 'Games', + quantity: 2, + product_id: '505bd76785ebb509fc183733', + }, + ], + }, + integrations: { + All: true, + 'DCM Floodlight': { + COPPA: 'false', + GDPR: '1', + npa: true, + }, + }, + messageId: 'ea5cfab2-3961-4d8a-8187-3d1858c90a9f', + originalTimestamp: '2020-01-17T04:53:51.185Z', + receivedAt: '2020-01-17T10:23:52.688+05:30', + sentAt: '2020-01-17T04:53:52.667Z', + timestamp: '2020-01-17T10:23:51.206+05:30', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'GET', + endpoint: + 'https://ad.doubleclick.net/ddm/activity/src=12649566;cat=check0;type=conv00;dc_rdid=T0T0T072-5e28-45a1-9eda-ce22a3e36d1a;ord=111;qty=3;cost=800;dc_lat=1;tag_for_child_directed_treatment=0;tfua=1;npa=1', + headers: { + 'User-Agent': + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'dcm_floodlight', + description: 'Test 9', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + advertiserId: '12649566', + activityTag: 'check0', + groupTag: 'conv00', + conversionEvents: [ + { + customVariables: [ + { + to: '', + from: '', + }, + ], + eventName: 'Sign up Completed', + floodlightActivityTag: 'signu0', + floodlightGroupTag: 'conv01', + salesTag: false, + }, + { + customVariables: [ + { + to: '1', + from: 'rudder1', + }, + { + to: '2', + from: 'akash1', + }, + ], + eventName: 'Order Complete', + floodlightActivityTag: 'order0', + floodlightGroupTag: 'conv000', + salesTag: false, + }, + { + eventName: 'Checkout Started', + floodlightActivityTag: '', + floodlightGroupTag: '', + salesTag: true, + }, + { + customVariables: [ + { + to: '1', + from: 'rudder2', + }, + { + to: '2', + from: 'akash2', + }, + { + to: '3', + from: 'friendlyName2', + }, + { + to: '4', + from: 'name2', + }, + ], + eventName: 'Purchase', + floodlightActivityTag: 'Pur0', + floodlightGroupTag: 'conv111', + salesTag: false, + }, + ], + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + message: { + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99090', + userId: '1234', + type: 'track', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + adTrackingEnabled: 'true', + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + ip: '0.0.0.0', + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + event: 'Sample event', + properties: { + orderId: 111, + quantity: 999999, + revenue: 800, + products: [ + { + sku: '45790-32', + url: 'https://www.example.com/product/path', + name: 'Monopoly: 3rd Edition', + price: 19, + category: 'Games', + quantity: 1, + image_url: 'https:///www.example.com/product/path.jpg', + product_id: '507f1f77bcf86cd799439011', + }, + { + sku: '46493-32', + name: 'Uno Card Game', + price: 3, + category: 'Games', + quantity: 2, + product_id: '505bd76785ebb509fc183733', + }, + ], + }, + integrations: { + All: true, + 'DCM Floodlight': { + COPPA: 'false', + GDPR: '1', + npa: true, + }, + }, + messageId: 'ea5cfab2-3961-4d8a-8187-3d1858c90a9f', + originalTimestamp: '2020-01-17T04:53:51.185Z', + receivedAt: '2020-01-17T10:23:52.688+05:30', + sentAt: '2020-01-17T04:53:52.667Z', + timestamp: '2020-01-17T10:23:51.206+05:30', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 400, + error: + 'track:: Conversion event not found: Workflow: procWorkflow, Step: handleConversionEvents, ChildStep: undefined, OriginalError: track:: Conversion event not found', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + implementation: 'cdkV2', + destType: 'DCM_FLOODLIGHT', + module: 'destination', + feature: 'processor', + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + }, + { + name: 'dcm_floodlight', + description: 'Test 10', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + advertiserId: '12649566', + activityTag: 'check0', + groupTag: 'conv00', + conversionEvents: [ + { + customVariables: [ + { + to: '', + from: '', + }, + ], + eventName: 'Sign up Completed', + floodlightActivityTag: 'signu0', + floodlightGroupTag: 'conv01', + salesTag: false, + }, + { + customVariables: [ + { + to: '1', + from: 'rudder1', + }, + { + to: '2', + from: 'akash1', + }, + ], + eventName: 'Order Complete', + floodlightActivityTag: 'order0', + floodlightGroupTag: 'conv000', + salesTag: false, + }, + { + eventName: 'Checkout Started', + floodlightActivityTag: '', + floodlightGroupTag: '', + salesTag: true, + }, + { + customVariables: [ + { + to: '1', + from: 'rudder2', + }, + { + to: '2', + from: 'akash2', + }, + { + to: '3', + from: 'friendlyName2', + }, + { + to: '4', + from: 'name2', + }, + ], + eventName: 'Purchase', + floodlightActivityTag: 'Pur0', + floodlightGroupTag: 'conv111', + salesTag: false, + }, + ], + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + message: { + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99090', + userId: '1234', + type: 'track', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + adTrackingEnabled: 'true', + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + ip: '0.0.0.0', + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + event: 'Checkout Started', + properties: { + orderId: 111, + quantity: 999999, + revenue: 800, + products: [ + { + sku: '45790-32', + url: 'https://www.example.com/product/path', + name: 'Monopoly: 3rd Edition', + price: 19, + category: 'Games', + quantity: 1, + image_url: 'https:///www.example.com/product/path.jpg', + product_id: '507f1f77bcf86cd799439011', + }, + ], + }, + integrations: { + All: true, + 'DCM Floodlight': { + COPPA: 'false', + GDPR: '1', + npa: true, + }, + }, + messageId: 'ea5cfab2-3961-4d8a-8187-3d1858c90a9f', + originalTimestamp: '2020-01-17T04:53:51.185Z', + receivedAt: '2020-01-17T10:23:52.688+05:30', + sentAt: '2020-01-17T04:53:52.667Z', + timestamp: '2020-01-17T10:23:51.206+05:30', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'GET', + endpoint: + 'https://ad.doubleclick.net/ddm/activity/src=12649566;cat=check0;type=conv00;dc_rdid=T0T0T072-5e28-45a1-9eda-ce22a3e36d1a;ord=111;qty=1;cost=800;dc_lat=1;tag_for_child_directed_treatment=0;tfua=1;npa=1', + headers: { + 'User-Agent': + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'dcm_floodlight', + description: 'Test 11', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + advertiserId: '12649566', + activityTag: 'check0', + groupTag: 'conv00', + conversionEvents: [ + { + customVariables: [ + { + to: '', + from: '', + }, + ], + eventName: 'Sign up Completed', + floodlightActivityTag: 'signu0', + floodlightGroupTag: 'conv01', + salesTag: false, + }, + { + customVariables: [ + { + to: '1', + from: 'rudder1', + }, + { + to: '2', + from: 'akash1', + }, + ], + eventName: 'Order Complete', + floodlightActivityTag: 'order0', + floodlightGroupTag: 'conv000', + salesTag: false, + }, + { + eventName: 'Checkout Started', + floodlightActivityTag: '', + floodlightGroupTag: '', + salesTag: true, + }, + { + customVariables: [ + { + to: '1', + from: 'rudder2', + }, + { + to: '2', + from: 'akash2', + }, + { + to: '3', + from: 'friendlyName2', + }, + { + to: '4', + from: 'name2', + }, + ], + eventName: 'Purchase', + floodlightActivityTag: 'Pur0', + floodlightGroupTag: 'conv111', + salesTag: false, + }, + ], + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + message: { + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99090', + userId: '1234', + type: 'track', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + adTrackingEnabled: 'true', + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + ip: '0.0.0.0', + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + event: 'Checkout Started', + properties: { + orderId: 111, + revenue: 800, + products: [ + { + sku: '45790-32', + url: 'https://www.example.com/product/path', + name: 'Monopoly: 3rd Edition', + price: 19, + category: 'Games', + quantity: 4, + image_url: 'https:///www.example.com/product/path.jpg', + product_id: '507f1f77bcf86cd799439011', + }, + { + sku: '46493-32', + name: 'Uno Card Game', + price: 3, + category: 'Games', + quantity: 2, + product_id: '505bd76785ebb509fc183733', + }, + ], + }, + integrations: { + All: true, + 'DCM Floodlight': { + COPPA: 'false', + GDPR: '1', + npa: true, + }, + }, + messageId: 'ea5cfab2-3961-4d8a-8187-3d1858c90a9f', + originalTimestamp: '2020-01-17T04:53:51.185Z', + receivedAt: '2020-01-17T10:23:52.688+05:30', + sentAt: '2020-01-17T04:53:52.667Z', + timestamp: '2020-01-17T10:23:51.206+05:30', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'GET', + endpoint: + 'https://ad.doubleclick.net/ddm/activity/src=12649566;cat=check0;type=conv00;dc_rdid=T0T0T072-5e28-45a1-9eda-ce22a3e36d1a;ord=111;qty=6;cost=800;dc_lat=1;tag_for_child_directed_treatment=0;tfua=1;npa=1', + headers: { + 'User-Agent': + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'dcm_floodlight', + description: 'Test 12', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + advertiserId: '12649566', + activityTag: 'check0', + groupTag: 'conv00', + conversionEvents: [ + { + customVariables: [ + { + to: '', + from: '', + }, + ], + eventName: 'Sign up Completed', + floodlightActivityTag: 'signu0', + floodlightGroupTag: 'conv01', + salesTag: false, + }, + { + customVariables: [ + { + to: '1', + from: 'rudder1', + }, + { + to: '2', + from: 'akash1', + }, + ], + eventName: 'Order Complete', + floodlightActivityTag: 'order0', + floodlightGroupTag: 'conv000', + salesTag: false, + }, + { + eventName: 'Checkout Started', + floodlightActivityTag: '', + floodlightGroupTag: '', + salesTag: true, + }, + { + customVariables: [ + { + to: '1', + from: 'rudder2', + }, + { + to: '2', + from: 'akash2', + }, + { + to: '3', + from: 'friendlyName2', + }, + { + to: '4', + from: 'name2', + }, + ], + eventName: 'Purchase', + floodlightActivityTag: 'Pur0', + floodlightGroupTag: 'conv111', + salesTag: false, + }, + ], + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + message: { + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99090', + userId: '1234', + type: 'track', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + adTrackingEnabled: 'true', + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + ip: '0.0.0.0', + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + event: 'Checkout Started', + properties: { + orderId: 111, + quantity: 999999, + revenue: 800, + }, + integrations: { + All: true, + 'DCM Floodlight': { + COPPA: 'false', + GDPR: '1', + npa: true, + }, + }, + messageId: 'ea5cfab2-3961-4d8a-8187-3d1858c90a9f', + originalTimestamp: '2020-01-17T04:53:51.185Z', + receivedAt: '2020-01-17T10:23:52.688+05:30', + sentAt: '2020-01-17T04:53:52.667Z', + timestamp: '2020-01-17T10:23:51.206+05:30', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'GET', + endpoint: + 'https://ad.doubleclick.net/ddm/activity/src=12649566;cat=check0;type=conv00;dc_rdid=T0T0T072-5e28-45a1-9eda-ce22a3e36d1a;ord=111;qty=999999;cost=800;dc_lat=1;tag_for_child_directed_treatment=0;tfua=1;npa=1', + headers: { + 'User-Agent': + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'dcm_floodlight', + description: 'Test 13', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + advertiserId: '12649566', + activityTag: 'check0', + groupTag: 'conv00', + conversionEvents: [ + { + customVariables: [ + { + to: '', + from: '', + }, + ], + eventName: 'Sign up Completed', + floodlightActivityTag: 'signu0', + floodlightGroupTag: 'conv01', + salesTag: false, + }, + { + customVariables: [ + { + to: '1', + from: 'rudder1', + }, + { + to: '2', + from: 'akash1', + }, + ], + eventName: 'Order Complete', + floodlightActivityTag: 'order0', + floodlightGroupTag: 'conv000', + salesTag: false, + }, + { + eventName: 'Checkout Started', + floodlightActivityTag: '', + floodlightGroupTag: '', + salesTag: true, + }, + { + customVariables: [ + { + to: '1', + from: 'rudder2', + }, + { + to: '2', + from: 'akash2', + }, + { + to: '3', + from: 'friendlyName2', + }, + { + to: '4', + from: 'name2', + }, + ], + eventName: 'Purchase', + floodlightActivityTag: 'Pur0', + floodlightGroupTag: 'conv111', + salesTag: false, + }, + ], + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + message: { + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99090', + userId: '1234', + type: 'track', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + adTrackingEnabled: 'true', + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + ip: '0.0.0.0', + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + event: 'OrDeR complete', + properties: { + orderId: 111, + quantity: 999999, + revenue: 800, + rudder1: 'rudder-v1', + akash1: 'akash-v1', + }, + integrations: { + All: true, + 'DCM Floodlight': { + COPPA: 'false', + GDPR: '1', + npa: true, + }, + }, + messageId: 'ea5cfab2-3961-4d8a-8187-3d1858c90a9f', + originalTimestamp: '2020-01-17T04:53:51.185Z', + receivedAt: '2020-01-17T10:23:52.688+05:30', + sentAt: '2020-01-17T04:53:52.667Z', + timestamp: '2020-01-17T10:23:51.206+05:30', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'GET', + endpoint: + 'https://ad.doubleclick.net/ddm/activity/src=12649566;cat=order0;type=conv000;dc_rdid=T0T0T072-5e28-45a1-9eda-ce22a3e36d1a;ord=ea5cfab2-3961-4d8a-8187-3d1858c90a9f;dc_lat=1;tag_for_child_directed_treatment=0;tfua=1;npa=1;u1=rudder-v1;u2=akash-v1', + headers: { + 'User-Agent': + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'dcm_floodlight', + description: 'Test 14', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + advertiserId: '12649566', + activityTag: 'check0', + groupTag: 'conv00', + conversionEvents: [ + { + customVariables: [ + { + to: '', + from: '', + }, + ], + eventName: 'Sign up Completed', + floodlightActivityTag: 'signu0', + floodlightGroupTag: 'conv01', + salesTag: false, + }, + { + customVariables: [ + { + to: '1', + from: 'rudder1', + }, + { + to: '2', + from: 'akash1', + }, + ], + eventName: 'Order Complete', + floodlightActivityTag: 'order0', + floodlightGroupTag: 'conv000', + salesTag: false, + }, + { + eventName: 'Checkout Started', + floodlightActivityTag: '', + floodlightGroupTag: '', + salesTag: true, + }, + { + customVariables: [ + { + to: '1', + from: 'rudder2', + }, + { + to: '2', + from: 'akash2', + }, + { + to: '3', + from: 'friendlyName2', + }, + { + to: '4', + from: 'name2', + }, + ], + eventName: 'Purchase', + floodlightActivityTag: 'Pur0', + floodlightGroupTag: 'conv111', + salesTag: false, + }, + ], + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + message: { + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99090', + userId: '1234', + type: 'track', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + adTrackingEnabled: 'true', + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + ip: '0.0.0.0', + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + event: 'Order complete', + properties: { + orderId: 111, + quantity: 999999, + revenue: 800, + rudder1: 'rudder-v1', + akash1: 'akash-v1', + }, + integrations: { + All: true, + 'DCM Floodlight': {}, + }, + messageId: 'ea5cfab2-3961-4d8a-8187-3d1858c90a9f', + originalTimestamp: '2020-01-17T04:53:51.185Z', + receivedAt: '2020-01-17T10:23:52.688+05:30', + sentAt: '2020-01-17T04:53:52.667Z', + timestamp: '2020-01-17T10:23:51.206+05:30', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'GET', + endpoint: + 'https://ad.doubleclick.net/ddm/activity/src=12649566;cat=order0;type=conv000;dc_rdid=T0T0T072-5e28-45a1-9eda-ce22a3e36d1a;ord=ea5cfab2-3961-4d8a-8187-3d1858c90a9f;dc_lat=1;u1=rudder-v1;u2=akash-v1', + headers: { + 'User-Agent': + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'dcm_floodlight', + description: 'Test 15', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + advertiserId: '12649566', + activityTag: 'check0', + groupTag: 'conv00', + conversionEvents: [ + { + customVariables: [ + { + to: '', + from: '', + }, + ], + eventName: 'Sign up Completed', + floodlightActivityTag: 'signu0', + floodlightGroupTag: 'conv01', + salesTag: false, + }, + { + customVariables: [ + { + to: '1', + from: 'rudder1', + }, + { + to: '2', + from: 'akash1', + }, + ], + eventName: 'Order Complete', + floodlightActivityTag: 'order0', + floodlightGroupTag: 'conv000', + salesTag: false, + }, + { + eventName: 'Checkout Started', + floodlightActivityTag: '', + floodlightGroupTag: '', + salesTag: true, + }, + { + customVariables: [ + { + to: '1', + from: 'rudder2', + }, + { + to: '2', + from: 'akash2', + }, + { + to: '3', + from: 'friendlyName2', + }, + { + to: '4', + from: 'name2', + }, + ], + eventName: 'Purchase', + floodlightActivityTag: 'Pur0', + floodlightGroupTag: 'conv111', + salesTag: false, + }, + ], + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + message: { + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99090', + userId: '1234', + type: 'track', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + adTrackingEnabled: 'true', + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + ip: '0.0.0.0', + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + event: 'Order complete', + properties: { + orderId: 111, + quantity: 999999, + revenue: 800, + rudder1: 100, + akash1: 5987, + }, + messageId: 'ea5cfab2-3961-4d8a-8187-3d1858c90a9f', + originalTimestamp: '2020-01-17T04:53:51.185Z', + receivedAt: '2020-01-17T10:23:52.688+05:30', + sentAt: '2020-01-17T04:53:52.667Z', + timestamp: '2020-01-17T10:23:51.206+05:30', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'GET', + endpoint: + 'https://ad.doubleclick.net/ddm/activity/src=12649566;cat=order0;type=conv000;dc_rdid=T0T0T072-5e28-45a1-9eda-ce22a3e36d1a;ord=ea5cfab2-3961-4d8a-8187-3d1858c90a9f;dc_lat=1;u1=100;u2=5987', + headers: { + 'User-Agent': + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'dcm_floodlight', + description: 'Test 16', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + advertiserId: '12649566', + activityTag: 'check0', + groupTag: 'conv00', + conversionEvents: [ + { + customVariables: [ + { + to: '', + from: '', + }, + ], + eventName: 'Sign up Completed', + floodlightActivityTag: 'signu0', + floodlightGroupTag: 'conv01', + salesTag: false, + }, + { + customVariables: [ + { + to: '1', + from: 'rudder1', + }, + { + to: '2', + from: 'akash1', + }, + ], + eventName: 'Order Complete', + floodlightActivityTag: 'order0', + floodlightGroupTag: 'conv000', + salesTag: false, + }, + { + eventName: 'Checkout Started', + floodlightActivityTag: '', + floodlightGroupTag: '', + salesTag: true, + }, + { + customVariables: [ + { + to: '1', + from: 'rudder2', + }, + { + to: '2', + from: 'akash2', + }, + { + to: '3', + from: 'friendlyName2', + }, + { + to: '4', + from: 'name2', + }, + ], + eventName: 'Purchase', + floodlightActivityTag: 'Pur0', + floodlightGroupTag: 'conv111', + salesTag: false, + }, + ], + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + message: { + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99090', + userId: '1234', + type: 'track', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + adTrackingEnabled: true, + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + ip: '0.0.0.0', + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + event: 'Order complete', + properties: { + orderId: 111, + quantity: 999999, + revenue: 800, + rudder1: 'rudder-v1', + akash1: 'akash-v1', + }, + integrations: { + All: true, + 'DCM Floodlight': { + COPPA: 1, + GDPR: 1, + npa: true, + }, + }, + messageId: 'ea5cfab2-3961-4d8a-8187-3d1858c90a9f', + originalTimestamp: '2020-01-17T04:53:51.185Z', + receivedAt: '2020-01-17T10:23:52.688+05:30', + sentAt: '2020-01-17T04:53:52.667Z', + timestamp: '2020-01-17T10:23:51.206+05:30', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'GET', + endpoint: + 'https://ad.doubleclick.net/ddm/activity/src=12649566;cat=order0;type=conv000;dc_rdid=T0T0T072-5e28-45a1-9eda-ce22a3e36d1a;ord=ea5cfab2-3961-4d8a-8187-3d1858c90a9f;dc_lat=1;tag_for_child_directed_treatment=1;tfua=1;npa=1;u1=rudder-v1;u2=akash-v1', + headers: { + 'User-Agent': + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'dcm_floodlight', + description: 'Test 17', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + advertiserId: '12649566', + activityTag: 'check0', + groupTag: 'conv00', + conversionEvents: [ + { + customVariables: [ + { + to: '', + from: '', + }, + ], + eventName: 'Sign up Completed', + floodlightActivityTag: 'signu0', + floodlightGroupTag: 'conv01', + salesTag: false, + }, + { + customVariables: [ + { + to: '1', + from: 'rudder1', + }, + { + to: '2', + from: 'akash1', + }, + ], + eventName: 'Order Complete', + floodlightActivityTag: 'order0', + floodlightGroupTag: 'conv000', + salesTag: false, + }, + { + eventName: 'Checkout Started', + floodlightActivityTag: '', + floodlightGroupTag: '', + salesTag: true, + }, + { + customVariables: [ + { + to: '1', + from: 'rudder2', + }, + { + to: '2', + from: 'akash2', + }, + { + to: '3', + from: 'friendlyName2', + }, + { + to: '4', + from: 'name2', + }, + ], + eventName: 'Purchase', + floodlightActivityTag: 'Pur0', + floodlightGroupTag: 'conv111', + salesTag: false, + }, + ], + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + message: { + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99090', + userId: '1234', + type: 'track', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + adTrackingEnabled: true, + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + ip: '0.0.0.0', + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + event: 'Order complete', + properties: { + orderId: 111, + quantity: 999999, + revenue: 800, + }, + integrations: { + All: true, + 'DCM Floodlight': { + COPPA: 'Yes', + GDPR: '1', + npa: true, + }, + }, + messageId: 'ea5cfab2-3961-4d8a-8187-3d1858c90a9f', + originalTimestamp: '2020-01-17T04:53:51.185Z', + receivedAt: '2020-01-17T10:23:52.688+05:30', + sentAt: '2020-01-17T04:53:52.667Z', + timestamp: '2020-01-17T10:23:51.206+05:30', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 400, + error: + 'COPPA: valid parameters are [1|true] or [0|false]: Workflow: procWorkflow, Step: handleIntegrationsObject, ChildStep: undefined, OriginalError: COPPA: valid parameters are [1|true] or [0|false]', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + implementation: 'cdkV2', + destType: 'DCM_FLOODLIGHT', + module: 'destination', + feature: 'processor', + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + }, + { + name: 'dcm_floodlight', + description: 'Test 18', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + advertiserId: '12649566', + activityTag: 'check0', + groupTag: 'conv00', + conversionEvents: [ + { + customVariables: [ + { + to: '', + from: '', + }, + ], + eventName: 'Sign up Completed', + floodlightActivityTag: 'signu0', + floodlightGroupTag: 'conv01', + salesTag: false, + }, + { + customVariables: [ + { + to: '1', + from: 'rudder1', + }, + { + to: '2', + from: 'akash1', + }, + ], + eventName: 'Order Complete', + floodlightActivityTag: 'order0', + floodlightGroupTag: 'conv000', + salesTag: false, + }, + { + eventName: 'Checkout Started', + floodlightActivityTag: '', + floodlightGroupTag: '', + salesTag: true, + }, + { + customVariables: [ + { + to: '1', + from: 'rudder2', + }, + { + to: '2', + from: 'akash2', + }, + { + to: '3', + from: 'friendlyName2', + }, + { + to: '4', + from: 'name2', + }, + ], + eventName: 'Purchase', + floodlightActivityTag: 'Pur0', + floodlightGroupTag: 'conv111', + salesTag: false, + }, + ], + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + message: { + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99090', + userId: '1234', + type: 'track', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + adTrackingEnabled: true, + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + ip: '0.0.0.0', + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + event: 'Order complete', + properties: { + orderId: 111, + quantity: 999999, + revenue: 800, + }, + integrations: { + All: true, + 'DCM Floodlight': { + COPPA: 'false', + GDPR: 'Yes', + npa: true, + }, + }, + messageId: 'ea5cfab2-3961-4d8a-8187-3d1858c90a9f', + originalTimestamp: '2020-01-17T04:53:51.185Z', + receivedAt: '2020-01-17T10:23:52.688+05:30', + sentAt: '2020-01-17T04:53:52.667Z', + timestamp: '2020-01-17T10:23:51.206+05:30', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 400, + error: + 'GDPR: valid parameters are [1|true] or [0|false]: Workflow: procWorkflow, Step: handleIntegrationsObject, ChildStep: undefined, OriginalError: GDPR: valid parameters are [1|true] or [0|false]', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + implementation: 'cdkV2', + destType: 'DCM_FLOODLIGHT', + module: 'destination', + feature: 'processor', + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + }, + { + name: 'dcm_floodlight', + description: 'Test 19', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + advertiserId: '12649566', + activityTag: 'check0', + groupTag: 'conv00', + conversionEvents: [ + { + customVariables: [ + { + to: '', + from: '', + }, + ], + eventName: 'Sign up Completed', + floodlightActivityTag: 'signu0', + floodlightGroupTag: 'conv01', + salesTag: false, + }, + { + customVariables: [ + { + to: '1', + from: 'rudder1', + }, + { + to: '2', + from: 'akash1', + }, + ], + eventName: 'Order Complete', + floodlightActivityTag: 'order0', + floodlightGroupTag: 'conv000', + salesTag: false, + }, + { + eventName: 'Checkout Started', + floodlightActivityTag: '', + floodlightGroupTag: '', + salesTag: true, + }, + { + customVariables: [ + { + to: '1', + from: 'rudder2', + }, + { + to: '2', + from: 'akash2', + }, + { + to: '3', + from: 'friendlyName2', + }, + { + to: '4', + from: 'name2', + }, + ], + eventName: 'Purchase', + floodlightActivityTag: 'Pur0', + floodlightGroupTag: 'conv111', + salesTag: false, + }, + ], + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + message: { + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99090', + userId: '1234', + type: 'track', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + adTrackingEnabled: true, + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + ip: '0.0.0.0', + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + event: 'Order complete', + properties: { + orderId: 111, + quantity: 999999, + revenue: 800, + }, + integrations: { + All: true, + 'DCM Floodlight': { + COPPA: 'false', + GDPR: '1', + npa: 'No', + }, + }, + messageId: 'ea5cfab2-3961-4d8a-8187-3d1858c90a9f', + originalTimestamp: '2020-01-17T04:53:51.185Z', + receivedAt: '2020-01-17T10:23:52.688+05:30', + sentAt: '2020-01-17T04:53:52.667Z', + timestamp: '2020-01-17T10:23:51.206+05:30', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 400, + error: + 'npa: valid parameters are [1|true] or [0|false]: Workflow: procWorkflow, Step: handleIntegrationsObject, ChildStep: undefined, OriginalError: npa: valid parameters are [1|true] or [0|false]', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + implementation: 'cdkV2', + destType: 'DCM_FLOODLIGHT', + module: 'destination', + feature: 'processor', + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + }, + { + name: 'dcm_floodlight', + description: 'Test 20', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + advertiserId: '12649566', + activityTag: 'check0', + groupTag: 'conv00', + conversionEvents: [ + { + customVariables: [ + { + to: '', + from: '', + }, + ], + eventName: 'Sign up Completed', + floodlightActivityTag: 'signu0', + floodlightGroupTag: 'conv01', + salesTag: false, + }, + { + customVariables: [ + { + to: '1', + from: 'rudder1', + }, + { + to: '2', + from: 'akash1', + }, + ], + eventName: 'Order Complete', + floodlightActivityTag: 'order0', + floodlightGroupTag: 'conv000', + salesTag: false, + }, + { + eventName: 'Checkout Started', + floodlightActivityTag: '', + floodlightGroupTag: '', + salesTag: true, + }, + { + customVariables: [ + { + to: '1', + from: 'rudder2', + }, + { + to: '2', + from: 'akash2', + }, + { + to: '3', + from: 'friendlyName2', + }, + { + to: '4', + from: 'name2', + }, + ], + eventName: 'Purchase', + floodlightActivityTag: 'Pur0', + floodlightGroupTag: 'conv111', + salesTag: false, + }, + ], + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + message: { + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99090', + userId: '1234', + type: 'track', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + adTrackingEnabled: 'Yes', + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + ip: '0.0.0.0', + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + event: 'Order complete', + properties: { + orderId: 111, + quantity: 999999, + revenue: 800, + }, + integrations: { + All: true, + 'DCM Floodlight': { + COPPA: 'false', + GDPR: '1', + npa: 'true', + }, + }, + messageId: 'ea5cfab2-3961-4d8a-8187-3d1858c90a9f', + originalTimestamp: '2020-01-17T04:53:51.185Z', + receivedAt: '2020-01-17T10:23:52.688+05:30', + sentAt: '2020-01-17T04:53:52.667Z', + timestamp: '2020-01-17T10:23:51.206+05:30', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 400, + error: + 'dc_lat: valid parameters are [1|true] or [0|false]: Workflow: procWorkflow, Step: cleanPayload, ChildStep: undefined, OriginalError: dc_lat: valid parameters are [1|true] or [0|false]', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + implementation: 'cdkV2', + destType: 'DCM_FLOODLIGHT', + module: 'destination', + feature: 'processor', + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + }, + { + name: 'dcm_floodlight', + description: 'Test 21', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + advertiserId: '12649566', + activityTag: 'check0', + groupTag: 'conv00', + conversionEvents: [ + { + customVariables: [ + { + to: '', + from: '', + }, + ], + eventName: 'Sign up Completed', + floodlightActivityTag: 'signu0', + floodlightGroupTag: 'conv01', + salesTag: false, + }, + { + customVariables: [ + { + to: '1', + from: 'rudder1', + }, + { + to: '2', + from: 'akash1', + }, + ], + eventName: 'Order Complete', + floodlightActivityTag: 'order0', + floodlightGroupTag: 'conv000', + salesTag: false, + }, + { + eventName: 'Checkout Started', + floodlightActivityTag: '', + floodlightGroupTag: '', + salesTag: true, + }, + { + customVariables: [ + { + to: '1', + from: 'rudder2', + }, + { + to: '2', + from: 'akash2', + }, + { + to: '3', + from: 'friendlyName2', + }, + { + to: '4', + from: 'name2', + }, + ], + eventName: 'Purchase', + floodlightActivityTag: 'Pur0', + floodlightGroupTag: 'conv111', + salesTag: false, + }, + ], + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + message: { + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99090', + userId: '1234', + type: 'page', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + adTrackingEnabled: 'Yes', + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + ip: '0.0.0.0', + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + properties: { + orderId: 111, + quantity: 999999, + revenue: 800, + }, + integrations: { + All: true, + 'DCM Floodlight': { + COPPA: 'false', + GDPR: '1', + npa: 'true', + }, + }, + messageId: 'ea5cfab2-3961-4d8a-8187-3d1858c90a9f', + originalTimestamp: '2020-01-17T04:53:51.185Z', + receivedAt: '2020-01-17T10:23:52.688+05:30', + sentAt: '2020-01-17T04:53:52.667Z', + timestamp: '2020-01-17T10:23:51.206+05:30', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 400, + error: + 'page:: Conversion event not found: Workflow: procWorkflow, Step: handleConversionEvents, ChildStep: undefined, OriginalError: page:: Conversion event not found', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + implementation: 'cdkV2', + destType: 'DCM_FLOODLIGHT', + module: 'destination', + feature: 'processor', + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + }, + { + name: 'dcm_floodlight', + description: 'Test 22', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + advertiserId: '12649566', + activityTag: 'check0', + groupTag: 'conv00', + conversionEvents: [ + { + customVariables: [ + { + to: '', + from: '', + }, + ], + eventName: 'Viewed Sign up Completed Page', + floodlightActivityTag: 'signu0', + floodlightGroupTag: 'conv01', + salesTag: false, + }, + { + customVariables: [ + { + to: '1', + from: 'rudder1', + }, + { + to: '2', + from: 'akash1', + }, + ], + eventName: 'Order Complete', + floodlightActivityTag: 'order0', + floodlightGroupTag: 'conv000', + salesTag: false, + }, + { + eventName: 'Checkout Started', + floodlightActivityTag: '', + floodlightGroupTag: '', + salesTag: true, + }, + { + customVariables: [ + { + to: '1', + from: 'rudder2', + }, + { + to: '2', + from: 'akash2', + }, + { + to: '3', + from: 'friendlyName2', + }, + { + to: '4', + from: 'name2', + }, + ], + eventName: 'Purchase', + floodlightActivityTag: 'Pur0', + floodlightGroupTag: 'conv111', + salesTag: false, + }, + ], + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + message: { + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99090', + userId: '1234', + type: 'page', + channel: 'web', + name: 'Sign up Completed', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + adTrackingEnabled: 'true', + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + ip: '0.0.0.0', + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + properties: { + orderId: 111, + quantity: 999999, + revenue: 800, + }, + integrations: { + All: true, + 'DCM Floodlight': { + COPPA: 'false', + GDPR: '1', + npa: 'true', + }, + }, + messageId: 'ea5cfab2-3961-4d8a-8187-3d1858c90a9f', + originalTimestamp: '2020-01-17T04:53:51.185Z', + receivedAt: '2020-01-17T10:23:52.688+05:30', + sentAt: '2020-01-17T04:53:52.667Z', + timestamp: '2020-01-17T10:23:51.206+05:30', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'GET', + endpoint: + 'https://ad.doubleclick.net/ddm/activity/src=12649566;cat=signu0;type=conv01;dc_rdid=T0T0T072-5e28-45a1-9eda-ce22a3e36d1a;ord=ea5cfab2-3961-4d8a-8187-3d1858c90a9f;dc_lat=1;tag_for_child_directed_treatment=0;tfua=1;npa=1', + headers: { + 'User-Agent': + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'dcm_floodlight', + description: 'Test 23', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + advertiserId: '22448662', + activityTag: '', + groupTag: '', + conversionEvents: [ + { + customVariables: [ + { + from: 'rudder1', + to: '1', + }, + { + from: 'rudder2', + to: '2', + }, + ], + eventName: 'Product viewed', + floodlightActivityTag: 'signu01', + floodlightGroupTag: 'conv01', + salesTag: false, + }, + { + customVariables: [ + { + from: '', + to: '', + }, + ], + eventName: 'Order Complete', + floodlightActivityTag: 'signu01', + floodlightGroupTag: 'conv02', + salesTag: false, + }, + ], + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + message: { + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99090', + userId: '1234', + type: 'track', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + adTrackingEnabled: 'true', + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + ip: '0.0.0.0', + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + event: 'Product viewed', + properties: { + orderId: 111, + quantity: 2, + revenue: 800, + }, + integrations: { + All: true, + 'DCM Floodlight': { + COPPA: 'false', + GDPR: '1', + npa: true, + }, + }, + messageId: 'ea5cfab2-3961-4d8a-8187-3d1858c90a9f', + originalTimestamp: '2020-01-17T04:53:51.185Z', + receivedAt: '2020-01-17T10:23:52.688+05:30', + sentAt: '2020-01-17T04:53:52.667Z', + timestamp: '2020-01-17T10:23:51.206+05:30', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'GET', + endpoint: + 'https://ad.doubleclick.net/ddm/activity/src=22448662;cat=signu01;type=conv01;dc_rdid=T0T0T072-5e28-45a1-9eda-ce22a3e36d1a;ord=ea5cfab2-3961-4d8a-8187-3d1858c90a9f;dc_lat=1;tag_for_child_directed_treatment=0;tfua=1;npa=1', + headers: { + 'User-Agent': + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'dcm_floodlight', + description: 'Test 24', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + activityTag: '', + advertiserId: '12649566', + conversionEvents: [ + { + customVariables: [ + { + from: '', + to: '', + }, + ], + eventName: 'Sign up Completed', + floodlightActivityTag: 'signu0', + floodlightGroupTag: 'conv01', + salesTag: false, + }, + { + customVariables: [ + { + from: 'rudder1', + to: '1', + }, + { + from: 'akash1', + to: '2', + }, + ], + eventName: 'Order Complete', + floodlightActivityTag: 'order0', + floodlightGroupTag: 'conv000', + salesTag: false, + }, + { + customVariables: [ + { + from: '', + to: '', + }, + ], + eventName: 'Checkout Started', + floodlightActivityTag: 'check0', + floodlightGroupTag: 'conv00', + salesTag: true, + }, + { + customVariables: [ + { + to: '1', + from: 'rudder2', + }, + { + to: '2', + from: 'akash2', + }, + { + to: '3', + from: 'friendlyName2', + }, + { + to: '4', + from: 'name2', + }, + ], + eventName: 'Purchase', + floodlightActivityTag: 'Pur0', + floodlightGroupTag: 'conv111', + salesTag: false, + }, + ], + groupTag: '', + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + message: { + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99090', + userId: '1234', + type: 'track', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + adTrackingEnabled: 'true', + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + ip: '0.0.0.0', + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + event: 'Purchase', + properties: { + orderId: 111, + quantity: 999999, + revenue: 800, + products: [ + { + sku: '45790-32', + url: 'https://www.example.com/product/path', + name: 'Monopoly: 3rd Edition', + price: 19, + category: 'Games', + quantity: 1, + image_url: 'https:///www.example.com/product/path.jpg', + product_id: '507f1f77bcf86cd799439011', + }, + { + sku: '46493-32', + name: 'Uno Card Game', + price: 3, + category: 'Games', + quantity: 2, + product_id: '505bd76785ebb509fc183733', + }, + ], + rudder2: 0, + akash2: 'akash2', + friendlyName2: false, + name2: '1234', + }, + integrations: { + All: true, + 'DCM Floodlight': { + COPPA: 'false', + GDPR: '1', + npa: true, + }, + }, + messageId: 'ea5cfab2-3961-4d8a-8187-3d1858c90a9f', + originalTimestamp: '2020-01-17T04:53:51.185Z', + receivedAt: '2020-01-17T10:23:52.688+05:30', + sentAt: '2020-01-17T04:53:52.667Z', + timestamp: '2020-01-17T10:23:51.206+05:30', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'GET', + endpoint: + 'https://ad.doubleclick.net/ddm/activity/src=12649566;cat=Pur0;type=conv111;dc_rdid=T0T0T072-5e28-45a1-9eda-ce22a3e36d1a;ord=ea5cfab2-3961-4d8a-8187-3d1858c90a9f;dc_lat=1;tag_for_child_directed_treatment=0;tfua=1;npa=1;u1=0;u2=akash2;u4=1234', + headers: { + 'User-Agent': + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'dcm_floodlight', + description: 'Test 25', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + advertiserId: '12649566', + activityTag: 'check0', + groupTag: 'conv00', + conversionEvents: [ + { + customVariables: [ + { + to: '', + from: '', + }, + ], + eventName: 'Viewed Page', + floodlightActivityTag: 'signu0', + floodlightGroupTag: 'conv01', + salesTag: false, + }, + { + customVariables: [ + { + to: '1', + from: 'rudder1', + }, + { + to: '2', + from: 'akash1', + }, + ], + eventName: 'Order Complete', + floodlightActivityTag: 'order0', + floodlightGroupTag: 'conv000', + salesTag: false, + }, + { + eventName: 'Checkout Started', + floodlightActivityTag: '', + floodlightGroupTag: '', + salesTag: true, + }, + { + customVariables: [ + { + to: '1', + from: 'rudder2', + }, + { + to: '2', + from: 'akash2', + }, + { + to: '3', + from: 'friendlyName2', + }, + { + to: '4', + from: 'name2', + }, + ], + eventName: 'Purchase', + floodlightActivityTag: 'Pur0', + floodlightGroupTag: 'conv111', + salesTag: false, + }, + ], + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + message: { + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99090', + userId: '1234', + type: 'page', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + adTrackingEnabled: 'true', + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + ip: '0.0.0.0', + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + properties: { + orderId: 111, + quantity: 999999, + revenue: 800, + }, + integrations: { + All: true, + 'DCM Floodlight': { + COPPA: 'false', + GDPR: '1', + npa: 'true', + }, + }, + messageId: 'ea5cfab2-3961-4d8a-8187-3d1858c90a9f', + originalTimestamp: '2020-01-17T04:53:51.185Z', + receivedAt: '2020-01-17T10:23:52.688+05:30', + sentAt: '2020-01-17T04:53:52.667Z', + timestamp: '2020-01-17T10:23:51.206+05:30', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'GET', + endpoint: + 'https://ad.doubleclick.net/ddm/activity/src=12649566;cat=signu0;type=conv01;dc_rdid=T0T0T072-5e28-45a1-9eda-ce22a3e36d1a;ord=ea5cfab2-3961-4d8a-8187-3d1858c90a9f;dc_lat=1;tag_for_child_directed_treatment=0;tfua=1;npa=1', + headers: { + 'User-Agent': + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'dcm_floodlight', + description: 'Test 26', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + activityTag: '', + advertiserId: '12649566', + conversionEvents: [ + { + customVariables: [ + { + to: '', + from: '', + }, + ], + eventName: 'Sign up Completed', + floodlightActivityTag: 'signu0', + floodlightGroupTag: 'conv01', + salesTag: false, + }, + { + customVariables: [ + { + to: '1', + from: 'rudder1', + }, + { + to: '2', + from: 'akash1', + }, + ], + eventName: 'Order Complete', + floodlightActivityTag: 'order0', + floodlightGroupTag: 'conv000', + salesTag: false, + }, + { + customVariables: [ + { + to: '', + from: '', + }, + ], + eventName: 'Checkout Started', + floodlightActivityTag: 'check0', + floodlightGroupTag: 'conv00', + salesTag: true, + }, + { + customVariables: [ + { + to: '1', + from: 'rudder2', + }, + { + to: '2', + from: 'akash2', + }, + { + to: '3', + from: 'friendlyName2', + }, + { + to: '4', + from: 'name2', + }, + ], + eventName: 'Purchase', + floodlightActivityTag: 'Pur0', + floodlightGroupTag: 'conv111', + salesTag: false, + }, + ], + groupTag: '', + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + message: { + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99090', + userId: '1234', + type: 'track', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + adTrackingEnabled: 'true', + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + model: 'AOSP on IA Emulator', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + brand: 'Google2', + }, + ip: '0.0.0.0', + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + traits: { + name2: 'traits-v1', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + event: 'Purchase', + properties: { + orderId: 111, + quantity: 999999, + revenue: 800, + products: [ + { + sku: '45790-32', + url: 'https://www.example.com/product/path', + name: 'Monopoly: 3rd Edition', + price: 19, + category: 'Games', + quantity: 1, + image_url: 'https:///www.example.com/product/path.jpg', + product_id: '507f1f77bcf86cd799439011', + }, + { + sku: '46493-32', + name: 'Uno Card Game', + price: 3, + category: 'Games', + quantity: 2, + product_id: '505bd76785ebb509fc183733', + }, + ], + rudder2: '0', + akash2: 'akash2', + friendlyName2: false, + }, + integrations: { + All: true, + 'DCM Floodlight': { + COPPA: 'false', + GDPR: '1', + npa: true, + }, + }, + messageId: 'ea5cfab2-3961-4d8a-8187-3d1858c90a9f', + originalTimestamp: '2020-01-17T04:53:51.185Z', + receivedAt: '2020-01-17T10:23:52.688+05:30', + sentAt: '2020-01-17T04:53:52.667Z', + timestamp: '2020-01-17T10:23:51.206+05:30', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'GET', + endpoint: + 'https://ad.doubleclick.net/ddm/activity/src=12649566;cat=Pur0;type=conv111;dc_rdid=T0T0T072-5e28-45a1-9eda-ce22a3e36d1a;ord=ea5cfab2-3961-4d8a-8187-3d1858c90a9f;dc_lat=1;tag_for_child_directed_treatment=0;tfua=1;npa=1;u1=0;u2=akash2;u4=traits-v1', + headers: { + 'User-Agent': + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/dynamic_yield/processor/data.ts b/test/integrations/destinations/dynamic_yield/processor/data.ts new file mode 100644 index 0000000000..f72f1574f7 --- /dev/null +++ b/test/integrations/destinations/dynamic_yield/processor/data.ts @@ -0,0 +1,1041 @@ +export const data = [ + { + name: 'dynamic_yield', + description: 'Identify call without hashed email 21313123', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: '507f191e810c19729de860ea', + context: { + ip: '54.100.200.255', + sessionId: '16733896350494', + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.115 Safari/537.36', + }, + integrations: { + All: true, + }, + receivedAt: '2015-02-23T22:28:55.387Z', + sentAt: '2015-02-23T22:28:55.111Z', + timestamp: '2015-02-23T22:28:55.111Z', + traits: { + email: 'peter@example.com', + }, + type: 'identify', + userId: 'user0', + version: '1', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + hashEmail: true, + }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://dy-api.com/v2/collect/user/event', + headers: { + 'Content-Type': 'application/json', + 'DY-API-Key': 'dummyApiKey', + }, + params: {}, + body: { + JSON: { + user: { id: 'user0' }, + session: { custom: '16733896350494' }, + context: { device: { ip: '54.100.200.255' } }, + events: [ + { + name: 'Identify User', + properties: { + dyType: 'identify-v1', + hashedEmail: + 'f111db891a36b76df28abc74867e6c7248f796e045117f0cff27b6e2be25d2df', + }, + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + }, + ], + }, + }, + }, + { + name: 'dynamic_yield', + description: 'Identify call with hashed email', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: '507f191e810c19729de860ea', + context: { + ip: '54.100.200.255', + sessionId: '16733896350494', + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.115 Safari/537.36', + }, + integrations: { + All: true, + }, + receivedAt: '2015-02-23T22:28:55.387Z', + sentAt: '2015-02-23T22:28:55.111Z', + timestamp: '2015-02-23T22:28:55.111Z', + traits: { + email: 'f111db891a36b76df28abc74867e6c7248f796e045117f0cff27b6e2be25d2df', + }, + type: 'identify', + userId: 'user0', + version: '1', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + hashEmail: false, + }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://dy-api.com/v2/collect/user/event', + headers: { + 'Content-Type': 'application/json', + 'DY-API-Key': 'dummyApiKey', + }, + params: {}, + body: { + JSON: { + user: { id: 'user0' }, + session: { custom: '16733896350494' }, + context: { device: { ip: '54.100.200.255' } }, + events: [ + { + name: 'Identify User', + properties: { + dyType: 'identify-v1', + hashedEmail: + 'f111db891a36b76df28abc74867e6c7248f796e045117f0cff27b6e2be25d2df', + }, + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + }, + ], + }, + }, + }, + { + name: 'dynamic_yield', + description: 'Track call with Product Added event', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + context: { + traits: { + 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', + }, + type: 'track', + session_id: '16733896350494', + originalTimestamp: '2019-10-14T09:03:17.562Z', + anonymousId: '123456', + event: 'Product Added', + userId: 'testuserId1', + properties: { + product_id: '123', + sku: 'item-34454ga', + category: 'Games', + name: 'Game', + brand: 'Gamepro', + variant: '111', + price: 39.95, + quantity: 1, + coupon: 'DISC21', + position: 1, + url: 'https://www.website.com/product/path', + image_url: 'https://www.website.com/product/path.png', + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + hashEmail: false, + }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://dy-api.com/v2/collect/user/event', + headers: { + 'Content-Type': 'application/json', + 'DY-API-Key': 'dummyApiKey', + }, + params: {}, + body: { + JSON: { + user: { id: 'testuserId1' }, + session: { custom: '16733896350494' }, + context: { device: { ip: '54.100.200.255' } }, + events: [ + { + name: 'Add to Cart', + properties: { + dyType: 'add-to-cart-v1', + value: 39.95, + productId: 'item-34454ga', + quantity: 1, + }, + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + }, + ], + }, + }, + }, + { + name: 'dynamic_yield', + description: 'Identify call without email', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: '507f191e810c19729de860ea', + context: { + ip: '54.100.200.255', + sessionId: '16733896350494', + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.115 Safari/537.36', + }, + integrations: { + All: true, + }, + receivedAt: '2015-02-23T22:28:55.387Z', + sentAt: '2015-02-23T22:28:55.111Z', + timestamp: '2015-02-23T22:28:55.111Z', + traits: {}, + type: 'identify', + userId: 'user0', + version: '1', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + hashEmail: false, + }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://dy-api.com/v2/collect/user/event', + headers: { + 'Content-Type': 'application/json', + 'DY-API-Key': 'dummyApiKey', + }, + params: {}, + body: { + JSON: { + user: { id: 'user0' }, + session: { custom: '16733896350494' }, + context: { device: { ip: '54.100.200.255' } }, + events: [ + { + name: 'Identify User', + properties: { + dyType: 'identify-v1', + cuid: 'user0', + cuidType: 'userId', + }, + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + }, + ], + }, + }, + }, + { + name: 'dynamic_yield', + description: 'Track call with Product Removed event', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + context: { + traits: { + 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', + }, + type: 'track', + session_id: '16733896350494', + originalTimestamp: '2019-10-14T09:03:17.562Z', + anonymousId: '123456', + event: 'Product Removed', + userId: 'testuserId1', + properties: { + product_id: '123', + sku: 'item-34454ga', + category: 'Games', + name: 'Game', + brand: 'Gamepro', + variant: '111', + price: 39.95, + quantity: 1, + coupon: 'DISC21', + position: 1, + url: 'https://www.website.com/product/path', + image_url: 'https://www.website.com/product/path.png', + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + hashEmail: false, + }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://dy-api.com/v2/collect/user/event', + headers: { + 'Content-Type': 'application/json', + 'DY-API-Key': 'dummyApiKey', + }, + params: {}, + body: { + JSON: { + user: { id: 'testuserId1' }, + session: { custom: '16733896350494' }, + context: { device: { ip: '54.100.200.255' } }, + events: [ + { + name: 'Remove from Cart', + properties: { + dyType: 'remove-from-cart-v1', + value: 39.95, + productId: 'item-34454ga', + quantity: 1, + }, + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + }, + ], + }, + }, + }, + { + name: 'dynamic_yield', + description: 'Track call with Product Added to Wishlist event', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + context: { + traits: { + 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', + }, + type: 'track', + session_id: '16733896350494', + originalTimestamp: '2019-10-14T09:03:17.562Z', + anonymousId: '123456', + event: 'Product Added to Wishlist', + userId: 'testuserId1', + properties: { + product_id: '123', + sku: 'item-34454ga', + category: 'Games', + name: 'Game', + brand: 'Gamepro', + variant: '111', + price: 39.95, + quantity: 1, + coupon: 'DISC21', + position: 1, + url: 'https://www.website.com/product/path', + image_url: 'https://www.website.com/product/path.png', + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + hashEmail: false, + }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://dy-api.com/v2/collect/user/event', + headers: { + 'Content-Type': 'application/json', + 'DY-API-Key': 'dummyApiKey', + }, + params: {}, + body: { + JSON: { + user: { id: 'testuserId1' }, + session: { custom: '16733896350494' }, + context: { device: { ip: '54.100.200.255' } }, + events: [ + { + name: 'Add to Wishlist', + properties: { + dyType: 'add-to-wishlist-v1', + value: 39.95, + productId: 'item-34454ga', + quantity: 1, + }, + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + }, + ], + }, + }, + }, + { + name: 'dynamic_yield', + description: 'Track call with order completed event', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + context: { + traits: { + 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', + }, + type: 'track', + session_id: '16733896350494', + originalTimestamp: '2019-10-14T09:03:17.562Z', + anonymousId: '123456', + event: 'Order Completed', + userId: 'testuserId1', + properties: { + checkout_id: '12345', + order_id: '1234', + affiliation: 'Apple Store', + total: 20, + revenue: 15, + shipping: 4, + tax: 1, + discount: 1.5, + coupon: 'ImagePro', + currency: 'USD', + products: [ + { + product_id: '123', + sku: 'G-32', + name: 'Monopoly', + price: 14, + quantity: 1, + category: 'Games', + url: 'https://www.website.com/product/path', + image_url: 'https://www.website.com/product/path.jpg', + }, + { + product_id: '345', + sku: 'F-32', + name: 'UNO', + price: 3.45, + quantity: 2, + category: 'Games', + }, + ], + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + hashEmail: false, + }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://dy-api.com/v2/collect/user/event', + headers: { + 'Content-Type': 'application/json', + 'DY-API-Key': 'dummyApiKey', + }, + params: {}, + body: { + JSON: { + user: { id: 'testuserId1' }, + session: { custom: '16733896350494' }, + context: { device: { ip: '54.100.200.255' } }, + events: [ + { + name: 'Purchase', + properties: { + dyType: 'purchase-v1', + uniqueTransactionId: '1234', + value: 15, + currency: 'USD', + cart: [ + { + itemPrice: 14, + productId: 'G-32', + quantity: 1, + }, + { + itemPrice: 3.45, + productId: 'F-32', + quantity: 2, + }, + ], + }, + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + }, + ], + }, + }, + }, + { + name: 'dynamic_yield', + description: 'Unsupported group call check', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: '507f191e810c19729de860ea', + context: { + ip: '54.100.200.255', + sessionId: '16733896350494', + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.115 Safari/537.36', + }, + integrations: { + All: true, + }, + receivedAt: '2015-02-23T22:28:55.387Z', + sentAt: '2015-02-23T22:28:55.111Z', + timestamp: '2015-02-23T22:28:55.111Z', + traits: { + email: 'peter@example.com', + }, + type: 'group', + userId: 'user0', + version: '1', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 400, + error: + 'message type group is not supported: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: message type group is not supported', + statTags: { + destType: 'DYNAMIC_YIELD', + destinationId: 'destId', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'cdkV2', + module: 'destination', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + }, + { + name: 'dynamic_yield', + description: 'Event type not present', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: '507f191e810c19729de860ea', + context: { + ip: '54.100.200.255', + sessionId: '16733896350494', + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.115 Safari/537.36', + }, + integrations: { + All: true, + }, + receivedAt: '2015-02-23T22:28:55.387Z', + sentAt: '2015-02-23T22:28:55.111Z', + timestamp: '2015-02-23T22:28:55.111Z', + traits: { + email: 'peter@example.com', + }, + userId: 'user0', + version: '1', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 400, + error: + 'message Type is not present. Aborting message.: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: message Type is not present. Aborting message.', + statTags: { + destType: 'DYNAMIC_YIELD', + destinationId: 'destId', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'cdkV2', + module: 'destination', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + }, + { + name: 'dynamic_yield', + description: 'API Key not present', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: '507f191e810c19729de860ea', + type: 'identify', + context: { + ip: '54.100.200.255', + sessionId: '16733896350494', + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.115 Safari/537.36', + }, + integrations: { + All: true, + }, + receivedAt: '2015-02-23T22:28:55.387Z', + sentAt: '2015-02-23T22:28:55.111Z', + timestamp: '2015-02-23T22:28:55.111Z', + traits: { + email: 'peter@example.com', + }, + userId: 'user0', + version: '1', + }, + destination: { + Config: {}, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 400, + error: + 'Api Key is not present: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: Api Key is not present', + statTags: { + destType: 'DYNAMIC_YIELD', + destinationId: 'destId', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'cdkV2', + module: 'destination', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + }, + { + name: 'dynamic_yield', + description: 'Event is not there in input', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + context: { + traits: { + 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', + }, + type: 'track', + session_id: '16733896350494', + originalTimestamp: '2019-10-14T09:03:17.562Z', + anonymousId: '123456', + userId: 'testuserId1', + properties: { + product_id: '123', + sku: 'item-34454ga', + category: 'Games', + name: 'Game', + brand: 'Gamepro', + variant: '111', + price: 39.95, + quantity: 1, + coupon: 'DISC21', + position: 1, + url: 'https://www.website.com/product/path', + image_url: 'https://www.website.com/product/path.png', + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + apiKey: 'dummyApiKey', + }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 400, + error: + 'event is not present. Aborting.: Workflow: procWorkflow, Step: validateInputForTrack, ChildStep: undefined, OriginalError: event is not present. Aborting.', + statTags: { + destType: 'DYNAMIC_YIELD', + destinationId: 'destId', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'cdkV2', + module: 'destination', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/eloqua/processor/data.ts b/test/integrations/destinations/eloqua/processor/data.ts new file mode 100644 index 0000000000..50aad5639a --- /dev/null +++ b/test/integrations/destinations/eloqua/processor/data.ts @@ -0,0 +1,460 @@ +export const data = [ + { + name: 'eloqua', + description: 'identify payload pass', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + type: 'identify', + traits: { + C_FirstName: 'Test User', + C_patient_id1: 1, + C_MobilePhone: '+008822773355', + C_City: 'Scranton', + C_date_of_birth_1life1: '22/12/01', + }, + userId: 'testUser1234@keeptesting.com', + context: { + sources: { + job_id: '2RVkqlV1adBiIpj33kWlQzchMP1/Syncher', + version: 'v1.28.0', + job_run_id: 'cja699onfuet3te5obc0', + task_run_id: 'cja699onfuet3te5obcg', + }, + externalId: [ + { + id: 'testUser1234@keeptesting.com', + type: 'ELOQUA-contacts', + identifierType: 'C_EmailAddress', + }, + ], + mappedToDestination: 'true', + }, + recordId: '1', + rudderId: '3606d3c7-8741-4245-a254-450e137d3866', + messageId: '40def17a-1b6a-4d2d-a851-2a8d96f913bd', + }, + destination: { + Config: { + customerAccountId: '89236978', + customerId: '78678678', + audienceId: '564567', + hashEmail: false, + }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: '', + headers: {}, + params: {}, + body: { + JSON: { + identifierFieldName: 'C_EmailAddress', + data: { + C_FirstName: 'Test User', + C_patient_id1: '1', + C_MobilePhone: '+008822773355', + C_City: 'Scranton', + C_date_of_birth_1life1: '22/12/01', + C_EmailAddress: 'testUser1234@keeptesting.com', + }, + customObjectId: 'contacts', + type: 'identify', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + }, + { + name: 'eloqua', + description: 'type not correect', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + type: 'audiencelist', + traits: { + C_FirstName: 'Test User', + C_patient_id1: 1, + C_MobilePhone: '+008822773355', + C_City: 'Scranton', + C_date_of_birth_1life1: '22/12/01', + }, + userId: 'testUser1234@keeptesting.com', + context: { + sources: { + job_id: '2RVkqlV1adBiIpj33kWlQzchMP1/Syncher', + version: 'v1.28.0', + job_run_id: 'cja699onfuet3te5obc0', + task_run_id: 'cja699onfuet3te5obcg', + }, + externalId: [ + { + id: 'testUser1234@keeptesting.com', + type: 'ELOQUA-contacts', + identifierType: 'C_EmailAddress', + }, + ], + mappedToDestination: 'true', + }, + recordId: '1', + rudderId: '3606d3c7-8741-4245-a254-450e137d3866', + messageId: '40def17a-1b6a-4d2d-a851-2a8d96f913bd', + }, + destination: { + Config: { + customerAccountId: '89236978', + customerId: '78678678', + audienceId: '564567', + hashEmail: false, + }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + 'Event type audiencelist is not supported. Aborting message.: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: Event type audiencelist is not supported. Aborting message.', + statTags: { + destType: 'ELOQUA', + destinationId: 'destId', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'cdkV2', + module: 'destination', + workspaceId: 'wspId', + }, + statusCode: 400, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + }, + { + name: 'eloqua', + description: 'trits not correect', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + type: 'identify', + userId: 'testUser1234@keeptesting.com', + context: { + sources: { + job_id: '2RVkqlV1adBiIpj33kWlQzchMP1/Syncher', + version: 'v1.28.0', + job_run_id: 'cja699onfuet3te5obc0', + task_run_id: 'cja699onfuet3te5obcg', + }, + externalId: [ + { + id: 'testUser1234@keeptesting.com', + type: 'ELOQUA-contacts', + identifierType: 'C_EmailAddress', + }, + ], + mappedToDestination: 'true', + }, + recordId: '1', + rudderId: '3606d3c7-8741-4245-a254-450e137d3866', + messageId: '40def17a-1b6a-4d2d-a851-2a8d96f913bd', + }, + destination: { + Config: { + customerAccountId: '89236978', + customerId: '78678678', + audienceId: '564567', + hashEmail: false, + }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + 'Message traits/properties not present. Aborting message.: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: Message traits/properties not present. Aborting message.', + statTags: { + destType: 'ELOQUA', + destinationId: 'destId', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'cdkV2', + module: 'destination', + workspaceId: 'wspId', + }, + statusCode: 400, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + }, + { + name: 'eloqua', + description: 'identify payload pass 2', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + type: 'identify', + traits: { + C_FirstName: 'Test User', + C_patient_id1: 1, + C_MobilePhone: '+008822773355', + C_City: 'Scranton', + C_date_of_birth_1life1: '22/12/01', + }, + userId: 'testUser1234@keeptesting.com', + context: { + sources: { + job_id: '2RVkqlV1adBiIpj33kWlQzchMP1/Syncher', + version: 'v1.28.0', + job_run_id: 'cja699onfuet3te5obc0', + task_run_id: 'cja699onfuet3te5obcg', + }, + externalId: [ + { + id: 'testUser1234@keeptesting.com', + type: 'ELOQUA-contacts', + identifierType: 'C_EmailAddress', + }, + ], + mappedToDestination: 'true', + }, + recordId: '1', + rudderId: '3606d3c7-8741-4245-a254-450e137d3866', + messageId: '40def17a-1b6a-4d2d-a851-2a8d96f913bd', + }, + destination: { + Config: { + customerAccountId: '89236978', + customerId: '78678678', + audienceId: '564567', + hashEmail: false, + }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: '', + headers: {}, + params: {}, + body: { + JSON: { + identifierFieldName: 'C_EmailAddress', + data: { + C_FirstName: 'Test User', + C_patient_id1: '1', + C_MobilePhone: '+008822773355', + C_City: 'Scranton', + C_date_of_birth_1life1: '22/12/01', + C_EmailAddress: 'testUser1234@keeptesting.com', + }, + customObjectId: 'contacts', + type: 'identify', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + }, + { + name: 'eloqua', + description: 'track payload pass', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + type: 'track', + properties: { + key11: 'Test User', + key21: 1, + contactID11: '+008822773355', + }, + userId: 'testUser1234@keeptesting.com', + channel: 'sources', + context: { + sources: { + job_id: '2RVkqlV1adBiIpj33kWlQzchMP1/Syncher', + version: 'v1.28.0', + job_run_id: 'cja699onfuet3te5obc0', + task_run_id: 'cja699onfuet3te5obcg', + }, + externalId: [ + { + id: 'testUser1234@keeptesting.com', + type: 'ELOQUA-172', + identifierType: 'contactID1', + }, + ], + mappedToDestination: 'true', + }, + recordId: '1', + rudderId: '3606d3c7-8741-4245-a254-450e137d3866', + messageId: '40def17a-1b6a-4d2d-a851-2a8d96f913bd', + }, + destination: { + Config: { + customerAccountId: '89236978', + customerId: '78678678', + audienceId: '564567', + hashEmail: false, + }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: '', + headers: {}, + params: {}, + body: { + JSON: { + identifierFieldName: 'contactID1', + data: { + key11: 'Test User', + key21: '1', + contactID11: '+008822773355', + contactID1: 'testUser1234@keeptesting.com', + }, + customObjectId: '172', + type: 'track', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/fullstory/processor/data.ts b/test/integrations/destinations/fullstory/processor/data.ts new file mode 100644 index 0000000000..d206b4a84f --- /dev/null +++ b/test/integrations/destinations/fullstory/processor/data.ts @@ -0,0 +1,462 @@ +export const data = [ + { + name: 'fullstory', + description: 'Complete track event', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: '78c53c15-32a1-4b65-adac-bec2d7bb8fab', + channel: 'web', + context: { + app: { + name: 'RSPM', + version: '1.9.0', + }, + campaign: { + name: 'sales campaign', + source: 'google', + medium: 'medium', + term: 'event data', + content: 'Make sense of the modern data stack', + }, + ip: '192.0.2.0', + library: { + name: 'RudderLabs JavaScript SDK', + version: '2.9.1', + }, + locale: 'en-US', + device: { + manufacturer: 'Nokia', + model: 'N2023', + }, + page: { + path: '/best-seller/1', + initial_referrer: 'https://www.google.com/search', + initial_referring_domain: 'google.com', + referrer: 'https://www.google.com/search?q=estore+bestseller', + referring_domain: 'google.com', + search: 'estore bestseller', + title: 'The best sellers offered by EStore', + url: 'https://www.estore.com/best-seller/1', + }, + screen: { + density: 420, + height: 1794, + width: 1080, + innerHeight: 200, + innerWidth: 100, + }, + userAgent: + 'Dalvik/2.1.0 (Linux; U; Android 9; Android SDK built for x86 Build/PSR1.180720.075)', + }, + event: 'Product Reviewed', + integrations: { + All: true, + }, + messageId: '1578564113557-af022c68-429e-4af4-b99b-2b9174056383', + properties: { + userId: 'u001', + sessionId: 's001', + review_id: 'review_id_1', + product_id: 'product_id_1', + rating: 5, + review_body: 'Sample Review Body', + latitude: 44.56, + longitude: 54.46, + region: 'Atlas', + city: 'NY', + country: 'USA', + }, + originalTimestamp: '2020-01-09T10:01:53.558Z', + type: 'track', + sentAt: '2020-01-09T10:02:03.257Z', + }, + destination: { + ID: '1pYpzzvcn7AQ2W9GGIAZSsN6Mfq', + Name: 'Fullstory', + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiKey: 'dummyfullstoryAPIKey', + }, + Enabled: true, + Transformations: [], + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + JSON: { + name: 'Product Reviewed', + properties: { + userId: 'u001', + sessionId: 's001', + review_id: 'review_id_1', + product_id: 'product_id_1', + rating: 5, + review_body: 'Sample Review Body', + latitude: 44.56, + longitude: 54.46, + region: 'Atlas', + city: 'NY', + country: 'USA', + }, + timestamp: '2020-01-09T10:01:53.558Z', + context: { + browser: { + url: 'https://www.estore.com/best-seller/1', + user_agent: + 'Dalvik/2.1.0 (Linux; U; Android 9; Android SDK built for x86 Build/PSR1.180720.075)', + initial_referrer: 'https://www.google.com/search', + }, + mobile: { + app_name: 'RSPM', + app_version: '1.9.0', + }, + device: { + manufacturer: 'Nokia', + model: 'N2023', + }, + location: { + ip_address: '192.0.2.0', + latitude: 44.56, + longitude: 54.46, + city: 'NY', + region: 'Atlas', + country: 'USA', + }, + }, + session: { + id: 's001', + }, + user: { + id: 'u001', + }, + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.fullstory.com/v2/events', + headers: { + authorization: 'Basic dummyfullstoryAPIKey', + 'content-type': 'application/json', + }, + params: {}, + files: {}, + userId: '', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'fullstory', + description: 'Missing event name', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + device: { + manufacturer: 'Nokia', + model: 'N2023', + }, + userAgent: + 'Dalvik/2.1.0 (Linux; U; Android 9; Android SDK built for x86 Build/PSR1.180720.075)', + }, + integrations: { + All: true, + }, + properties: { + userId: 'u001', + latitude: 44.56, + longitude: 54.46, + region: 'Atlas', + city: 'NY', + country: 'USA', + }, + originalTimestamp: '2020-01-09T10:01:53.558Z', + type: 'track', + sentAt: '2020-01-09T10:02:03.257Z', + }, + destination: { + ID: '1pYpzzvcn7AQ2W9GGIAZSsN6Mfq', + Name: 'Fullstory', + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiKey: 'dummyfullstoryAPIKey', + }, + Enabled: true, + Transformations: [], + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 400, + error: + 'event is required for track call: Workflow: procWorkflow, Step: validateEventName, ChildStep: undefined, OriginalError: event is required for track call', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + implementation: 'cdkV2', + destType: 'FULLSTORY', + module: 'destination', + feature: 'processor', + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + }, + { + name: 'fullstory', + description: 'Complete identify event', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + userId: 'dummy-user001', + channel: 'web', + context: { + traits: { + company: 'Initech', + address: { + country: 'USA', + state: 'CA', + street: '101 dummy street', + }, + email: 'dummyuser@domain.com', + name: 'dummy user', + phone: '099-999-9999', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36', + }, + integrations: { + All: true, + }, + originalTimestamp: '2020-01-27T12:20:55.301Z', + receivedAt: '2020-01-27T17:50:58.657+05:30', + request_ip: '14.98.244.60', + sentAt: '2020-01-27T12:20:56.849Z', + timestamp: '2020-01-27T17:50:57.109+05:30', + type: 'identify', + }, + destination: { + ID: '1pYpzzvcn7AQ2W9GGIAZSsN6Mfq', + Name: 'Fullstory', + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiKey: 'fullstoryAPIKey', + }, + Enabled: true, + Transformations: [], + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + JSON: { + properties: { + company: 'Initech', + address: { + country: 'USA', + state: 'CA', + street: '101 dummy street', + }, + email: 'dummyuser@domain.com', + name: 'dummy user', + phone: '099-999-9999', + }, + uid: 'dummy-user001', + email: 'dummyuser@domain.com', + display_name: 'dummy user', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.fullstory.com/v2/users', + headers: { + authorization: 'Basic fullstoryAPIKey', + 'content-type': 'application/json', + }, + params: {}, + files: {}, + userId: '', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'fullstory', + description: 'Identify event with needed traits', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + userId: 'dummy-user001', + channel: 'web', + context: { + traits: { + email: 'dummyuser@domain.com', + name: 'dummy user', + phone: '099-999-9999', + }, + }, + timestamp: '2020-01-27T17:50:57.109+05:30', + type: 'identify', + }, + destination: { + ID: '1pYpzzvcn7AQ2W9GGIAZSsN6Mfq', + Name: 'Fullstory', + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiKey: 'fullstoryAPIKey', + }, + Enabled: true, + Transformations: [], + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + JSON: { + properties: { + email: 'dummyuser@domain.com', + name: 'dummy user', + phone: '099-999-9999', + }, + uid: 'dummy-user001', + email: 'dummyuser@domain.com', + display_name: 'dummy user', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.fullstory.com/v2/users', + headers: { + authorization: 'Basic fullstoryAPIKey', + 'content-type': 'application/json', + }, + params: {}, + files: {}, + userId: '', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/heap/processor/data.ts b/test/integrations/destinations/heap/processor/data.ts index be4f9c87bf..6efa45435c 100644 --- a/test/integrations/destinations/heap/processor/data.ts +++ b/test/integrations/destinations/heap/processor/data.ts @@ -15,7 +15,7 @@ export const data = [ }, DestinationDefinition: { Config: { - cdkEnabled: true, + cdkV2Enabled: true, }, DisplayName: 'Heap.io', ID: '1WTbl0l5GjOQKOvfmcGwk0T49kV', @@ -26,6 +26,10 @@ export const data = [ Name: 'heap test', Transformations: [], }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, message: { anonymousId: 'sampath', channel: 'web', @@ -104,6 +108,10 @@ export const data = [ userId: 'sampath', }, statusCode: 200, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, @@ -125,7 +133,7 @@ export const data = [ }, DestinationDefinition: { Config: { - cdkEnabled: true, + cdkV2Enabled: true, }, DisplayName: 'Heap.io', ID: '1WTbl0l5GjOQKOvfmcGwk0T49kV', @@ -136,6 +144,10 @@ export const data = [ Name: 'heap test', Transformations: [], }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, message: { anonymousId: 'sampath', channel: 'web', @@ -221,6 +233,10 @@ export const data = [ userId: 'sampath', }, statusCode: 200, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, @@ -242,7 +258,7 @@ export const data = [ }, DestinationDefinition: { Config: { - cdkEnabled: false, + cdkV2Enabled: false, }, DisplayName: 'Heap.io', ID: '1WTbl0l5GjOQKOvfmcGwk0T49kV', @@ -253,6 +269,10 @@ export const data = [ Name: 'heap test', Transformations: [], }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, message: { anonymousId: 'sampath', channel: 'web', @@ -311,8 +331,14 @@ export const data = [ feature: 'processor', implementation: 'native', module: 'destination', + destinationId: 'destId', + workspaceId: 'wspId', }, statusCode: 400, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, @@ -334,7 +360,7 @@ export const data = [ }, DestinationDefinition: { Config: { - cdkEnabled: false, + cdkV2Enabled: false, }, DisplayName: 'Heap.io', ID: '1WTbl0l5GjOQKOvfmcGwk0T49kV', @@ -345,6 +371,10 @@ export const data = [ Name: 'heap test', Transformations: [], }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, message: { anonymousId: 'sampath', channel: 'web', @@ -403,6 +433,8 @@ export const data = [ { error: 'message type page not supported for heap', statTags: { + destinationId: 'destId', + workspaceId: 'wspId', destType: 'HEAP', errorCategory: 'dataValidation', errorType: 'instrumentation', @@ -411,6 +443,10 @@ export const data = [ module: 'destination', }, statusCode: 400, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, @@ -432,7 +468,7 @@ export const data = [ }, DestinationDefinition: { Config: { - cdkEnabled: true, + cdkV2Enabled: true, }, DisplayName: 'Heap.io', ID: '1WTbl0l5GjOQKOvfmcGwk0T49kV', @@ -443,6 +479,10 @@ export const data = [ Name: 'heap test', Transformations: [], }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, message: { anonymousId: 'sampath', channel: 'web', @@ -530,6 +570,10 @@ export const data = [ userId: 'sampath', }, statusCode: 200, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, @@ -551,7 +595,7 @@ export const data = [ }, DestinationDefinition: { Config: { - cdkEnabled: true, + cdkV2Enabled: true, }, DisplayName: 'Heap.io', ID: '1WTbl0l5GjOQKOvfmcGwk0T49kV', @@ -562,6 +606,10 @@ export const data = [ Name: 'heap test', Transformations: [], }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, message: { anonymousId: 'sampath', channel: 'web', @@ -649,6 +697,10 @@ export const data = [ userId: 'sampath', }, statusCode: 200, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, @@ -670,7 +722,7 @@ export const data = [ }, DestinationDefinition: { Config: { - cdkEnabled: true, + cdkV2Enabled: true, }, DisplayName: 'Heap.io', ID: '1WTbl0l5GjOQKOvfmcGwk0T49kV', @@ -681,6 +733,10 @@ export const data = [ Name: 'heap test', Transformations: [], }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, message: { anonymousId: 'sampath', channel: 'web', @@ -771,6 +827,10 @@ export const data = [ userId: 'sampath', }, statusCode: 200, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, @@ -792,7 +852,7 @@ export const data = [ }, DestinationDefinition: { Config: { - cdkEnabled: true, + cdkV2Enabled: true, }, DisplayName: 'Heap.io', ID: '1WTbl0l5GjOQKOvfmcGwk0T49kV', @@ -803,6 +863,10 @@ export const data = [ Name: 'heap test', Transformations: [], }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, message: { anonymousId: 'sampath', channel: 'web', @@ -888,6 +952,10 @@ export const data = [ userId: 'sampath', }, statusCode: 200, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, diff --git a/test/integrations/destinations/kochava/processor/data.ts b/test/integrations/destinations/kochava/processor/data.ts index d17e9795ff..06b5667c2a 100644 --- a/test/integrations/destinations/kochava/processor/data.ts +++ b/test/integrations/destinations/kochava/processor/data.ts @@ -12,7 +12,7 @@ export const data = [ destination: { Config: { apiKey: '' }, DestinationDefinition: { - Config: { cdkEnabled: true }, + Config: { cdkV2Enabled: true }, DisplayName: 'Kochava', ID: '1WTpBSTiL3iAUHUdW7rHT4sawgU', Name: 'KOCHAVA', @@ -22,6 +22,10 @@ export const data = [ Name: 'kochava test', Transformations: [], }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, message: { anonymousId: 'sampath', channel: 'web', @@ -103,6 +107,10 @@ export const data = [ userId: 'sampath', }, statusCode: 200, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, @@ -144,12 +152,13 @@ export const data = [ sentAt: '2019-10-14T09:03:22.563Z', }, metadata: { - destinationId: '1WTpIHpH7NTBgjeiUPW1kCUgZGI', + destinationId: 'destId', + workspaceId: 'wspId', }, destination: { Config: { apiKey: '' }, DestinationDefinition: { - Config: { cdkEnabled: true }, + Config: { cdkV2Enabled: true }, DisplayName: 'Kochava', ID: '1WTpBSTiL3iAUHUdW7rHT4sawgU', Name: 'KOCHAVA', @@ -170,18 +179,21 @@ export const data = [ status: 200, body: [ { - error: 'Bad event. Original error: message type "identify" not supported for "kochava"', + error: + 'message type identify is not supported: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: message type identify is not supported', metadata: { - destinationId: '1WTpIHpH7NTBgjeiUPW1kCUgZGI', + destinationId: 'destId', + workspaceId: 'wspId', }, statTags: { destType: 'KOCHAVA', errorCategory: 'dataValidation', - destinationId: '1WTpIHpH7NTBgjeiUPW1kCUgZGI', + destinationId: 'destId', errorType: 'instrumentation', feature: 'processor', - implementation: 'cdkV1', + implementation: 'cdkV2', module: 'destination', + workspaceId: 'wspId', }, statusCode: 400, }, @@ -225,10 +237,14 @@ export const data = [ integrations: { All: true }, sentAt: '2019-10-14T09:03:22.563Z', }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, destination: { Config: { apiKey: '' }, DestinationDefinition: { - Config: { cdkEnabled: true }, + Config: { cdkV2Enabled: true }, DisplayName: 'Kochava', ID: '1WTpBSTiL3iAUHUdW7rHT4sawgU', Name: 'KOCHAVA', @@ -288,6 +304,10 @@ export const data = [ userId: '00000000000000000000000000', }, statusCode: 200, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, @@ -329,10 +349,14 @@ export const data = [ integrations: { All: true }, sentAt: '2019-10-14T09:03:22.563Z', }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, destination: { Config: { apiKey: '' }, DestinationDefinition: { - Config: { cdkEnabled: true }, + Config: { cdkV2Enabled: true }, DisplayName: 'Kochava', ID: '1WTpBSTiL3iAUHUdW7rHT4sawgU', Name: 'KOCHAVA', @@ -392,6 +416,10 @@ export const data = [ userId: '00000000000000000000000000', }, statusCode: 200, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, @@ -444,10 +472,14 @@ export const data = [ type: 'screen', sentAt: '2020-03-12T09:05:13.042Z', }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, destination: { Config: { apiKey: '' }, DestinationDefinition: { - Config: { cdkEnabled: true }, + Config: { cdkV2Enabled: true }, DisplayName: 'Kochava', ID: '1WTpBSTiL3iAUHUdW7rHT4sawgU', Name: 'KOCHAVA', @@ -511,6 +543,10 @@ export const data = [ userId: '5094f5704b9cf2b3', }, statusCode: 200, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, @@ -564,10 +600,14 @@ export const data = [ type: 'screen', sentAt: '2020-03-12T09:05:13.042Z', }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, destination: { Config: { apiKey: '' }, DestinationDefinition: { - Config: { cdkEnabled: true }, + Config: { cdkV2Enabled: true }, DisplayName: 'Kochava', ID: '1WTpBSTiL3iAUHUdW7rHT4sawgU', Name: 'KOCHAVA', @@ -631,6 +671,10 @@ export const data = [ userId: '5094f5704b9cf2b3', }, statusCode: 200, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, @@ -687,7 +731,7 @@ export const data = [ destination: { Config: { apiKey: '' }, DestinationDefinition: { - Config: { cdkEnabled: true }, + Config: { cdkV2Enabled: true }, DisplayName: 'Kochava', ID: '1WTpBSTiL3iAUHUdW7rHT4sawgU', Name: 'KOCHAVA', @@ -697,6 +741,10 @@ export const data = [ Name: 'kochava test', Transformations: [], }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], method: 'POST', @@ -750,6 +798,10 @@ export const data = [ userId: '5094f5704b9cf2b3', }, statusCode: 200, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, @@ -800,10 +852,14 @@ export const data = [ type: 'screen', sentAt: '2020-03-12T09:05:13.042Z', }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, destination: { Config: { apiKey: '' }, DestinationDefinition: { - Config: { cdkEnabled: true }, + Config: { cdkV2Enabled: true }, DisplayName: 'Kochava', ID: '1WTpBSTiL3iAUHUdW7rHT4sawgU', Name: 'KOCHAVA', @@ -862,6 +918,10 @@ export const data = [ userId: '5094f5704b9cf2b3', }, statusCode: 200, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, @@ -914,7 +974,7 @@ export const data = [ destination: { Config: { apiKey: '' }, DestinationDefinition: { - Config: { cdkEnabled: true }, + Config: { cdkV2Enabled: true }, DisplayName: 'Kochava', ID: '1WTpBSTiL3iAUHUdW7rHT4sawgU', Name: 'KOCHAVA', @@ -924,6 +984,10 @@ export const data = [ Name: 'kochava test', Transformations: [], }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], method: 'POST', @@ -972,6 +1036,10 @@ export const data = [ userId: '5094f5704b9cf2b3', }, statusCode: 200, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, @@ -1012,10 +1080,14 @@ export const data = [ integrations: { All: true }, sentAt: '2019-10-14T09:03:22.563Z', }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, destination: { Config: { apiKey: '' }, DestinationDefinition: { - Config: { cdkEnabled: true }, + Config: { cdkV2Enabled: true }, DisplayName: 'Kochava', ID: '1WTpBSTiL3iAUHUdW7rHT4sawgU', Name: 'KOCHAVA', @@ -1074,6 +1146,10 @@ export const data = [ userId: '00000000000000000000000000', }, statusCode: 200, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, @@ -1115,10 +1191,14 @@ export const data = [ integrations: { All: true }, sentAt: '2019-10-14T09:03:22.563Z', }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, destination: { Config: { apiKey: '' }, DestinationDefinition: { - Config: { cdkEnabled: true }, + Config: { cdkV2Enabled: true }, DisplayName: 'Kochava', ID: '1WTpBSTiL3iAUHUdW7rHT4sawgU', Name: 'KOCHAVA', @@ -1182,6 +1262,10 @@ export const data = [ userId: '00000000000000000000000000', }, statusCode: 200, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, @@ -1222,10 +1306,14 @@ export const data = [ integrations: { All: true }, sentAt: '2019-10-14T09:03:22.563Z', }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, destination: { Config: { apiKey: '' }, DestinationDefinition: { - Config: { cdkEnabled: true }, + Config: { cdkV2Enabled: true }, DisplayName: 'Kochava', ID: '1WTpBSTiL3iAUHUdW7rHT4sawgU', Name: 'KOCHAVA', @@ -1289,6 +1377,10 @@ export const data = [ userId: '00000000000000000000000000', }, statusCode: 200, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, @@ -1329,10 +1421,14 @@ export const data = [ integrations: { All: true }, sentAt: '2019-10-14T09:03:22.563Z', }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, destination: { Config: { apiKey: '' }, DestinationDefinition: { - Config: { cdkEnabled: true }, + Config: { cdkV2Enabled: true }, DisplayName: 'Kochava', ID: '1WTpBSTiL3iAUHUdW7rHT4sawgU', Name: 'KOCHAVA', @@ -1396,6 +1492,10 @@ export const data = [ userId: '00000000000000000000000000', }, statusCode: 200, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, diff --git a/test/integrations/destinations/launchdarkly_audience/processor/data.ts b/test/integrations/destinations/launchdarkly_audience/processor/data.ts new file mode 100644 index 0000000000..b26cf60f4c --- /dev/null +++ b/test/integrations/destinations/launchdarkly_audience/processor/data.ts @@ -0,0 +1,611 @@ +export const data = [ + { + name: 'launchdarkly_audience', + description: 'Unsupported event type', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + userId: 'user123', + type: 'abc', + properties: { + listData: { + add: [ + { + identifier: 'alex@email.com', + }, + { + identifier: 'ryan@email.com', + }, + { + identifier: 'van@email.com', + }, + ], + }, + }, + context: { + ip: '14.5.67.21', + library: { + name: 'http', + }, + }, + timestamp: '2020-02-02T00:23:09.544Z', + }, + destination: { + Config: { + audienceId: 'test-audienceId', + audienceName: 'test-audienceName', + accessToken: 'test-accessToken', + clientSideId: 'test-clientSideId', + }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 400, + error: + 'Event type abc is not supported. Aborting message.: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: Event type abc is not supported. Aborting message.', + statTags: { + destType: 'LAUNCHDARKLY_AUDIENCE', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'cdkV2', + module: 'destination', + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + }, + { + name: 'launchdarkly_audience', + description: 'List data is not passed', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + userId: 'user123', + type: 'audiencelist', + properties: {}, + context: { + ip: '14.5.67.21', + library: { + name: 'http', + }, + }, + timestamp: '2020-02-02T00:23:09.544Z', + }, + destination: { + Config: { + audienceId: 'test-audienceId', + audienceName: 'test-audienceName', + accessToken: 'test-accessToken', + clientSideId: 'test-clientSideId', + }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 400, + error: + '`listData` is not present inside properties. Aborting message.: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: `listData` is not present inside properties. Aborting message.', + statTags: { + destType: 'LAUNCHDARKLY_AUDIENCE', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'cdkV2', + module: 'destination', + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + }, + { + name: 'launchdarkly_audience', + description: 'List data is empty', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + userId: 'user123', + type: 'audiencelist', + properties: { + listData: {}, + }, + context: { + ip: '14.5.67.21', + library: { + name: 'http', + }, + }, + timestamp: '2020-02-02T00:23:09.544Z', + }, + destination: { + Config: { + audienceId: 'test-audienceId', + audienceName: 'test-audienceName', + accessToken: 'test-accessToken', + clientSideId: 'test-clientSideId', + }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 400, + error: + '`listData` is empty. Aborting message.: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: `listData` is empty. Aborting message.', + statTags: { + destType: 'LAUNCHDARKLY_AUDIENCE', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'cdkV2', + module: 'destination', + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + }, + { + name: 'launchdarkly_audience', + description: 'Unsupported action type', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + userId: 'user123', + type: 'audiencelist', + properties: { + listData: { + update: [ + { + identifier: 'alex@email.com', + }, + ], + }, + }, + context: { + ip: '14.5.67.21', + library: { + name: 'http', + }, + }, + timestamp: '2020-02-02T00:23:09.544Z', + }, + destination: { + Config: { + audienceId: 'test-audienceId', + audienceName: 'test-audienceName', + accessToken: 'test-accessToken', + clientSideId: 'test-clientSideId', + }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 400, + error: + 'Unsupported action type. Aborting message.: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: Unsupported action type. Aborting message.', + statTags: { + destType: 'LAUNCHDARKLY_AUDIENCE', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'cdkV2', + module: 'destination', + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + }, + { + name: 'launchdarkly_audience', + description: 'Add members to the audience list', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + userId: 'user123', + type: 'audiencelist', + properties: { + listData: { + add: [ + { + identifier: 'alex@email.com', + }, + { + identifier: 'ryan@email.com', + }, + { + identifier: 'van@email.com', + }, + ], + }, + }, + context: { + ip: '14.5.67.21', + library: { + name: 'http', + }, + }, + timestamp: '2020-02-02T00:23:09.544Z', + }, + destination: { + Config: { + audienceId: 'test-audienceId', + audienceName: 'test-audienceName', + accessToken: 'test-accessToken', + clientSideId: 'test-clientSideId', + }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://app.launchdarkly.com/api/v2/segment-targets/rudderstack', + headers: { + Authorization: 'test-accessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + environmentId: 'test-clientSideId', + cohortId: 'test-audienceId', + cohortName: 'test-audienceName', + listData: { + add: [ + { + id: 'alex@email.com', + }, + { + id: 'ryan@email.com', + }, + { + id: 'van@email.com', + }, + ], + remove: [], + }, + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + }, + ], + }, + }, + }, + { + name: 'launchdarkly_audience', + description: 'Remove members from the audience list', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + userId: 'user123', + type: 'audiencelist', + properties: { + listData: { + remove: [ + { + identifier: 'alex@email.com', + }, + { + identifier: 'ryan@email.com', + }, + { + identifier: 'van@email.com', + }, + ], + }, + }, + context: { + ip: '14.5.67.21', + library: { + name: 'http', + }, + }, + timestamp: '2020-02-02T00:23:09.544Z', + }, + destination: { + Config: { + audienceId: 'test-audienceId', + audienceName: 'test-audienceName', + accessToken: 'test-accessToken', + clientSideId: 'test-clientSideId', + }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://app.launchdarkly.com/api/v2/segment-targets/rudderstack', + headers: { + Authorization: 'test-accessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + environmentId: 'test-clientSideId', + cohortId: 'test-audienceId', + cohortName: 'test-audienceName', + listData: { + remove: [ + { + id: 'alex@email.com', + }, + { + id: 'ryan@email.com', + }, + { + id: 'van@email.com', + }, + ], + add: [], + }, + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + }, + ], + }, + }, + }, + { + name: 'launchdarkly_audience', + description: 'Add/Remove members', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + userId: 'user123', + type: 'audiencelist', + properties: { + listData: { + add: [ + { + identifier: 'alex@email.com', + }, + { + userId: 'user1', + }, + ], + remove: [ + { + identifier: 'ryan@email.com', + }, + { + identifier: 'van@email.com', + }, + ], + }, + }, + context: { + ip: '14.5.67.21', + library: { + name: 'http', + }, + }, + timestamp: '2020-02-02T00:23:09.544Z', + }, + destination: { + Config: { + audienceId: 'test-audienceId', + audienceName: 'test-audienceName', + accessToken: 'test-accessToken', + clientSideId: 'test-clientSideId', + }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://app.launchdarkly.com/api/v2/segment-targets/rudderstack', + headers: { + Authorization: 'test-accessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + environmentId: 'test-clientSideId', + cohortId: 'test-audienceId', + cohortName: 'test-audienceName', + listData: { + add: [ + { + id: 'alex@email.com', + }, + ], + remove: [ + { + id: 'ryan@email.com', + }, + { + id: 'van@email.com', + }, + ], + }, + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/lytics/processor/data.ts b/test/integrations/destinations/lytics/processor/data.ts index e04b1aa413..344eecc3cd 100644 --- a/test/integrations/destinations/lytics/processor/data.ts +++ b/test/integrations/destinations/lytics/processor/data.ts @@ -112,12 +112,16 @@ export const data = [ userId: 'rudder123', }, destination: { - DestinationDefinition: { Config: { cdkEnabled: true } }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, Config: { apiKey: 'dummyApiKey', stream: 'default' }, Enabled: true, Transformations: [], IsProcessorEnabled: true, }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], method: 'POST', @@ -197,6 +201,10 @@ export const data = [ files: {}, userId: '', }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, statusCode: 200, }, ], @@ -255,12 +263,16 @@ export const data = [ userId: 'rudder123', }, destination: { - DestinationDefinition: { Config: { cdkEnabled: true } }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, Config: { apiKey: 'dummyApiKey', stream: 'default' }, Enabled: true, Transformations: [], IsProcessorEnabled: true, }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], method: 'POST', @@ -295,6 +307,10 @@ export const data = [ files: {}, userId: '', }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, statusCode: 200, }, ], @@ -361,12 +377,16 @@ export const data = [ userId: 'rudder123', }, destination: { - DestinationDefinition: { Config: { cdkEnabled: true } }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, Config: { apiKey: 'dummyApiKey', stream: 'default' }, Enabled: true, Transformations: [], IsProcessorEnabled: true, }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], method: 'POST', @@ -401,6 +421,10 @@ export const data = [ files: {}, userId: '', }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, statusCode: 200, }, ], @@ -459,12 +483,17 @@ export const data = [ userId: 'rudder123', }, destination: { - DestinationDefinition: { Config: { cdkEnabled: true } }, + ID: '1pYpzzvcn7AQ2W9GGIAZSsN6Mfq', + DestinationDefinition: { Config: { cdkV2Enabled: true } }, Config: { apiKey: 'dummyApiKey', stream: 'default' }, Enabled: true, Transformations: [], IsProcessorEnabled: true, }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], method: 'POST', @@ -500,6 +529,10 @@ export const data = [ userId: '', }, statusCode: 200, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, @@ -557,12 +590,16 @@ export const data = [ userId: 'rudder123', }, destination: { - DestinationDefinition: { Config: { cdkEnabled: true } }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, Config: { apiKey: 'dummyApiKey', stream: 'default' }, Enabled: true, Transformations: [], IsProcessorEnabled: true, }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], method: 'POST', @@ -598,6 +635,10 @@ export const data = [ userId: '', }, statusCode: 200, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, @@ -655,12 +696,16 @@ export const data = [ userId: 'rudder123', }, destination: { - DestinationDefinition: { Config: { cdkEnabled: true } }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, Config: { apiKey: 'dummyApiKey', stream: 'default' }, Enabled: true, Transformations: [], IsProcessorEnabled: true, }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], method: 'POST', @@ -696,6 +741,10 @@ export const data = [ userId: '', }, statusCode: 200, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, @@ -753,7 +802,7 @@ export const data = [ }, metadata: { destinationID: 'ewksfdgDFSdvzsdmwsdfvcxj' }, destination: { - DestinationDefinition: { Config: { cdkEnabled: true } }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, Config: { apiKey: 'dummyApiKey', stream: 'default' }, Enabled: true, Transformations: [], @@ -771,13 +820,14 @@ export const data = [ body: [ { error: - 'Unknown error occurred. Original error: "type" is a required field and it must be a string', + 'message Type is not present. Aborting message.: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: message Type is not present. Aborting message.', metadata: { destinationID: 'ewksfdgDFSdvzsdmwsdfvcxj' }, statTags: { destType: 'LYTICS', - errorCategory: 'transformation', + errorCategory: 'dataValidation', + errorType: 'instrumentation', feature: 'processor', - implementation: 'cdkV1', + implementation: 'cdkV2', module: 'destination', }, statusCode: 400, @@ -839,7 +889,7 @@ export const data = [ }, metadata: { destinationID: 'ewksfdgDFSdvzsdmwsdfvcxj' }, destination: { - DestinationDefinition: { Config: { cdkEnabled: true } }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, Config: { apiKey: 'dummyApiKey', stream: 'default' }, Enabled: true, Transformations: [], @@ -856,14 +906,15 @@ export const data = [ status: 200, body: [ { - error: 'Bad event. Original error: message type "gone" not supported for "lytics"', + error: + 'message type gone is not supported: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: message type gone is not supported', metadata: { destinationID: 'ewksfdgDFSdvzsdmwsdfvcxj' }, statTags: { destType: 'LYTICS', errorCategory: 'dataValidation', errorType: 'instrumentation', feature: 'processor', - implementation: 'cdkV1', + implementation: 'cdkV2', module: 'destination', }, statusCode: 400, @@ -984,12 +1035,16 @@ export const data = [ userId: 'rudder123', }, destination: { - DestinationDefinition: { Config: { cdkEnabled: true } }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, Config: { apiKey: 'dummyApiKey', stream: 'default' }, Enabled: true, Transformations: [], IsProcessorEnabled: true, }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], method: 'POST', @@ -1070,6 +1125,10 @@ export const data = [ userId: '', }, statusCode: 200, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, @@ -1119,12 +1178,16 @@ export const data = [ destination_props: { AF: { af_uid: 'afUid' } }, }, destination: { - DestinationDefinition: { Config: { cdkEnabled: true } }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, Config: { apiKey: 'dummyApiKey', stream: 'default' }, Enabled: true, Transformations: [], IsProcessorEnabled: true, }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], method: 'POST', @@ -1160,6 +1223,10 @@ export const data = [ userId: '', }, statusCode: 200, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, @@ -1209,12 +1276,16 @@ export const data = [ destination_props: { AF: { af_uid: 'afUid' } }, }, destination: { - DestinationDefinition: { Config: { cdkEnabled: true } }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, Config: { apiKey: 'dummyApiKey', stream: 'default' }, Enabled: true, Transformations: [], IsProcessorEnabled: true, }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], method: 'POST', @@ -1250,6 +1321,10 @@ export const data = [ userId: '', }, statusCode: 200, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, @@ -1309,12 +1384,16 @@ export const data = [ userId: 'rudder123', }, destination: { - DestinationDefinition: { Config: { cdkEnabled: true } }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, Config: { apiKey: 'dummyApiKey', stream: 'default' }, Enabled: true, Transformations: [], IsProcessorEnabled: true, }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], method: 'POST', @@ -1352,6 +1431,10 @@ export const data = [ userId: '', }, statusCode: 200, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, diff --git a/test/integrations/destinations/new_relic/processor/data.ts b/test/integrations/destinations/new_relic/processor/data.ts new file mode 100644 index 0000000000..7eb4099e3b --- /dev/null +++ b/test/integrations/destinations/new_relic/processor/data.ts @@ -0,0 +1,882 @@ +export const data = [ + { + name: 'new_relic', + description: 'Test 0', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + event: 'first', + userId: 'identified user id', + type: 'track', + anonymousId: 'anon-id-new', + context: { + traits: { + trait1: 'new-val', + }, + ip: '14.5.67.21', + library: { + name: 'http', + }, + }, + properties: { + abc: '123', + key: { + abc: 123, + }, + array: [ + { + abc: 123, + }, + { + def: 123, + }, + ], + }, + timestamp: '2020-02-02T00:23:09.544Z', + sentAt: '2020-02-02T00:23:09.544Z', + originalTimestamp: '2020-02-02T00:23:09.544Z', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + accountId: '12345', + insertKey: '11111122702j2a2U2K2C7H', + customEventType: '', + sendDeviceContext: true, + sendUserIdanonymousId: true, + dataCenter: 'us', + }, + Enabled: true, + Transformations: [], + IsProcessorEnabled: true, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://insights-collector.newrelic.com/v1/accounts/12345/events', + headers: { + 'Api-Key': '11111122702j2a2U2K2C7H', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + event: 'first', + abc: '123', + 'key.abc': 123, + 'array[0].abc': 123, + 'array[1].def': 123, + timestamp: 1580602989, + eventType: 'rudderstack', + userId: 'identified user id', + anonymousId: 'anon-id-new', + 'traits.trait1': 'new-val', + ip: '14.5.67.21', + 'library.name': 'http', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'new_relic', + description: 'Test 1', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + event: 'second', + userId: 'identified user id', + type: 'track', + anonymousId: 'anon-id-new', + context: { + traits: { + trait1: 'new-val', + }, + ip: '14.5.67.21', + library: { + name: 'http', + }, + }, + properties: { + abc: '123', + key: { + abc: 123, + }, + array: [ + { + abc: 123, + }, + { + def: 'test', + }, + ], + }, + timestamp: '2020-02-02T00:23:09.544Z', + sentAt: '2020-02-02T00:23:09.544Z', + originalTimestamp: '2020-02-02T00:23:09.544Z', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + accountId: '12345', + insertKey: '11111122702j2a2U2K2C7H', + customEventType: '', + sendDeviceContext: false, + sendUserIdanonymousId: false, + dataCenter: 'us', + }, + Enabled: true, + Transformations: [], + IsProcessorEnabled: true, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://insights-collector.newrelic.com/v1/accounts/12345/events', + headers: { + 'Api-Key': '11111122702j2a2U2K2C7H', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + event: 'second', + abc: '123', + 'key.abc': 123, + 'array[0].abc': 123, + 'array[1].def': 'test', + timestamp: 1580602989, + eventType: 'rudderstack', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'new_relic', + description: 'Test 2', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + event: 'test', + userId: 'identified user id', + type: 'track', + anonymousId: 'anon-id-new', + context: { + traits: { + trait1: 'new-val', + }, + ip: '14.5.67.21', + library: { + name: 'http', + }, + }, + properties: { + abc: '123', + key: { + abc: 123, + }, + array: [ + { + abc: 123, + }, + { + def: 123, + }, + ], + }, + timestamp: '2020-02-02T00:23:09.544Z', + sentAt: '2020-02-02T00:23:09.544Z', + originalTimestamp: '2020-02-02T00:23:09.544Z', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + accountId: '12345', + insertKey: '11111122702j2a2U2K2C7H', + customEventType: 'rudder-testing', + sendDeviceContext: false, + sendUserIdanonymousId: false, + dataCenter: 'us', + }, + Enabled: true, + Transformations: [], + IsProcessorEnabled: true, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://insights-collector.newrelic.com/v1/accounts/12345/events', + headers: { + 'Api-Key': '11111122702j2a2U2K2C7H', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + event: 'test', + abc: '123', + 'key.abc': 123, + 'array[0].abc': 123, + 'array[1].def': 123, + timestamp: 1580602989, + eventType: 'rudder-testing', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'new_relic', + description: 'Test 3', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + event: 'first', + userId: 'identified user id', + type: 'track', + anonymousId: 'anon-id-new', + context: { + traits: { + trait1: 'new-val', + }, + ip: '14.5.67.21', + library: { + name: 'http', + }, + }, + properties: { + abc: '123', + key: { + abc: 123, + }, + array: [ + { + abc: 123, + }, + { + def: 123, + }, + ], + }, + timestamp: '2020-02-02T00:23:09.544Z', + sentAt: '2020-02-02T00:23:09.544Z', + originalTimestamp: '2020-02-02T00:23:09.544Z', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + accountId: '12345', + insertKey: '11111122702j2a2U2K2C7H', + customEventType: '', + sendDeviceContext: true, + sendUserIdanonymousId: true, + dataCenter: 'eu', + }, + Enabled: true, + Transformations: [], + IsProcessorEnabled: true, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://insights-collector.eu01.nr-data.net/v1/accounts/12345/events', + headers: { + 'Api-Key': '11111122702j2a2U2K2C7H', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + event: 'first', + abc: '123', + 'key.abc': 123, + 'array[0].abc': 123, + 'array[1].def': 123, + timestamp: 1580602989, + eventType: 'rudderstack', + userId: 'identified user id', + anonymousId: 'anon-id-new', + 'traits.trait1': 'new-val', + ip: '14.5.67.21', + 'library.name': 'http', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'new_relic', + description: 'Test 4', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + event: 'second', + userId: 'identified user id', + type: 'track', + anonymousId: 'anon-id-new', + context: { + traits: { + trait1: 'new-val', + }, + ip: '14.5.67.21', + library: { + name: 'http', + }, + }, + properties: { + abc: '123', + key: { + abc: 123, + }, + array: [ + { + abc: 123, + }, + { + def: 'test', + }, + ], + }, + timestamp: '2020-02-02T00:23:09.544Z', + sentAt: '2020-02-02T00:23:09.544Z', + originalTimestamp: '2020-02-02T00:23:09.544Z', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + accountId: '12345', + insertKey: '11111122702j2a2U2K2C7H', + customEventType: '', + sendDeviceContext: false, + sendUserIdanonymousId: false, + dataCenter: 'eu', + }, + Enabled: true, + Transformations: [], + IsProcessorEnabled: true, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://insights-collector.eu01.nr-data.net/v1/accounts/12345/events', + headers: { + 'Api-Key': '11111122702j2a2U2K2C7H', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + event: 'second', + abc: '123', + 'key.abc': 123, + 'array[0].abc': 123, + 'array[1].def': 'test', + timestamp: 1580602989, + eventType: 'rudderstack', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'new_relic', + description: 'Test 5', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + event: 'test', + userId: 'identified user id', + type: 'track', + anonymousId: 'anon-id-new', + context: { + traits: { + trait1: 'new-val', + }, + ip: '14.5.67.21', + library: { + name: 'http', + }, + }, + properties: { + abc: '123', + key: { + abc: 123, + }, + array: [ + { + abc: 123, + }, + { + def: 123, + }, + ], + }, + timestamp: '2020-02-02T00:23:09.544Z', + sentAt: '2020-02-02T00:23:09.544Z', + originalTimestamp: '2020-02-02T00:23:09.544Z', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + accountId: '12345', + insertKey: '11111122702j2a2U2K2C7H', + customEventType: 'rudder-testing', + sendDeviceContext: false, + sendUserIdanonymousId: true, + dataCenter: 'eu', + }, + Enabled: true, + Transformations: [], + IsProcessorEnabled: true, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://insights-collector.eu01.nr-data.net/v1/accounts/12345/events', + headers: { + 'Api-Key': '11111122702j2a2U2K2C7H', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + event: 'test', + abc: '123', + 'key.abc': 123, + 'array[0].abc': 123, + 'array[1].def': 123, + timestamp: 1580602989, + eventType: 'rudder-testing', + userId: 'identified user id', + anonymousId: 'anon-id-new', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'new_relic', + description: 'Test 6', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + event: 'test', + type: 'track', + anonymousId: 'anon-id-new', + context: { + traits: { + trait1: 'new-val', + }, + ip: '14.5.67.21', + library: { + name: 'http', + }, + }, + properties: { + abc: '123', + key: { + abc: 123, + }, + array: [ + { + abc: 123, + }, + { + def: 123, + }, + ], + }, + timestamp: '2020-02-02T00:23:09.544Z', + sentAt: '2020-02-02T00:23:09.544Z', + originalTimestamp: '2020-02-02T00:23:09.544Z', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + accountId: '12345', + insertKey: '11111122702j2a2U2K2C7H', + customEventType: '', + sendDeviceContext: true, + sendUserIdanonymousId: true, + dataCenter: 'us', + }, + Enabled: true, + Transformations: [], + IsProcessorEnabled: true, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://insights-collector.newrelic.com/v1/accounts/12345/events', + headers: { + 'Api-Key': '11111122702j2a2U2K2C7H', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + event: 'test', + abc: '123', + 'key.abc': 123, + 'array[0].abc': 123, + 'array[1].def': 123, + timestamp: 1580602989, + eventType: 'rudderstack', + anonymousId: 'anon-id-new', + 'traits.trait1': 'new-val', + ip: '14.5.67.21', + 'library.name': 'http', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'new_relic', + description: 'Test 7', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + event: 'first', + userId: 'identified user id', + type: 'identify', + anonymousId: 'anon-id-new', + context: { + traits: { + trait1: 'new-val', + }, + ip: '14.5.67.21', + library: { + name: 'http', + }, + }, + traits: { + abc: '123', + key: { + abc: 123, + }, + array: [ + { + abc: 123, + }, + { + def: 123, + }, + ], + }, + timestamp: '2020-02-02T00:23:09.544Z', + sentAt: '2020-02-02T00:23:09.544Z', + originalTimestamp: '2020-02-02T00:23:09.544Z', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + accountId: '12345', + insertKey: '11111122702j2a2U2K2C7H', + customEventType: '', + sendDeviceContext: true, + sendUserIdanonymousId: true, + dataCenter: 'us', + }, + Enabled: true, + Transformations: [], + IsProcessorEnabled: true, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 400, + error: + 'message type identify is not supported: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: message type identify is not supported', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + implementation: 'cdkV2', + destType: 'NEW_RELIC', + module: 'destination', + feature: 'processor', + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/optimizely_fullstack/processor/data.ts b/test/integrations/destinations/optimizely_fullstack/processor/data.ts index 09749178ee..52fbdfe5fe 100644 --- a/test/integrations/destinations/optimizely_fullstack/processor/data.ts +++ b/test/integrations/destinations/optimizely_fullstack/processor/data.ts @@ -55,7 +55,8 @@ export const data = [ 'Data File Url is not present. Aborting: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: Data File Url is not present. Aborting', statTags: { destType: 'OPTIMIZELY_FULLSTACK', - errorCategory: 'platform', + errorCategory: 'dataValidation', + errorType: 'configuration', feature: 'processor', implementation: 'cdkV2', module: 'destination', @@ -121,7 +122,8 @@ export const data = [ 'Variation ID is not present in the integrations object: Workflow: procWorkflow, Step: validateInputForIdentify, ChildStep: undefined, OriginalError: Variation ID is not present in the integrations object', statTags: { destType: 'OPTIMIZELY_FULLSTACK', - errorCategory: 'platform', + errorCategory: 'dataValidation', + errorType: 'instrumentation', feature: 'processor', implementation: 'cdkV2', module: 'destination', @@ -186,7 +188,8 @@ export const data = [ 'Account ID is not present. Aborting: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: Account ID is not present. Aborting', statTags: { destType: 'OPTIMIZELY_FULLSTACK', - errorCategory: 'platform', + errorCategory: 'dataValidation', + errorType: 'configuration', feature: 'processor', implementation: 'cdkV2', module: 'destination', @@ -251,7 +254,8 @@ export const data = [ 'Campaign ID is not present. Aborting: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: Campaign ID is not present. Aborting', statTags: { destType: 'OPTIMIZELY_FULLSTACK', - errorCategory: 'platform', + errorCategory: 'dataValidation', + errorType: 'configuration', feature: 'processor', implementation: 'cdkV2', module: 'destination', @@ -316,7 +320,8 @@ export const data = [ 'Experiment ID is not present. Aborting: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: Experiment ID is not present. Aborting', statTags: { destType: 'OPTIMIZELY_FULLSTACK', - errorCategory: 'platform', + errorCategory: 'dataValidation', + errorType: 'configuration', feature: 'processor', implementation: 'cdkV2', module: 'destination', @@ -388,7 +393,8 @@ export const data = [ "Both 'Track Categorized Pages' and 'Track Named Pages' toggles are disabled in webapp. Please enable at one of them to send page/screen events to Optimizely.: Workflow: procWorkflow, Step: validateInputForPageAndScreen, ChildStep: undefined, OriginalError: Both 'Track Categorized Pages' and 'Track Named Pages' toggles are disabled in webapp. Please enable at one of them to send page/screen events to Optimizely.", statTags: { destType: 'OPTIMIZELY_FULLSTACK', - errorCategory: 'platform', + errorCategory: 'dataValidation', + errorType: 'configuration', feature: 'processor', implementation: 'cdkV2', module: 'destination', @@ -467,7 +473,8 @@ export const data = [ "UserId is required for event tracking when the 'Track Known Users' setting is enabled. Please include a 'userId' in your event payload: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: UserId is required for event tracking when the 'Track Known Users' setting is enabled. Please include a 'userId' in your event payload", statTags: { destType: 'OPTIMIZELY_FULLSTACK', - errorCategory: 'platform', + errorCategory: 'dataValidation', + errorType: 'configuration', feature: 'processor', implementation: 'cdkV2', module: 'destination', @@ -530,7 +537,8 @@ export const data = [ 'Event is not present. Aborting.: Workflow: procWorkflow, Step: validateInputForTrack, ChildStep: undefined, OriginalError: Event is not present. Aborting.', statTags: { destType: 'OPTIMIZELY_FULLSTACK', - errorCategory: 'platform', + errorCategory: 'dataValidation', + errorType: 'instrumentation', feature: 'processor', implementation: 'cdkV2', module: 'destination', @@ -591,15 +599,16 @@ export const data = [ body: [ { error: - '{"message":"Data File Lookup Failed due to {\\"code\\":\\"document_not_found\\",\\"message\\":\\"document_not_found\\"}: Workflow: procWorkflow, Step: dataFile, ChildStep: undefined, OriginalError: Data File Lookup Failed due to {\\"code\\":\\"document_not_found\\",\\"message\\":\\"document_not_found\\"}","destinationResponse":{"code":"document_not_found","message":"document_not_found"}}', + '{"message":"{\\"message\\":\\"Data File Lookup Failed due to {\\\\\\"code\\\\\\":\\\\\\"document_not_found\\\\\\",\\\\\\"message\\\\\\":\\\\\\"document_not_found\\\\\\"}: Workflow: procWorkflow, Step: dataFile, ChildStep: undefined, OriginalError: Data File Lookup Failed due to {\\\\\\"code\\\\\\":\\\\\\"document_not_found\\\\\\",\\\\\\"message\\\\\\":\\\\\\"document_not_found\\\\\\"}\\",\\"destinationResponse\\":{\\"code\\":\\"document_not_found\\",\\"message\\":\\"document_not_found\\"}}","destinationResponse":{"code":"document_not_found","message":"document_not_found"}}', statTags: { destType: 'OPTIMIZELY_FULLSTACK', - errorCategory: 'platform', + errorCategory: 'network', + errorType: 'aborted', feature: 'processor', implementation: 'cdkV2', module: 'destination', }, - statusCode: 400, + statusCode: 404, metadata: { jobId: 10, }, @@ -670,7 +679,8 @@ export const data = [ "Event 'product_added' is not present in data file. Make sure event exists in Optimizely.: Workflow: procWorkflow, Step: prepareTrackPayload, ChildStep: optimizelyEvent, OriginalError: Event 'product_added' is not present in data file. Make sure event exists in Optimizely.", statTags: { destType: 'OPTIMIZELY_FULLSTACK', - errorCategory: 'platform', + errorCategory: 'dataValidation', + errorType: 'instrumentation', feature: 'processor', implementation: 'cdkV2', module: 'destination', @@ -1162,7 +1172,8 @@ export const data = [ metadata: { jobId: 15 }, statTags: { destType: 'OPTIMIZELY_FULLSTACK', - errorCategory: 'platform', + errorCategory: 'dataValidation', + errorType: 'instrumentation', feature: 'processor', implementation: 'cdkV2', module: 'destination', diff --git a/test/integrations/destinations/ortto/processor/data.ts b/test/integrations/destinations/ortto/processor/data.ts index 9c3d00b874..e7c71c7355 100644 --- a/test/integrations/destinations/ortto/processor/data.ts +++ b/test/integrations/destinations/ortto/processor/data.ts @@ -347,7 +347,8 @@ export const data = [ { statTags: { destType: 'ORTTO', - errorCategory: 'platform', + errorCategory: 'dataValidation', + errorType: 'instrumentation', feature: 'processor', implementation: 'cdkV2', module: 'destination', @@ -505,7 +506,8 @@ export const data = [ { statTags: { destType: 'ORTTO', - errorCategory: 'platform', + errorCategory: 'dataValidation', + errorType: 'instrumentation', feature: 'processor', implementation: 'cdkV2', module: 'destination', @@ -667,7 +669,8 @@ export const data = [ { statTags: { destType: 'ORTTO', - errorCategory: 'platform', + errorCategory: 'dataValidation', + errorType: 'configuration', feature: 'processor', implementation: 'cdkV2', module: 'destination', @@ -829,7 +832,8 @@ export const data = [ { statTags: { destType: 'ORTTO', - errorCategory: 'platform', + errorCategory: 'dataValidation', + errorType: 'configuration', feature: 'processor', implementation: 'cdkV2', module: 'destination', @@ -1216,7 +1220,8 @@ export const data = [ { statTags: { destType: 'ORTTO', - errorCategory: 'platform', + errorCategory: 'dataValidation', + errorType: 'instrumentation', feature: 'processor', implementation: 'cdkV2', module: 'destination', diff --git a/test/integrations/destinations/pinterest_tag/processor/data.ts b/test/integrations/destinations/pinterest_tag/processor/data.ts index 2887ee8cb9..17ab83b2e9 100644 --- a/test/integrations/destinations/pinterest_tag/processor/data.ts +++ b/test/integrations/destinations/pinterest_tag/processor/data.ts @@ -564,7 +564,8 @@ export const data = [ metadata: { destintionId: '1pYpzzvcn7AQ2W9GGIAZSsN6Mfq' }, statTags: { destType: 'PINTEREST_TAG', - errorCategory: 'platform', + errorCategory: 'dataValidation', + errorType: 'configuration', feature: 'processor', implementation: 'cdkV2', module: 'destination', @@ -681,7 +682,8 @@ export const data = [ 'It is required at least one of em, hashed_maids or pair of client_ip_address and client_user_agent: Workflow: procWorkflow, Step: validateUserFields, ChildStep: undefined, OriginalError: It is required at least one of em, hashed_maids or pair of client_ip_address and client_user_agent', statTags: { destType: 'PINTEREST_TAG', - errorCategory: 'platform', + errorCategory: 'dataValidation', + errorType: 'instrumentation', feature: 'processor', implementation: 'cdkV2', module: 'destination', @@ -960,7 +962,8 @@ export const data = [ metadata: { destintionId: '1pYpzzvcn7AQ2W9GGIAZSsN6Mfq' }, statTags: { destType: 'PINTEREST_TAG', - errorCategory: 'platform', + errorCategory: 'dataValidation', + errorType: 'configuration', feature: 'processor', implementation: 'cdkV2', module: 'destination', @@ -1079,7 +1082,8 @@ export const data = [ metadata: { destintionId: '1pYpzzvcn7AQ2W9GGIAZSsN6Mfq' }, statTags: { destType: 'PINTEREST_TAG', - errorCategory: 'platform', + errorCategory: 'dataValidation', + errorType: 'instrumentation', feature: 'processor', implementation: 'cdkV2', module: 'destination', @@ -1199,7 +1203,8 @@ export const data = [ 'Action source must be one of app_android, app_ios, web, offline: Workflow: procWorkflow, Step: validateCommonFields, ChildStep: undefined, OriginalError: Action source must be one of app_android, app_ios, web, offline', statTags: { destType: 'PINTEREST_TAG', - errorCategory: 'platform', + errorCategory: 'dataValidation', + errorType: 'instrumentation', feature: 'processor', implementation: 'cdkV2', module: 'destination', @@ -3236,7 +3241,8 @@ export const data = [ metadata: { destintionId: '1pYpzzvcn7AQ2W9GGIAZSsN6Mfq' }, statTags: { destType: 'PINTEREST_TAG', - errorCategory: 'platform', + errorCategory: 'dataValidation', + errorType: 'configuration', feature: 'processor', implementation: 'cdkV2', module: 'destination', @@ -3323,7 +3329,8 @@ export const data = [ metadata: { destintionId: '1pYpzzvcn7AQ2W9GGIAZSsN6Mfq' }, statTags: { destType: 'PINTEREST_TAG', - errorCategory: 'platform', + errorCategory: 'dataValidation', + errorType: 'configuration', feature: 'processor', implementation: 'cdkV2', module: 'destination', @@ -3550,7 +3557,8 @@ export const data = [ metadata: { destintionId: '1pYpzzvcn7AQ2W9GGIAZSsN6Mfq' }, statTags: { destType: 'PINTEREST_TAG', - errorCategory: 'platform', + errorCategory: 'dataValidation', + errorType: 'instrumentation', feature: 'processor', implementation: 'cdkV2', module: 'destination', diff --git a/test/integrations/destinations/userlist/processor/data.ts b/test/integrations/destinations/userlist/processor/data.ts new file mode 100644 index 0000000000..f07006b186 --- /dev/null +++ b/test/integrations/destinations/userlist/processor/data.ts @@ -0,0 +1,894 @@ +export const data = [ + { + name: 'userlist', + description: 'Test 0', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + pushKey: 'userlist-push-key', + }, + }, + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + anonymousId: '123456', + email: 'test@rudderstack.com', + address: { + city: 'kolkata', + country: 'India', + postalCode: 712136, + state: 'WB', + street: '', + }, + ip: '0.0.0.0', + age: 26, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + 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', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + user_properties: { + prop1: 'val1', + prop2: 'val2', + }, + type: 'identify', + messageId: '84e26acc-56a5-4835-8233-591137fca468', + originalTimestamp: '2019-10-14T09:03:17.562Z', + anonymousId: '123456', + userId: '123456', + integrations: { + All: true, + }, + traits: { + anonymousId: 'anon-id', + email: 'test@gmail.com', + address: { + city: 'NY', + country: 'USA', + postalCode: 712136, + state: 'CA', + street: '', + }, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + XML: {}, + JSON_ARRAY: {}, + JSON: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + anonymousId: '123456', + email: 'test@rudderstack.com', + address: { + city: 'kolkata', + country: 'India', + postalCode: 712136, + state: 'WB', + street: '', + }, + ip: '0.0.0.0', + age: 26, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + 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', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + user_properties: { + prop1: 'val1', + prop2: 'val2', + }, + type: 'identify', + messageId: '84e26acc-56a5-4835-8233-591137fca468', + originalTimestamp: '2019-10-14T09:03:17.562Z', + anonymousId: '123456', + userId: '123456', + integrations: { + All: true, + }, + traits: { + anonymousId: 'anon-id', + email: 'test@gmail.com', + address: { + city: 'NY', + country: 'USA', + postalCode: 712136, + state: 'CA', + street: '', + }, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + FORM: {}, + }, + files: {}, + endpoint: 'https://incoming.userlist.com/rudderstack/events', + headers: { + Authorization: 'Push userlist-push-key', + 'Content-Type': 'application/json', + }, + version: '1', + params: {}, + type: 'REST', + method: 'POST', + userId: '', + }, + statusCode: 200, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + }, + { + name: 'userlist', + description: 'Test 1', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + pushKey: 'userlist-push-key', + }, + }, + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.1.5', + }, + traits: { + name: 'Shehan Study', + category: 'SampleIdentify', + email: 'test@rudderstack.com', + plan: 'Open source', + logins: 5, + createdAt: 1599264000, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.1.5', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 0.8999999761581421, + }, + campaign: { + source: 'google', + medium: 'medium', + term: 'keyword', + content: 'some content', + name: 'some campaign', + test: 'other value', + }, + page: { + path: '/html/sajal.html', + referrer: '', + search: + '?utm_source=google&utm_medium=medium&utm_term=keyword&utm_content=some%20content&utm_campaign=some%20campaign&utm_test=other%20value', + title: '', + url: 'http://localhost:9116/html/sajal.html?utm_source=google&utm_medium=medium&utm_term=keyword&utm_content=some%20content&utm_campaign=some%20campaign&utm_test=other%20value', + }, + }, + type: 'group', + messageId: 'e5034df0-a404-47b4-a463-76df99934fea', + originalTimestamp: '2020-10-20T07:54:58.983Z', + anonymousId: 'my-anonymous-id-new', + userId: 'sampleusrRudder3', + integrations: { + All: true, + }, + groupId: 'Sample_groupId23', + traits: { + KEY_3: { + CHILD_KEY_92: 'value_95', + CHILD_KEY_102: 'value_103', + }, + KEY_2: { + CHILD_KEY_92: 'value_95', + CHILD_KEY_102: 'value_103', + }, + name_trait: 'Company', + value_trait: ['Comapny-ABC'], + }, + sentAt: '2020-10-20T07:54:58.983Z', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + XML: {}, + JSON_ARRAY: {}, + JSON: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.1.5', + }, + traits: { + name: 'Shehan Study', + category: 'SampleIdentify', + email: 'test@rudderstack.com', + plan: 'Open source', + logins: 5, + createdAt: 1599264000, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.1.5', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 0.8999999761581421, + }, + campaign: { + source: 'google', + medium: 'medium', + term: 'keyword', + content: 'some content', + name: 'some campaign', + test: 'other value', + }, + page: { + path: '/html/sajal.html', + referrer: '', + search: + '?utm_source=google&utm_medium=medium&utm_term=keyword&utm_content=some%20content&utm_campaign=some%20campaign&utm_test=other%20value', + title: '', + url: 'http://localhost:9116/html/sajal.html?utm_source=google&utm_medium=medium&utm_term=keyword&utm_content=some%20content&utm_campaign=some%20campaign&utm_test=other%20value', + }, + }, + type: 'group', + messageId: 'e5034df0-a404-47b4-a463-76df99934fea', + originalTimestamp: '2020-10-20T07:54:58.983Z', + anonymousId: 'my-anonymous-id-new', + userId: 'sampleusrRudder3', + integrations: { + All: true, + }, + groupId: 'Sample_groupId23', + traits: { + KEY_3: { + CHILD_KEY_92: 'value_95', + CHILD_KEY_102: 'value_103', + }, + KEY_2: { + CHILD_KEY_92: 'value_95', + CHILD_KEY_102: 'value_103', + }, + name_trait: 'Company', + value_trait: ['Comapny-ABC'], + }, + sentAt: '2020-10-20T07:54:58.983Z', + }, + FORM: {}, + }, + files: {}, + endpoint: 'https://incoming.userlist.com/rudderstack/events', + headers: { + Authorization: 'Push userlist-push-key', + 'Content-Type': 'application/json', + }, + version: '1', + params: {}, + type: 'REST', + method: 'POST', + userId: '', + }, + statusCode: 200, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + }, + { + name: 'userlist', + description: 'Test 2', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + pushKey: 'userlist-push-key', + }, + }, + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + anonymousId: '12345', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + 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', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'test track event', + properties: { + user_actual_role: 'system_admin', + user_actual_id: 12345, + user_time_spent: 50000, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + XML: {}, + JSON_ARRAY: {}, + JSON: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + anonymousId: '12345', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + 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', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2019-10-14T11:15:18.300Z', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'test track event', + properties: { + user_actual_role: 'system_admin', + user_actual_id: 12345, + user_time_spent: 50000, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + FORM: {}, + }, + files: {}, + endpoint: 'https://incoming.userlist.com/rudderstack/events', + headers: { + Authorization: 'Push userlist-push-key', + 'Content-Type': 'application/json', + }, + version: '1', + params: {}, + type: 'REST', + method: 'POST', + userId: '', + }, + statusCode: 200, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + }, + { + name: 'userlist', + description: 'Test 2', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + pushKey: 'userlist-push-key', + }, + }, + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + anonymousId: '123456', + email: 'test@rudderstack.com', + address: { + city: 'kolkata', + country: 'India', + postalCode: 712136, + state: 'WB', + street: '', + }, + ip: '0.0.0.0', + age: 26, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + 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', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + user_properties: { + prop1: 'val1', + prop2: 'val2', + }, + type: 'identify', + messageId: '84e26acc-56a5-4835-8233-591137fca468', + originalTimestamp: '2019-10-14T09:03:17.562Z', + anonymousId: '123456', + integrations: { + All: true, + }, + traits: { + anonymousId: 'anon-id', + email: 'test@gmail.com', + address: { + city: 'NY', + country: 'USA', + postalCode: 712136, + state: 'CA', + street: '', + }, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + statusCode: 400, + error: + 'userId is required: Workflow: procWorkflow, Step: preparePayload, ChildStep: undefined, OriginalError: userId is required', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'USERLIST', + module: 'destination', + implementation: 'cdkV2', + destinationId: 'destId', + workspaceId: 'wspId', + feature: 'processor', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + }, + { + name: 'userlist', + description: 'Test 2', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + pushKey: 'userlist-push-key', + }, + }, + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + anonymousId: '123456', + email: 'test@rudderstack.com', + address: { + city: 'kolkata', + country: 'India', + postalCode: 712136, + state: 'WB', + street: '', + }, + ip: '0.0.0.0', + age: 26, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + 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', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + user_properties: { + prop1: 'val1', + prop2: 'val2', + }, + type: 'identify', + messageId: '84e26acc-56a5-4835-8233-591137fca468', + originalTimestamp: '2019-10-14T09:03:17.562Z', + anonymousId: '123456', + integrations: { + All: true, + }, + traits: { + anonymousId: 'anon-id', + email: 'test@gmail.com', + address: { + city: 'NY', + country: 'USA', + postalCode: 712136, + state: 'CA', + street: '', + }, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + statusCode: 400, + error: + 'userId is required: Workflow: procWorkflow, Step: preparePayload, ChildStep: undefined, OriginalError: userId is required', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'USERLIST', + module: 'destination', + implementation: 'cdkV2', + destinationId: 'destId', + workspaceId: 'wspId', + feature: 'processor', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + }, + { + name: 'userlist', + description: 'Test 2', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + pushKey: 'userlist-push-key', + }, + }, + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + anonymousId: '123456', + email: 'test@rudderstack.com', + address: { + city: 'kolkata', + country: 'India', + postalCode: 712136, + state: 'WB', + street: '', + }, + ip: '0.0.0.0', + age: 26, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + 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', + locale: 'en-US', + ip: '0.0.0.0', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + user_properties: { + prop1: 'val1', + prop2: 'val2', + }, + type: 'page', + messageId: '84e26acc-56a5-4835-8233-591137fca468', + originalTimestamp: '2019-10-14T09:03:17.562Z', + anonymousId: '123456', + integrations: { + All: true, + }, + traits: { + anonymousId: 'anon-id', + email: 'test@gmail.com', + address: { + city: 'NY', + country: 'USA', + postalCode: 712136, + state: 'CA', + street: '', + }, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + statusCode: 400, + error: + 'message type page is not supported: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: message type page is not supported', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'USERLIST', + module: 'destination', + implementation: 'cdkV2', + destinationId: 'destId', + workspaceId: 'wspId', + feature: 'processor', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/vitally/processor/data.ts b/test/integrations/destinations/vitally/processor/data.ts new file mode 100644 index 0000000000..2c3fdd3297 --- /dev/null +++ b/test/integrations/destinations/vitally/processor/data.ts @@ -0,0 +1,300 @@ +export const data = [ + { + name: 'vitally', + description: 'Test 0', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKeyVitally: 'abc123', + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + message: { + userId: '0220c056-934e-11ed-a1eb-0242ac120002', + event: 'this is a track event', + type: 'track', + properties: { + thing: 'amazing!', + }, + originalTimestamp: '2023-01-13T09:03:17.562Z', + sentAt: '2023-01-13T09:03:17.562Z', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + FORM: {}, + JSON_ARRAY: {}, + XML: {}, + JSON: { + userId: '0220c056-934e-11ed-a1eb-0242ac120002', + event: 'this is a track event', + type: 'track', + properties: { + thing: 'amazing!', + }, + originalTimestamp: '2023-01-13T09:03:17.562Z', + sentAt: '2023-01-13T09:03:17.562Z', + }, + }, + endpoint: 'https://api.vitally.io/rudderstack', + files: {}, + params: {}, + type: 'REST', + version: '1', + method: 'POST', + userId: '', + headers: { + authorization: 'Basic abc123', + 'content-type': 'application/json', + }, + }, + statusCode: 200, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + }, + { + name: 'vitally', + description: 'Test 1', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKeyVitally: 'abc123', + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + message: { + userId: '0220c056-934e-11ed-a1eb-0242ac120002', + type: 'identify', + traits: { + name: 'Johnny Appleseed', + }, + originalTimestamp: '2023-01-13T09:03:17.562Z', + sentAt: '2023-01-13T09:03:17.562Z', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + FORM: {}, + JSON_ARRAY: {}, + XML: {}, + JSON: { + userId: '0220c056-934e-11ed-a1eb-0242ac120002', + type: 'identify', + traits: { + name: 'Johnny Appleseed', + }, + originalTimestamp: '2023-01-13T09:03:17.562Z', + sentAt: '2023-01-13T09:03:17.562Z', + }, + }, + endpoint: 'https://api.vitally.io/rudderstack', + files: {}, + params: {}, + type: 'REST', + version: '1', + method: 'POST', + userId: '', + headers: { + authorization: 'Basic abc123', + 'content-type': 'application/json', + }, + }, + statusCode: 200, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + }, + { + name: 'vitally', + description: 'Test 1', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKeyVitally: 'abc123', + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + message: { + userId: '0220c056-934e-11ed-a1eb-0242ac120002', + type: 'group', + groupId: '5de17322-934e-11ed-a1eb-0242ac120002', + originalTimestamp: '2023-01-13T09:03:17.562Z', + sentAt: '2023-01-13T09:03:17.562Z', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + FORM: {}, + JSON_ARRAY: {}, + XML: {}, + JSON: { + userId: '0220c056-934e-11ed-a1eb-0242ac120002', + type: 'group', + groupId: '5de17322-934e-11ed-a1eb-0242ac120002', + originalTimestamp: '2023-01-13T09:03:17.562Z', + sentAt: '2023-01-13T09:03:17.562Z', + }, + }, + endpoint: 'https://api.vitally.io/rudderstack', + files: {}, + params: {}, + type: 'REST', + version: '1', + method: 'POST', + userId: '', + headers: { + authorization: 'Basic abc123', + 'content-type': 'application/json', + }, + }, + statusCode: 200, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + }, + + { + name: 'vitally', + description: 'Test 1', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKeyVitally: 'abc123', + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + message: { + userId: '0220c056-934e-11ed-a1eb-0242ac120002', + type: 'page', + groupId: '5de17322-934e-11ed-a1eb-0242ac120002', + originalTimestamp: '2023-01-13T09:03:17.562Z', + sentAt: '2023-01-13T09:03:17.562Z', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + statusCode: 400, + error: + 'message type page is not supported: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: message type page is not supported', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'VITALLY', + module: 'destination', + implementation: 'cdkV2', + destinationId: 'destId', + workspaceId: 'wspId', + feature: 'processor', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/zapier/data.ts b/test/integrations/destinations/zapier/data.ts index 6dbabd26d8..122ffd2d1d 100644 --- a/test/integrations/destinations/zapier/data.ts +++ b/test/integrations/destinations/zapier/data.ts @@ -41,10 +41,14 @@ export const data = [ originalTimestamp: '2020-04-17T14:42:44.724Z', sentAt: '2020-04-17T14:42:44.724Z', }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, destination: { DestinationDefinition: { Config: { - cdkEnabled: true, + cdkV2Enabled: true, }, }, Config: { @@ -116,6 +120,10 @@ export const data = [ userId: '', }, statusCode: 200, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, @@ -163,10 +171,14 @@ export const data = [ originalTimestamp: '2020-04-17T14:42:44.724Z', sentAt: '2020-04-17T14:42:44.724Z', }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, destination: { DestinationDefinition: { Config: { - cdkEnabled: true, + cdkV2Enabled: true, }, }, Config: { @@ -247,6 +259,10 @@ export const data = [ userId: '', }, statusCode: 200, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, @@ -294,10 +310,14 @@ export const data = [ originalTimestamp: '2020-04-17T14:42:44.724Z', sentAt: '2020-04-17T14:42:44.724Z', }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, destination: { DestinationDefinition: { Config: { - cdkEnabled: true, + cdkV2Enabled: true, }, }, Config: { @@ -387,6 +407,10 @@ export const data = [ userId: '', }, statusCode: 200, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, @@ -434,10 +458,14 @@ export const data = [ originalTimestamp: '2020-04-17T14:42:44.724Z', sentAt: '2020-04-17T14:42:44.724Z', }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, destination: { DestinationDefinition: { Config: { - cdkEnabled: true, + cdkV2Enabled: true, }, }, Config: { @@ -527,6 +555,10 @@ export const data = [ userId: '', }, statusCode: 200, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, @@ -574,10 +606,14 @@ export const data = [ originalTimestamp: '2020-04-17T14:42:44.724Z', sentAt: '2020-04-17T14:42:44.724Z', }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, destination: { DestinationDefinition: { Config: { - cdkEnabled: true, + cdkV2Enabled: true, }, }, Config: { @@ -658,6 +694,10 @@ export const data = [ userId: '', }, statusCode: 200, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, }, ], }, From e82cef88e154d47519f0deeb60f55773f25fd3ad Mon Sep 17 00:00:00 2001 From: Sandeep Digumarty Date: Mon, 13 Nov 2023 12:08:47 +0530 Subject: [PATCH 31/93] feat: add delivery_category as part of contents, remove flattening custom_data in FB conversions (#2812) * feat: add delivery_category as part of contents, remove flattening custom_data in FB conversions * feat: update API version to v18.0 * feat: updated tests --- .../facebook_conversions/config.js | 2 +- .../facebook_conversions/transform.js | 8 +- .../facebook_conversions/utils.js | 8 +- test/__tests__/data/facebook_conversions.json | 260 ++++++++++++++++-- .../facebook_conversions_router_input.json | 4 +- .../facebook_conversions_router_output.json | 8 +- ...rsions.js => facebook_conversions.test.js} | 0 7 files changed, 254 insertions(+), 36 deletions(-) rename test/__tests__/{facebook_conversions.js => facebook_conversions.test.js} (100%) diff --git a/src/v0/destinations/facebook_conversions/config.js b/src/v0/destinations/facebook_conversions/config.js index fc04f13be6..0c1fc12e15 100644 --- a/src/v0/destinations/facebook_conversions/config.js +++ b/src/v0/destinations/facebook_conversions/config.js @@ -1,7 +1,7 @@ const { getMappingConfig } = require('../../util'); const ENDPOINT = (datasetId, accessToken) => - `https://graph.facebook.com/v17.0/${datasetId}/events?access_token=${accessToken}`; + `https://graph.facebook.com/v18.0/${datasetId}/events?access_token=${accessToken}`; const CONFIG_CATEGORIES = { USERDATA: { diff --git a/src/v0/destinations/facebook_conversions/transform.js b/src/v0/destinations/facebook_conversions/transform.js index cf11795605..1bb97b2672 100644 --- a/src/v0/destinations/facebook_conversions/transform.js +++ b/src/v0/destinations/facebook_conversions/transform.js @@ -14,7 +14,6 @@ const { EventType } = require('../../../constants'); const { constructPayload, extractCustomFields, - flattenJson, getIntegrationsObj, getValidDynamicFormConfig, simpleProcessRouterDest, @@ -73,8 +72,11 @@ const responseBuilderSimple = (message, category, destination) => { commonData.action_source = getActionSource(commonData, actionSource); let customData = {}; - customData = flattenJson( - extractCustomFields(message, customData, ['properties'], FB_CONVERSIONS_DEFAULT_EXCLUSION), + customData = extractCustomFields( + message, + customData, + ['properties'], + FB_CONVERSIONS_DEFAULT_EXCLUSION, ); customData = transformedPayloadData( diff --git a/src/v0/destinations/facebook_conversions/utils.js b/src/v0/destinations/facebook_conversions/utils.js index 32fafae3d0..26204ec61a 100644 --- a/src/v0/destinations/facebook_conversions/utils.js +++ b/src/v0/destinations/facebook_conversions/utils.js @@ -44,7 +44,11 @@ const getCategoryFromEvent = (eventName) => { return category; }; -const populateContentsAndContentIDs = (productPropertiesArray, fallbackQuantity) => { +const populateContentsAndContentIDs = ( + productPropertiesArray, + fallbackQuantity, + fallbackDeliveryCategory, +) => { const contentIds = []; const contents = []; if (Array.isArray(productPropertiesArray)) { @@ -57,6 +61,7 @@ const populateContentsAndContentIDs = (productPropertiesArray, fallbackQuantity) id: productId, quantity: productProps.quantity || fallbackQuantity || 1, item_price: productProps.price, + delivery_category: productProps.delivery_category || fallbackDeliveryCategory, }); } } @@ -142,6 +147,7 @@ const populateCustomDataBasedOnCategory = (customData, message, category, catego const { contentIds, contents } = populateContentsAndContentIDs( message.properties?.products, message.properties?.quantity, + message.properties?.delivery_category, ); const contentCategory = eventTypeCustomData.content_category; diff --git a/test/__tests__/data/facebook_conversions.json b/test/__tests__/data/facebook_conversions.json index 62d0a49c0f..cc4d9a1421 100644 --- a/test/__tests__/data/facebook_conversions.json +++ b/test/__tests__/data/facebook_conversions.json @@ -120,7 +120,7 @@ "revenue": 400, "additional_bet_index": 0 }, - "timestamp": "2023-10-15T15:46:51.693229+05:30", + "timestamp": "2023-11-12T15:46:51.693229+05:30", "type": "track" }, "destination": { @@ -201,7 +201,7 @@ "revenue": 400, "additional_bet_index": 0 }, - "timestamp": "2023-10-15T15:46:51.693229+05:30", + "timestamp": "2023-11-12T15:46:51.693229+05:30", "type": "track" }, "destination": { @@ -241,7 +241,7 @@ "version": "1", "type": "REST", "method": "POST", - "endpoint": "https://graph.facebook.com/v17.0/dummyID/events?access_token=09876", + "endpoint": "https://graph.facebook.com/v18.0/dummyID/events?access_token=09876", "headers": {}, "params": {}, "body": { @@ -250,7 +250,7 @@ "JSON_ARRAY": {}, "FORM": { "data": [ - "{\"user_data\":{\"em\":\"48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08\",\"zp\":\"03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4\"},\"event_name\":\"spin_result\",\"event_time\":1697365011,\"action_source\":\"website\",\"custom_data\":{\"revenue\":400,\"additional_bet_index\":0,\"value\":400,\"currency\":\"USD\"}}" + "{\"user_data\":{\"em\":\"48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08\",\"zp\":\"03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4\"},\"event_name\":\"spin_result\",\"event_time\":1699784211,\"action_source\":\"website\",\"custom_data\":{\"revenue\":400,\"additional_bet_index\":0,\"value\":400,\"currency\":\"USD\"}}" ] } }, @@ -298,7 +298,7 @@ "revenue": 400, "additional_bet_index": 0 }, - "timestamp": "2023-10-15T15:46:51.693229+05:30", + "timestamp": "2023-11-12T15:46:51.693229+05:30", "type": "track" }, "destination": { @@ -338,7 +338,7 @@ "version": "1", "type": "REST", "method": "POST", - "endpoint": "https://graph.facebook.com/v17.0/dummyID/events?access_token=09876", + "endpoint": "https://graph.facebook.com/v18.0/dummyID/events?access_token=09876", "headers": {}, "params": {}, "body": { @@ -347,7 +347,7 @@ "JSON_ARRAY": {}, "FORM": { "data": [ - "{\"user_data\":{\"em\":\"48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08\",\"zp\":\"03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4\"},\"event_name\":\"Search\",\"event_time\":1697365011,\"action_source\":\"website\",\"custom_data\":{\"revenue\":400,\"additional_bet_index\":0,\"content_ids\":[],\"contents\":[],\"content_type\":\"product\",\"currency\":\"USD\",\"value\":400}}" + "{\"user_data\":{\"em\":\"48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08\",\"zp\":\"03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4\"},\"event_name\":\"Search\",\"event_time\":1699784211,\"action_source\":\"website\",\"custom_data\":{\"revenue\":400,\"additional_bet_index\":0,\"content_ids\":[],\"contents\":[],\"content_type\":\"product\",\"currency\":\"USD\",\"value\":400}}" ] } }, @@ -395,7 +395,7 @@ "revenue": 400, "additional_bet_index": 0 }, - "timestamp": "2023-10-15T15:46:51.693229+05:30", + "timestamp": "2023-11-12T15:46:51.693229+05:30", "type": "track" }, "destination": { @@ -435,7 +435,7 @@ "version": "1", "type": "REST", "method": "POST", - "endpoint": "https://graph.facebook.com/v17.0/dummyID/events?access_token=09876", + "endpoint": "https://graph.facebook.com/v18.0/dummyID/events?access_token=09876", "headers": {}, "params": {}, "body": { @@ -444,7 +444,7 @@ "JSON_ARRAY": {}, "FORM": { "data": [ - "{\"user_data\":{\"em\":\"48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08\",\"zp\":\"03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4\"},\"event_name\":\"AddToCart\",\"event_time\":1697365011,\"action_source\":\"website\",\"custom_data\":{\"revenue\":400,\"additional_bet_index\":0,\"content_ids\":[],\"contents\":[],\"content_type\":\"product\",\"currency\":\"USD\",\"value\":400}}" + "{\"user_data\":{\"em\":\"48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08\",\"zp\":\"03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4\"},\"event_name\":\"AddToCart\",\"event_time\":1699784211,\"action_source\":\"website\",\"custom_data\":{\"revenue\":400,\"additional_bet_index\":0,\"content_ids\":[],\"contents\":[],\"content_type\":\"product\",\"currency\":\"USD\",\"value\":400}}" ] } }, @@ -492,7 +492,7 @@ "revenue": 400, "additional_bet_index": 0 }, - "timestamp": "2023-10-15T15:46:51.693229+05:30", + "timestamp": "2023-11-12T15:46:51.693229+05:30", "type": "track" }, "destination": { @@ -532,7 +532,7 @@ "version": "1", "type": "REST", "method": "POST", - "endpoint": "https://graph.facebook.com/v17.0/dummyID/events?access_token=09876", + "endpoint": "https://graph.facebook.com/v18.0/dummyID/events?access_token=09876", "headers": {}, "params": {}, "body": { @@ -541,7 +541,7 @@ "JSON_ARRAY": {}, "FORM": { "data": [ - "{\"user_data\":{\"em\":\"48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08\",\"zp\":\"03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4\"},\"event_name\":\"ViewContent\",\"event_time\":1697365011,\"action_source\":\"website\",\"custom_data\":{\"revenue\":400,\"additional_bet_index\":0,\"content_ids\":[],\"contents\":[],\"content_type\":\"product\",\"currency\":\"USD\",\"value\":400}}" + "{\"user_data\":{\"em\":\"48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08\",\"zp\":\"03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4\"},\"event_name\":\"ViewContent\",\"event_time\":1699784211,\"action_source\":\"website\",\"custom_data\":{\"revenue\":400,\"additional_bet_index\":0,\"content_ids\":[],\"contents\":[],\"content_type\":\"product\",\"currency\":\"USD\",\"value\":400}}" ] } }, @@ -596,7 +596,7 @@ } ] }, - "timestamp": "2023-10-15T15:46:51.693229+05:30", + "timestamp": "2023-11-12T15:46:51.693229+05:30", "type": "track" }, "destination": { @@ -636,7 +636,7 @@ "version": "1", "type": "REST", "method": "POST", - "endpoint": "https://graph.facebook.com/v17.0/dummyID/events?access_token=09876", + "endpoint": "https://graph.facebook.com/v18.0/dummyID/events?access_token=09876", "headers": {}, "params": {}, "body": { @@ -645,7 +645,7 @@ "JSON_ARRAY": {}, "FORM": { "data": [ - "{\"user_data\":{\"em\":\"48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08\",\"zp\":\"03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4\"},\"event_name\":\"ViewContent\",\"event_time\":1697365011,\"action_source\":\"website\",\"custom_data\":{\"revenue\":400,\"additional_bet_index\":0,\"products[0].product_id\":1234,\"products[0].quantity\":5,\"products[0].price\":55,\"content_ids\":[1234],\"contents\":[{\"id\":1234,\"quantity\":5,\"item_price\":55}],\"content_type\":\"product\",\"currency\":\"USD\",\"value\":400}}" + "{\"user_data\":{\"em\":\"48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08\",\"zp\":\"03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4\"},\"event_name\":\"ViewContent\",\"event_time\":1699784211,\"action_source\":\"website\",\"custom_data\":{\"revenue\":400,\"additional_bet_index\":0,\"products\":[{\"product_id\":1234,\"quantity\":5,\"price\":55}],\"content_ids\":[1234],\"contents\":[{\"id\":1234,\"quantity\":5,\"item_price\":55}],\"content_type\":\"product\",\"currency\":\"USD\",\"value\":400}}" ] } }, @@ -694,7 +694,7 @@ "additional_bet_index": 0, "category": "randomCategory" }, - "timestamp": "2023-10-15T15:46:51.693229+05:30", + "timestamp": "2023-11-12T15:46:51.693229+05:30", "type": "track" }, "destination": { @@ -734,7 +734,7 @@ "version": "1", "type": "REST", "method": "POST", - "endpoint": "https://graph.facebook.com/v17.0/dummyID/events?access_token=09876", + "endpoint": "https://graph.facebook.com/v18.0/dummyID/events?access_token=09876", "headers": {}, "params": {}, "body": { @@ -743,7 +743,7 @@ "JSON_ARRAY": {}, "FORM": { "data": [ - "{\"user_data\":{\"em\":\"48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08\",\"zp\":\"03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4\"},\"event_name\":\"ViewContent\",\"event_time\":1697365011,\"action_source\":\"website\",\"custom_data\":{\"revenue\":400,\"additional_bet_index\":0,\"category\":\"randomCategory\",\"content_ids\":[\"randomCategory\"],\"contents\":[{\"id\":\"randomCategory\",\"quantity\":1}],\"content_type\":\"product_group\",\"content_category\":\"randomCategory\",\"currency\":\"USD\",\"value\":400}}" + "{\"user_data\":{\"em\":\"48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08\",\"zp\":\"03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4\"},\"event_name\":\"ViewContent\",\"event_time\":1699784211,\"action_source\":\"website\",\"custom_data\":{\"revenue\":400,\"additional_bet_index\":0,\"category\":\"randomCategory\",\"content_ids\":[\"randomCategory\"],\"contents\":[{\"id\":\"randomCategory\",\"quantity\":1}],\"content_type\":\"product_group\",\"content_category\":\"randomCategory\",\"currency\":\"USD\",\"value\":400}}" ] } }, @@ -791,7 +791,7 @@ "revenue": 400, "additional_bet_index": 0 }, - "timestamp": "2023-10-15T15:46:51.693229+05:30", + "timestamp": "2023-11-12T15:46:51.693229+05:30", "type": "track" }, "destination": { @@ -831,7 +831,7 @@ "version": "1", "type": "REST", "method": "POST", - "endpoint": "https://graph.facebook.com/v17.0/dummyID/events?access_token=09876", + "endpoint": "https://graph.facebook.com/v18.0/dummyID/events?access_token=09876", "headers": {}, "params": {}, "body": { @@ -840,7 +840,7 @@ "JSON_ARRAY": {}, "FORM": { "data": [ - "{\"user_data\":{\"em\":\"48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08\",\"zp\":\"03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4\"},\"event_name\":\"AddToWishlist\",\"event_time\":1697365011,\"action_source\":\"website\",\"custom_data\":{\"revenue\":400,\"additional_bet_index\":0,\"content_ids\":[],\"contents\":[],\"currency\":\"USD\",\"value\":400}}" + "{\"user_data\":{\"em\":\"48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08\",\"zp\":\"03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4\"},\"event_name\":\"AddToWishlist\",\"event_time\":1699784211,\"action_source\":\"website\",\"custom_data\":{\"revenue\":400,\"additional_bet_index\":0,\"content_ids\":[],\"contents\":[],\"currency\":\"USD\",\"value\":400}}" ] } }, @@ -888,7 +888,7 @@ "revenue": 400, "additional_bet_index": 0 }, - "timestamp": "2023-10-15T15:46:51.693229+05:30", + "timestamp": "2023-11-12T15:46:51.693229+05:30", "type": "track" }, "destination": { @@ -928,7 +928,7 @@ "version": "1", "type": "REST", "method": "POST", - "endpoint": "https://graph.facebook.com/v17.0/dummyID/events?access_token=09876", + "endpoint": "https://graph.facebook.com/v18.0/dummyID/events?access_token=09876", "headers": {}, "params": {}, "body": { @@ -937,7 +937,217 @@ "JSON_ARRAY": {}, "FORM": { "data": [ - "{\"user_data\":{\"em\":\"48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08\",\"zp\":\"03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4\"},\"event_name\":\"AddPaymentInfo\",\"event_time\":1697365011,\"action_source\":\"website\",\"custom_data\":{\"revenue\":400,\"additional_bet_index\":0,\"content_ids\":[],\"contents\":[],\"currency\":\"USD\",\"value\":400}}" + "{\"user_data\":{\"em\":\"48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08\",\"zp\":\"03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4\"},\"event_name\":\"AddPaymentInfo\",\"event_time\":1699784211,\"action_source\":\"website\",\"custom_data\":{\"revenue\":400,\"additional_bet_index\":0,\"content_ids\":[],\"contents\":[],\"currency\":\"USD\",\"value\":400}}" + ] + } + }, + "files": {} + } + }, + { + "description": "Track event with standard event order completed with delivery_category in products array", + "input": { + "message": { + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "channel": "web", + "context": { + "device": { + "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", + "manufacturer": "Xiaomi", + "model": "Redmi 6", + "name": "xiaomi" + }, + "network": { + "carrier": "Banglalink" + }, + "os": { + "name": "android", + "version": "8.1.0" + }, + "screen": { + "height": "100", + "density": 50 + }, + "traits": { + "email": " aBc@gmail.com ", + "address": { + "zip": 1234 + }, + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" + } + }, + "event": "order completed", + "integrations": { + "All": true + }, + "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", + "properties": { + "revenue": 400, + "additional_bet_index": 0, + "products": [ + { + "product_id": 1234, + "quantity": 5, + "price": 55, + "delivery_category": "home_delivery" + } + ] + }, + "timestamp": "2023-11-12T15:46:51.693229+05:30", + "type": "track" + }, + "destination": { + "Config": { + "limitedDataUsage": true, + "blacklistPiiProperties": [ + { + "blacklistPiiProperties": "", + "blacklistPiiHash": false + } + ], + "accessToken": "09876", + "datasetId": "dummyID", + "eventsToEvents": [ + { + "from": "", + "to": "" + } + ], + "eventCustomProperties": [ + { + "eventCustomProperties": "" + } + ], + "removeExternalId": true, + "whitelistPiiProperties": [ + { + "whitelistPiiProperties": "" + } + ], + "actionSource": "website" + }, + "Enabled": true + } + }, + "output": { + "version": "1", + "type": "REST", + "method": "POST", + "endpoint": "https://graph.facebook.com/v18.0/dummyID/events?access_token=09876", + "headers": {}, + "params": {}, + "body": { + "JSON": {}, + "XML": {}, + "JSON_ARRAY": {}, + "FORM": { + "data": [ + "{\"user_data\":{\"em\":\"48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08\",\"zp\":\"03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4\"},\"event_name\":\"Purchase\",\"event_time\":1699784211,\"action_source\":\"website\",\"custom_data\":{\"revenue\":400,\"additional_bet_index\":0,\"products\":[{\"product_id\":1234,\"quantity\":5,\"price\":55,\"delivery_category\":\"home_delivery\"}],\"content_ids\":[1234],\"contents\":[{\"id\":1234,\"quantity\":5,\"item_price\":55,\"delivery_category\":\"home_delivery\"}],\"content_type\":\"product\",\"currency\":\"USD\",\"value\":400,\"num_items\":1}}" + ] + } + }, + "files": {} + } + }, + { + "description": "Track event with standard event order completed with delivery_category in properties", + "input": { + "message": { + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "channel": "web", + "context": { + "device": { + "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", + "manufacturer": "Xiaomi", + "model": "Redmi 6", + "name": "xiaomi" + }, + "network": { + "carrier": "Banglalink" + }, + "os": { + "name": "android", + "version": "8.1.0" + }, + "screen": { + "height": "100", + "density": 50 + }, + "traits": { + "email": " aBc@gmail.com ", + "address": { + "zip": 1234 + }, + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" + } + }, + "event": "order completed", + "integrations": { + "All": true + }, + "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", + "properties": { + "revenue": 400, + "additional_bet_index": 0, + "delivery_category": "home_delivery", + "products": [ + { + "product_id": 1234, + "quantity": 5, + "price": 55 + } + ] + }, + "timestamp": "2023-11-12T15:46:51.693229+05:30", + "type": "track" + }, + "destination": { + "Config": { + "limitedDataUsage": true, + "blacklistPiiProperties": [ + { + "blacklistPiiProperties": "", + "blacklistPiiHash": false + } + ], + "accessToken": "09876", + "datasetId": "dummyID", + "eventsToEvents": [ + { + "from": "", + "to": "" + } + ], + "eventCustomProperties": [ + { + "eventCustomProperties": "" + } + ], + "removeExternalId": true, + "whitelistPiiProperties": [ + { + "whitelistPiiProperties": "" + } + ], + "actionSource": "website" + }, + "Enabled": true + } + }, + "output": { + "version": "1", + "type": "REST", + "method": "POST", + "endpoint": "https://graph.facebook.com/v18.0/dummyID/events?access_token=09876", + "headers": {}, + "params": {}, + "body": { + "JSON": {}, + "XML": {}, + "JSON_ARRAY": {}, + "FORM": { + "data": [ + "{\"user_data\":{\"em\":\"48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08\",\"zp\":\"03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4\"},\"event_name\":\"Purchase\",\"event_time\":1699784211,\"action_source\":\"website\",\"custom_data\":{\"revenue\":400,\"additional_bet_index\":0,\"delivery_category\":\"home_delivery\",\"products\":[{\"product_id\":1234,\"quantity\":5,\"price\":55}],\"content_ids\":[1234],\"contents\":[{\"id\":1234,\"quantity\":5,\"item_price\":55,\"delivery_category\":\"home_delivery\"}],\"content_type\":\"product\",\"currency\":\"USD\",\"value\":400,\"num_items\":1}}" ] } }, diff --git a/test/__tests__/data/facebook_conversions_router_input.json b/test/__tests__/data/facebook_conversions_router_input.json index 4abe66d3c4..b8865d124e 100644 --- a/test/__tests__/data/facebook_conversions_router_input.json +++ b/test/__tests__/data/facebook_conversions_router_input.json @@ -41,7 +41,7 @@ "revenue": 400, "additional_bet_index": 0 }, - "timestamp": "2023-10-15T15:46:51.693229+05:30", + "timestamp": "2023-11-12T15:46:51.693229+05:30", "type": "track" }, "destination": { @@ -119,7 +119,7 @@ "revenue": 400, "additional_bet_index": 0 }, - "timestamp": "2023-10-15T15:46:51.693229+05:30", + "timestamp": "2023-11-12T15:46:51.693229+05:30", "type": "track" }, "destination": { diff --git a/test/__tests__/data/facebook_conversions_router_output.json b/test/__tests__/data/facebook_conversions_router_output.json index d376a91027..542c173090 100644 --- a/test/__tests__/data/facebook_conversions_router_output.json +++ b/test/__tests__/data/facebook_conversions_router_output.json @@ -4,7 +4,7 @@ "version": "1", "type": "REST", "method": "POST", - "endpoint": "https://graph.facebook.com/v17.0/dummyID/events?access_token=09876", + "endpoint": "https://graph.facebook.com/v18.0/dummyID/events?access_token=09876", "headers": {}, "params": {}, "body": { @@ -13,7 +13,7 @@ "JSON_ARRAY": {}, "FORM": { "data": [ - "{\"user_data\":{\"em\":\"48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08\",\"zp\":\"03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4\"},\"event_name\":\"spin_result\",\"event_time\":1697365011,\"action_source\":\"website\",\"custom_data\":{\"revenue\":400,\"additional_bet_index\":0,\"value\":400,\"currency\":\"USD\"}}" + "{\"user_data\":{\"em\":\"48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08\",\"zp\":\"03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4\"},\"event_name\":\"spin_result\",\"event_time\":1699784211,\"action_source\":\"website\",\"custom_data\":{\"revenue\":400,\"additional_bet_index\":0,\"value\":400,\"currency\":\"USD\"}}" ] } }, @@ -64,7 +64,7 @@ "version": "1", "type": "REST", "method": "POST", - "endpoint": "https://graph.facebook.com/v17.0/dummyID/events?access_token=09876", + "endpoint": "https://graph.facebook.com/v18.0/dummyID/events?access_token=09876", "headers": {}, "params": {}, "body": { @@ -73,7 +73,7 @@ "JSON_ARRAY": {}, "FORM": { "data": [ - "{\"user_data\":{\"em\":\"48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08\",\"zp\":\"03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4\"},\"event_name\":\"Search\",\"event_time\":1697365011,\"action_source\":\"website\",\"custom_data\":{\"revenue\":400,\"additional_bet_index\":0,\"content_ids\":[],\"contents\":[],\"content_type\":\"product\",\"currency\":\"USD\",\"value\":400}}" + "{\"user_data\":{\"em\":\"48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08\",\"zp\":\"03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4\"},\"event_name\":\"Search\",\"event_time\":1699784211,\"action_source\":\"website\",\"custom_data\":{\"revenue\":400,\"additional_bet_index\":0,\"content_ids\":[],\"contents\":[],\"content_type\":\"product\",\"currency\":\"USD\",\"value\":400}}" ] } }, diff --git a/test/__tests__/facebook_conversions.js b/test/__tests__/facebook_conversions.test.js similarity index 100% rename from test/__tests__/facebook_conversions.js rename to test/__tests__/facebook_conversions.test.js From 916ea4c8d08f69b68b7795dd513a25a3cded55fa Mon Sep 17 00:00:00 2001 From: shrouti1507 <60211312+shrouti1507@users.noreply.github.com> Date: Mon, 13 Nov 2023 12:54:49 +0530 Subject: [PATCH 32/93] feat: adding support for future oauth facility in salesforce (#2746) * feat: oauth in salesforce * fix: backward compatibility initial * fix: editing error class and proxy test case * fix: access token call for legacy auth * Update src/v0/destinations/salesforce/utils.js Co-authored-by: Sudip Paul <67197965+ItsSudip@users.noreply.github.com> * feat: added missing authorization logic for axios calls * fix: adding new dest salesforce oauth * fix: review comment addressed * feat: review comments addressed * feat: small edit * fix: review comments addressed * Update src/v0/destinations/salesforce/transform.js Co-authored-by: Sankeerth * fix: review comments addressed * fix: review comments addressed --------- Co-authored-by: Sudip Paul <67197965+ItsSudip@users.noreply.github.com> Co-authored-by: Sankeerth --- src/constants/destinationCanonicalNames.js | 1 + src/features.json | 1 + src/v0/destinations/salesforce/config.js | 4 + src/v0/destinations/salesforce/transform.js | 74 +++++++--- src/v0/destinations/salesforce/utils.js | 54 +++++++- .../salesforce/dataDelivery/data.ts | 3 +- .../destinations/salesforce/processor/data.ts | 128 ++++++++++++++++++ 7 files changed, 236 insertions(+), 29 deletions(-) diff --git a/src/constants/destinationCanonicalNames.js b/src/constants/destinationCanonicalNames.js index 870c534db0..d1e199c9e2 100644 --- a/src/constants/destinationCanonicalNames.js +++ b/src/constants/destinationCanonicalNames.js @@ -1,5 +1,6 @@ const DestHandlerMap = { ga360: 'ga', + salesforce_oauth: 'salesforce', }; const DestCanonicalNames = { diff --git a/src/features.json b/src/features.json index d3ea3e98a6..27da6cfaf2 100644 --- a/src/features.json +++ b/src/features.json @@ -25,6 +25,7 @@ "PINTEREST_TAG": true, "PROFITWELL": true, "SALESFORCE": true, + "SALESFORCE_OAUTH": true, "SFMC": true, "SNAPCHAT_CONVERSION": true, "TIKTOK_ADS": true, diff --git a/src/v0/destinations/salesforce/config.js b/src/v0/destinations/salesforce/config.js index 6c0ccde80f..1425bad51b 100644 --- a/src/v0/destinations/salesforce/config.js +++ b/src/v0/destinations/salesforce/config.js @@ -24,6 +24,8 @@ const SF_TOKEN_REQUEST_URL = 'https://login.salesforce.com/services/oauth2/token const SF_TOKEN_REQUEST_URL_SANDBOX = 'https://test.salesforce.com/services/oauth2/token'; const DESTINATION = 'Salesforce'; +const OAUTH = 'oauth'; +const LEGACY = 'legacy'; const mappingConfig = getMappingConfig(ConfigCategory, __dirname); @@ -37,4 +39,6 @@ module.exports = { ignoredContactTraits: mappingConfig[ConfigCategory.IGNORE_CONTACT.name], ACCESS_TOKEN_CACHE_TTL, DESTINATION, + OAUTH, + LEGACY, }; diff --git a/src/v0/destinations/salesforce/transform.js b/src/v0/destinations/salesforce/transform.js index ab06a16d07..5ada9dfaa0 100644 --- a/src/v0/destinations/salesforce/transform.js +++ b/src/v0/destinations/salesforce/transform.js @@ -26,8 +26,9 @@ const { checkInvalidRtTfEvents, handleRtTfSingleEventError, generateErrorObject, + isHttpStatusSuccess, } = require('../../util'); -const { getAccessToken, salesforceResponseHandler } = require('./utils'); +const { salesforceResponseHandler, collectAuthorizationInfo, getAuthHeader } = require('./utils'); const { handleHttpRequest } = require('../../../adapters/network'); const { JSON_MIME_TYPE } = require('../../util/constant'); @@ -41,6 +42,7 @@ function responseBuilderSimple( authorizationData, mapProperty, mappedToDestination, + authorizationFlow, ) { const { salesforceType, salesforceId } = salesforceMap; @@ -87,12 +89,12 @@ function responseBuilderSimple( } const response = defaultRequestConfig(); - const header = { + + response.method = defaultPostRequestConfig.requestMethod; + response.headers = { 'Content-Type': JSON_MIME_TYPE, - Authorization: authorizationData.token, + ...getAuthHeader({ authorizationFlow, authorizationData }), }; - response.method = defaultPostRequestConfig.requestMethod; - response.headers = header; response.body.JSON = removeUndefinedValues(rawPayload); response.endpoint = targetEndpoint; @@ -106,24 +108,26 @@ async function getSaleforceIdForRecord( identifierType, identifierValue, destination, + authorizationFlow, ) { const objSearchUrl = `${authorizationData.instanceUrl}/services/data/v${SF_API_VERSION}/parameterizedSearch/?q=${identifierValue}&sobject=${objectType}&in=${identifierType}&${objectType}.fields=id,${identifierType}`; const { processedResponse: processedsfSearchResponse } = await handleHttpRequest( 'get', objSearchUrl, { - headers: { Authorization: authorizationData.token }, + headers: getAuthHeader({ authorizationFlow, authorizationData }), }, { destType: 'salesforce', feature: 'transformation', }, ); - if (processedsfSearchResponse.status !== 200) { + if (!isHttpStatusSuccess(processedsfSearchResponse.status)) { salesforceResponseHandler( processedsfSearchResponse, `:- SALESFORCE SEARCH BY ID`, destination.ID, + authorizationFlow, ); } const searchRecord = processedsfSearchResponse.response?.searchRecords?.find( @@ -149,7 +153,12 @@ async function getSaleforceIdForRecord( // We'll use the Salesforce Object names by removing "Salesforce-" string from the type field // // Default Object type will be "Lead" for backward compatibility -async function getSalesforceIdFromPayload(message, authorizationData, destination) { +async function getSalesforceIdFromPayload( + message, + authorizationData, + destination, + authorizationFlow, +) { // define default map const salesforceMaps = []; @@ -191,6 +200,7 @@ async function getSalesforceIdFromPayload(message, authorizationData, destinatio identifierType, id, destination, + authorizationFlow, ); } @@ -212,12 +222,13 @@ async function getSalesforceIdFromPayload(message, authorizationData, destinatio throw new InstrumentationError('Invalid Email address for Lead Objet'); } const leadQueryUrl = `${authorizationData.instanceUrl}/services/data/v${SF_API_VERSION}/parameterizedSearch/?q=${email}&sobject=Lead&Lead.fields=id,IsConverted,ConvertedContactId,IsDeleted`; + // request configuration will be conditional const { processedResponse: processedLeadQueryResponse } = await handleHttpRequest( 'get', leadQueryUrl, { - headers: { Authorization: authorizationData.token }, + headers: getAuthHeader({ authorizationFlow, authorizationData }), }, { destType: 'salesforce', @@ -225,8 +236,13 @@ async function getSalesforceIdFromPayload(message, authorizationData, destinatio }, ); - if (processedLeadQueryResponse.status !== 200) { - salesforceResponseHandler(processedLeadQueryResponse, `:- during Lead Query`, destination.ID); + if (!isHttpStatusSuccess(processedLeadQueryResponse.status)) { + salesforceResponseHandler( + processedLeadQueryResponse, + `:- during Lead Query`, + destination.ID, + authorizationFlow, + ); } if (processedLeadQueryResponse.response.searchRecords.length > 0) { @@ -262,7 +278,7 @@ async function getSalesforceIdFromPayload(message, authorizationData, destinatio } // Function for handling identify events -async function processIdentify(message, authorizationData, destination) { +async function processIdentify(message, authorizationData, destination, authorizationFlow) { const mapProperty = destination.Config.mapProperty === undefined ? true : destination.Config.mapProperty; // check the traits before hand @@ -283,7 +299,12 @@ async function processIdentify(message, authorizationData, destination) { const responseData = []; // get salesforce object map - const salesforceMaps = await getSalesforceIdFromPayload(message, authorizationData, destination); + const salesforceMaps = await getSalesforceIdFromPayload( + message, + authorizationData, + destination, + authorizationFlow, + ); // iterate over the object types found salesforceMaps.forEach((salesforceMap) => { @@ -295,6 +316,7 @@ async function processIdentify(message, authorizationData, destination) { authorizationData, mapProperty, mappedToDestination, + authorizationFlow, ), ); }); @@ -304,10 +326,10 @@ async function processIdentify(message, authorizationData, destination) { // Generic process function which invokes specific handler functions depending on message type // and event type where applicable -async function processSingleMessage(message, authorizationData, destination) { +async function processSingleMessage(message, authorizationData, destination, authorizationFlow) { let response; if (message.type === EventType.IDENTIFY) { - response = await processIdentify(message, authorizationData, destination); + response = await processIdentify(message, authorizationData, destination, authorizationFlow); } else { throw new InstrumentationError(`message type ${message.type} is not supported`); } @@ -315,9 +337,13 @@ async function processSingleMessage(message, authorizationData, destination) { } async function process(event) { - // Get the authorization header if not available - const authorizationData = await getAccessToken(event.destination); - const response = await processSingleMessage(event.message, authorizationData, event.destination); + const authInfo = await collectAuthorizationInfo(event); + const response = await processSingleMessage( + event.message, + authInfo.authorizationData, + event.destination, + authInfo.authorizationFlow, + ); return response; } @@ -326,10 +352,9 @@ const processRouterDest = async (inputs, reqMetadata) => { if (errorRespEvents.length > 0) { return errorRespEvents; } - - let authorizationData; + let authInfo; try { - authorizationData = await getAccessToken(inputs[0].destination); + authInfo = await collectAuthorizationInfo(inputs[0]); } catch (error) { const errObj = generateErrorObject(error); const respEvents = getErrorRespEvents( @@ -351,7 +376,12 @@ const processRouterDest = async (inputs, reqMetadata) => { // unprocessed payload return getSuccessRespEvents( - await processSingleMessage(input.message, authorizationData, input.destination), + await processSingleMessage( + input.message, + authInfo.authorizationData, + input.destination, + authInfo.authorizationFlow, + ), [input.metadata], input.destination, ); diff --git a/src/v0/destinations/salesforce/utils.js b/src/v0/destinations/salesforce/utils.js index 9429e12e8d..c725ec3b20 100644 --- a/src/v0/destinations/salesforce/utils.js +++ b/src/v0/destinations/salesforce/utils.js @@ -1,12 +1,18 @@ const { RetryableError, ThrottledError, AbortedError } = require('@rudderstack/integrations-lib'); const { handleHttpRequest } = require('../../../adapters/network'); -const { isHttpStatusSuccess } = require('../../util'); +const { + isHttpStatusSuccess, + getAuthErrCategoryFromStCode, + isDefinedAndNotNull, +} = require('../../util'); const Cache = require('../../util/cache'); const { ACCESS_TOKEN_CACHE_TTL, SF_TOKEN_REQUEST_URL_SANDBOX, SF_TOKEN_REQUEST_URL, DESTINATION, + LEGACY, + OAUTH, } = require('./config'); const ACCESS_TOKEN_CACHE = new Cache(ACCESS_TOKEN_CACHE_TTL); @@ -19,7 +25,7 @@ const ACCESS_TOKEN_CACHE = new Cache(ACCESS_TOKEN_CACHE_TTL); * @param {*} stage * @param {String} authKey */ -const salesforceResponseHandler = (destResponse, sourceMessage, authKey) => { +const salesforceResponseHandler = (destResponse, sourceMessage, authKey, authorizationFlow) => { const { status, response } = destResponse; // if the response from destination is not a success case build an explicit error @@ -27,13 +33,16 @@ const salesforceResponseHandler = (destResponse, sourceMessage, authKey) => { const matchErrorCode = (errorCode) => response && Array.isArray(response) && response.some((resp) => resp?.errorCode === errorCode); if (status === 401 && authKey && matchErrorCode('INVALID_SESSION_ID')) { - // checking for invalid/expired token errors and evicting cache in that case - // rudderJobMetadata contains some destination info which is being used to evict the cache - ACCESS_TOKEN_CACHE.del(authKey); + if (authorizationFlow === LEGACY) { + // checking for invalid/expired token errors and evicting cache in that case + // rudderJobMetadata contains some destination info which is being used to evict the cache + ACCESS_TOKEN_CACHE.del(authKey); + } throw new RetryableError( `${DESTINATION} Request Failed - due to "INVALID_SESSION_ID", (Retryable) ${sourceMessage}`, 500, destResponse, + authorizationFlow === LEGACY ? '' : getAuthErrCategoryFromStCode(status), ); } else if (status === 403 && matchErrorCode('REQUEST_LIMIT_EXCEEDED')) { // If the error code is REQUEST_LIMIT_EXCEEDED, you’ve exceeded API request limits in your org. @@ -89,6 +98,11 @@ const salesforceResponseHandler = (destResponse, sourceMessage, authKey) => { * @param {*} destination * @returns */ +const getAccessTokenOauth = (metadata) => ({ + token: metadata.secret?.access_token, + instanceUrl: metadata.secret?.instance_url, +}); + const getAccessToken = async (destination) => { const accessTokenKey = destination.ID; @@ -122,6 +136,7 @@ const getAccessToken = async (destination) => { processedResponse, `:- authentication failed during fetching access token.`, accessTokenKey, + LEGACY, ); } const token = httpResponse.response.data; @@ -131,6 +146,7 @@ const getAccessToken = async (destination) => { processedResponse, `:- authentication failed could not retrieve authorization token.`, accessTokenKey, + LEGACY, ); } return { @@ -140,4 +156,30 @@ const getAccessToken = async (destination) => { }); }; -module.exports = { getAccessToken, salesforceResponseHandler }; +const collectAuthorizationInfo = async (event) => { + let authorizationFlow; + let authorizationData; + if (isDefinedAndNotNull(event.metadata?.secret)) { + authorizationFlow = OAUTH; + authorizationData = getAccessTokenOauth(event.metadata); + } else { + authorizationFlow = LEGACY; + authorizationData = await getAccessToken(event.destination); + } + return { authorizationFlow, authorizationData }; +}; + +const getAuthHeader = (authInfo) => { + const { authorizationFlow, authorizationData } = authInfo; + return authorizationFlow === OAUTH + ? { Authorization: `Bearer ${authorizationData.token}` } + : { Authorization: authorizationData.token }; +}; + +module.exports = { + getAccessTokenOauth, + salesforceResponseHandler, + getAccessToken, + collectAuthorizationInfo, + getAuthHeader, +}; diff --git a/test/integrations/destinations/salesforce/dataDelivery/data.ts b/test/integrations/destinations/salesforce/dataDelivery/data.ts index 504159cc6f..c53ce58f9e 100644 --- a/test/integrations/destinations/salesforce/dataDelivery/data.ts +++ b/test/integrations/destinations/salesforce/dataDelivery/data.ts @@ -119,6 +119,7 @@ export const data = [ body: { output: { status: 500, + authErrorCategory: 'REFRESH_TOKEN', message: 'Salesforce Request Failed - due to "INVALID_SESSION_ID", (Retryable) during Salesforce Response Handling', destinationResponse: { @@ -128,12 +129,12 @@ export const data = [ errorCode: 'INVALID_SESSION_ID', }, ], - status: 401, rudderJobMetadata: { destInfo: { authKey: '2HezPl1w11opbFSxnLDEgZ7kWTf', }, }, + status: 401, }, statTags: { destType: 'SALESFORCE', diff --git a/test/integrations/destinations/salesforce/processor/data.ts b/test/integrations/destinations/salesforce/processor/data.ts index ad0dbb6843..4ccc8cca79 100644 --- a/test/integrations/destinations/salesforce/processor/data.ts +++ b/test/integrations/destinations/salesforce/processor/data.ts @@ -1381,4 +1381,132 @@ export const data = [ }, }, }, + { + name: 'salesforce', + description: 'Test 10', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + initialAccessToken: '7fiy1FKcO9sohsxq1v6J88sg', + password: 'dummyPassword2', + userName: 'test.c97-qvpd@force.com.test', + sandbox: true, + }, + DestinationDefinition: { + DisplayName: 'Salesforce', + ID: '1T96GHZ0YZ1qQSLULHCoJkow9KC', + Name: 'SALESFORCE', + }, + Enabled: true, + ID: '1ut7LcVW1QC56y2EoTNo7ZwBWSY', + Name: 'Test SF', + Transformations: [], + }, + metadata: { + secret: { + access_token: 'dummyAccessToken', + instance_url: 'http://dummyurl.com', + }, + }, + message: { + anonymousId: '1e7673da-9473-49c6-97f7-da848ecafa76', + channel: 'web', + context: { + mappedToDestination: true, + externalId: [ + { + id: 'a005g0000383kmUAAQ', + type: 'SALESFORCE-custom_object__c', + identifierType: 'Id', + }, + ], + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + ip: '0.0.0.0', + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + traits: { + email: 'john@rs.com', + firstname: 'john doe', + Id: 'some-id', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36', + }, + integrations: { + All: true, + }, + messageId: 'f19c35da-e9de-4c6e-b6e5-9e60cccc12c8', + originalTimestamp: '2020-01-27T12:20:55.301Z', + receivedAt: '2020-01-27T17:50:58.657+05:30', + request_ip: '14.98.244.60', + sentAt: '2020-01-27T12:20:56.849Z', + timestamp: '2020-01-27T17:50:57.109+05:30', + type: 'identify', + userId: '1e7673da-9473-49c6-97f7-da848ecafa76', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + statusCode: 200, + metadata: { + secret: { + access_token: 'dummyAccessToken', + instance_url: 'http://dummyurl.com', + }, + }, + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: + 'http://dummyurl.com/services/data/v50.0/sobjects/custom_object__c/a005g0000383kmUAAQ?_HttpMethod=PATCH', + headers: { + 'Content-Type': 'application/json', + Authorization: 'Bearer dummyAccessToken', + }, + params: {}, + body: { + JSON: { + email: 'john@rs.com', + firstname: 'john doe', + }, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + }, + ], + }, + }, + }, ]; From ee1f4733e82291375d85a6de8b8626ffdc8907b1 Mon Sep 17 00:00:00 2001 From: Sandeep Digumarty Date: Mon, 13 Nov 2023 13:04:34 +0530 Subject: [PATCH 33/93] feat: add delivery_category as part of contents, update flattening custom_data in FB Pixel (#2816) * feat: remove contents and content_ids from flattening before setting in custom_data * feat: add delivery_category as part of contents * feat: update API version to v18.0 * chore: updated tests * feat: revert v18 version update * feat: added tests * feat: added tests --- src/v0/destinations/facebook_pixel/config.js | 2 + .../destinations/facebook_pixel/transform.js | 13 +- src/v0/destinations/facebook_pixel/utils.js | 22 +- .../facebook_pixel/processor/data.ts | 401 ++++++++++++++++++ 4 files changed, 435 insertions(+), 3 deletions(-) diff --git a/src/v0/destinations/facebook_pixel/config.js b/src/v0/destinations/facebook_pixel/config.js index 99c3c70b2d..f5f895aea9 100644 --- a/src/v0/destinations/facebook_pixel/config.js +++ b/src/v0/destinations/facebook_pixel/config.js @@ -95,6 +95,7 @@ const OTHER_STANDARD_EVENTS = [ ]; const FB_PIXEL_DEFAULT_EXCLUSION = ['opt_out', 'event_id', 'action_source']; +const FB_PIXEL_CUSTOM_DATA_EXCLUDE_FLATTENING = ['content_ids', 'contents']; const STANDARD_ECOMM_EVENTS_TYPE = [ CONFIG_CATEGORIES.PRODUCT_LIST_VIEWED.type, CONFIG_CATEGORIES.PRODUCT_VIEWED.type, @@ -109,6 +110,7 @@ module.exports = { MAPPING_CONFIG, ACTION_SOURCES_VALUES, FB_PIXEL_DEFAULT_EXCLUSION, + FB_PIXEL_CUSTOM_DATA_EXCLUDE_FLATTENING, STANDARD_ECOMM_EVENTS_TYPE, OTHER_STANDARD_EVENTS, DESTINATION: 'FACEBOOK_PIXEL', diff --git a/src/v0/destinations/facebook_pixel/transform.js b/src/v0/destinations/facebook_pixel/transform.js index 7c55b61302..1bc97ac1fb 100644 --- a/src/v0/destinations/facebook_pixel/transform.js +++ b/src/v0/destinations/facebook_pixel/transform.js @@ -7,6 +7,7 @@ const { CONFIG_CATEGORIES, MAPPING_CONFIG, FB_PIXEL_DEFAULT_EXCLUSION, + FB_PIXEL_CUSTOM_DATA_EXCLUDE_FLATTENING, STANDARD_ECOMM_EVENTS_TYPE, } = require('./config'); const { EventType } = require('../../../constants'); @@ -84,7 +85,12 @@ const responseBuilderSimple = (message, category, destination) => { if (category.type !== 'identify') { customData = flattenJson( - extractCustomFields(message, customData, ['properties'], FB_PIXEL_DEFAULT_EXCLUSION), + extractCustomFields( + message, + customData, + ['properties'], + [...FB_PIXEL_DEFAULT_EXCLUSION, ...FB_PIXEL_CUSTOM_DATA_EXCLUDE_FLATTENING], + ), ); if (standardPageCall && category.type === 'page') { category.standard = true; @@ -124,6 +130,11 @@ const responseBuilderSimple = (message, category, destination) => { if (type === 'simple track') { customData.value = message.properties?.revenue; delete customData.revenue; + FB_PIXEL_CUSTOM_DATA_EXCLUDE_FLATTENING.forEach((customDataParameter) => { + if (message.properties?.[customDataParameter]) { + customData[customDataParameter] = message.properties[customDataParameter]; + } + }); } } } else { diff --git a/src/v0/destinations/facebook_pixel/utils.js b/src/v0/destinations/facebook_pixel/utils.js index 1901edf306..8a63a0b0fe 100644 --- a/src/v0/destinations/facebook_pixel/utils.js +++ b/src/v0/destinations/facebook_pixel/utils.js @@ -1,6 +1,11 @@ const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { isObject } = require('../../util'); -const { ACTION_SOURCES_VALUES, CONFIG_CATEGORIES, OTHER_STANDARD_EVENTS } = require('./config'); +const { + ACTION_SOURCES_VALUES, + CONFIG_CATEGORIES, + OTHER_STANDARD_EVENTS, + FB_PIXEL_CUSTOM_DATA_EXCLUDE_FLATTENING, +} = require('./config'); const { getContentType, getContentCategory } = require('../../util/facebookUtils'); /** format revenue according to fb standards with max two decimal places. @@ -54,7 +59,14 @@ const handleOrder = (message, categoryToContent) => { const contentType = getContentType(message, 'product', categoryToContent); const contentIds = []; const contents = []; - const { category, quantity, price, currency, contentName } = message.properties; + const { + category, + quantity, + price, + currency, + contentName, + delivery_category: deliveryCategory, + } = message.properties; if (products) { if (products.length > 0 && Array.isArray(products)) { products.forEach((singleProduct) => { @@ -67,6 +79,7 @@ const handleOrder = (message, categoryToContent) => { id: pId, quantity: singleProduct.quantity || quantity || 1, item_price: singleProduct.price || price, + delivery_category: singleProduct.delivery_category || deliveryCategory, }; contents.push(content); } @@ -262,6 +275,11 @@ const populateCustomDataBasedOnCategory = ( case 'page': // executed when page call is done with standard PageView turned on case 'otherStandard': updatedCustomData = { ...customData }; + FB_PIXEL_CUSTOM_DATA_EXCLUDE_FLATTENING.forEach((customDataParameter) => { + if (message.properties?.[customDataParameter]) { + updatedCustomData[customDataParameter] = message.properties[customDataParameter]; + } + }); break; default: throw new InstrumentationError(`${category.standard} type of standard event does not exist`); diff --git a/test/integrations/destinations/facebook_pixel/processor/data.ts b/test/integrations/destinations/facebook_pixel/processor/data.ts index d5d0a8ec96..96e80c01e8 100644 --- a/test/integrations/destinations/facebook_pixel/processor/data.ts +++ b/test/integrations/destinations/facebook_pixel/processor/data.ts @@ -6058,4 +6058,405 @@ export const data = [ }, }, }, + { + name: 'facebook_pixel', + description: 'Test 48', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + traits: { + email: 'test@rudderstack.com', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + 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', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + }, + type: 'track', + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2023-10-14T15:46:51.693229+05:30', + anonymousId: '00000000000000000000000000', + userId: '12345', + event: 'order completed', + properties: { + category: ['clothing', 'fishing'], + order_id: 'rudderstackorder1', + total: 99.99, + revenue: 12.24, + shipping: 13.99, + tax: 20.99, + currency: 'INR', + products: [ + { + quantity: 1, + price: 24.75, + name: 'my product', + sku: 'p-298', + delivery_category: 'home_delivery', + }, + { + quantity: 3, + price: 24.75, + name: 'other product', + sku: 'p-299', + delivery_category: 'home_delivery', + }, + ], + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: { + Config: { + blacklistPiiProperties: [ + { + blacklistPiiProperties: '', + blacklistPiiHash: true, + }, + ], + categoryToContent: [ + { + from: 'clothing', + to: 'product', + }, + ], + accessToken: '09876', + pixelId: 'dummyPixelId', + eventsToEvents: [ + { + from: '', + to: '', + }, + ], + eventCustomProperties: [ + { + eventCustomProperties: '', + }, + ], + valueFieldIdentifier: 'properties.price', + advancedMapping: false, + whitelistPiiProperties: [ + { + whitelistPiiProperties: '', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://graph.facebook.com/v17.0/dummyPixelId/events?access_token=09876', + headers: {}, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: { + data: [ + '{"user_data":{"external_id":"5994471abb01112afcc18159f6cc74b4f511b99806da59b3caf5a9c173cacfc5","em":"1c5e54849f5c711ce38fa60716fbbe44bff478f9ca250897b39cdfc2438cd1bd","client_user_agent":"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"},"event_name":"Purchase","event_time":1697278611,"event_id":"ec5481b6-a926-4d2e-b293-0b3a77c4d3be","action_source":"website","custom_data":{"category[0]":"clothing","category[1]":"fishing","order_id":"rudderstackorder1","total":99.99,"revenue":12.24,"shipping":13.99,"tax":20.99,"currency":"INR","products[0].quantity":1,"products[0].price":24.75,"products[0].name":"my product","products[0].sku":"p-298","products[0].delivery_category":"home_delivery","products[1].quantity":3,"products[1].price":24.75,"products[1].name":"other product","products[1].sku":"p-299","products[1].delivery_category":"home_delivery","content_category":"clothing,fishing","content_ids":["p-298","p-299"],"content_type":"product","value":12.24,"contents":[{"id":"p-298","quantity":1,"item_price":24.75,"delivery_category":"home_delivery"},{"id":"p-299","quantity":3,"item_price":24.75,"delivery_category":"home_delivery"}],"num_items":2}}', + ], + }, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'facebook_pixel', + description: 'Test 49', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + channel: 'mobile', + destination_props: { + Fb: { + app_id: 'RudderFbApp', + }, + }, + context: { + device: { + id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', + manufacturer: 'Xiaomi', + model: 'Redmi 6', + name: 'xiaomi', + }, + network: { + carrier: 'Banglalink', + }, + os: { + name: 'android', + version: '8.1.0', + }, + screen: { + height: '100', + density: 50, + }, + traits: { + email: ' aBc@gmail.com ', + address: { + zip: 1234, + }, + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + }, + }, + event: 'spin_result', + integrations: { + All: true, + }, + message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', + properties: { + revenue: 400, + additional_bet_index: 0, + content_ids: ['prod1', 'prod2'], + }, + timestamp: '2023-10-14T00:00:00.693229+05:30', + type: 'track', + }, + destination: { + Config: { + limitedDataUsage: true, + blacklistPiiProperties: [ + { + blacklistPiiProperties: '', + blacklistPiiHash: false, + }, + ], + accessToken: '09876', + pixelId: 'dummyPixelId', + eventsToEvents: [ + { + from: '', + to: '', + }, + ], + eventCustomProperties: [ + { + eventCustomProperties: '', + }, + ], + removeExternalId: true, + valueFieldIdentifier: '', + advancedMapping: false, + whitelistPiiProperties: [ + { + whitelistPiiProperties: '', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://graph.facebook.com/v17.0/dummyPixelId/events?access_token=09876', + headers: {}, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: { + data: [ + '{"user_data":{"em":"48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08","zp":"03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4"},"event_name":"spin_result","event_time":1697221800,"action_source":"app","custom_data":{"additional_bet_index":0,"value":400,"content_ids":["prod1","prod2"]}}', + ], + }, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'facebook_pixel', + description: 'Test 50', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + channel: 'mobile', + destination_props: { + Fb: { + app_id: 'RudderFbApp', + }, + }, + context: { + device: { + id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', + manufacturer: 'Xiaomi', + model: 'Redmi 6', + name: 'xiaomi', + }, + network: { + carrier: 'Banglalink', + }, + os: { + name: 'android', + version: '8.1.0', + }, + screen: { + height: '100', + density: 50, + }, + traits: { + email: ' aBc@gmail.com ', + address: { + zip: 1234, + }, + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + }, + }, + event: 'spin_result', + integrations: { + All: true, + }, + message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', + properties: { + revenue: 400, + additional_bet_index: 0, + contents: [ + { + id: 'prod1', + quantity: 5, + item_price: 55, + }, + ], + }, + timestamp: '2023-10-14T00:00:00.693229+05:30', + type: 'track', + }, + destination: { + Config: { + limitedDataUsage: true, + blacklistPiiProperties: [ + { + blacklistPiiProperties: '', + blacklistPiiHash: false, + }, + ], + accessToken: '09876', + pixelId: 'dummyPixelId', + eventsToEvents: [ + { + from: '', + to: '', + }, + ], + eventCustomProperties: [ + { + eventCustomProperties: '', + }, + ], + removeExternalId: true, + valueFieldIdentifier: '', + advancedMapping: false, + whitelistPiiProperties: [ + { + whitelistPiiProperties: '', + }, + ], + }, + Enabled: true, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://graph.facebook.com/v17.0/dummyPixelId/events?access_token=09876', + headers: {}, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: { + data: [ + '{"user_data":{"em":"48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08","zp":"03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4"},"event_name":"spin_result","event_time":1697221800,"action_source":"app","custom_data":{"additional_bet_index":0,"value":400,"contents":[{"id":"prod1","quantity":5,"item_price":55}]}}', + ], + }, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, ].map((d) => ({ ...d, mockFns })); From 93a82bd4856b462768d0213ae3de8b9b78e9858c Mon Sep 17 00:00:00 2001 From: AASHISH MALIK Date: Mon, 13 Nov 2023 13:21:51 +0530 Subject: [PATCH 34/93] feat: use custom screen name amplitude (#2823) * feat: use custom screen name amplitude * fix: use name if custom screen name is empty --- src/v0/destinations/am/transform.js | 44 +++++--- test/__tests__/data/am_input.json | 100 ++++++++++++++++++ test/__tests__/data/am_output.json | 156 ++++++++++++++++++++++++++++ 3 files changed, 286 insertions(+), 14 deletions(-) diff --git a/src/v0/destinations/am/transform.js b/src/v0/destinations/am/transform.js index 27d5bc3161..bed5d45b28 100644 --- a/src/v0/destinations/am/transform.js +++ b/src/v0/destinations/am/transform.js @@ -591,7 +591,8 @@ const processSingleMessage = (message, destination) => { const { name, event, properties } = message; const messageType = message.type.toLowerCase(); const CATEGORY_KEY = 'properties.category'; - const { useUserDefinedPageEventName, userProvidedPageEventString } = destination.Config; + const { useUserDefinedPageEventName, userProvidedPageEventString, + useUserDefinedScreenEventName, userProvidedScreenEventString } = destination.Config; switch (messageType) { case EventType.IDENTIFY: payloadObjectName = 'events'; // identify same as events @@ -601,17 +602,17 @@ const processSingleMessage = (message, destination) => { case EventType.PAGE: if (useUserDefinedPageEventName) { const getMessagePath = userProvidedPageEventString - .substring( - userProvidedPageEventString.indexOf('{') + 2, - userProvidedPageEventString.indexOf('}'), - ) - .trim(); + .substring( + userProvidedPageEventString.indexOf('{') + 2, + userProvidedPageEventString.indexOf('}'), + ) + .trim(); evType = - userProvidedPageEventString.trim() === '' - ? name - : userProvidedPageEventString - .trim() - .replaceAll(/{{([^{}]+)}}/g, get(message, getMessagePath)); + userProvidedPageEventString.trim() === '' + ? name + : userProvidedPageEventString + .trim() + .replaceAll(/{{([^{}]+)}}/g, get(message, getMessagePath)); } else { evType = `Viewed ${name || get(message, CATEGORY_KEY) || ''} Page`; } @@ -624,10 +625,25 @@ const processSingleMessage = (message, destination) => { case EventType.SCREEN: { const { eventType, updatedProperties } = getScreenevTypeAndUpdatedProperties( - message, - CATEGORY_KEY, + message, + CATEGORY_KEY, ); - evType = eventType; + let customScreenEv = ''; + if (useUserDefinedScreenEventName) { + const getMessagePath = userProvidedScreenEventString + .substring( + userProvidedScreenEventString.indexOf('{') + 2, + userProvidedScreenEventString.indexOf('}'), + ) + .trim(); + customScreenEv = + userProvidedScreenEventString.trim() === '' + ? name + : userProvidedScreenEventString + .trim() + .replaceAll(/{{([^{}]+)}}/g, get(message, getMessagePath)); + } + evType =useUserDefinedScreenEventName ? customScreenEv : eventType; message.properties = updatedProperties; category = ConfigCategory.SCREEN; } diff --git a/test/__tests__/data/am_input.json b/test/__tests__/data/am_input.json index 3e5cde2cca..126d235787 100644 --- a/test/__tests__/data/am_input.json +++ b/test/__tests__/data/am_input.json @@ -4842,5 +4842,105 @@ "userProvidedPageEventString": "Viewed {{context.page.title}} event." } } + }, + { + "message": { + "type": "screen", + "userId": "identified user id", + "anonymousId": "anon-id-new", + "event": "Screen View", + "properties": { + "prop1": "5" + }, + "context": { + "ip": "14.5.67.21", + "library": { + "name": "http" + } + }, + "timestamp": "2020-02-02T00:23:09.544Z" + }, + "destination": { + "Config": { + "apiKey": "abcde", + "useUserDefinedScreenEventName": true, + "userProvidedScreenEventString": "My {{ event }} event." + } + } + }, + { + "message": { + "type": "screen", + "userId": "identified user id", + "anonymousId": "anon-id-new", + "event": "Screen View", + "properties": { + "prop1": "5" + }, + "context": { + "ip": "14.5.67.21", + "library": { + "name": "http" + } + }, + "timestamp": "2020-02-02T00:23:09.544Z" + }, + "destination": { + "Config": { + "apiKey": "abcde", + "useUserDefinedScreenEventName": false, + "userProvidedScreenEventString": "My {{ event }} event." + } + } + }, + { + "message": { + "type": "screen", + "userId": "identified user id", + "anonymousId": "anon-id-new", + "event": "Screen same as event", + "properties": { + "prop1": "5" + }, + "context": { + "ip": "14.5.67.21", + "library": { + "name": "http" + } + }, + "timestamp": "2020-02-02T00:23:09.544Z" + }, + "destination": { + "Config": { + "apiKey": "abcde", + "useUserDefinedScreenEventName": true, + "userProvidedScreenEventString": "{{ event }}" + } + } + }, + { + "message": { + "type": "screen", + "userId": "identified user id", + "anonymousId": "anon-id-new", + "name": "Screen", + "properties": { + "prop1": "5" + }, + "context": { + "ip": "14.5.67.21", + "library": { + "name": "http" + } + }, + "timestamp": "2020-02-02T00:23:09.544Z" + }, + "destination": { + "Config": { + "apiKey": "abcde", + "useUserDefinedScreenEventName": true, + "userProvidedScreenEventString": "" + } + } } ] \ No newline at end of file diff --git a/test/__tests__/data/am_output.json b/test/__tests__/data/am_output.json index ea4b8b908d..5a9c674113 100644 --- a/test/__tests__/data/am_output.json +++ b/test/__tests__/data/am_output.json @@ -4311,5 +4311,161 @@ }, "files": {}, "userId": "00000000000000000000000000" + }, + { + "version": "1", + "type": "REST", + "method": "POST", + "endpoint": "https://api2.amplitude.com/2/httpapi", + "headers": { + "Content-Type": "application/json" + }, + "params": {}, + "body": { + "JSON": { + "api_key": "abcde", + "events": [ + { + "device_id": "anon-id-new", + "library": "rudderstack", + "event_properties": { + "prop1": "5", + "name": "Screen View" + }, + "event_type": "My Screen View event.", + "time": 1580602989544, + "user_id": "identified user id", + "user_properties": {}, + "session_id": -1, + "ip": "14.5.67.21" + } + ], + "options": { + "min_id_length": 1 + } + }, + "XML": {}, + "JSON_ARRAY": {}, + "FORM": {} + }, + "files": {}, + "userId": "anon-id-new" + }, + { + "version": "1", + "type": "REST", + "method": "POST", + "endpoint": "https://api2.amplitude.com/2/httpapi", + "headers": { + "Content-Type": "application/json" + }, + "params": {}, + "body": { + "JSON": { + "api_key": "abcde", + "events": [ + { + "device_id": "anon-id-new", + "library": "rudderstack", + "event_properties": { + "prop1": "5", + "name": "Screen View" + }, + "event_type": "Viewed Screen View Screen", + "time": 1580602989544, + "user_id": "identified user id", + "user_properties": {}, + "session_id": -1, + "ip": "14.5.67.21" + } + ], + "options": { + "min_id_length": 1 + } + }, + "XML": {}, + "JSON_ARRAY": {}, + "FORM": {} + }, + "files": {}, + "userId": "anon-id-new" + }, + { + "version": "1", + "type": "REST", + "method": "POST", + "endpoint": "https://api2.amplitude.com/2/httpapi", + "headers": { + "Content-Type": "application/json" + }, + "params": {}, + "body": { + "JSON": { + "api_key": "abcde", + "events": [ + { + "device_id": "anon-id-new", + "library": "rudderstack", + "event_properties": { + "prop1": "5", + "name": "Screen same as event" + }, + "event_type": "Screen same as event", + "time": 1580602989544, + "user_id": "identified user id", + "user_properties": {}, + "session_id": -1, + "ip": "14.5.67.21" + } + ], + "options": { + "min_id_length": 1 + } + }, + "XML": {}, + "JSON_ARRAY": {}, + "FORM": {} + }, + "files": {}, + "userId": "anon-id-new" + }, + { + "version": "1", + "type": "REST", + "method": "POST", + "endpoint": "https://api2.amplitude.com/2/httpapi", + "headers": { + "Content-Type": "application/json" + }, + "params": {}, + "body": { + "JSON": { + "api_key": "abcde", + "events": [ + { + "device_id": "anon-id-new", + "library": "rudderstack", + "event_properties": { + "prop1": "5", + "name": "Screen" + }, + "event_type": "Screen", + "time": 1580602989544, + "user_id": "identified user id", + "user_properties": {}, + "session_id": -1, + "ip": "14.5.67.21" + } + ], + "options": { + "min_id_length": 1 + } + }, + "XML": {}, + "JSON_ARRAY": {}, + "FORM": {} + }, + "files": {}, + "userId": "anon-id-new" } ] \ No newline at end of file From b92846170b11158b9fea889f579ec590ed2c512a Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Mon, 13 Nov 2023 07:58:21 +0000 Subject: [PATCH 35/93] chore(release): 1.50.0 --- CHANGELOG.md | 18 ++++++++++++++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 97a3a2c226..04ebb304cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,24 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +## [1.50.0](https://github.com/rudderlabs/rudder-transformer/compare/v1.49.1...v1.50.0) (2023-11-13) + + +### Features + +* add clickId support for tiktok and pinterest destination ([#2784](https://github.com/rudderlabs/rudder-transformer/issues/2784)) ([0e14296](https://github.com/rudderlabs/rudder-transformer/commit/0e1429663d167a2c5cded0d9130374eb586a18c0)) +* add delivery_category as part of contents, remove flattening custom_data in FB conversions ([#2812](https://github.com/rudderlabs/rudder-transformer/issues/2812)) ([e82cef8](https://github.com/rudderlabs/rudder-transformer/commit/e82cef88e154d47519f0deeb60f55773f25fd3ad)) +* add delivery_category as part of contents, update flattening custom_data in FB Pixel ([#2816](https://github.com/rudderlabs/rudder-transformer/issues/2816)) ([ee1f473](https://github.com/rudderlabs/rudder-transformer/commit/ee1f4733e82291375d85a6de8b8626ffdc8907b1)) +* adding support for future oauth facility in salesforce ([#2746](https://github.com/rudderlabs/rudder-transformer/issues/2746)) ([916ea4c](https://github.com/rudderlabs/rudder-transformer/commit/916ea4c8d08f69b68b7795dd513a25a3cded55fa)) +* introduce v1/source/sourceType endpoint ([#2722](https://github.com/rudderlabs/rudder-transformer/issues/2722)) ([0996e81](https://github.com/rudderlabs/rudder-transformer/commit/0996e816d3671c3e25561f76e3219be99225f24b)) +* move cdkV1 to cdkv2 component tests ([#2804](https://github.com/rudderlabs/rudder-transformer/issues/2804)) ([195b48a](https://github.com/rudderlabs/rudder-transformer/commit/195b48ac0f438a200933e4bbb956fcc3941b7aed)) +* use custom screen name amplitude ([#2823](https://github.com/rudderlabs/rudder-transformer/issues/2823)) ([93a82bd](https://github.com/rudderlabs/rudder-transformer/commit/93a82bd4856b462768d0213ae3de8b9b78e9858c)) + + +### Bug Fixes + +* shopify redis metric when there is no data returned for a key ([#2811](https://github.com/rudderlabs/rudder-transformer/issues/2811)) ([c02370e](https://github.com/rudderlabs/rudder-transformer/commit/c02370e38fabb581698baa00e1ddd3da93dc07fa)) + ### [1.49.1](https://github.com/rudderlabs/rudder-transformer/compare/v1.49.0...v1.49.1) (2023-11-10) diff --git a/package-lock.json b/package-lock.json index f1d3be597c..28d814c925 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "rudder-transformer", - "version": "1.49.1", + "version": "1.50.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "rudder-transformer", - "version": "1.49.1", + "version": "1.50.0", "license": "ISC", "dependencies": { "@amplitude/ua-parser-js": "^0.7.24", diff --git a/package.json b/package.json index 076e912112..e4a4d9151c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rudder-transformer", - "version": "1.49.1", + "version": "1.50.0", "description": "", "homepage": "https://github.com/rudderlabs/rudder-transformer#readme", "bugs": { From a56d66810bdcbcf8a4073735dd1a9622ba48c27e Mon Sep 17 00:00:00 2001 From: chandumlg <54652834+chandumlg@users.noreply.github.com> Date: Mon, 13 Nov 2023 09:07:36 -0600 Subject: [PATCH 36/93] fix: source transform error stat (#2825) * fix: source_transform_error_stat * chore: update changelog --------- Co-authored-by: Chandra shekar Varkala --- CHANGELOG.md | 1 + src/services/source/nativeIntegration.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 04ebb304cf..c720cc8718 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ All notable changes to this project will be documented in this file. See [standa ### Bug Fixes +* source_transform_error stat label correction ([#2825](https://github.com/rudderlabs/rudder-transformer/issues/2825)) ([f3bcd7c](https://github.com/rudderlabs/rudder-transformer/commit/f3bcd7c9338ef96267be84f845c63f5234d37e33)) * shopify redis metric when there is no data returned for a key ([#2811](https://github.com/rudderlabs/rudder-transformer/issues/2811)) ([c02370e](https://github.com/rudderlabs/rudder-transformer/commit/c02370e38fabb581698baa00e1ddd3da93dc07fa)) ### [1.49.1](https://github.com/rudderlabs/rudder-transformer/compare/v1.49.0...v1.49.1) (2023-11-10) diff --git a/src/services/source/nativeIntegration.ts b/src/services/source/nativeIntegration.ts index f29d68d054..22783db049 100644 --- a/src/services/source/nativeIntegration.ts +++ b/src/services/source/nativeIntegration.ts @@ -42,7 +42,7 @@ export default class NativeIntegrationSourceService implements IntegrationSource } catch (error: FixMe) { const metaTO = this.getTags(); stats.increment('source_transform_errors', { - sourceType, + source: sourceType, version, }); return PostTransformationServiceSource.handleFailureEventsSource(error, metaTO); From 2055dabb25e0e67a61dda263ca75f93408f1bf9c Mon Sep 17 00:00:00 2001 From: AASHISH MALIK Date: Tue, 14 Nov 2023 11:24:35 +0530 Subject: [PATCH 37/93] fix: snapchat_conversion category mapping (#2826) * fix: snapchat_conversion category mapping --- CHANGELOG.md | 1 + .../data/OrderCompletedConfig.json | 2 +- .../snapchat_conversion/processor/data.ts | 309 ++++++++++++++++++ 3 files changed, 311 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c720cc8718..8f990fe3b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ All notable changes to this project will be documented in this file. See [standa * source_transform_error stat label correction ([#2825](https://github.com/rudderlabs/rudder-transformer/issues/2825)) ([f3bcd7c](https://github.com/rudderlabs/rudder-transformer/commit/f3bcd7c9338ef96267be84f845c63f5234d37e33)) * shopify redis metric when there is no data returned for a key ([#2811](https://github.com/rudderlabs/rudder-transformer/issues/2811)) ([c02370e](https://github.com/rudderlabs/rudder-transformer/commit/c02370e38fabb581698baa00e1ddd3da93dc07fa)) +* snapchat_conversion category mapping ([#2826](https://github.com/rudderlabs/rudder-transformer/issues/2826)) ([7acd004](https://github.com/rudderlabs/rudder-transformer/commit/7acd004e4290dfb5ea20402929041462eddb4496)) ### [1.49.1](https://github.com/rudderlabs/rudder-transformer/compare/v1.49.0...v1.49.1) (2023-11-10) diff --git a/src/v0/destinations/snapchat_conversion/data/OrderCompletedConfig.json b/src/v0/destinations/snapchat_conversion/data/OrderCompletedConfig.json index dc5696e9a4..38e85ca2d8 100644 --- a/src/v0/destinations/snapchat_conversion/data/OrderCompletedConfig.json +++ b/src/v0/destinations/snapchat_conversion/data/OrderCompletedConfig.json @@ -6,7 +6,7 @@ }, { "destKey": "item_category", - "sourceKeys": "properties.item_category", + "sourceKeys": ["properties.item_category", "properties.category"], "required": false }, { diff --git a/test/integrations/destinations/snapchat_conversion/processor/data.ts b/test/integrations/destinations/snapchat_conversion/processor/data.ts index ed38673d95..baa2b2b99e 100644 --- a/test/integrations/destinations/snapchat_conversion/processor/data.ts +++ b/test/integrations/destinations/snapchat_conversion/processor/data.ts @@ -4291,6 +4291,315 @@ export const data = [ }, }, }, + { + name: 'snapchat_conversion', + description: 'Test Case for Order Completed event category', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2022-04-22T10:57:58Z', + channel: 'mobile', + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99090', + context: { + traits: { + email: 'test@email.com', + phone: '+91 2111111 ', + }, + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + externalId: [ + { + type: 'ga4AppInstanceId', + id: 'f0dd99v4f979fb997ce453373900f891', + }, + ], + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + type: 'track', + event: 'Order Completed', + properties: { + brands: ['brand01', 'brand02'], + products: [ + { + product_id: '123', + price: '14', + quantity: 1, + }, + { + product_id: '124', + price: 14, + quantity: 3, + }, + ], + category: 'shoes' + }, + integrations: { + All: true, + }, + sentAt: '2022-04-22T10:57:58Z', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: false, + }, + }, + Config: { + apiKey: 'dummyApiKey', + pixelId: 'dummyPixelId', + appId: 'dhfeih44f', + snapAppId: 'hfhdhfd', + }, + }, + metadata: { + jobId: 31, + destinationId: 'd2', + workspaceId: 'w2', + }, + }, + ], + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + jobId: 31, + destinationId: 'd2', + workspaceId: 'w2', + }, + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://tr.snapchat.com/v2/conversion', + headers: { + Authorization: 'Bearer dummyApiKey', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + event_type: 'PURCHASE', + item_ids: ['123', '124'], + brands: ['brand01', 'brand02'], + item_category: "shoes", + price: '56', + hashed_email: '73062d872926c2a556f17b36f50e328ddf9bff9d403939bd14b6c3b7f5a33fc2', + hashed_phone_number: + 'bc77d64d7045fe44795ed926df37231a0cfb6ec6b74588c512790e9f143cc492', + hashed_mobile_ad_id: + 'f9779d734aaee50f16ee0011260bae7048f1d9a128c62b6a661077875701edd2', + hashed_idfv: '54bd0b26a3d39dad90f5149db49b9fd9ba885f8e35d1d94cae69273f5e657b9f', + user_agent: + 'mozilla/5.0 (macintosh; intel mac os x 10_15_2) applewebkit/537.36 (khtml, like gecko) chrome/79.0.3945.88 safari/537.36', + timestamp: '1650625078', + event_conversion_type: 'MOBILE_APP', + snap_app_id: 'hfhdhfd', + app_id: 'dhfeih44f', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'snapchat_conversion', + description: 'Test Case for Order Completed event with both category and item_category', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2022-04-22T10:57:58Z', + channel: 'mobile', + anonymousId: 'ea5cfab2-3961-4d8a-8187-3d1858c99090', + context: { + traits: { + email: 'test@email.com', + phone: '+91 2111111 ', + }, + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + device: { + advertisingId: 'T0T0T072-5e28-45a1-9eda-ce22a3e36d1a', + id: '3f034872-5e28-45a1-9eda-ce22a3e36d1a', + manufacturer: 'Google', + name: 'generic_x86_arm', + type: 'ios', + attTrackingStatus: 3, + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + locale: 'en-US', + os: { + name: 'iOS', + version: '14.4.1', + }, + screen: { + density: 2, + }, + externalId: [ + { + type: 'ga4AppInstanceId', + id: 'f0dd99v4f979fb997ce453373900f891', + }, + ], + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + }, + type: 'track', + event: 'Order Completed', + properties: { + brands: ['brand01', 'brand02'], + products: [ + { + product_id: '123', + price: '14', + quantity: 1, + }, + { + product_id: '124', + price: 14, + quantity: 3, + }, + ], + category: 'shoes', + item_category: 'glass' + }, + integrations: { + All: true, + }, + sentAt: '2022-04-22T10:57:58Z', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: false, + }, + }, + Config: { + apiKey: 'dummyApiKey', + pixelId: 'dummyPixelId', + appId: 'dhfeih44f', + snapAppId: 'hfhdhfd', + }, + }, + metadata: { + jobId: 31, + destinationId: 'd2', + workspaceId: 'w2', + }, + }, + ], + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + jobId: 31, + destinationId: 'd2', + workspaceId: 'w2', + }, + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://tr.snapchat.com/v2/conversion', + headers: { + Authorization: 'Bearer dummyApiKey', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + event_type: 'PURCHASE', + item_ids: ['123', '124'], + brands: ['brand01', 'brand02'], + item_category: "glass", + price: '56', + hashed_email: '73062d872926c2a556f17b36f50e328ddf9bff9d403939bd14b6c3b7f5a33fc2', + hashed_phone_number: + 'bc77d64d7045fe44795ed926df37231a0cfb6ec6b74588c512790e9f143cc492', + hashed_mobile_ad_id: + 'f9779d734aaee50f16ee0011260bae7048f1d9a128c62b6a661077875701edd2', + hashed_idfv: '54bd0b26a3d39dad90f5149db49b9fd9ba885f8e35d1d94cae69273f5e657b9f', + user_agent: + 'mozilla/5.0 (macintosh; intel mac os x 10_15_2) applewebkit/537.36 (khtml, like gecko) chrome/79.0.3945.88 safari/537.36', + timestamp: '1650625078', + event_conversion_type: 'MOBILE_APP', + snap_app_id: 'hfhdhfd', + app_id: 'dhfeih44f', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + } ].map((tc) => ({ ...tc, mockFns: (_) => { From 06c6503c8857e61d084c7f5f997ab2efaf9012f9 Mon Sep 17 00:00:00 2001 From: Utsab Chowdhury Date: Tue, 14 Nov 2023 17:27:48 +0530 Subject: [PATCH 38/93] chore: update import and export names, default new routes (#2810) --- .eslintrc.json | 2 +- package.json | 1 + src/controllers/delivery.ts | 12 +- src/controllers/destination.ts | 26 +-- src/controllers/eventTest.ts | 4 +- src/controllers/misc.ts | 4 +- src/controllers/profile.ts | 6 +- src/controllers/regulation.ts | 9 +- src/controllers/source.ts | 12 +- src/controllers/trackingPlan.ts | 6 +- src/controllers/userTransform.ts | 6 +- src/controllers/util/index.test.ts | 2 +- src/controllers/util/index.ts | 2 +- src/helpers/fetchHandlers.ts | 4 +- src/helpers/serviceSelector.ts | 16 +- src/index.ts | 14 +- src/interfaces/DestinationService.ts | 2 +- src/interfaces/SourceService.ts | 2 +- src/middlewares/featureFlag.ts | 2 +- src/middlewares/routeActivation.ts | 2 +- src/routes/delivery.ts | 4 +- src/routes/destination.ts | 26 +-- src/routes/misc.ts | 4 +- src/routes/source.ts | 8 +- src/routes/testEvents.ts | 2 +- src/routes/trackingPlan.ts | 2 +- src/routes/userTransform.ts | 18 +- src/services/comparator.ts | 13 +- src/services/delivertTest/deliveryTest.ts | 2 +- src/services/destination/cdkV1Integration.ts | 6 +- src/services/destination/cdkV2Integration.ts | 6 +- src/services/destination/nativeIntegration.ts | 8 +- .../destination/postTransformation.ts | 4 +- src/services/destination/preTransformation.ts | 2 +- src/services/errorReporting.ts | 2 +- src/services/eventTest/eventTester.ts | 2 +- src/services/misc.ts | 2 +- src/services/profile.ts | 2 +- src/services/source/nativeIntegration.ts | 12 +- src/services/source/postTransformation.ts | 4 +- src/services/trackingPlan.ts | 2 +- src/services/userTransform.ts | 2 +- src/util/dynamicConfigParser.ts | 2 +- src/v0/destinations/hs/util.js | 3 +- src/v0/sources/shopify/util.js | 5 +- .../data/sanity/active_campaign_output.json | 54 ----- .../data/sanity/destination_config.json | 102 --------- .../data/sanity/marketo_router_output.json | 165 -------------- test/__tests__/data/sanity/sanity_input.json | 185 ---------------- .../data/sanity/sanity_router_input.json | 59 ----- test/__tests__/legacyRouter.test.ts | 2 +- test/__tests__/sanity.test.js | 204 ------------------ test/__tests__/user_transformation_ts.test.ts | 2 +- .../data_scenarios/source/v1/pipedream.json | 2 +- test/controllerUtility/ctrl-utility.test.ts | 2 +- 55 files changed, 138 insertions(+), 916 deletions(-) delete mode 100644 test/__tests__/data/sanity/active_campaign_output.json delete mode 100644 test/__tests__/data/sanity/destination_config.json delete mode 100644 test/__tests__/data/sanity/marketo_router_output.json delete mode 100644 test/__tests__/data/sanity/sanity_input.json delete mode 100644 test/__tests__/data/sanity/sanity_router_input.json delete mode 100644 test/__tests__/sanity.test.js diff --git a/.eslintrc.json b/.eslintrc.json index c2614ac5ef..d2928e50fd 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -54,7 +54,7 @@ "@typescript-eslint/no-explicit-any": "off", "class-methods-use-this": "off", "@typescript-eslint/return-await": "error", - "import/prefer-default-export": "error", + "import/prefer-default-export": "off", "sonarjs/no-ignored-return": "error", "no-new": "error", "@typescript-eslint/no-shadow": "error", diff --git a/package.json b/package.json index e4a4d9151c..f8851cc687 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "build:ci": "tsc -p tsconfig.json", "build:swagger": "npm run build && npm run setup:swagger", "build": "npm run build:ci && npm run copy", + "clean:build": "npm run clean && npm run build", "build:clean": "npm run clean && npm run build", "verify": "eslint . || exit 1; npm run test:js || exit 1", "test:testRouter": "jest testRouter --detectOpenHandles --coverage --notify --watchAll=false", diff --git a/src/controllers/delivery.ts b/src/controllers/delivery.ts index 5dee091c46..af94764d46 100644 --- a/src/controllers/delivery.ts +++ b/src/controllers/delivery.ts @@ -1,15 +1,15 @@ import { Context } from 'koa'; -import MiscService from '../services/misc'; +import { MiscService } from '../services/misc'; import { DeliveryResponse, ProcessorTransformationOutput } from '../types/index'; -import ServiceSelector from '../helpers/serviceSelector'; -import DeliveryTestService from '../services/delivertTest/deliveryTest'; -import ControllerUtility from './util'; +import { ServiceSelector } from '../helpers/serviceSelector'; +import { DeliveryTestService } from '../services/delivertTest/deliveryTest'; +import { ControllerUtility } from './util'; import logger from '../logger'; -import DestinationPostTransformationService from '../services/destination/postTransformation'; +import { DestinationPostTransformationService } from '../services/destination/postTransformation'; import tags from '../v0/util/tags'; import { FixMe } from '../util/types'; -export default class DeliveryController { +export class DeliveryController { public static async deliverToDestination(ctx: Context) { logger.debug('Native(Delivery):: Request to transformer::', JSON.stringify(ctx.request.body)); let deliveryResponse: DeliveryResponse; diff --git a/src/controllers/destination.ts b/src/controllers/destination.ts index 60eac8a56c..71075d1b4c 100644 --- a/src/controllers/destination.ts +++ b/src/controllers/destination.ts @@ -1,22 +1,22 @@ import { Context } from 'koa'; -import MiscService from '../services/misc'; -import PreTransformationDestinationService from '../services/destination/preTransformation'; -import PostTransformationDestinationService from '../services/destination/postTransformation'; +import { MiscService } from '../services/misc'; +import { DestinationPreTransformationService } from '../services/destination/preTransformation'; +import { DestinationPostTransformationService } from '../services/destination/postTransformation'; import { ProcessorTransformationRequest, RouterTransformationRequest, ProcessorTransformationResponse, RouterTransformationResponse, } from '../types/index'; -import ServiceSelector from '../helpers/serviceSelector'; -import ControllerUtility from './util'; +import { ServiceSelector } from '../helpers/serviceSelector'; +import { ControllerUtility } from './util'; import stats from '../util/stats'; import logger from '../logger'; import { getIntegrationVersion } from '../util/utils'; import tags from '../v0/util/tags'; -import DynamicConfigParser from '../util/dynamicConfigParser'; +import { DynamicConfigParser } from '../util/dynamicConfigParser'; -export default class DestinationController { +export class DestinationController { public static async destinationTransformAtProcessor(ctx: Context) { const startTime = new Date(); logger.debug( @@ -36,7 +36,7 @@ export default class DestinationController { const integrationService = ServiceSelector.getDestinationService(events); try { integrationService.init(); - events = PreTransformationDestinationService.preProcess( + events = DestinationPreTransformationService.preProcess( events, ctx, ) as ProcessorTransformationRequest[]; @@ -59,7 +59,7 @@ export default class DestinationController { tags.FEATURES.PROCESSOR, ); metaTO.metadata = ev.metadata; - const errResp = PostTransformationDestinationService.handleProcessorTransformFailureEvents( + const errResp = DestinationPostTransformationService.handleProcessorTransformFailureEvents( error, metaTO, ); @@ -110,7 +110,7 @@ export default class DestinationController { const integrationService = ServiceSelector.getDestinationService(events); let resplist: RouterTransformationResponse[]; try { - events = PreTransformationDestinationService.preProcess(events, ctx); + events = DestinationPreTransformationService.preProcess(events, ctx); const timestampCorrectEvents = ControllerUtility.handleTimestampInEvents(events); events = DynamicConfigParser.process(timestampCorrectEvents); resplist = await integrationService.doRouterTransformation( @@ -127,7 +127,7 @@ export default class DestinationController { tags.FEATURES.ROUTER, ); metaTO.metadatas = events.map((ev) => ev.metadata); - const errResp = PostTransformationDestinationService.handleRouterTransformFailureEvents( + const errResp = DestinationPostTransformationService.handleRouterTransformFailureEvents( error, metaTO, ); @@ -165,7 +165,7 @@ export default class DestinationController { let events = routerRequest.input; const integrationService = ServiceSelector.getDestinationService(events); try { - events = PreTransformationDestinationService.preProcess(events, ctx); + events = DestinationPreTransformationService.preProcess(events, ctx); const timestampCorrectEvents = ControllerUtility.handleTimestampInEvents(events); const resplist = integrationService.doBatchTransformation( timestampCorrectEvents, @@ -182,7 +182,7 @@ export default class DestinationController { tags.FEATURES.BATCH, ); metaTO.metadatas = events.map((ev) => ev.metadata); - const errResp = PostTransformationDestinationService.handleBatchTransformFailureEvents( + const errResp = DestinationPostTransformationService.handleBatchTransformFailureEvents( error, metaTO, ); diff --git a/src/controllers/eventTest.ts b/src/controllers/eventTest.ts index 8888b63807..d5507f65d2 100644 --- a/src/controllers/eventTest.ts +++ b/src/controllers/eventTest.ts @@ -1,9 +1,9 @@ import { Context } from 'koa'; -import EventTesterService from '../services/eventTest/eventTester'; +import { EventTesterService } from '../services/eventTest/eventTester'; // eslint-disable-next-line @typescript-eslint/no-unused-vars import { CatchErr, FixMe } from '../util/types'; -export default class EventTestController { +export class EventTestController { private static API_VERSION = '1'; public static async testEvent(ctx: Context) { diff --git a/src/controllers/misc.ts b/src/controllers/misc.ts index 92ec33f80f..e2efdab5db 100644 --- a/src/controllers/misc.ts +++ b/src/controllers/misc.ts @@ -1,7 +1,7 @@ import { Context } from 'koa'; -import MiscService from '../services/misc'; +import { MiscService } from '../services/misc'; -export default class MiscController { +export class MiscController { public static healthStats(ctx: Context) { ctx.body = MiscService.getHealthInfo(); ctx.status = 200; diff --git a/src/controllers/profile.ts b/src/controllers/profile.ts index 984f4ac645..a0a62bf479 100644 --- a/src/controllers/profile.ts +++ b/src/controllers/profile.ts @@ -1,8 +1,8 @@ import { Context } from 'koa'; -import ProfileService from '../services/profile'; -import ControllerUtility from './util'; +import { ProfileService } from '../services/profile'; +import { ControllerUtility } from './util'; -export default class ProfileController { +export class ProfileController { /** * Example usage of API * diff --git a/src/controllers/regulation.ts b/src/controllers/regulation.ts index cefe1f748a..a50541780d 100644 --- a/src/controllers/regulation.ts +++ b/src/controllers/regulation.ts @@ -1,15 +1,14 @@ import { Context } from 'koa'; import logger from '../logger'; import { UserDeletionRequest, UserDeletionResponse } from '../types'; -import ServiceSelector from '../helpers/serviceSelector'; +import { ServiceSelector } from '../helpers/serviceSelector'; import tags from '../v0/util/tags'; import stats from '../util/stats'; -import PostTransformationDestinationService from '../services/destination/postTransformation'; +import { DestinationPostTransformationService } from '../services/destination/postTransformation'; // eslint-disable-next-line @typescript-eslint/no-unused-vars import { CatchErr } from '../util/types'; -// TODO: refactor this class to new format -export default class RegulationController { +export class RegulationController { public static async deleteUsers(ctx: Context) { logger.debug( 'Native(Process-Transform):: Requst to transformer::', @@ -44,7 +43,7 @@ export default class RegulationController { tags.FEATURES.USER_DELETION, ); // eslint-disable-next-line @typescript-eslint/no-unused-vars - const errResp = PostTransformationDestinationService.handleUserDeletionFailureEvents( + const errResp = DestinationPostTransformationService.handleUserDeletionFailureEvents( error, metaTO, ); diff --git a/src/controllers/source.ts b/src/controllers/source.ts index b1e7e8fe12..ef5483a756 100644 --- a/src/controllers/source.ts +++ b/src/controllers/source.ts @@ -1,11 +1,11 @@ import { Context } from 'koa'; -import MiscService from '../services/misc'; -import ServiceSelector from '../helpers/serviceSelector'; -import ControllerUtility from './util'; +import { MiscService } from '../services/misc'; +import { ServiceSelector } from '../helpers/serviceSelector'; +import { ControllerUtility } from './util'; import logger from '../logger'; -import PostTransformationServiceSource from '../services/source/postTransformation'; +import { SourcePostTransformationService } from '../services/source/postTransformation'; -export default class SourceController { +export class SourceController { public static async sourceTransform(ctx: Context) { logger.debug( 'Native(Source-Transform):: Request to transformer::', @@ -30,7 +30,7 @@ export default class SourceController { ctx.body = resplist; } catch (err: any) { const metaTO = integrationService.getTags(); - const resp = PostTransformationServiceSource.handleFailureEventsSource(err, metaTO); + const resp = SourcePostTransformationService.handleFailureEventsSource(err, metaTO); ctx.body = [resp]; } ControllerUtility.postProcess(ctx); diff --git a/src/controllers/trackingPlan.ts b/src/controllers/trackingPlan.ts index 66bf360700..74e47e0ec9 100644 --- a/src/controllers/trackingPlan.ts +++ b/src/controllers/trackingPlan.ts @@ -1,8 +1,8 @@ import { Context } from 'koa'; -import TrackingPlanservice from '../services/trackingPlan'; -import ControllerUtility from './util'; +import { TrackingPlanservice } from '../services/trackingPlan'; +import { ControllerUtility } from './util'; -export default class TrackingPlanController { +export class TrackingPlanController { public static async validateTrackingPlan(ctx: Context) { const events = ctx.request.body; const requestSize = Number(ctx.request.get('content-length')); diff --git a/src/controllers/userTransform.ts b/src/controllers/userTransform.ts index 6cbf578077..c344bd072a 100644 --- a/src/controllers/userTransform.ts +++ b/src/controllers/userTransform.ts @@ -1,15 +1,15 @@ import { Context } from 'koa'; import { ProcessorTransformationRequest, UserTransformationServiceResponse } from '../types/index'; -import UserTransformService from '../services/userTransform'; +import { UserTransformService } from '../services/userTransform'; import logger from '../logger'; import { setupUserTransformHandler, extractLibraries, validateCode, } from '../util/customTransformer'; -import ControllerUtility from './util'; +import { ControllerUtility } from './util'; -export default class UserTransformController { +export class UserTransformController { public static async transform(ctx: Context) { logger.debug( '(User transform - router:/customTransform ):: Request to transformer', diff --git a/src/controllers/util/index.test.ts b/src/controllers/util/index.test.ts index 0bc5f174b0..e23d3f6832 100644 --- a/src/controllers/util/index.test.ts +++ b/src/controllers/util/index.test.ts @@ -1,4 +1,4 @@ -import ControllerUtility from './index'; +import { ControllerUtility } from './index'; describe('adaptInputToVersion', () => { it('should return the input unchanged when the implementation version is not found', () => { diff --git a/src/controllers/util/index.ts b/src/controllers/util/index.ts index c52eb6899e..75d3d8ffa7 100644 --- a/src/controllers/util/index.ts +++ b/src/controllers/util/index.ts @@ -15,7 +15,7 @@ import { getValueFromMessage } from '../../v0/util'; import genericFieldMap from '../../v0/util/data/GenericFieldMapping.json'; import { EventType, MappedToDestinationKey } from '../../constants'; -export default class ControllerUtility { +export class ControllerUtility { private static sourceVersionMap: Map = new Map(); public static timestampValsMap: Record = { diff --git a/src/helpers/fetchHandlers.ts b/src/helpers/fetchHandlers.ts index 96a74e528d..ef7d9e6611 100644 --- a/src/helpers/fetchHandlers.ts +++ b/src/helpers/fetchHandlers.ts @@ -1,6 +1,6 @@ -import MiscService from '../services/misc'; +import { MiscService } from '../services/misc'; -export default class FetchHandler { +export class FetchHandler { private static sourceHandlerMap: Map = new Map(); private static destHandlerMap: Map = new Map(); diff --git a/src/helpers/serviceSelector.ts b/src/helpers/serviceSelector.ts index 891c21313d..89678e9407 100644 --- a/src/helpers/serviceSelector.ts +++ b/src/helpers/serviceSelector.ts @@ -1,16 +1,16 @@ import { PlatformError } from '@rudderstack/integrations-lib'; import { ProcessorTransformationRequest, RouterTransformationRequestData } from '../types/index'; import { INTEGRATION_SERVICE } from '../routes/utils/constants'; -import CDKV1DestinationService from '../services/destination/cdkV1Integration'; -import CDKV2DestinationService from '../services/destination/cdkV2Integration'; -import DestinationService from '../interfaces/DestinationService'; -import NativeIntegrationDestinationService from '../services/destination/nativeIntegration'; -import SourceService from '../interfaces/SourceService'; -import NativeIntegrationSourceService from '../services/source/nativeIntegration'; -import ComparatorService from '../services/comparator'; +import { CDKV1DestinationService } from '../services/destination/cdkV1Integration'; +import { CDKV2DestinationService } from '../services/destination/cdkV2Integration'; +import { DestinationService } from '../interfaces/DestinationService'; +import { NativeIntegrationDestinationService } from '../services/destination/nativeIntegration'; +import { SourceService } from '../interfaces/SourceService'; +import { NativeIntegrationSourceService } from '../services/source/nativeIntegration'; +import { ComparatorService } from '../services/comparator'; import { FixMe } from '../util/types'; -export default class ServiceSelector { +export class ServiceSelector { private static serviceMap: Map = new Map(); private static services = { diff --git a/src/index.ts b/src/index.ts index d1cc95cc36..36f32f1aed 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,8 +4,6 @@ import gracefulShutdown from 'http-graceful-shutdown'; import dotenv from 'dotenv'; import logger from './logger'; import cluster from './util/cluster'; -import { router } from './legacy/router'; -import { testRouter } from './testRouter'; import { metricsRouter } from './routes/metricsRouter'; import { addStatMiddleware, addRequestSizeMiddleware, initPyroscope } from './middleware'; import { logProcessInfo } from './util/utils'; @@ -14,7 +12,6 @@ import { RedisDB } from './util/redis/redisConnector'; dotenv.config(); const clusterEnabled = process.env.CLUSTER_ENABLED !== 'false'; -const useUpdatedRoutes = process.env.ENABLE_NEW_ROUTES !== 'false'; const port = parseInt(process.env.PORT ?? '9090', 10); const metricsPort = parseInt(process.env.METRICS_PORT || '9091', 10); @@ -35,15 +32,8 @@ app.use( addRequestSizeMiddleware(app); addSwaggerRoutes(app); -if (useUpdatedRoutes) { - logger.info('Using new routes'); - applicationRoutes(app); -} else { - // To be depricated - logger.info('Using old routes'); - app.use(router.routes()).use(router.allowedMethods()); - app.use(testRouter.routes()).use(testRouter.allowedMethods()); -} +logger.info('Using new routes'); +applicationRoutes(app); function finalFunction() { RedisDB.disconnect(); diff --git a/src/interfaces/DestinationService.ts b/src/interfaces/DestinationService.ts index 123da35292..b27f98da2a 100644 --- a/src/interfaces/DestinationService.ts +++ b/src/interfaces/DestinationService.ts @@ -10,7 +10,7 @@ import { UserDeletionResponse, } from '../types/index'; -export default interface DestinationService { +export interface DestinationService { getName(): string; init(): void; diff --git a/src/interfaces/SourceService.ts b/src/interfaces/SourceService.ts index 99b29f095b..c7de8cfe8b 100644 --- a/src/interfaces/SourceService.ts +++ b/src/interfaces/SourceService.ts @@ -1,6 +1,6 @@ import { MetaTransferObject, SourceTransformationResponse } from '../types/index'; -export default interface SourceService { +export interface SourceService { getTags(): MetaTransferObject; sourceTransformRoutine( diff --git a/src/middlewares/featureFlag.ts b/src/middlewares/featureFlag.ts index 146e57186c..206fa7c5ea 100644 --- a/src/middlewares/featureFlag.ts +++ b/src/middlewares/featureFlag.ts @@ -6,7 +6,7 @@ export interface FeatureFlags { export const FEATURE_FILTER_CODE = 'filter-code'; -export default class FeatureFlagMiddleware { +export class FeatureFlagMiddleware { public static async handle(ctx: Context, next: Next): Promise { // Initialize ctx.state.features if it doesn't exist ctx.state.features = (ctx.state.features || {}) as FeatureFlags; diff --git a/src/middlewares/routeActivation.ts b/src/middlewares/routeActivation.ts index dfdaef964e..ffb1e15e80 100644 --- a/src/middlewares/routeActivation.ts +++ b/src/middlewares/routeActivation.ts @@ -18,7 +18,7 @@ const destinationFilterList = process.env.DESTINATION_FILTER_LIST?.toLocaleLower const sourceFilteList = process.env.SOURCE_FILTER_LIST?.toLocaleLowerCase(); const deliveryFilterList = process.env.DESTINATION_DELIVERY_FILTER_LIST?.toLocaleLowerCase(); -export default class RouteActivationMiddleware { +export class RouteActivationMiddleware { private static executeActivationRule(ctx: Context, next: Next, shouldActivate: boolean) { if (shouldActivate) { return next(); diff --git a/src/routes/delivery.ts b/src/routes/delivery.ts index 141700fd9f..0591dc8b9e 100644 --- a/src/routes/delivery.ts +++ b/src/routes/delivery.ts @@ -1,6 +1,6 @@ import Router from '@koa/router'; -import DeliveryController from '../controllers/delivery'; -import RouteActivationMiddleware from '../middlewares/routeActivation'; +import { DeliveryController } from '../controllers/delivery'; +import { RouteActivationMiddleware } from '../middlewares/routeActivation'; const router = new Router(); diff --git a/src/routes/destination.ts b/src/routes/destination.ts index 3d4be42ff3..1c47825145 100644 --- a/src/routes/destination.ts +++ b/src/routes/destination.ts @@ -1,30 +1,30 @@ import Router from '@koa/router'; -import DestinationController from '../controllers/destination'; -import RegulationController from '../controllers/regulation'; -import FeatureFlagController from '../middlewares/featureFlag'; -import RouteActivationController from '../middlewares/routeActivation'; +import { DestinationController } from '../controllers/destination'; +import { RegulationController } from '../controllers/regulation'; +import { FeatureFlagMiddleware } from '../middlewares/featureFlag'; +import { RouteActivationMiddleware } from '../middlewares/routeActivation'; const router = new Router(); router.post( '/:version/destinations/:destination', - RouteActivationController.isDestinationRouteActive, - RouteActivationController.destinationProcFilter, - FeatureFlagController.handle, + RouteActivationMiddleware.isDestinationRouteActive, + RouteActivationMiddleware.destinationProcFilter, + FeatureFlagMiddleware.handle, DestinationController.destinationTransformAtProcessor, ); router.post( '/routerTransform', - RouteActivationController.isDestinationRouteActive, - RouteActivationController.destinationRtFilter, - FeatureFlagController.handle, + RouteActivationMiddleware.isDestinationRouteActive, + RouteActivationMiddleware.destinationRtFilter, + FeatureFlagMiddleware.handle, DestinationController.destinationTransformAtRouter, ); router.post( '/batch', - RouteActivationController.isDestinationRouteActive, - RouteActivationController.destinationBatchFilter, - FeatureFlagController.handle, + RouteActivationMiddleware.isDestinationRouteActive, + RouteActivationMiddleware.destinationBatchFilter, + FeatureFlagMiddleware.handle, DestinationController.batchProcess, ); diff --git a/src/routes/misc.ts b/src/routes/misc.ts index 750c1194dd..4d1c5d5fb5 100644 --- a/src/routes/misc.ts +++ b/src/routes/misc.ts @@ -1,6 +1,6 @@ import Router from '@koa/router'; -import ProfileController from '../controllers/profile'; -import MiscController from '../controllers/misc'; +import { ProfileController } from '../controllers/profile'; +import { MiscController } from '../controllers/misc'; const router = new Router(); diff --git a/src/routes/source.ts b/src/routes/source.ts index ade26c8700..1abc46e2e4 100644 --- a/src/routes/source.ts +++ b/src/routes/source.ts @@ -1,13 +1,13 @@ import Router from '@koa/router'; -import RouteActivationController from '../middlewares/routeActivation'; -import SourceController from '../controllers/source'; +import { RouteActivationMiddleware } from '../middlewares/routeActivation'; +import { SourceController } from '../controllers/source'; const router = new Router(); router.post( '/:version/sources/:source', - RouteActivationController.isSourceRouteActive, - RouteActivationController.sourceFilter, + RouteActivationMiddleware.isSourceRouteActive, + RouteActivationMiddleware.sourceFilter, SourceController.sourceTransform, ); diff --git a/src/routes/testEvents.ts b/src/routes/testEvents.ts index 556ec10198..a35fe447ba 100644 --- a/src/routes/testEvents.ts +++ b/src/routes/testEvents.ts @@ -1,5 +1,5 @@ import Router from '@koa/router'; -import EventTestController from '../controllers/eventTest'; +import { EventTestController } from '../controllers/eventTest'; const router = new Router({ prefix: '/test-router' }); diff --git a/src/routes/trackingPlan.ts b/src/routes/trackingPlan.ts index d177af7b2c..3e62ba2a74 100644 --- a/src/routes/trackingPlan.ts +++ b/src/routes/trackingPlan.ts @@ -1,5 +1,5 @@ import Router from '@koa/router'; -import TrackingPlanController from '../controllers/trackingPlan'; +import { TrackingPlanController } from '../controllers/trackingPlan'; const router = new Router(); diff --git a/src/routes/userTransform.ts b/src/routes/userTransform.ts index 23870db3b4..1fb8ad3a1c 100644 --- a/src/routes/userTransform.ts +++ b/src/routes/userTransform.ts @@ -1,34 +1,34 @@ import Router from '@koa/router'; -import RouteActivationController from '../middlewares/routeActivation'; -import FeatureFlagController from '../middlewares/featureFlag'; -import UserTransformController from '../controllers/userTransform'; +import { RouteActivationMiddleware } from '../middlewares/routeActivation'; +import { FeatureFlagMiddleware } from '../middlewares/featureFlag'; +import { UserTransformController } from '../controllers/userTransform'; const router = new Router(); router.post( '/customTransform', - RouteActivationController.isUserTransformRouteActive, - FeatureFlagController.handle, + RouteActivationMiddleware.isUserTransformRouteActive, + FeatureFlagMiddleware.handle, UserTransformController.transform, ); router.post( '/transformation/test', - RouteActivationController.isUserTransformTestRouteActive, + RouteActivationMiddleware.isUserTransformTestRouteActive, UserTransformController.testTransform, ); router.post( '/transformationLibrary/test', - RouteActivationController.isUserTransformTestRouteActive, + RouteActivationMiddleware.isUserTransformTestRouteActive, UserTransformController.testTransformLibrary, ); router.post( '/transformation/sethandle', - RouteActivationController.isUserTransformTestRouteActive, + RouteActivationMiddleware.isUserTransformTestRouteActive, UserTransformController.testTransformSethandle, ); router.post( '/extractLibs', - RouteActivationController.isUserTransformRouteActive, + RouteActivationMiddleware.isUserTransformRouteActive, UserTransformController.extractLibhandle, ); diff --git a/src/services/comparator.ts b/src/services/comparator.ts index 3495b7bbfd..7f63da9402 100644 --- a/src/services/comparator.ts +++ b/src/services/comparator.ts @@ -1,5 +1,5 @@ /* eslint-disable class-methods-use-this */ -import IntegrationDestinationService from '../interfaces/DestinationService'; +import { DestinationService } from '../interfaces/DestinationService'; import { DeliveryResponse, Destination, @@ -20,15 +20,12 @@ import { CommonUtils } from '../util/common'; const NS_PER_SEC = 1e9; -export default class ComparatorService implements IntegrationDestinationService { - secondaryService: IntegrationDestinationService; +export class ComparatorService implements DestinationService { + secondaryService: DestinationService; - primaryService: IntegrationDestinationService; + primaryService: DestinationService; - constructor( - primaryService: IntegrationDestinationService, - secondaryService: IntegrationDestinationService, - ) { + constructor(primaryService: DestinationService, secondaryService: DestinationService) { this.primaryService = primaryService; this.secondaryService = secondaryService; } diff --git a/src/services/delivertTest/deliveryTest.ts b/src/services/delivertTest/deliveryTest.ts index e5713073c1..0d960ade17 100644 --- a/src/services/delivertTest/deliveryTest.ts +++ b/src/services/delivertTest/deliveryTest.ts @@ -7,7 +7,7 @@ import stats from '../../util/stats'; import logger from '../../logger'; import tags from '../../v0/util/tags'; -export default class DeliveryTestService { +export class DeliveryTestService { public static async doTestDelivery( destination: string, routerDestReqPayload: any, diff --git a/src/services/destination/cdkV1Integration.ts b/src/services/destination/cdkV1Integration.ts index 2f655fca9b..8ccd3341e5 100644 --- a/src/services/destination/cdkV1Integration.ts +++ b/src/services/destination/cdkV1Integration.ts @@ -2,7 +2,7 @@ import { ConfigFactory, Executor, RudderBaseConfig } from 'rudder-transformer-cdk'; import path from 'path'; import { TransformationError } from '@rudderstack/integrations-lib'; -import IntegrationDestinationService from '../../interfaces/DestinationService'; +import { DestinationService } from '../../interfaces/DestinationService'; import { DeliveryResponse, ErrorDetailer, @@ -15,12 +15,12 @@ import { UserDeletionRequest, UserDeletionResponse, } from '../../types/index'; -import DestinationPostTransformationService from './postTransformation'; +import { DestinationPostTransformationService } from './postTransformation'; import tags from '../../v0/util/tags'; import { getErrorInfo } from '../../cdk/v1/handler'; import { CatchErr } from '../../util/types'; -export default class CDKV1DestinationService implements IntegrationDestinationService { +export class CDKV1DestinationService implements DestinationService { public init() { ConfigFactory.init({ basePath: path.resolve(__dirname, '../../cdk/v1'), diff --git a/src/services/destination/cdkV2Integration.ts b/src/services/destination/cdkV2Integration.ts index bc5a1126a8..e333d4544e 100644 --- a/src/services/destination/cdkV2Integration.ts +++ b/src/services/destination/cdkV2Integration.ts @@ -3,7 +3,7 @@ import groupBy from 'lodash/groupBy'; import { TransformationError } from '@rudderstack/integrations-lib'; import { processCdkV2Workflow } from '../../cdk/v2/handler'; -import IntegrationDestinationService from '../../interfaces/DestinationService'; +import { DestinationService } from '../../interfaces/DestinationService'; import { DeliveryResponse, ErrorDetailer, @@ -17,11 +17,11 @@ import { UserDeletionResponse, } from '../../types/index'; import tags from '../../v0/util/tags'; -import DestinationPostTransformationService from './postTransformation'; +import { DestinationPostTransformationService } from './postTransformation'; import stats from '../../util/stats'; import { CatchErr } from '../../util/types'; -export default class CDKV2DestinationService implements IntegrationDestinationService { +export class CDKV2DestinationService implements DestinationService { public init() {} public getName(): string { diff --git a/src/services/destination/nativeIntegration.ts b/src/services/destination/nativeIntegration.ts index a788b388e4..6763f54c7e 100644 --- a/src/services/destination/nativeIntegration.ts +++ b/src/services/destination/nativeIntegration.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ import groupBy from 'lodash/groupBy'; import cloneDeep from 'lodash/cloneDeep'; -import IntegrationDestinationService from '../../interfaces/DestinationService'; +import { DestinationService } from '../../interfaces/DestinationService'; import { DeliveryResponse, ErrorDetailer, @@ -14,12 +14,12 @@ import { UserDeletionRequest, UserDeletionResponse, } from '../../types/index'; -import DestinationPostTransformationService from './postTransformation'; +import { DestinationPostTransformationService } from './postTransformation'; import networkHandlerFactory from '../../adapters/networkHandlerFactory'; -import FetchHandler from '../../helpers/fetchHandlers'; +import { FetchHandler } from '../../helpers/fetchHandlers'; import tags from '../../v0/util/tags'; -export default class NativeIntegrationDestinationService implements IntegrationDestinationService { +export class NativeIntegrationDestinationService implements DestinationService { public init() {} public getName(): string { diff --git a/src/services/destination/postTransformation.ts b/src/services/destination/postTransformation.ts index 090e39b059..0b91eb7cc1 100644 --- a/src/services/destination/postTransformation.ts +++ b/src/services/destination/postTransformation.ts @@ -12,11 +12,11 @@ import { UserDeletionResponse, } from '../../types/index'; import { generateErrorObject } from '../../v0/util'; -import ErrorReportingService from '../errorReporting'; +import { ErrorReportingService } from '../errorReporting'; import tags from '../../v0/util/tags'; import stats from '../../util/stats'; -export default class DestinationPostTransformationService { +export class DestinationPostTransformationService { public static handleProcessorTransformSucessEvents( event: ProcessorTransformationRequest, transformedPayloads: ProcessorTransformationOutput | ProcessorTransformationOutput[], diff --git a/src/services/destination/preTransformation.ts b/src/services/destination/preTransformation.ts index dd5579b7b9..db1d76d64e 100644 --- a/src/services/destination/preTransformation.ts +++ b/src/services/destination/preTransformation.ts @@ -1,7 +1,7 @@ import { Context } from 'koa'; import { ProcessorTransformationRequest, RouterTransformationRequestData } from '../../types/index'; -export default class PreTransformationDestinationService { +export class DestinationPreTransformationService { public static preProcess( events: ProcessorTransformationRequest[] | RouterTransformationRequestData[], ctx: Context, diff --git a/src/services/errorReporting.ts b/src/services/errorReporting.ts index 2d3c84ff30..3a4276f978 100644 --- a/src/services/errorReporting.ts +++ b/src/services/errorReporting.ts @@ -1,6 +1,6 @@ import { client } from '../util/errorNotifier'; -export default class ErrorReportingService { +export class ErrorReportingService { public static reportError(error: NonNullable, context: string, errorResp: object) { client.notify(error, context, { ...errorResp, diff --git a/src/services/eventTest/eventTester.ts b/src/services/eventTest/eventTester.ts index a3755d3e80..75df29cc63 100644 --- a/src/services/eventTest/eventTester.ts +++ b/src/services/eventTest/eventTester.ts @@ -1,7 +1,7 @@ import { sendToDestination, userTransformHandler } from '../../routerUtils'; import { FixMe } from '../../util/types'; -export default class EventTesterService { +export class EventTesterService { private static getDestHandler(version, destination) { // eslint-disable-next-line global-require, import/no-dynamic-require return require(`../../${version}/destinations/${destination}/transform`); diff --git a/src/services/misc.ts b/src/services/misc.ts index 4c3e2ae6da..e0953d08bf 100644 --- a/src/services/misc.ts +++ b/src/services/misc.ts @@ -6,7 +6,7 @@ import { DestHandlerMap } from '../constants/destinationCanonicalNames'; import { Metadata } from '../types'; import { getCPUProfile, getHeapProfile } from '../middleware'; -export default class MiscService { +export class MiscService { public static getDestHandler(dest: string, version: string) { if (DestHandlerMap.hasOwnProperty(dest)) { return require(`../${version}/destinations/${DestHandlerMap[dest]}/transform`); diff --git a/src/services/profile.ts b/src/services/profile.ts index 4d7a7104e7..d71826e251 100644 --- a/src/services/profile.ts +++ b/src/services/profile.ts @@ -22,7 +22,7 @@ logger.info(`Interval Bytes set: ${intervalBytes}`); heap.start(intervalBytes, stackDepth); -export default class ProfileService { +export class ProfileService { private static async promisifiedRead(readable: any) { // eslint-disable-next-line no-new new Promise((resolve, reject) => { diff --git a/src/services/source/nativeIntegration.ts b/src/services/source/nativeIntegration.ts index 22783db049..6eaef2f835 100644 --- a/src/services/source/nativeIntegration.ts +++ b/src/services/source/nativeIntegration.ts @@ -1,4 +1,4 @@ -import IntegrationSourceService from '../../interfaces/SourceService'; +import { SourceService } from '../../interfaces/SourceService'; import { ErrorDetailer, MetaTransferObject, @@ -6,12 +6,12 @@ import { SourceTransformationResponse, } from '../../types/index'; import { FixMe } from '../../util/types'; -import PostTransformationServiceSource from './postTransformation'; -import FetchHandler from '../../helpers/fetchHandlers'; +import { SourcePostTransformationService } from './postTransformation'; +import { FetchHandler } from '../../helpers/fetchHandlers'; import tags from '../../v0/util/tags'; import stats from '../../util/stats'; -export default class NativeIntegrationSourceService implements IntegrationSourceService { +export class NativeIntegrationSourceService implements SourceService { public getTags(): MetaTransferObject { const metaTO = { errorDetails: { @@ -38,14 +38,14 @@ export default class NativeIntegrationSourceService implements IntegrationSource try { const respEvents: RudderMessage | RudderMessage[] | SourceTransformationResponse = await sourceHandler.process(sourceEvent); - return PostTransformationServiceSource.handleSuccessEventsSource(respEvents); + return SourcePostTransformationService.handleSuccessEventsSource(respEvents); } catch (error: FixMe) { const metaTO = this.getTags(); stats.increment('source_transform_errors', { source: sourceType, version, }); - return PostTransformationServiceSource.handleFailureEventsSource(error, metaTO); + return SourcePostTransformationService.handleFailureEventsSource(error, metaTO); } }), ); diff --git a/src/services/source/postTransformation.ts b/src/services/source/postTransformation.ts index f732cac3a7..20c815171b 100644 --- a/src/services/source/postTransformation.ts +++ b/src/services/source/postTransformation.ts @@ -1,9 +1,9 @@ import { MetaTransferObject, RudderMessage, SourceTransformationResponse } from '../../types/index'; import { CatchErr } from '../../util/types'; import { generateErrorObject } from '../../v0/util'; -import ErrorReportingService from '../errorReporting'; +import { ErrorReportingService } from '../errorReporting'; -export default class PostTransformationSourceService { +export class SourcePostTransformationService { public static handleFailureEventsSource( error: CatchErr, metaTO: MetaTransferObject, diff --git a/src/services/trackingPlan.ts b/src/services/trackingPlan.ts index 35f21320a5..2e68df55e9 100644 --- a/src/services/trackingPlan.ts +++ b/src/services/trackingPlan.ts @@ -4,7 +4,7 @@ import { getMetadata } from '../v0/util'; import eventValidator from '../util/eventValidation'; import stats from '../util/stats'; -export default class TrackingPlanservice { +export class TrackingPlanservice { public static async validateTrackingPlan(events, requestSize, reqParams) { const requestStartTime = new Date(); const respList: any[] = []; diff --git a/src/services/userTransform.ts b/src/services/userTransform.ts index 4fe1ad0b52..ddd5c82f67 100644 --- a/src/services/userTransform.ts +++ b/src/services/userTransform.ts @@ -24,7 +24,7 @@ import { CatchErr, FixMe } from '../util/types'; import { FeatureFlags, FEATURE_FILTER_CODE } from '../middlewares/featureFlag'; import { HTTP_CUSTOM_STATUS_CODES } from '../constants'; -export default class UserTransformService { +export class UserTransformService { public static async transformRoutine( events: ProcessorTransformationRequest[], features: FeatureFlags = {}, diff --git a/src/util/dynamicConfigParser.ts b/src/util/dynamicConfigParser.ts index 73ad85a0d2..6de2e38f94 100644 --- a/src/util/dynamicConfigParser.ts +++ b/src/util/dynamicConfigParser.ts @@ -6,7 +6,7 @@ import { FixMe } from './types'; const get = require('get-value'); const unset = require('unset-value'); -export default class DynamicConfigParser { +export class DynamicConfigParser { private static getDynamicConfigValue( event: ProcessorTransformationRequest | RouterTransformationRequestData, value: FixMe, diff --git a/src/v0/destinations/hs/util.js b/src/v0/destinations/hs/util.js index 72025997d2..f83ce0b6de 100644 --- a/src/v0/destinations/hs/util.js +++ b/src/v0/destinations/hs/util.js @@ -607,7 +607,8 @@ const splitEventsForCreateUpdate = async (inputs, destination) => { const { destinationExternalId } = getDestinationExternalIDInfoForRetl(message, DESTINATION); const filteredInfo = updateHubspotIds.filter( - (update) => update.property.toString().toLowerCase() === destinationExternalId.toString().toLowerCase(), + (update) => + update.property.toString().toLowerCase() === destinationExternalId.toString().toLowerCase(), ); if (filteredInfo.length > 0) { diff --git a/src/v0/sources/shopify/util.js b/src/v0/sources/shopify/util.js index 1da75cba3d..61501bdab6 100644 --- a/src/v0/sources/shopify/util.js +++ b/src/v0/sources/shopify/util.js @@ -32,7 +32,10 @@ const getDataFromRedis = async (key, metricMetadata) => { ...metricMetadata, }); const redisData = await RedisDB.getVal(key); - if (redisData === null || (typeof redisData === "object" && Object.keys(redisData).length === 0)) { + if ( + redisData === null || + (typeof redisData === 'object' && Object.keys(redisData).length === 0) + ) { stats.increment('shopify_redis_no_val', { ...metricMetadata, }); diff --git a/test/__tests__/data/sanity/active_campaign_output.json b/test/__tests__/data/sanity/active_campaign_output.json deleted file mode 100644 index 544f9b937f..0000000000 --- a/test/__tests__/data/sanity/active_campaign_output.json +++ /dev/null @@ -1,54 +0,0 @@ -[ - { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://active.campaigns.rudder.com/api/3/contact/sync", - "headers": { - "Content-Type": "application/json", - "Api-Token": "dummyApiToken" - }, - "params": {}, - "body": { - "JSON": { - "contact": { - "email": "manashi@gmail.com", - "phone": 9090909000, - "firstName": null, - "lastName": null - }, - "apiKey": "dummyApiKey" - }, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {} - }, - { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://active.campaigns.rudder.com/api/3/contact/sync", - "headers": { - "Content-Type": "application/json", - "Api-Token": "dummyApiToken" - }, - "params": {}, - "body": { - "JSON": { - "contact": { - "email": "testkolkata@rudderlabs.com", - "phone": "570-690-4150", - "firstName": "Sajal", - "lastName": "Mohanta" - }, - "apiKey": "dummyApiKey" - }, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {} - } -] diff --git a/test/__tests__/data/sanity/destination_config.json b/test/__tests__/data/sanity/destination_config.json deleted file mode 100644 index 11c999aa9c..0000000000 --- a/test/__tests__/data/sanity/destination_config.json +++ /dev/null @@ -1,102 +0,0 @@ -{ - "active_campaign": { - "config": { - "processor": { - "Config": { - "apiKey": "dummyApiKey", - "apiUrl": "https://active.campaigns.rudder.com", - "actid": "476550467", - "eventKey": "f8a866fddc721350fdc2fbbd2e5c43a6dddaaa03" - } - } - } - }, - "clevertap": { - "config": { - "processor": {}, - "router": {} - } - }, - "marketo": { - "config": { - "router": { - "Config": { - "accountId": "marketo_acct_id_success", - "clientId": "marketo_client_id_success", - "clientSecret": "marketo_client_secret_success", - "trackAnonymousEvents": true, - "customActivityEventMap": [{ "from": "Product Clicked", "to": "100001" }], - "customActivityPropertyMap": [{ "from": "name", "to": "productName" }], - "customActivityPrimaryKeyMap": [{ "from": "Product Clicked", "to": "name" }], - "leadTraitMapping": [{ "from": "leadScore", "to": "customLeadScore" }] - }, - "secretConfig": {}, - "ID": "1mMy5cqbtfuaKZv1IhVQKnBdVwe", - "name": "Marketo", - "enabled": true, - "workspaceId": "1TSN08muJTZwH8iCDmnnRt1pmLd", - "deleted": false, - "createdAt": "2020-12-30T08:39:32.005Z", - "updatedAt": "2021-02-03T16:22:31.374Z", - "destinationDefinition": { - "config": { - "destConfig": { - "defaultConfig": [ - "accountId", - "clientId", - "clientSecret", - "trackAnonymousEvents", - "customActivityEventMap", - "customActivityPropertyMap", - "customActivityPrimaryKeyMap", - "leadTraitMapping" - ] - }, - "secretKeys": ["clientSecret"], - "excludeKeys": [], - "includeKeys": [], - "routerTransform": true, - "supportedSourceTypes": [ - "android", - "ios", - "web", - "unity", - "amp", - "cloud", - "reactnative" - ] - }, - "responseRules": { - "responseType": "JSON", - "rules": { - "retryable": [ - { "success": "false", "errors.0.code": 600 }, - { "success": "false", "errors.0.code": 601 }, - { "success": "false", "errors.0.code": 602 }, - { "success": "false", "errors.0.code": 604 }, - { "success": "false", "errors.0.code": 606 }, - { "success": "false", "errors.0.code": 607 }, - { "success": "false", "errors.0.code": 608 }, - { "success": "false", "errors.0.code": 611 } - ], - "abortable": [ - { "success": "false", "errors.0.code": 603 }, - { "success": "false", "errors.0.code": 605 }, - { "success": "false", "errors.0.code": 609 }, - { "success": "false", "errors.0.code": 610 } - ] - } - }, - "id": "1aIXqM806xAVm92nx07YwKbRrO9", - "name": "MARKETO", - "displayName": "Marketo", - "createdAt": "2020-04-09T09:24:31.794Z", - "updatedAt": "2021-01-11T11:03:28.103Z" - }, - "transformations": [], - "isConnectionEnabled": true, - "isProcessorEnabled": true - } - } - } -} diff --git a/test/__tests__/data/sanity/marketo_router_output.json b/test/__tests__/data/sanity/marketo_router_output.json deleted file mode 100644 index 9f967074a3..0000000000 --- a/test/__tests__/data/sanity/marketo_router_output.json +++ /dev/null @@ -1,165 +0,0 @@ -[ - { - "batchedRequest": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://marketo_acct_id_success.mktorest.com/rest/v1/activities/external.json", - "headers": { - "Authorization": "Bearer access_token_success", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "input": [ - { - "activityDate": "2020-12-17T21:00:59.176Z", - "activityTypeId": 100001, - "attributes": [], - "leadId": 4, - "primaryAttributeValue": "Test Product" - } - ] - }, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {} - }, - "metadata": [ - { - "jobId": 1 - } - ], - "batched": false, - "statusCode": 200, - "destination": { - "Config": { - "accountId": "marketo_acct_id_success", - "clientId": "marketo_client_id_success", - "clientSecret": "marketo_client_secret_success", - "trackAnonymousEvents": true, - "customActivityEventMap": [ - { - "from": "Product Clicked", - "to": "100001" - } - ], - "customActivityPropertyMap": [ - { - "from": "name", - "to": "productName" - } - ], - "customActivityPrimaryKeyMap": [ - { - "from": "Product Clicked", - "to": "name" - } - ], - "leadTraitMapping": [ - { - "from": "leadScore", - "to": "customLeadScore" - } - ] - }, - "secretConfig": {}, - "ID": "1mMy5cqbtfuaKZv1IhVQKnBdVwe", - "name": "Marketo", - "enabled": true, - "workspaceId": "1TSN08muJTZwH8iCDmnnRt1pmLd", - "deleted": false, - "createdAt": "2020-12-30T08:39:32.005Z", - "updatedAt": "2021-02-03T16:22:31.374Z", - "destinationDefinition": { - "config": { - "destConfig": { - "defaultConfig": [ - "accountId", - "clientId", - "clientSecret", - "trackAnonymousEvents", - "customActivityEventMap", - "customActivityPropertyMap", - "customActivityPrimaryKeyMap", - "leadTraitMapping" - ] - }, - "secretKeys": ["clientSecret"], - "excludeKeys": [], - "includeKeys": [], - "routerTransform": true, - "supportedSourceTypes": ["android", "ios", "web", "unity", "amp", "cloud", "reactnative"] - }, - "responseRules": { - "responseType": "JSON", - "rules": { - "retryable": [ - { - "success": "false", - "errors.0.code": 600 - }, - { - "success": "false", - "errors.0.code": 601 - }, - { - "success": "false", - "errors.0.code": 602 - }, - { - "success": "false", - "errors.0.code": 604 - }, - { - "success": "false", - "errors.0.code": 606 - }, - { - "success": "false", - "errors.0.code": 607 - }, - { - "success": "false", - "errors.0.code": 608 - }, - { - "success": "false", - "errors.0.code": 611 - } - ], - "abortable": [ - { - "success": "false", - "errors.0.code": 603 - }, - { - "success": "false", - "errors.0.code": 605 - }, - { - "success": "false", - "errors.0.code": 609 - }, - { - "success": "false", - "errors.0.code": 610 - } - ] - } - }, - "id": "1aIXqM806xAVm92nx07YwKbRrO9", - "name": "MARKETO", - "displayName": "Marketo", - "createdAt": "2020-04-09T09:24:31.794Z", - "updatedAt": "2021-01-11T11:03:28.103Z" - }, - "transformations": [], - "isConnectionEnabled": true, - "isProcessorEnabled": true - } - } -] diff --git a/test/__tests__/data/sanity/sanity_input.json b/test/__tests__/data/sanity/sanity_input.json deleted file mode 100644 index 9dd9961160..0000000000 --- a/test/__tests__/data/sanity/sanity_input.json +++ /dev/null @@ -1,185 +0,0 @@ -{ - "messages": [ - { - "type": "identify", - "event": "identify", - "sentAt": "2021-02-08T12:45:42.760Z", - "userId": "User_111", - "channel": "mobile", - "context": { - "os": { - "name": "iOS", - "version": "13.0" - }, - "app": { - "name": "MyApp", - "build": "1", - "version": "1.0", - "namespace": "com.rudderlabs.MyApp" - }, - "device": { - "id": "e2b94e2d-8327-429c-9d91-792a80d189c8", - "name": "iPhone 11 Pro Max", - "type": "iOS", - "model": "iPhone", - "manufacturer": "Apple" - }, - "locale": "en-US", - "screen": { - "width": 896, - "height": 414, - "density": 3 - }, - "traits": { - "age": 24, - "city": "Bangalore", - "name": "Manashi Mazumder", - "email": "manashi@gmail.com", - "phone": 9090909000, - "userId": "User_111", - "anonymousId": "e2b94e2d-8327-429c-9d91-792a80d189c8" - }, - "library": { - "name": "rudder-ios-library", - "version": "1.0.11" - }, - "network": { - "wifi": true, - "carrier": "unavailable", - "cellular": false, - "bluetooth": false - }, - "timezone": "Asia/Kolkata", - "userAgent": "unknown" - }, - "rudderId": "139d65bb-8a40-48c7-854c-06bbf44f686e", - "messageId": "1612788330-7e1e60a8-fb7e-437d-81c1-5b000318d0cb", - "anonymousId": "e2b94e2d-8327-429c-9d91-792a80d189c8", - "integrations": { - "All": true - }, - "originalTimestamp": "2021-02-08T12:45:30.717Z" - }, - { - "type": "identify", - "sentAt": "2021-04-15T19:43:53.393Z", - "userId": "sajal1234", - "channel": "web", - "context": { - "id": "ID101", - "ip": "0.0.0.0", - "os": { - "name": "", - "version": "" - }, - "app": { - "name": "RudderLabs JavaScript SDK", - "build": "1.0.0", - "version": "1.1.17", - "namespace": "com.rudderlabs.javascript" - }, - "page": { - "url": "www.rudderstack.com", - "path": "/path5", - "title": "JS Test", - "search": "My Page", - "tab_url": "https://odd-rat-19.loca.lt/Rectified.html", - "referrer": "www.google.com", - "initial_referrer": "$direct", - "referring_domain": "", - "initial_referring_domain": "" - }, - "event": "Sample Identify call", - "locale": "en-US", - "screen": { - "density": 2.75 - }, - "traits": { - "id": "ID101", - "city": "east greenwich", - "plan": "Open source", - "tags": ["x0002x", "y0004y", "t0001t"], - "email": "testkolkata@rudderlabs.com", - "event": "Sample Identify call", - "lists": [ - { - "id": 2, - "status": "unsubscribed" - }, - { - "id": 3, - "status": "unsubscribe" - } - ], - "phone": "570-690-4150", - "state": "RI", - "title": "Mr", - "logins": 5, - "mobile": "123456786", - "rating": "Hot", - "street": "19123 forest lane", - "company": { - "id": 378763009439, - "name": "Rudderlabs", - "industry": "IT", - "employee_count": 1200 - }, - "country": "USA", - "sent_at": "20210109134567", - "birthDay": "2021/04/15", - "category": "SampleIdentify", - "industry": "ITES", - "lastName": "Mohanta", - "timezone": "Berlin", - "Homephone": 9836543283, - "createdAt": "2021/04/15", - "fieldInfo": { - "state": "California", - "Address": "kolkata", - "listBox": ["Option1", "Option2"], - "CheckBox": ["Option1", "Option2", "Option3"], - "TextArea": "This is a sample text area field value . it is tested for Active Campaign. It should have more than 100 words. Lorem ipsum is a dummy sentence to fill up any area. And also , it is used to fill up dummy website. So, it is wriiten by simply wasting time. ", - "DateField": "1988-12-05", - "HiddenField": "Hidden", - "RadioButton": "Option1", - "multiChoice": "Option 1", - "DateTimeField": "2020-05-19T02:45:00-05:00" - }, - "firstName": "Sajal", - "isEnabled": true, - "timestamp": "1403743443", - "event_text": "identify", - "leadSource": "WEB", - "postalCode": "94115", - "received_at": "202101091347654", - "organizationId": 378763009439, - "original_timestamp": "1403743443" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "1.1.17" - }, - "sent_at": "20210109134567", - "campaign": {}, - "timestamp": "1403743443", - "userAgent": "Mozilla/5.0 (Linux; Android 11; sdk_gphone_x86_arm Build/RSR1.201013.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/83.0.4103.106 Mobile Safari/537.36", - "event_text": "identify", - "externalId": [ - { - "id": "0035g000002XN5MAAW", - "type": "Salesforce-Contact" - } - ], - "received_at": "202101091347654", - "original_timestamp": "1403743443" - }, - "rudderId": "bc2402b7-6796-4fa5-9beb-bad3761fc961", - "messageId": "9d0df235-d354-4a81-8056-07dcb58081d7", - "anonymousId": "anonIDfromAndroid", - "integrations": { - "All": true - }, - "originalTimestamp": "2021-04-15T19:43:53.392Z" - } - ] -} diff --git a/test/__tests__/data/sanity/sanity_router_input.json b/test/__tests__/data/sanity/sanity_router_input.json deleted file mode 100644 index 16b8ccffad..0000000000 --- a/test/__tests__/data/sanity/sanity_router_input.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "messages": [ - { - "anonymousId": "anon_id_success", - "channel": "mobile", - "context": { - "app": { - "build": "1", - "name": "TestAppName", - "namespace": "com.android.sample", - "version": "1.0" - }, - "device": { - "id": "anon_id_success", - "manufacturer": "Google", - "model": "Android SDK built for x86", - "name": "generic_x86", - "type": "android" - }, - "library": { - "name": "com.rudderstack.android.sdk.core", - "version": "1.0.1-beta.1" - }, - "locale": "en-US", - "network": { - "carrier": "Android", - "bluetooth": false, - "cellular": true, - "wifi": true - }, - "os": { - "name": "Android", - "version": "8.1.0" - }, - "screen": { - "density": 420, - "height": 1794, - "width": 1080 - }, - "timezone": "Asia/Kolkata", - "traits": { - "anonymousId": "anon_id_success" - }, - "userAgent": "Dalvik/2.1.0 (Linux; U; Android 8.1.0; Android SDK built for x86 Build/OSM1.180201.007)" - }, - "event": "Product Clicked", - "integrations": { - "All": true - }, - "messageId": "id1", - "properties": { - "name": "Test Product" - }, - "originalTimestamp": "2020-12-17T21:00:59.176Z", - "type": "track", - "sentAt": "2020-03-12T09:05:03.421Z" - } - ] -} diff --git a/test/__tests__/legacyRouter.test.ts b/test/__tests__/legacyRouter.test.ts index 768db08ca8..926f6e76d4 100644 --- a/test/__tests__/legacyRouter.test.ts +++ b/test/__tests__/legacyRouter.test.ts @@ -1,6 +1,6 @@ import fs from 'fs'; import path from 'path'; -import DestinationController from '../../src/controllers/destination'; +import { DestinationController } from '../../src/controllers/destination'; const destArg = process.argv.filter((x) => x.startsWith('--destName='))[0]; // send arguments on which destination const typeArg = process.argv.filter((x) => x.startsWith('--type='))[0]; // send argument on which function diff --git a/test/__tests__/sanity.test.js b/test/__tests__/sanity.test.js deleted file mode 100644 index ae5faa917c..0000000000 --- a/test/__tests__/sanity.test.js +++ /dev/null @@ -1,204 +0,0 @@ -jest.mock("axios"); -const name = "Sanity"; -const fs = require("fs"); -const path = require("path"); -const version = "v0"; -const { getDirectories } = require("./util"); -const { mockaxios } = require("../__mocks__/network"); - -// ******************************** -// Getting Started -// ******************************** -// sanity-folder-structure -// __tests__ -// | -// |--sanity.test.js -// |--data -// | | -// | |--sanity -// | | -// | {integration(s)}_output.json -// | {integration(s)}_router_output.json -// | sanity_input.json -// | sanity_router_input.json -// | destination_config.json - -// ------ destination_config.json ------ -// JSON to store the destination-config of all the destinations -// Each destination-config object has a config object storing the -// processor/ router (transform-at) configs -// ------------------------------------- -// If transformation is only done at processor -// only use the processor as key and store the -// destination definition as value. -// -// Format : -// { -// "clevertap": { -// "config": { -// "processor": { ...destination_definition }, -// "router": { ...destination_definition } -// } -// } -// .. -// .. -// } - -// ----- sanity_input.json ----- -// JSON to store the sanity input messages which will be -// used to test sanity for all the destination. -// -// Format: -// { -// "messages": [ -// { sanity_input_message_1}, -// { sanity_input_message_2}, -// { sanity_input_message_3} -// ... -// ] -// } - -// ----- sanity_router_input.json ----- -// JSON to store the sanity input messages which will be -// used to test sanity for all the destination. -// These inputs will be used for testing router -// transformation for all destination which support it. -// -// Format: -// { -// "messages": [ -// { router_sanity_input_message_1}, -// { router_sanity_input_message_2}, -// { router_sanity_input_message_3} -// ... -// ] -// } - -// ------ {integration(s)}_output.json ------ -// These are specific output for each of the destinations -// given the sanity input. We are using jest result matcher -// to check if the output is matching with the expected output. -// Example clevertap_output.json -// Format: -// [ -// {sanity_output_for_message_1}, -// {sanity_output_for_message_2}, -// .. -// ] - -// ------ {integration(s)}_router_output.json ------ -// These are specific output for each of the destinations -// given the router sanity input. -// ** CHECK IF THE PARTICULAR DESTINATION SUPPORTS ROUTER TRANSFORMATION ** -// Example clevertap_router_output.json -// Format: -// [ -// {router_sanity_output_for_message_1}, -// {router_sanity_output_for_message_2}, -// .. -// ] - -// Parsing all the destination names from /v0/destinations dir structure -// parsing it into an array of string. This keeping the destinations to test -// dynamic. -// const integrations = getDirectories( -// path.resolve(__dirname, `../${version}/destinations/`) -// ); -// For Testing Current: -// Uncomment this Line and comment the above 3 lines -const integrations = ["marketo"]; - -// Parsing the sanity input JSON which will be used for testing each destination -const processorSanityInput = JSON.parse( - fs.readFileSync(path.resolve(__dirname, `./data/sanity/sanity_input.json`)) -); - -// Parsing the sanity router input JSON which will be used for testing each destination -// which support it -const routerSanityInputRouter = JSON.parse( - fs.readFileSync( - path.resolve(__dirname, `./data/sanity/sanity_router_input.json`) - ) -); -// Parsing the destination config JSON from which we will get the destination definitions -// along with if the destination supports router-transformation -const destinationConfig = JSON.parse( - fs.readFileSync( - path.resolve(__dirname, `./data/sanity/destination_config.json`) - ) -); - -// Iterating each of the destinations -integrations.forEach(intg => { - // Getting the transformation object - const transformer = require(`../../src/${version}/destinations/${intg}/transform`); - // Getting the config for this particular destination - const { config } = destinationConfig[`${intg}`]; - // Where the ransformation is done at (processor, router ..) - Object.keys(config).forEach(processAt => { - // Depending on the case - switch (processAt) { - case "processor": - { - // Parsing the expected data for this particular destination - const expectedData = JSON.parse( - fs.readFileSync( - path.resolve(__dirname, `./data/sanity/${intg}_output.json`) - ) - ); - // For each of the messages we are processing using the transformer - processorSanityInput.messages.forEach((message, index) => { - // Building the event object with specified destination-definition - const event = { - message, - destination: config[`${processAt}`] - }; - // Sending the event to transformer and matching the result with expected output - it(`${name} - integration[Processor]: ${intg} payload:${index}`, async () => { - try { - const output = await transformer.process(event); - expect(output).toEqual(expectedData[index]); - } catch (error) { - expect(error.message).toEqual(expectedData[index].error); - } - }); - }); - } - break; - - case "router": - { - // Parsing the expected router output data for this particular destination - const expectedData = JSON.parse( - fs.readFileSync( - path.resolve( - __dirname, - `./data/sanity/${intg}_router_output.json` - ) - ) - ); - // For each of the messages we are processing using the router transformer - routerSanityInputRouter.messages.forEach((message, index) => { - // Building the event object with specified destination-definition - const events = [ - { - message, - metadata: { - jobId: 1 - }, - destination: config[`${processAt}`] - } - ]; - // Sending the event to router transformer of this destinationand matching the result with expected output - it(`${name} - integration(Router): ${intg} payload:${index}`, async () => { - const routerOutput = await transformer.processRouterDest(events); - expect(routerOutput[0]).toEqual(expectedData[index]); - }); - }); - } - break; - default: - throw new Error("Undefined Transform-At Config"); - } - }); -}); diff --git a/test/__tests__/user_transformation_ts.test.ts b/test/__tests__/user_transformation_ts.test.ts index 418c42fe33..971476e513 100644 --- a/test/__tests__/user_transformation_ts.test.ts +++ b/test/__tests__/user_transformation_ts.test.ts @@ -1,5 +1,5 @@ import fetch from 'node-fetch'; -import UserTransformService from '../../src/services/userTransform'; +import { UserTransformService } from '../../src/services/userTransform'; import { FeatureFlags, FEATURE_FILTER_CODE } from '../../src/middlewares/featureFlag'; jest.mock('node-fetch', () => jest.fn()); diff --git a/test/apitests/data_scenarios/source/v1/pipedream.json b/test/apitests/data_scenarios/source/v1/pipedream.json index 4219f3f6b1..1496471066 100644 --- a/test/apitests/data_scenarios/source/v1/pipedream.json +++ b/test/apitests/data_scenarios/source/v1/pipedream.json @@ -46,4 +46,4 @@ } } ] -} \ No newline at end of file +} diff --git a/test/controllerUtility/ctrl-utility.test.ts b/test/controllerUtility/ctrl-utility.test.ts index c3a668d7e7..bf9eef1846 100644 --- a/test/controllerUtility/ctrl-utility.test.ts +++ b/test/controllerUtility/ctrl-utility.test.ts @@ -1,5 +1,5 @@ import { ProcessorTransformationRequest, RouterTransformationRequestData } from '../../src/types'; -import ControllerUtility from '../../src/controllers/util'; +import { ControllerUtility } from '../../src/controllers/util'; type timestampTestCases = { caseName: string; From ff80b885fe0507c137b3c9eacffcef331010da0c Mon Sep 17 00:00:00 2001 From: Mihir Bhalala <77438541+mihir-4116@users.noreply.github.com> Date: Tue, 14 Nov 2023 18:33:35 +0530 Subject: [PATCH 39/93] feat(INT-305): onboard gladly destination (#2786) * feat: onboard gladly destination * chore: code review changes * chore: code review changes * chore: code review changes * chore: code review changes * chore: code review changes * chore: code review changes * chore: code review changes * chore: code review changes * fix: package.json changes * chore: added utility tests * chore: added gladly router and processor tests * chore: added gladly rETL tests * fix: sonar code smell * chore: code review changes --- package-lock.json | 131 ++- package.json | 2 +- .../v2/destinations/gladly/procWorkflow.yaml | 88 ++ .../v2/destinations/gladly/rtWorkflow.yaml | 33 + src/cdk/v2/destinations/gladly/utils.js | 175 ++++ src/cdk/v2/destinations/gladly/utils.test.js | 503 +++++++++++ src/cdk/v2/handler.ts | 11 +- src/constants/destinationCanonicalNames.js | 2 +- src/features.json | 1 + src/services/destination/cdkV2Integration.ts | 7 +- .../destinations/gladly/network.ts | 120 +++ .../destinations/gladly/processor/data.ts | 809 ++++++++++++++++++ .../destinations/gladly/router/data.ts | 604 +++++++++++++ 13 files changed, 2456 insertions(+), 30 deletions(-) create mode 100644 src/cdk/v2/destinations/gladly/procWorkflow.yaml create mode 100644 src/cdk/v2/destinations/gladly/rtWorkflow.yaml create mode 100644 src/cdk/v2/destinations/gladly/utils.js create mode 100644 src/cdk/v2/destinations/gladly/utils.test.js create mode 100644 test/integrations/destinations/gladly/network.ts create mode 100644 test/integrations/destinations/gladly/processor/data.ts create mode 100644 test/integrations/destinations/gladly/router/data.ts diff --git a/package-lock.json b/package-lock.json index 28d814c925..4f83954e5b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,7 +20,7 @@ "@ndhoule/extend": "^2.0.0", "@pyroscope/nodejs": "^0.2.6", "@rudderstack/integrations-lib": "^0.1.8", - "@rudderstack/workflow-engine": "^0.5.7", + "@rudderstack/workflow-engine": "^0.6.9", "ajv": "^8.12.0", "ajv-draft-04": "^1.0.0", "ajv-formats": "^2.1.1", @@ -6657,13 +6657,45 @@ "tslib": "^2.4.0" } }, - "node_modules/@rudderstack/json-template-engine": { + "node_modules/@rudderstack/integrations-lib/node_modules/@aws-crypto/sha256-js": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-4.0.0.tgz", + "integrity": "sha512-MHGJyjE7TX9aaqXj7zk2ppnFUOhaDs5sP+HtNS0evOxn72c+5njUmyJmpGd7TfyoDznZlHMmdo/xGUdu2NIjNQ==", + "dependencies": { + "@aws-crypto/util": "^4.0.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@rudderstack/integrations-lib/node_modules/@aws-crypto/sha256-js/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@rudderstack/integrations-lib/node_modules/@aws-crypto/util": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-4.0.0.tgz", + "integrity": "sha512-2EnmPy2gsFZ6m8bwUQN4jq+IyXV3quHAcwPOS6ZA3k+geujiqI8aRokO2kFJe+idJ/P3v4qWI186rVMo0+zLDQ==", + "dependencies": { + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-utf8-browser": "^3.0.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@rudderstack/integrations-lib/node_modules/@aws-crypto/util/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@rudderstack/integrations-lib/node_modules/@rudderstack/json-template-engine": { "version": "0.5.5", - "license": "MIT" + "resolved": "https://registry.npmjs.org/@rudderstack/json-template-engine/-/json-template-engine-0.5.5.tgz", + "integrity": "sha512-p3HdTqgZiJjjZmjaHN2paa1e87ifGE5UjkA4zdvge4bBzJbKKMQNWqRg6I96SwoA+hsxNkW/f9R83SPLU9t7LA==" }, - "node_modules/@rudderstack/workflow-engine": { - "version": "0.5.7", - "license": "MIT", + "node_modules/@rudderstack/integrations-lib/node_modules/@rudderstack/workflow-engine": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/@rudderstack/workflow-engine/-/workflow-engine-0.5.8.tgz", + "integrity": "sha512-H1aCowYqTnOoqJtL9cGDhdhoGNl+KzqmVbSjFmE7n75onZaIMs87+HQyW08jYxS9l1Uo4TL8SAvzFICqFqkBbw==", "dependencies": { "@aws-crypto/sha256-js": "^4.0.0", "@rudderstack/json-template-engine": "^0.5.5", @@ -6673,27 +6705,81 @@ "object-sizeof": "^2.6.3" } }, + "node_modules/@rudderstack/json-template-engine": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/@rudderstack/json-template-engine/-/json-template-engine-0.8.2.tgz", + "integrity": "sha512-9oMBnqgNuwiXd7MUlNOAchCnJXQAy6w6XGmDqDM6iXdYDkvqYFiq7sbg5j4SdtpTTST293hahREr5PXfFVzVKg==" + }, + "node_modules/@rudderstack/workflow-engine": { + "version": "0.6.9", + "resolved": "https://registry.npmjs.org/@rudderstack/workflow-engine/-/workflow-engine-0.6.9.tgz", + "integrity": "sha512-b0ZHURJfCj2REIL/w7AJgJ+K5BGwIVX3sRDZQqN3F4YWcZX3ZYUXo7gtUeb99FLnZzm7KuThIWR02Fxwos+L4Q==", + "dependencies": { + "@aws-crypto/sha256-js": "^5.0.0", + "@rudderstack/json-template-engine": "^0.8.1", + "jsonata": "^2.0.3", + "lodash": "^4.17.21", + "object-sizeof": "^2.6.3", + "yaml": "^2.3.2" + } + }, "node_modules/@rudderstack/workflow-engine/node_modules/@aws-crypto/sha256-js": { - "version": "4.0.0", - "license": "Apache-2.0", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", + "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", "dependencies": { - "@aws-crypto/util": "^4.0.0", + "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", - "tslib": "^1.11.1" + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" } }, "node_modules/@rudderstack/workflow-engine/node_modules/@aws-crypto/util": { - "version": "4.0.0", - "license": "Apache-2.0", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", + "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", "dependencies": { "@aws-sdk/types": "^3.222.0", - "@aws-sdk/util-utf8-browser": "^3.0.0", - "tslib": "^1.11.1" + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" } }, - "node_modules/@rudderstack/workflow-engine/node_modules/tslib": { - "version": "1.14.1", - "license": "0BSD" + "node_modules/@rudderstack/workflow-engine/node_modules/@smithy/is-array-buffer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.0.0.tgz", + "integrity": "sha512-z3PjFjMyZNI98JFRJi/U0nGoLWMSJlDjAW4QUX2WNZLas5C0CmVV6LJ01JI0k90l7FvpmixjWxPFmENSClQ7ug==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@rudderstack/workflow-engine/node_modules/@smithy/util-buffer-from": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.0.0.tgz", + "integrity": "sha512-/YNnLoHsR+4W4Vf2wL5lGv0ksg8Bmk3GEGxn2vEQt52AQaPSCuaO5PM5VM7lP1K9qHRKHwrPGktqVoAHKWHxzw==", + "dependencies": { + "@smithy/is-array-buffer": "^2.0.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@rudderstack/workflow-engine/node_modules/@smithy/util-utf8": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.0.2.tgz", + "integrity": "sha512-qOiVORSPm6Ce4/Yu6hbSgNHABLP2VMv8QOC3tTDNHHlWY19pPyc++fBTbZPtx6egPXi4HQxKDnMxVxpbtX2GoA==", + "dependencies": { + "@smithy/util-buffer-from": "^2.0.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } }, "node_modules/@sideway/address": { "version": "4.1.4", @@ -19379,8 +19465,9 @@ } }, "node_modules/tslib": { - "version": "2.5.3", - "license": "0BSD" + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, "node_modules/tsscmp": { "version": "1.0.6", @@ -19918,9 +20005,9 @@ "license": "ISC" }, "node_modules/yaml": { - "version": "2.3.1", - "dev": true, - "license": "ISC", + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz", + "integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==", "engines": { "node": ">= 14" } diff --git a/package.json b/package.json index f8851cc687..8a8b6177bd 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "@ndhoule/extend": "^2.0.0", "@pyroscope/nodejs": "^0.2.6", "@rudderstack/integrations-lib": "^0.1.8", - "@rudderstack/workflow-engine": "^0.5.7", + "@rudderstack/workflow-engine": "^0.6.9", "ajv": "^8.12.0", "ajv-draft-04": "^1.0.0", "ajv-formats": "^2.1.1", diff --git a/src/cdk/v2/destinations/gladly/procWorkflow.yaml b/src/cdk/v2/destinations/gladly/procWorkflow.yaml new file mode 100644 index 0000000000..fe8697bc31 --- /dev/null +++ b/src/cdk/v2/destinations/gladly/procWorkflow.yaml @@ -0,0 +1,88 @@ +bindings: + - name: EventType + path: ../../../../constants + - path: ./utils + exportAll: true + - name: defaultRequestConfig + path: ../../../../v0/util + - name: removeUndefinedAndNullValues + path: ../../../../v0/util + - name: getDestinationExternalID + path: ../../../../v0/util + - name: httpGET + path: ../../../../adapters/network + - name: processAxiosResponse + path: ../../../../adapters/utils/networkUtils + + +steps: + - name: checkIfProcessed + condition: .message.statusCode + template: | + $.batchMode ? .message.body.JSON : .message + onComplete: return + + - name: messageType + template: | + .message.type.toLowerCase() + + - name: validateInput + template: | + let messageType = $.outputs.messageType + $.assert(messageType, "message Type is not present. Aborting") + $.assert(messageType in {{$.EventType.([.IDENTIFY])}}, "message type " + messageType + " is not supported") + $.assertConfig(.destination.Config.apiToken, "API Token is not present. Aborting") + $.assertConfig(.destination.Config.domain, "Gladly domain is not present. Aborting") + $.assertConfig(.destination.Config.userName, "User Name is not present. Aborting") + + - name: preparePayload + template: | + $.context.payload = { + name: .message.traits.name || .message.context.traits.name, + image: .message.traits.avatar || .message.context.traits.avatar, + address: .message.traits.address || .message.context.traits.address + } + $.context.payload.address && typeof $.context.payload.address === "object" ? $.context.payload.address = JSON.stringify($.context.payload.address) + $.context.payload.emails = $.formatField(.message, "email") + $.context.payload.phones = $.formatField(.message, "phone") + $.context.payload.customAttributes = $.getCustomAttributes(.message) + $.context.payload.externalCustomerId = $.getExternalCustomerId(.message) + $.context.payload.id = $.getCustomerId(.message) + $.context.payload = $.removeUndefinedAndNullValues($.context.payload) + + - name: validatePayload + template: | + $.validatePayload($.context.payload) + + - name: findCustomer + description: Find if customer is exist or not based on email, phone or externalCustomerId + condition: $.getQueryParams($.context.payload) !== undefined + template: | + const requestOptions = { + headers: $.getHeaders(.destination) + } + const endpoint = $.getEndpoint(.destination) + "?" + $.getQueryParams($.context.payload); + const rawResponse = await $.httpGET(endpoint,requestOptions) + const processedResponse = $.processAxiosResponse(rawResponse) + processedResponse + + - name: createCustomer + description: Build response for create customer + condition: $.outputs.findCustomer.status === 400 || ($.outputs.findCustomer.status === 200 && $.outputs.findCustomer.response.length === 0) || $.getQueryParams($.context.payload) === undefined + template: | + const response = $.defaultRequestConfig() + response.body.JSON = $.removeUndefinedAndNullValues($.context.payload) + response.endpoint = $.getEndpoint(.destination) + response.method = "POST" + response.headers = $.getHeaders(.destination) + response + else: + name: updateCustomer + description: Build response for update customer + template: | + const response = $.defaultRequestConfig() + response.body.JSON = $.removeUndefinedAndNullValues($.context.payload.{~["id"]}) + response.endpoint = $.getEndpoint(.destination) + "/" + $.outputs.findCustomer.response[0].id + response.method = "PATCH" + response.headers = $.getHeaders(.destination) + response diff --git a/src/cdk/v2/destinations/gladly/rtWorkflow.yaml b/src/cdk/v2/destinations/gladly/rtWorkflow.yaml new file mode 100644 index 0000000000..341e5552c8 --- /dev/null +++ b/src/cdk/v2/destinations/gladly/rtWorkflow.yaml @@ -0,0 +1,33 @@ +bindings: + - name: handleRtTfSingleEventError + path: ../../../../v0/util/index + - path: ./utils + exportAll: true + +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.({ + "batchedRequest": ., + "batched": false, + "destination": ^[idx].destination, + "metadata": ^[idx].metadata[], + "statusCode": 200 + })[] + - name: failedEvents + template: | + $.outputs.transform#idx.error.( + $.handleRtTfSingleEventError(^[idx], .originalError ?? ., {}) + )[] + - name: finalPayload + template: | + [...$.outputs.successfulEvents, ...$.outputs.failedEvents] \ No newline at end of file diff --git a/src/cdk/v2/destinations/gladly/utils.js b/src/cdk/v2/destinations/gladly/utils.js new file mode 100644 index 0000000000..5abc9b6dd0 --- /dev/null +++ b/src/cdk/v2/destinations/gladly/utils.js @@ -0,0 +1,175 @@ +const get = require('get-value'); +const { InstrumentationError } = require('@rudderstack/integrations-lib'); +const { + base64Convertor, + getDestinationExternalID, +} = require('../../../../v0/util'); +const { MappedToDestinationKey } = require('../../../../constants'); + +const reservedCustomAttributes = [ + 'email', + 'phone', + 'address', + 'name', + 'avatar', + 'firstName', + 'lastName', + 'userId', +]; + +const externalIdKey = 'context.externalId.0.id'; +const identifierTypeKey = 'context.externalId.0.identifierType'; + +const getHeaders = (destination) => { + const { apiToken, userName } = destination.Config; + const credentials = `${userName}:${apiToken}`; + const base64Credentials = base64Convertor(credentials); + return { + 'Content-Type': 'application/json', + Authorization: `Basic ${base64Credentials}`, + }; +}; + +const getEndpoint = (destination) => { + const { domain } = destination.Config; + return `https://${domain}/api/v1/customer-profiles`; +}; + + +const getFieldValue = (field) => { + if (field) { + if (Array.isArray(field)) { + return field.map((item) => ({ original: item })); + } + return [{ original: field }]; + } + return undefined; +} + +const formatFieldForRETl = (message, fieldName) => { + const identifierType = get(message, identifierTypeKey); + if (identifierType && identifierType === fieldName) { + const field = get(message, externalIdKey); + if (field) { + return [{ original: field }]; + } + } + const key = fieldName === 'email' ? 'emails' : 'phones'; + const field = get(message, `traits.${key}`); + return getFieldValue(field); +}; + +const formatFieldForEventStream = (message, fieldName) => { + const field = get(message, `context.traits.${fieldName}`); + return getFieldValue(field); +}; + +const formatField = (message, fieldName) => { + const mappedToDestination = get(message, MappedToDestinationKey); + if (mappedToDestination) { + return formatFieldForRETl(message, fieldName); + } + return formatFieldForEventStream(message, fieldName); + +}; + +const getCustomAttributes = (message) => { + const mappedToDestination = get(message, MappedToDestinationKey); + // for rETL + if (mappedToDestination) { + if (message?.traits?.customAttributes && typeof message.traits.customAttributes === 'object') { + return Object.keys(message.traits.customAttributes).length > 0 ? message.traits.customAttributes : undefined; + } + return undefined; + } + + // for event stream + const customAttributes = message.context?.traits || {}; + reservedCustomAttributes.forEach((customAttribute) => { + if (customAttributes[customAttribute]) { + delete customAttributes[customAttribute]; + } + }); + return Object.keys(customAttributes).length > 0 ? customAttributes : undefined; +}; + +const getExternalCustomerId = (message) => { + const mappedToDestination = get(message, MappedToDestinationKey); + // for rETL + if (mappedToDestination) { + const identifierType = get(message, identifierTypeKey); + if (identifierType === 'externalCustomerId') { + return get(message, externalIdKey); + } + + if (message?.traits?.externalCustomerId) { + return message.traits.externalCustomerId; + } + + return undefined; + } + + // for event stream + return message.userId; +}; + +const getCustomerId = (message) => { + const mappedToDestination = get(message, MappedToDestinationKey); + // for rETL + if (mappedToDestination) { + const identifierType = get(message, identifierTypeKey); + if (identifierType === 'id') { + return get(message, externalIdKey); + } + + if (message?.traits?.id) { + return message.traits.id; + } + + return undefined; + } + + // for event stream + const customerId = getDestinationExternalID(message, 'GladlyCustomerId'); + if (customerId) { + return customerId; + } + + return undefined; +}; + +const validatePayload = (payload) => { + if (!(payload?.phones || payload?.emails || payload?.id || payload?.externalCustomerId)) { + throw new InstrumentationError('One of phone, email, userId or GladlyCustomerId is required for an identify call'); + } +}; + +const getQueryParams = (payload) => { + if (payload.emails && payload.emails.length > 0) { + return `email=${encodeURIComponent(payload.emails[0].original)}` + } + + if (payload.phones && payload.phones.length > 0) { + return `phoneNumber=${encodeURIComponent(payload.phones[0].original)}` + } + + if (payload.externalCustomerId) { + return `externalCustomerId=${encodeURIComponent(payload.externalCustomerId)}` + } + + return undefined; +} + +module.exports = { + getHeaders, + getEndpoint, + formatField, + getFieldValue, + getCustomerId, + getQueryParams, + validatePayload, + formatFieldForRETl, + getCustomAttributes, + getExternalCustomerId, + formatFieldForEventStream +}; diff --git a/src/cdk/v2/destinations/gladly/utils.test.js b/src/cdk/v2/destinations/gladly/utils.test.js new file mode 100644 index 0000000000..116f150448 --- /dev/null +++ b/src/cdk/v2/destinations/gladly/utils.test.js @@ -0,0 +1,503 @@ +const { + getHeaders, + getEndpoint, + formatField, + getCustomerId, + getFieldValue, + getQueryParams, + validatePayload, + formatFieldForRETl, + getCustomAttributes, + getExternalCustomerId, + formatFieldForEventStream, +} = require('./utils'); +const { base64Convertor } = require('../../../../v0/util'); + +describe('Unit test cases for getHeaders function', () => { + it('Should return headers', () => { + const destination = { + Config: { + apiToken: 'token', + userName: 'user', + }, + }; + const expectedHeaders = { + 'Content-Type': 'application/json', + Authorization: `Basic ${base64Convertor('user:token')}`, + }; + + const result = getHeaders(destination); + + expect(result).toEqual(expectedHeaders); + }); +}); + +describe('Unit test cases for getEndpoint function', () => { + it('Should return destination endpoint', () => { + const destination = { + Config: { + domain: 'rudderstack.us-uat.gladly.qa', + }, + }; + const expected = 'https://rudderstack.us-uat.gladly.qa/api/v1/customer-profiles'; + const result = getEndpoint(destination); + expect(result).toBe(expected); + }); +}); + +describe('Unit test cases for getFieldValue function', () => { + it('Should return an array with a single object containing the original value when the input field is a string', () => { + const field = 'rudderlabs1@gmail.com'; + const result = getFieldValue(field); + expect(result).toEqual([{ original: field }]); + }); + + it('should return an array with each element containing the original value when the input field is an array', () => { + const field = ['rudderlabs1@gmail.com', 'rudderlabs2@gmail.com', 'rudderlabs3@gmail.com']; + const result = getFieldValue(field); + expect(result).toEqual([ + { + original: 'rudderlabs1@gmail.com', + }, + { + original: 'rudderlabs2@gmail.com', + }, + { + original: 'rudderlabs3@gmail.com', + }, + ]); + }); + + it('Should return undefined when the input field is null', () => { + const field = null; + const result = getFieldValue(field); + expect(result).toBeUndefined(); + }); + + it('Should return undefined when the input field is undefined', () => { + const field = undefined; + const result = getFieldValue(field); + expect(result).toBeUndefined(); + }); +}); + +describe('Unit test cases for formatFieldForRETl function', () => { + it('should return the object containing the original value when identifierType matches fieldName', () => { + const message = { + context: { + externalId: [ + { + id: 'test@rudderlabs.com', + identifierType: 'email', + }, + ], + }, + traits: { + emails: ['test@rudderlabs.com', 'test@rudderlabshome.com'], + }, + }; + const fieldName = 'email'; + const expected = [{ original: 'test@rudderlabs.com' }]; + + const result = formatFieldForRETl(message, fieldName); + + expect(result).toEqual(expected); + }); + + it('Should retrieve the email value from traits when fieldName does not match with identifierType', () => { + const message = { + context: { + externalId: [ + { + id: '+91 9999999999', + identifierType: 'phone', + }, + ], + }, + traits: { + emails: ['test@rudderlabs.com', 'test@rudderlabshome.com'], + }, + }; + const fieldName = 'email'; + const expected = [{ original: 'test@rudderlabs.com' }, { original: 'test@rudderlabshome.com' }]; + + const result = formatFieldForRETl(message, fieldName); + + expect(result).toEqual(expected); + }); +}); + +describe('Unit test cases for formatFieldForEventStream function', () => { + it('Should return field value when fieldName exist in payload', () => { + const message = { + context: { + traits: { + phone: '+91 9999999999', + }, + }, + }; + const fieldName = 'phone'; + const expected = [{ original: '+91 9999999999' }]; + + const result = formatFieldForEventStream(message, fieldName); + expect(result).toEqual(expected); + }); + + it('Should return undefined when fieldName does not exist in payload', () => { + const message = { + context: { + traits: { + phone: '+91 9999999999', + }, + }, + }; + const fieldName = 'email'; + const result = formatFieldForEventStream(message, fieldName); + expect(result).toBeUndefined(); + }); +}); + +describe('Unit test cases for formatField function', () => { + describe('rETL tests', () => { + it('Should return field value from externalId when identifier type matches with fieldName', () => { + const message = { + context: { + externalId: [ + { + id: '+91 9999999999', + identifierType: 'phone', + }, + ], + mappedToDestination: true, + }, + traits: { + emails: ['test@rudderlabs.com', 'test@rudderlabshome.com'], + }, + }; + const result = formatField(message, 'phone'); + expect(result).toEqual([{ original: '+91 9999999999' }]); + }); + + it('Should return field value from traits when identifier type does not match with fieldName', () => { + const message = { + context: { + externalId: [ + { + id: 'user@1', + identifierType: 'externalCustomerId', + }, + ], + mappedToDestination: true, + }, + traits: { + phones: ['+91 9999999999'], + }, + }; + const result = formatField(message, 'phone'); + expect(result).toEqual([{ original: '+91 9999999999' }]); + }); + }); + + describe('Event stream tests', () => { + it('Should return field value from payload', () => { + const message = { + context: { + traits: { + phone: ['+91 9999999999'], + }, + }, + }; + const result = formatField(message, 'phone'); + expect(result).toEqual([{ original: '+91 9999999999' }]); + }); + }); +}); + +describe('Unit test cases for getCustomAttributes function', () => { + describe('rETL tests', () => { + it('Should return custom attributes from payload', () => { + const message = { + context: { + mappedToDestination: true, + }, + traits: { + customAttributes: { + attribute1: 'value1', + attribute2: 'value2', + }, + }, + }; + const result = getCustomAttributes(message); + expect(result).toEqual({ + attribute1: 'value1', + attribute2: 'value2', + }); + }); + + it('Should return undefined when empty custom attributes object is present in payload', () => { + const message = { + context: { + mappedToDestination: true, + }, + traits: { + customAttributes: {}, + }, + }; + const result = getCustomAttributes(message); + expect(result).toBeUndefined(); + }); + + it('Should return undefined when no custom attributes are present in payload', () => { + const message = { + context: { + mappedToDestination: true, + }, + traits: {}, + }; + const result = getCustomAttributes(message); + expect(result).toBeUndefined(); + }); + }); + + describe('Event stream tests', () => { + it('Should filter traits and return remaining custom attributes from payload', () => { + const message = { + context: { + traits: { + name: 'John Doe', + email: 'john@gmail.com', + age: 65, + source: 'rudderstack', + }, + }, + }; + const result = getCustomAttributes(message); + expect(result).toEqual({ + age: 65, + source: 'rudderstack', + }); + }); + + it('Should return undefined when empty traits object is present in payload', () => { + const message = { + context: { + traits: {}, + }, + }; + const result = getCustomAttributes(message); + expect(result).toBeUndefined(); + }); + + it('Should return undefined when no traits object is present in payload', () => { + const message = { + context: {}, + }; + const result = getCustomAttributes(message); + expect(result).toBeUndefined(); + }); + }); +}); + +describe('Unit test cases for getExternalCustomerId function', () => { + describe('rETL tests', () => { + it('Should return the external ID when the identifier type is "externalCustomerId"', () => { + const message = { + context: { + externalId: [ + { + id: 'externalCustomer@1', + identifierType: 'externalCustomerId', + }, + ], + mappedToDestination: true, + }, + }; + + const result = getExternalCustomerId(message); + expect(result).toBe('externalCustomer@1'); + }); + + it('Should return the external ID from traits when identifier type is not "externalCustomerId"', () => { + const message = { + context: { + externalId: [ + { + id: 'test@rudderlabs.com', + identifierType: 'email', + }, + ], + mappedToDestination: true, + }, + traits: { + externalCustomerId: 'externalCustomer@1', + }, + }; + const result = getExternalCustomerId(message); + expect(result).toBe('externalCustomer@1'); + }); + + it('Should return undefined when external customer id is not present in payload', () => { + const message = { + context: { + mappedToDestination: true, + }, + }; + + const result = getExternalCustomerId(message); + expect(result).toBeUndefined(); + }); + }); + + describe('Event stream tests', () => { + it('Should return the external ID as userId is present in payload', () => { + const message = { + userId: 'externalCustomer@1', + context: {}, + }; + + const result = getExternalCustomerId(message); + expect(result).toBe('externalCustomer@1'); + }); + + it('Should return undefined when userId is not present in payload', () => { + const message = { + context: {}, + }; + + const result = getExternalCustomerId(message); + expect(result).toBeUndefined(); + }); + }); +}); + +describe('Unit test cases for getCustomerId function', () => { + describe('rETL tests', () => { + it('Should return the customerId when the identifier type is "id"', () => { + const message = { + context: { + externalId: [ + { + id: 'user@1', + identifierType: 'id', + }, + ], + mappedToDestination: true, + }, + }; + + const result = getCustomerId(message); + expect(result).toBe('user@1'); + }); + + it('Should return the customerId from traits when identifier type is not "id"', () => { + const message = { + context: { + externalId: [ + { + id: 'test@rudderlabs.com', + identifierType: 'email', + }, + ], + mappedToDestination: true, + }, + traits: { + id: 'user@1', + }, + }; + const result = getCustomerId(message); + expect(result).toBe('user@1'); + }); + + it('Should return undefined when customerId is not present in payload', () => { + const message = { + context: { + mappedToDestination: true, + }, + }; + + const result = getCustomerId(message); + expect(result).toBeUndefined(); + }); + }); + + describe('Event stream tests', () => { + it('Should return the customerId as GladlyCustomerId is present in payload', () => { + const message = { + context: { + externalId: [ + { + id: 'user@1', + type: 'GladlyCustomerId', + }, + ], + }, + }; + const result = getCustomerId(message); + expect(result).toBe('user@1'); + }); + + it('Should return undefined when GladlyCustomerId is not present in payload', () => { + const message = { + context: {}, + }; + const result = getCustomerId(message); + expect(result).toBeUndefined(); + }); + }); +}); + +describe('Unit test cases for validatePayload function', () => { + it('Should throw an error when payload does not have all required fields', () => { + const payload = {}; + try { + validatePayload(payload); + } catch (err) { + expect(err.message).toEqual( + 'One of phone, email, userId or GladlyCustomerId is required for an identify call', + ); + } + }); + + it('Should throw an error when payload is undefined', () => { + const payload = undefined; + try { + validatePayload(payload); + } catch (err) { + expect(err.message).toEqual( + 'One of phone, email, userId or GladlyCustomerId is required for an identify call', + ); + } + }); +}); + +describe('Unit test cases for getQueryParams function', () => { + it('Should return email as query parameter if email is present in payload', () => { + const payload = { + emails: [{ original: 'test@example.com' }], + }; + const result = getQueryParams(payload); + expect(result).toBe('email=test%40example.com'); + }); + + it('Should return phone as query parameter if phone is present in payload', () => { + const payload = { + phones: [{ original: '+91 9999999999' }], + }; + const result = getQueryParams(payload); + expect(result).toBe('phoneNumber=%2B91%209999999999'); + }); + + it('Should return externalCustomerId as query parameter if externalCustomerId is present in payload', () => { + const payload = { + externalCustomerId: 'externalCustomer@1', + }; + const result = getQueryParams(payload); + expect(result).toBe('externalCustomerId=externalCustomer%401'); + }); + + it('should return undefined when no supported query params are present in payload', () => { + const payload = {}; + const result = getQueryParams(payload); + expect(result).toBeUndefined(); + }); +}); diff --git a/src/cdk/v2/handler.ts b/src/cdk/v2/handler.ts index 3058d62e51..47d6d10179 100644 --- a/src/cdk/v2/handler.ts +++ b/src/cdk/v2/handler.ts @@ -64,8 +64,12 @@ export function getCachedWorkflowEngine( return workflowEnginePromiseMap[destName][feature]; } -export async function executeWorkflow(workflowEngine: WorkflowEngine, parsedEvent: FixMe) { - const result = await workflowEngine.execute(parsedEvent); +export async function executeWorkflow( + workflowEngine: WorkflowEngine, + parsedEvent: FixMe, + requestMetadata: NonNullable = {}, +) { + const result = await workflowEngine.execute(parsedEvent, { requestMetadata }); // TODO: Handle remaining output scenarios return result.output; } @@ -74,11 +78,12 @@ export async function processCdkV2Workflow( destType: string, parsedEvent: FixMe, feature: string, + requestMetadata: NonNullable = {}, bindings: Record = {}, ) { try { const workflowEngine = await getCachedWorkflowEngine(destType, feature, bindings); - return await executeWorkflow(workflowEngine, parsedEvent); + return await executeWorkflow(workflowEngine, parsedEvent, requestMetadata); } catch (error) { throw getErrorInfo(error, isCdkV2Destination(parsedEvent), defTags); } diff --git a/src/constants/destinationCanonicalNames.js b/src/constants/destinationCanonicalNames.js index d1e199c9e2..48e7c6d8bb 100644 --- a/src/constants/destinationCanonicalNames.js +++ b/src/constants/destinationCanonicalNames.js @@ -140,7 +140,7 @@ const DestCanonicalNames = { 'twitter_ads', 'TWITTER_ADS', ], - BRAZE: ['BRAZE', 'Braze', 'braze'], + BRAZE: ['BRAZE', 'Braze', 'braze'] }; module.exports = { DestHandlerMap, DestCanonicalNames }; diff --git a/src/features.json b/src/features.json index 27da6cfaf2..224968c99b 100644 --- a/src/features.json +++ b/src/features.json @@ -60,6 +60,7 @@ "TWITTER_ADS": true, "CLEVERTAP": true, "ORTTO": true, + "GLADLY": true, "ONE_SIGNAL": true, "TIKTOK_AUDIENCE": true }, diff --git a/src/services/destination/cdkV2Integration.ts b/src/services/destination/cdkV2Integration.ts index e333d4544e..f3be2c0144 100644 --- a/src/services/destination/cdkV2Integration.ts +++ b/src/services/destination/cdkV2Integration.ts @@ -52,7 +52,7 @@ export class CDKV2DestinationService implements DestinationService { events: ProcessorTransformationRequest[], destinationType: string, _version: string, - _requestMetadata: NonNullable, + requestMetadata: NonNullable, ): Promise { // TODO: Change the promise type const respList: ProcessorTransformationResponse[][] = await Promise.all( @@ -64,6 +64,7 @@ export class CDKV2DestinationService implements DestinationService { destinationType, event, tags.FEATURES.PROCESSOR, + requestMetadata ); stats.increment('event_transform_success', { @@ -108,7 +109,7 @@ export class CDKV2DestinationService implements DestinationService { events: RouterTransformationRequestData[], destinationType: string, _version: string, - _requestMetadata: NonNullable, + requestMetadata: NonNullable, ): Promise { const allDestEvents: object = groupBy( events, @@ -126,7 +127,7 @@ export class CDKV2DestinationService implements DestinationService { metaTo.metadata = destInputArray[0].metadata; try { const doRouterTransformationResponse: RouterTransformationResponse[] = - await processCdkV2Workflow(destinationType, destInputArray, tags.FEATURES.ROUTER); + await processCdkV2Workflow(destinationType, destInputArray, tags.FEATURES.ROUTER, requestMetadata); return DestinationPostTransformationService.handleRouterTransformSuccessEvents( doRouterTransformationResponse, undefined, diff --git a/test/integrations/destinations/gladly/network.ts b/test/integrations/destinations/gladly/network.ts new file mode 100644 index 0000000000..8c1c228738 --- /dev/null +++ b/test/integrations/destinations/gladly/network.ts @@ -0,0 +1,120 @@ +const deleteNwData = [ + { + httpReq: { + method: 'get', + url: 'https://rudderlabs.us-uat.gladly.qa/api/v1/customer-profiles?email=test%40rudderlabs.com', + headers: { + 'Content-Type': 'application/json', + Authorization: 'Basic dGVzdFVzZXJOYW1lOnRlc3RBcGlUb2tlbg==', + }, + }, + httpRes: { + data: [], + status: 200, + }, + }, + { + httpReq: { + method: 'get', + url: 'https://rudderlabs.us-uat.gladly.qa/api/v1/customer-profiles?email=test%2B2%40rudderlabs.com', + headers: { + 'Content-Type': 'application/json', + Authorization: 'Basic dGVzdFVzZXJOYW1lOnRlc3RBcGlUb2tlbg==', + }, + }, + httpRes: { + data: [ + { + emails: [ + { + normalized: 'test+2@rudderstack.com', + original: 'test+2@rudderlabs.com', + }, + ], + externalCustomerId: 'externalCustomer@2', + name: 'Test Rudderstack', + phones: [], + id: 'user@2', + }, + ], + status: 200, + }, + }, + { + httpReq: { + method: 'get', + url: 'https://rudderlabs.us-uat.gladly.qa/api/v1/customer-profiles?phoneNumber=%2B91%209999999988', + headers: { + 'Content-Type': 'application/json', + Authorization: 'Basic dGVzdFVzZXJOYW1lOnRlc3RBcGlUb2tlbg==', + }, + }, + httpRes: { + data: [ + { + emails: [ + { + normalized: 'test+3@rudderstack.com', + original: 'test+3@rudderlabs.com', + }, + ], + externalCustomerId: 'externalCustomer@3', + name: 'Test Rudderstack', + phones: [], + id: 'user@3', + }, + { + emails: [ + { + normalized: 'test+4@rudderstack.com', + original: 'test+4@rudderlabs.com', + }, + ], + externalCustomerId: 'externalCustomer@4', + name: 'Test Rudderstack', + phones: [], + id: 'user@4', + }, + ], + status: 200, + }, + }, + { + httpReq: { + method: 'get', + url: 'https://rudderlabs.us-uat.gladly.qa/api/v1/customer-profiles?email=test6%40rudderlabs.com', + headers: { + 'Content-Type': 'application/json', + Authorization: 'Basic dGVzdFVzZXJOYW1lOnRlc3RBcGlUb2tlbg==', + }, + }, + httpRes: { + data: [], + status: 200, + }, + }, + { + httpReq: { + method: 'get', + url: 'https://rudderlabs.us-uat.gladly.qa/api/v1/customer-profiles?email=abc', + headers: { + 'Content-Type': 'application/json', + Authorization: 'Basic dGVzdFVzZXJOYW1lOnRlc3RBcGlUb2tlbg==', + }, + }, + httpRes: { + data: { + errors: [ + { + attr: 'email', + code: 'invalid', + detail: 'invalid email address', + }, + ], + }, + status: 400, + }, + }, +]; + +export const networkCallsData = [...deleteNwData]; diff --git a/test/integrations/destinations/gladly/processor/data.ts b/test/integrations/destinations/gladly/processor/data.ts new file mode 100644 index 0000000000..211fa78134 --- /dev/null +++ b/test/integrations/destinations/gladly/processor/data.ts @@ -0,0 +1,809 @@ +export const data = [ + { + name: 'gladly', + description: 'No message type', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + userId: 'user@1', + channel: 'web', + context: { + traits: { + age: 23, + email: 'adc@test.com', + firstName: 'Test', + }, + }, + originalTimestamp: '2023-11-10T14:42:44.724Z', + timestamp: '2023-11-22T10:12:44.757+05:30', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiToken: 'testApiToken', + userName: 'testUserName', + domain: 'rudderlabs.us-uat.gladly.qa', + }, + }, + metadata: { + jobId: 1, + }, + }, + ], + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + jobId: 1, + }, + statusCode: 400, + error: + 'message Type is not present. Aborting: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: message Type is not present. Aborting', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'GLADLY', + module: 'destination', + implementation: 'cdkV2', + feature: 'processor', + }, + }, + ], + }, + }, + }, + { + name: 'gladly', + description: 'Unsupported message type', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + userId: 'user@1', + channel: 'web', + context: { + traits: { + age: 23, + email: 'adc@test.com', + firstName: 'Test', + }, + }, + event: 'Product Viewed', + type: 'track', + originalTimestamp: '2023-11-10T14:42:44.724Z', + timestamp: '2023-11-22T10:12:44.757+05:30', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiToken: 'testApiToken', + userName: 'testUserName', + domain: 'rudderlabs.us-uat.gladly.qa', + }, + }, + metadata: { + jobId: 2, + }, + }, + ], + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + jobId: 2, + }, + statusCode: 400, + error: + 'message type track is not supported: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: message type track is not supported', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'GLADLY', + module: 'destination', + implementation: 'cdkV2', + feature: 'processor', + }, + }, + ], + }, + }, + }, + { + name: 'gladly', + description: 'Missing config', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + userId: 'user@1', + channel: 'web', + context: { + traits: { + age: 23, + email: 'adc@test.com', + firstName: 'Test', + }, + }, + type: 'identify', + originalTimestamp: '2023-11-10T14:42:44.724Z', + timestamp: '2023-11-22T10:12:44.757+05:30', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiToken: 'testApiToken', + domain: 'rudderlabs.us-uat.gladly.qa', + }, + }, + metadata: { + jobId: 3, + }, + }, + ], + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + jobId: 3, + }, + statusCode: 400, + error: + 'User Name is not present. Aborting: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: User Name is not present. Aborting', + statTags: { + errorCategory: 'dataValidation', + errorType: 'configuration', + destType: 'GLADLY', + module: 'destination', + implementation: 'cdkV2', + feature: 'processor', + }, + }, + ], + }, + }, + }, + { + name: 'gladly', + description: 'Create customer with email as lookup field', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + userId: 'externalCustomer@1', + channel: 'web', + context: { + traits: { + age: 23, + email: 'test@rudderlabs.com', + phone: '+91 9999999999', + firstName: 'Test', + lastName: 'Rudderlabs', + address: 'california usa', + }, + externalId: [ + { + id: 'user@1', + type: 'GladlyCustomerId', + }, + ], + }, + type: 'identify', + originalTimestamp: '2023-11-10T14:42:44.724Z', + timestamp: '2023-11-22T10:12:44.757+05:30', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiToken: 'testApiToken', + userName: 'testUserName', + domain: 'rudderlabs.us-uat.gladly.qa', + }, + }, + metadata: { + jobId: 4, + }, + }, + ], + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + JSON: { + address: 'california usa', + customAttributes: { age: 23 }, + emails: [{ original: 'test@rudderlabs.com' }], + externalCustomerId: 'externalCustomer@1', + id: 'user@1', + phones: [{ original: '+91 9999999999' }], + }, + XML: {}, + FORM: {}, + JSON_ARRAY: {}, + }, + endpoint: 'https://rudderlabs.us-uat.gladly.qa/api/v1/customer-profiles', + headers: { + Authorization: 'Basic dGVzdFVzZXJOYW1lOnRlc3RBcGlUb2tlbg==', + 'Content-Type': 'application/json', + }, + userId: '', + version: '1', + type: 'REST', + method: 'POST', + files: {}, + params: {}, + }, + metadata: { jobId: 4 }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'gladly', + description: 'Update customer with email as lookup field', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + userId: 'externalCustomer@2', + channel: 'web', + context: { + traits: { + age: 23, + email: 'test+2@rudderlabs.com', + phone: '+91 9999999998', + firstName: 'Test', + lastName: 'Rudderstack', + address: 'New York, USA', + }, + externalId: [ + { + id: 'user@2', + type: 'GladlyCustomerId', + }, + ], + }, + type: 'identify', + originalTimestamp: '2023-11-10T14:42:44.724Z', + timestamp: '2023-11-22T10:12:44.757+05:30', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiToken: 'testApiToken', + userName: 'testUserName', + domain: 'rudderlabs.us-uat.gladly.qa', + }, + }, + metadata: { + jobId: 5, + }, + }, + ], + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + JSON: { + address: 'New York, USA', + customAttributes: { age: 23 }, + emails: [{ original: 'test+2@rudderlabs.com' }], + externalCustomerId: 'externalCustomer@2', + phones: [{ original: '+91 9999999998' }], + }, + XML: {}, + FORM: {}, + JSON_ARRAY: {}, + }, + endpoint: 'https://rudderlabs.us-uat.gladly.qa/api/v1/customer-profiles/user@2', + headers: { + Authorization: 'Basic dGVzdFVzZXJOYW1lOnRlc3RBcGlUb2tlbg==', + 'Content-Type': 'application/json', + }, + userId: '', + version: '1', + type: 'REST', + method: 'PATCH', + files: {}, + params: {}, + }, + metadata: { jobId: 5 }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'gladly', + description: 'Update customer with phone as lookup field', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + userId: 'externalCustomer@3', + channel: 'web', + context: { + traits: { + phone: '+91 9999999988', + firstName: 'Test', + lastName: 'Rudderstack', + address: 'New York, USA', + }, + externalId: [ + { + id: 'user@3', + type: 'GladlyCustomerId', + }, + ], + }, + type: 'identify', + originalTimestamp: '2023-11-10T14:42:44.724Z', + timestamp: '2023-11-22T10:12:44.757+05:30', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiToken: 'testApiToken', + userName: 'testUserName', + domain: 'rudderlabs.us-uat.gladly.qa', + }, + }, + metadata: { + jobId: 6, + }, + }, + ], + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + JSON: { + address: 'New York, USA', + externalCustomerId: 'externalCustomer@3', + phones: [{ original: '+91 9999999988' }], + }, + XML: {}, + FORM: {}, + JSON_ARRAY: {}, + }, + endpoint: 'https://rudderlabs.us-uat.gladly.qa/api/v1/customer-profiles/user@3', + headers: { + Authorization: 'Basic dGVzdFVzZXJOYW1lOnRlc3RBcGlUb2tlbg==', + 'Content-Type': 'application/json', + }, + userId: '', + version: '1', + type: 'REST', + method: 'PATCH', + files: {}, + params: {}, + }, + metadata: { jobId: 6 }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'gladly', + description: 'Required values are not present in payload to create or update customer', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + traits: { + firstName: 'Test', + lastName: 'Rudderstack', + address: 'New York, USA', + }, + }, + type: 'identify', + anonymousId: '78c53c15-32a1-4b65-adac-bec2d7bb8fab', + originalTimestamp: '2023-11-10T14:42:44.724Z', + timestamp: '2023-11-22T10:12:44.757+05:30', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiToken: 'testApiToken', + userName: 'testUserName', + domain: 'rudderlabs.us-uat.gladly.qa', + }, + }, + metadata: { + jobId: 7, + }, + }, + ], + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + jobId: 7, + }, + statusCode: 400, + error: + 'One of phone, email, userId or GladlyCustomerId is required for an identify call: Workflow: procWorkflow, Step: validatePayload, ChildStep: undefined, OriginalError: One of phone, email, userId or GladlyCustomerId is required for an identify call', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'GLADLY', + module: 'destination', + implementation: 'cdkV2', + feature: 'processor', + }, + }, + ], + }, + }, + }, + { + name: 'gladly', + description: 'Multiple emails and phones are present in payload', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + userId: 'externalCustomer@6', + channel: 'web', + context: { + traits: { + age: 23, + email: [ + 'test6@rudderlabs.com', + 'test6home@rudderlabs.com', + 'test6office@rudderlabs.com', + ], + phone: ['+91 8888888888', '+91 8888888889'], + firstName: 'Test', + lastName: 'Rudderlabs', + address: 'Germany', + }, + externalId: [ + { + id: 'user@6', + type: 'GladlyCustomerId', + }, + ], + }, + type: 'identify', + originalTimestamp: '2023-11-10T14:42:44.724Z', + timestamp: '2023-11-22T10:12:44.757+05:30', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiToken: 'testApiToken', + userName: 'testUserName', + domain: 'rudderlabs.us-uat.gladly.qa', + }, + }, + metadata: { + jobId: 8, + }, + }, + ], + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + JSON: { + address: 'Germany', + customAttributes: { age: 23 }, + emails: [ + { original: 'test6@rudderlabs.com' }, + { original: 'test6home@rudderlabs.com' }, + { original: 'test6office@rudderlabs.com' }, + ], + externalCustomerId: 'externalCustomer@6', + id: 'user@6', + phones: [{ original: '+91 8888888888' }, { original: '+91 8888888889' }], + }, + XML: {}, + FORM: {}, + JSON_ARRAY: {}, + }, + endpoint: 'https://rudderlabs.us-uat.gladly.qa/api/v1/customer-profiles', + headers: { + Authorization: 'Basic dGVzdFVzZXJOYW1lOnRlc3RBcGlUb2tlbg==', + 'Content-Type': 'application/json', + }, + userId: '', + version: '1', + type: 'REST', + method: 'POST', + files: {}, + params: {}, + }, + metadata: { jobId: 8 }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'gladly', + description: 'Create customer with only GladlyCustomerId', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + traits: { + firstName: 'Test', + lastName: 'Undefined', + address: 'India', + isProUser: true, + }, + externalId: [ + { + id: 'user@9', + type: 'GladlyCustomerId', + }, + ], + }, + type: 'identify', + originalTimestamp: '2023-11-10T14:42:44.724Z', + timestamp: '2023-11-22T10:12:44.757+05:30', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiToken: 'testApiToken', + userName: 'testUserName', + domain: 'rudderlabs.us-uat.gladly.qa', + }, + }, + metadata: { + jobId: 9, + }, + }, + ], + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + JSON: { + address: 'India', + customAttributes: { isProUser: true }, + id: 'user@9', + }, + XML: {}, + FORM: {}, + JSON_ARRAY: {}, + }, + endpoint: 'https://rudderlabs.us-uat.gladly.qa/api/v1/customer-profiles', + headers: { + Authorization: 'Basic dGVzdFVzZXJOYW1lOnRlc3RBcGlUb2tlbg==', + 'Content-Type': 'application/json', + }, + userId: '', + version: '1', + type: 'REST', + method: 'POST', + files: {}, + params: {}, + }, + metadata: { jobId: 9 }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'gladly', + description: 'Create customer with invalid lookup field value', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + traits: { + firstName: 'Test', + lastName: 'Undefined', + address: 'Pakistan', + email: 'abc', + }, + externalId: [ + { + id: 'user@10', + type: 'GladlyCustomerId', + }, + ], + }, + type: 'identify', + originalTimestamp: '2023-11-10T14:42:44.724Z', + timestamp: '2023-11-22T10:12:44.757+05:30', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiToken: 'testApiToken', + userName: 'testUserName', + domain: 'rudderlabs.us-uat.gladly.qa', + }, + }, + metadata: { + jobId: 10, + }, + }, + ], + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + JSON: { + address: 'Pakistan', + emails: [{original: 'abc'}], + id: 'user@10', + }, + XML: {}, + FORM: {}, + JSON_ARRAY: {}, + }, + endpoint: 'https://rudderlabs.us-uat.gladly.qa/api/v1/customer-profiles', + headers: { + Authorization: 'Basic dGVzdFVzZXJOYW1lOnRlc3RBcGlUb2tlbg==', + 'Content-Type': 'application/json', + }, + userId: '', + version: '1', + type: 'REST', + method: 'POST', + files: {}, + params: {}, + }, + metadata: { jobId: 10 }, + statusCode: 200, + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/gladly/router/data.ts b/test/integrations/destinations/gladly/router/data.ts new file mode 100644 index 0000000000..d3339d8108 --- /dev/null +++ b/test/integrations/destinations/gladly/router/data.ts @@ -0,0 +1,604 @@ +export const data = [ + { + name: 'gladly', + description: 'Gladly router tests', + feature: 'router', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + input: [ + { + message: { + userId: 'externalCustomer@1', + channel: 'web', + context: { + traits: { + age: 23, + email: 'test@rudderlabs.com', + phone: '+91 9999999999', + firstName: 'Test', + lastName: 'Rudderlabs', + address: 'california usa', + }, + externalId: [ + { + id: 'user@1', + type: 'GladlyCustomerId', + }, + ], + }, + type: 'identify', + originalTimestamp: '2023-11-10T14:42:44.724Z', + timestamp: '2023-11-22T10:12:44.75705:30', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiToken: 'testApiToken', + userName: 'testUserName', + domain: 'rudderlabs.us-uat.gladly.qa', + }, + }, + metadata: { + jobId: 1, + }, + }, + { + message: { + userId: 'externalCustomer@2', + channel: 'web', + context: { + traits: { + age: 23, + email: 'test+2@rudderlabs.com', + phone: '+91 9999999998', + firstName: 'Test', + lastName: 'Rudderstack', + address: 'New York, USA', + }, + externalId: [ + { + id: 'user@2', + type: 'GladlyCustomerId', + }, + ], + }, + type: 'identify', + originalTimestamp: '2023-11-10T14:42:44.724Z', + timestamp: '2023-11-22T10:12:44.75705:30', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiToken: 'testApiToken', + userName: 'testUserName', + domain: 'rudderlabs.us-uat.gladly.qa', + }, + }, + metadata: { + jobId: 2, + }, + }, + { + message: { + userId: 'externalCustomer@3', + channel: 'web', + context: { + traits: { + phone: '+91 9999999988', + firstName: 'Test', + lastName: 'Rudderstack', + address: 'New York, USA', + }, + externalId: [ + { + id: 'user@3', + type: 'GladlyCustomerId', + }, + ], + }, + type: 'identify', + originalTimestamp: '2023-11-10T14:42:44.724Z', + timestamp: '2023-11-22T10:12:44.75705:30', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiToken: 'testApiToken', + userName: 'testUserName', + domain: 'rudderlabs.us-uat.gladly.qa', + }, + }, + metadata: { + jobId: 3, + }, + }, + ], + destType: 'gladly', + }, + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: [ + { + batched: false, + batchedRequest: { + body: { + FORM: {}, + JSON: { + address: 'california usa', + customAttributes: { + age: 23, + }, + emails: [ + { + original: 'test@rudderlabs.com', + }, + ], + externalCustomerId: 'externalCustomer@1', + id: 'user@1', + phones: [ + { + original: '+91 9999999999', + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + }, + endpoint: 'https://rudderlabs.us-uat.gladly.qa/api/v1/customer-profiles', + files: {}, + headers: { + Authorization: 'Basic dGVzdFVzZXJOYW1lOnRlc3RBcGlUb2tlbg==', + 'Content-Type': 'application/json', + }, + method: 'POST', + params: {}, + type: 'REST', + version: '1', + }, + destination: { + Config: { + apiToken: 'testApiToken', + domain: 'rudderlabs.us-uat.gladly.qa', + userName: 'testUserName', + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + metadata: [ + { + jobId: 1, + }, + ], + statusCode: 200, + }, + { + batched: false, + batchedRequest: { + body: { + FORM: {}, + JSON: { + address: 'New York, USA', + customAttributes: { + age: 23, + }, + emails: [ + { + original: 'test+2@rudderlabs.com', + }, + ], + externalCustomerId: 'externalCustomer@2', + phones: [ + { + original: '+91 9999999998', + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + }, + endpoint: 'https://rudderlabs.us-uat.gladly.qa/api/v1/customer-profiles/user@2', + files: {}, + headers: { + Authorization: 'Basic dGVzdFVzZXJOYW1lOnRlc3RBcGlUb2tlbg==', + 'Content-Type': 'application/json', + }, + method: 'PATCH', + params: {}, + type: 'REST', + version: '1', + }, + destination: { + Config: { + apiToken: 'testApiToken', + domain: 'rudderlabs.us-uat.gladly.qa', + userName: 'testUserName', + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + metadata: [ + { + jobId: 2, + }, + ], + statusCode: 200, + }, + { + batched: false, + batchedRequest: { + body: { + FORM: {}, + JSON: { + address: 'New York, USA', + externalCustomerId: 'externalCustomer@3', + phones: [ + { + original: '+91 9999999988', + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + }, + endpoint: 'https://rudderlabs.us-uat.gladly.qa/api/v1/customer-profiles/user@3', + files: {}, + headers: { + Authorization: 'Basic dGVzdFVzZXJOYW1lOnRlc3RBcGlUb2tlbg==', + 'Content-Type': 'application/json', + }, + method: 'PATCH', + params: {}, + type: 'REST', + version: '1', + }, + destination: { + Config: { + apiToken: 'testApiToken', + domain: 'rudderlabs.us-uat.gladly.qa', + userName: 'testUserName', + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + metadata: [ + { + jobId: 3, + }, + ], + statusCode: 200, + }, + ], + }, + }, + }, + }, + { + name: 'gladly', + description: 'Gladly rETL tests', + feature: 'router', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + input: [ + { + message: { + userId: 'externalCustomer@1', + channel: 'web', + context: { + externalId: [ + { + id: 'externalCustomer@1', + identifierType: 'externalCustomerId', + }, + ], + mappedToDestination: true + }, + traits: { + id: 'user@1', + emails: ['test@rudderlabs.com'], + phones: ['+91 9999999999'], + firstName: 'Test', + lastName: 'Rudderlabs', + address: 'california usa', + }, + type: 'identify', + originalTimestamp: '2023-11-10T14:42:44.724Z', + timestamp: '2023-11-22T10:12:44.75705:30', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiToken: 'testApiToken', + userName: 'testUserName', + domain: 'rudderlabs.us-uat.gladly.qa', + }, + }, + metadata: { + jobId: 1, + }, + }, + { + message: { + userId: 'externalCustomer@2', + channel: 'web', + context: { + externalId: [ + { + id: 'externalCustomer@2', + identifierType: 'externalCustomerId', + }, + ], + mappedToDestination: true, + }, + traits: { + id: 'user@2', + emails: 'test+2@rudderlabs.com', + phones: '+91 9999999998', + firstName: 'Test', + lastName: 'Rudderstack', + address: 'New York, USA', + }, + type: 'identify', + originalTimestamp: '2023-11-10T14:42:44.724Z', + timestamp: '2023-11-22T10:12:44.75705:30', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiToken: 'testApiToken', + userName: 'testUserName', + domain: 'rudderlabs.us-uat.gladly.qa', + }, + }, + metadata: { + jobId: 2, + }, + }, + { + message: { + userId: 'externalCustomer@3', + channel: 'web', + context: { + externalId: [ + { + id: 'externalCustomer@3', + identifierType: 'externalCustomerId', + }, + ], + mappedToDestination: true, + }, + traits: { + id: 'user@3', + phones: '+91 9999999988', + firstName: 'Test', + lastName: 'Rudderstack', + address: 'New York, USA', + }, + type: 'identify', + originalTimestamp: '2023-11-10T14:42:44.724Z', + timestamp: '2023-11-22T10:12:44.75705:30', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiToken: 'testApiToken', + userName: 'testUserName', + domain: 'rudderlabs.us-uat.gladly.qa', + }, + }, + metadata: { + jobId: 3, + }, + }, + ], + destType: 'gladly', + }, + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: [ + { + batched: false, + batchedRequest: { + body: { + FORM: {}, + JSON: { + address: 'california usa', + emails: [ + { + original: 'test@rudderlabs.com', + }, + ], + externalCustomerId: 'externalCustomer@1', + id: 'user@1', + phones: [ + { + original: '+91 9999999999', + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + }, + endpoint: 'https://rudderlabs.us-uat.gladly.qa/api/v1/customer-profiles', + files: {}, + headers: { + Authorization: 'Basic dGVzdFVzZXJOYW1lOnRlc3RBcGlUb2tlbg==', + 'Content-Type': 'application/json', + }, + method: 'POST', + params: {}, + type: 'REST', + version: '1', + }, + destination: { + Config: { + apiToken: 'testApiToken', + domain: 'rudderlabs.us-uat.gladly.qa', + userName: 'testUserName', + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + metadata: [ + { + jobId: 1, + }, + ], + statusCode: 200, + }, + { + batched: false, + batchedRequest: { + body: { + FORM: {}, + JSON: { + address: 'New York, USA', + emails: [ + { + original: 'test+2@rudderlabs.com', + }, + ], + externalCustomerId: 'externalCustomer@2', + phones: [ + { + original: '+91 9999999998', + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + }, + endpoint: 'https://rudderlabs.us-uat.gladly.qa/api/v1/customer-profiles/user@2', + files: {}, + headers: { + Authorization: 'Basic dGVzdFVzZXJOYW1lOnRlc3RBcGlUb2tlbg==', + 'Content-Type': 'application/json', + }, + method: 'PATCH', + params: {}, + type: 'REST', + version: '1', + }, + destination: { + Config: { + apiToken: 'testApiToken', + domain: 'rudderlabs.us-uat.gladly.qa', + userName: 'testUserName', + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + metadata: [ + { + jobId: 2, + }, + ], + statusCode: 200, + }, + { + batched: false, + batchedRequest: { + body: { + FORM: {}, + JSON: { + address: 'New York, USA', + externalCustomerId: 'externalCustomer@3', + phones: [ + { + original: '+91 9999999988', + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + }, + endpoint: 'https://rudderlabs.us-uat.gladly.qa/api/v1/customer-profiles/user@3', + files: {}, + headers: { + Authorization: 'Basic dGVzdFVzZXJOYW1lOnRlc3RBcGlUb2tlbg==', + 'Content-Type': 'application/json', + }, + method: 'PATCH', + params: {}, + type: 'REST', + version: '1', + }, + destination: { + Config: { + apiToken: 'testApiToken', + domain: 'rudderlabs.us-uat.gladly.qa', + userName: 'testUserName', + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + metadata: [ + { + jobId: 3, + }, + ], + statusCode: 200, + }, + ], + }, + }, + }, + }, +]; From e5f8714a51bd28154ce0c84301042f544a744479 Mon Sep 17 00:00:00 2001 From: Abhimanyu Babbar Date: Thu, 16 Nov 2023 17:52:46 +0530 Subject: [PATCH 40/93] chore: capture correct status code on faas pod time out (#2831) --- src/util/openfaas/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/openfaas/index.js b/src/util/openfaas/index.js index 47a69aeb18..2792003f4a 100644 --- a/src/util/openfaas/index.js +++ b/src/util/openfaas/index.js @@ -277,7 +277,7 @@ const executeFaasFunction = async ( } if (error.statusCode === 504) { - throw new RespStatusError(`${name} timed out`); + throw new RespStatusError(`${name} timed out`, 504); } throw error; From 5c63d2c5bc9507d43b9377ac84ce9ba7d59b37c8 Mon Sep 17 00:00:00 2001 From: Sandeep Digumarty Date: Tue, 21 Nov 2023 15:50:09 +0530 Subject: [PATCH 41/93] chore: add date mock to fix timestamp validation in tests (#2844) chore: add date mock to fix timestamp validation --- test/__tests__/facebook_conversions.test.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/__tests__/facebook_conversions.test.js b/test/__tests__/facebook_conversions.test.js index a450952efe..9495a85913 100644 --- a/test/__tests__/facebook_conversions.test.js +++ b/test/__tests__/facebook_conversions.test.js @@ -23,6 +23,8 @@ const outputRouterDataFile = fs.readFileSync( const inputRouterData = JSON.parse(inputRouterDataFile); const expectedRouterData = JSON.parse(outputRouterDataFile); +Date.now = jest.fn(() => new Date("2023-11-12T15:46:51.000Z")); // 2023-11-12T15:46:51.693229+05:30 + describe(`${name} Tests`, () => { describe("Processor", () => { testData.forEach((dataPoint, index) => { From 9eda50e850c5a1ccb46f1b54c3d176edb915eb27 Mon Sep 17 00:00:00 2001 From: shrouti1507 <60211312+shrouti1507@users.noreply.github.com> Date: Thu, 23 Nov 2023 19:51:50 +0530 Subject: [PATCH 42/93] feat: mixpanel set once feature onboard (#2820) * feat: initial commit * feat: making sure existing functionality is intact * fix: edits for exclusion keys * fix: edits for supporting property paths * fix: delete wrong test case * fix: test cases * fix: removed unnecessary code * fix: adding unit test cases for trimTraits * fix: changing the order of priority in property mapping * fix: edited distinct id logic * fix: small edit * fix: review comments addressed * fix: adding dedicated mappingJson for setOnce * fix: adding all the fields to the dedicated json * fix: addressing review comments * feat: review comments addressed --- src/v0/destinations/mp/config.js | 3 + .../destinations/mp/data/MPSetOnceConfig.json | 122 ++++++++ src/v0/destinations/mp/transform.js | 47 ++- src/v0/destinations/mp/util.js | 70 +++++ src/v0/destinations/mp/util.test.js | 94 ++++++ src/v0/util/index.js | 26 ++ test/integrations/destinations/mp/common.ts | 40 ++- .../destinations/mp/processor/data.ts | 271 +++++++++++++++++- 8 files changed, 665 insertions(+), 8 deletions(-) create mode 100644 src/v0/destinations/mp/data/MPSetOnceConfig.json diff --git a/src/v0/destinations/mp/config.js b/src/v0/destinations/mp/config.js index 41a801e9da..35b40294f5 100644 --- a/src/v0/destinations/mp/config.js +++ b/src/v0/destinations/mp/config.js @@ -11,6 +11,9 @@ const ConfigCategory = { IDENTIFY: { name: 'MPIdentifyConfig', }, + SET_ONCE: { + name: 'MPSetOnceConfig', + }, PROFILE_ANDROID: { name: 'MPProfilePropertiesAndroid', }, diff --git a/src/v0/destinations/mp/data/MPSetOnceConfig.json b/src/v0/destinations/mp/data/MPSetOnceConfig.json new file mode 100644 index 0000000000..e5aaf851a3 --- /dev/null +++ b/src/v0/destinations/mp/data/MPSetOnceConfig.json @@ -0,0 +1,122 @@ +[ + { + "destKey": "$created", + "sourceKeys": "createdAt", + "required": false + }, + { + "destKey": "$email", + "sourceKeys": "email", + "required": false + }, + { + "destKey": "$first_name", + "sourceKeys": ["firstName", "firstname", "first_name"], + "required": false + }, + { + "destKey": "$last_name", + "sourceKeys": ["lastName", "lastname", "last_name"], + "required": false + }, + { + "destKey": "$name", + "sourceKeys": "name", + "required": false + }, + { + "destKey": "$username", + "sourceKeys": ["username", "userName"], + "required": false + }, + { + "destKey": "$phone", + "sourceKeys": "phone", + "required": false + }, + { + "destKey": "$avatar", + "sourceKeys": "avatar", + "required": false + }, + { + "destKey": "$country_code", + "sourceKeys": ["country", "address.country"], + "required": false + }, + { + "destKey": "$city", + "sourceKeys": ["city", "address.city"], + "required": false + }, + { + "destKey": "$region", + "sourceKeys": ["state", "address.state", "location.region"], + "required": false + }, + { + "destKey": "$unsubscribed", + "sourceKeys": "unsubscribed", + "required": false + }, + { + "destKey": "$geo_source", + "sourceKeys": "location.geoSource", + "required": false + }, + { + "destKey": "$timezone", + "sourceKeys": "location.timezone", + "required": false + }, + { + "destKey": "$latitude", + "sourceKeys": "location.latitude", + "required": false + }, + { + "destKey": "$longitude", + "sourceKeys": "location.longitude", + "required": false + }, + { + "destKey": "$carrier", + "sourceKeys": "network.carrier", + "required": false + }, + { + "destKey": "$manufacturer", + "sourceKeys": "device.manufacturer", + "required": false + }, + { + "destKey": "$model", + "sourceKeys": "device.model", + "required": false + }, + { + "destKey": "$screen_height", + "sourceKeys": "screen.height", + "required": false + }, + { + "destKey": "$screen_width", + "sourceKeys": "screen.width", + "required": false + }, + { + "destKey": "$wifi", + "sourceKeys": "network.wifi", + "required": false + }, + { + "destKey": "$initial_referrer", + "sourceKeys": "page.initial_referrer", + "required": false + }, + { + "destKey": "$initial_referring_domain", + "sourceKeys": ["page.initial_referring_domain", "page.initialReferringDomain"], + "required": false + } +] diff --git a/src/v0/destinations/mp/transform.js b/src/v0/destinations/mp/transform.js index bb8d3e5756..3d0aaa7c4c 100644 --- a/src/v0/destinations/mp/transform.js +++ b/src/v0/destinations/mp/transform.js @@ -17,6 +17,7 @@ const { checkInvalidRtTfEvents, handleRtTfSingleEventError, groupEventsByType, + parseConfigArray, } = require('../../util'); const { ConfigCategory, @@ -35,6 +36,7 @@ const { combineBatchRequestsWithSameJobIds, groupEventsByEndpoint, batchEvents, + trimTraits, } = require('./util'); const { CommonUtils } = require('../../../util/common'); @@ -226,17 +228,51 @@ const processTrack = (message, destination) => { return returnValue; }; +const createSetOnceResponse = (message, type, destination, setOnce) => { + const payload = { + $set_once: setOnce, + $token: destination.Config.token, + $distinct_id: message.userId || message.anonymousId, + }; + + if (destination?.Config.identityMergeApi === 'simplified') { + payload.$distinct_id = message.userId || `$device:${message.anonymousId}`; + } + + return responseBuilderSimple(payload, message, type, destination.Config); +}; + const processIdentifyEvents = async (message, type, destination) => { + const messageClone = { ...message }; + let seggregatedTraits = {}; const returnValue = []; + let setOnceProperties = []; + + // making payload for set_once properties + if (destination.Config.setOnceProperties && destination.Config.setOnceProperties.length > 0) { + setOnceProperties = parseConfigArray(destination.Config.setOnceProperties, 'property'); + seggregatedTraits = trimTraits( + messageClone.traits, + messageClone.context.traits, + setOnceProperties, + ); + messageClone.traits = seggregatedTraits.traits; + messageClone.context.traits = seggregatedTraits.contextTraits; + if (Object.keys(seggregatedTraits.setOnce).length > 0) { + returnValue.push( + createSetOnceResponse(messageClone, type, destination, seggregatedTraits.setOnce), + ); + } + } // Creating the user profile // https://developer.mixpanel.com/reference/profile-set - returnValue.push(createIdentifyResponse(message, type, destination, responseBuilderSimple)); + returnValue.push(createIdentifyResponse(messageClone, type, destination, responseBuilderSimple)); if ( destination.Config?.identityMergeApi !== 'simplified' && - message.userId && - message.anonymousId && + messageClone.userId && + messageClone.anonymousId && isImportAuthCredentialsAvailable(destination) ) { // If userId and anonymousId both are present and required credentials for /import @@ -245,13 +281,13 @@ const processIdentifyEvents = async (message, type, destination) => { const trackPayload = { event: '$merge', properties: { - $distinct_ids: [message.userId, message.anonymousId], + $distinct_ids: [messageClone.userId, messageClone.anonymousId], token: destination.Config.token, }, }; const identifyTrackResponse = responseBuilderSimple( trackPayload, - message, + messageClone, 'merge', destination.Config, ); @@ -440,7 +476,6 @@ const processRouterDest = async (inputs, reqMetadata) => { destination: event.destination, }; } - let processedEvents = await process(event); processedEvents = CommonUtils.toArray(processedEvents); return processedEvents.map((res) => ({ diff --git a/src/v0/destinations/mp/util.js b/src/v0/destinations/mp/util.js index bb4c23f1b4..bb8f36fdbe 100644 --- a/src/v0/destinations/mp/util.js +++ b/src/v0/destinations/mp/util.js @@ -1,3 +1,4 @@ +const lodash = require('lodash'); const set = require('set-value'); const get = require('get-value'); const { InstrumentationError } = require('@rudderstack/integrations-lib'); @@ -14,6 +15,7 @@ const { defaultBatchRequestConfig, IsGzipSupported, isObject, + isDefinedAndNotNullAndNotEmpty, } = require('../../util'); const { ConfigCategory, @@ -26,6 +28,7 @@ const { CommonUtils } = require('../../../util/common'); const mPIdentifyConfigJson = mappingConfig[ConfigCategory.IDENTIFY.name]; const mPProfileAndroidConfigJson = mappingConfig[ConfigCategory.PROFILE_ANDROID.name]; const mPProfileIosConfigJson = mappingConfig[ConfigCategory.PROFILE_IOS.name]; +const mPSetOnceConfigJson = mappingConfig[ConfigCategory.SET_ONCE.name]; /** * this function has been used to create @@ -322,6 +325,72 @@ const combineBatchRequestsWithSameJobIds = (inputBatches) => { return combineBatches(combineBatches(inputBatches)); }; +/** + * Trims the traits and contextTraits objects based on the setOnceProperties array and returns an object containing the modified traits, contextTraits, and setOnce properties. + * + * @param {object} traits - An object representing the traits. + * @param {object} contextTraits - An object representing the context traits. + * @param {string[]} setOnceProperties - An array of property paths to be considered for the setOnce transformation. + * @returns {object} - An object containing the modified traits, contextTraits, and setOnce properties. + * + * @example + * const traits = { name: 'John', age: 30 }; + * const contextTraits = { country: 'USA', language: 'English', address: { city: 'New York', state: 'NY' }}}; + * const setOnceProperties = ['name', 'country', 'address.city']; + * + * const result = trimTraits(traits, contextTraits, setOnceProperties); + * // Output: { traits: { age: 30 }, contextTraits: { language: 'English' }, setOnce: { $name: 'John', $country_code: 'USA', city: 'New York'} } + */ +function trimTraits(traits, contextTraits, setOnceProperties) { + let sentOnceTransformedPayload; + // Create a copy of the original traits object + const traitsCopy = { ...traits }; + const contextTraitsCopy = { ...contextTraits }; + + // Initialize setOnce object + const setOnceEligible = {}; + + // Step 1: find the k-v pairs of setOnceProperties in traits and contextTraits + + setOnceProperties.forEach((propertyPath) => { + const propName = lodash.last(propertyPath.split('.')); + + const traitsValue = get(traitsCopy, propertyPath); + const contextTraitsValue = get(contextTraitsCopy, propertyPath); + + if (isDefinedAndNotNullAndNotEmpty(traitsValue)) { + setOnceEligible[propName] = traitsValue; + lodash.unset(traitsCopy, propertyPath); + } + if (isDefinedAndNotNullAndNotEmpty(contextTraitsValue)) { + if (!setOnceEligible.hasOwnProperty(propName)) { + setOnceEligible[propName] = contextTraitsValue; + } + lodash.unset(contextTraitsCopy, propertyPath); + } + }); + + if (setOnceEligible && Object.keys(setOnceEligible).length > 0) { + // Step 2: transform properties eligible as per rudderstack declared identify event mapping + // setOnce should have all traits from message.traits and message.context.traits by now + sentOnceTransformedPayload = constructPayload(setOnceEligible, mPSetOnceConfigJson); + + // Step 3: combine the transformed and custom setOnce traits + sentOnceTransformedPayload = extractCustomFields( + setOnceEligible, + sentOnceTransformedPayload, + 'root', + MP_IDENTIFY_EXCLUSION_LIST, + ); + } + + return { + traits: traitsCopy, + contextTraits: contextTraitsCopy, + setOnce: sentOnceTransformedPayload || {}, + }; +} + module.exports = { createIdentifyResponse, isImportAuthCredentialsAvailable, @@ -330,4 +399,5 @@ module.exports = { generateBatchedPayloadForArray, batchEvents, combineBatchRequestsWithSameJobIds, + trimTraits, }; diff --git a/src/v0/destinations/mp/util.test.js b/src/v0/destinations/mp/util.test.js index 6d5b24766d..fbaa6f9b9f 100644 --- a/src/v0/destinations/mp/util.test.js +++ b/src/v0/destinations/mp/util.test.js @@ -4,6 +4,7 @@ const { batchEvents, generateBatchedPayloadForArray, buildUtmParams, + trimTraits, } = require('./util'); const { FEATURE_GZIP_SUPPORT } = require('../../util/constant'); @@ -602,4 +603,97 @@ describe('Mixpanel utils test', () => { }); }); }); + describe('Unit test cases for trimTraits', () => { + // Given a valid traits object and contextTraits object, and a valid setOnceProperties array, the function should return an object containing traits, contextTraits, and setOnce properties. + it('should return an object containing traits, contextTraits, and setOnce properties when given valid inputs', () => { + const traits = { name: 'John', age: 30 }; + const contextTraits = { email: 'john@example.com' }; + const setOnceProperties = ['name', 'email']; + + const result = trimTraits(traits, contextTraits, setOnceProperties); + console.log(result); + + expect(result).toEqual({ + traits: { + age: 30, + }, + contextTraits: {}, + setOnce: { $name: 'John', $email: 'john@example.com' }, + }); + }); + + // Given an empty traits object and contextTraits object, and a valid setOnceProperties array, the function should return an object containing empty traits and contextTraits, and an empty setOnce property. + it('should return an object containing empty traits and contextTraits, and an empty setOnce property when given empty traits and contextTraits objects', () => { + const traits = {}; + const contextTraits = {}; + const setOnceProperties = ['name', 'email']; + + const result = trimTraits(traits, contextTraits, setOnceProperties); + + expect(result).toEqual({ + traits: {}, + contextTraits: {}, + setOnce: {}, + }); + }); + + // Given an empty setOnceProperties array, the function should return an object containing the original traits and contextTraits objects, and an empty setOnce property. + it('should return an object containing the original traits and contextTraits objects, and an empty setOnce property when given an empty setOnceProperties array', () => { + const traits = { name: 'John', age: 30 }; + const contextTraits = { email: 'john@example.com' }; + const setOnceProperties = []; + + const result = trimTraits(traits, contextTraits, setOnceProperties); + + expect(result).toEqual({ + traits: { name: 'John', age: 30 }, + contextTraits: { email: 'john@example.com' }, + setOnce: {}, + }); + }); + + // Given a setOnceProperties array containing properties that do not exist in either traits or contextTraits objects, the function should not add the property to the setOnce property. + it('should not add properties to the setOnce property when given setOnceProperties array with non-existent properties', () => { + const traits = { name: 'John', age: 30 }; + const contextTraits = { email: 'john@example.com' }; + const setOnceProperties = ['name', 'email', 'address']; + + const result = trimTraits(traits, contextTraits, setOnceProperties); + + expect(result).toEqual({ + traits: { age: 30 }, + contextTraits: {}, + setOnce: { $name: 'John', $email: 'john@example.com' }, + }); + }); + + // Given a setOnceProperties array containing properties with nested paths that do not exist in either traits or contextTraits objects, the function should not add the property to the setOnce property. + it('should not add properties to the setOnce property when given setOnceProperties array with non-existent nested properties', () => { + const traits = { name: 'John', age: 30, address: 'kolkata' }; + const contextTraits = { email: 'john@example.com' }; + const setOnceProperties = ['name', 'email', 'address.city']; + + const result = trimTraits(traits, contextTraits, setOnceProperties); + + expect(result).toEqual({ + traits: { age: 30, address: 'kolkata' }, + contextTraits: {}, + setOnce: { $name: 'John', $email: 'john@example.com' }, + }); + }); + + it('should add properties to the setOnce property when given setOnceProperties array with existent nested properties', () => { + const traits = { name: 'John', age: 30, address: { city: 'kolkata' }, isAdult: false }; + const contextTraits = { email: 'john@example.com' }; + const setOnceProperties = ['name', 'email', 'address.city']; + + const result = trimTraits(traits, contextTraits, setOnceProperties); + + expect(result).toEqual({ + traits: { age: 30, address: {}, isAdult: false }, + contextTraits: {}, + setOnce: { $name: 'John', $email: 'john@example.com', $city: 'kolkata' }, + }); + }); + }); }); diff --git a/src/v0/util/index.js b/src/v0/util/index.js index 0296895662..fee1d7a96d 100644 --- a/src/v0/util/index.js +++ b/src/v0/util/index.js @@ -2083,6 +2083,31 @@ const IsGzipSupported = (reqMetadata = {}) => { return false; }; +/** + * Returns an array containing the values of the specified key from each object in the input array. + * If the input array is falsy (null, undefined, empty array), an empty array is returned. + * + * @param {Array} arr - The input array from which values will be extracted. + * @param {string} key - The key of the property whose values will be extracted from each object in the input array. + * @returns {Array} - A new array containing the values of the specified key from each object in the input array. + * + * @example + * const configArray = [ + * { name: 'John', age: 25 }, + * { name: 'Jane', age: 30 }, + * { name: 'Bob', age: 35 } + * ]; + * + * const result = parseConfigArray(configArray, 'name'); + * Output: ['John', 'Jane', 'Bob'] + */ +const parseConfigArray = (arr, key) => { + if (!arr) { + return []; + } + return arr.map((item) => item[key]); +}; + // ======================================================================== // EXPORTS // ======================================================================== @@ -2192,4 +2217,5 @@ module.exports = { isValidInteger, isNewStatusCodesAccepted, IsGzipSupported, + parseConfigArray, }; diff --git a/test/integrations/destinations/mp/common.ts b/test/integrations/destinations/mp/common.ts index ad12566cc6..76ed25a760 100644 --- a/test/integrations/destinations/mp/common.ts +++ b/test/integrations/destinations/mp/common.ts @@ -20,4 +20,42 @@ const sampleDestination = { Transformations: [], }; -export { sampleDestination, defaultMockFns }; +const destinationWithSetOnceProperty = { + Config: { + apiSecret: 'dummySecret', + dataResidency: 'us', + identityMergeApi: 'simplified', + setOnceProperties: [ + { + property: 'nationality', + }, + { + property: 'firstName', + }, + { + property: 'address.city', + }, + ], + superProperties: [ + { + property: 'random', + }, + ], + token: 'dummyToken', + useNativeSDK: false, + useNewMapping: false, + userDeletionApi: 'engage', + whitelistedEvents: [], + }, + DestinationDefinition: { + DisplayName: 'Kiss Metrics', + ID: '1WhbSZ6uA3H5ChVifHpfL2H6sie', + Name: 'MIXPANEL', + }, + Enabled: true, + ID: '1WhcOCGgj9asZu850HvugU2C3Aq', + Name: 'Kiss Metrics', + Transformations: [], +}; + +export { sampleDestination, defaultMockFns, destinationWithSetOnceProperty }; diff --git a/test/integrations/destinations/mp/processor/data.ts b/test/integrations/destinations/mp/processor/data.ts index 2745c09ecc..a6ba51ee78 100644 --- a/test/integrations/destinations/mp/processor/data.ts +++ b/test/integrations/destinations/mp/processor/data.ts @@ -1,5 +1,5 @@ import { overrideDestination } from '../../../testUtils'; -import { sampleDestination, defaultMockFns } from '../common'; +import { sampleDestination, defaultMockFns, destinationWithSetOnceProperty } from '../common'; export const data = [ { @@ -5852,4 +5852,273 @@ export const data = [ }, }, }, + { + name: 'mp', + description: 'Test Set Once Property', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + description: 'Alias: with property beyond and within exclusion list', + destination: destinationWithSetOnceProperty, + message: { + anonymousId: 'e6ab2c5e-2cda-44a9-a962-e2f67df78bca', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.5', + }, + ip: '0.0.0.0', + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.5', + }, + locale: 'en-GB', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + traits: { + address: { + city: 'Disney', + }, + country: 'USA', + email: 'TestSanity@disney.com', + firstName: 'Mickey test', + lastName: 'VarChange', + createdAt: '2020-01-23T08:54:02.362Z', + nationality: 'USA', + random: 'superProp', + }, + page: { + path: '/destinations/mixpanel', + referrer: '', + search: '', + title: '', + url: 'https://docs.rudderstack.com/destinations/mixpanel', + category: 'destination', + initial_referrer: 'https://docs.rudderstack.com', + initial_referring_domain: 'docs.rudderstack.com', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36', + }, + integrations: { + All: true, + }, + page: { + path: '/destinations/mixpanel', + referrer: '', + search: '', + title: '', + url: 'https://docs.rudderstack.com/destinations/mixpanel', + category: 'destination', + initial_referrer: 'https://docs.rudderstack.com', + initial_referring_domain: 'docs.rudderstack.com', + }, + request_ip: '[::1]:53709', + type: 'identify', + userId: 'Santiy', + }, + }, + ], + method: 'POST', + }, + pathSuffix: '', + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.mixpanel.com/engage/', + headers: {}, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: { + batch: + '[{"$set_once":{"$first_name":"Mickey test","$city":"Disney","nationality":"USA"},"$token":"dummyToken","$distinct_id":"Santiy"}]', + }, + XML: {}, + FORM: {}, + }, + files: {}, + userId: 'Santiy', + }, + statusCode: 200, + }, + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.mixpanel.com/engage/', + headers: {}, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: { + batch: + '[{"$set":{"$created":"2020-01-23T08:54:02.362Z","$email":"TestSanity@disney.com","$country_code":"USA","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","random":"superProp","$lastName":"VarChange","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyToken","$distinct_id":"Santiy","$ip":"0.0.0.0","$time":null}]', + }, + XML: {}, + FORM: {}, + }, + files: {}, + userId: 'Santiy', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'mp', + description: 'Test Set Once Property with anonymousId', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + description: 'Alias: with property beyond and within exclusion list', + destination: destinationWithSetOnceProperty, + message: { + anonymousId: 'dummyAnnonymousId', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.5', + }, + ip: '0.0.0.0', + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.5', + }, + locale: 'en-GB', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + traits: { + address: { + city: 'Disney', + }, + country: 'USA', + email: 'TestSanity@disney.com', + firstName: 'Mickey test', + lastName: 'VarChange', + createdAt: '2020-01-23T08:54:02.362Z', + nationality: 'USA', + random: 'superProp', + }, + page: { + path: '/destinations/mixpanel', + referrer: '', + search: '', + title: '', + url: 'https://docs.rudderstack.com/destinations/mixpanel', + category: 'destination', + initial_referrer: 'https://docs.rudderstack.com', + initial_referring_domain: 'docs.rudderstack.com', + }, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36', + }, + integrations: { + All: true, + }, + page: { + path: '/destinations/mixpanel', + referrer: '', + search: '', + title: '', + url: 'https://docs.rudderstack.com/destinations/mixpanel', + category: 'destination', + initial_referrer: 'https://docs.rudderstack.com', + initial_referring_domain: 'docs.rudderstack.com', + }, + request_ip: '[::1]:53709', + type: 'identify', + }, + }, + ], + method: 'POST', + }, + pathSuffix: '', + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.mixpanel.com/engage/', + headers: {}, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: { + batch: + '[{"$set_once":{"$first_name":"Mickey test","$city":"Disney","nationality":"USA"},"$token":"dummyToken","$distinct_id":"$device:dummyAnnonymousId"}]', + }, + XML: {}, + FORM: {}, + }, + files: {}, + userId: 'dummyAnnonymousId', + }, + statusCode: 200, + }, + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.mixpanel.com/engage/', + headers: {}, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: { + batch: + '[{"$set":{"$created":"2020-01-23T08:54:02.362Z","$email":"TestSanity@disney.com","$country_code":"USA","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","random":"superProp","$lastName":"VarChange","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyToken","$distinct_id":"$device:dummyAnnonymousId","$ip":"0.0.0.0","$time":null}]', + }, + XML: {}, + FORM: {}, + }, + files: {}, + userId: 'dummyAnnonymousId', + }, + statusCode: 200, + }, + ], + }, + }, + }, ]; From 8c02b8ccb2101147ac84b4555e7fd07235ebf9fc Mon Sep 17 00:00:00 2001 From: Sankeerth Date: Tue, 28 Nov 2023 15:06:00 +0530 Subject: [PATCH 43/93] fix: unhandled error code in facebook_custom_audience (#2853) --- src/v0/util/facebookUtils/networkHandler.js | 3 + .../fb_custom_audience/dataDelivery/data.ts | 1120 ++++++++--------- .../fb_custom_audience/network.ts | 909 ++++++------- 3 files changed, 1008 insertions(+), 1024 deletions(-) diff --git a/src/v0/util/facebookUtils/networkHandler.js b/src/v0/util/facebookUtils/networkHandler.js index 9589d17255..e0d69fa5c8 100644 --- a/src/v0/util/facebookUtils/networkHandler.js +++ b/src/v0/util/facebookUtils/networkHandler.js @@ -195,6 +195,9 @@ const errorDetailsMap = { .setMessage('There have been too many calls to this ad-account.') .build(), }, + 200: { + default: new ErrorDetailsExtractorBuilder().setStatus(403).setMessageField('message').build(), + }, }; const getErrorDetailsFromErrorMap = (error) => { diff --git a/test/integrations/destinations/fb_custom_audience/dataDelivery/data.ts b/test/integrations/destinations/fb_custom_audience/dataDelivery/data.ts index ddb081ba87..d2220e16da 100644 --- a/test/integrations/destinations/fb_custom_audience/dataDelivery/data.ts +++ b/test/integrations/destinations/fb_custom_audience/dataDelivery/data.ts @@ -1,617 +1,573 @@ export const data = [ - { - name: 'fb_custom_audience', - description: 'successfully adding users to audience', - feature: 'dataDelivery', - module: 'destination', - version: 'v0', - input: { - request: { - body: { - version: '1', - type: 'REST', - method: 'DELETE', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', - headers: { - "test-dest-response-key": "successResponse" - }, - params: { - access_token: 'ABC', - payload: { - is_raw: true, - data_source: { - sub_type: 'ANYTHING', - }, - schema: [ - 'EMAIL', - 'DOBM', - 'DOBD', - 'DOBY', - 'PHONE', - 'GEN', - 'FI', - 'MADID', - 'ZIP', - 'ST', - 'COUNTRY', - ], - data: [ - [ - 'shrouti@abc.com', - '2', - '13', - '2013', - '@09432457768', - 'f', - 'Ms.', - 'ABC', - 'ZIP ', - '123abc ', - 'IN', - ], - ], - }, - }, - userId: '', - body: { - JSON: {}, - XML: {}, - JSON_ARRAY: {}, - FORM: {}, - }, - files: {}, - } + { + name: 'fb_custom_audience', + description: 'successfully adding users to audience', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + version: '1', + type: 'REST', + method: 'DELETE', + endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + headers: { + 'test-dest-response-key': 'successResponse', + }, + params: { + access_token: 'ABC', + payload: { + is_raw: true, + data_source: { + sub_type: 'ANYTHING', + }, + schema: [ + 'EMAIL', + 'DOBM', + 'DOBD', + 'DOBY', + 'PHONE', + 'GEN', + 'FI', + 'MADID', + 'ZIP', + 'ST', + 'COUNTRY', + ], + data: [ + [ + 'shrouti@abc.com', + '2', + '13', + '2013', + '@09432457768', + 'f', + 'Ms.', + 'ABC', + 'ZIP ', + '123abc ', + 'IN', + ], + ], }, + }, + userId: '', + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, }, - output: { - response: { - status: 200, - body: { - output: { - status: 200, - message: 'Request Processed Successfully', - destinationResponse: { - audience_id: 'aud1', - invalid_entry_samples: {}, - num_invalid_entries: 0, - num_received: 4, - session_id: '123' - } - } - } + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 200, + message: 'Request Processed Successfully', + destinationResponse: { + audience_id: 'aud1', + invalid_entry_samples: {}, + num_invalid_entries: 0, + num_received: 4, + session_id: '123', }, + }, }, + }, }, - { - name: 'fb_custom_audience', - description: 'user addition failed due to missing permission', - feature: 'dataDelivery', - module: 'destination', - version: 'v0', - input: { - request: { - body: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', - headers: { - "test-dest-response-key": "permissionMissingError" - }, - params: { - access_token: 'BCD', - payload: { - is_raw: true, - data_source: { - sub_type: 'ANYTHING', - }, - schema: [ - 'DOBM', - 'DOBD', - 'DOBY', - 'PHONE', - 'GEN', - 'FI', - 'MADID', - 'ZIP', - 'ST', - 'COUNTRY', - ], - data: [ - [ - '2', - '13', - '2013', - '@09432457768', - 'f', - 'Ms.', - 'ABC', - 'ZIP ', - '123abc ', - 'IN', - ], - ], - }, - }, - body: { - JSON: {}, - XML: {}, - JSON_ARRAY: {}, - FORM: {}, - }, - files: {}, - } + }, + { + name: 'fb_custom_audience', + description: 'user addition failed due to missing permission', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + headers: { + 'test-dest-response-key': 'permissionMissingError', + }, + params: { + access_token: 'BCD', + payload: { + is_raw: true, + data_source: { + sub_type: 'ANYTHING', + }, + schema: [ + 'DOBM', + 'DOBD', + 'DOBY', + 'PHONE', + 'GEN', + 'FI', + 'MADID', + 'ZIP', + 'ST', + 'COUNTRY', + ], + data: [ + ['2', '13', '2013', '@09432457768', 'f', 'Ms.', 'ABC', 'ZIP ', '123abc ', 'IN'], + ], }, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, }, - output: { - response: { - status: 400, - body: { - output: { - destinationResponse: { - error: { - code: 294, - message: "Missing permission. Please make sure you have ads_management permission and the application is included in the allowlist", - type: "GraphMethodException", - }, - status: 400, - - }, - message: "Missing permission. Please make sure you have ads_management permission and the application is included in the allowlist", - statTags: { - destType: "FB_CUSTOM_AUDIENCE", - destinationId: "Non-determininable", - errorCategory: "network", - errorType: "aborted", - feature: "dataDelivery", - implementation: "native", - module: "destination", - workspaceId: "Non-determininable", - }, - "status": 400, - }, - }, + }, + }, + output: { + response: { + status: 400, + body: { + output: { + destinationResponse: { + error: { + code: 294, + message: + 'Missing permission. Please make sure you have ads_management permission and the application is included in the allowlist', + type: 'GraphMethodException', + }, + status: 400, + }, + message: + 'Missing permission. Please make sure you have ads_management permission and the application is included in the allowlist', + statTags: { + destType: 'FB_CUSTOM_AUDIENCE', + destinationId: 'Non-determininable', + errorCategory: 'network', + errorType: 'aborted', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', + workspaceId: 'Non-determininable', }, + status: 400, + }, }, + }, }, - { - name: 'fb_custom_audience', - description: 'user addition failed due to unavailable audience error', - feature: 'dataDelivery', - module: 'destination', - version: 'v0', - input: { - request: { - body: { - version: '1', - type: 'REST', - method: 'DELETE', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', - headers: { - "test-dest-response-key": "audienceUnavailableError" - }, - params: { - access_token: 'ABC', - payload: { - is_raw: true, - data_source: { - sub_type: 'ANYTHING', - }, - schema: [ - 'DOBY', - 'PHONE', - 'GEN', - 'FI', - 'MADID', - 'ZIP', - 'ST', - 'COUNTRY', - ], - data: [ - [ - '2013', - '@09432457768', - 'f', - 'Ms.', - 'ABC', - 'ZIP ', - '123abc ', - 'IN', - ], - ], - }, - }, - body: { - JSON: {}, - XML: {}, - JSON_ARRAY: {}, - FORM: {}, - }, - files: {}, - } + }, + { + name: 'fb_custom_audience', + description: 'user addition failed due to unavailable audience error', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + version: '1', + type: 'REST', + method: 'DELETE', + endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + headers: { + 'test-dest-response-key': 'audienceUnavailableError', + }, + params: { + access_token: 'ABC', + payload: { + is_raw: true, + data_source: { + sub_type: 'ANYTHING', + }, + schema: ['DOBY', 'PHONE', 'GEN', 'FI', 'MADID', 'ZIP', 'ST', 'COUNTRY'], + data: [['2013', '@09432457768', 'f', 'Ms.', 'ABC', 'ZIP ', '123abc ', 'IN']], }, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, }, - output: { - response: { - status: 400, - body: { - output: { - destinationResponse: { - error: { - code: 1487301, - message: "Custom Audience Unavailable: The custom audience you are trying to use has not been shared with your ad account", - type: "GraphMethodException", - }, - status: 400, - - }, - message: "Custom Audience Unavailable: The custom audience you are trying to use has not been shared with your ad account", - statTags: { - destType: "FB_CUSTOM_AUDIENCE", - destinationId: "Non-determininable", - errorCategory: "network", - errorType: "aborted", - feature: "dataDelivery", - implementation: "native", - module: "destination", - workspaceId: "Non-determininable", - }, - "status": 400, - }, - }, + }, + }, + output: { + response: { + status: 400, + body: { + output: { + destinationResponse: { + error: { + code: 1487301, + message: + 'Custom Audience Unavailable: The custom audience you are trying to use has not been shared with your ad account', + type: 'GraphMethodException', + }, + status: 400, + }, + message: + 'Custom Audience Unavailable: The custom audience you are trying to use has not been shared with your ad account', + statTags: { + destType: 'FB_CUSTOM_AUDIENCE', + destinationId: 'Non-determininable', + errorCategory: 'network', + errorType: 'aborted', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', + workspaceId: 'Non-determininable', }, + status: 400, + }, }, + }, }, - { - name: 'fb_custom_audience', - description: 'user addition failed because the custom audience has been deleted', - feature: 'dataDelivery', - module: 'destination', - version: 'v0', - input: { - request: { - body: { - version: '1', - type: 'REST', - method: 'DELETE', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', - headers: { - "test-dest-response-key": "audienceDeletedError" - }, - params: { - access_token: 'ABC', - payload: { - is_raw: true, - data_source: { - sub_type: 'ANYTHING', - }, - schema: [ - 'DOBY', - 'PHONE', - 'GEN', - 'FI', - 'MADID', - 'ZIP', - 'ST', - 'COUNTRY', - ], - data: [ - [ - '2013', - '@09432457768', - 'f', - 'Ms.', - 'ABC', - 'ZIP ', - '123abc ', - 'IN', - ], - ], - }, - }, - body: { - JSON: {}, - XML: {}, - JSON_ARRAY: {}, - FORM: {}, - }, - files: {}, - } + }, + { + name: 'fb_custom_audience', + description: 'user addition failed because the custom audience has been deleted', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + version: '1', + type: 'REST', + method: 'DELETE', + endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + headers: { + 'test-dest-response-key': 'audienceDeletedError', + }, + params: { + access_token: 'ABC', + payload: { + is_raw: true, + data_source: { + sub_type: 'ANYTHING', + }, + schema: ['DOBY', 'PHONE', 'GEN', 'FI', 'MADID', 'ZIP', 'ST', 'COUNTRY'], + data: [['2013', '@09432457768', 'f', 'Ms.', 'ABC', 'ZIP ', '123abc ', 'IN']], }, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, }, - output: { - response: { - status: 400, - body: { - output: { - destinationResponse: { - error: { - code: 1487366, - message: "Custom Audience Has Been Deleted", - type: "GraphMethodException", - }, - status: 400, - - }, - message: "Custom Audience Has Been Deleted", - statTags: { - destType: "FB_CUSTOM_AUDIENCE", - destinationId: "Non-determininable", - errorCategory: "network", - errorType: "aborted", - feature: "dataDelivery", - implementation: "native", - module: "destination", - workspaceId: "Non-determininable", - }, - "status": 400, - }, - }, + }, + }, + output: { + response: { + status: 400, + body: { + output: { + destinationResponse: { + error: { + code: 1487366, + message: 'Custom Audience Has Been Deleted', + type: 'GraphMethodException', + }, + status: 400, }, + message: 'Custom Audience Has Been Deleted', + statTags: { + destType: 'FB_CUSTOM_AUDIENCE', + destinationId: 'Non-determininable', + errorCategory: 'network', + errorType: 'aborted', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', + workspaceId: 'Non-determininable', + }, + status: 400, + }, }, + }, }, - { - name: 'fb_custom_audience', - description: 'Failed to update the custom audience for unknown reason', - feature: 'dataDelivery', - module: 'destination', - version: 'v0', - input: { - request: { - body: { - version: '1', - type: 'REST', - method: 'DELETE', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', - headers: { - "test-dest-response-key": "failedToUpdateAudienceError" - }, - params: { - access_token: 'ABC', - payload: { - is_raw: true, - data_source: { - sub_type: 'ANYTHING', - }, - schema: [ - 'DOBY', - 'PHONE', - 'GEN', - 'FI', - 'MADID', - 'ZIP', - 'ST', - 'COUNTRY', - ], - data: [ - [ - '2013', - '@09432457768', - 'f', - 'Ms.', - 'ABC', - 'ZIP ', - '123abc ', - 'IN', - ], - ], - }, - }, - body: { - JSON: {}, - XML: {}, - JSON_ARRAY: {}, - FORM: {}, - }, - files: {}, - } + }, + { + name: 'fb_custom_audience', + description: 'Failed to update the custom audience for unknown reason', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + version: '1', + type: 'REST', + method: 'DELETE', + endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + headers: { + 'test-dest-response-key': 'failedToUpdateAudienceError', + }, + params: { + access_token: 'ABC', + payload: { + is_raw: true, + data_source: { + sub_type: 'ANYTHING', + }, + schema: ['DOBY', 'PHONE', 'GEN', 'FI', 'MADID', 'ZIP', 'ST', 'COUNTRY'], + data: [['2013', '@09432457768', 'f', 'Ms.', 'ABC', 'ZIP ', '123abc ', 'IN']], }, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, }, - output: { - response: { - status: 400, - body: { - output: { - destinationResponse: { - error: { - code: 2650, - message: "Failed to update the custom audience", - type: "GraphMethodException", - }, - status: 400, - - }, - message: "Failed to update the custom audience", - statTags: { - destType: "FB_CUSTOM_AUDIENCE", - destinationId: "Non-determininable", - errorCategory: "network", - errorType: "aborted", - feature: "dataDelivery", - implementation: "native", - module: "destination", - workspaceId: "Non-determininable", - }, - "status": 400, - }, - }, + }, + }, + output: { + response: { + status: 400, + body: { + output: { + destinationResponse: { + error: { + code: 2650, + message: 'Failed to update the custom audience', + type: 'GraphMethodException', + }, + status: 400, + }, + message: 'Failed to update the custom audience', + statTags: { + destType: 'FB_CUSTOM_AUDIENCE', + destinationId: 'Non-determininable', + errorCategory: 'network', + errorType: 'aborted', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', + workspaceId: 'Non-determininable', }, + status: 400, + }, }, + }, }, - { - name: 'fb_custom_audience', - description: 'Failed to update the custom audience as excessive number of parameters were passed in the request', - feature: 'dataDelivery', - module: 'destination', - version: 'v0', - input: { - request: { - body: { - version: '1', - type: 'REST', - method: 'DELETE', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', - headers: { - "test-dest-response-key": "parameterExceededError" - }, - params: { - access_token: 'ABC', - payload: { - is_raw: true, - data_source: { - sub_type: 'ANYTHING', - }, - schema: [ - 'DOBY', - 'PHONE', - 'GEN', - 'FI', - 'MADID', - 'ZIP', - 'ST', - 'COUNTRY', - ], - data: [ - [ - '2013', - '@09432457768', - 'f', - 'Ms.', - 'ABC', - 'ZIP ', - '123abc ', - 'IN', - ], - ], - }, - }, - body: { - JSON: {}, - XML: {}, - JSON_ARRAY: {}, - FORM: {}, - }, - files: {}, - } + }, + { + name: 'fb_custom_audience', + description: + 'Failed to update the custom audience as excessive number of parameters were passed in the request', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + version: '1', + type: 'REST', + method: 'DELETE', + endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + headers: { + 'test-dest-response-key': 'parameterExceededError', + }, + params: { + access_token: 'ABC', + payload: { + is_raw: true, + data_source: { + sub_type: 'ANYTHING', + }, + schema: ['DOBY', 'PHONE', 'GEN', 'FI', 'MADID', 'ZIP', 'ST', 'COUNTRY'], + data: [['2013', '@09432457768', 'f', 'Ms.', 'ABC', 'ZIP ', '123abc ', 'IN']], }, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, }, - output: { - response: { - status: 400, - body: { - output: { - destinationResponse: { - error: { - code: 105, - message: "The number of parameters exceeded the maximum for this operation", - type: "GraphMethodException", - }, - status: 400, - - }, - message: "The number of parameters exceeded the maximum for this operation", - statTags: { - destType: "FB_CUSTOM_AUDIENCE", - destinationId: "Non-determininable", - errorCategory: "network", - errorType: "aborted", - feature: "dataDelivery", - implementation: "native", - module: "destination", - workspaceId: "Non-determininable", - }, - "status": 400, - }, - }, + }, + }, + output: { + response: { + status: 400, + body: { + output: { + destinationResponse: { + error: { + code: 105, + message: 'The number of parameters exceeded the maximum for this operation', + type: 'GraphMethodException', + }, + status: 400, + }, + message: 'The number of parameters exceeded the maximum for this operation', + statTags: { + destType: 'FB_CUSTOM_AUDIENCE', + destinationId: 'Non-determininable', + errorCategory: 'network', + errorType: 'aborted', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', + workspaceId: 'Non-determininable', }, + status: 400, + }, }, + }, }, - { - name: 'fb_custom_audience', - description: 'user update request is throttled due to too many calls to the ad account', - feature: 'dataDelivery', - module: 'destination', - version: 'v0', - input: { - request: { - body: { - version: '1', - type: 'REST', - method: 'DELETE', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', - headers: { - "test-dest-response-key": "tooManyCallsError" - }, - params: { - access_token: 'ABC', - payload: { - is_raw: true, - data_source: { - sub_type: 'ANYTHING', - }, - schema: [ - 'DOBY', - 'PHONE', - 'GEN', - 'FI', - 'MADID', - 'ZIP', - 'ST', - 'COUNTRY', - ], - data: [ - [ - '2013', - '@09432457768', - 'f', - 'Ms.', - 'ABC', - 'ZIP ', - '123abc ', - 'IN', - ], - ], - }, - }, - body: { - JSON: {}, - XML: {}, - JSON_ARRAY: {}, - FORM: {}, - }, - files: {}, - } + }, + { + name: 'fb_custom_audience', + description: 'user update request is throttled due to too many calls to the ad account', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + version: '1', + type: 'REST', + method: 'DELETE', + endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + headers: { + 'test-dest-response-key': 'tooManyCallsError', + }, + params: { + access_token: 'ABC', + payload: { + is_raw: true, + data_source: { + sub_type: 'ANYTHING', + }, + schema: ['DOBY', 'PHONE', 'GEN', 'FI', 'MADID', 'ZIP', 'ST', 'COUNTRY'], + data: [['2013', '@09432457768', 'f', 'Ms.', 'ABC', 'ZIP ', '123abc ', 'IN']], }, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, }, - output: { - response: { - status: 429, - body: { - output: { - destinationResponse: { - error: { - code: 80003, - message: "There have been too many calls to this ad-account.", - type: "GraphMethodException", - }, - status: 429, - - }, - message: "There have been too many calls to this ad-account.", - statTags: { - destType: "FB_CUSTOM_AUDIENCE", - destinationId: "Non-determininable", - errorCategory: "network", - errorType: "throttled", - feature: "dataDelivery", - implementation: "native", - module: "destination", - workspaceId: "Non-determininable", - }, - "status": 429, - }, - }, + }, + }, + output: { + response: { + status: 429, + body: { + output: { + destinationResponse: { + error: { + code: 80003, + message: 'There have been too many calls to this ad-account.', + type: 'GraphMethodException', + }, + status: 429, + }, + message: 'There have been too many calls to this ad-account.', + statTags: { + destType: 'FB_CUSTOM_AUDIENCE', + destinationId: 'Non-determininable', + errorCategory: 'network', + errorType: 'throttled', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', + workspaceId: 'Non-determininable', + }, + status: 429, + }, + }, + }, + }, + }, + { + name: 'fb_custom_audience', + description: 'user having permission issue while updating audience', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + version: '1', + type: 'REST', + method: 'DELETE', + endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + headers: { + 'test-dest-response-key': 'code200PermissionError', + }, + params: { + access_token: 'ABC', + payload: { + is_raw: true, + data_source: { + sub_type: 'ANYTHING', + }, + schema: ['DOBY', 'PHONE', 'GEN', 'FI', 'MADID', 'ZIP', 'ST', 'COUNTRY'], + data: [['2013', '@09432457768', 'f', 'Ms.', 'ABC', 'ZIP ', '123abc ', 'IN']], }, + }, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, }, - } -] \ No newline at end of file + }, + }, + output: { + response: { + status: 403, + body: { + output: { + destinationResponse: { + error: { + code: 200, + fbtrace_id: 'AFfWqjY-_y2Q92DsyJ4DQ6f', + message: '(#200) The current user can not update audience 23861283180290489', + type: 'OAuthException', + }, + status: 403, + }, + message: '(#200) The current user can not update audience 23861283180290489', + statTags: { + destType: 'FB_CUSTOM_AUDIENCE', + destinationId: 'Non-determininable', + errorCategory: 'network', + errorType: 'aborted', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', + workspaceId: 'Non-determininable', + }, + status: 403, + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/fb_custom_audience/network.ts b/test/integrations/destinations/fb_custom_audience/network.ts index 2c19a6fe0d..7dd904fdd9 100644 --- a/test/integrations/destinations/fb_custom_audience/network.ts +++ b/test/integrations/destinations/fb_custom_audience/network.ts @@ -1,456 +1,481 @@ export const networkCallsData = [ - { - httpReq: { - version: '1', - type: 'REST', - method: 'DELETE', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', - headers: { - 'test-dest-response-key': 'successResponse' - }, - params: { - access_token: 'ABC', - payload: { - is_raw: true, - data_source: { - sub_type: 'ANYTHING', - }, - schema: [ - 'EMAIL', - 'DOBM', - 'DOBD', - 'DOBY', - 'PHONE', - 'GEN', - 'FI', - 'MADID', - 'ZIP', - 'ST', - 'COUNTRY', - ], - data: [ - [ - 'shrouti@abc.com', - '2', - '13', - '2013', - '@09432457768', - 'f', - 'Ms.', - 'ABC', - 'ZIP ', - '123abc ', - 'IN', - ], - ], - }, - }, - userId: '', - body: { - JSON: {}, - XML: {}, - JSON_ARRAY: {}, - FORM: {}, - }, - files: {}, + { + httpReq: { + version: '1', + type: 'REST', + method: 'DELETE', + endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + headers: { + 'test-dest-response-key': 'successResponse', + }, + params: { + access_token: 'ABC', + payload: { + is_raw: true, + data_source: { + sub_type: 'ANYTHING', + }, + schema: [ + 'EMAIL', + 'DOBM', + 'DOBD', + 'DOBY', + 'PHONE', + 'GEN', + 'FI', + 'MADID', + 'ZIP', + 'ST', + 'COUNTRY', + ], + data: [ + [ + 'shrouti@abc.com', + '2', + '13', + '2013', + '@09432457768', + 'f', + 'Ms.', + 'ABC', + 'ZIP ', + '123abc ', + 'IN', + ], + ], }, - httpRes: { - "data": { - "audience_id": "aud1", - "session_id": "123", - "num_received": 4, - "num_invalid_entries": 0, - "invalid_entry_samples": {} - }, - "status": 200 - } + }, + userId: '', + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, }, - { - httpReq: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', - headers: { - 'test-dest-response-key': 'permissionMissingError' - }, - params: { - access_token: 'BCD', - payload: { - is_raw: true, - data_source: { - sub_type: 'ANYTHING', - }, - schema: [ - 'DOBM', - 'DOBD', - 'DOBY', - 'PHONE', - 'GEN', - 'FI', - 'MADID', - 'ZIP', - 'ST', - 'COUNTRY', - ], - data: [ - [ - '2', - '13', - '2013', - '@09432457768', - 'f', - 'Ms.', - 'ABC', - 'ZIP ', - '123abc ', - 'IN', - ], - ], - }, - }, - userId: '', - body: { - JSON: {}, - XML: {}, - JSON_ARRAY: {}, - FORM: {}, - }, - files: {}, + httpRes: { + data: { + audience_id: 'aud1', + session_id: '123', + num_received: 4, + num_invalid_entries: 0, + invalid_entry_samples: {}, + }, + status: 200, + }, + }, + { + httpReq: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + headers: { + 'test-dest-response-key': 'permissionMissingError', + }, + params: { + access_token: 'BCD', + payload: { + is_raw: true, + data_source: { + sub_type: 'ANYTHING', + }, + schema: ['DOBM', 'DOBD', 'DOBY', 'PHONE', 'GEN', 'FI', 'MADID', 'ZIP', 'ST', 'COUNTRY'], + data: [['2', '13', '2013', '@09432457768', 'f', 'Ms.', 'ABC', 'ZIP ', '123abc ', 'IN']], + }, + }, + userId: '', + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + }, + httpRes: { + data: { + error: { + code: 294, + message: + 'Missing permission. Please make sure you have ads_management permission and the application is included in the allowlist', + type: 'GraphMethodException', + }, + }, + status: 400, + }, + }, + { + httpReq: { + version: '1', + type: 'REST', + method: 'DELETE', + endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + headers: { + 'test-dest-response-key': 'audienceUnavailableError', + }, + params: { + access_token: 'ABC', + payload: { + is_raw: true, + data_source: { + sub_type: 'ANYTHING', + }, + schema: ['DOBY', 'PHONE', 'GEN', 'FI', 'MADID', 'ZIP', 'ST', 'COUNTRY'], + data: [['2013', '@09432457768', 'f', 'Ms.', 'ABC', 'ZIP ', '123abc ', 'IN']], + }, + }, + userId: '', + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + }, + httpRes: { + data: { + error: { + code: 1487301, + message: + 'Custom Audience Unavailable: The custom audience you are trying to use has not been shared with your ad account', + type: 'GraphMethodException', + }, + }, + status: 400, + }, + }, + { + httpReq: { + version: '1', + type: 'REST', + method: 'DELETE', + endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + headers: { + 'test-dest-response-key': 'audienceDeletedError', + }, + params: { + access_token: 'ABC', + payload: { + is_raw: true, + data_source: { + sub_type: 'ANYTHING', + }, + schema: [ + 'EMAIL', + 'DOBM', + 'DOBD', + 'DOBY', + 'PHONE', + 'GEN', + 'FI', + 'MADID', + 'ZIP', + 'ST', + 'COUNTRY', + ], + data: [ + [ + 'shrouti@abc.com', + '2', + '13', + '2013', + '@09432457768', + 'f', + 'Ms.', + 'ABC', + 'ZIP ', + '123abc ', + 'IN', + ], + ], }, - httpRes: { - data: { - error: { - code: 294, - message: "Missing permission. Please make sure you have ads_management permission and the application is included in the allowlist", - type: "GraphMethodException", - } - }, - "status": 400 - } + }, + userId: '', + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, }, - { - httpReq: { - version: '1', - type: 'REST', - method: 'DELETE', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', - headers: { - 'test-dest-response-key': 'audienceUnavailableError' - }, - params: { - access_token: 'ABC', - payload: { - is_raw: true, - data_source: { - sub_type: 'ANYTHING', - }, - schema: [ - 'DOBY', - 'PHONE', - 'GEN', - 'FI', - 'MADID', - 'ZIP', - 'ST', - 'COUNTRY', - ], - data: [ - [ - '2013', - '@09432457768', - 'f', - 'Ms.', - 'ABC', - 'ZIP ', - '123abc ', - 'IN', - ], - ], - }, - }, - userId: '', - body: { - JSON: {}, - XML: {}, - JSON_ARRAY: {}, - FORM: {}, - }, - files: {}, + httpRes: { + data: { + error: { + code: 1487366, + message: 'Custom Audience Has Been Deleted', + type: 'GraphMethodException', }, - httpRes: { - data: { - error: { - code: 1487301, - message: "Custom Audience Unavailable: The custom audience you are trying to use has not been shared with your ad account", - type: "GraphMethodException", - } - }, - "status": 400 - } + }, + status: 400, }, - { - httpReq: { - version: '1', - type: 'REST', - method: 'DELETE', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', - headers: { - 'test-dest-response-key': 'audienceDeletedError' - }, - params: { - access_token: 'ABC', - payload: { - is_raw: true, - data_source: { - sub_type: 'ANYTHING', - }, - schema: [ - 'EMAIL', - 'DOBM', - 'DOBD', - 'DOBY', - 'PHONE', - 'GEN', - 'FI', - 'MADID', - 'ZIP', - 'ST', - 'COUNTRY', - ], - data: [ - [ - 'shrouti@abc.com', - '2', - '13', - '2013', - '@09432457768', - 'f', - 'Ms.', - 'ABC', - 'ZIP ', - '123abc ', - 'IN', - ], - ], - }, - }, - userId: '', - body: { - JSON: {}, - XML: {}, - JSON_ARRAY: {}, - FORM: {}, - }, - files: {}, + }, + { + httpReq: { + version: '1', + type: 'REST', + method: 'DELETE', + endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + headers: { + 'test-dest-response-key': 'failedToUpdateAudienceError', + }, + params: { + access_token: 'ABC', + payload: { + is_raw: true, + data_source: { + sub_type: 'ANYTHING', + }, + schema: [ + 'EMAIL', + 'DOBM', + 'DOBD', + 'DOBY', + 'PHONE', + 'GEN', + 'FI', + 'MADID', + 'ZIP', + 'ST', + 'COUNTRY', + ], + data: [ + [ + 'shrouti@abc.com', + '2', + '13', + '2013', + '@09432457768', + 'f', + 'Ms.', + 'ABC', + 'ZIP ', + '123abc ', + 'IN', + ], + ], }, - httpRes: { - data: { - error: { - code: 1487366, - message: "Custom Audience Has Been Deleted", - type: "GraphMethodException", - } - }, - "status": 400 - } + }, + userId: '', + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, }, - { - httpReq: { - version: '1', - type: 'REST', - method: 'DELETE', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', - headers: { - 'test-dest-response-key': 'failedToUpdateAudienceError' - }, - params: { - access_token: 'ABC', - payload: { - is_raw: true, - data_source: { - sub_type: 'ANYTHING', - }, - schema: [ - 'EMAIL', - 'DOBM', - 'DOBD', - 'DOBY', - 'PHONE', - 'GEN', - 'FI', - 'MADID', - 'ZIP', - 'ST', - 'COUNTRY', - ], - data: [ - [ - 'shrouti@abc.com', - '2', - '13', - '2013', - '@09432457768', - 'f', - 'Ms.', - 'ABC', - 'ZIP ', - '123abc ', - 'IN', - ], - ], - }, - }, - userId: '', - body: { - JSON: {}, - XML: {}, - JSON_ARRAY: {}, - FORM: {}, - }, - files: {}, + httpRes: { + data: { + error: { + code: 2650, + message: 'Failed to update the custom audience', + type: 'GraphMethodException', }, - httpRes: { - data: { - error: { - code: 2650, - message: "Failed to update the custom audience", - type: "GraphMethodException", - } - }, - "status": 400 - } + }, + status: 400, }, - { - httpReq: { - version: '1', - type: 'REST', - method: 'DELETE', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', - headers: { - 'test-dest-response-key': 'parameterExceededError' - }, - params: { - access_token: 'ABC', - payload: { - is_raw: true, - data_source: { - sub_type: 'ANYTHING', - }, - schema: [ - 'EMAIL', - 'DOBM', - 'DOBD', - 'DOBY', - 'PHONE', - 'GEN', - 'FI', - 'MADID', - 'ZIP', - 'ST', - 'COUNTRY', - ], - data: [ - [ - 'shrouti@abc.com', - '2', - '13', - '2013', - '@09432457768', - 'f', - 'Ms.', - 'ABC', - 'ZIP ', - '123abc ', - 'IN', - ], - ], - }, - }, - userId: '', - body: { - JSON: {}, - XML: {}, - JSON_ARRAY: {}, - FORM: {}, - }, - files: {}, + }, + { + httpReq: { + version: '1', + type: 'REST', + method: 'DELETE', + endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + headers: { + 'test-dest-response-key': 'parameterExceededError', + }, + params: { + access_token: 'ABC', + payload: { + is_raw: true, + data_source: { + sub_type: 'ANYTHING', + }, + schema: [ + 'EMAIL', + 'DOBM', + 'DOBD', + 'DOBY', + 'PHONE', + 'GEN', + 'FI', + 'MADID', + 'ZIP', + 'ST', + 'COUNTRY', + ], + data: [ + [ + 'shrouti@abc.com', + '2', + '13', + '2013', + '@09432457768', + 'f', + 'Ms.', + 'ABC', + 'ZIP ', + '123abc ', + 'IN', + ], + ], }, - httpRes: { - data: { - error: { - code: 105, - message: "The number of parameters exceeded the maximum for this operation", - type: "GraphMethodException", - } - }, - "status": 400 - } + }, + userId: '', + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, }, - { - httpReq: { - version: '1', - type: 'REST', - method: 'DELETE', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', - headers: { - 'test-dest-response-key': 'tooManyCallsError' - }, - params: { - access_token: 'ABC', - payload: { - is_raw: true, - data_source: { - sub_type: 'ANYTHING', - }, - schema: [ - 'EMAIL', - 'DOBM', - 'DOBD', - 'DOBY', - 'PHONE', - 'GEN', - 'FI', - 'MADID', - 'ZIP', - 'ST', - 'COUNTRY', - ], - data: [ - [ - 'shrouti@abc.com', - '2', - '13', - '2013', - '@09432457768', - 'f', - 'Ms.', - 'ABC', - 'ZIP ', - '123abc ', - 'IN', - ], - ], - }, - }, - userId: '', - body: { - JSON: {}, - XML: {}, - JSON_ARRAY: {}, - FORM: {}, - }, - files: {}, + httpRes: { + data: { + error: { + code: 105, + message: 'The number of parameters exceeded the maximum for this operation', + type: 'GraphMethodException', }, - httpRes: { - data: { - error: { - code: 80003, - message: "There have been too many calls to this ad-account.", - type: "GraphMethodException", - } - }, - "status": 429 - } - } -]; \ No newline at end of file + }, + status: 400, + }, + }, + { + httpReq: { + version: '1', + type: 'REST', + method: 'DELETE', + endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + headers: { + 'test-dest-response-key': 'tooManyCallsError', + }, + params: { + access_token: 'ABC', + payload: { + is_raw: true, + data_source: { + sub_type: 'ANYTHING', + }, + schema: [ + 'EMAIL', + 'DOBM', + 'DOBD', + 'DOBY', + 'PHONE', + 'GEN', + 'FI', + 'MADID', + 'ZIP', + 'ST', + 'COUNTRY', + ], + data: [ + [ + 'shrouti@abc.com', + '2', + '13', + '2013', + '@09432457768', + 'f', + 'Ms.', + 'ABC', + 'ZIP ', + '123abc ', + 'IN', + ], + ], + }, + }, + userId: '', + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + }, + httpRes: { + data: { + error: { + code: 80003, + message: 'There have been too many calls to this ad-account.', + type: 'GraphMethodException', + }, + }, + status: 429, + }, + }, + { + httpReq: { + version: '1', + type: 'REST', + method: 'DELETE', + endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + headers: { + 'test-dest-response-key': 'code200PermissionError', + }, + params: { + access_token: 'ABC', + payload: { + is_raw: true, + data_source: { + sub_type: 'ANYTHING', + }, + schema: [ + 'EMAIL', + 'DOBM', + 'DOBD', + 'DOBY', + 'PHONE', + 'GEN', + 'FI', + 'MADID', + 'ZIP', + 'ST', + 'COUNTRY', + ], + data: [ + [ + 'shrouti@abc.com', + '2', + '13', + '2013', + '@09432457768', + 'f', + 'Ms.', + 'ABC', + 'ZIP ', + '123abc ', + 'IN', + ], + ], + }, + }, + userId: '', + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: {}, + }, + files: {}, + }, + httpRes: { + data: { + error: { + code: 200, + fbtrace_id: 'AFfWqjY-_y2Q92DsyJ4DQ6f', + message: '(#200) The current user can not update audience 23861283180290489', + type: 'OAuthException', + }, + }, + status: 403, + }, + }, +]; From cd9a046f66eab8363373cb9a0fa1afeef3137d78 Mon Sep 17 00:00:00 2001 From: Utsab Chowdhury Date: Wed, 29 Nov 2023 12:06:38 +0530 Subject: [PATCH 44/93] fix: sfmc bug fix for track event validations (#2852) --- src/v0/destinations/sfmc/transform.js | 23 +++- src/v0/destinations/sfmc/transform.test.js | 125 ++++++++++++++++++++ test/__tests__/data/sfmc_output.json | 2 +- test/__tests__/data/sfmc_router_output.json | 2 +- 4 files changed, 145 insertions(+), 7 deletions(-) create mode 100644 src/v0/destinations/sfmc/transform.test.js diff --git a/src/v0/destinations/sfmc/transform.js b/src/v0/destinations/sfmc/transform.js index 879ca1989a..7623d751f1 100644 --- a/src/v0/destinations/sfmc/transform.js +++ b/src/v0/destinations/sfmc/transform.js @@ -3,6 +3,8 @@ const { NetworkError, ConfigurationError, InstrumentationError, + isDefinedAndNotNull, + isEmpty, } = require('@rudderstack/integrations-lib'); const myAxios = require('../../../util/myAxios'); const { EventType } = require('../../../constants'); @@ -17,7 +19,6 @@ const { flattenJson, toTitleCase, getHashFromArray, - isEmpty, simpleProcessRouterDest, } = require('../../util'); const { @@ -221,10 +222,22 @@ const responseBuilderSimple = async (message, category, destination) => { } if (category.type === 'identify' && createOrUpdateContacts) { - throw new ConfigurationError('Creating or updating contacts is disabled'); + throw new ConfigurationError( + 'Creating or updating contacts is disabled. To enable this feature set "Do Not Create or Update Contacts" to false', + ); } - if (category.type === 'track' && hashMapExternalKey[message.event.toLowerCase()]) { + if (category.type === 'track') { + if (isEmpty(message.event)) { + throw new ConfigurationError('Event name is required for track events'); + } + if (typeof message.event !== 'string') { + throw new ConfigurationError('Event name must be a string'); + } + if (!isDefinedAndNotNull(hashMapExternalKey[message.event.toLowerCase()])) { + throw new ConfigurationError('Event not mapped for this track call'); + } + return responseBuilderForInsertData( message, hashMapExternalKey[message.event.toLowerCase()], @@ -237,7 +250,7 @@ const responseBuilderSimple = async (message, category, destination) => { ); } - throw new ConfigurationError('Event not mapped for this track call'); + throw new ConfigurationError(`Event type '${category.type}' not supported`); }; const processEvent = async (message, destination) => { @@ -274,4 +287,4 @@ const processRouterDest = async (inputs, reqMetadata) => { return respList; }; -module.exports = { process, processRouterDest }; +module.exports = { process, processRouterDest, responseBuilderSimple }; diff --git a/src/v0/destinations/sfmc/transform.test.js b/src/v0/destinations/sfmc/transform.test.js new file mode 100644 index 0000000000..c49c49017c --- /dev/null +++ b/src/v0/destinations/sfmc/transform.test.js @@ -0,0 +1,125 @@ +const { ConfigurationError } = require('@rudderstack/integrations-lib'); +const axios = require('axios'); +const MockAxiosAdapter = require('axios-mock-adapter'); +const { responseBuilderSimple } = require('./transform'); +beforeAll(() => { + const mock = new MockAxiosAdapter(axios); + mock + .onPost('https://yourSubDomain.auth.marketingcloudapis.com/v2/token') + .reply(200, '{"access_token":"yourAuthToken"}'); +}); + +describe('responseBuilderSimple', () => { + const destination = { + Config: { + clientId: 'yourClientId', + clientSecret: 'yourClientSecret', + subDomain: 'yourSubDomain', + createOrUpdateContacts: false, + externalKey: 'yourExternalKey', + eventToExternalKey: [{ from: 'purchase', to: 'purchaseKey' }], + eventToPrimaryKey: [{ from: 'purchase', to: 'primaryKey' }], + eventToUUID: [{ event: 'purchase', uuid: true }], + }, + }; + it('should return an array of two payloads for identify calls when createOrUpdateContacts is false', async () => { + const message = { + type: 'identify', + userId: '12345', + }; + + const category = { + type: 'identify', + name: 'Identify', + }; + + const response = await responseBuilderSimple(message, category, destination); + + expect(response).toHaveLength(2); + expect(response[0]).toHaveProperty('endpoint'); + expect(response[0]).toHaveProperty('method'); + expect(response[0]).toHaveProperty('body.JSON'); + expect(response[0]).toHaveProperty('headers'); + expect(response[1]).toHaveProperty('endpoint'); + expect(response[1]).toHaveProperty('method'); + expect(response[1]).toHaveProperty('body.JSON'); + expect(response[1]).toHaveProperty('headers'); + }); + + // Throws an error when event name is not provided for track calls + it('should throw an error when event name is not provided for track calls', async () => { + const message = { + type: 'track', + }; + + const category = { + type: 'track', + name: 'Track', + }; + + try { + await responseBuilderSimple(message, category, destination); + } catch (e) { + expect(e).toBeInstanceOf(ConfigurationError); + expect(e.message).toBe('Event name is required for track events'); + } + }); + + // Throws an error when event is not mapped for track calls + it('should throw an error when event is not mapped for track calls', async () => { + const message = { + type: 'track', + event: 'unmappedEvent', + }; + + const category = { + type: 'track', + name: 'Track', + }; + try { + await responseBuilderSimple(message, category, destination); + } catch (e) { + expect(e).toBeInstanceOf(ConfigurationError); + expect(e.message).toBe('Event not mapped for this track call'); + } + }); + + // Throws an error when event type is not supported + it('should throw an error when event type is not supported', async () => { + const message = { + type: 'unsupported', + }; + + const category = { + type: 'unsupported', + name: 'Unsupported', + }; + + try { + await responseBuilderSimple(message, category, destination); + } catch (e) { + expect(e).toBeInstanceOf(ConfigurationError); + expect(e.message).toBe("Event type 'unsupported' not supported"); + } + }); + + // Returns a payload for track calls when event is mapped and event name is a string + it('should return a payload for track calls when event is mapped and event name is a string', async () => { + const message = { + type: 'track', + event: 'purchase', + userId: '12345', + }; + + const category = { + type: 'track', + name: 'Track', + }; + + const response = await responseBuilderSimple(message, category, destination); + expect(response).toHaveProperty('endpoint'); + expect(response).toHaveProperty('method'); + expect(response).toHaveProperty('body.JSON'); + expect(response).toHaveProperty('headers'); + }); +}); diff --git a/test/__tests__/data/sfmc_output.json b/test/__tests__/data/sfmc_output.json index 0271475e4a..aaaf23aea8 100644 --- a/test/__tests__/data/sfmc_output.json +++ b/test/__tests__/data/sfmc_output.json @@ -1,6 +1,6 @@ [ { - "error": "Creating or updating contacts is disabled" + "error": "Creating or updating contacts is disabled. To enable this feature set \"Do Not Create or Update Contacts\" to false" }, [ { diff --git a/test/__tests__/data/sfmc_router_output.json b/test/__tests__/data/sfmc_router_output.json index d207b792ee..beb90b5e13 100644 --- a/test/__tests__/data/sfmc_router_output.json +++ b/test/__tests__/data/sfmc_router_output.json @@ -37,7 +37,7 @@ }, "batched": false, "statusCode": 400, - "error": "Creating or updating contacts is disabled", + "error": "Creating or updating contacts is disabled. To enable this feature set \"Do Not Create or Update Contacts\" to false", "statTags": { "errorCategory": "dataValidation", "errorType": "configuration" From 91d4cd16f9839b0be5a663ca5010bdd72cff9bdc Mon Sep 17 00:00:00 2001 From: Sankeerth Date: Wed, 29 Nov 2023 12:54:12 +0530 Subject: [PATCH 45/93] fix: remove errorCategory for braze dedup error (#2850) --- src/v0/util/errorTypes/filteredEventsError.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/v0/util/errorTypes/filteredEventsError.js b/src/v0/util/errorTypes/filteredEventsError.js index 35a384f4e3..cb0236f342 100644 --- a/src/v0/util/errorTypes/filteredEventsError.js +++ b/src/v0/util/errorTypes/filteredEventsError.js @@ -1,13 +1,9 @@ -const tags = require('../tags'); const { BaseError } = require('./base'); const { HTTP_STATUS_CODES } = require('../constant'); class FilteredEventsError extends BaseError { constructor(message, statusCode = HTTP_STATUS_CODES.FILTER_EVENTS) { - const finalStatTags = { - [tags.TAG_NAMES.ERROR_CATEGORY]: tags.ERROR_CATEGORIES.TRANSFORMATION, - }; - super(message, statusCode, finalStatTags); + super(message, statusCode); } } From 3127a1ca8dc1b887f9158a1d839c5504f40c4678 Mon Sep 17 00:00:00 2001 From: Sandeep Digumarty Date: Wed, 29 Nov 2023 16:37:21 +0530 Subject: [PATCH 46/93] feat: update facebook destinations API version to v18.0 (#2828) * feat: update facebook destinations API version to v18.0 * feat: updated fb_pixel tests to pick version dynamically from config.js * feat: updated fb tests to pick version dynamically from config.js * feat: updated fb_custom_audience tests to pick version dynamically from config.js --- src/v0/destinations/facebook_pixel/config.js | 3 + .../destinations/facebook_pixel/transform.js | 3 +- src/v0/destinations/fb/config.js | 3 + src/v0/destinations/fb/transform.js | 3 +- .../destinations/fb_custom_audience/config.js | 4 +- .../facebook_pixel/dataDelivery/data.ts | 29 +- .../destinations/facebook_pixel/network.ts | 19 +- .../facebook_pixel/processor/data.ts | 79 +-- .../facebook_pixel/router/data.ts | 6 +- .../destinations/fb/dataDelivery/data.ts | 649 +++++++++--------- test/integrations/destinations/fb/network.ts | 5 +- .../destinations/fb/processor/data.ts | 24 +- .../fb_custom_audience/dataDelivery/data.ts | 18 +- .../fb_custom_audience/network.ts | 18 +- .../fb_custom_audience/processor/data.ts | 44 +- .../fb_custom_audience/router/data.ts | 20 +- 16 files changed, 479 insertions(+), 448 deletions(-) diff --git a/src/v0/destinations/facebook_pixel/config.js b/src/v0/destinations/facebook_pixel/config.js index f5f895aea9..17d5887e1b 100644 --- a/src/v0/destinations/facebook_pixel/config.js +++ b/src/v0/destinations/facebook_pixel/config.js @@ -1,5 +1,7 @@ const { getMappingConfig } = require('../../util'); +const VERSION = 'v18.0'; + const CONFIG_CATEGORIES = { USERDATA: { standard: false, @@ -106,6 +108,7 @@ const STANDARD_ECOMM_EVENTS_TYPE = [ ]; module.exports = { + VERSION, CONFIG_CATEGORIES, MAPPING_CONFIG, ACTION_SOURCES_VALUES, diff --git a/src/v0/destinations/facebook_pixel/transform.js b/src/v0/destinations/facebook_pixel/transform.js index 1bc97ac1fb..8a63998b45 100644 --- a/src/v0/destinations/facebook_pixel/transform.js +++ b/src/v0/destinations/facebook_pixel/transform.js @@ -4,6 +4,7 @@ const moment = require('moment'); const { InstrumentationError, ConfigurationError } = require('@rudderstack/integrations-lib'); const stats = require('../../../util/stats'); const { + VERSION, CONFIG_CATEGORIES, MAPPING_CONFIG, FB_PIXEL_DEFAULT_EXCLUSION, @@ -65,7 +66,7 @@ const responseBuilderSimple = (message, category, destination) => { } = Config; const integrationsObj = getIntegrationsObj(message, 'fb_pixel'); - const endpoint = `https://graph.facebook.com/v17.0/${pixelId}/events?access_token=${accessToken}`; + const endpoint = `https://graph.facebook.com/${VERSION}/${pixelId}/events?access_token=${accessToken}`; const userData = fetchUserData( message, diff --git a/src/v0/destinations/fb/config.js b/src/v0/destinations/fb/config.js index 2ad9aeacba..0e52b42416 100644 --- a/src/v0/destinations/fb/config.js +++ b/src/v0/destinations/fb/config.js @@ -1,6 +1,8 @@ const fs = require('fs'); const path = require('path'); +const VERSION = 'v18.0'; + const getPath = (file) => path.resolve(__dirname, file); const baseMapping = JSON.parse(fs.readFileSync(getPath('./data/FbAppBasicMapping.json'))); @@ -20,6 +22,7 @@ const eventPropToTypeMapping = JSON.parse( ); module.exports = { + VERSION, baseMapping, eventNameMapping, eventPropsMapping, diff --git a/src/v0/destinations/fb/transform.js b/src/v0/destinations/fb/transform.js index c0d78a2b3f..e6f8e986cf 100644 --- a/src/v0/destinations/fb/transform.js +++ b/src/v0/destinations/fb/transform.js @@ -14,6 +14,7 @@ const { } = require('../../util'); const { + VERSION, baseMapping, eventNameMapping, eventPropsMapping, @@ -250,7 +251,7 @@ function responseBuilderSimple(message, payload, destination) { // "https://graph.facebook.com/v13.0/644748472345539/activities" - const endpoint = `https://graph.facebook.com/v17.0/${appID}/activities`; + const endpoint = `https://graph.facebook.com/${VERSION}/${appID}/activities`; const response = defaultRequestConfig(); response.endpoint = endpoint; diff --git a/src/v0/destinations/fb_custom_audience/config.js b/src/v0/destinations/fb_custom_audience/config.js index 635ad2a9bb..284ab0d4a4 100644 --- a/src/v0/destinations/fb_custom_audience/config.js +++ b/src/v0/destinations/fb_custom_audience/config.js @@ -1,4 +1,4 @@ -const BASE_URL = 'https://graph.facebook.com/v17.0'; +const BASE_URL = 'https://graph.facebook.com/v18.0'; function getEndPoint(audienceId) { return `${BASE_URL}/${audienceId}/users`; @@ -93,7 +93,7 @@ const subTypeFields = [ // const MAX_USER_COUNT = 500; (using from destination definition) const USER_ADD = 'add'; const USER_DELETE = 'remove'; -/* No official Documentation is available for this but using trial +/* No official Documentation is available for this but using trial and error method we found that 65000 bytes is the maximum payload allowed size but we are 60000 just to be sure batching is done properly */ const maxPayloadSize = 60000; // bytes diff --git a/test/integrations/destinations/facebook_pixel/dataDelivery/data.ts b/test/integrations/destinations/facebook_pixel/dataDelivery/data.ts index d560658341..eb9ce344e0 100644 --- a/test/integrations/destinations/facebook_pixel/dataDelivery/data.ts +++ b/test/integrations/destinations/facebook_pixel/dataDelivery/data.ts @@ -1,3 +1,5 @@ +import { VERSION } from '../../../../../src/v0/destinations/facebook_pixel/config'; + export const data = [ { name: 'facebook_pixel', @@ -24,8 +26,7 @@ export const data = [ userId: '', headers: {}, version: '1', - endpoint: - 'https://graph.facebook.com/v17.0/1234567891234567/events?access_token=invalid_access_token', + endpoint: `https://graph.facebook.com/${VERSION}/1234567891234567/events?access_token=invalid_access_token`, params: { destination: 'facebook_pixel', }, @@ -89,8 +90,7 @@ export const data = [ userId: '', headers: {}, version: '1', - endpoint: - 'https://graph.facebook.com/v17.0/1234567891234567/events?access_token=my_access_token', + endpoint: `https://graph.facebook.com/${VERSION}/1234567891234567/events?access_token=my_access_token`, params: { destination: 'facebook_pixel', }, @@ -139,8 +139,7 @@ export const data = [ userId: '', headers: {}, version: '1', - endpoint: - 'https://graph.facebook.com/v17.0/1234567891234567/events?access_token=invalid_timestamp_correct_access_token', + endpoint: `https://graph.facebook.com/${VERSION}/1234567891234567/events?access_token=invalid_timestamp_correct_access_token`, params: { destination: 'facebook_pixel', }, @@ -209,8 +208,7 @@ export const data = [ userId: '', headers: {}, version: '1', - endpoint: - 'https://graph.facebook.com/v17.0/1234567891234567/events?access_token=throttled_valid_access_token', + endpoint: `https://graph.facebook.com/${VERSION}/1234567891234567/events?access_token=throttled_valid_access_token`, params: { destination: 'facebook_pixel', }, @@ -274,8 +272,7 @@ export const data = [ userId: '', headers: {}, version: '1', - endpoint: - 'https://graph.facebook.com/v17.0/1234567891234567/events?access_token=invalid_account_id_valid_access_token', + endpoint: `https://graph.facebook.com/${VERSION}/1234567891234567/events?access_token=invalid_account_id_valid_access_token`, params: { destination: 'facebook_pixel', }, @@ -342,8 +339,7 @@ export const data = [ userId: '', headers: {}, version: '1', - endpoint: - 'https://graph.facebook.com/v17.0/1234567891234567/events?access_token=not_found_access_token', + endpoint: `https://graph.facebook.com/${VERSION}/1234567891234567/events?access_token=not_found_access_token`, params: { destination: 'facebook_pixel', }, @@ -411,8 +407,7 @@ export const data = [ userId: '', headers: {}, version: '1', - endpoint: - 'https://graph.facebook.com/v17.0/1234567891234570/events?access_token=valid_access_token', + endpoint: `https://graph.facebook.com/${VERSION}/1234567891234570/events?access_token=valid_access_token`, }, method: 'POST', }, @@ -477,8 +472,7 @@ export const data = [ userId: '', headers: {}, version: '1', - endpoint: - 'https://graph.facebook.com/v17.0/1234567891234571/events?access_token=valid_access_token', + endpoint: `https://graph.facebook.com/${VERSION}/1234567891234571/events?access_token=valid_access_token`, }, method: 'POST', }, @@ -543,8 +537,7 @@ export const data = [ userId: '', headers: {}, version: '1', - endpoint: - 'https://graph.facebook.com/v17.0/1234567891234572/events?access_token=valid_access_token_unhandled_response', + endpoint: `https://graph.facebook.com/${VERSION}/1234567891234572/events?access_token=valid_access_token_unhandled_response`, }, method: 'POST', }, diff --git a/test/integrations/destinations/facebook_pixel/network.ts b/test/integrations/destinations/facebook_pixel/network.ts index a63970c4c6..05b3a05fd0 100644 --- a/test/integrations/destinations/facebook_pixel/network.ts +++ b/test/integrations/destinations/facebook_pixel/network.ts @@ -1,10 +1,11 @@ import { data } from './dataDelivery/data'; import { getFormData } from '../../../../src/adapters/network'; +import { VERSION } from '../../../../src/v0/destinations/facebook_pixel/config'; export const networkCallsData = [ { httpReq: { - url: 'https://graph.facebook.com/v17.0/1234567891234567/events?access_token=invalid_access_token', + url: `https://graph.facebook.com/${VERSION}/1234567891234567/events?access_token=invalid_access_token`, data: getFormData(data[0].input.request.body.body.FORM).toString(), params: { destination: 'facebook_pixel' }, headers: { 'User-Agent': 'RudderLabs' }, @@ -24,7 +25,7 @@ export const networkCallsData = [ }, { httpReq: { - url: 'https://graph.facebook.com/v17.0/1234567891234567/events?access_token=invalid_timestamp_correct_access_token', + url: `https://graph.facebook.com/${VERSION}/1234567891234567/events?access_token=invalid_timestamp_correct_access_token`, data: getFormData(data[2].input.request.body.body.FORM).toString(), params: { destination: 'facebook_pixel' }, headers: { 'User-Agent': 'RudderLabs' }, @@ -49,7 +50,7 @@ export const networkCallsData = [ }, { httpReq: { - url: 'https://graph.facebook.com/v17.0/1234567891234567/events?access_token=throttled_valid_access_token', + url: `https://graph.facebook.com/${VERSION}/1234567891234567/events?access_token=throttled_valid_access_token`, data: getFormData(data[3].input.request.body.body.FORM).toString(), params: { destination: 'facebook_pixel' }, headers: { 'User-Agent': 'RudderLabs' }, @@ -69,7 +70,7 @@ export const networkCallsData = [ }, { httpReq: { - url: 'https://graph.facebook.com/v17.0/1234567891234567/events?access_token=invalid_account_id_valid_access_token', + url: `https://graph.facebook.com/${VERSION}/1234567891234567/events?access_token=invalid_account_id_valid_access_token`, data: getFormData(data[4].input.request.body.body.FORM).toString(), params: { destination: 'facebook_pixel' }, headers: { 'User-Agent': 'RudderLabs' }, @@ -91,7 +92,7 @@ export const networkCallsData = [ }, { httpReq: { - url: 'https://graph.facebook.com/v17.0/1234567891234567/events?access_token=not_found_access_token', + url: `https://graph.facebook.com/${VERSION}/1234567891234567/events?access_token=not_found_access_token`, data: getFormData(data[5].input.request.body.body.FORM).toString(), params: { destination: 'facebook_pixel' }, headers: { 'User-Agent': 'RudderLabs' }, @@ -112,7 +113,7 @@ export const networkCallsData = [ }, { httpReq: { - url: 'https://graph.facebook.com/v17.0/1234567891234570/events?access_token=valid_access_token', + url: `https://graph.facebook.com/${VERSION}/1234567891234570/events?access_token=valid_access_token`, data: getFormData(data[6].input.request.body.body.FORM).toString(), params: { destination: 'facebook_pixel' }, headers: { 'User-Agent': 'RudderLabs' }, @@ -133,7 +134,7 @@ export const networkCallsData = [ }, { httpReq: { - url: 'https://graph.facebook.com/v17.0/1234567891234571/events?access_token=valid_access_token', + url: `https://graph.facebook.com/${VERSION}/1234567891234571/events?access_token=valid_access_token`, data: getFormData(data[7].input.request.body.body.FORM).toString(), params: { destination: 'facebook_pixel' }, headers: { 'User-Agent': 'RudderLabs' }, @@ -154,7 +155,7 @@ export const networkCallsData = [ }, { httpReq: { - url: 'https://graph.facebook.com/v17.0/1234567891234572/events?access_token=valid_access_token_unhandled_response', + url: `https://graph.facebook.com/${VERSION}/1234567891234572/events?access_token=valid_access_token_unhandled_response`, data: getFormData(data[8].input.request.body.body.FORM).toString(), params: { destination: 'facebook_pixel' }, headers: { 'User-Agent': 'RudderLabs' }, @@ -175,7 +176,7 @@ export const networkCallsData = [ }, { httpReq: { - url: 'https://graph.facebook.com/v17.0/1234567891234567/events?access_token=my_access_token', + url: `https://graph.facebook.com/${VERSION}/1234567891234567/events?access_token=my_access_token`, data: getFormData(data[1].input.request.body.body.FORM).toString(), params: { destination: 'facebook_pixel' }, headers: { 'User-Agent': 'RudderLabs' }, diff --git a/test/integrations/destinations/facebook_pixel/processor/data.ts b/test/integrations/destinations/facebook_pixel/processor/data.ts index 96e80c01e8..557bc7066c 100644 --- a/test/integrations/destinations/facebook_pixel/processor/data.ts +++ b/test/integrations/destinations/facebook_pixel/processor/data.ts @@ -1,3 +1,5 @@ +import { VERSION } from '../../../../../src/v0/destinations/facebook_pixel/config'; + export const mockFns = (_) => { // @ts-ignore jest.useFakeTimers().setSystemTime(new Date('2023-10-15')); @@ -106,7 +108,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/dummyPixelId/events?access_token=09876', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, headers: {}, params: {}, body: { @@ -445,7 +447,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/dummyPixelId/events?access_token=09876', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, headers: {}, params: {}, body: { @@ -569,7 +571,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/dummyPixelId/events?access_token=09876', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, headers: {}, params: {}, body: { @@ -688,7 +690,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/dummyPixelId/events?access_token=09876', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, headers: {}, params: {}, body: { @@ -807,7 +809,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/dummyPixelId/events?access_token=09876', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, headers: {}, params: {}, body: { @@ -927,7 +929,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/dummyPixelId/events?access_token=09876', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, headers: {}, params: {}, body: { @@ -1047,7 +1049,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/dummyPixelId/events?access_token=09876', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, headers: {}, params: {}, body: { @@ -1166,7 +1168,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/dummyPixelId/events?access_token=09876', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, headers: {}, params: {}, body: { @@ -1284,7 +1286,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/dummyPixelId/events?access_token=09876', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, headers: {}, params: {}, body: { @@ -1419,7 +1421,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/dummyPixelId/events?access_token=09876', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, headers: {}, params: {}, body: { @@ -1554,7 +1556,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/dummyPixelId/events?access_token=09876', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, headers: {}, params: {}, body: { @@ -1705,7 +1707,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/dummyPixelId/events?access_token=09876', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, headers: {}, params: {}, body: { @@ -1855,7 +1857,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/dummyPixelId/events?access_token=09876', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, headers: {}, params: {}, body: { @@ -1984,7 +1986,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/dummyPixelId/events?access_token=09876', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, headers: {}, params: {}, body: { @@ -2106,7 +2108,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/dummyPixelId/events?access_token=09876', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, headers: {}, params: {}, body: { @@ -2249,7 +2251,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/dummyPixelId/events?access_token=09876', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, headers: {}, params: {}, body: { @@ -2392,7 +2394,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/dummyPixelId/events?access_token=09876', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, headers: {}, params: {}, body: { @@ -2516,7 +2518,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/dummyPixelId/events?access_token=09876', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, headers: {}, params: {}, body: { @@ -2640,7 +2642,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/dummyPixelId/events?access_token=09876', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, headers: {}, params: {}, body: { @@ -2768,7 +2770,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/dummyPixelId/events?access_token=09876', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, headers: {}, params: {}, body: { @@ -2893,7 +2895,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/dummyPixelId/events?access_token=09876', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, headers: {}, params: {}, body: { @@ -3014,7 +3016,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/dummyPixelId/events?access_token=09876', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, headers: {}, params: {}, body: { @@ -3133,7 +3135,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/dummyPixelId/events?access_token=09876', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, headers: {}, params: {}, body: { @@ -3282,7 +3284,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/dummyPixelId/events?access_token=09876', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, headers: {}, params: {}, body: { @@ -3510,7 +3512,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/dummyPixelId/events?access_token=09876', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, headers: {}, params: {}, body: { @@ -3631,7 +3633,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/dummyPixelId/events?access_token=09876', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, headers: {}, params: {}, body: { @@ -3884,7 +3886,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/dummyPixelId/events?access_token=09876', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, headers: {}, params: {}, body: { @@ -4027,7 +4029,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/dummyPixelId/events?access_token=09876', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, headers: {}, params: {}, body: { @@ -4289,7 +4291,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/dummyPixelId/events?access_token=09876', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, headers: {}, params: {}, body: { @@ -4752,7 +4754,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/dummyPixelId/events?access_token=09876', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, headers: {}, params: {}, body: { @@ -4897,7 +4899,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/dummyPixelId/events?access_token=09876', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, headers: {}, params: {}, body: { @@ -5178,7 +5180,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/dummyPixelId/events?access_token=09876', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, headers: {}, params: {}, body: { @@ -5310,7 +5312,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/dummyPixelId/events?access_token=09876', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, headers: {}, params: {}, body: { @@ -5440,7 +5442,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/dummyPixelId/events?access_token=09876', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, headers: {}, params: {}, body: { @@ -6032,8 +6034,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: - 'https://graph.facebook.com/v17.0/dummyPixelId/events?access_token=dummyAccessToken', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=dummyAccessToken`, headers: {}, params: {}, body: { @@ -6181,7 +6182,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/dummyPixelId/events?access_token=09876', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, headers: {}, params: {}, body: { @@ -6306,7 +6307,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/dummyPixelId/events?access_token=09876', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, headers: {}, params: {}, body: { @@ -6437,7 +6438,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/dummyPixelId/events?access_token=09876', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, headers: {}, params: {}, body: { diff --git a/test/integrations/destinations/facebook_pixel/router/data.ts b/test/integrations/destinations/facebook_pixel/router/data.ts index ef6b9f8635..ee2f6968b1 100644 --- a/test/integrations/destinations/facebook_pixel/router/data.ts +++ b/test/integrations/destinations/facebook_pixel/router/data.ts @@ -1,3 +1,5 @@ +import { VERSION } from '../../../../../src/v0/destinations/facebook_pixel/config'; + export const mockFns = (_) => { // @ts-ignore jest.useFakeTimers().setSystemTime(new Date('2023-10-15')); @@ -193,7 +195,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/dummyPixelId/events?access_token=09876', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, headers: {}, params: {}, body: { @@ -254,7 +256,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/dummyPixelId/events?access_token=09876', + endpoint: `https://graph.facebook.com/${VERSION}/dummyPixelId/events?access_token=09876`, headers: {}, params: {}, body: { diff --git a/test/integrations/destinations/fb/dataDelivery/data.ts b/test/integrations/destinations/fb/dataDelivery/data.ts index c50cffee80..f9405ba4b3 100644 --- a/test/integrations/destinations/fb/dataDelivery/data.ts +++ b/test/integrations/destinations/fb/dataDelivery/data.ts @@ -1,357 +1,372 @@ +import { VERSION } from '../../../../../src/v0/destinations/fb/config'; + export const data = [ { - "name": "fb", - "description": "Test 0", - "feature": "dataDelivery", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": { - "body": { - "XML": {}, - "JSON_ARRAY": {}, - "FORM": { - "event": "CUSTOM_APP_EVENTS", - "advertiser_id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", - "ud[em]": "48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08", - "ud[fn]": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08", - "ud[ge]": "62c66a7a5dd70c3146618063c344e531e6d4b59e379808443ce962b3abd63c5a", - "ud[ln]": "3547cb112ac4489af2310c0626cdba6f3097a2ad5a3b42ddd3b59c76c7a079a3", - "ud[ph]": "588211a01b10feacbf7988d97a06e86c18af5259a7f457fd8759b7f7409a7d1f", - "extinfo": "[\"a2\",\"\",\"\",\"\",\"8.1.0\",\"Redmi 6\",\"\",\"\",\"Banglalink\",640,480,\"1.23\",0,0,0,\"Europe/Berlin\"]", - "app_user_id": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "custom_events": "[{\"_logTime\":1567333011693,\"_eventName\":\"spin_result\",\"_valueToSum\":400,\"fb_currency\":\"GBP\",\"additional_bet_index\":0,\"battle_id\":\"N/A\",\"bet_amount\":9,\"bet_level\":1,\"bet_multiplier\":1,\"coin_balance\":9466052,\"current_module_name\":\"CasinoGameModule\",\"days_in_game\":0,\"extra_param\":\"N/A\",\"fb_profile\":\"0\",\"featureGameType\":\"N/A\",\"game_fps\":30,\"game_id\":\"fireEagleBase\",\"game_name\":\"FireEagleSlots\",\"gem_balance\":0,\"graphicsQuality\":\"HD\",\"idfa\":\"2bf99787-33d2-4ae2-a76a-c49672f97252\",\"internetReachability\":\"ReachableViaLocalAreaNetwork\",\"isLowEndDevice\":\"False\",\"is_auto_spin\":\"False\",\"is_turbo\":\"False\",\"isf\":\"False\",\"ishighroller\":\"False\",\"jackpot_win_amount\":90,\"jackpot_win_type\":\"Silver\",\"level\":6,\"lifetime_gem_balance\":0,\"no_of_spin\":1,\"player_total_battles\":0,\"player_total_shields\":0,\"start_date\":\"2019-08-01\",\"total_payments\":0,\"tournament_id\":\"T1561970819\",\"userId\":\"c82cbdff-e5be-4009-ac78-cdeea09ab4b1\",\"versionSessionCount\":2,\"win_amount\":0,\"fb_content_id\":[\"123\",\"345\",\"567\"]}]", - "advertiser_tracking_enabled": "0", - "application_tracking_enabled": "0" + name: 'fb', + description: 'Test 0', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + body: { + XML: {}, + JSON_ARRAY: {}, + FORM: { + event: 'CUSTOM_APP_EVENTS', + advertiser_id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', + 'ud[em]': '48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08', + 'ud[fn]': '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08', + 'ud[ge]': '62c66a7a5dd70c3146618063c344e531e6d4b59e379808443ce962b3abd63c5a', + 'ud[ln]': '3547cb112ac4489af2310c0626cdba6f3097a2ad5a3b42ddd3b59c76c7a079a3', + 'ud[ph]': '588211a01b10feacbf7988d97a06e86c18af5259a7f457fd8759b7f7409a7d1f', + extinfo: + '["a2","","","","8.1.0","Redmi 6","","","Banglalink",640,480,"1.23",0,0,0,"Europe/Berlin"]', + app_user_id: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + custom_events: + '[{"_logTime":1567333011693,"_eventName":"spin_result","_valueToSum":400,"fb_currency":"GBP","additional_bet_index":0,"battle_id":"N/A","bet_amount":9,"bet_level":1,"bet_multiplier":1,"coin_balance":9466052,"current_module_name":"CasinoGameModule","days_in_game":0,"extra_param":"N/A","fb_profile":"0","featureGameType":"N/A","game_fps":30,"game_id":"fireEagleBase","game_name":"FireEagleSlots","gem_balance":0,"graphicsQuality":"HD","idfa":"2bf99787-33d2-4ae2-a76a-c49672f97252","internetReachability":"ReachableViaLocalAreaNetwork","isLowEndDevice":"False","is_auto_spin":"False","is_turbo":"False","isf":"False","ishighroller":"False","jackpot_win_amount":90,"jackpot_win_type":"Silver","level":6,"lifetime_gem_balance":0,"no_of_spin":1,"player_total_battles":0,"player_total_shields":0,"start_date":"2019-08-01","total_payments":0,"tournament_id":"T1561970819","userId":"c82cbdff-e5be-4009-ac78-cdeea09ab4b1","versionSessionCount":2,"win_amount":0,"fb_content_id":["123","345","567"]}]', + advertiser_tracking_enabled: '0', + application_tracking_enabled: '0', }, - "JSON": {} + JSON: {}, + }, + endpoint: `https://graph.facebook.com/${VERSION}/RudderFbApp/activities?access_token=invalid_access_token`, + files: {}, + headers: { + 'x-forwarded-for': '1.2.3.4', }, - "endpoint": "https://graph.facebook.com/v17.0/RudderFbApp/activities?access_token=invalid_access_token", - "files": {}, - "headers": { - "x-forwarded-for": "1.2.3.4" + method: 'POST', + statusCode: 200, + type: 'REST', + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + version: '1', + params: { + destination: 'fb', }, - "method": "POST", - "statusCode": 200, - "type": "REST", - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "version": "1", - "params": { - "destination": "fb" - } }, - "method": "POST" - } + method: 'POST', + }, }, - "output": { - "response": { - "status": 400, - "body": { - "output": { - "status": 400, - "message": "Invalid OAuth 2.0 access token", - "destinationResponse": { - "error": { - "message": "The access token could not be decrypted", - "type": "OAuthException", - "code": 190, - "fbtrace_id": "fbpixel_trace_id" + output: { + response: { + status: 400, + body: { + output: { + status: 400, + message: 'Invalid OAuth 2.0 access token', + destinationResponse: { + error: { + message: 'The access token could not be decrypted', + type: 'OAuthException', + code: 190, + fbtrace_id: 'fbpixel_trace_id', }, - "status": 500 + status: 500, }, - "statTags": { - "destType": "FB", - "errorCategory": "network", - "destinationId": "Non-determininable", - "workspaceId": "Non-determininable", - "errorType": "aborted", - "feature": "dataDelivery", - "implementation": "native", - "module": "destination" - } - } - } - } - } + statTags: { + destType: 'FB', + errorCategory: 'network', + destinationId: 'Non-determininable', + workspaceId: 'Non-determininable', + errorType: 'aborted', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', + }, + }, + }, + }, + }, }, { - "name": "fb", - "description": "Test 1", - "feature": "dataDelivery", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": { - "body": { - "XML": {}, - "JSON_ARRAY": {}, - "FORM": { - "event": "CUSTOM_APP_EVENTS", - "advertiser_id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", - "ud[em]": "48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08", - "ud[fn]": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08", - "ud[ge]": "62c66a7a5dd70c3146618063c344e531e6d4b59e379808443ce962b3abd63c5a", - "ud[ln]": "3547cb112ac4489af2310c0626cdba6f3097a2ad5a3b42ddd3b59c76c7a079a3", - "ud[ph]": "588211a01b10feacbf7988d97a06e86c18af5259a7f457fd8759b7f7409a7d1f", - "extinfo": "[\"a2\",\"\",\"\",\"\",\"8.1.0\",\"Redmi 6\",\"\",\"\",\"Banglalink\",640,480,\"1.23\",0,0,0,\"Europe/Berlin\"]", - "app_user_id": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "custom_events": "[{\"_logTime\":1567333011693,\"_eventName\":\"spin_result\",\"_valueToSum\":400,\"fb_currency\":\"GBP\",\"additional_bet_index\":0,\"battle_id\":\"N/A\",\"bet_amount\":9,\"bet_level\":1,\"bet_multiplier\":1,\"coin_balance\":9466052,\"current_module_name\":\"CasinoGameModule\",\"days_in_game\":0,\"extra_param\":\"N/A\",\"fb_profile\":\"0\",\"featureGameType\":\"N/A\",\"game_fps\":30,\"game_id\":\"fireEagleBase\",\"game_name\":\"FireEagleSlots\",\"gem_balance\":0,\"graphicsQuality\":\"HD\",\"idfa\":\"2bf99787-33d2-4ae2-a76a-c49672f97252\",\"internetReachability\":\"ReachableViaLocalAreaNetwork\",\"isLowEndDevice\":\"False\",\"is_auto_spin\":\"False\",\"is_turbo\":\"False\",\"isf\":\"False\",\"ishighroller\":\"False\",\"jackpot_win_amount\":90,\"jackpot_win_type\":\"Silver\",\"level\":6,\"lifetime_gem_balance\":0,\"no_of_spin\":1,\"player_total_battles\":0,\"player_total_shields\":0,\"start_date\":\"2019-08-01\",\"total_payments\":0,\"tournament_id\":\"T1561970819\",\"userId\":\"c82cbdff-e5be-4009-ac78-cdeea09ab4b1\",\"versionSessionCount\":2,\"win_amount\":0,\"fb_content_id\":[\"123\",\"345\",\"567\"]}]", - "advertiser_tracking_enabled": "0", - "application_tracking_enabled": "0" + name: 'fb', + description: 'Test 1', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + body: { + XML: {}, + JSON_ARRAY: {}, + FORM: { + event: 'CUSTOM_APP_EVENTS', + advertiser_id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', + 'ud[em]': '48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08', + 'ud[fn]': '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08', + 'ud[ge]': '62c66a7a5dd70c3146618063c344e531e6d4b59e379808443ce962b3abd63c5a', + 'ud[ln]': '3547cb112ac4489af2310c0626cdba6f3097a2ad5a3b42ddd3b59c76c7a079a3', + 'ud[ph]': '588211a01b10feacbf7988d97a06e86c18af5259a7f457fd8759b7f7409a7d1f', + extinfo: + '["a2","","","","8.1.0","Redmi 6","","","Banglalink",640,480,"1.23",0,0,0,"Europe/Berlin"]', + app_user_id: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + custom_events: + '[{"_logTime":1567333011693,"_eventName":"spin_result","_valueToSum":400,"fb_currency":"GBP","additional_bet_index":0,"battle_id":"N/A","bet_amount":9,"bet_level":1,"bet_multiplier":1,"coin_balance":9466052,"current_module_name":"CasinoGameModule","days_in_game":0,"extra_param":"N/A","fb_profile":"0","featureGameType":"N/A","game_fps":30,"game_id":"fireEagleBase","game_name":"FireEagleSlots","gem_balance":0,"graphicsQuality":"HD","idfa":"2bf99787-33d2-4ae2-a76a-c49672f97252","internetReachability":"ReachableViaLocalAreaNetwork","isLowEndDevice":"False","is_auto_spin":"False","is_turbo":"False","isf":"False","ishighroller":"False","jackpot_win_amount":90,"jackpot_win_type":"Silver","level":6,"lifetime_gem_balance":0,"no_of_spin":1,"player_total_battles":0,"player_total_shields":0,"start_date":"2019-08-01","total_payments":0,"tournament_id":"T1561970819","userId":"c82cbdff-e5be-4009-ac78-cdeea09ab4b1","versionSessionCount":2,"win_amount":0,"fb_content_id":["123","345","567"]}]', + advertiser_tracking_enabled: '0', + application_tracking_enabled: '0', }, - "JSON": {} + JSON: {}, }, - "endpoint": "https://graph.facebook.com/v17.0/RudderFbApp/activities?access_token=my_access_token", - "files": {}, - "headers": { - "x-forwarded-for": "1.2.3.4" + endpoint: `https://graph.facebook.com/${VERSION}/RudderFbApp/activities?access_token=my_access_token`, + files: {}, + headers: { + 'x-forwarded-for': '1.2.3.4', + }, + method: 'POST', + statusCode: 200, + type: 'REST', + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + version: '1', + params: { + destination: 'fb', }, - "method": "POST", - "statusCode": 200, - "type": "REST", - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "version": "1", - "params": { - "destination": "fb" - } }, - "method": "POST" - } + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 200, + message: 'Request Processed Successfully', + destinationResponse: { + events_received: 1, + fbtrace_id: 'facebook_trace_id', + }, + }, + }, + }, }, - "output": { - "response": { - "status": 200, - "body": { - "output": { - "status": 200, - "message": "Request Processed Successfully", - "destinationResponse": { - "events_received": 1, - "fbtrace_id": "facebook_trace_id" - } - } - } - } - } }, { - "name": "fb", - "description": "Test 2", - "feature": "dataDelivery", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": { - "body": { - "XML": {}, - "JSON_ARRAY": {}, - "FORM": { - "event": "CUSTOM_APP_EVENTS", - "advertiser_id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", - "ud[em]": "48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08", - "ud[fn]": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08", - "ud[ge]": "62c66a7a5dd70c3146618063c344e531e6d4b59e379808443ce962b3abd63c5a", - "ud[ln]": "3547cb112ac4489af2310c0626cdba6f3097a2ad5a3b42ddd3b59c76c7a079a3", - "ud[ph]": "588211a01b10feacbf7988d97a06e86c18af5259a7f457fd8759b7f7409a7d1f", - "extinfo": "[\"a2\",\"\",\"\",\"\",\"8.1.0\",\"Redmi 6\",\"\",\"\",\"Banglalink\",640,480,\"1.23\",0,0,0,\"Europe/Berlin\"]", - "app_user_id": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "custom_events": "[{\"_logTime\":1567333011693,\"_eventName\":\"spin_result\",\"_valueToSum\":400,\"fb_currency\":\"GBP\",\"additional_bet_index\":0,\"battle_id\":\"N/A\",\"bet_amount\":9,\"bet_level\":1,\"bet_multiplier\":1,\"coin_balance\":9466052,\"current_module_name\":\"CasinoGameModule\",\"days_in_game\":0,\"extra_param\":\"N/A\",\"fb_profile\":\"0\",\"featureGameType\":\"N/A\",\"game_fps\":30,\"game_id\":\"fireEagleBase\",\"game_name\":\"FireEagleSlots\",\"gem_balance\":0,\"graphicsQuality\":\"HD\",\"idfa\":\"2bf99787-33d2-4ae2-a76a-c49672f97252\",\"internetReachability\":\"ReachableViaLocalAreaNetwork\",\"isLowEndDevice\":\"False\",\"is_auto_spin\":\"False\",\"is_turbo\":\"False\",\"isf\":\"False\",\"ishighroller\":\"False\",\"jackpot_win_amount\":90,\"jackpot_win_type\":\"Silver\",\"level\":6,\"lifetime_gem_balance\":0,\"no_of_spin\":1,\"player_total_battles\":0,\"player_total_shields\":0,\"start_date\":\"2019-08-01\",\"total_payments\":0,\"tournament_id\":\"T1561970819\",\"userId\":\"c82cbdff-e5be-4009-ac78-cdeea09ab4b1\",\"versionSessionCount\":2,\"win_amount\":0,\"fb_content_id\":[\"123\",\"345\",\"567\"]}]", - "advertiser_tracking_enabled": "0", - "application_tracking_enabled": "0" + name: 'fb', + description: 'Test 2', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + body: { + XML: {}, + JSON_ARRAY: {}, + FORM: { + event: 'CUSTOM_APP_EVENTS', + advertiser_id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', + 'ud[em]': '48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08', + 'ud[fn]': '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08', + 'ud[ge]': '62c66a7a5dd70c3146618063c344e531e6d4b59e379808443ce962b3abd63c5a', + 'ud[ln]': '3547cb112ac4489af2310c0626cdba6f3097a2ad5a3b42ddd3b59c76c7a079a3', + 'ud[ph]': '588211a01b10feacbf7988d97a06e86c18af5259a7f457fd8759b7f7409a7d1f', + extinfo: + '["a2","","","","8.1.0","Redmi 6","","","Banglalink",640,480,"1.23",0,0,0,"Europe/Berlin"]', + app_user_id: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + custom_events: + '[{"_logTime":1567333011693,"_eventName":"spin_result","_valueToSum":400,"fb_currency":"GBP","additional_bet_index":0,"battle_id":"N/A","bet_amount":9,"bet_level":1,"bet_multiplier":1,"coin_balance":9466052,"current_module_name":"CasinoGameModule","days_in_game":0,"extra_param":"N/A","fb_profile":"0","featureGameType":"N/A","game_fps":30,"game_id":"fireEagleBase","game_name":"FireEagleSlots","gem_balance":0,"graphicsQuality":"HD","idfa":"2bf99787-33d2-4ae2-a76a-c49672f97252","internetReachability":"ReachableViaLocalAreaNetwork","isLowEndDevice":"False","is_auto_spin":"False","is_turbo":"False","isf":"False","ishighroller":"False","jackpot_win_amount":90,"jackpot_win_type":"Silver","level":6,"lifetime_gem_balance":0,"no_of_spin":1,"player_total_battles":0,"player_total_shields":0,"start_date":"2019-08-01","total_payments":0,"tournament_id":"T1561970819","userId":"c82cbdff-e5be-4009-ac78-cdeea09ab4b1","versionSessionCount":2,"win_amount":0,"fb_content_id":["123","345","567"]}]', + advertiser_tracking_enabled: '0', + application_tracking_enabled: '0', }, - "JSON": {} + JSON: {}, + }, + endpoint: `https://graph.facebook.com/${VERSION}/1234567891234567/events?access_token=invalid_timestamp_correct_access_token`, + files: {}, + headers: { + 'x-forwarded-for': '1.2.3.4', }, - "endpoint": "https://graph.facebook.com/v17.0/1234567891234567/events?access_token=invalid_timestamp_correct_access_token", - "files": {}, - "headers": { - "x-forwarded-for": "1.2.3.4" + method: 'POST', + statusCode: 200, + type: 'REST', + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + version: '1', + params: { + destination: 'fb', }, - "method": "POST", - "statusCode": 200, - "type": "REST", - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "version": "1", - "params": { - "destination": "fb" - } }, - "method": "POST" - } + method: 'POST', + }, }, - "output": { - "response": { - "status": 400, - "body": { - "output": { - "status": 400, - "message": "Event Timestamp Too Old", - "destinationResponse": { - "error": { - "message": "Invalid parameter", - "type": "OAuthException", - "code": 100, - "error_subcode": 2804003, - "is_transient": false, - "error_user_title": "Event Timestamp Too Old", - "error_user_msg": "The timestamp for this event is too far in the past. Events need to be sent from your server within 7 days of when they occurred. Enter a timestamp that has occurred within the last 7 days.", - "fbtrace_id": "A6UyEgg_HdoiRX9duxcBOjb" + output: { + response: { + status: 400, + body: { + output: { + status: 400, + message: 'Event Timestamp Too Old', + destinationResponse: { + error: { + message: 'Invalid parameter', + type: 'OAuthException', + code: 100, + error_subcode: 2804003, + is_transient: false, + error_user_title: 'Event Timestamp Too Old', + error_user_msg: + 'The timestamp for this event is too far in the past. Events need to be sent from your server within 7 days of when they occurred. Enter a timestamp that has occurred within the last 7 days.', + fbtrace_id: 'A6UyEgg_HdoiRX9duxcBOjb', }, - "status": 400 + status: 400, }, - "statTags": { - "destType": "FB", - "errorCategory": "network", - "destinationId": "Non-determininable", - "workspaceId": "Non-determininable", - "errorType": "aborted", - "feature": "dataDelivery", - "implementation": "native", - "module": "destination" - } - } - } - } - } + statTags: { + destType: 'FB', + errorCategory: 'network', + destinationId: 'Non-determininable', + workspaceId: 'Non-determininable', + errorType: 'aborted', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', + }, + }, + }, + }, + }, }, { - "name": "fb", - "description": "Test 3", - "feature": "dataDelivery", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://graph.facebook.com/v17.0/1234567891234567/events?access_token=throttled_valid_access_token", - "headers": {}, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": { - "extinfo": "[\"a2\",\"\",\"\",\"\",\"8.1.0\",\"Redmi 6\",\"\",\"\",\"Banglalink\",0,100,\"50.00\",0,0,0,\"\"]", - "custom_events": "[{\"_logTime\":1567333011693,\"_eventName\":\"Viewed Screen\",\"fb_description\":\"Main.1233\"}]", - "ud[em]": "48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08", - "advertiser_tracking_enabled": "0", - "application_tracking_enabled": "0", - "event": "CUSTOM_APP_EVENTS" - } + name: 'fb', + description: 'Test 3', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: `https://graph.facebook.com/${VERSION}/1234567891234567/events?access_token=throttled_valid_access_token`, + headers: {}, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: { + extinfo: + '["a2","","","","8.1.0","Redmi 6","","","Banglalink",0,100,"50.00",0,0,0,""]', + custom_events: + '[{"_logTime":1567333011693,"_eventName":"Viewed Screen","fb_description":"Main.1233"}]', + 'ud[em]': '48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08', + advertiser_tracking_enabled: '0', + application_tracking_enabled: '0', + event: 'CUSTOM_APP_EVENTS', + }, + }, + files: {}, + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + statusCode: 200, + params: { + destination: 'fb', }, - "files": {}, - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "statusCode": 200, - "params": { - "destination": "fb" - } }, - "method": "POST" - } + method: 'POST', + }, }, - "output": { - "response": { - "status": 429, - "body": { - "output": { - "status": 429, - "message": "API User Too Many Calls", - "destinationResponse": { - "error": { - "message": "User request limit reached", - "type": "OAuthException", - "code": 17, - "fbtrace_id": "facebook_px_trace_id_4" + output: { + response: { + status: 429, + body: { + output: { + status: 429, + message: 'API User Too Many Calls', + destinationResponse: { + error: { + message: 'User request limit reached', + type: 'OAuthException', + code: 17, + fbtrace_id: 'facebook_px_trace_id_4', }, - "status": 500 + status: 500, + }, + statTags: { + destType: 'FB', + errorCategory: 'network', + destinationId: 'Non-determininable', + workspaceId: 'Non-determininable', + errorType: 'throttled', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', }, - "statTags": { - "destType": "FB", - "errorCategory": "network", - "destinationId": "Non-determininable", - "workspaceId": "Non-determininable", - "errorType": "throttled", - "feature": "dataDelivery", - "implementation": "native", - "module": "destination" - } - } - } - } - } + }, + }, + }, + }, }, { - "name": "fb", - "description": "Test 4", - "feature": "dataDelivery", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://graph.facebook.com/v17.0/1234567891234567/events?access_token=invalid_account_id_valid_access_token", - "headers": {}, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": { - "extinfo": "[\"a2\",\"\",\"\",\"\",\"8.1.0\",\"Redmi 6\",\"\",\"\",\"Banglalink\",0,100,\"50.00\",0,0,0,\"\"]", - "custom_events": "[{\"_logTime\":1567333011693,\"_eventName\":\"Viewed Screen\",\"fb_description\":\"Main.1233\"}]", - "ud[em]": "48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08", - "advertiser_tracking_enabled": "0", - "application_tracking_enabled": "0", - "event": "CUSTOM_APP_EVENTS" - } + name: 'fb', + description: 'Test 4', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: `https://graph.facebook.com/${VERSION}/1234567891234567/events?access_token=invalid_account_id_valid_access_token`, + headers: {}, + body: { + JSON: {}, + XML: {}, + JSON_ARRAY: {}, + FORM: { + extinfo: + '["a2","","","","8.1.0","Redmi 6","","","Banglalink",0,100,"50.00",0,0,0,""]', + custom_events: + '[{"_logTime":1567333011693,"_eventName":"Viewed Screen","fb_description":"Main.1233"}]', + 'ud[em]': '48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08', + advertiser_tracking_enabled: '0', + application_tracking_enabled: '0', + event: 'CUSTOM_APP_EVENTS', + }, + }, + files: {}, + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + statusCode: 200, + params: { + destination: 'fb', }, - "files": {}, - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "statusCode": 200, - "params": { - "destination": "fb" - } }, - "method": "POST" - } + method: 'POST', + }, }, - "output": { - "response": { - "status": 400, - "body": { - "output": { - "status": 400, - "message": "Object with ID 'PIXEL_ID' / 'DATASET_ID' / 'AUDIENCE_ID' does not exist, cannot be loaded due to missing permissions, or does not support this operation", - "destinationResponse": { - "error": { - "message": "Unsupported post request. Object with ID '1234567891234569' does not exist, cannot be loaded due to missing permissions, or does not support this operation. Please read the Graph API documentation at https://developers.facebook.com/docs/graph-api", - "type": "GraphMethodException", - "code": 100, - "error_subcode": 33, - "fbtrace_id": "facebook_px_trace_id_5" + output: { + response: { + status: 400, + body: { + output: { + status: 400, + message: + "Object with ID 'PIXEL_ID' / 'DATASET_ID' / 'AUDIENCE_ID' does not exist, cannot be loaded due to missing permissions, or does not support this operation", + destinationResponse: { + error: { + message: + "Unsupported post request. Object with ID '1234567891234569' does not exist, cannot be loaded due to missing permissions, or does not support this operation. Please read the Graph API documentation at https://developers.facebook.com/docs/graph-api", + type: 'GraphMethodException', + code: 100, + error_subcode: 33, + fbtrace_id: 'facebook_px_trace_id_5', }, - "status": 400 + status: 400, }, - "statTags": { - "destType": "FB", - "errorCategory": "network", - "destinationId": "Non-determininable", - "workspaceId": "Non-determininable", - "errorType": "aborted", - "feature": "dataDelivery", - "implementation": "native", - "module": "destination" - } - } - } - } - } - } -] \ No newline at end of file + statTags: { + destType: 'FB', + errorCategory: 'network', + destinationId: 'Non-determininable', + workspaceId: 'Non-determininable', + errorType: 'aborted', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', + }, + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/fb/network.ts b/test/integrations/destinations/fb/network.ts index 07a84a7e66..1a2f114d74 100644 --- a/test/integrations/destinations/fb/network.ts +++ b/test/integrations/destinations/fb/network.ts @@ -2,6 +2,7 @@ import { cloneDeep } from 'lodash'; import { getFormData } from '../../../../src/adapters/network'; import * as fbPixelNw from '../facebook_pixel/network'; import { data } from './dataDelivery/data'; +import { VERSION } from '../../../../src/v0/destinations/fb/config'; const fbPixelTcs = data .filter((_, i) => [2, 3, 4].includes(i)) @@ -19,7 +20,7 @@ const fbPixelTcs = data export const networkCallsData = [ { httpReq: { - url: 'https://graph.facebook.com/v17.0/RudderFbApp/activities?access_token=invalid_access_token', + url: `https://graph.facebook.com/${VERSION}/RudderFbApp/activities?access_token=invalid_access_token`, data: getFormData(data[0].input.request.body.body.FORM).toString(), params: { destination: 'fb' }, headers: { 'User-Agent': 'RudderLabs' }, @@ -39,7 +40,7 @@ export const networkCallsData = [ }, { httpReq: { - url: 'https://graph.facebook.com/v17.0/RudderFbApp/activities?access_token=my_access_token', + url: `https://graph.facebook.com/${VERSION}/RudderFbApp/activities?access_token=my_access_token`, data: getFormData(data[1].input.request.body.body.FORM).toString(), params: { destination: 'fb' }, headers: { 'x-forwarded-for': '1.2.3.4', 'User-Agent': 'RudderLabs' }, diff --git a/test/integrations/destinations/fb/processor/data.ts b/test/integrations/destinations/fb/processor/data.ts index 9b57f3ef78..a437b90855 100644 --- a/test/integrations/destinations/fb/processor/data.ts +++ b/test/integrations/destinations/fb/processor/data.ts @@ -1,3 +1,5 @@ +import { VERSION } from '../../../../../src/v0/destinations/fb/config'; + export const data = [ { name: 'fb', @@ -618,7 +620,7 @@ export const data = [ }, JSON: {}, }, - endpoint: 'https://graph.facebook.com/v17.0/RudderFbApp/activities', + endpoint: `https://graph.facebook.com/${VERSION}/RudderFbApp/activities`, files: {}, headers: { 'x-forwarded-for': '1.2.3.4', @@ -803,7 +805,7 @@ export const data = [ }, JSON: {}, }, - endpoint: 'https://graph.facebook.com/v17.0/RudderFbApp/activities', + endpoint: `https://graph.facebook.com/${VERSION}/RudderFbApp/activities`, files: {}, headers: { 'x-forwarded-for': '1.2.3.4', @@ -893,7 +895,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/RudderFbApp/activities', + endpoint: `https://graph.facebook.com/${VERSION}/RudderFbApp/activities`, headers: {}, params: {}, body: { @@ -993,7 +995,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/RudderFbApp/activities', + endpoint: `https://graph.facebook.com/${VERSION}/RudderFbApp/activities`, headers: {}, params: {}, body: { @@ -1177,7 +1179,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/RudderFbApp/activities', + endpoint: `https://graph.facebook.com/${VERSION}/RudderFbApp/activities`, headers: {}, params: {}, body: { @@ -1277,7 +1279,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/RudderFbApp/activities', + endpoint: `https://graph.facebook.com/${VERSION}/RudderFbApp/activities`, headers: {}, params: {}, body: { @@ -1377,7 +1379,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/RudderFbApp/activities', + endpoint: `https://graph.facebook.com/${VERSION}/RudderFbApp/activities`, headers: {}, params: {}, body: { @@ -1551,7 +1553,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/RudderFbApp/activities', + endpoint: `https://graph.facebook.com/${VERSION}/RudderFbApp/activities`, headers: {}, params: {}, body: { @@ -1731,7 +1733,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/RudderFbApp/activities', + endpoint: `https://graph.facebook.com/${VERSION}/RudderFbApp/activities`, headers: {}, params: {}, body: { @@ -1831,7 +1833,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/RudderFbApp/activities', + endpoint: `https://graph.facebook.com/${VERSION}/RudderFbApp/activities`, headers: { 'x-forwarded-for': '2.3.4.5', }, @@ -2153,7 +2155,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/RudderFbApp/activities', + endpoint: `https://graph.facebook.com/${VERSION}/RudderFbApp/activities`, headers: {}, params: {}, body: { diff --git a/test/integrations/destinations/fb_custom_audience/dataDelivery/data.ts b/test/integrations/destinations/fb_custom_audience/dataDelivery/data.ts index d2220e16da..3066dae887 100644 --- a/test/integrations/destinations/fb_custom_audience/dataDelivery/data.ts +++ b/test/integrations/destinations/fb_custom_audience/dataDelivery/data.ts @@ -1,3 +1,5 @@ +import { getEndPoint } from '../../../../../src/v0/destinations/fb_custom_audience/config'; + export const data = [ { name: 'fb_custom_audience', @@ -11,7 +13,7 @@ export const data = [ version: '1', type: 'REST', method: 'DELETE', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + endpoint: getEndPoint('aud1'), headers: { 'test-dest-response-key': 'successResponse', }, @@ -94,7 +96,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + endpoint: getEndPoint('aud1'), headers: { 'test-dest-response-key': 'permissionMissingError', }, @@ -176,7 +178,7 @@ export const data = [ version: '1', type: 'REST', method: 'DELETE', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + endpoint: getEndPoint('aud1'), headers: { 'test-dest-response-key': 'audienceUnavailableError', }, @@ -245,7 +247,7 @@ export const data = [ version: '1', type: 'REST', method: 'DELETE', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + endpoint: getEndPoint('aud1'), headers: { 'test-dest-response-key': 'audienceDeletedError', }, @@ -312,7 +314,7 @@ export const data = [ version: '1', type: 'REST', method: 'DELETE', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + endpoint: getEndPoint('aud1'), headers: { 'test-dest-response-key': 'failedToUpdateAudienceError', }, @@ -380,7 +382,7 @@ export const data = [ version: '1', type: 'REST', method: 'DELETE', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + endpoint: getEndPoint('aud1'), headers: { 'test-dest-response-key': 'parameterExceededError', }, @@ -447,7 +449,7 @@ export const data = [ version: '1', type: 'REST', method: 'DELETE', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + endpoint: getEndPoint('aud1'), headers: { 'test-dest-response-key': 'tooManyCallsError', }, @@ -514,7 +516,7 @@ export const data = [ version: '1', type: 'REST', method: 'DELETE', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + endpoint: getEndPoint('aud1'), headers: { 'test-dest-response-key': 'code200PermissionError', }, diff --git a/test/integrations/destinations/fb_custom_audience/network.ts b/test/integrations/destinations/fb_custom_audience/network.ts index 7dd904fdd9..bbdc1ffc28 100644 --- a/test/integrations/destinations/fb_custom_audience/network.ts +++ b/test/integrations/destinations/fb_custom_audience/network.ts @@ -1,10 +1,12 @@ +import { getEndPoint } from '../../../../src/v0/destinations/fb_custom_audience/config'; + export const networkCallsData = [ { httpReq: { version: '1', type: 'REST', method: 'DELETE', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + endpoint: getEndPoint('aud1'), headers: { 'test-dest-response-key': 'successResponse', }, @@ -70,7 +72,7 @@ export const networkCallsData = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + endpoint: getEndPoint('aud1'), headers: { 'test-dest-response-key': 'permissionMissingError', }, @@ -111,7 +113,7 @@ export const networkCallsData = [ version: '1', type: 'REST', method: 'DELETE', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + endpoint: getEndPoint('aud1'), headers: { 'test-dest-response-key': 'audienceUnavailableError', }, @@ -152,7 +154,7 @@ export const networkCallsData = [ version: '1', type: 'REST', method: 'DELETE', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + endpoint: getEndPoint('aud1'), headers: { 'test-dest-response-key': 'audienceDeletedError', }, @@ -218,7 +220,7 @@ export const networkCallsData = [ version: '1', type: 'REST', method: 'DELETE', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + endpoint: getEndPoint('aud1'), headers: { 'test-dest-response-key': 'failedToUpdateAudienceError', }, @@ -284,7 +286,7 @@ export const networkCallsData = [ version: '1', type: 'REST', method: 'DELETE', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + endpoint: getEndPoint('aud1'), headers: { 'test-dest-response-key': 'parameterExceededError', }, @@ -350,7 +352,7 @@ export const networkCallsData = [ version: '1', type: 'REST', method: 'DELETE', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + endpoint: getEndPoint('aud1'), headers: { 'test-dest-response-key': 'tooManyCallsError', }, @@ -416,7 +418,7 @@ export const networkCallsData = [ version: '1', type: 'REST', method: 'DELETE', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + endpoint: getEndPoint('aud1'), headers: { 'test-dest-response-key': 'code200PermissionError', }, diff --git a/test/integrations/destinations/fb_custom_audience/processor/data.ts b/test/integrations/destinations/fb_custom_audience/processor/data.ts index 17dcda3a98..4f892f6fef 100644 --- a/test/integrations/destinations/fb_custom_audience/processor/data.ts +++ b/test/integrations/destinations/fb_custom_audience/processor/data.ts @@ -1,3 +1,5 @@ +import { getEndPoint } from '../../../../../src/v0/destinations/fb_custom_audience/config'; + export const data = [ { name: 'fb_custom_audience', @@ -552,7 +554,7 @@ export const data = [ version: '1', type: 'REST', method: 'DELETE', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + endpoint: getEndPoint('aud1'), headers: {}, params: { access_token: 'ABC', @@ -607,7 +609,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + endpoint: getEndPoint('aud1'), headers: {}, params: { access_token: 'ABC', @@ -763,7 +765,7 @@ export const data = [ version: '1', type: 'REST', method: 'DELETE', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + endpoint: getEndPoint('aud1'), headers: {}, params: { access_token: 'ABC', @@ -818,7 +820,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + endpoint: getEndPoint('aud1'), headers: {}, userId: '', params: { @@ -963,7 +965,7 @@ export const data = [ version: '1', type: 'REST', method: 'DELETE', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + endpoint: getEndPoint('aud1'), headers: {}, params: { access_token: 'ABC', @@ -993,7 +995,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + endpoint: getEndPoint('aud1'), headers: {}, params: { access_token: 'ABC', @@ -1123,7 +1125,7 @@ export const data = [ version: '1', type: 'REST', method: 'DELETE', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + endpoint: getEndPoint('aud1'), headers: {}, params: { access_token: 'ABC', @@ -1179,7 +1181,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + endpoint: getEndPoint('aud1'), headers: {}, params: { access_token: 'ABC', @@ -1336,7 +1338,7 @@ export const data = [ version: '1', type: 'REST', method: 'DELETE', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + endpoint: getEndPoint('aud1'), headers: {}, userId: '', params: { @@ -1391,7 +1393,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + endpoint: getEndPoint('aud1'), headers: {}, params: { access_token: 'ABC', @@ -1547,7 +1549,7 @@ export const data = [ version: '1', type: 'REST', method: 'DELETE', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + endpoint: getEndPoint('aud1'), headers: {}, params: { access_token: 'ABC', @@ -1602,7 +1604,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + endpoint: getEndPoint('aud1'), headers: {}, params: { access_token: 'ABC', @@ -1758,7 +1760,7 @@ export const data = [ version: '1', type: 'REST', method: 'DELETE', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + endpoint: getEndPoint('aud1'), headers: {}, userId: '', params: { @@ -1813,7 +1815,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + endpoint: getEndPoint('aud1'), headers: {}, userId: '', params: { @@ -1955,7 +1957,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + endpoint: getEndPoint('aud1'), headers: {}, userId: '', params: { @@ -2097,7 +2099,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + endpoint: getEndPoint('aud1'), headers: {}, userId: '', params: { @@ -2226,7 +2228,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + endpoint: getEndPoint('aud1'), headers: {}, params: { access_token: 'ABC', @@ -28302,7 +28304,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + endpoint: getEndPoint('aud1'), headers: {}, params: { access_token: 'ABC', @@ -34844,7 +34846,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + endpoint: getEndPoint('aud1'), headers: {}, params: { access_token: 'ABC', @@ -41386,7 +41388,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + endpoint: getEndPoint('aud1'), headers: {}, params: { access_token: 'ABC', @@ -47902,7 +47904,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + endpoint: getEndPoint('aud1'), headers: {}, params: { access_token: 'ABC', diff --git a/test/integrations/destinations/fb_custom_audience/router/data.ts b/test/integrations/destinations/fb_custom_audience/router/data.ts index c458b45c91..efefb80a89 100644 --- a/test/integrations/destinations/fb_custom_audience/router/data.ts +++ b/test/integrations/destinations/fb_custom_audience/router/data.ts @@ -1,3 +1,5 @@ +import { getEndPoint } from '../../../../../src/v0/destinations/fb_custom_audience/config'; + export const data = [ { name: 'fb_custom_audience', @@ -189,7 +191,7 @@ export const data = [ version: '1', type: 'REST', method: 'DELETE', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + endpoint: getEndPoint('aud1'), headers: {}, params: { access_token: 'ABC', @@ -241,7 +243,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + endpoint: getEndPoint('aud1'), headers: {}, params: { access_token: 'ABC', @@ -332,7 +334,7 @@ export const data = [ version: '1', type: 'REST', method: 'DELETE', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + endpoint: getEndPoint('aud1'), headers: {}, params: { access_token: 'ABC', @@ -383,7 +385,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + endpoint: getEndPoint('aud1'), headers: {}, params: { access_token: 'ABC', @@ -26748,7 +26750,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/23848494844100489/users', + endpoint: getEndPoint('23848494844100489'), headers: {}, params: { access_token: 'ABC', @@ -26874,7 +26876,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + endpoint: getEndPoint('aud1'), headers: {}, params: { access_token: 'ABC', @@ -33409,7 +33411,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + endpoint: getEndPoint('aud1'), headers: {}, params: { access_token: 'ABC', @@ -39944,7 +39946,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + endpoint: getEndPoint('aud1'), headers: {}, params: { access_token: 'ABC', @@ -46453,7 +46455,7 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://graph.facebook.com/v17.0/aud1/users', + endpoint: getEndPoint('aud1'), headers: {}, params: { access_token: 'ABC', From 4bde43509c60d17001fc45bec405f9598776b966 Mon Sep 17 00:00:00 2001 From: Yashasvi Bajpai <33063622+yashasvibajpai@users.noreply.github.com> Date: Wed, 29 Nov 2023 19:11:13 +0530 Subject: [PATCH 47/93] chore: update PR template (#2851) --- .github/pull_request_template.md | 57 ++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 .github/pull_request_template.md diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000000..5b716b7e9f --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,57 @@ +## What are the changes introduced in this PR? + +Write a brief explainer on your code changes. + +## Please explain the objectives of your changes below + +Put down any required details on the broader aspect of your changes. If there are any dependent changes, **mandatorily** mention them here + +### Type of change + +If the pull request is a **bug-fix**, **enhancement** or a **refactor**, please fill in the details on the changes made. + +- Existing capabilities/behavior + +- New capabilities/behavior + +If the pull request is a **new feature**, + +### Any technical or performance related pointers to consider with the change? + +N/A + +### Any new dependencies introduced with this change? + +N/A + +### Any new generic utility introduced or modified. Please explain the changes. + +N/A + +### If the PR has changes in more than 10 files, please mention why the changes were not split into multiple PRs. + +N/A + +### If multiple linear tasks are associated with the PR changes, please elaborate on the reason: + +N/A + +
+ +### Developer checklist + +- [ ] **No breaking changes are being introduced.** + +- [ ] Are all related docs linked with the PR? + +- [ ] Are all changes manually tested? + +- [ ] Does this change require any documentation changes? + +- [ ] Are relevant unit and component test-cases added? + +### Reviewer checklist + +- [ ] Is the type of change in the PR title appropriate as per the changes? + +- [ ] Verified that there are no credentials or confidential data exposed with the changes. From 0e7adc66ff88d9510e48a5651460b4e02cc57c78 Mon Sep 17 00:00:00 2001 From: Sankeerth Date: Wed, 29 Nov 2023 21:57:25 +0530 Subject: [PATCH 48/93] fix: bugsnag issue in moengage identify event (#2845) --- src/v0/destinations/moengage/transform.js | 2 +- .../destinations/moengage/processor/data.ts | 101 ++++++++++++++++++ 2 files changed, 102 insertions(+), 1 deletion(-) diff --git a/src/v0/destinations/moengage/transform.js b/src/v0/destinations/moengage/transform.js index ea7db24406..8a16d9c7a7 100644 --- a/src/v0/destinations/moengage/transform.js +++ b/src/v0/destinations/moengage/transform.js @@ -119,7 +119,7 @@ const processEvent = (message, destination) => { response = responseBuilderSimple(message, category, destination); // only if device information is present device info will be added/updated // with an identify call otherwise only user info will be added/updated - if (message.context.device && message.context.device.type && message.context.device.token) { + if (message?.context?.device?.type && message?.context?.device?.token) { // build the response response = [ // user api payload (output for identify) diff --git a/test/integrations/destinations/moengage/processor/data.ts b/test/integrations/destinations/moengage/processor/data.ts index 50b0361381..1ce8705f53 100644 --- a/test/integrations/destinations/moengage/processor/data.ts +++ b/test/integrations/destinations/moengage/processor/data.ts @@ -2777,4 +2777,105 @@ export const data = [ }, }, }, + { + name: 'moengage', + description: + 'when identify is sent without context, the event should not throw internal server error', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + type: 'identify', + event: 'identify', + sentAt: '2023-11-22T03:42:40.346Z', + userId: 'userId16', + channel: 'mobile', + rudderId: 'dummy-rudderId', + timestamp: '2023-11-22T03:42:31.470Z', + receivedAt: '2023-11-22T03:42:43.281Z', + request_ip: '114.122.233.48', + anonymousId: 'anon-dummyId-1', + integrations: { + All: true, + }, + originalTimestamp: '2023-11-22T03:42:28.535Z', + }, + destination: { + ID: '1iuTZs6eEZVMm6GjRBe6bNShaL3', + Name: 'MoEngage Testing', + DestinationDefinition: { + ID: '1iu4802Tx27kNC4KNYYou6D8jzL', + Name: 'MOENGAGE', + DisplayName: 'MoEngage', + Config: { + destConfig: { defaultConfig: ['apiId', 'apiKey', 'region'] }, + excludeKeys: [], + includeKeys: [], + supportedSourceTypes: [ + 'android', + 'ios', + 'web', + 'unity', + 'amp', + 'cloud', + 'reactnative', + ], + }, + }, + Config: { + apiId: 'W0ZHNMPI2O4KHJ48ZILZACRA', + apiKey: 'dummyApiKey', + eventDelivery: false, + eventDeliveryTS: 1602757086384, + region: 'US', + }, + Enabled: true, + Transformations: [], + IsProcessorEnabled: true, + }, + }, + ], + method: 'POST', + }, + pathSuffix: '', + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + FORM: {}, + JSON: { + attributes: {}, + customer_id: 'userId16', + type: 'customer', + }, + JSON_ARRAY: {}, + XML: {}, + }, + endpoint: 'https://api-01.moengage.com/v1/customer/W0ZHNMPI2O4KHJ48ZILZACRA', + files: {}, + headers: { + Authorization: 'Basic VzBaSE5NUEkyTzRLSEo0OFpJTFpBQ1JBOmR1bW15QXBpS2V5', + 'Content-Type': 'application/json', + 'MOE-APPKEY': 'W0ZHNMPI2O4KHJ48ZILZACRA', + }, + method: 'POST', + params: {}, + type: 'REST', + userId: 'anon-dummyId-1', + version: '1', + }, + statusCode: 200, + }, + ], + }, + }, + }, ]; From 27f0797c6dcd626a713c11a48c6e85a69e0a4963 Mon Sep 17 00:00:00 2001 From: AASHISH MALIK Date: Thu, 30 Nov 2023 11:15:22 +0530 Subject: [PATCH 49/93] feat: cm360 transformerproxy V1 flag (#2848) * feat: cm360 transformerproxy, V1 features.json update * feat: add support for both v0,v1 in handler for old server support * fix: addressed comments * chore: added tests for V1 too --- src/adapters/networkHandlerFactory.js | 18 +- src/adapters/networkHandlerFactory.test.js | 25 + src/controllers/delivery.ts | 8 +- src/features.json | 3 +- src/interfaces/DestinationService.ts | 1 + src/routes/utils/constants.js | 6 +- src/services/comparator.ts | 2 + src/services/destination/nativeIntegration.ts | 3 +- .../campaign_manager/networkHandler.js | 117 ++++ .../data/campaign_manager_proxy_input.json | 96 --- .../data/campaign_manager_proxy_output.json | 51 -- .../campaign_manager/dataDelivery/data.ts | 604 ++++++++++++++++++ .../destinations/campaign_manager/network.ts | 311 +++++++++ 13 files changed, 1089 insertions(+), 156 deletions(-) create mode 100644 src/adapters/networkHandlerFactory.test.js create mode 100644 src/v1/destinations/campaign_manager/networkHandler.js delete mode 100644 test/__tests__/data/campaign_manager_proxy_input.json delete mode 100644 test/__tests__/data/campaign_manager_proxy_output.json create mode 100644 test/integrations/destinations/campaign_manager/dataDelivery/data.ts create mode 100644 test/integrations/destinations/campaign_manager/network.ts diff --git a/src/adapters/networkHandlerFactory.js b/src/adapters/networkHandlerFactory.js index 7cfa4b048e..f4940553f5 100644 --- a/src/adapters/networkHandlerFactory.js +++ b/src/adapters/networkHandlerFactory.js @@ -8,6 +8,8 @@ const { getIntegrations } = require('../routes/utils'); const handlers = { generic: GenericNetworkHandler, + v0: {}, + v1: {}, }; // Dynamically import the network handlers for all @@ -16,7 +18,17 @@ SUPPORTED_VERSIONS.forEach((version) => { const destinations = getIntegrations(path.resolve(__dirname, `../${version}/destinations`)); destinations.forEach((dest) => { try { - handlers[dest] = require(`../${version}/destinations/${dest}/networkHandler`).networkHandler; + // handles = { + // v0: { + // dest: handler + // }, + // v1: { + // dest: handler + // }, + // generic: GenericNetworkHandler, + // } + handlers[version][dest] = + require(`../${version}/destinations/${dest}/networkHandler`).networkHandler; } catch { // Do nothing as exception indicates // network handler is not defined for that destination @@ -24,8 +36,8 @@ SUPPORTED_VERSIONS.forEach((version) => { }); }); -const getNetworkHandler = (type) => { - const NetworkHandler = handlers[type] || handlers.generic; +const getNetworkHandler = (type, version) => { + const NetworkHandler = handlers[version][type] || handlers.generic; return new NetworkHandler(); }; diff --git a/src/adapters/networkHandlerFactory.test.js b/src/adapters/networkHandlerFactory.test.js new file mode 100644 index 0000000000..c4713e66a8 --- /dev/null +++ b/src/adapters/networkHandlerFactory.test.js @@ -0,0 +1,25 @@ +const { getNetworkHandler } = require('./networkHandlerFactory'); +const { networkHandler: GenericNetworkHandler } = require('./networkhandler/genericNetworkHandler'); + +describe(`Network Handler Tests`, () => { + it('Should return v0 networkhandler', () => { + let proxyHandler = getNetworkHandler('campaign_manager', `v0`); + const cmProxy = require(`../v0/destinations/campaign_manager/networkHandler`).networkHandler; + expect(proxyHandler).toEqual(new cmProxy()); + + proxyHandler = getNetworkHandler('braze', `v0`); + const brazeProxy = require(`../v0/destinations/braze/networkHandler`).networkHandler; + expect(proxyHandler).toEqual(new brazeProxy()); + }); + + it('Should return v1 networkhandler', () => { + let proxyHandler = getNetworkHandler('campaign_manager', `v1`); + const cmProxy = require(`../v1/destinations/campaign_manager/networkHandler`).networkHandler; + expect(proxyHandler).toEqual(new cmProxy()); + }); + + it('Should return genericHandler if v1 proxy and handler is not present for destination', () => { + let proxyHandler = getNetworkHandler('braze', `v1`); + expect(proxyHandler).toEqual(new GenericNetworkHandler()); + }); +}); diff --git a/src/controllers/delivery.ts b/src/controllers/delivery.ts index af94764d46..3ccc241b87 100644 --- a/src/controllers/delivery.ts +++ b/src/controllers/delivery.ts @@ -16,9 +16,15 @@ export class DeliveryController { const requestMetadata = MiscService.getRequestMetadata(ctx); const event = ctx.request.body as ProcessorTransformationOutput; const { destination }: { destination: string } = ctx.params; + const { version }: { version: string } = ctx.params; const integrationService = ServiceSelector.getNativeDestinationService(); try { - deliveryResponse = await integrationService.deliver(event, destination, requestMetadata); + deliveryResponse = await integrationService.deliver( + event, + destination, + requestMetadata, + version, + ); } catch (error: any) { const metaTO = integrationService.getTags( destination, diff --git a/src/features.json b/src/features.json index 224968c99b..23c01c3731 100644 --- a/src/features.json +++ b/src/features.json @@ -64,5 +64,6 @@ "ONE_SIGNAL": true, "TIKTOK_AUDIENCE": true }, - "supportSourceTransformV1": true + "supportSourceTransformV1": true, + "transformerProxyV1": true } diff --git a/src/interfaces/DestinationService.ts b/src/interfaces/DestinationService.ts index b27f98da2a..16f6b9349c 100644 --- a/src/interfaces/DestinationService.ts +++ b/src/interfaces/DestinationService.ts @@ -47,6 +47,7 @@ export interface DestinationService { event: ProcessorTransformationOutput, destinationType: string, requestMetadata: NonNullable, + version: string, ): Promise; processUserDeletion( diff --git a/src/routes/utils/constants.js b/src/routes/utils/constants.js index f074db6c62..ccec8e54dd 100644 --- a/src/routes/utils/constants.js +++ b/src/routes/utils/constants.js @@ -1,4 +1,4 @@ -const SUPPORTED_VERSIONS = ['v0']; +const SUPPORTED_VERSIONS = ['v0', 'v1']; const API_VERSION = '2'; const INTEGRATION_SERVICE = { COMPARATOR: 'comparator', @@ -7,8 +7,8 @@ const INTEGRATION_SERVICE = { NATIVE_DEST: 'native_dest', NATIVE_SOURCE: 'native_source', }; -const CHANNELS= { - sources: 'sources' +const CHANNELS = { + sources: 'sources', }; const RETL_TIMESTAMP = 'timestamp'; diff --git a/src/services/comparator.ts b/src/services/comparator.ts index 7f63da9402..58c96beabb 100644 --- a/src/services/comparator.ts +++ b/src/services/comparator.ts @@ -368,11 +368,13 @@ export class ComparatorService implements DestinationService { event: ProcessorTransformationOutput, destinationType: string, requestMetadata: NonNullable, + version: string, ): Promise { const primaryResplist = await this.primaryService.deliver( event, destinationType, requestMetadata, + version, ); logger.error('[LIVE_COMPARE_TEST] not implemented for delivery routine'); diff --git a/src/services/destination/nativeIntegration.ts b/src/services/destination/nativeIntegration.ts index 6763f54c7e..510fa80362 100644 --- a/src/services/destination/nativeIntegration.ts +++ b/src/services/destination/nativeIntegration.ts @@ -172,9 +172,10 @@ export class NativeIntegrationDestinationService implements DestinationService { destinationRequest: ProcessorTransformationOutput, destinationType: string, _requestMetadata: NonNullable, + version: string, ): Promise { try { - const networkHandler = networkHandlerFactory.getNetworkHandler(destinationType); + const networkHandler = networkHandlerFactory.getNetworkHandler(destinationType, version); const rawProxyResponse = await networkHandler.proxy(destinationRequest, destinationType); const processedProxyResponse = networkHandler.processAxiosResponse(rawProxyResponse); return networkHandler.responseHandler( diff --git a/src/v1/destinations/campaign_manager/networkHandler.js b/src/v1/destinations/campaign_manager/networkHandler.js new file mode 100644 index 0000000000..b3b82c8cf3 --- /dev/null +++ b/src/v1/destinations/campaign_manager/networkHandler.js @@ -0,0 +1,117 @@ +/* eslint-disable no-param-reassign */ +/* eslint-disable no-restricted-syntax */ +const { NetworkError } = require('@rudderstack/integrations-lib'); +const { prepareProxyRequest, proxyRequest } = require('../../../adapters/network'); +const { isHttpStatusSuccess, getAuthErrCategoryFromStCode } = require('../../../v0/util/index'); + +const { + processAxiosResponse, + getDynamicErrorType, +} = require('../../../adapters/utils/networkUtils'); +const tags = require('../../../v0/util/tags'); + +function isEventRetryableAndExtractErrMsg(element, proxyOutputObj) { + let isRetryable = false; + let errorMsg = ''; + // success event + if (!element.errors) { + return isRetryable; + } + for (const err of element.errors) { + errorMsg += `${err.message}, `; + if (err.code === 'INTERNAL') { + isRetryable = true; + } + } + if (errorMsg) { + proxyOutputObj.error = errorMsg; + } + return isRetryable; +} + +function isEventAbortableAndExtractErrMsg(element, proxyOutputObj) { + let isAbortable = false; + let errorMsg = ''; + // success event + if (!element.errors) { + return isAbortable; + } + for (const err of element.errors) { + errorMsg += `${err.message}, `; + // if code is any of these, event is not retryable + if ( + err.code === 'PERMISSION_DENIED' || + err.code === 'INVALID_ARGUMENT' || + err.code === 'NOT_FOUND' + ) { + isAbortable = true; + } + } + if (errorMsg) { + proxyOutputObj.error = errorMsg; + } + return isAbortable; +} + +const responseHandler = (destinationResponse) => { + const message = `[CAMPAIGN_MANAGER Response V1 Handler] - Request Processed Successfully`; + const responseWithIndividualEvents = []; + const { response, status, rudderJobMetadata } = destinationResponse; + + if (isHttpStatusSuccess(status)) { + // check for Partial Event failures and Successes + const destPartialStatus = response.status; + + for (const [idx, element] of destPartialStatus.entries()) { + const proxyOutputObj = { + statusCode: 200, + metadata: rudderJobMetadata[idx], + error: 'success', + }; + // update status of partial event as per retriable or abortable + if (isEventRetryableAndExtractErrMsg(element, proxyOutputObj)) { + proxyOutputObj.statusCode = 500; + } else if (isEventAbortableAndExtractErrMsg(element, proxyOutputObj)) { + proxyOutputObj.statusCode = 400; + } + responseWithIndividualEvents.push(proxyOutputObj); + } + + return { + status, + message, + destinationResponse, + response: responseWithIndividualEvents, + }; + } + + // in case of failure status, populate response to maintain len(metadata)=len(response) + const errorMessage = response.error?.message || 'unknown error format'; + for (const metadata of rudderJobMetadata) { + responseWithIndividualEvents.push({ + statusCode: 500, + metadata, + error: errorMessage, + }); + } + + throw new NetworkError( + `Campaign Manager: Error transformer proxy v1 during CAMPAIGN_MANAGER response transformation`, + 500, + { + [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(status), + }, + destinationResponse, + getAuthErrCategoryFromStCode(status), + responseWithIndividualEvents, + ); +}; + +function networkHandler() { + this.prepareProxy = prepareProxyRequest; + this.proxy = proxyRequest; + this.processAxiosResponse = processAxiosResponse; + this.responseHandler = responseHandler; +} + +module.exports = { networkHandler }; diff --git a/test/__tests__/data/campaign_manager_proxy_input.json b/test/__tests__/data/campaign_manager_proxy_input.json deleted file mode 100644 index e7bf369d0c..0000000000 --- a/test/__tests__/data/campaign_manager_proxy_input.json +++ /dev/null @@ -1,96 +0,0 @@ -[ - { - "request": { - "body": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://dfareporting.googleapis.com/dfareporting/v4/userprofiles/437689/conversions/batchupdate", - "headers": { - "Authorization": "Bearer dummyApiKey", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "kind": "dfareporting#conversionsBatchInsertRequest", - "encryptionInfo": { - "kind": "dfareporting#encryptionInfo", - "encryptionSource": "AD_SERVING", - "encryptionEntityId": "3564523", - "encryptionEntityType": "DCM_ACCOUNT" - }, - "conversions": [ - { - "timestampMicros": "1668624722000000", - "floodlightConfigurationId": "213123123", - "ordinal": "string", - "floodlightActivityId": "456543345245", - "mobileDeviceId": "string", - "value": 7, - "encryptedUserIdCandidates": ["dfghjbnm"], - "gclid": "string", - "matchId": "string", - "dclid": "string", - "impressionId": "string", - "limitAdTracking": true, - "childDirectedTreatment": true - } - ] - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {} - } - } - }, - { - "request": { - "body": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://dfareporting.googleapis.com/dfareporting/v4/userprofiles/437689/conversions/batchupdate", - "headers": { - "Authorization": "Bearer dummyApiKey", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": { - "kind": "dfareporting#conversionsBatchUpdateRequest", - "encryptionInfo": { - "kind": "dfareporting#encryptionInfo", - "encryptionSource": "AD_SERVING", - "encryptionEntityId": "3564523", - "encryptionEntityType": "DCM_ACCOUNT" - }, - "conversions": [ - { - "timestampMicros": "1668624722000000", - "floodlightConfigurationId": "213123123", - "ordinal": "string", - "floodlightActivityId": "456543345245", - "mobileDeviceId": "string", - "value": 7, - "encryptedUserIdCandidates": ["dfghjbnm"], - "gclid": "string", - "matchId": "string", - "dclid": "string", - "impressionId": "string", - "limitAdTracking": true, - "childDirectedTreatment": true - } - ] - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {} - } - } - } -] diff --git a/test/__tests__/data/campaign_manager_proxy_output.json b/test/__tests__/data/campaign_manager_proxy_output.json deleted file mode 100644 index c5dcc4559f..0000000000 --- a/test/__tests__/data/campaign_manager_proxy_output.json +++ /dev/null @@ -1,51 +0,0 @@ -[ - { - "output": { - "destinationResponse": { - "error": { - "code": 403, - "message": "The caller does not have permission", - "errors": [ - { - "message": "Invalid Credentials", - "domain": "global", - "reason": "authError", - "location": "Authorization", - "locationType": "header" - } - ], - "status": "PERMISSION_DENIED" - } - }, - "message": "Campaign Manager: Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project. during CAMPAIGN_MANAGER response transformation", - "statTags": { - "destType": "CAMPAIGN_MANAGER", - "errorAt": "proxy", - "scope": "exception", - "stage": "responseTransform" - }, - "status": 403 - } - }, - { - "output": { - "status": 200, - "message": "[CAMPAIGN_MANAGER Response Handler] - Request Processed Successfully", - "destinationResponse": { - "response": [ - { - "adjustmentType": "ENHANCEMENT", - "conversionAction": "customers/7693729833/conversionActions/874224905", - "adjustmentDateTime": "2021-01-01 12:32:45-08:00", - "gclidDateTimePair": { - "gclid": "1234", - "conversionDateTime": "2021-01-01 12:32:45-08:00" - }, - "orderId": "12345" - } - ], - "status": 200 - } - } - } -] diff --git a/test/integrations/destinations/campaign_manager/dataDelivery/data.ts b/test/integrations/destinations/campaign_manager/dataDelivery/data.ts new file mode 100644 index 0000000000..f2a7654e3c --- /dev/null +++ b/test/integrations/destinations/campaign_manager/dataDelivery/data.ts @@ -0,0 +1,604 @@ +export const data = [ + { + name: 'campaign_manager', + description: 'Sucess insert request', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: + 'https://dfareporting.googleapis.com/dfareporting/v4/userprofiles/437689/conversions/batchinsert', + headers: { + Authorization: 'Bearer dummyApiKey', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + kind: 'dfareporting#conversionsBatchInsertRequest', + encryptionInfo: { + kind: 'dfareporting#encryptionInfo', + encryptionSource: 'AD_SERVING', + encryptionEntityId: '3564523', + encryptionEntityType: 'DCM_ACCOUNT', + }, + conversions: [ + { + timestampMicros: '1668624722000000', + floodlightConfigurationId: '213123123', + ordinal: '1', + floodlightActivityId: '456543345245', + value: 7, + gclid: '123', + limitAdTracking: true, + childDirectedTreatment: true, + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + }, + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 200, + message: '[CAMPAIGN_MANAGER Response Handler] - Request Processed Successfully', + destinationResponse: { + response: { + hasFailures: false, + status: [ + { + conversion: { + timestampMicros: '1668624722000000', + floodlightConfigurationId: '213123123', + ordinal: '1', + floodlightActivityId: '456543345245', + value: 7, + gclid: '123', + limitAdTracking: true, + childDirectedTreatment: true, + }, + kind: 'dfareporting#conversionStatus', + }, + ], + kind: 'dfareporting#conversionsBatchInsertResponse', + }, + status: 200, + }, + }, + }, + }, + }, + }, + { + name: 'campaign_manager', + description: 'Failure insert request', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: + 'https://dfareporting.googleapis.com/dfareporting/v4/userprofiles/437690/conversions/batchinsert', + headers: { + Authorization: 'Bearer dummyApiKey', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + kind: 'dfareporting#conversionsBatchInsertRequest', + encryptionInfo: { + kind: 'dfareporting#encryptionInfo', + encryptionSource: 'AD_SERVING', + encryptionEntityId: '3564523', + encryptionEntityType: 'DCM_ACCOUNT', + }, + conversions: [ + { + timestampMicros: '1668624722000000', + floodlightConfigurationId: '213123123', + ordinal: '1', + floodlightActivityId: '456543345245', + value: 7, + gclid: '123', + limitAdTracking: true, + childDirectedTreatment: true, + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + }, + method: 'POST', + }, + }, + output: { + response: { + status: 500, + body: { + output: { + status: 500, + message: 'Campaign Manager: Retrying during CAMPAIGN_MANAGER response transformation', + statTags: { + errorCategory: 'network', + errorType: 'retryable', + destType: 'CAMPAIGN_MANAGER', + module: 'destination', + implementation: 'native', + feature: 'dataDelivery', + destinationId: 'Non-determininable', + workspaceId: 'Non-determininable', + }, + destinationResponse: { + response: { + hasFailures: true, + status: [ + { + conversion: { + timestampMicros: '1668624722000000', + floodlightConfigurationId: '213123123', + ordinal: '1', + floodlightActivityId: '456543345245', + value: 7, + gclid: '123', + limitAdTracking: true, + childDirectedTreatment: true, + }, + errors: [ + { + code: 'NOT_FOUND', + message: 'Floodlight config id: 213123123 was not found.', + kind: 'dfareporting#conversionError', + }, + ], + kind: 'dfareporting#conversionStatus', + }, + ], + kind: 'dfareporting#conversionsBatchInsertResponse', + }, + status: 200, + }, + }, + }, + }, + }, + }, + { + name: 'campaign_manager', + description: 'Failure insert request Aborted', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: + 'https://dfareporting.googleapis.com/dfareporting/v4/userprofiles/437691/conversions/batchinsert', + headers: { + Authorization: 'Bearer dummyApiKey', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + kind: 'dfareporting#conversionsBatchInsertRequest', + encryptionInfo: { + kind: 'dfareporting#encryptionInfo', + encryptionSource: 'AD_SERVING', + encryptionEntityId: '3564523', + encryptionEntityType: 'DCM_ACCOUNT', + }, + conversions: [ + { + timestampMicros: '1668624722000000', + floodlightConfigurationId: '213123123', + ordinal: '1', + floodlightActivityId: '456543345245', + value: 7, + gclid: '123', + limitAdTracking: true, + childDirectedTreatment: true, + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + }, + method: 'POST', + }, + }, + output: { + response: { + status: 400, + body: { + output: { + status: 400, + message: 'Campaign Manager: Aborting during CAMPAIGN_MANAGER response transformation', + statTags: { + errorCategory: 'network', + errorType: 'aborted', + destType: 'CAMPAIGN_MANAGER', + module: 'destination', + implementation: 'native', + feature: 'dataDelivery', + destinationId: 'Non-determininable', + workspaceId: 'Non-determininable', + }, + destinationResponse: { + response: { + hasFailures: true, + status: [ + { + conversion: { + timestampMicros: '1668624722000000', + floodlightConfigurationId: '213123123', + ordinal: '1', + floodlightActivityId: '456543345245', + value: 7, + gclid: '123', + limitAdTracking: true, + childDirectedTreatment: true, + }, + errors: [ + { + code: 'INVALID_ARGUMENT', + message: 'Floodlight config id: 213123123 was not found.', + kind: 'dfareporting#conversionError', + }, + ], + kind: 'dfareporting#conversionStatus', + }, + ], + kind: 'dfareporting#conversionsBatchInsertResponse', + }, + status: 200, + }, + }, + }, + }, + }, + }, + { + name: 'campaign_manager', + description: 'Sucess and fail insert request v1', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: + 'https://dfareporting.googleapis.com/dfareporting/v4/userprofiles/437692/conversions/batchinsert', + headers: { + Authorization: 'Bearer dummyApiKey', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + kind: 'dfareporting#conversionsBatchInsertRequest', + conversions: [ + { + timestampMicros: '1668624722000000', + floodlightConfigurationId: '213123123', + ordinal: '1', + floodlightActivityId: '456543345245', + value: 7, + gclid: '123', + limitAdTracking: true, + childDirectedTreatment: true, + }, + { + timestampMicros: '1668624722000000', + floodlightConfigurationId: '213123123', + ordinal: '1', + floodlightActivityId: '456543345245', + value: 8, + gclid: '123', + limitAdTracking: true, + childDirectedTreatment: true, + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + metadata: [ + { + jobId: 2, + attemptNum: 0, + userId: '', + sourceId: '2Vsge2uWYdrLfG7pZb5Y82eo4lr', + destinationId: '2RHh08uOsXqE9KvCDg3hoaeuK2L', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', + secret: { + access_token: 'secret', + refresh_token: 'refresh', + developer_token: 'developer_Token', + }, + }, + { + jobId: 3, + attemptNum: 1, + userId: '', + sourceId: '2Vsge2uWYdrLfG7pZb5Y82eo4lr', + destinationId: '2RHh08uOsXqE9KvCDg3hoaeuK2L', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', + secret: { + access_token: 'secret', + refresh_token: 'refresh', + developer_token: 'developer_Token', + }, + }, + ], + files: {}, + }, + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 200, + message: '[CAMPAIGN_MANAGER Response V1 Handler] - Request Processed Successfully', + destinationResponse: { + response: { + hasFailures: true, + status: [ + { + conversion: { + timestampMicros: '1668624722000000', + floodlightConfigurationId: '213123123', + ordinal: '1', + floodlightActivityId: '456543345245', + value: 7, + gclid: '123', + limitAdTracking: true, + childDirectedTreatment: true, + }, + kind: 'dfareporting#conversionStatus', + errors: [ + { + code: 'INVALID_ARGUMENT', + kind: 'dfareporting#conversionError', + message: 'Floodlight config id: 213123123 was not found.', + }, + ], + }, + { + conversion: { + timestampMicros: '1668624722000000', + floodlightConfigurationId: '213123123', + ordinal: '1', + floodlightActivityId: '456543345245', + value: 8, + gclid: '123', + limitAdTracking: true, + childDirectedTreatment: true, + }, + kind: 'dfareporting#conversionStatus', + }, + ], + kind: 'dfareporting#conversionsBatchInsertResponse', + }, + status: 200, + rudderJobMetadata: [ + { + jobId: 2, + attemptNum: 0, + userId: '', + sourceId: '2Vsge2uWYdrLfG7pZb5Y82eo4lr', + destinationId: '2RHh08uOsXqE9KvCDg3hoaeuK2L', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', + secret: { + access_token: 'secret', + refresh_token: 'refresh', + developer_token: 'developer_Token', + }, + }, + { + jobId: 3, + attemptNum: 1, + userId: '', + sourceId: '2Vsge2uWYdrLfG7pZb5Y82eo4lr', + destinationId: '2RHh08uOsXqE9KvCDg3hoaeuK2L', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', + secret: { + access_token: 'secret', + refresh_token: 'refresh', + developer_token: 'developer_Token', + }, + }, + ], + }, + response: [ + { + error: 'Floodlight config id: 213123123 was not found., ', + statusCode: 400, + metadata: { + attemptNum: 0, + destinationId: '2RHh08uOsXqE9KvCDg3hoaeuK2L', + jobId: 2, + secret: { + access_token: 'secret', + developer_token: 'developer_Token', + refresh_token: 'refresh', + }, + sourceId: '2Vsge2uWYdrLfG7pZb5Y82eo4lr', + userId: '', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', + }, + }, + { + error: 'success', + metadata: { + attemptNum: 1, + destinationId: '2RHh08uOsXqE9KvCDg3hoaeuK2L', + jobId: 3, + secret: { + access_token: 'secret', + developer_token: 'developer_Token', + refresh_token: 'refresh', + }, + sourceId: '2Vsge2uWYdrLfG7pZb5Y82eo4lr', + userId: '', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', + }, + statusCode: 200, + }, + ], + }, + }, + }, + }, + }, + { + name: 'campaign_manager', + description: 'Sucess insert request v1', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: + 'https://dfareporting.googleapis.com/dfareporting/v4/userprofiles/43770/conversions/batchinsert', + headers: { + Authorization: 'Bearer dummyApiKey', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + kind: 'dfareporting#conversionsBatchInsertRequest', + encryptionInfo: { + kind: 'dfareporting#encryptionInfo', + encryptionSource: 'AD_SERVING', + encryptionEntityId: '3564523', + encryptionEntityType: 'DCM_ACCOUNT', + }, + conversions: [ + { + timestampMicros: '1668624722000000', + floodlightConfigurationId: '213123123', + ordinal: '1', + floodlightActivityId: '456543345245', + value: 7, + gclid: '123', + limitAdTracking: true, + childDirectedTreatment: true, + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + metadata: { + jobId: 2, + attemptNum: 0, + userId: '', + sourceId: '2Vsge2uWYdrLfG7pZb5Y82eo4lr', + destinationId: '2RHh08uOsXqE9KvCDg3hoaeuK2L', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', + secret: { + access_token: 'secret', + refresh_token: 'refresh', + developer_token: 'developer_Token', + }, + }, + files: {}, + }, + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 200, + message: '[CAMPAIGN_MANAGER Response V1 Handler] - Request Processed Successfully', + destinationResponse: { + response: { + hasFailures: false, + status: [ + { + conversion: { + timestampMicros: '1668624722000000', + floodlightConfigurationId: '213123123', + ordinal: '1', + floodlightActivityId: '456543345245', + value: 7, + gclid: '123', + limitAdTracking: true, + childDirectedTreatment: true, + }, + kind: 'dfareporting#conversionStatus', + }, + ], + kind: 'dfareporting#conversionsBatchInsertResponse', + }, + status: 200, + rudderJobMetadata: { + jobId: 2, + attemptNum: 0, + userId: '', + sourceId: '2Vsge2uWYdrLfG7pZb5Y82eo4lr', + destinationId: '2RHh08uOsXqE9KvCDg3hoaeuK2L', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', + secret: { + access_token: 'secret', + refresh_token: 'refresh', + developer_token: 'developer_Token', + }, + }, + }, + response: [ + { + error: 'success', + statusCode: 200, + }, + ], + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/campaign_manager/network.ts b/test/integrations/destinations/campaign_manager/network.ts new file mode 100644 index 0000000000..ddecbaf8fa --- /dev/null +++ b/test/integrations/destinations/campaign_manager/network.ts @@ -0,0 +1,311 @@ +const Data = [ + { + httpReq: { + method: 'post', + url: 'https://dfareporting.googleapis.com/dfareporting/v4/userprofiles/437689/conversions/batchinsert', + data: { + kind: 'dfareporting#conversionsBatchInsertRequest', + encryptionInfo: { + kind: 'dfareporting#encryptionInfo', + encryptionSource: 'AD_SERVING', + encryptionEntityId: '3564523', + encryptionEntityType: 'DCM_ACCOUNT', + }, + conversions: [ + { + timestampMicros: '1668624722000000', + floodlightConfigurationId: '213123123', + ordinal: '1', + floodlightActivityId: '456543345245', + value: 7, + gclid: '123', + limitAdTracking: true, + childDirectedTreatment: true, + }, + ], + }, + headers: { + Authorization: 'Bearer dummyApiKey', + 'Content-Type': 'application/json', + }, + }, + httpRes: { + data: { + hasFailures: false, + status: [ + { + conversion: { + timestampMicros: '1668624722000000', + floodlightConfigurationId: '213123123', + ordinal: '1', + floodlightActivityId: '456543345245', + value: 7, + gclid: '123', + limitAdTracking: true, + childDirectedTreatment: true, + }, + kind: 'dfareporting#conversionStatus', + }, + ], + kind: 'dfareporting#conversionsBatchInsertResponse', + }, + status: 200, + statusText: 'OK', + }, + }, + { + httpReq: { + method: 'post', + url: 'https://dfareporting.googleapis.com/dfareporting/v4/userprofiles/437690/conversions/batchinsert', + data: { + kind: 'dfareporting#conversionsBatchInsertRequest', + encryptionInfo: { + kind: 'dfareporting#encryptionInfo', + encryptionSource: 'AD_SERVING', + encryptionEntityId: '3564523', + encryptionEntityType: 'DCM_ACCOUNT', + }, + conversions: [ + { + timestampMicros: '1668624722000000', + floodlightConfigurationId: '213123123', + ordinal: '1', + floodlightActivityId: '456543345245', + value: 7, + gclid: '123', + limitAdTracking: true, + childDirectedTreatment: true, + }, + ], + }, + headers: { + Authorization: 'Bearer dummyApiKey', + 'Content-Type': 'application/json', + }, + }, + httpRes: { + data: { + hasFailures: true, + status: [ + { + conversion: { + timestampMicros: '1668624722000000', + floodlightConfigurationId: '213123123', + ordinal: '1', + floodlightActivityId: '456543345245', + value: 7, + gclid: '123', + limitAdTracking: true, + childDirectedTreatment: true, + }, + errors: [ + { + code: 'NOT_FOUND', + message: 'Floodlight config id: 213123123 was not found.', + kind: 'dfareporting#conversionError', + }, + ], + kind: 'dfareporting#conversionStatus', + }, + ], + kind: 'dfareporting#conversionsBatchInsertResponse', + }, + status: 200, + statusText: 'OK', + }, + }, + { + httpReq: { + method: 'post', + url: 'https://dfareporting.googleapis.com/dfareporting/v4/userprofiles/43770/conversions/batchinsert', + data: { + kind: 'dfareporting#conversionsBatchInsertRequest', + encryptionInfo: { + kind: 'dfareporting#encryptionInfo', + encryptionSource: 'AD_SERVING', + encryptionEntityId: '3564523', + encryptionEntityType: 'DCM_ACCOUNT', + }, + conversions: [ + { + timestampMicros: '1668624722000000', + floodlightConfigurationId: '213123123', + ordinal: '1', + floodlightActivityId: '456543345245', + value: 7, + gclid: '123', + limitAdTracking: true, + childDirectedTreatment: true, + }, + ], + }, + headers: { + Authorization: 'Bearer dummyApiKey', + 'Content-Type': 'application/json', + }, + }, + httpRes: { + data: { + hasFailures: false, + status: [ + { + conversion: { + timestampMicros: '1668624722000000', + floodlightConfigurationId: '213123123', + ordinal: '1', + floodlightActivityId: '456543345245', + value: 7, + gclid: '123', + limitAdTracking: true, + childDirectedTreatment: true, + }, + kind: 'dfareporting#conversionStatus', + }, + ], + kind: 'dfareporting#conversionsBatchInsertResponse', + }, + status: 200, + statusText: 'OK', + }, + }, + { + httpReq: { + method: 'post', + url: 'https://dfareporting.googleapis.com/dfareporting/v4/userprofiles/437692/conversions/batchinsert', + data: { + kind: 'dfareporting#conversionsBatchInsertRequest', + conversions: [ + { + timestampMicros: '1668624722000000', + floodlightConfigurationId: '213123123', + ordinal: '1', + floodlightActivityId: '456543345245', + value: 7, + gclid: '123', + limitAdTracking: true, + childDirectedTreatment: true, + }, + { + timestampMicros: '1668624722000000', + floodlightConfigurationId: '213123123', + ordinal: '1', + floodlightActivityId: '456543345245', + value: 8, + gclid: '123', + limitAdTracking: true, + childDirectedTreatment: true, + }, + ], + }, + headers: { + Authorization: 'Bearer dummyApiKey', + 'Content-Type': 'application/json', + }, + }, + httpRes: { + data: { + hasFailures: true, + status: [ + { + conversion: { + timestampMicros: '1668624722000000', + floodlightConfigurationId: '213123123', + ordinal: '1', + floodlightActivityId: '456543345245', + value: 7, + gclid: '123', + limitAdTracking: true, + childDirectedTreatment: true, + }, + errors: [ + { + code: 'INVALID_ARGUMENT', + message: 'Floodlight config id: 213123123 was not found.', + kind: 'dfareporting#conversionError', + }, + ], + kind: 'dfareporting#conversionStatus', + }, + { + conversion: { + timestampMicros: '1668624722000000', + floodlightConfigurationId: '213123123', + ordinal: '1', + floodlightActivityId: '456543345245', + value: 8, + gclid: '123', + limitAdTracking: true, + childDirectedTreatment: true, + }, + kind: 'dfareporting#conversionStatus', + }, + ], + kind: 'dfareporting#conversionsBatchInsertResponse', + }, + status: 200, + statusText: 'OK', + }, + }, + { + httpReq: { + method: 'post', + url: 'https://dfareporting.googleapis.com/dfareporting/v4/userprofiles/437691/conversions/batchinsert', + data: { + kind: 'dfareporting#conversionsBatchInsertRequest', + encryptionInfo: { + kind: 'dfareporting#encryptionInfo', + encryptionSource: 'AD_SERVING', + encryptionEntityId: '3564523', + encryptionEntityType: 'DCM_ACCOUNT', + }, + conversions: [ + { + timestampMicros: '1668624722000000', + floodlightConfigurationId: '213123123', + ordinal: '1', + floodlightActivityId: '456543345245', + value: 7, + gclid: '123', + limitAdTracking: true, + childDirectedTreatment: true, + }, + ], + }, + headers: { + Authorization: 'Bearer dummyApiKey', + 'Content-Type': 'application/json', + }, + }, + httpRes: { + data: { + hasFailures: true, + status: [ + { + conversion: { + timestampMicros: '1668624722000000', + floodlightConfigurationId: '213123123', + ordinal: '1', + floodlightActivityId: '456543345245', + value: 7, + gclid: '123', + limitAdTracking: true, + childDirectedTreatment: true, + }, + errors: [ + { + code: 'INVALID_ARGUMENT', + message: 'Floodlight config id: 213123123 was not found.', + kind: 'dfareporting#conversionError', + }, + ], + kind: 'dfareporting#conversionStatus', + }, + ], + kind: 'dfareporting#conversionsBatchInsertResponse', + }, + status: 200, + statusText: 'OK', + }, + }, +]; +export const networkCallsData = [...Data]; From 571dbf5bd65e7d0e261562ff3da3b393f27f27b6 Mon Sep 17 00:00:00 2001 From: Yashasvi Bajpai <33063622+yashasvibajpai@users.noreply.github.com> Date: Thu, 30 Nov 2023 13:05:00 +0530 Subject: [PATCH 50/93] fix: encode &, < and > to html counterparts in adobe analytics (#2854) * fix: encode &, < and > to html counterparts in adobe * fix: use encodeurl on url valuez --- .../destinations/adobe_analytics/transform.js | 3 +- src/v0/destinations/adobe_analytics/utils.js | 26 ++++++++-- .../adobe_analytics/processor/data.ts | 47 ++++++++++--------- 3 files changed, 49 insertions(+), 27 deletions(-) diff --git a/src/v0/destinations/adobe_analytics/transform.js b/src/v0/destinations/adobe_analytics/transform.js index a805e379ff..8bac0edd70 100644 --- a/src/v0/destinations/adobe_analytics/transform.js +++ b/src/v0/destinations/adobe_analytics/transform.js @@ -76,6 +76,7 @@ const responseBuilderSimple = async (message, destinationConfig, basicPayload) = } payload.linkURL = adobeIntegrationsObject?.linkURL || context?.page?.url || 'No linkURL provided'; + payload.linkURL = encodeURI(payload.linkURL); } // handle hier if (overrideHiers) { @@ -97,7 +98,7 @@ const responseBuilderSimple = async (message, destinationConfig, basicPayload) = const propertiesPageUrl = properties?.pageUrl; const pageUrl = contextPageUrl || propertiesPageUrl; if (isDefinedAndNotNullAndNotEmpty(pageUrl)) { - payload.pageUrl = pageUrl; + payload.pageUrl = encodeURI(pageUrl); } if (trackPageName) { // better handling possible here, both error and implementation wise diff --git a/src/v0/destinations/adobe_analytics/utils.js b/src/v0/destinations/adobe_analytics/utils.js index cbd4f51c23..bcb138d77b 100644 --- a/src/v0/destinations/adobe_analytics/utils.js +++ b/src/v0/destinations/adobe_analytics/utils.js @@ -75,6 +75,25 @@ function handleContextData(payload, destinationConfig, message) { return payload; } +/** + * This function is used for replacing '&', '<' and '>' with their respective HTML entities + * @param {*} inputString + * @returns string with HTML entities replaced + * + */ + +function escapeToHTML(inputString) { + return inputString.replace( + /[&<>]/g, + (match) => + ({ + '&': '&', + '<': '<', + '>': '>', + }[match]), + ); +} + /** * This function is used for populating the eVars and hVars in the payload * @param {*} destVarMapping @@ -90,16 +109,16 @@ function rudderPropToDestMap(destVarMapping, message, payload, destVarStrPrefix) let val = get(message, `properties.${key}`); if (isDefinedAndNotNull(val)) { const destVarKey = destVarStrPrefix + destVarMapping[key]; - mappedVar[destVarKey] = val; + mappedVar[destVarKey] = escapeToHTML(val); } else { SOURCE_KEYS.some((sourceKey) => { val = getMappingFieldValueFormMessage(message, sourceKey, key); if (isDefinedAndNotNull(val)) { - mappedVar[`${destVarStrPrefix}${[destVarMapping[key]]}`] = val; + mappedVar[`${destVarStrPrefix}${[destVarMapping[key]]}`] = escapeToHTML(val); } else { val = getValueByPath(message, key); if (isDefinedAndNotNull(val)) { - mappedVar[`${destVarStrPrefix}${[destVarMapping[key]]}`] = val; + mappedVar[`${destVarStrPrefix}${[destVarMapping[key]]}`] = escapeToHTML(val); } } }); @@ -200,4 +219,5 @@ module.exports = { handleList, handleCustomProperties, stringifyValueAndJoinWithDelimiter, + escapeToHTML, }; diff --git a/test/integrations/destinations/adobe_analytics/processor/data.ts b/test/integrations/destinations/adobe_analytics/processor/data.ts index 378523ac3c..690639c057 100644 --- a/test/integrations/destinations/adobe_analytics/processor/data.ts +++ b/test/integrations/destinations/adobe_analytics/processor/data.ts @@ -1,7 +1,7 @@ export const data = [ { name: 'adobe_analytics', - description: 'Test 0', + description: 'Test 0: [ECom]: Product Viewed', feature: 'processor', module: 'destination', version: 'v0', @@ -31,7 +31,7 @@ export const data = [ referring_domain: 'google.com', search: 'estore bestseller', title: 'The best sellers offered by EStore', - url: 'https://www.estore.com/best-seller/1', + url: 'https://www.estore.com/best-seller/News & Sports?ik=123&ij=456', name: 'Best Seller', }, screen: { @@ -61,7 +61,7 @@ export const data = [ coupon: 'DISC21', currency: 'USD', position: 1, - url: 'https://www.website.com/product/path', + url: 'https://www.website.com/product/path?ik=123&ij=456', image_url: 'https://www.website.com/product/path.png', currencyMerch: 25, addressMerch: 'Delhi', @@ -170,7 +170,7 @@ export const data = [ JSON_ARRAY: {}, XML: { payload: - '17941080sales campaignwebUSD127.0.0.1en-USDalvik/2.1.0 (Linux; U; Android 9; Android SDK built for x86 Build/PSR1.180720.075)https://www.google.com/search?q=estore+bestsellert01t02roottval001Kolkata9935400932RudderLabs JavaScript SDKr15,faze90Rciaz,hummer,tharhttps://www.estore.com/best-seller/1Best Sellercustompropval1custompropval22020-01-09T10:01:53.558Zmktcloudid001prodViewGames;Game;11;148.39footlockerrudderstackpoc', + '17941080sales campaignwebUSD127.0.0.1en-USDalvik/2.1.0 (Linux; U; Android 9; Android SDK built for x86 Build/PSR1.180720.075)https://www.google.com/search?q=estore+bestsellert01t02roottval001Kolkata9935400932RudderLabs JavaScript SDKr15,faze90Rciaz,hummer,tharhttps://www.estore.com/best-seller/News%20&%20Sports?ik=123&ij=456Best Sellercustompropval1custompropval22020-01-09T10:01:53.558Zmktcloudid001prodViewGames;Game;11;148.39footlockerrudderstackpoc', }, FORM: {}, }, @@ -185,7 +185,7 @@ export const data = [ }, { name: 'adobe_analytics', - description: 'Test 1', + description: 'Test 1: [ECom]: Product Added', feature: 'processor', module: 'destination', version: 'v0', @@ -356,7 +356,7 @@ export const data = [ }, { name: 'adobe_analytics', - description: 'Test 2', + description: 'Test 2: [ECom]: Product Removed', feature: 'processor', module: 'destination', version: 'v0', @@ -527,7 +527,7 @@ export const data = [ }, { name: 'adobe_analytics', - description: 'Test 3', + description: 'Test 3: [ECom]: Cart Viewed', feature: 'processor', module: 'destination', version: 'v0', @@ -708,7 +708,7 @@ export const data = [ }, { name: 'adobe_analytics', - description: 'Test 4', + description: 'Test 4: [ECom]: Checkout started', feature: 'processor', module: 'destination', version: 'v0', @@ -896,7 +896,7 @@ export const data = [ }, { name: 'adobe_analytics', - description: 'Test 5', + description: 'Test 5: [ECom]: Order Completed', feature: 'processor', module: 'destination', version: 'v0', @@ -1085,7 +1085,7 @@ export const data = [ }, { name: 'adobe_analytics', - description: 'Test 6', + description: 'Test 6: Cart Opened', feature: 'processor', module: 'destination', version: 'v0', @@ -1265,7 +1265,7 @@ export const data = [ }, { name: 'adobe_analytics', - description: 'Test 7', + description: 'Test 7: [Custom] Watched Video', feature: 'processor', module: 'destination', version: 'v0', @@ -1285,7 +1285,7 @@ export const data = [ term: 'event data', content: 'Make sense of the modern data stack', }, - library: { name: 'RudderLabs JavaScript SDK', version: '2.9.1' }, + library: { name: 'RudderLabs JavaScript SDK ', version: '2.9.1' }, locale: 'en-US', page: { path: '/best-seller/1', @@ -1311,7 +1311,7 @@ export const data = [ traits: { roott01: 'roottval001' }, event: 'Watched Video', integrations: { All: true }, - properties: { plan: 'growth', video: 'TEDxGROWTH' }, + properties: { plan: 'growth', video: 'TEDxGROWTH&MARKETING' }, originalTimestamp: '2020-01-09T10:01:53.558Z', type: 'track', sentAt: '2020-01-09T10:02:03.257Z', @@ -1412,7 +1412,7 @@ export const data = [ JSON_ARRAY: {}, XML: { payload: - '17941080sales campaignweb127.0.0.1en-USDalvik/2.1.0 (Linux; U; Android 9; Android SDK built for x86 Build/PSR1.180720.075)https://www.google.com/search?q=estore+bestsellerroottval001RudderLabs JavaScript SDKTEDxGROWTHoWatched Videohttps://www.estore.com/best-seller/1growth2020-01-09T10:01:53.558Zmktcloudid001event1footlockerrudderstackpoc', + '17941080sales campaignweb127.0.0.1en-USDalvik/2.1.0 (Linux; U; Android 9; Android SDK built for x86 Build/PSR1.180720.075)https://www.google.com/search?q=estore+bestsellerroottval001RudderLabs JavaScript SDK <Custom>TEDxGROWTH&MARKETINGoWatched Videohttps://www.estore.com/best-seller/1growth2020-01-09T10:01:53.558Zmktcloudid001event1footlockerrudderstackpoc', }, FORM: {}, }, @@ -1427,7 +1427,7 @@ export const data = [ }, { name: 'adobe_analytics', - description: 'Test 8', + description: 'Test 8: Common Page Call', feature: 'processor', module: 'destination', version: 'v0', @@ -1597,7 +1597,7 @@ export const data = [ }, { name: 'adobe_analytics', - description: 'Test 9', + description: 'Test 9: Currency test event', feature: 'processor', module: 'destination', version: 'v0', @@ -1789,7 +1789,7 @@ export const data = [ }, { name: 'adobe_analytics', - description: 'Test 10', + description: 'Test 10: Override feature test', feature: 'processor', module: 'destination', version: 'v0', @@ -1988,7 +1988,7 @@ export const data = [ }, { name: 'adobe_analytics', - description: 'Test 11', + description: 'Test 11: Override hiers test', feature: 'processor', module: 'destination', version: 'v0', @@ -2188,7 +2188,7 @@ export const data = [ }, { name: 'adobe_analytics', - description: 'Test 12', + description: 'Test 12: product level eVaR', feature: 'processor', module: 'destination', version: 'v0', @@ -2390,7 +2390,7 @@ export const data = [ }, { name: 'adobe_analytics', - description: 'Test 13', + description: 'Test 13: [ERROR]: Invalid message type: Identify', feature: 'processor', module: 'destination', version: 'v0', @@ -2523,7 +2523,7 @@ export const data = [ }, { name: 'adobe_analytics', - description: 'Test 14', + description: 'Test 14: [ERROR]: Message Type is not present.', feature: 'processor', module: 'destination', version: 'v0', @@ -2697,7 +2697,8 @@ export const data = [ }, { name: 'adobe_analytics', - description: 'Test 15', + description: + 'Test 15: [ERROR]: The event is not a supported ECOM event or a mapped custom event.', feature: 'processor', module: 'destination', version: 'v0', @@ -2872,7 +2873,7 @@ export const data = [ }, { name: 'adobe_analytics', - description: 'Test 16', + description: 'Test 16: Test overrideEventName property', feature: 'processor', module: 'destination', version: 'v0', From 4b260e4ec6d25875903830004b3e4975b3402b2d Mon Sep 17 00:00:00 2001 From: AASHISH MALIK Date: Thu, 30 Nov 2023 16:05:12 +0530 Subject: [PATCH 51/93] feat: cm360 router batching (#2836) * fix: timestamp microseconds input cm360 * feat: batching in cm360 * chore: addressed comments * chore: addressed comments * fix: return aborted inside cath block * feat: update batching partial events * feat: update batching partial events * feat: update batching partial events * feat: update batching partial events * chore: removed hardcoded response * feat: added new error class * chore: develop merge * feat: handle metadata as obj * feat: handle metadata as obj * chore: removed commented code * fix: merged develop * fix: merged develop * chore: added tests for batching * chore: added tests for batching --- .../destination/postTransformation.ts | 17 +- src/types/index.ts | 1 + src/v0/destinations/am/transform.js | 54 +- .../destinations/campaign_manager/config.js | 3 + .../campaign_manager/networkHandler.js | 35 +- .../campaign_manager/transform.js | 113 ++- test/__tests__/facebook_conversions.test.js | 2 +- .../campaign_manager/dataDelivery/data.ts | 10 +- .../campaign_manager/router/data.ts | 819 +++++++++++++++++- 9 files changed, 999 insertions(+), 55 deletions(-) diff --git a/src/services/destination/postTransformation.ts b/src/services/destination/postTransformation.ts index 0b91eb7cc1..1e99961045 100644 --- a/src/services/destination/postTransformation.ts +++ b/src/services/destination/postTransformation.ts @@ -16,6 +16,15 @@ import { ErrorReportingService } from '../errorReporting'; import tags from '../../v0/util/tags'; import stats from '../../util/stats'; +type ErrorResponse = { + status?: number; + message?: string; + destinationResponse?: object; + statTags?: object; + authErrorCategory?: string | undefined; + response?: object | undefined; +}; + export class DestinationPostTransformationService { public static handleProcessorTransformSucessEvents( event: ProcessorTransformationRequest, @@ -139,7 +148,7 @@ export class DestinationPostTransformationService { } public static handleDeliveryFailureEvents( - error: NonNullable, + error: ErrorResponse, metaTo: MetaTransferObject, ): DeliveryResponse { const errObj = generateErrorObject(error, metaTo.errorDetails, false); @@ -152,6 +161,12 @@ export class DestinationPostTransformationService { authErrorCategory: errObj.authErrorCategory, }), } as DeliveryResponse; + + // for transformer-proxy to maintain contract + const { response } = error; + if (response) { + resp.response = response; + } ErrorReportingService.reportError(error, metaTo.errorContext, resp); return resp; } diff --git a/src/types/index.ts b/src/types/index.ts index 9292fe2cc2..7a23132173 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -140,6 +140,7 @@ type DeliveryResponse = { destinationResponse: any; statTags: object; authErrorCategory?: string; + response?: object; }; enum MessageType { diff --git a/src/v0/destinations/am/transform.js b/src/v0/destinations/am/transform.js index bed5d45b28..05a130d6e0 100644 --- a/src/v0/destinations/am/transform.js +++ b/src/v0/destinations/am/transform.js @@ -591,8 +591,12 @@ const processSingleMessage = (message, destination) => { const { name, event, properties } = message; const messageType = message.type.toLowerCase(); const CATEGORY_KEY = 'properties.category'; - const { useUserDefinedPageEventName, userProvidedPageEventString, - useUserDefinedScreenEventName, userProvidedScreenEventString } = destination.Config; + const { + useUserDefinedPageEventName, + userProvidedPageEventString, + useUserDefinedScreenEventName, + userProvidedScreenEventString, + } = destination.Config; switch (messageType) { case EventType.IDENTIFY: payloadObjectName = 'events'; // identify same as events @@ -602,17 +606,17 @@ const processSingleMessage = (message, destination) => { case EventType.PAGE: if (useUserDefinedPageEventName) { const getMessagePath = userProvidedPageEventString - .substring( - userProvidedPageEventString.indexOf('{') + 2, - userProvidedPageEventString.indexOf('}'), - ) - .trim(); + .substring( + userProvidedPageEventString.indexOf('{') + 2, + userProvidedPageEventString.indexOf('}'), + ) + .trim(); evType = - userProvidedPageEventString.trim() === '' - ? name - : userProvidedPageEventString - .trim() - .replaceAll(/{{([^{}]+)}}/g, get(message, getMessagePath)); + userProvidedPageEventString.trim() === '' + ? name + : userProvidedPageEventString + .trim() + .replaceAll(/{{([^{}]+)}}/g, get(message, getMessagePath)); } else { evType = `Viewed ${name || get(message, CATEGORY_KEY) || ''} Page`; } @@ -625,25 +629,25 @@ const processSingleMessage = (message, destination) => { case EventType.SCREEN: { const { eventType, updatedProperties } = getScreenevTypeAndUpdatedProperties( - message, - CATEGORY_KEY, + message, + CATEGORY_KEY, ); let customScreenEv = ''; if (useUserDefinedScreenEventName) { const getMessagePath = userProvidedScreenEventString - .substring( - userProvidedScreenEventString.indexOf('{') + 2, - userProvidedScreenEventString.indexOf('}'), - ) - .trim(); + .substring( + userProvidedScreenEventString.indexOf('{') + 2, + userProvidedScreenEventString.indexOf('}'), + ) + .trim(); customScreenEv = - userProvidedScreenEventString.trim() === '' - ? name - : userProvidedScreenEventString - .trim() - .replaceAll(/{{([^{}]+)}}/g, get(message, getMessagePath)); + userProvidedScreenEventString.trim() === '' + ? name + : userProvidedScreenEventString + .trim() + .replaceAll(/{{([^{}]+)}}/g, get(message, getMessagePath)); } - evType =useUserDefinedScreenEventName ? customScreenEv : eventType; + evType = useUserDefinedScreenEventName ? customScreenEv : eventType; message.properties = updatedProperties; category = ConfigCategory.SCREEN; } diff --git a/src/v0/destinations/campaign_manager/config.js b/src/v0/destinations/campaign_manager/config.js index 063f65cb14..b3a9531347 100644 --- a/src/v0/destinations/campaign_manager/config.js +++ b/src/v0/destinations/campaign_manager/config.js @@ -9,6 +9,8 @@ const ConfigCategories = { }, }; +const MAX_BATCH_CONVERSATIONS_SIZE = 1000; + const EncryptionEntityType = [ 'ENCRYPTION_ENTITY_TYPE_UNKNOWN', 'DCM_ACCOUNT', @@ -28,4 +30,5 @@ module.exports = { BASE_URL, EncryptionEntityType, EncryptionSource, + MAX_BATCH_CONVERSATIONS_SIZE, }; diff --git a/src/v0/destinations/campaign_manager/networkHandler.js b/src/v0/destinations/campaign_manager/networkHandler.js index 0683b0c55c..63efff5b50 100644 --- a/src/v0/destinations/campaign_manager/networkHandler.js +++ b/src/v0/destinations/campaign_manager/networkHandler.js @@ -1,3 +1,4 @@ +/* eslint-disable no-restricted-syntax */ const { AbortedError, RetryableError, NetworkError } = require('@rudderstack/integrations-lib'); const { prepareProxyRequest, proxyRequest } = require('../../../adapters/network'); const { isHttpStatusSuccess, getAuthErrCategoryFromStCode } = require('../../util/index'); @@ -9,22 +10,44 @@ const { const tags = require('../../util/tags'); function checkIfFailuresAreRetryable(response) { + const { status } = response; try { - if (Array.isArray(response.status) && Array.isArray(response.status[0].errors)) { - return ( - response.status[0].errors[0].code !== 'PERMISSION_DENIED' && - response.status[0].errors[0].code !== 'INVALID_ARGUMENT' - ); + if (Array.isArray(status)) { + // iterate over each status, and if found retryable in conversations ..retry else discard + /* status : [{ + "conversion": { + object (Conversion) + }, + "errors": [ + { + object (ConversionError) + } + ], + "kind": string + }] */ + for (const st of status) { + for (const err of st.errors) { + // if code is any of these, event is not retryable + if ( + err.code === 'PERMISSION_DENIED' || + err.code === 'INVALID_ARGUMENT' || + err.code === 'NOT_FOUND' + ) { + return false; + } + } + } } return true; } catch (e) { - return true; + return false; } } const responseHandler = (destinationResponse) => { const message = `[CAMPAIGN_MANAGER Response Handler] - Request Processed Successfully`; const { response, status } = destinationResponse; + if (isHttpStatusSuccess(status)) { // check for Failures if (response.hasFailures === true) { diff --git a/src/v0/destinations/campaign_manager/transform.js b/src/v0/destinations/campaign_manager/transform.js index 7b6d6cba4c..3b480dbac2 100644 --- a/src/v0/destinations/campaign_manager/transform.js +++ b/src/v0/destinations/campaign_manager/transform.js @@ -1,13 +1,16 @@ const { InstrumentationError } = require('@rudderstack/integrations-lib'); +const lodash = require('lodash'); const { EventType } = require('../../../constants'); - const { constructPayload, defaultRequestConfig, defaultPostRequestConfig, + defaultBatchRequestConfig, removeUndefinedAndNullValues, + getSuccessRespEvents, isDefinedAndNotNull, - simpleProcessRouterDest, + checkInvalidRtTfEvents, + handleRtTfSingleEventError, getAccessToken, } = require('../../util'); @@ -17,6 +20,7 @@ const { BASE_URL, EncryptionEntityType, EncryptionSource, + MAX_BATCH_CONVERSATIONS_SIZE, } = require('./config'); const { convertToMicroseconds } = require('./util'); @@ -178,9 +182,110 @@ function process(event) { return response; } +const generateBatch = (eventKind, events) => { + const batchRequestObject = defaultBatchRequestConfig(); + const conversions = []; + let encryptionInfo = {}; + const metadata = []; + // extracting destination, message from the first event in a batch + const { destination, message } = events[0]; + // Batch event into dest batch structure + events.forEach((ev) => { + conversions.push(...ev.message.body.JSON.conversions); + metadata.push(ev.metadata); + if (ev.message.body.JSON.encryptionInfo) { + encryptionInfo = ev.message.body.JSON.encryptionInfo; + } + }); + + batchRequestObject.batchedRequest.body.JSON = { + kind: eventKind, + conversions, + }; + + if (Object.keys(encryptionInfo).length > 0) { + batchRequestObject.batchedRequest.body.JSON.encryptionInfo = encryptionInfo; + } + + batchRequestObject.batchedRequest.endpoint = message.endpoint; + + batchRequestObject.batchedRequest.headers = message.headers; + + return { + ...batchRequestObject, + metadata, + destination, + }; +}; + +const batchEvents = (eventChunksArray) => { + const batchedResponseList = []; + + // group batchInsert and batchUpdate payloads + const groupedEventChunks = lodash.groupBy( + eventChunksArray, + (event) => event.message.body.JSON.kind, + ); + Object.keys(groupedEventChunks).forEach((eventKind) => { + // eventChunks = [[e1,e2,e3,..batchSize],[e1,e2,e3,..batchSize]..] + const eventChunks = lodash.chunk(groupedEventChunks[eventKind], MAX_BATCH_CONVERSATIONS_SIZE); + eventChunks.forEach((chunk) => { + const batchEventResponse = generateBatch(eventKind, chunk); + batchedResponseList.push( + getSuccessRespEvents( + batchEventResponse.batchedRequest, + batchEventResponse.metadata, + batchEventResponse.destination, + true, + ), + ); + }); + }); + return batchedResponseList; +}; + const processRouterDest = async (inputs, reqMetadata) => { - const respList = await simpleProcessRouterDest(inputs, process, reqMetadata); - return respList; + const errorRespEvents = checkInvalidRtTfEvents(inputs); + if (errorRespEvents.length > 0) { + return errorRespEvents; + } + + const batchErrorRespList = []; + const eventChunksArray = []; + const { destination } = inputs[0]; + await Promise.all( + inputs.map(async (event) => { + try { + if (event.message.statusCode) { + // already transformed event + eventChunksArray.push({ + message: event.message, + metadata: event.metadata, + destination, + }); + } else { + // if not transformed + const proccessedRespList = process(event); + const transformedPayload = { + message: proccessedRespList, + metadata: event.metadata, + destination, + }; + eventChunksArray.push(transformedPayload); + } + } catch (error) { + const errRespEvent = handleRtTfSingleEventError(event, error, reqMetadata); + batchErrorRespList.push(errRespEvent); + } + }), + ); + + let batchResponseList = []; + if (eventChunksArray.length > 0) { + batchResponseList = batchEvents(eventChunksArray); + } + + return [...batchResponseList, ...batchErrorRespList]; }; module.exports = { process, processRouterDest }; diff --git a/test/__tests__/facebook_conversions.test.js b/test/__tests__/facebook_conversions.test.js index 9495a85913..5bb905b5c8 100644 --- a/test/__tests__/facebook_conversions.test.js +++ b/test/__tests__/facebook_conversions.test.js @@ -38,7 +38,7 @@ describe(`${name} Tests`, () => { }); }); }); - + describe("Router Tests", () => { it("Payload", async () => { const routerOutput = await transformer.processRouterDest(inputRouterData); diff --git a/test/integrations/destinations/campaign_manager/dataDelivery/data.ts b/test/integrations/destinations/campaign_manager/dataDelivery/data.ts index f2a7654e3c..601ad56401 100644 --- a/test/integrations/destinations/campaign_manager/dataDelivery/data.ts +++ b/test/integrations/destinations/campaign_manager/dataDelivery/data.ts @@ -1,7 +1,7 @@ export const data = [ { name: 'campaign_manager', - description: 'Sucess insert request', + description: 'Sucess insert request V0', feature: 'dataDelivery', module: 'destination', version: 'v0', @@ -135,14 +135,14 @@ export const data = [ }, output: { response: { - status: 500, + status: 400, body: { output: { - status: 500, - message: 'Campaign Manager: Retrying during CAMPAIGN_MANAGER response transformation', + status: 400, + message: 'Campaign Manager: Aborting during CAMPAIGN_MANAGER response transformation', statTags: { errorCategory: 'network', - errorType: 'retryable', + errorType: 'aborted', destType: 'CAMPAIGN_MANAGER', module: 'destination', implementation: 'native', diff --git a/test/integrations/destinations/campaign_manager/router/data.ts b/test/integrations/destinations/campaign_manager/router/data.ts index 95372e1925..2ab1813cf8 100644 --- a/test/integrations/destinations/campaign_manager/router/data.ts +++ b/test/integrations/destinations/campaign_manager/router/data.ts @@ -1,7 +1,7 @@ export const data = [ { name: 'campaign_manager', - description: 'Test 0', + description: 'Batch Different Type Requests', feature: 'router', module: 'destination', version: 'v0', @@ -77,7 +77,7 @@ export const data = [ properties: { profileId: 437689, floodlightConfigurationId: '213123123', - ordinal: 'string', + ordinal: '1', quantity: '455678', floodlightActivityId: '456543345245', value: 7, @@ -167,7 +167,7 @@ export const data = [ properties: { profileId: 437689, floodlightConfigurationId: '213123123', - ordinal: 'string', + ordinal: '2', floodlightActivityId: '456543345245', quantity: '455678', value: 7, @@ -256,16 +256,11 @@ export const data = [ properties: { profileId: 437689, floodlightConfigurationId: '213123123', - ordinal: 'string', + ordinal: '3', floodlightActivityId: '456543345245', - mobileDeviceId: 'string', value: 7, encryptedUserIdCandidates: ['dfghjbnm'], - gclid: 'string', - matchId: 'string', - dclid: 'string', quantity: '455678', - impressionId: 'string', limitAdTracking: true, childDirectedTreatment: true, encryptionInfo: { @@ -322,7 +317,7 @@ export const data = [ treatmentForUnderage: false, timestampMicros: '1668624722903000', floodlightConfigurationId: '213123123', - ordinal: 'string', + ordinal: '1', quantity: '455678', floodlightActivityId: '456543345245', value: 7, @@ -348,7 +343,7 @@ export const data = [ jobId: 1, }, ], - batched: false, + batched: true, statusCode: 200, destination: { Config: { @@ -387,7 +382,7 @@ export const data = [ treatmentForUnderage: false, timestampMicros: '1668624722903000', floodlightConfigurationId: '213123123', - ordinal: 'string', + ordinal: '2', quantity: '455678', floodlightActivityId: '456543345245', value: 7, @@ -411,7 +406,7 @@ export const data = [ jobId: 2, }, ], - batched: false, + batched: true, statusCode: 200, destination: { Config: { @@ -461,4 +456,802 @@ export const data = [ }, }, }, + { + name: 'campaign_manager', + description: 'Batch Sucessful BatchInsert Request', + feature: 'router', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + input: [ + { + metadata: { + secret: { + access_token: 'dummyApiToken', + refresh_token: 'efgh5678', + developer_token: 'ijkl91011', + }, + jobId: 4, + }, + destination: { + Config: { + treatmentForUnderage: false, + limitAdTracking: false, + childDirectedTreatment: false, + nonPersonalizedAd: false, + rudderAccountId: '2EOknn1JNH7WK1MfNku4fGYKkRK', + }, + }, + message: { + channel: 'web', + event: 'Promotion Clicked', + originalTimestamp: '2022-11-17T00:22:02.903+05:30', + properties: { + profileId: 437689, + matchId: '123', + floodlightConfigurationId: '213123123', + quantity: '455678', + ordinal: '1', + floodlightActivityId: '456543345245', + value: 7, + limitAdTracking: true, + childDirectedTreatment: true, + requestType: 'batchinsert', + }, + type: 'track', + anonymousId: 'randomId', + integrations: { + All: true, + }, + name: 'ApplicationLoaded', + sentAt: '2022-11-17T00:22:02.903+05:30', + }, + }, + { + metadata: { + secret: { + access_token: 'dummyApiToken', + refresh_token: 'efgh5678', + developer_token: 'ijkl91011', + }, + jobId: 5, + }, + destination: { + Config: { + treatmentForUnderage: false, + limitAdTracking: false, + childDirectedTreatment: false, + nonPersonalizedAd: false, + rudderAccountId: '2EOknn1JNH7WK1MfNku4fGYKkRK', + }, + }, + message: { + channel: 'web', + event: 'Promotion Clicked', + type: 'track', + originalTimestamp: '2022-11-17T00:22:02.903+05:30', + properties: { + profileId: 437689, + floodlightConfigurationId: '213123123', + ordinal: '1', + floodlightActivityId: '456543345245', + quantity: '455678', + value: 7, + matchId: '111', + limitAdTracking: true, + childDirectedTreatment: true, + requestType: 'batchinsert', + }, + anonymousId: 'randomId', + integrations: { + All: true, + }, + name: 'ApplicationLoaded', + sentAt: '2022-11-17T00:22:02.903+05:30', + }, + }, + { + metadata: { + secret: { + access_token: 'dummyApiToken', + refresh_token: 'efgh5678', + developer_token: 'ijkl91011', + }, + jobId: 6, + }, + destination: { + Config: { + treatmentForUnderage: false, + limitAdTracking: false, + childDirectedTreatment: false, + nonPersonalizedAd: false, + rudderAccountId: '2EOknn1JNH7WK1MfNku4fGYKkRK', + }, + }, + message: { + channel: 'web', + event: 'Promotion Clicked', + type: 'track', + originalTimestamp: '2022-11-17T00:22:02.903+05:30', + properties: { + profileId: 437689, + floodlightConfigurationId: '213123123', + floodlightActivityId: '456543345245', + value: 7, + gclid: '123', + ordinal: '1', + quantity: '455678', + limitAdTracking: true, + childDirectedTreatment: true, + requestType: 'batchinsert', + }, + anonymousId: 'randomId', + integrations: { + All: true, + }, + name: 'ApplicationLoaded', + sentAt: '2022-11-17T00:22:02.903+05:30', + }, + }, + ], + destType: 'campaign_manager', + }, + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: [ + { + batchedRequest: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: + 'https://dfareporting.googleapis.com/dfareporting/v4/userprofiles/437689/conversions/batchinsert', + headers: { + Authorization: 'Bearer dummyApiToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + kind: 'dfareporting#conversionsBatchInsertRequest', + conversions: [ + { + floodlightConfigurationId: '213123123', + ordinal: '1', + timestampMicros: '1668624722903000', + floodlightActivityId: '456543345245', + quantity: '455678', + value: 7, + matchId: '123', + limitAdTracking: true, + childDirectedTreatment: true, + nonPersonalizedAd: false, + treatmentForUnderage: false, + }, + { + floodlightConfigurationId: '213123123', + ordinal: '1', + timestampMicros: '1668624722903000', + floodlightActivityId: '456543345245', + quantity: '455678', + value: 7, + matchId: '111', + limitAdTracking: true, + childDirectedTreatment: true, + nonPersonalizedAd: false, + treatmentForUnderage: false, + }, + { + floodlightConfigurationId: '213123123', + ordinal: '1', + timestampMicros: '1668624722903000', + floodlightActivityId: '456543345245', + quantity: '455678', + value: 7, + gclid: '123', + limitAdTracking: true, + childDirectedTreatment: true, + nonPersonalizedAd: false, + treatmentForUnderage: false, + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + }, + metadata: [ + { + secret: { + access_token: 'dummyApiToken', + refresh_token: 'efgh5678', + developer_token: 'ijkl91011', + }, + jobId: 4, + }, + { + secret: { + access_token: 'dummyApiToken', + refresh_token: 'efgh5678', + developer_token: 'ijkl91011', + }, + jobId: 5, + }, + { + secret: { + access_token: 'dummyApiToken', + refresh_token: 'efgh5678', + developer_token: 'ijkl91011', + }, + jobId: 6, + }, + ], + batched: true, + statusCode: 200, + destination: { + Config: { + treatmentForUnderage: false, + limitAdTracking: false, + childDirectedTreatment: false, + nonPersonalizedAd: false, + rudderAccountId: '2EOknn1JNH7WK1MfNku4fGYKkRK', + }, + }, + }, + ], + }, + }, + }, + }, + { + name: 'campaign_manager', + description: 'Batch Sucessful BatchInsert and BatchUpdate Request', + feature: 'router', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + input: [ + { + metadata: { + secret: { + access_token: 'dummyApiToken', + refresh_token: 'efgh5678', + developer_token: 'ijkl91011', + }, + jobId: 4, + }, + destination: { + Config: { + treatmentForUnderage: false, + limitAdTracking: false, + childDirectedTreatment: false, + nonPersonalizedAd: false, + rudderAccountId: '2EOknn1JNH7WK1MfNku4fGYKkRK', + }, + }, + message: { + channel: 'web', + event: 'Promotion Clicked', + originalTimestamp: '2022-11-17T00:22:02.903+05:30', + properties: { + profileId: 437689, + matchId: '123', + floodlightConfigurationId: '213123123', + quantity: '455678', + ordinal: '1', + floodlightActivityId: '456543345245', + value: 7, + limitAdTracking: true, + childDirectedTreatment: true, + requestType: 'batchupdate', + }, + type: 'track', + anonymousId: 'randomId', + integrations: { + All: true, + }, + name: 'ApplicationLoaded', + sentAt: '2022-11-17T00:22:02.903+05:30', + }, + }, + { + metadata: { + secret: { + access_token: 'dummyApiToken', + refresh_token: 'efgh5678', + developer_token: 'ijkl91011', + }, + jobId: 5, + }, + destination: { + Config: { + treatmentForUnderage: false, + limitAdTracking: false, + childDirectedTreatment: false, + nonPersonalizedAd: false, + rudderAccountId: '2EOknn1JNH7WK1MfNku4fGYKkRK', + }, + }, + message: { + channel: 'web', + event: 'Promotion Clicked', + type: 'track', + originalTimestamp: '2022-11-17T00:22:02.903+05:30', + properties: { + profileId: 437689, + floodlightConfigurationId: '213123123', + ordinal: '1', + floodlightActivityId: '456543345245', + quantity: '455678', + value: 7, + matchId: '111', + limitAdTracking: true, + childDirectedTreatment: true, + requestType: 'batchupdate', + }, + anonymousId: 'randomId', + integrations: { + All: true, + }, + name: 'ApplicationLoaded', + sentAt: '2022-11-17T00:22:02.903+05:30', + }, + }, + { + metadata: { + secret: { + access_token: 'dummyApiToken', + refresh_token: 'efgh5678', + developer_token: 'ijkl91011', + }, + jobId: 6, + }, + destination: { + Config: { + treatmentForUnderage: false, + limitAdTracking: false, + childDirectedTreatment: false, + nonPersonalizedAd: false, + rudderAccountId: '2EOknn1JNH7WK1MfNku4fGYKkRK', + }, + }, + message: { + channel: 'web', + event: 'Promotion Clicked', + type: 'track', + originalTimestamp: '2022-11-17T00:22:02.903+05:30', + properties: { + profileId: 437689, + floodlightConfigurationId: '213123123', + floodlightActivityId: '456543345245', + value: 7, + gclid: '123', + ordinal: '1', + quantity: '455678', + limitAdTracking: true, + childDirectedTreatment: true, + requestType: 'batchinsert', + }, + anonymousId: 'randomId', + integrations: { + All: true, + }, + name: 'ApplicationLoaded', + sentAt: '2022-11-17T00:22:02.903+05:30', + }, + }, + ], + destType: 'campaign_manager', + }, + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: [ + { + batchedRequest: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: + 'https://dfareporting.googleapis.com/dfareporting/v4/userprofiles/437689/conversions/batchupdate', + headers: { + Authorization: 'Bearer dummyApiToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + kind: 'dfareporting#conversionsBatchUpdateRequest', + conversions: [ + { + floodlightConfigurationId: '213123123', + ordinal: '1', + timestampMicros: '1668624722903000', + floodlightActivityId: '456543345245', + quantity: '455678', + value: 7, + matchId: '123', + nonPersonalizedAd: false, + treatmentForUnderage: false, + }, + { + floodlightConfigurationId: '213123123', + ordinal: '1', + timestampMicros: '1668624722903000', + floodlightActivityId: '456543345245', + quantity: '455678', + value: 7, + matchId: '111', + nonPersonalizedAd: false, + treatmentForUnderage: false, + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + }, + metadata: [ + { + secret: { + access_token: 'dummyApiToken', + refresh_token: 'efgh5678', + developer_token: 'ijkl91011', + }, + jobId: 4, + }, + { + secret: { + access_token: 'dummyApiToken', + refresh_token: 'efgh5678', + developer_token: 'ijkl91011', + }, + jobId: 5, + }, + ], + batched: true, + statusCode: 200, + destination: { + Config: { + treatmentForUnderage: false, + limitAdTracking: false, + childDirectedTreatment: false, + nonPersonalizedAd: false, + rudderAccountId: '2EOknn1JNH7WK1MfNku4fGYKkRK', + }, + }, + }, + { + batchedRequest: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: + 'https://dfareporting.googleapis.com/dfareporting/v4/userprofiles/437689/conversions/batchinsert', + headers: { + Authorization: 'Bearer dummyApiToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + kind: 'dfareporting#conversionsBatchInsertRequest', + conversions: [ + { + floodlightConfigurationId: '213123123', + ordinal: '1', + timestampMicros: '1668624722903000', + floodlightActivityId: '456543345245', + quantity: '455678', + value: 7, + gclid: '123', + limitAdTracking: true, + childDirectedTreatment: true, + nonPersonalizedAd: false, + treatmentForUnderage: false, + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + }, + metadata: [ + { + secret: { + access_token: 'dummyApiToken', + refresh_token: 'efgh5678', + developer_token: 'ijkl91011', + }, + jobId: 6, + }, + ], + batched: true, + statusCode: 200, + destination: { + Config: { + treatmentForUnderage: false, + limitAdTracking: false, + childDirectedTreatment: false, + nonPersonalizedAd: false, + rudderAccountId: '2EOknn1JNH7WK1MfNku4fGYKkRK', + }, + }, + }, + ], + }, + }, + }, + }, + { + name: 'campaign_manager', + description: 'Entire Batch has data instrumentation', + feature: 'router', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + input: [ + { + metadata: { + secret: { + access_token: 'dummyApiToken', + refresh_token: 'efgh5678', + developer_token: 'ijkl91011', + }, + jobId: 4, + }, + destination: { + Config: { + treatmentForUnderage: false, + limitAdTracking: false, + childDirectedTreatment: false, + nonPersonalizedAd: false, + rudderAccountId: '2EOknn1JNH7WK1MfNku4fGYKkRK', + }, + }, + message: { + channel: 'web', + event: 'Promotion Clicked', + originalTimestamp: '2022-11-17T00:22:02.903+05:30', + properties: { + profileId: 437689, + floodlightConfigurationId: '213123123', + quantity: '455678', + ordinal: '1', + floodlightActivityId: '456543345245', + value: 7, + limitAdTracking: true, + childDirectedTreatment: true, + requestType: 'batchupdate', + }, + type: 'track', + anonymousId: 'randomId', + integrations: { + All: true, + }, + name: 'ApplicationLoaded', + sentAt: '2022-11-17T00:22:02.903+05:30', + }, + }, + { + metadata: { + secret: { + access_token: 'dummyApiToken', + refresh_token: 'efgh5678', + developer_token: 'ijkl91011', + }, + jobId: 5, + }, + destination: { + Config: { + treatmentForUnderage: false, + limitAdTracking: false, + childDirectedTreatment: false, + nonPersonalizedAd: false, + rudderAccountId: '2EOknn1JNH7WK1MfNku4fGYKkRK', + }, + }, + message: { + channel: 'web', + event: 'Promotion Clicked', + type: 'track', + originalTimestamp: '2022-11-17T00:22:02.903+05:30', + properties: { + profileId: 437689, + floodlightConfigurationId: '213123123', + ordinal: '1', + floodlightActivityId: '456543345245', + quantity: '455678', + value: 7, + limitAdTracking: true, + childDirectedTreatment: true, + requestType: 'batchupdate', + }, + anonymousId: 'randomId', + integrations: { + All: true, + }, + name: 'ApplicationLoaded', + sentAt: '2022-11-17T00:22:02.903+05:30', + }, + }, + { + metadata: { + secret: { + access_token: 'dummyApiToken', + refresh_token: 'efgh5678', + developer_token: 'ijkl91011', + }, + jobId: 6, + }, + destination: { + Config: { + treatmentForUnderage: false, + limitAdTracking: false, + childDirectedTreatment: false, + nonPersonalizedAd: false, + rudderAccountId: '2EOknn1JNH7WK1MfNku4fGYKkRK', + }, + }, + message: { + channel: 'web', + event: 'Promotion Clicked', + type: 'track', + originalTimestamp: '2022-11-17T00:22:02.903+05:30', + properties: { + profileId: 437689, + floodlightConfigurationId: '213123123', + floodlightActivityId: '456543345245', + value: 7, + + ordinal: '1', + quantity: '455678', + limitAdTracking: true, + childDirectedTreatment: true, + requestType: 'batchinsert', + }, + anonymousId: 'randomId', + integrations: { + All: true, + }, + name: 'ApplicationLoaded', + sentAt: '2022-11-17T00:22:02.903+05:30', + }, + }, + ], + destType: 'campaign_manager', + }, + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: [ + { + metadata: [ + { + secret: { + access_token: 'dummyApiToken', + refresh_token: 'efgh5678', + developer_token: 'ijkl91011', + }, + jobId: 4, + }, + ], + batched: false, + statusCode: 400, + error: + '[CAMPAIGN MANAGER (DCM)]: Atleast one of encryptedUserId,encryptedUserIdCandidates, matchId, mobileDeviceId, gclid, dclid, impressionId.', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'CAMPAIGN_MANAGER', + module: 'destination', + implementation: 'native', + feature: 'router', + }, + destination: { + Config: { + treatmentForUnderage: false, + limitAdTracking: false, + childDirectedTreatment: false, + nonPersonalizedAd: false, + rudderAccountId: '2EOknn1JNH7WK1MfNku4fGYKkRK', + }, + }, + }, + { + metadata: [ + { + secret: { + access_token: 'dummyApiToken', + refresh_token: 'efgh5678', + developer_token: 'ijkl91011', + }, + jobId: 5, + }, + ], + batched: false, + statusCode: 400, + error: + '[CAMPAIGN MANAGER (DCM)]: Atleast one of encryptedUserId,encryptedUserIdCandidates, matchId, mobileDeviceId, gclid, dclid, impressionId.', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'CAMPAIGN_MANAGER', + module: 'destination', + implementation: 'native', + feature: 'router', + }, + destination: { + Config: { + treatmentForUnderage: false, + limitAdTracking: false, + childDirectedTreatment: false, + nonPersonalizedAd: false, + rudderAccountId: '2EOknn1JNH7WK1MfNku4fGYKkRK', + }, + }, + }, + { + metadata: [ + { + secret: { + access_token: 'dummyApiToken', + refresh_token: 'efgh5678', + developer_token: 'ijkl91011', + }, + jobId: 6, + }, + ], + batched: false, + statusCode: 400, + error: + '[CAMPAIGN MANAGER (DCM)]: Atleast one of encryptedUserId,encryptedUserIdCandidates, matchId, mobileDeviceId, gclid, dclid, impressionId.', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'CAMPAIGN_MANAGER', + module: 'destination', + implementation: 'native', + feature: 'router', + }, + destination: { + Config: { + treatmentForUnderage: false, + limitAdTracking: false, + childDirectedTreatment: false, + nonPersonalizedAd: false, + rudderAccountId: '2EOknn1JNH7WK1MfNku4fGYKkRK', + }, + }, + }, + ], + }, + }, + }, + }, ]; From 1a8d825ccbb87d34d8ae5ff2cb02f4be9700eee6 Mon Sep 17 00:00:00 2001 From: AASHISH MALIK Date: Fri, 1 Dec 2023 10:54:27 +0530 Subject: [PATCH 52/93] fix: updated transformerProxyV1 name (#2859) --- src/features.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/features.json b/src/features.json index 23c01c3731..2d064eeae0 100644 --- a/src/features.json +++ b/src/features.json @@ -65,5 +65,5 @@ "TIKTOK_AUDIENCE": true }, "supportSourceTransformV1": true, - "transformerProxyV1": true + "supportTransformerProxyV1": true } From a015460f0a6d2d5320f633abc151febf22561b6b Mon Sep 17 00:00:00 2001 From: Sankeerth Date: Fri, 1 Dec 2023 12:33:42 +0530 Subject: [PATCH 53/93] fix: error handling in active_campaign (#2843) --- .../destinations/active_campaign/transform.js | 53 +++---------------- src/v0/destinations/active_campaign/util.js | 35 +++++------- 2 files changed, 20 insertions(+), 68 deletions(-) diff --git a/src/v0/destinations/active_campaign/transform.js b/src/v0/destinations/active_campaign/transform.js index e00808622d..973a928472 100644 --- a/src/v0/destinations/active_campaign/transform.js +++ b/src/v0/destinations/active_campaign/transform.js @@ -1,11 +1,7 @@ /* eslint-disable array-callback-return */ /* eslint-disable no-empty */ const get = require('get-value'); -const { - InstrumentationError, - TransformationError, - NetworkError, -} = require('@rudderstack/integrations-lib'); +const { InstrumentationError, TransformationError } = require('@rudderstack/integrations-lib'); const { EventType } = require('../../../constants'); const { CONFIG_CATEGORIES, MAPPING_CONFIG, getHeader } = require('./config'); const { @@ -17,8 +13,6 @@ const { } = require('../../util'); const { errorHandler } = require('./util'); const { httpGET, httpPOST } = require('../../../adapters/network'); -const { getDynamicErrorType } = require('../../../adapters/utils/networkUtils'); -const tags = require('../../util/tags'); const TOTAL_RECORDS_KEY = 'response.data.meta.total'; const EVENT_DATA_KEY = 'properties.eventData'; @@ -72,14 +66,7 @@ const syncContact = async (contactPayload, category, destination) => { } const createdContact = get(res, 'response.data.contact'); // null safe if (!createdContact) { - throw new NetworkError( - 'Unable to Create Contact', - res.response?.status, - { - [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(res.response?.status), - }, - res.response, - ); + errorHandler(res.response, 'Failed to create new contact'); } return createdContact.id; }; @@ -421,14 +408,7 @@ const screenRequestHandler = async (message, category, destination) => { } if (res?.response?.status !== 200) { - throw new NetworkError( - 'Unable to create event', - res.response?.status, - { - [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(res.response?.status), - }, - res.response, - ); + errorHandler(res.response, 'Unable to create event'); } const storedEventsArr = res.response?.data?.eventTrackingEvents; @@ -455,14 +435,7 @@ const screenRequestHandler = async (message, category, destination) => { } if (res.response.status !== 201) { - throw new NetworkError( - 'Unable to create event', - res.response.status, - { - [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(res.response.status), - }, - res?.response, - ); + errorHandler(res.response, 'Unable to create event'); } } // Previous operations successfull then @@ -499,14 +472,7 @@ const trackRequestHandler = async (message, category, destination) => { } if (res.response.status !== 200) { - throw new NetworkError( - 'Unable to fetch events. Aborting', - res.response.status, - { - [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(res.response.status), - }, - res?.response, - ); + errorHandler(res.response, 'Unable to fetch events. Aborting'); } const storedEventsArr = res.response?.data?.eventTrackingEvents; @@ -529,14 +495,7 @@ const trackRequestHandler = async (message, category, destination) => { feature: 'transformation', }); if (res.response?.status !== 201) { - throw new NetworkError( - 'Unable to create event. Aborting', - res.response.status, - { - [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(res.response.status), - }, - res.response, - ); + errorHandler(res.response, 'Unable to create event. Aborting'); } } diff --git a/src/v0/destinations/active_campaign/util.js b/src/v0/destinations/active_campaign/util.js index 6e1f5a3683..457413c3e2 100644 --- a/src/v0/destinations/active_campaign/util.js +++ b/src/v0/destinations/active_campaign/util.js @@ -1,31 +1,24 @@ const { NetworkError } = require('@rudderstack/integrations-lib'); const { - nodeSysErrorToStatus, getDynamicErrorType, + processAxiosResponse, } = require('../../../adapters/utils/networkUtils'); const tags = require('../../util/tags'); -const errorHandler = (err, message) => { - if (err.response) { - throw new NetworkError( - `${message} (${err.response?.statusText},${JSON.stringify(err.response?.data)})`, - err.status, - { - [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(err.status), - }, - err, - ); - } else { - const httpError = nodeSysErrorToStatus(err.code); - throw new NetworkError( - `${message} ${httpError.message}`, - httpError.status, - { - [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(httpError.status), - }, - err, - ); +const errorHandler = (httpCallError, message) => { + const {response, status} = processAxiosResponse(httpCallError); + let msg = message; + if (response) { + msg = `${message} (${httpCallError.response?.statusText},${JSON.stringify(response)})`; } + throw new NetworkError( + msg, + status, + { + [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(status), + }, + response, + ); }; const offsetLimitVarPath = 'response.data.meta.total'; From 284d1411514c26dda2403a4a18967e5f40e255ea Mon Sep 17 00:00:00 2001 From: AASHISH MALIK Date: Fri, 1 Dec 2023 20:14:44 +0530 Subject: [PATCH 54/93] feat: onboard webhook to component tests (#2837) --- .../destinations/webhook/processor/data.ts | 4929 +++++++++-------- .../destinations/webhook/router/data.ts | 22 +- 2 files changed, 2781 insertions(+), 2170 deletions(-) diff --git a/test/integrations/destinations/webhook/processor/data.ts b/test/integrations/destinations/webhook/processor/data.ts index d02fa58227..8f37a26da2 100644 --- a/test/integrations/destinations/webhook/processor/data.ts +++ b/test/integrations/destinations/webhook/processor/data.ts @@ -1,2170 +1,2761 @@ export const data = [ - { - name: 'webhook', - description: 'Test 0', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - context: { - device: { - id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', - manufacturer: 'Xiaomi', - model: 'Redmi 6', - name: 'xiaomi', - }, - network: { carrier: 'Banglalink' }, - os: { name: 'android', version: '8.1.0' }, - traits: { - address: { city: 'Dhaka', country: 'Bangladesh' }, - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - }, - }, - event: 'spin_result', - integrations: { All: true }, - message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', - properties: { - additional_bet_index: 0, - battle_id: 'N/A', - bet_amount: 9, - bet_level: 1, - bet_multiplier: 1, - coin_balance: 9466052, - current_module_name: 'CasinoGameModule', - days_in_game: 0, - extra_param: 'N/A', - fb_profile: '0', - featureGameType: 'N/A', - game_fps: 30, - game_id: 'fireEagleBase', - game_name: 'FireEagleSlots', - gem_balance: 0, - graphicsQuality: 'HD', - idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', - internetReachability: 'ReachableViaLocalAreaNetwork', - isLowEndDevice: 'False', - is_auto_spin: 'False', - is_turbo: 'False', - isf: 'False', - ishighroller: 'False', - jackpot_win_amount: 90, - jackpot_win_type: 'Silver', - level: 6, - lifetime_gem_balance: 0, - no_of_spin: 1, - player_total_battles: 0, - player_total_shields: 0, - start_date: '2019-08-01', - total_payments: 0, - tournament_id: 'T1561970819', - userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - versionSessionCount: 2, - win_amount: 0, - }, - timestamp: '2019-09-01T15:46:51.693229+05:30', - type: 'track', - user_properties: { - coin_balance: 9466052, - current_module_name: 'CasinoGameModule', - fb_profile: '0', - game_fps: 30, - game_name: 'FireEagleSlots', - gem_balance: 0, - graphicsQuality: 'HD', - idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', - internetReachability: 'ReachableViaLocalAreaNetwork', - isLowEndDevice: false, - level: 6, - lifetime_gem_balance: 0, - player_total_battles: 0, - player_total_shields: 0, - start_date: '2019-08-01', - total_payments: 0, - userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - versionSessionCount: 2, - }, - }, - destination: { - Config: { - webhookUrl: 'http://6b0e6a60.ngrok.io', - headers: [ - { from: '', to: '' }, - { from: 'test2', to: 'value2' }, - ], - }, - }, - }, - ], - method: 'POST', - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - body: { - XML: {}, - JSON_ARRAY: {}, - JSON: { - timestamp: '2019-09-01T15:46:51.693229+05:30', - user_properties: { - total_payments: 0, - internetReachability: 'ReachableViaLocalAreaNetwork', - level: 6, - userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - coin_balance: 9466052, - player_total_shields: 0, - isLowEndDevice: false, - game_fps: 30, - idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', - graphicsQuality: 'HD', - current_module_name: 'CasinoGameModule', - player_total_battles: 0, - lifetime_gem_balance: 0, - gem_balance: 0, - fb_profile: '0', - start_date: '2019-08-01', - versionSessionCount: 2, - game_name: 'FireEagleSlots', - }, - integrations: { All: true }, - event: 'spin_result', - message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - context: { - device: { - model: 'Redmi 6', - manufacturer: 'Xiaomi', - id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', - name: 'xiaomi', - }, - traits: { - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - address: { city: 'Dhaka', country: 'Bangladesh' }, - }, - os: { version: '8.1.0', name: 'android' }, - network: { carrier: 'Banglalink' }, - }, - type: 'track', - properties: { - userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - jackpot_win_type: 'Silver', - coin_balance: 9466052, - bet_level: 1, - ishighroller: 'False', - tournament_id: 'T1561970819', - battle_id: 'N/A', - bet_amount: 9, - fb_profile: '0', - player_total_shields: 0, - is_turbo: 'False', - player_total_battles: 0, - bet_multiplier: 1, - start_date: '2019-08-01', - versionSessionCount: 2, - graphicsQuality: 'HD', - is_auto_spin: 'False', - days_in_game: 0, - additional_bet_index: 0, - isLowEndDevice: 'False', - game_fps: 30, - extra_param: 'N/A', - idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', - current_module_name: 'CasinoGameModule', - game_id: 'fireEagleBase', - featureGameType: 'N/A', - gem_balance: 0, - internetReachability: 'ReachableViaLocalAreaNetwork', - total_payments: 0, - level: 6, - win_amount: 0, - no_of_spin: 1, - game_name: 'FireEagleSlots', - jackpot_win_amount: 90, - lifetime_gem_balance: 0, - isf: 'False', - }, - }, - FORM: {}, - }, - files: {}, - endpoint: 'http://6b0e6a60.ngrok.io', - userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - headers: { 'content-type': 'application/json', test2: 'value2' }, - version: '1', - params: {}, - type: 'REST', - method: 'POST', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'webhook', - description: 'Test 1', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - context: { - device: { - id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', - manufacturer: 'Xiaomi', - model: 'Redmi 6', - name: 'xiaomi', - }, - network: { carrier: 'Banglalink' }, - os: { name: 'android', version: '8.1.0' }, - traits: { - address: { city: 'Dhaka', country: 'Bangladesh' }, - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - }, - }, - event: 'spin_result', - integrations: { All: true }, - message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', - properties: { - additional_bet_index: 0, - battle_id: 'N/A', - bet_amount: 9, - bet_level: 1, - bet_multiplier: 1, - coin_balance: 9466052, - current_module_name: 'CasinoGameModule', - days_in_game: 0, - extra_param: 'N/A', - fb_profile: '0', - featureGameType: 'N/A', - game_fps: 30, - game_id: 'fireEagleBase', - game_name: 'FireEagleSlots', - gem_balance: 0, - graphicsQuality: 'HD', - idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', - internetReachability: 'ReachableViaLocalAreaNetwork', - isLowEndDevice: 'False', - is_auto_spin: 'False', - is_turbo: 'False', - isf: 'False', - ishighroller: 'False', - jackpot_win_amount: 90, - jackpot_win_type: 'Silver', - level: 6, - lifetime_gem_balance: 0, - no_of_spin: 1, - player_total_battles: 0, - player_total_shields: 0, - start_date: '2019-08-01', - total_payments: 0, - tournament_id: 'T1561970819', - userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - versionSessionCount: 2, - win_amount: 0, - }, - timestamp: '2019-09-01T15:46:51.693229+05:30', - type: 'track', - user_properties: { - coin_balance: 9466052, - current_module_name: 'CasinoGameModule', - fb_profile: '0', - game_fps: 30, - game_name: 'FireEagleSlots', - gem_balance: 0, - graphicsQuality: 'HD', - idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', - internetReachability: 'ReachableViaLocalAreaNetwork', - isLowEndDevice: false, - level: 6, - lifetime_gem_balance: 0, - player_total_battles: 0, - player_total_shields: 0, - start_date: '2019-08-01', - total_payments: 0, - userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - versionSessionCount: 2, - }, - }, - destination: { Config: { webhookUrl: 'https://6b0e6a60.ngrok.io/n' } }, - }, - ], - method: 'POST', - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - body: { - XML: {}, - JSON_ARRAY: {}, - JSON: { - timestamp: '2019-09-01T15:46:51.693229+05:30', - user_properties: { - total_payments: 0, - internetReachability: 'ReachableViaLocalAreaNetwork', - level: 6, - userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - coin_balance: 9466052, - player_total_shields: 0, - isLowEndDevice: false, - game_fps: 30, - idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', - graphicsQuality: 'HD', - current_module_name: 'CasinoGameModule', - player_total_battles: 0, - lifetime_gem_balance: 0, - gem_balance: 0, - fb_profile: '0', - start_date: '2019-08-01', - versionSessionCount: 2, - game_name: 'FireEagleSlots', - }, - integrations: { All: true }, - event: 'spin_result', - message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - context: { - device: { - model: 'Redmi 6', - manufacturer: 'Xiaomi', - id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', - name: 'xiaomi', - }, - traits: { - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - address: { city: 'Dhaka', country: 'Bangladesh' }, - }, - os: { version: '8.1.0', name: 'android' }, - network: { carrier: 'Banglalink' }, - }, - type: 'track', - properties: { - userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - jackpot_win_type: 'Silver', - coin_balance: 9466052, - bet_level: 1, - ishighroller: 'False', - tournament_id: 'T1561970819', - battle_id: 'N/A', - bet_amount: 9, - fb_profile: '0', - player_total_shields: 0, - is_turbo: 'False', - player_total_battles: 0, - bet_multiplier: 1, - start_date: '2019-08-01', - versionSessionCount: 2, - graphicsQuality: 'HD', - is_auto_spin: 'False', - days_in_game: 0, - additional_bet_index: 0, - isLowEndDevice: 'False', - game_fps: 30, - extra_param: 'N/A', - idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', - current_module_name: 'CasinoGameModule', - game_id: 'fireEagleBase', - featureGameType: 'N/A', - gem_balance: 0, - internetReachability: 'ReachableViaLocalAreaNetwork', - total_payments: 0, - level: 6, - win_amount: 0, - no_of_spin: 1, - game_name: 'FireEagleSlots', - jackpot_win_amount: 90, - lifetime_gem_balance: 0, - isf: 'False', - }, - }, - FORM: {}, - }, - files: {}, - endpoint: 'https://6b0e6a60.ngrok.io/n', - userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - headers: { 'content-type': 'application/json' }, - version: '1', - params: {}, - type: 'REST', - method: 'POST', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'webhook', - description: 'Test 2', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - context: { - device: { - id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', - manufacturer: 'Xiaomi', - model: 'Redmi 6', - name: 'xiaomi', - }, - network: { carrier: 'Banglalink' }, - os: { name: 'android', version: '8.1.0' }, - traits: { - address: { city: 'Dhaka', country: 'Bangladesh' }, - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - }, - }, - event: 'spin_result', - integrations: { All: true }, - message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', - properties: { - additional_bet_index: 0, - battle_id: 'N/A', - bet_amount: 9, - bet_level: 1, - bet_multiplier: 1, - coin_balance: 9466052, - current_module_name: 'CasinoGameModule', - days_in_game: 0, - extra_param: 'N/A', - fb_profile: '0', - featureGameType: 'N/A', - game_fps: 30, - game_id: 'fireEagleBase', - game_name: 'FireEagleSlots', - gem_balance: 0, - graphicsQuality: 'HD', - idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', - internetReachability: 'ReachableViaLocalAreaNetwork', - isLowEndDevice: 'False', - is_auto_spin: 'False', - is_turbo: 'False', - isf: 'False', - ishighroller: 'False', - jackpot_win_amount: 90, - jackpot_win_type: 'Silver', - level: 6, - lifetime_gem_balance: 0, - no_of_spin: 1, - player_total_battles: 0, - player_total_shields: 0, - start_date: '2019-08-01', - total_payments: 0, - tournament_id: 'T1561970819', - userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - versionSessionCount: 2, - win_amount: 0, - }, - timestamp: '2019-09-01T15:46:51.693229+05:30', - type: 'track', - user_properties: { - coin_balance: 9466052, - current_module_name: 'CasinoGameModule', - fb_profile: '0', - game_fps: 30, - game_name: 'FireEagleSlots', - gem_balance: 0, - graphicsQuality: 'HD', - idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', - internetReachability: 'ReachableViaLocalAreaNetwork', - isLowEndDevice: false, - level: 6, - lifetime_gem_balance: 0, - player_total_battles: 0, - player_total_shields: 0, - start_date: '2019-08-01', - total_payments: 0, - userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - versionSessionCount: 2, - }, - }, - destination: { Config: { webhookUrl: 'https://6b0e6a60.' } }, - }, - ], - method: 'POST', - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - body: { - XML: {}, - JSON_ARRAY: {}, - JSON: { - timestamp: '2019-09-01T15:46:51.693229+05:30', - user_properties: { - total_payments: 0, - internetReachability: 'ReachableViaLocalAreaNetwork', - level: 6, - userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - coin_balance: 9466052, - player_total_shields: 0, - isLowEndDevice: false, - game_fps: 30, - idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', - graphicsQuality: 'HD', - current_module_name: 'CasinoGameModule', - player_total_battles: 0, - lifetime_gem_balance: 0, - gem_balance: 0, - fb_profile: '0', - start_date: '2019-08-01', - versionSessionCount: 2, - game_name: 'FireEagleSlots', - }, - integrations: { All: true }, - event: 'spin_result', - message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - context: { - device: { - model: 'Redmi 6', - manufacturer: 'Xiaomi', - id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', - name: 'xiaomi', - }, - traits: { - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - address: { city: 'Dhaka', country: 'Bangladesh' }, - }, - os: { version: '8.1.0', name: 'android' }, - network: { carrier: 'Banglalink' }, - }, - type: 'track', - properties: { - userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - jackpot_win_type: 'Silver', - coin_balance: 9466052, - bet_level: 1, - ishighroller: 'False', - tournament_id: 'T1561970819', - battle_id: 'N/A', - bet_amount: 9, - fb_profile: '0', - player_total_shields: 0, - is_turbo: 'False', - player_total_battles: 0, - bet_multiplier: 1, - start_date: '2019-08-01', - versionSessionCount: 2, - graphicsQuality: 'HD', - is_auto_spin: 'False', - days_in_game: 0, - additional_bet_index: 0, - isLowEndDevice: 'False', - game_fps: 30, - extra_param: 'N/A', - idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', - current_module_name: 'CasinoGameModule', - game_id: 'fireEagleBase', - featureGameType: 'N/A', - gem_balance: 0, - internetReachability: 'ReachableViaLocalAreaNetwork', - total_payments: 0, - level: 6, - win_amount: 0, - no_of_spin: 1, - game_name: 'FireEagleSlots', - jackpot_win_amount: 90, - lifetime_gem_balance: 0, - isf: 'False', - }, - }, - FORM: {}, - }, - files: {}, - endpoint: 'https://6b0e6a60.', - userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - headers: { 'content-type': 'application/json' }, - version: '1', - params: {}, - type: 'REST', - method: 'POST', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'webhook', - description: 'Test 3', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - context: { - device: { - id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', - manufacturer: 'Xiaomi', - model: 'Redmi 6', - name: 'xiaomi', - }, - network: { carrier: 'Banglalink' }, - os: { name: 'android', version: '8.1.0' }, - traits: { - address: { city: 'Dhaka', country: 'Bangladesh' }, - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - }, - }, - event: 'spin_result', - integrations: { All: true }, - message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', - properties: { k1: 'v1', k2: { k3: 'c3', k4: { k5: 'c5' } } }, - timestamp: '2019-09-01T15:46:51.693229+05:30', - type: 'track', - }, - destination: { - Config: { - webhookUrl: 'https://6b0e6a60.', - webhookMethod: 'GET', - headers: [{ from: 'X-customHeader', to: 'customHeaderVal' }], - }, - }, - }, - ], - method: 'POST', - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'GET', - endpoint: 'https://6b0e6a60.', - headers: { 'x-customheader': 'customHeaderVal' }, - params: { k1: 'v1', 'k2.k3': 'c3', 'k2.k4.k5': 'c5' }, - body: { JSON: {}, XML: {}, JSON_ARRAY: {}, FORM: {} }, - files: {}, - userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'webhook', - description: 'Test 4', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - context: { - device: { - id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', - manufacturer: 'Xiaomi', - model: 'Redmi 6', - name: 'xiaomi', - }, - network: { carrier: 'Banglalink' }, - os: { name: 'android', version: '8.1.0' }, - traits: { - address: { city: 'Dhaka', country: 'Bangladesh' }, - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - }, - }, - event: 'spin_result', - integrations: { All: true }, - message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', - properties: { k1: 'v1', k2: { k3: 'c3', k4: { k5: 'c5' } } }, - timestamp: '2019-09-01T15:46:51.693229+05:30', - type: 'track', - }, - destination: { Config: { webhookUrl: 'https://6b0e6a60.', webhookMethod: 'GET' } }, - }, - ], - method: 'POST', - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'GET', - endpoint: 'https://6b0e6a60.', - headers: {}, - params: { k1: 'v1', 'k2.k3': 'c3', 'k2.k4.k5': 'c5' }, - body: { JSON: {}, XML: {}, JSON_ARRAY: {}, FORM: {} }, - files: {}, - userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'webhook', - description: 'Test 5', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - context: { - device: { - id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', - manufacturer: 'Xiaomi', - model: 'Redmi 6', - name: 'xiaomi', - }, - network: { carrier: 'Banglalink' }, - os: { name: 'android', version: '8.1.0' }, - traits: { - address: { city: 'Dhaka', country: 'Bangladesh' }, - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - }, - }, - event: 'spin_result', - integrations: { All: true }, - message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', - properties: { - additional_bet_index: 0, - battle_id: 'N/A', - bet_amount: 9, - bet_level: 1, - bet_multiplier: 1, - coin_balance: 9466052, - current_module_name: 'CasinoGameModule', - days_in_game: 0, - extra_param: 'N/A', - fb_profile: '0', - featureGameType: 'N/A', - game_fps: 30, - game_id: 'fireEagleBase', - game_name: 'FireEagleSlots', - gem_balance: 0, - graphicsQuality: 'HD', - idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', - internetReachability: 'ReachableViaLocalAreaNetwork', - isLowEndDevice: 'False', - is_auto_spin: 'False', - is_turbo: 'False', - isf: 'False', - ishighroller: 'False', - jackpot_win_amount: 90, - jackpot_win_type: 'Silver', - level: 6, - lifetime_gem_balance: 0, - no_of_spin: 1, - player_total_battles: 0, - player_total_shields: 0, - start_date: '2019-08-01', - total_payments: 0, - tournament_id: 'T1561970819', - userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - versionSessionCount: 2, - win_amount: 0, - }, - timestamp: '2019-09-01T15:46:51.693229+05:30', - type: 'track', - request_ip: '127.0.0.1', - }, - destination: { - Config: { - webhookUrl: 'http://6b0e6a60.ngrok.io', - header: [ - { from: 'test1', to: 'value1' }, - { from: 'test2', to: 'value2' }, - ], - }, - }, - }, - ], - method: 'POST', - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'http://6b0e6a60.ngrok.io', - headers: { 'content-type': 'application/json' }, - params: {}, - body: { - JSON: { - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - context: { - device: { - id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', - manufacturer: 'Xiaomi', - model: 'Redmi 6', - name: 'xiaomi', - }, - network: { carrier: 'Banglalink' }, - os: { name: 'android', version: '8.1.0' }, - traits: { - address: { city: 'Dhaka', country: 'Bangladesh' }, - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - }, - ip: '127.0.0.1', - }, - event: 'spin_result', - integrations: { All: true }, - message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', - properties: { - additional_bet_index: 0, - battle_id: 'N/A', - bet_amount: 9, - bet_level: 1, - bet_multiplier: 1, - coin_balance: 9466052, - current_module_name: 'CasinoGameModule', - days_in_game: 0, - extra_param: 'N/A', - fb_profile: '0', - featureGameType: 'N/A', - game_fps: 30, - game_id: 'fireEagleBase', - game_name: 'FireEagleSlots', - gem_balance: 0, - graphicsQuality: 'HD', - idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', - internetReachability: 'ReachableViaLocalAreaNetwork', - isLowEndDevice: 'False', - is_auto_spin: 'False', - is_turbo: 'False', - isf: 'False', - ishighroller: 'False', - jackpot_win_amount: 90, - jackpot_win_type: 'Silver', - level: 6, - lifetime_gem_balance: 0, - no_of_spin: 1, - player_total_battles: 0, - player_total_shields: 0, - start_date: '2019-08-01', - total_payments: 0, - tournament_id: 'T1561970819', - userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - versionSessionCount: 2, - win_amount: 0, - }, - timestamp: '2019-09-01T15:46:51.693229+05:30', - type: 'track', - request_ip: '127.0.0.1', - }, - XML: {}, - JSON_ARRAY: {}, - FORM: {}, - }, - files: {}, - userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'webhook', - description: 'Test 6', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - context: { - device: { - id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', - manufacturer: 'Xiaomi', - model: 'Redmi 6', - name: 'xiaomi', - }, - network: { carrier: 'Banglalink' }, - os: { name: 'android', version: '8.1.0' }, - traits: { - address: { city: 'Dhaka', country: 'Bangladesh' }, - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - }, - }, - event: 'spin_result', - integrations: { All: true }, - message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', - properties: { - additional_bet_index: 0, - battle_id: 'N/A', - bet_amount: 9, - bet_level: 1, - bet_multiplier: 1, - coin_balance: 9466052, - current_module_name: 'CasinoGameModule', - days_in_game: 0, - extra_param: 'N/A', - fb_profile: '0', - featureGameType: 'N/A', - game_fps: 30, - game_id: 'fireEagleBase', - game_name: 'FireEagleSlots', - gem_balance: 0, - graphicsQuality: 'HD', - idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', - internetReachability: 'ReachableViaLocalAreaNetwork', - isLowEndDevice: 'False', - is_auto_spin: 'False', - is_turbo: 'False', - isf: 'False', - ishighroller: 'False', - jackpot_win_amount: 90, - jackpot_win_type: 'Silver', - level: 6, - lifetime_gem_balance: 0, - no_of_spin: 1, - player_total_battles: 0, - player_total_shields: 0, - start_date: '2019-08-01', - total_payments: 0, - tournament_id: 'T1561970819', - userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - versionSessionCount: 2, - win_amount: 0, - }, - timestamp: '2019-09-01T15:46:51.693229+05:30', - type: 'track', - request_ip: '127.0.0.1', - }, - destination: { - Config: { - webhookUrl: 'http://6b0e6a60.ngrok.io', - headers: [ - { from: 'Content-Type', to: 'application/xml' }, - { from: 'test2', to: 'value2' }, - ], - }, - }, - }, - ], - method: 'POST', - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'http://6b0e6a60.ngrok.io', - headers: { 'content-type': 'application/xml', test2: 'value2' }, - params: {}, - body: { - JSON: { - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - context: { - device: { - id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', - manufacturer: 'Xiaomi', - model: 'Redmi 6', - name: 'xiaomi', - }, - network: { carrier: 'Banglalink' }, - os: { name: 'android', version: '8.1.0' }, - traits: { - address: { city: 'Dhaka', country: 'Bangladesh' }, - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - }, - ip: '127.0.0.1', - }, - event: 'spin_result', - integrations: { All: true }, - message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', - properties: { - additional_bet_index: 0, - battle_id: 'N/A', - bet_amount: 9, - bet_level: 1, - bet_multiplier: 1, - coin_balance: 9466052, - current_module_name: 'CasinoGameModule', - days_in_game: 0, - extra_param: 'N/A', - fb_profile: '0', - featureGameType: 'N/A', - game_fps: 30, - game_id: 'fireEagleBase', - game_name: 'FireEagleSlots', - gem_balance: 0, - graphicsQuality: 'HD', - idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', - internetReachability: 'ReachableViaLocalAreaNetwork', - isLowEndDevice: 'False', - is_auto_spin: 'False', - is_turbo: 'False', - isf: 'False', - ishighroller: 'False', - jackpot_win_amount: 90, - jackpot_win_type: 'Silver', - level: 6, - lifetime_gem_balance: 0, - no_of_spin: 1, - player_total_battles: 0, - player_total_shields: 0, - start_date: '2019-08-01', - total_payments: 0, - tournament_id: 'T1561970819', - userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - versionSessionCount: 2, - win_amount: 0, - }, - timestamp: '2019-09-01T15:46:51.693229+05:30', - type: 'track', - request_ip: '127.0.0.1', - }, - XML: {}, - JSON_ARRAY: {}, - FORM: {}, - }, - files: {}, - userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'webhook', - description: 'Test 7', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - event: 'spin_result', - integrations: { All: true }, - message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', - properties: { - additional_bet_index: 0, - battle_id: 'N/A', - bet_amount: 9, - bet_level: 1, - bet_multiplier: 1, - coin_balance: 9466052, - current_module_name: 'CasinoGameModule', - days_in_game: 0, - extra_param: 'N/A', - fb_profile: '0', - featureGameType: 'N/A', - game_fps: 30, - game_id: 'fireEagleBase', - game_name: 'FireEagleSlots', - gem_balance: 0, - graphicsQuality: 'HD', - idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', - internetReachability: 'ReachableViaLocalAreaNetwork', - isLowEndDevice: 'False', - is_auto_spin: 'False', - is_turbo: 'False', - isf: 'False', - ishighroller: 'False', - jackpot_win_amount: 90, - jackpot_win_type: 'Silver', - level: 6, - lifetime_gem_balance: 0, - no_of_spin: 1, - player_total_battles: 0, - player_total_shields: 0, - start_date: '2019-08-01', - total_payments: 0, - tournament_id: 'T1561970819', - userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - versionSessionCount: 2, - win_amount: 0, - }, - timestamp: '2019-09-01T15:46:51.693229+05:30', - type: 'track', - }, - destination: { - Config: { - webhookUrl: 'http://6b0e6a60.ngrok.io', - headers: [ - { from: 'Content-Type', to: 'application/xml' }, - { from: 'test2', to: 'value2' }, - ], - }, - }, - }, - ], - method: 'POST', - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'http://6b0e6a60.ngrok.io', - headers: { 'content-type': 'application/xml', test2: 'value2' }, - params: {}, - body: { - JSON: { - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - event: 'spin_result', - integrations: { All: true }, - message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', - properties: { - additional_bet_index: 0, - battle_id: 'N/A', - bet_amount: 9, - bet_level: 1, - bet_multiplier: 1, - coin_balance: 9466052, - current_module_name: 'CasinoGameModule', - days_in_game: 0, - extra_param: 'N/A', - fb_profile: '0', - featureGameType: 'N/A', - game_fps: 30, - game_id: 'fireEagleBase', - game_name: 'FireEagleSlots', - gem_balance: 0, - graphicsQuality: 'HD', - idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', - internetReachability: 'ReachableViaLocalAreaNetwork', - isLowEndDevice: 'False', - is_auto_spin: 'False', - is_turbo: 'False', - isf: 'False', - ishighroller: 'False', - jackpot_win_amount: 90, - jackpot_win_type: 'Silver', - level: 6, - lifetime_gem_balance: 0, - no_of_spin: 1, - player_total_battles: 0, - player_total_shields: 0, - start_date: '2019-08-01', - total_payments: 0, - tournament_id: 'T1561970819', - userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - versionSessionCount: 2, - win_amount: 0, - }, - timestamp: '2019-09-01T15:46:51.693229+05:30', - type: 'track', - }, - XML: {}, - JSON_ARRAY: {}, - FORM: {}, - }, - files: {}, - userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'webhook', - description: 'Test 8', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - context: { - device: { - id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', - manufacturer: 'Xiaomi', - model: 'Redmi 6', - name: 'xiaomi', - }, - network: { carrier: 'Banglalink' }, - os: { name: 'android', version: '8.1.0' }, - traits: { - address: { city: 'Dhaka', country: 'Bangladesh' }, - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - }, - }, - event: 'spin_result', - integrations: { All: true }, - message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', - properties: { - additional_bet_index: 0, - battle_id: 'N/A', - featureGameType: 'N/A', - win_amount: 0, - }, - timestamp: '2019-09-01T15:46:51.693229+05:30', - type: 'track', - header: { - dynamic_header_key_string: 'dynamic_header_value_string', - dynamic_header_key_num: 10, - dynamic_header_key_object: { k1: 'v1' }, - }, - appendPath: '/product/search?string=value', - }, - destination: { - Config: { - webhookUrl: 'http://6b0e6a60.ngrok.io', - headers: [ - { from: '', to: '' }, - { from: 'test2', to: 'value2' }, - ], - }, - }, - }, - ], - method: 'POST', - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - body: { - XML: {}, - JSON_ARRAY: {}, - JSON: { - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - context: { - device: { - id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', - manufacturer: 'Xiaomi', - model: 'Redmi 6', - name: 'xiaomi', - }, - network: { carrier: 'Banglalink' }, - os: { name: 'android', version: '8.1.0' }, - traits: { - address: { city: 'Dhaka', country: 'Bangladesh' }, - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - }, - }, - event: 'spin_result', - integrations: { All: true }, - message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', - properties: { - additional_bet_index: 0, - battle_id: 'N/A', - featureGameType: 'N/A', - win_amount: 0, - }, - timestamp: '2019-09-01T15:46:51.693229+05:30', - type: 'track', - }, - FORM: {}, - }, - files: {}, - endpoint: 'http://6b0e6a60.ngrok.io/product/search?string=value', - userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - headers: { - 'content-type': 'application/json', - test2: 'value2', - dynamic_header_key_string: 'dynamic_header_value_string', - }, - version: '1', - params: {}, - type: 'REST', - method: 'POST', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'webhook', - description: 'Test 9', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - context: { - device: { - id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', - manufacturer: 'Xiaomi', - model: 'Redmi 6', - name: 'xiaomi', - }, - network: { carrier: 'Banglalink' }, - os: { name: 'android', version: '8.1.0' }, - traits: { - address: { city: 'Dhaka', country: 'Bangladesh' }, - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - }, - }, - event: 'spin_result', - integrations: { All: true }, - message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', - properties: { - additional_bet_index: 0, - battle_id: 'N/A', - featureGameType: 'N/A', - win_amount: 0, - }, - timestamp: '2019-09-01T15:46:51.693229+05:30', - type: 'track', - fullPath: 'https://www.google.com', - }, - destination: { - Config: { - webhookUrl: 'http://6b0e6a60.ngrok.io', - headers: [ - { from: '', to: '' }, - { from: 'test2', to: 'value2' }, - ], - }, - }, - }, - ], - method: 'POST', - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - body: { - XML: {}, - JSON_ARRAY: {}, - JSON: { - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - context: { - device: { - id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', - manufacturer: 'Xiaomi', - model: 'Redmi 6', - name: 'xiaomi', - }, - network: { carrier: 'Banglalink' }, - os: { name: 'android', version: '8.1.0' }, - traits: { - address: { city: 'Dhaka', country: 'Bangladesh' }, - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - }, - }, - event: 'spin_result', - integrations: { All: true }, - message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', - properties: { - additional_bet_index: 0, - battle_id: 'N/A', - featureGameType: 'N/A', - win_amount: 0, - }, - timestamp: '2019-09-01T15:46:51.693229+05:30', - type: 'track', - }, - FORM: {}, - }, - files: {}, - endpoint: 'https://www.google.com', - userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - headers: { 'content-type': 'application/json', test2: 'value2' }, - version: '1', - params: {}, - type: 'REST', - method: 'POST', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'webhook', - description: 'Test 10', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - context: { - device: { - id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', - manufacturer: 'Xiaomi', - model: 'Redmi 6', - name: 'xiaomi', - }, - network: { carrier: 'Banglalink' }, - os: { name: 'android', version: '8.1.0' }, - traits: { - address: { city: 'Dhaka', country: 'Bangladesh' }, - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - }, - }, - event: 'spin_result', - integrations: { All: true }, - message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', - properties: { - additional_bet_index: 0, - battle_id: 'N/A', - featureGameType: 'N/A', - win_amount: 0, - }, - timestamp: '2019-09-01T15:46:51.693229+05:30', - type: 'track', - fullPath: 'https://www.google.com/', - appendPath: '?searchTerms=cats', - }, - destination: { - Config: { - webhookUrl: 'http://6b0e6a60.ngrok.io', - headers: [ - { from: '', to: '' }, - { from: 'test2', to: 'value2' }, - ], - }, - }, - }, - ], - method: 'POST', - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - body: { - XML: {}, - JSON_ARRAY: {}, - JSON: { - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - context: { - device: { - id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', - manufacturer: 'Xiaomi', - model: 'Redmi 6', - name: 'xiaomi', - }, - network: { carrier: 'Banglalink' }, - os: { name: 'android', version: '8.1.0' }, - traits: { - address: { city: 'Dhaka', country: 'Bangladesh' }, - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - }, - }, - event: 'spin_result', - integrations: { All: true }, - message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', - properties: { - additional_bet_index: 0, - battle_id: 'N/A', - featureGameType: 'N/A', - win_amount: 0, - }, - timestamp: '2019-09-01T15:46:51.693229+05:30', - type: 'track', - }, - FORM: {}, - }, - files: {}, - endpoint: 'https://www.google.com/?searchTerms=cats', - userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - headers: { 'content-type': 'application/json', test2: 'value2' }, - version: '1', - params: {}, - type: 'REST', - method: 'POST', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'webhook', - description: 'Test 11', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - context: { - device: { - id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', - manufacturer: 'Xiaomi', - model: 'Redmi 6', - name: 'xiaomi', - }, - network: { carrier: 'Banglalink' }, - os: { name: 'android', version: '8.1.0' }, - traits: { - address: { city: 'Dhaka', country: 'Bangladesh' }, - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - }, - }, - event: 'spin_result', - integrations: { All: true }, - message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', - properties: { - additional_bet_index: 0, - battle_id: 'N/A', - featureGameType: 'N/A', - win_amount: 0, - }, - timestamp: '2019-09-01T15:46:51.693229+05:30', - type: 'track', - fullPath: 'https://www.google.com/', - appendPath: '?searchTerms=cats', - }, - destination: { - Config: { - webhookUrl: 'http://6b0e6a60.ngrok.io', - webhookMethod: 'PUT', - headers: [ - { from: '', to: '' }, - { from: 'test2', to: 'value2' }, - ], - }, - }, - }, - ], - method: 'POST', - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - body: { - XML: {}, - JSON_ARRAY: {}, - JSON: { - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - context: { - device: { - id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', - manufacturer: 'Xiaomi', - model: 'Redmi 6', - name: 'xiaomi', - }, - network: { carrier: 'Banglalink' }, - os: { name: 'android', version: '8.1.0' }, - traits: { - address: { city: 'Dhaka', country: 'Bangladesh' }, - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - }, - }, - event: 'spin_result', - integrations: { All: true }, - message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', - properties: { - additional_bet_index: 0, - battle_id: 'N/A', - featureGameType: 'N/A', - win_amount: 0, - }, - timestamp: '2019-09-01T15:46:51.693229+05:30', - type: 'track', - }, - FORM: {}, - }, - files: {}, - endpoint: 'https://www.google.com/?searchTerms=cats', - userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - headers: { 'content-type': 'application/json', test2: 'value2' }, - version: '1', - params: {}, - type: 'REST', - method: 'PUT', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'webhook', - description: 'Test 12', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - context: { - device: { - id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', - manufacturer: 'Xiaomi', - model: 'Redmi 6', - name: 'xiaomi', - }, - network: { carrier: 'Banglalink' }, - os: { name: 'android', version: '8.1.0' }, - traits: { - address: { city: 'Dhaka', country: 'Bangladesh' }, - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - }, - }, - event: 'spin_result', - integrations: { All: true }, - message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', - properties: { - additional_bet_index: 0, - battle_id: 'N/A', - featureGameType: 'N/A', - win_amount: 0, - }, - timestamp: '2019-09-01T15:46:51.693229+05:30', - type: 'track', - fullPath: 'https://www.google.com/', - appendPath: '?searchTerms=cats', - }, - destination: { - Config: { - webhookUrl: 'http://6b0e6a60.ngrok.io', - webhookMethod: 'DELETE', - headers: [ - { from: '', to: '' }, - { from: 'test2', to: 'value2' }, - ], - }, - }, - }, - ], - method: 'POST', - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - body: { XML: {}, JSON_ARRAY: {}, JSON: {}, FORM: {} }, - files: {}, - endpoint: 'https://www.google.com/?searchTerms=cats', - userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - headers: { test2: 'value2' }, - version: '1', - params: { - additional_bet_index: 0, - battle_id: 'N/A', - featureGameType: 'N/A', - win_amount: 0, - }, - type: 'REST', - method: 'DELETE', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'webhook', - description: 'Test 13', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - context: { - device: { - id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', - manufacturer: 'Xiaomi', - model: 'Redmi 6', - name: 'xiaomi', - }, - network: { carrier: 'Banglalink' }, - os: { name: 'android', version: '8.1.0' }, - traits: { - address: { city: 'Dhaka', country: 'Bangladesh' }, - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - }, - }, - event: 'spin_result', - integrations: { All: true }, - message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', - properties: { - additional_bet_index: 0, - battle_id: 'N/A', - bet_amount: 9, - bet_level: 1, - bet_multiplier: 1, - coin_balance: 9466052, - current_module_name: 'CasinoGameModule', - days_in_game: 0, - extra_param: 'N/A', - fb_profile: '0', - featureGameType: 'N/A', - game_fps: 30, - game_id: 'fireEagleBase', - game_name: 'FireEagleSlots', - gem_balance: 0, - graphicsQuality: 'HD', - idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', - internetReachability: 'ReachableViaLocalAreaNetwork', - isLowEndDevice: 'False', - is_auto_spin: 'False', - is_turbo: 'False', - isf: 'False', - ishighroller: 'False', - jackpot_win_amount: 90, - jackpot_win_type: 'Silver', - level: 6, - lifetime_gem_balance: 0, - no_of_spin: 1, - player_total_battles: 0, - player_total_shields: 0, - start_date: '2019-08-01', - total_payments: 0, - tournament_id: 'T1561970819', - userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - versionSessionCount: 2, - win_amount: 0, - }, - timestamp: '2019-09-01T15:46:51.693229+05:30', - type: 'track', - user_properties: { - coin_balance: 9466052, - current_module_name: 'CasinoGameModule', - fb_profile: '0', - game_fps: 30, - game_name: 'FireEagleSlots', - gem_balance: 0, - graphicsQuality: 'HD', - idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', - internetReachability: 'ReachableViaLocalAreaNetwork', - isLowEndDevice: false, - level: 6, - lifetime_gem_balance: 0, - player_total_battles: 0, - player_total_shields: 0, - start_date: '2019-08-01', - total_payments: 0, - userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - versionSessionCount: 2, - }, - }, - destination: { - Config: { - webhookUrl: 'http://6b0e6a60.ngrok.io', - webhookMethod: 'POST', - headers: [{ from: 'test2', to: 'value2' }], - }, - }, - }, - ], - method: 'POST', - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - body: { - FORM: {}, - JSON: { - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - context: { - device: { - id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', - manufacturer: 'Xiaomi', - model: 'Redmi 6', - name: 'xiaomi', - }, - network: { carrier: 'Banglalink' }, - os: { name: 'android', version: '8.1.0' }, - traits: { - address: { city: 'Dhaka', country: 'Bangladesh' }, - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - }, - }, - event: 'spin_result', - integrations: { All: true }, - message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', - properties: { - additional_bet_index: 0, - battle_id: 'N/A', - bet_amount: 9, - bet_level: 1, - bet_multiplier: 1, - coin_balance: 9466052, - current_module_name: 'CasinoGameModule', - days_in_game: 0, - extra_param: 'N/A', - fb_profile: '0', - featureGameType: 'N/A', - game_fps: 30, - game_id: 'fireEagleBase', - game_name: 'FireEagleSlots', - gem_balance: 0, - graphicsQuality: 'HD', - idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', - internetReachability: 'ReachableViaLocalAreaNetwork', - isLowEndDevice: 'False', - is_auto_spin: 'False', - is_turbo: 'False', - isf: 'False', - ishighroller: 'False', - jackpot_win_amount: 90, - jackpot_win_type: 'Silver', - level: 6, - lifetime_gem_balance: 0, - no_of_spin: 1, - player_total_battles: 0, - player_total_shields: 0, - start_date: '2019-08-01', - total_payments: 0, - tournament_id: 'T1561970819', - userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - versionSessionCount: 2, - win_amount: 0, - }, - timestamp: '2019-09-01T15:46:51.693229+05:30', - type: 'track', - user_properties: { - coin_balance: 9466052, - current_module_name: 'CasinoGameModule', - fb_profile: '0', - game_fps: 30, - game_name: 'FireEagleSlots', - gem_balance: 0, - graphicsQuality: 'HD', - idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', - internetReachability: 'ReachableViaLocalAreaNetwork', - isLowEndDevice: false, - level: 6, - lifetime_gem_balance: 0, - player_total_battles: 0, - player_total_shields: 0, - start_date: '2019-08-01', - total_payments: 0, - userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - versionSessionCount: 2, - }, - }, - JSON_ARRAY: {}, - XML: {}, - }, - endpoint: 'http://6b0e6a60.ngrok.io', - files: {}, - headers: { 'content-type': 'application/json', test2: 'value2' }, - method: 'POST', - params: {}, - type: 'REST', - userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - version: '1', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'webhook', - description: 'Test 14', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - context: { - device: { - id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', - manufacturer: 'Xiaomi', - model: 'Redmi 6', - name: 'xiaomi', - }, - network: { carrier: 'Banglalink' }, - os: { name: 'android', version: '8.1.0' }, - traits: { - address: { city: 'Dhaka', country: 'Bangladesh' }, - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - }, - }, - event: 'spin_result', - integrations: { All: true }, - message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', - properties: { - additional_bet_index: 0, - battle_id: 'N/A', - bet_amount: 9, - bet_level: 1, - bet_multiplier: 1, - coin_balance: 9466052, - current_module_name: 'CasinoGameModule', - days_in_game: 0, - extra_param: 'N/A', - fb_profile: '0', - featureGameType: 'N/A', - game_fps: 30, - game_id: 'fireEagleBase', - game_name: 'FireEagleSlots', - gem_balance: 0, - graphicsQuality: 'HD', - idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', - internetReachability: 'ReachableViaLocalAreaNetwork', - isLowEndDevice: 'False', - is_auto_spin: 'False', - is_turbo: 'False', - isf: 'False', - ishighroller: 'False', - jackpot_win_amount: 90, - jackpot_win_type: 'Silver', - level: 6, - lifetime_gem_balance: 0, - no_of_spin: 1, - player_total_battles: 0, - player_total_shields: 0, - start_date: '2019-08-01', - total_payments: 0, - tournament_id: 'T1561970819', - userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - versionSessionCount: 2, - win_amount: 0, - }, - timestamp: '2019-09-01T15:46:51.693229+05:30', - type: 'track', - user_properties: { - coin_balance: 9466052, - current_module_name: 'CasinoGameModule', - fb_profile: '0', - game_fps: 30, - game_name: 'FireEagleSlots', - gem_balance: 0, - graphicsQuality: 'HD', - idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', - internetReachability: 'ReachableViaLocalAreaNetwork', - isLowEndDevice: false, - level: 6, - lifetime_gem_balance: 0, - player_total_battles: 0, - player_total_shields: 0, - start_date: '2019-08-01', - total_payments: 0, - userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - versionSessionCount: 2, - }, - }, - destination: { - Config: { - webhookUrl: 'http://6b0e6a60.ngrok.io', - webhookMethod: 'PATCH', - headers: [{ from: 'test2', to: 'value2' }], - }, - }, - }, - ], - method: 'POST', - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - body: { - FORM: {}, - JSON: { - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - context: { - device: { - id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', - manufacturer: 'Xiaomi', - model: 'Redmi 6', - name: 'xiaomi', - }, - network: { carrier: 'Banglalink' }, - os: { name: 'android', version: '8.1.0' }, - traits: { - address: { city: 'Dhaka', country: 'Bangladesh' }, - anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - }, - }, - event: 'spin_result', - integrations: { All: true }, - message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', - properties: { - additional_bet_index: 0, - battle_id: 'N/A', - bet_amount: 9, - bet_level: 1, - bet_multiplier: 1, - coin_balance: 9466052, - current_module_name: 'CasinoGameModule', - days_in_game: 0, - extra_param: 'N/A', - fb_profile: '0', - featureGameType: 'N/A', - game_fps: 30, - game_id: 'fireEagleBase', - game_name: 'FireEagleSlots', - gem_balance: 0, - graphicsQuality: 'HD', - idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', - internetReachability: 'ReachableViaLocalAreaNetwork', - isLowEndDevice: 'False', - is_auto_spin: 'False', - is_turbo: 'False', - isf: 'False', - ishighroller: 'False', - jackpot_win_amount: 90, - jackpot_win_type: 'Silver', - level: 6, - lifetime_gem_balance: 0, - no_of_spin: 1, - player_total_battles: 0, - player_total_shields: 0, - start_date: '2019-08-01', - total_payments: 0, - tournament_id: 'T1561970819', - userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - versionSessionCount: 2, - win_amount: 0, - }, - timestamp: '2019-09-01T15:46:51.693229+05:30', - type: 'track', - user_properties: { - coin_balance: 9466052, - current_module_name: 'CasinoGameModule', - fb_profile: '0', - game_fps: 30, - game_name: 'FireEagleSlots', - gem_balance: 0, - graphicsQuality: 'HD', - idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', - internetReachability: 'ReachableViaLocalAreaNetwork', - isLowEndDevice: false, - level: 6, - lifetime_gem_balance: 0, - player_total_battles: 0, - player_total_shields: 0, - start_date: '2019-08-01', - total_payments: 0, - userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - versionSessionCount: 2, - }, - }, - JSON_ARRAY: {}, - XML: {}, - }, - endpoint: 'http://6b0e6a60.ngrok.io', - files: {}, - headers: { 'content-type': 'application/json', test2: 'value2' }, - method: 'PATCH', - params: {}, - type: 'REST', - userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', - version: '1', - }, - statusCode: 200, - }, - ], - }, - }, - }, -]; + { + "name": "webhook", + "description": "Test 0", + "feature": "processor", + "module": "destination", + "version": "v0", + "input": { + "request": { + "body": [ + { + "message": { + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "context": { + "device": { + "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", + "manufacturer": "Xiaomi", + "model": "Redmi 6", + "name": "xiaomi" + }, + "network": { + "carrier": "Banglalink" + }, + "os": { + "name": "android", + "version": "8.1.0" + }, + "traits": { + "address": { + "city": "Dhaka", + "country": "Bangladesh" + }, + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" + } + }, + "event": "spin_result", + "integrations": { + "All": true + }, + "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", + "properties": { + "additional_bet_index": 0, + "battle_id": "N/A", + "bet_amount": 9, + "bet_level": 1, + "bet_multiplier": 1, + "coin_balance": 9466052, + "current_module_name": "CasinoGameModule", + "days_in_game": 0, + "extra_param": "N/A", + "fb_profile": "0", + "featureGameType": "N/A", + "game_fps": 30, + "game_id": "fireEagleBase", + "game_name": "FireEagleSlots", + "gem_balance": 0, + "graphicsQuality": "HD", + "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", + "internetReachability": "ReachableViaLocalAreaNetwork", + "isLowEndDevice": "False", + "is_auto_spin": "False", + "is_turbo": "False", + "isf": "False", + "ishighroller": "False", + "jackpot_win_amount": 90, + "jackpot_win_type": "Silver", + "level": 6, + "lifetime_gem_balance": 0, + "no_of_spin": 1, + "player_total_battles": 0, + "player_total_shields": 0, + "start_date": "2019-08-01", + "total_payments": 0, + "tournament_id": "T1561970819", + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "versionSessionCount": 2, + "win_amount": 0 + }, + "timestamp": "2019-09-01T15:46:51.693229+05:30", + "type": "track", + "user_properties": { + "coin_balance": 9466052, + "current_module_name": "CasinoGameModule", + "fb_profile": "0", + "game_fps": 30, + "game_name": "FireEagleSlots", + "gem_balance": 0, + "graphicsQuality": "HD", + "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", + "internetReachability": "ReachableViaLocalAreaNetwork", + "isLowEndDevice": false, + "level": 6, + "lifetime_gem_balance": 0, + "player_total_battles": 0, + "player_total_shields": 0, + "start_date": "2019-08-01", + "total_payments": 0, + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "versionSessionCount": 2 + } + }, + "destination": { + "Config": { + "webhookUrl": "http://6b0e6a60.ngrok.io", + "headers": [ + { + "from": "", + "to": "" + }, + { + "from": "test2", + "to": "value2" + } + ] + }, + "DestinationDefinition": { + "Config": { + "cdkV2Enabled": true + } + } + }, + "metadata": { + "destinationId": "destId", + "workspaceId": "wspId" + } + } + ] + } + }, + "output": { + "response": { + "status": 200, + "body": [ + { + "output": { + "body": { + "JSON": { + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "context": { + "device": { + "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", + "manufacturer": "Xiaomi", + "model": "Redmi 6", + "name": "xiaomi" + }, + "network": { + "carrier": "Banglalink" + }, + "os": { + "name": "android", + "version": "8.1.0" + }, + "traits": { + "address": { + "city": "Dhaka", + "country": "Bangladesh" + }, + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" + } + }, + "event": "spin_result", + "integrations": { + "All": true + }, + "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", + "properties": { + "additional_bet_index": 0, + "battle_id": "N/A", + "bet_amount": 9, + "bet_level": 1, + "bet_multiplier": 1, + "coin_balance": 9466052, + "current_module_name": "CasinoGameModule", + "days_in_game": 0, + "extra_param": "N/A", + "fb_profile": "0", + "featureGameType": "N/A", + "game_fps": 30, + "game_id": "fireEagleBase", + "game_name": "FireEagleSlots", + "gem_balance": 0, + "graphicsQuality": "HD", + "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", + "internetReachability": "ReachableViaLocalAreaNetwork", + "isLowEndDevice": "False", + "is_auto_spin": "False", + "is_turbo": "False", + "isf": "False", + "ishighroller": "False", + "jackpot_win_amount": 90, + "jackpot_win_type": "Silver", + "level": 6, + "lifetime_gem_balance": 0, + "no_of_spin": 1, + "player_total_battles": 0, + "player_total_shields": 0, + "start_date": "2019-08-01", + "total_payments": 0, + "tournament_id": "T1561970819", + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "versionSessionCount": 2, + "win_amount": 0 + }, + "timestamp": "2019-09-01T15:46:51.693229+05:30", + "type": "track", + "user_properties": { + "coin_balance": 9466052, + "current_module_name": "CasinoGameModule", + "fb_profile": "0", + "game_fps": 30, + "game_name": "FireEagleSlots", + "gem_balance": 0, + "graphicsQuality": "HD", + "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", + "internetReachability": "ReachableViaLocalAreaNetwork", + "isLowEndDevice": false, + "level": 6, + "lifetime_gem_balance": 0, + "player_total_battles": 0, + "player_total_shields": 0, + "start_date": "2019-08-01", + "total_payments": 0, + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "versionSessionCount": 2 + } + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "version": "1", + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "type": "REST", + "method": "POST", + "endpoint": "http://6b0e6a60.ngrok.io", + "headers": { + "content-type": "application/json", + "test2": "value2" + }, + "params": {}, + "files": {} + }, + "metadata": { + "destinationId": "destId", + "workspaceId": "wspId" + }, + "statusCode": 200 + } + ] + } + } + }, + { + "name": "webhook", + "description": "Test 1", + "feature": "processor", + "module": "destination", + "version": "v0", + "input": { + "request": { + "body": [ + { + "message": { + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "context": { + "device": { + "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", + "manufacturer": "Xiaomi", + "model": "Redmi 6", + "name": "xiaomi" + }, + "network": { + "carrier": "Banglalink" + }, + "os": { + "name": "android", + "version": "8.1.0" + }, + "traits": { + "address": { + "city": "Dhaka", + "country": "Bangladesh" + }, + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" + } + }, + "event": "spin_result", + "integrations": { + "All": true + }, + "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", + "properties": { + "additional_bet_index": 0, + "battle_id": "N/A", + "bet_amount": 9, + "bet_level": 1, + "bet_multiplier": 1, + "coin_balance": 9466052, + "current_module_name": "CasinoGameModule", + "days_in_game": 0, + "extra_param": "N/A", + "fb_profile": "0", + "featureGameType": "N/A", + "game_fps": 30, + "game_id": "fireEagleBase", + "game_name": "FireEagleSlots", + "gem_balance": 0, + "graphicsQuality": "HD", + "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", + "internetReachability": "ReachableViaLocalAreaNetwork", + "isLowEndDevice": "False", + "is_auto_spin": "False", + "is_turbo": "False", + "isf": "False", + "ishighroller": "False", + "jackpot_win_amount": 90, + "jackpot_win_type": "Silver", + "level": 6, + "lifetime_gem_balance": 0, + "no_of_spin": 1, + "player_total_battles": 0, + "player_total_shields": 0, + "start_date": "2019-08-01", + "total_payments": 0, + "tournament_id": "T1561970819", + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "versionSessionCount": 2, + "win_amount": 0 + }, + "timestamp": "2019-09-01T15:46:51.693229+05:30", + "type": "track", + "user_properties": { + "coin_balance": 9466052, + "current_module_name": "CasinoGameModule", + "fb_profile": "0", + "game_fps": 30, + "game_name": "FireEagleSlots", + "gem_balance": 0, + "graphicsQuality": "HD", + "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", + "internetReachability": "ReachableViaLocalAreaNetwork", + "isLowEndDevice": false, + "level": 6, + "lifetime_gem_balance": 0, + "player_total_battles": 0, + "player_total_shields": 0, + "start_date": "2019-08-01", + "total_payments": 0, + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "versionSessionCount": 2 + } + }, + "destination": { + "Config": { + "webhookUrl": "https://6b0e6a60.ngrok.io/n" + }, + "DestinationDefinition": { + "Config": { + "cdkV2Enabled": true + } + } + }, + "metadata": { + "destinationId": "destId", + "workspaceId": "wspId" + } + } + ] + } + }, + "output": { + "response": { + "status": 200, + "body": [ + { + "output": { + "body": { + "JSON": { + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "context": { + "device": { + "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", + "manufacturer": "Xiaomi", + "model": "Redmi 6", + "name": "xiaomi" + }, + "network": { + "carrier": "Banglalink" + }, + "os": { + "name": "android", + "version": "8.1.0" + }, + "traits": { + "address": { + "city": "Dhaka", + "country": "Bangladesh" + }, + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" + } + }, + "event": "spin_result", + "integrations": { + "All": true + }, + "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", + "properties": { + "additional_bet_index": 0, + "battle_id": "N/A", + "bet_amount": 9, + "bet_level": 1, + "bet_multiplier": 1, + "coin_balance": 9466052, + "current_module_name": "CasinoGameModule", + "days_in_game": 0, + "extra_param": "N/A", + "fb_profile": "0", + "featureGameType": "N/A", + "game_fps": 30, + "game_id": "fireEagleBase", + "game_name": "FireEagleSlots", + "gem_balance": 0, + "graphicsQuality": "HD", + "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", + "internetReachability": "ReachableViaLocalAreaNetwork", + "isLowEndDevice": "False", + "is_auto_spin": "False", + "is_turbo": "False", + "isf": "False", + "ishighroller": "False", + "jackpot_win_amount": 90, + "jackpot_win_type": "Silver", + "level": 6, + "lifetime_gem_balance": 0, + "no_of_spin": 1, + "player_total_battles": 0, + "player_total_shields": 0, + "start_date": "2019-08-01", + "total_payments": 0, + "tournament_id": "T1561970819", + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "versionSessionCount": 2, + "win_amount": 0 + }, + "timestamp": "2019-09-01T15:46:51.693229+05:30", + "type": "track", + "user_properties": { + "coin_balance": 9466052, + "current_module_name": "CasinoGameModule", + "fb_profile": "0", + "game_fps": 30, + "game_name": "FireEagleSlots", + "gem_balance": 0, + "graphicsQuality": "HD", + "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", + "internetReachability": "ReachableViaLocalAreaNetwork", + "isLowEndDevice": false, + "level": 6, + "lifetime_gem_balance": 0, + "player_total_battles": 0, + "player_total_shields": 0, + "start_date": "2019-08-01", + "total_payments": 0, + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "versionSessionCount": 2 + } + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "version": "1", + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "type": "REST", + "method": "POST", + "endpoint": "https://6b0e6a60.ngrok.io/n", + "headers": { + "content-type": "application/json" + }, + "params": {}, + "files": {} + }, + "metadata": { + "destinationId": "destId", + "workspaceId": "wspId" + }, + "statusCode": 200 + } + ] + } + } + }, + { + "name": "webhook", + "description": "Test 2", + "feature": "processor", + "module": "destination", + "version": "v0", + "input": { + "request": { + "body": [ + { + "message": { + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "context": { + "device": { + "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", + "manufacturer": "Xiaomi", + "model": "Redmi 6", + "name": "xiaomi" + }, + "network": { + "carrier": "Banglalink" + }, + "os": { + "name": "android", + "version": "8.1.0" + }, + "traits": { + "address": { + "city": "Dhaka", + "country": "Bangladesh" + }, + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" + } + }, + "event": "spin_result", + "integrations": { + "All": true + }, + "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", + "properties": { + "additional_bet_index": 0, + "battle_id": "N/A", + "bet_amount": 9, + "bet_level": 1, + "bet_multiplier": 1, + "coin_balance": 9466052, + "current_module_name": "CasinoGameModule", + "days_in_game": 0, + "extra_param": "N/A", + "fb_profile": "0", + "featureGameType": "N/A", + "game_fps": 30, + "game_id": "fireEagleBase", + "game_name": "FireEagleSlots", + "gem_balance": 0, + "graphicsQuality": "HD", + "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", + "internetReachability": "ReachableViaLocalAreaNetwork", + "isLowEndDevice": "False", + "is_auto_spin": "False", + "is_turbo": "False", + "isf": "False", + "ishighroller": "False", + "jackpot_win_amount": 90, + "jackpot_win_type": "Silver", + "level": 6, + "lifetime_gem_balance": 0, + "no_of_spin": 1, + "player_total_battles": 0, + "player_total_shields": 0, + "start_date": "2019-08-01", + "total_payments": 0, + "tournament_id": "T1561970819", + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "versionSessionCount": 2, + "win_amount": 0 + }, + "timestamp": "2019-09-01T15:46:51.693229+05:30", + "type": "track", + "user_properties": { + "coin_balance": 9466052, + "current_module_name": "CasinoGameModule", + "fb_profile": "0", + "game_fps": 30, + "game_name": "FireEagleSlots", + "gem_balance": 0, + "graphicsQuality": "HD", + "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", + "internetReachability": "ReachableViaLocalAreaNetwork", + "isLowEndDevice": false, + "level": 6, + "lifetime_gem_balance": 0, + "player_total_battles": 0, + "player_total_shields": 0, + "start_date": "2019-08-01", + "total_payments": 0, + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "versionSessionCount": 2 + } + }, + "destination": { + "Config": { + "webhookUrl": "https://6b0e6a60." + }, + "DestinationDefinition": { + "Config": { + "cdkV2Enabled": true + } + } + }, + "metadata": { + "destinationId": "destId", + "workspaceId": "wspId" + } + } + ] + } + }, + "output": { + "response": { + "status": 200, + "body": [ + { + "output": { + "body": { + "JSON": { + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "context": { + "device": { + "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", + "manufacturer": "Xiaomi", + "model": "Redmi 6", + "name": "xiaomi" + }, + "network": { + "carrier": "Banglalink" + }, + "os": { + "name": "android", + "version": "8.1.0" + }, + "traits": { + "address": { + "city": "Dhaka", + "country": "Bangladesh" + }, + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" + } + }, + "event": "spin_result", + "integrations": { + "All": true + }, + "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", + "properties": { + "additional_bet_index": 0, + "battle_id": "N/A", + "bet_amount": 9, + "bet_level": 1, + "bet_multiplier": 1, + "coin_balance": 9466052, + "current_module_name": "CasinoGameModule", + "days_in_game": 0, + "extra_param": "N/A", + "fb_profile": "0", + "featureGameType": "N/A", + "game_fps": 30, + "game_id": "fireEagleBase", + "game_name": "FireEagleSlots", + "gem_balance": 0, + "graphicsQuality": "HD", + "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", + "internetReachability": "ReachableViaLocalAreaNetwork", + "isLowEndDevice": "False", + "is_auto_spin": "False", + "is_turbo": "False", + "isf": "False", + "ishighroller": "False", + "jackpot_win_amount": 90, + "jackpot_win_type": "Silver", + "level": 6, + "lifetime_gem_balance": 0, + "no_of_spin": 1, + "player_total_battles": 0, + "player_total_shields": 0, + "start_date": "2019-08-01", + "total_payments": 0, + "tournament_id": "T1561970819", + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "versionSessionCount": 2, + "win_amount": 0 + }, + "timestamp": "2019-09-01T15:46:51.693229+05:30", + "type": "track", + "user_properties": { + "coin_balance": 9466052, + "current_module_name": "CasinoGameModule", + "fb_profile": "0", + "game_fps": 30, + "game_name": "FireEagleSlots", + "gem_balance": 0, + "graphicsQuality": "HD", + "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", + "internetReachability": "ReachableViaLocalAreaNetwork", + "isLowEndDevice": false, + "level": 6, + "lifetime_gem_balance": 0, + "player_total_battles": 0, + "player_total_shields": 0, + "start_date": "2019-08-01", + "total_payments": 0, + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "versionSessionCount": 2 + } + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "version": "1", + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "type": "REST", + "method": "POST", + "endpoint": "https://6b0e6a60.", + "headers": { + "content-type": "application/json" + }, + "params": {}, + "files": {} + }, + "metadata": { + "destinationId": "destId", + "workspaceId": "wspId" + }, + "statusCode": 200 + } + ] + } + } + }, + { + "name": "webhook", + "description": "Test 3", + "feature": "processor", + "module": "destination", + "version": "v0", + "input": { + "request": { + "body": [ + { + "message": { + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "context": { + "device": { + "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", + "manufacturer": "Xiaomi", + "model": "Redmi 6", + "name": "xiaomi" + }, + "network": { + "carrier": "Banglalink" + }, + "os": { + "name": "android", + "version": "8.1.0" + }, + "traits": { + "address": { + "city": "Dhaka", + "country": "Bangladesh" + }, + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" + } + }, + "event": "spin_result", + "integrations": { + "All": true + }, + "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", + "properties": { + "k1": "v1", + "k2": { + "k3": "c3", + "k4": { + "k5": "c5" + } + } + }, + "timestamp": "2019-09-01T15:46:51.693229+05:30", + "type": "track" + }, + "destination": { + "Config": { + "webhookUrl": "https://6b0e6a60.", + "webhookMethod": "GET", + "headers": [ + { + "from": "X-customHeader", + "to": "customHeaderVal" + } + ] + }, + "DestinationDefinition": { + "Config": { + "cdkV2Enabled": true + } + } + }, + "metadata": { + "destinationId": "destId", + "workspaceId": "wspId" + } + } + ] + } + }, + "output": { + "response": { + "status": 200, + "body": [ + { + "output": { + "body": { + "JSON": {}, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "version": "1", + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "type": "REST", + "method": "GET", + "endpoint": "https://6b0e6a60.", + "headers": { + "x-customheader": "customHeaderVal" + }, + "params": { + "k1": "v1", + "k2.k3": "c3", + "k2.k4.k5": "c5" + }, + "files": {} + }, + "metadata": { + "destinationId": "destId", + "workspaceId": "wspId" + }, + "statusCode": 200 + } + ] + } + } + }, + { + "name": "webhook", + "description": "Test 4", + "feature": "processor", + "module": "destination", + "version": "v0", + "input": { + "request": { + "body": [ + { + "message": { + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "context": { + "device": { + "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", + "manufacturer": "Xiaomi", + "model": "Redmi 6", + "name": "xiaomi" + }, + "network": { + "carrier": "Banglalink" + }, + "os": { + "name": "android", + "version": "8.1.0" + }, + "traits": { + "address": { + "city": "Dhaka", + "country": "Bangladesh" + }, + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" + } + }, + "event": "spin_result", + "integrations": { + "All": true + }, + "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", + "properties": { + "k1": "v1", + "k2": { + "k3": "c3", + "k4": { + "k5": "c5" + } + } + }, + "timestamp": "2019-09-01T15:46:51.693229+05:30", + "type": "track" + }, + "destination": { + "Config": { + "webhookUrl": "https://6b0e6a60.", + "webhookMethod": "GET" + }, + "DestinationDefinition": { + "Config": { + "cdkV2Enabled": true + } + } + }, + "metadata": { + "destinationId": "destId", + "workspaceId": "wspId" + } + } + ] + } + }, + "output": { + "response": { + "status": 200, + "body": [ + { + "output": { + "body": { + "JSON": {}, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "version": "1", + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "type": "REST", + "method": "GET", + "endpoint": "https://6b0e6a60.", + "headers": {}, + "params": { + "k1": "v1", + "k2.k3": "c3", + "k2.k4.k5": "c5" + }, + "files": {} + }, + "metadata": { + "destinationId": "destId", + "workspaceId": "wspId" + }, + "statusCode": 200 + } + ] + } + } + }, + { + "name": "webhook", + "description": "Test 5", + "feature": "processor", + "module": "destination", + "version": "v0", + "input": { + "request": { + "body": [ + { + "message": { + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "context": { + "device": { + "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", + "manufacturer": "Xiaomi", + "model": "Redmi 6", + "name": "xiaomi" + }, + "network": { + "carrier": "Banglalink" + }, + "os": { + "name": "android", + "version": "8.1.0" + }, + "traits": { + "address": { + "city": "Dhaka", + "country": "Bangladesh" + }, + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" + } + }, + "event": "spin_result", + "integrations": { + "All": true + }, + "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", + "properties": { + "additional_bet_index": 0, + "battle_id": "N/A", + "bet_amount": 9, + "bet_level": 1, + "bet_multiplier": 1, + "coin_balance": 9466052, + "current_module_name": "CasinoGameModule", + "days_in_game": 0, + "extra_param": "N/A", + "fb_profile": "0", + "featureGameType": "N/A", + "game_fps": 30, + "game_id": "fireEagleBase", + "game_name": "FireEagleSlots", + "gem_balance": 0, + "graphicsQuality": "HD", + "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", + "internetReachability": "ReachableViaLocalAreaNetwork", + "isLowEndDevice": "False", + "is_auto_spin": "False", + "is_turbo": "False", + "isf": "False", + "ishighroller": "False", + "jackpot_win_amount": 90, + "jackpot_win_type": "Silver", + "level": 6, + "lifetime_gem_balance": 0, + "no_of_spin": 1, + "player_total_battles": 0, + "player_total_shields": 0, + "start_date": "2019-08-01", + "total_payments": 0, + "tournament_id": "T1561970819", + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "versionSessionCount": 2, + "win_amount": 0 + }, + "timestamp": "2019-09-01T15:46:51.693229+05:30", + "type": "track", + "request_ip": "127.0.0.1" + }, + "destination": { + "Config": { + "webhookUrl": "http://6b0e6a60.ngrok.io", + "header": [ + { + "from": "test1", + "to": "value1" + }, + { + "from": "test2", + "to": "value2" + } + ] + }, + "DestinationDefinition": { + "Config": { + "cdkV2Enabled": true + } + } + }, + "metadata": { + "destinationId": "destId", + "workspaceId": "wspId" + } + } + ] + } + }, + "output": { + "response": { + "status": 200, + "body": [ + { + "output": { + "body": { + "JSON": { + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "context": { + "device": { + "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", + "manufacturer": "Xiaomi", + "model": "Redmi 6", + "name": "xiaomi" + }, + "network": { + "carrier": "Banglalink" + }, + "os": { + "name": "android", + "version": "8.1.0" + }, + "traits": { + "address": { + "city": "Dhaka", + "country": "Bangladesh" + }, + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" + }, + "ip": "127.0.0.1" + }, + "event": "spin_result", + "integrations": { + "All": true + }, + "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", + "properties": { + "additional_bet_index": 0, + "battle_id": "N/A", + "bet_amount": 9, + "bet_level": 1, + "bet_multiplier": 1, + "coin_balance": 9466052, + "current_module_name": "CasinoGameModule", + "days_in_game": 0, + "extra_param": "N/A", + "fb_profile": "0", + "featureGameType": "N/A", + "game_fps": 30, + "game_id": "fireEagleBase", + "game_name": "FireEagleSlots", + "gem_balance": 0, + "graphicsQuality": "HD", + "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", + "internetReachability": "ReachableViaLocalAreaNetwork", + "isLowEndDevice": "False", + "is_auto_spin": "False", + "is_turbo": "False", + "isf": "False", + "ishighroller": "False", + "jackpot_win_amount": 90, + "jackpot_win_type": "Silver", + "level": 6, + "lifetime_gem_balance": 0, + "no_of_spin": 1, + "player_total_battles": 0, + "player_total_shields": 0, + "start_date": "2019-08-01", + "total_payments": 0, + "tournament_id": "T1561970819", + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "versionSessionCount": 2, + "win_amount": 0 + }, + "timestamp": "2019-09-01T15:46:51.693229+05:30", + "type": "track", + "request_ip": "127.0.0.1" + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "version": "1", + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "type": "REST", + "method": "POST", + "endpoint": "http://6b0e6a60.ngrok.io", + "headers": { + "content-type": "application/json" + }, + "params": {}, + "files": {} + }, + "metadata": { + "destinationId": "destId", + "workspaceId": "wspId" + }, + "statusCode": 200 + } + ] + } + } + }, + { + "name": "webhook", + "description": "Test 6", + "feature": "processor", + "module": "destination", + "version": "v0", + "input": { + "request": { + "body": [ + { + "message": { + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "context": { + "device": { + "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", + "manufacturer": "Xiaomi", + "model": "Redmi 6", + "name": "xiaomi" + }, + "network": { + "carrier": "Banglalink" + }, + "os": { + "name": "android", + "version": "8.1.0" + }, + "traits": { + "address": { + "city": "Dhaka", + "country": "Bangladesh" + }, + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" + } + }, + "event": "spin_result", + "integrations": { + "All": true + }, + "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", + "properties": { + "additional_bet_index": 0, + "battle_id": "N/A", + "bet_amount": 9, + "bet_level": 1, + "bet_multiplier": 1, + "coin_balance": 9466052, + "current_module_name": "CasinoGameModule", + "days_in_game": 0, + "extra_param": "N/A", + "fb_profile": "0", + "featureGameType": "N/A", + "game_fps": 30, + "game_id": "fireEagleBase", + "game_name": "FireEagleSlots", + "gem_balance": 0, + "graphicsQuality": "HD", + "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", + "internetReachability": "ReachableViaLocalAreaNetwork", + "isLowEndDevice": "False", + "is_auto_spin": "False", + "is_turbo": "False", + "isf": "False", + "ishighroller": "False", + "jackpot_win_amount": 90, + "jackpot_win_type": "Silver", + "level": 6, + "lifetime_gem_balance": 0, + "no_of_spin": 1, + "player_total_battles": 0, + "player_total_shields": 0, + "start_date": "2019-08-01", + "total_payments": 0, + "tournament_id": "T1561970819", + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "versionSessionCount": 2, + "win_amount": 0 + }, + "timestamp": "2019-09-01T15:46:51.693229+05:30", + "type": "track", + "request_ip": "127.0.0.1" + }, + "destination": { + "Config": { + "webhookUrl": "http://6b0e6a60.ngrok.io", + "headers": [ + { + "from": "Content-Type", + "to": "application/xml" + }, + { + "from": "test2", + "to": "value2" + } + ] + }, + "DestinationDefinition": { + "Config": { + "cdkV2Enabled": true + } + } + }, + "metadata": { + "destinationId": "destId", + "workspaceId": "wspId" + } + } + ] + } + }, + "output": { + "response": { + "status": 200, + "body": [ + { + "output": { + "body": { + "JSON": { + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "context": { + "device": { + "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", + "manufacturer": "Xiaomi", + "model": "Redmi 6", + "name": "xiaomi" + }, + "network": { + "carrier": "Banglalink" + }, + "os": { + "name": "android", + "version": "8.1.0" + }, + "traits": { + "address": { + "city": "Dhaka", + "country": "Bangladesh" + }, + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" + }, + "ip": "127.0.0.1" + }, + "event": "spin_result", + "integrations": { + "All": true + }, + "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", + "properties": { + "additional_bet_index": 0, + "battle_id": "N/A", + "bet_amount": 9, + "bet_level": 1, + "bet_multiplier": 1, + "coin_balance": 9466052, + "current_module_name": "CasinoGameModule", + "days_in_game": 0, + "extra_param": "N/A", + "fb_profile": "0", + "featureGameType": "N/A", + "game_fps": 30, + "game_id": "fireEagleBase", + "game_name": "FireEagleSlots", + "gem_balance": 0, + "graphicsQuality": "HD", + "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", + "internetReachability": "ReachableViaLocalAreaNetwork", + "isLowEndDevice": "False", + "is_auto_spin": "False", + "is_turbo": "False", + "isf": "False", + "ishighroller": "False", + "jackpot_win_amount": 90, + "jackpot_win_type": "Silver", + "level": 6, + "lifetime_gem_balance": 0, + "no_of_spin": 1, + "player_total_battles": 0, + "player_total_shields": 0, + "start_date": "2019-08-01", + "total_payments": 0, + "tournament_id": "T1561970819", + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "versionSessionCount": 2, + "win_amount": 0 + }, + "timestamp": "2019-09-01T15:46:51.693229+05:30", + "type": "track", + "request_ip": "127.0.0.1" + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "version": "1", + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "type": "REST", + "method": "POST", + "endpoint": "http://6b0e6a60.ngrok.io", + "headers": { + "content-type": "application/xml", + "test2": "value2" + }, + "params": {}, + "files": {} + }, + "metadata": { + "destinationId": "destId", + "workspaceId": "wspId" + }, + "statusCode": 200 + } + ] + } + } + }, + { + "name": "webhook", + "description": "Test 7", + "feature": "processor", + "module": "destination", + "version": "v0", + "input": { + "request": { + "body": [ + { + "message": { + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "event": "spin_result", + "integrations": { + "All": true + }, + "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", + "properties": { + "additional_bet_index": 0, + "battle_id": "N/A", + "bet_amount": 9, + "bet_level": 1, + "bet_multiplier": 1, + "coin_balance": 9466052, + "current_module_name": "CasinoGameModule", + "days_in_game": 0, + "extra_param": "N/A", + "fb_profile": "0", + "featureGameType": "N/A", + "game_fps": 30, + "game_id": "fireEagleBase", + "game_name": "FireEagleSlots", + "gem_balance": 0, + "graphicsQuality": "HD", + "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", + "internetReachability": "ReachableViaLocalAreaNetwork", + "isLowEndDevice": "False", + "is_auto_spin": "False", + "is_turbo": "False", + "isf": "False", + "ishighroller": "False", + "jackpot_win_amount": 90, + "jackpot_win_type": "Silver", + "level": 6, + "lifetime_gem_balance": 0, + "no_of_spin": 1, + "player_total_battles": 0, + "player_total_shields": 0, + "start_date": "2019-08-01", + "total_payments": 0, + "tournament_id": "T1561970819", + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "versionSessionCount": 2, + "win_amount": 0 + }, + "timestamp": "2019-09-01T15:46:51.693229+05:30", + "type": "track" + }, + "destination": { + "Config": { + "webhookUrl": "http://6b0e6a60.ngrok.io", + "headers": [ + { + "from": "Content-Type", + "to": "application/xml" + }, + { + "from": "test2", + "to": "value2" + } + ] + }, + "DestinationDefinition": { + "Config": { + "cdkV2Enabled": true + } + } + }, + "metadata": { + "destinationId": "destId", + "workspaceId": "wspId" + } + } + ] + } + }, + "output": { + "response": { + "status": 200, + "body": [ + { + "output": { + "body": { + "JSON": { + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "event": "spin_result", + "integrations": { + "All": true + }, + "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", + "properties": { + "additional_bet_index": 0, + "battle_id": "N/A", + "bet_amount": 9, + "bet_level": 1, + "bet_multiplier": 1, + "coin_balance": 9466052, + "current_module_name": "CasinoGameModule", + "days_in_game": 0, + "extra_param": "N/A", + "fb_profile": "0", + "featureGameType": "N/A", + "game_fps": 30, + "game_id": "fireEagleBase", + "game_name": "FireEagleSlots", + "gem_balance": 0, + "graphicsQuality": "HD", + "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", + "internetReachability": "ReachableViaLocalAreaNetwork", + "isLowEndDevice": "False", + "is_auto_spin": "False", + "is_turbo": "False", + "isf": "False", + "ishighroller": "False", + "jackpot_win_amount": 90, + "jackpot_win_type": "Silver", + "level": 6, + "lifetime_gem_balance": 0, + "no_of_spin": 1, + "player_total_battles": 0, + "player_total_shields": 0, + "start_date": "2019-08-01", + "total_payments": 0, + "tournament_id": "T1561970819", + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "versionSessionCount": 2, + "win_amount": 0 + }, + "timestamp": "2019-09-01T15:46:51.693229+05:30", + "type": "track" + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "version": "1", + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "type": "REST", + "method": "POST", + "endpoint": "http://6b0e6a60.ngrok.io", + "headers": { + "content-type": "application/xml", + "test2": "value2" + }, + "params": {}, + "files": {} + }, + "metadata": { + "destinationId": "destId", + "workspaceId": "wspId" + }, + "statusCode": 200 + } + ] + } + } + }, + { + "name": "webhook", + "description": "Test 8", + "feature": "processor", + "module": "destination", + "version": "v0", + "input": { + "request": { + "body": [ + { + "message": { + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "context": { + "device": { + "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", + "manufacturer": "Xiaomi", + "model": "Redmi 6", + "name": "xiaomi" + }, + "network": { + "carrier": "Banglalink" + }, + "os": { + "name": "android", + "version": "8.1.0" + }, + "traits": { + "address": { + "city": "Dhaka", + "country": "Bangladesh" + }, + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" + } + }, + "event": "spin_result", + "integrations": { + "All": true + }, + "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", + "properties": { + "additional_bet_index": 0, + "battle_id": "N/A", + "featureGameType": "N/A", + "win_amount": 0 + }, + "timestamp": "2019-09-01T15:46:51.693229+05:30", + "type": "track", + "header": { + "dynamic_header_key_string": "dynamic_header_value_string", + "dynamic_header_key_num": 10, + "dynamic_header_key_object": { + "k1": "v1" + } + }, + "appendPath": "/product/search?string=value" + }, + "destination": { + "Config": { + "webhookUrl": "http://6b0e6a60.ngrok.io", + "headers": [ + { + "from": "", + "to": "" + }, + { + "from": "test2", + "to": "value2" + } + ] + }, + "DestinationDefinition": { + "Config": { + "cdkV2Enabled": true + } + } + }, + "metadata": { + "destinationId": "destId", + "workspaceId": "wspId" + } + } + ] + } + }, + "output": { + "response": { + "status": 200, + "body": [ + { + "output": { + "body": { + "JSON": { + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "context": { + "device": { + "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", + "manufacturer": "Xiaomi", + "model": "Redmi 6", + "name": "xiaomi" + }, + "network": { + "carrier": "Banglalink" + }, + "os": { + "name": "android", + "version": "8.1.0" + }, + "traits": { + "address": { + "city": "Dhaka", + "country": "Bangladesh" + }, + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" + } + }, + "event": "spin_result", + "integrations": { + "All": true + }, + "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", + "properties": { + "additional_bet_index": 0, + "battle_id": "N/A", + "featureGameType": "N/A", + "win_amount": 0 + }, + "timestamp": "2019-09-01T15:46:51.693229+05:30", + "type": "track" + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "version": "1", + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "type": "REST", + "method": "POST", + "endpoint": "http://6b0e6a60.ngrok.io/product/search?string=value", + "headers": { + "content-type": "application/json", + "test2": "value2", + "dynamic_header_key_string": "dynamic_header_value_string" + }, + "params": {}, + "files": {} + }, + "metadata": { + "destinationId": "destId", + "workspaceId": "wspId" + }, + "statusCode": 200 + } + ] + } + } + }, + { + "name": "webhook", + "description": "Test 9", + "feature": "processor", + "module": "destination", + "version": "v0", + "input": { + "request": { + "body": [ + { + "message": { + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "context": { + "device": { + "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", + "manufacturer": "Xiaomi", + "model": "Redmi 6", + "name": "xiaomi" + }, + "network": { + "carrier": "Banglalink" + }, + "os": { + "name": "android", + "version": "8.1.0" + }, + "traits": { + "address": { + "city": "Dhaka", + "country": "Bangladesh" + }, + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" + } + }, + "event": "spin_result", + "integrations": { + "All": true + }, + "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", + "properties": { + "additional_bet_index": 0, + "battle_id": "N/A", + "featureGameType": "N/A", + "win_amount": 0 + }, + "timestamp": "2019-09-01T15:46:51.693229+05:30", + "type": "track", + "fullPath": "https://www.google.com" + }, + "destination": { + "Config": { + "webhookUrl": "http://6b0e6a60.ngrok.io", + "headers": [ + { + "from": "", + "to": "" + }, + { + "from": "test2", + "to": "value2" + } + ] + }, + "DestinationDefinition": { + "Config": { + "cdkV2Enabled": true + } + } + }, + "metadata": { + "destinationId": "destId", + "workspaceId": "wspId" + } + } + ] + } + }, + "output": { + "response": { + "status": 200, + "body": [ + { + "output": { + "body": { + "JSON": { + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "context": { + "device": { + "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", + "manufacturer": "Xiaomi", + "model": "Redmi 6", + "name": "xiaomi" + }, + "network": { + "carrier": "Banglalink" + }, + "os": { + "name": "android", + "version": "8.1.0" + }, + "traits": { + "address": { + "city": "Dhaka", + "country": "Bangladesh" + }, + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" + } + }, + "event": "spin_result", + "integrations": { + "All": true + }, + "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", + "properties": { + "additional_bet_index": 0, + "battle_id": "N/A", + "featureGameType": "N/A", + "win_amount": 0 + }, + "timestamp": "2019-09-01T15:46:51.693229+05:30", + "type": "track" + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "version": "1", + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "type": "REST", + "method": "POST", + "endpoint": "https://www.google.com", + "headers": { + "content-type": "application/json", + "test2": "value2" + }, + "params": {}, + "files": {} + }, + "metadata": { + "destinationId": "destId", + "workspaceId": "wspId" + }, + "statusCode": 200 + } + ] + } + } + }, + { + "name": "webhook", + "description": "Test 10", + "feature": "processor", + "module": "destination", + "version": "v0", + "input": { + "request": { + "body": [ + { + "message": { + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "context": { + "device": { + "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", + "manufacturer": "Xiaomi", + "model": "Redmi 6", + "name": "xiaomi" + }, + "network": { + "carrier": "Banglalink" + }, + "os": { + "name": "android", + "version": "8.1.0" + }, + "traits": { + "address": { + "city": "Dhaka", + "country": "Bangladesh" + }, + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" + } + }, + "event": "spin_result", + "integrations": { + "All": true + }, + "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", + "properties": { + "additional_bet_index": 0, + "battle_id": "N/A", + "featureGameType": "N/A", + "win_amount": 0 + }, + "timestamp": "2019-09-01T15:46:51.693229+05:30", + "type": "track", + "fullPath": "https://www.google.com/", + "appendPath": "?searchTerms=cats" + }, + "destination": { + "Config": { + "webhookUrl": "http://6b0e6a60.ngrok.io", + "headers": [ + { + "from": "", + "to": "" + }, + { + "from": "test2", + "to": "value2" + } + ] + }, + "DestinationDefinition": { + "Config": { + "cdkV2Enabled": true + } + } + }, + "metadata": { + "destinationId": "destId", + "workspaceId": "wspId" + } + } + ] + } + }, + "output": { + "response": { + "status": 200, + "body": [ + { + "output": { + "body": { + "JSON": { + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "context": { + "device": { + "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", + "manufacturer": "Xiaomi", + "model": "Redmi 6", + "name": "xiaomi" + }, + "network": { + "carrier": "Banglalink" + }, + "os": { + "name": "android", + "version": "8.1.0" + }, + "traits": { + "address": { + "city": "Dhaka", + "country": "Bangladesh" + }, + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" + } + }, + "event": "spin_result", + "integrations": { + "All": true + }, + "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", + "properties": { + "additional_bet_index": 0, + "battle_id": "N/A", + "featureGameType": "N/A", + "win_amount": 0 + }, + "timestamp": "2019-09-01T15:46:51.693229+05:30", + "type": "track" + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "version": "1", + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "type": "REST", + "method": "POST", + "endpoint": "https://www.google.com/?searchTerms=cats", + "headers": { + "content-type": "application/json", + "test2": "value2" + }, + "params": {}, + "files": {} + }, + "metadata": { + "destinationId": "destId", + "workspaceId": "wspId" + }, + "statusCode": 200 + } + ] + } + } + }, + { + "name": "webhook", + "description": "Test 11", + "feature": "processor", + "module": "destination", + "version": "v0", + "input": { + "request": { + "body": [ + { + "message": { + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "context": { + "device": { + "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", + "manufacturer": "Xiaomi", + "model": "Redmi 6", + "name": "xiaomi" + }, + "network": { + "carrier": "Banglalink" + }, + "os": { + "name": "android", + "version": "8.1.0" + }, + "traits": { + "address": { + "city": "Dhaka", + "country": "Bangladesh" + }, + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" + } + }, + "event": "spin_result", + "integrations": { + "All": true + }, + "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", + "properties": { + "additional_bet_index": 0, + "battle_id": "N/A", + "featureGameType": "N/A", + "win_amount": 0 + }, + "timestamp": "2019-09-01T15:46:51.693229+05:30", + "type": "track", + "fullPath": "https://www.google.com/", + "appendPath": "?searchTerms=cats" + }, + "destination": { + "Config": { + "webhookUrl": "http://6b0e6a60.ngrok.io", + "webhookMethod": "PUT", + "headers": [ + { + "from": "", + "to": "" + }, + { + "from": "test2", + "to": "value2" + } + ] + }, + "DestinationDefinition": { + "Config": { + "cdkV2Enabled": true + } + } + }, + "metadata": { + "destinationId": "destId", + "workspaceId": "wspId" + } + } + ] + } + }, + "output": { + "response": { + "status": 200, + "body": [ + { + "output": { + "body": { + "JSON": { + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "context": { + "device": { + "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", + "manufacturer": "Xiaomi", + "model": "Redmi 6", + "name": "xiaomi" + }, + "network": { + "carrier": "Banglalink" + }, + "os": { + "name": "android", + "version": "8.1.0" + }, + "traits": { + "address": { + "city": "Dhaka", + "country": "Bangladesh" + }, + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" + } + }, + "event": "spin_result", + "integrations": { + "All": true + }, + "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", + "properties": { + "additional_bet_index": 0, + "battle_id": "N/A", + "featureGameType": "N/A", + "win_amount": 0 + }, + "timestamp": "2019-09-01T15:46:51.693229+05:30", + "type": "track" + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "version": "1", + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "type": "REST", + "method": "PUT", + "endpoint": "https://www.google.com/?searchTerms=cats", + "headers": { + "content-type": "application/json", + "test2": "value2" + }, + "params": {}, + "files": {} + }, + "metadata": { + "destinationId": "destId", + "workspaceId": "wspId" + }, + "statusCode": 200 + } + ] + } + } + }, + { + "name": "webhook", + "description": "Test 12", + "feature": "processor", + "module": "destination", + "version": "v0", + "input": { + "request": { + "body": [ + { + "message": { + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "context": { + "device": { + "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", + "manufacturer": "Xiaomi", + "model": "Redmi 6", + "name": "xiaomi" + }, + "network": { + "carrier": "Banglalink" + }, + "os": { + "name": "android", + "version": "8.1.0" + }, + "traits": { + "address": { + "city": "Dhaka", + "country": "Bangladesh" + }, + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" + } + }, + "event": "spin_result", + "integrations": { + "All": true + }, + "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", + "properties": { + "additional_bet_index": 0, + "battle_id": "N/A", + "featureGameType": "N/A", + "win_amount": 0 + }, + "timestamp": "2019-09-01T15:46:51.693229+05:30", + "type": "track", + "fullPath": "https://www.google.com/", + "appendPath": "?searchTerms=cats" + }, + "destination": { + "Config": { + "webhookUrl": "http://6b0e6a60.ngrok.io", + "webhookMethod": "DELETE", + "headers": [ + { + "from": "", + "to": "" + }, + { + "from": "test2", + "to": "value2" + } + ] + }, + "DestinationDefinition": { + "Config": { + "cdkV2Enabled": true + } + } + }, + "metadata": { + "destinationId": "destId", + "workspaceId": "wspId" + } + } + ] + } + }, + "output": { + "response": { + "status": 200, + "body": [ + { + "output": { + "body": { + "JSON": {}, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "version": "1", + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "type": "REST", + "method": "DELETE", + "endpoint": "https://www.google.com/?searchTerms=cats", + "headers": { + "test2": "value2" + }, + "params": { + "additional_bet_index": 0, + "battle_id": "N/A", + "featureGameType": "N/A", + "win_amount": 0 + }, + "files": {} + }, + "metadata": { + "destinationId": "destId", + "workspaceId": "wspId" + }, + "statusCode": 200 + } + ] + } + } + }, + { + "name": "webhook", + "description": "Test 13", + "feature": "processor", + "module": "destination", + "version": "v0", + "input": { + "request": { + "body": [ + { + "message": { + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "context": { + "device": { + "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", + "manufacturer": "Xiaomi", + "model": "Redmi 6", + "name": "xiaomi" + }, + "network": { + "carrier": "Banglalink" + }, + "os": { + "name": "android", + "version": "8.1.0" + }, + "traits": { + "address": { + "city": "Dhaka", + "country": "Bangladesh" + }, + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" + } + }, + "event": "spin_result", + "integrations": { + "All": true + }, + "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", + "properties": { + "additional_bet_index": 0, + "battle_id": "N/A", + "bet_amount": 9, + "bet_level": 1, + "bet_multiplier": 1, + "coin_balance": 9466052, + "current_module_name": "CasinoGameModule", + "days_in_game": 0, + "extra_param": "N/A", + "fb_profile": "0", + "featureGameType": "N/A", + "game_fps": 30, + "game_id": "fireEagleBase", + "game_name": "FireEagleSlots", + "gem_balance": 0, + "graphicsQuality": "HD", + "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", + "internetReachability": "ReachableViaLocalAreaNetwork", + "isLowEndDevice": "False", + "is_auto_spin": "False", + "is_turbo": "False", + "isf": "False", + "ishighroller": "False", + "jackpot_win_amount": 90, + "jackpot_win_type": "Silver", + "level": 6, + "lifetime_gem_balance": 0, + "no_of_spin": 1, + "player_total_battles": 0, + "player_total_shields": 0, + "start_date": "2019-08-01", + "total_payments": 0, + "tournament_id": "T1561970819", + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "versionSessionCount": 2, + "win_amount": 0 + }, + "timestamp": "2019-09-01T15:46:51.693229+05:30", + "type": "track", + "user_properties": { + "coin_balance": 9466052, + "current_module_name": "CasinoGameModule", + "fb_profile": "0", + "game_fps": 30, + "game_name": "FireEagleSlots", + "gem_balance": 0, + "graphicsQuality": "HD", + "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", + "internetReachability": "ReachableViaLocalAreaNetwork", + "isLowEndDevice": false, + "level": 6, + "lifetime_gem_balance": 0, + "player_total_battles": 0, + "player_total_shields": 0, + "start_date": "2019-08-01", + "total_payments": 0, + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "versionSessionCount": 2 + } + }, + "destination": { + "Config": { + "webhookUrl": "http://6b0e6a60.ngrok.io", + "webhookMethod": "POST", + "headers": [ + { + "from": "test2", + "to": "value2" + } + ] + }, + "DestinationDefinition": { + "Config": { + "cdkV2Enabled": true + } + } + }, + "metadata": { + "destinationId": "destId", + "workspaceId": "wspId" + } + } + ] + } + }, + "output": { + "response": { + "status": 200, + "body": [ + { + "output": { + "body": { + "JSON": { + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "context": { + "device": { + "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", + "manufacturer": "Xiaomi", + "model": "Redmi 6", + "name": "xiaomi" + }, + "network": { + "carrier": "Banglalink" + }, + "os": { + "name": "android", + "version": "8.1.0" + }, + "traits": { + "address": { + "city": "Dhaka", + "country": "Bangladesh" + }, + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" + } + }, + "event": "spin_result", + "integrations": { + "All": true + }, + "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", + "properties": { + "additional_bet_index": 0, + "battle_id": "N/A", + "bet_amount": 9, + "bet_level": 1, + "bet_multiplier": 1, + "coin_balance": 9466052, + "current_module_name": "CasinoGameModule", + "days_in_game": 0, + "extra_param": "N/A", + "fb_profile": "0", + "featureGameType": "N/A", + "game_fps": 30, + "game_id": "fireEagleBase", + "game_name": "FireEagleSlots", + "gem_balance": 0, + "graphicsQuality": "HD", + "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", + "internetReachability": "ReachableViaLocalAreaNetwork", + "isLowEndDevice": "False", + "is_auto_spin": "False", + "is_turbo": "False", + "isf": "False", + "ishighroller": "False", + "jackpot_win_amount": 90, + "jackpot_win_type": "Silver", + "level": 6, + "lifetime_gem_balance": 0, + "no_of_spin": 1, + "player_total_battles": 0, + "player_total_shields": 0, + "start_date": "2019-08-01", + "total_payments": 0, + "tournament_id": "T1561970819", + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "versionSessionCount": 2, + "win_amount": 0 + }, + "timestamp": "2019-09-01T15:46:51.693229+05:30", + "type": "track", + "user_properties": { + "coin_balance": 9466052, + "current_module_name": "CasinoGameModule", + "fb_profile": "0", + "game_fps": 30, + "game_name": "FireEagleSlots", + "gem_balance": 0, + "graphicsQuality": "HD", + "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", + "internetReachability": "ReachableViaLocalAreaNetwork", + "isLowEndDevice": false, + "level": 6, + "lifetime_gem_balance": 0, + "player_total_battles": 0, + "player_total_shields": 0, + "start_date": "2019-08-01", + "total_payments": 0, + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "versionSessionCount": 2 + } + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "version": "1", + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "type": "REST", + "method": "POST", + "endpoint": "http://6b0e6a60.ngrok.io", + "headers": { + "content-type": "application/json", + "test2": "value2" + }, + "params": {}, + "files": {} + }, + "metadata": { + "destinationId": "destId", + "workspaceId": "wspId" + }, + "statusCode": 200 + } + ] + } + } + }, + { + "name": "webhook", + "description": "Test 14", + "feature": "processor", + "module": "destination", + "version": "v0", + "input": { + "request": { + "body": [ + { + "message": { + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "context": { + "device": { + "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", + "manufacturer": "Xiaomi", + "model": "Redmi 6", + "name": "xiaomi" + }, + "network": { + "carrier": "Banglalink" + }, + "os": { + "name": "android", + "version": "8.1.0" + }, + "traits": { + "address": { + "city": "Dhaka", + "country": "Bangladesh" + }, + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" + } + }, + "event": "spin_result", + "integrations": { + "All": true + }, + "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", + "properties": { + "additional_bet_index": 0, + "battle_id": "N/A", + "bet_amount": 9, + "bet_level": 1, + "bet_multiplier": 1, + "coin_balance": 9466052, + "current_module_name": "CasinoGameModule", + "days_in_game": 0, + "extra_param": "N/A", + "fb_profile": "0", + "featureGameType": "N/A", + "game_fps": 30, + "game_id": "fireEagleBase", + "game_name": "FireEagleSlots", + "gem_balance": 0, + "graphicsQuality": "HD", + "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", + "internetReachability": "ReachableViaLocalAreaNetwork", + "isLowEndDevice": "False", + "is_auto_spin": "False", + "is_turbo": "False", + "isf": "False", + "ishighroller": "False", + "jackpot_win_amount": 90, + "jackpot_win_type": "Silver", + "level": 6, + "lifetime_gem_balance": 0, + "no_of_spin": 1, + "player_total_battles": 0, + "player_total_shields": 0, + "start_date": "2019-08-01", + "total_payments": 0, + "tournament_id": "T1561970819", + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "versionSessionCount": 2, + "win_amount": 0 + }, + "timestamp": "2019-09-01T15:46:51.693229+05:30", + "type": "track", + "user_properties": { + "coin_balance": 9466052, + "current_module_name": "CasinoGameModule", + "fb_profile": "0", + "game_fps": 30, + "game_name": "FireEagleSlots", + "gem_balance": 0, + "graphicsQuality": "HD", + "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", + "internetReachability": "ReachableViaLocalAreaNetwork", + "isLowEndDevice": false, + "level": 6, + "lifetime_gem_balance": 0, + "player_total_battles": 0, + "player_total_shields": 0, + "start_date": "2019-08-01", + "total_payments": 0, + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "versionSessionCount": 2 + } + }, + "destination": { + "Config": { + "webhookUrl": "http://6b0e6a60.ngrok.io", + "webhookMethod": "PATCH", + "headers": [ + { + "from": "test2", + "to": "value2" + } + ] + }, + "DestinationDefinition": { + "Config": { + "cdkV2Enabled": true + } + } + }, + "metadata": { + "destinationId": "destId", + "workspaceId": "wspId" + } + } + ] + } + }, + "output": { + "response": { + "status": 200, + "body": [ + { + "output": { + "body": { + "JSON": { + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "context": { + "device": { + "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", + "manufacturer": "Xiaomi", + "model": "Redmi 6", + "name": "xiaomi" + }, + "network": { + "carrier": "Banglalink" + }, + "os": { + "name": "android", + "version": "8.1.0" + }, + "traits": { + "address": { + "city": "Dhaka", + "country": "Bangladesh" + }, + "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" + } + }, + "event": "spin_result", + "integrations": { + "All": true + }, + "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", + "properties": { + "additional_bet_index": 0, + "battle_id": "N/A", + "bet_amount": 9, + "bet_level": 1, + "bet_multiplier": 1, + "coin_balance": 9466052, + "current_module_name": "CasinoGameModule", + "days_in_game": 0, + "extra_param": "N/A", + "fb_profile": "0", + "featureGameType": "N/A", + "game_fps": 30, + "game_id": "fireEagleBase", + "game_name": "FireEagleSlots", + "gem_balance": 0, + "graphicsQuality": "HD", + "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", + "internetReachability": "ReachableViaLocalAreaNetwork", + "isLowEndDevice": "False", + "is_auto_spin": "False", + "is_turbo": "False", + "isf": "False", + "ishighroller": "False", + "jackpot_win_amount": 90, + "jackpot_win_type": "Silver", + "level": 6, + "lifetime_gem_balance": 0, + "no_of_spin": 1, + "player_total_battles": 0, + "player_total_shields": 0, + "start_date": "2019-08-01", + "total_payments": 0, + "tournament_id": "T1561970819", + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "versionSessionCount": 2, + "win_amount": 0 + }, + "timestamp": "2019-09-01T15:46:51.693229+05:30", + "type": "track", + "user_properties": { + "coin_balance": 9466052, + "current_module_name": "CasinoGameModule", + "fb_profile": "0", + "game_fps": 30, + "game_name": "FireEagleSlots", + "gem_balance": 0, + "graphicsQuality": "HD", + "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", + "internetReachability": "ReachableViaLocalAreaNetwork", + "isLowEndDevice": false, + "level": 6, + "lifetime_gem_balance": 0, + "player_total_battles": 0, + "player_total_shields": 0, + "start_date": "2019-08-01", + "total_payments": 0, + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "versionSessionCount": 2 + } + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "version": "1", + "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", + "type": "REST", + "method": "PATCH", + "endpoint": "http://6b0e6a60.ngrok.io", + "headers": { + "content-type": "application/json", + "test2": "value2" + }, + "params": {}, + "files": {} + }, + "metadata": { + "destinationId": "destId", + "workspaceId": "wspId" + }, + "statusCode": 200 + } + ] + } + } + } +] \ No newline at end of file diff --git a/test/integrations/destinations/webhook/router/data.ts b/test/integrations/destinations/webhook/router/data.ts index e9c4f8701a..ec0bf5634e 100644 --- a/test/integrations/destinations/webhook/router/data.ts +++ b/test/integrations/destinations/webhook/router/data.ts @@ -117,6 +117,11 @@ export const data = [ }, ], }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, }, }, { @@ -217,6 +222,11 @@ export const data = [ Config: { webhookUrl: 'https://6b0e6a60.ngrok.io/n', }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, }, }, ], @@ -360,7 +370,12 @@ export const data = [ }, ], }, - }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + } }, { batchedRequest: { @@ -481,6 +496,11 @@ export const data = [ Config: { webhookUrl: 'https://6b0e6a60.ngrok.io/n', }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, }, }, ], From 80cf69dc40bb4dc7c0a6d516814f36d962018745 Mon Sep 17 00:00:00 2001 From: AASHISH MALIK Date: Fri, 1 Dec 2023 21:30:40 +0530 Subject: [PATCH 55/93] fix: make supportTransformerProxyV1 false (#2861) --- src/features.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/features.json b/src/features.json index 2d064eeae0..0d2d71bbd9 100644 --- a/src/features.json +++ b/src/features.json @@ -65,5 +65,5 @@ "TIKTOK_AUDIENCE": true }, "supportSourceTransformV1": true, - "supportTransformerProxyV1": true + "supportTransformerProxyV1": false } From 7910dba2318f92cec3be1b7c7aa6b00428ecae94 Mon Sep 17 00:00:00 2001 From: Anant Jain <62471433+anantjain45823@users.noreply.github.com> Date: Sat, 2 Dec 2023 08:48:37 +0530 Subject: [PATCH 56/93] feat: marketo: migrate config fields and fix test cases (#2789) * feat: marketo: migrate config fields and fix test cases * Update destination_config.json * chore: fix test cases * Update utils.js * Update destinationCanonicalNames.js * Update cdkV2Integration.ts * Update index.js * Update am_input.json * Update am_output.json * Update am_input.json * Update am_output.json * Update data.ts * Update am_input.json * Update data.ts * Update data.ts * chore: small fix --- src/v0/destinations/marketo/config.js | 12 +- test/__tests__/data/marketo_input.json | 272 +-- test/__tests__/data/marketo_router_input.json | 2025 +++++++++-------- .../data/marketo_router_metadata_input.json | 102 +- .../__tests__/data/marketo_router_output.json | 227 +- 5 files changed, 1360 insertions(+), 1278 deletions(-) diff --git a/src/v0/destinations/marketo/config.js b/src/v0/destinations/marketo/config.js index 5d70cc0425..16449ebbad 100644 --- a/src/v0/destinations/marketo/config.js +++ b/src/v0/destinations/marketo/config.js @@ -15,9 +15,9 @@ const formatConfig = (destination) => ({ ID: destination.ID, ...destination.Config, customActivityEventMap: getHashFromArray( - destination.Config.customActivityEventMap, - 'from', - 'to', + destination.Config.rudderEventsMapping, + 'event', + 'marketoActivityId', false, ), customActivityPropertyMap: getHashFromArray( @@ -27,9 +27,9 @@ const formatConfig = (destination) => ({ false, ), customActivityPrimaryKeyMap: getHashFromArray( - destination.Config.customActivityPrimaryKeyMap, - 'from', - 'to', + destination.Config.rudderEventsMapping, + 'event', + 'marketoPrimarykey', false, ), leadTraitMapping: getHashFromArray(destination.Config.leadTraitMapping, 'from', 'to', false), diff --git a/test/__tests__/data/marketo_input.json b/test/__tests__/data/marketo_input.json index c54005b9f6..6a891fdea0 100644 --- a/test/__tests__/data/marketo_input.json +++ b/test/__tests__/data/marketo_input.json @@ -55,7 +55,12 @@ "includeKeys": [], "saveDestinationResponse": true, "secretKeys": [], - "supportedMessageTypes": ["identify", "page", "screen", "track"], + "supportedMessageTypes": [ + "identify", + "page", + "screen", + "track" + ], "supportedSourceTypes": [ "android", "ios", @@ -77,7 +82,8 @@ "Config": { "clientId": "marketo_client_id_success", "clientSecret": "marketo_client_secret_success", - "accountId": "marketo_acct_id_success" + "accountId": "marketo_acct_id_success", + "rudderEventsMapping": [] }, "Enabled": true, "Transformations": [], @@ -151,31 +157,26 @@ "clientId": "marketo_client_id_success", "clientSecret": "marketo_client_secret_success", "trackAnonymousEvents": true, - "customActivityEventMap": [ - { - "from": "Product Clicked", - "to": "100001" - } - ], "customActivityPropertyMap": [ { "from": "name", "to": "productName" } ], - "customActivityPrimaryKeyMap": [ - { - "from": "Product Clicked", - "to": "name" - } - ], "leadTraitMapping": [ { "from": "leadScore", "to": "customLeadScore" } ], - "createIfNotExist": true + "createIfNotExist": true, + "rudderEventsMapping": [ + { + "event": "Product Clicked", + "marketoPrimarykey": "name", + "marketoActivityId": "100001" + } + ] } } }, @@ -243,12 +244,6 @@ "clientId": "marketo_client_id_success", "clientSecret": "marketo_client_secret_success", "trackAnonymousEvents": true, - "customActivityEventMap": [ - { - "from": "Product Clicked", - "to": "100001" - } - ], "customActivityPropertyMap": [ { "from": "name", @@ -259,19 +254,20 @@ "to": "productId" } ], - "customActivityPrimaryKeyMap": [ - { - "from": "Product Clicked", - "to": "name" - } - ], "leadTraitMapping": [ { "from": "leadScore", "to": "customLeadScore" } ], - "createIfNotExist": true + "createIfNotExist": true, + "rudderEventsMapping": [ + { + "event": "Product Clicked", + "marketoPrimarykey": "name", + "marketoActivityId": "100001" + } + ] } } }, @@ -339,31 +335,26 @@ "clientId": "marketo_client_id_success", "clientSecret": "marketo_client_secret_success", "trackAnonymousEvents": false, - "customActivityEventMap": [ - { - "from": "Product Clicked", - "to": "100001" - } - ], "customActivityPropertyMap": [ { "from": "name", "to": "productName" } ], - "customActivityPrimaryKeyMap": [ - { - "from": "Product Clicked", - "to": "name" - } - ], "leadTraitMapping": [ { "from": "leadScore", "to": "customLeadScore" } ], - "createIfNotExist": true + "createIfNotExist": true, + "rudderEventsMapping": [ + { + "event": "Product Clicked", + "marketoPrimarykey": "name", + "marketoActivityId": "100001" + } + ] } } }, @@ -397,31 +388,26 @@ "clientId": "marketo_acct_id_token_failure", "clientSecret": "marketo_acct_id_token_failure", "trackAnonymousEvents": false, - "customActivityEventMap": [ - { - "from": "Product Clicked", - "to": "100001" - } - ], "customActivityPropertyMap": [ { "from": "name", "to": "productName" } ], - "customActivityPrimaryKeyMap": [ - { - "from": "Product Clicked", - "to": "name" - } - ], "leadTraitMapping": [ { "from": "leadScore", "to": "customLeadScore" } ], - "createIfNotExist": true + "createIfNotExist": true, + "rudderEventsMapping": [ + { + "event": "Product Clicked", + "marketoPrimarykey": "name", + "marketoActivityId": "100001" + } + ] } } }, @@ -489,31 +475,26 @@ "clientId": "marketo_client_id_success", "clientSecret": "marketo_client_secret_success", "trackAnonymousEvents": false, - "customActivityEventMap": [ - { - "from": "Product Clicked", - "to": "100001" - } - ], "customActivityPropertyMap": [ { "from": "name", "to": "productName" } ], - "customActivityPrimaryKeyMap": [ - { - "from": "Product Clicked", - "to": "name" - } - ], "leadTraitMapping": [ { "from": "leadScore", "to": "customLeadScore" } ], - "createIfNotExist": true + "createIfNotExist": true, + "rudderEventsMapping": [ + { + "event": "Product Clicked", + "marketoPrimarykey": "name", + "marketoActivityId": "100001" + } + ] } } }, @@ -558,12 +539,6 @@ "clientId": "marketo_client_id_success", "clientSecret": "marketo_client_secret_success", "trackAnonymousEvents": true, - "customActivityEventMap": [ - { - "from": "Product Clicked", - "to": "100001" - } - ], "customActivityPropertyMap": [ { "from": "name", @@ -574,19 +549,20 @@ "to": "productId" } ], - "customActivityPrimaryKeyMap": [ - { - "from": "Product Clicked", - "to": "name" - } - ], "leadTraitMapping": [ { "from": "leadScore", "to": "customLeadScore" } ], - "createIfNotExist": true + "createIfNotExist": true, + "rudderEventsMapping": [ + { + "event": "Product Clicked", + "marketoPrimarykey": "name", + "marketoActivityId": "100001" + } + ] } } }, @@ -653,31 +629,26 @@ "clientId": "marketo_client_id_success", "clientSecret": "marketo_client_secret_success", "trackAnonymousEvents": false, - "customActivityEventMap": [ - { - "from": "Product Clicked", - "to": "100001" - } - ], "customActivityPropertyMap": [ { "from": "name", "to": "productName" } ], - "customActivityPrimaryKeyMap": [ - { - "from": "Product Clicked", - "to": "name" - } - ], "leadTraitMapping": [ { "from": "leadScore", "to": "customLeadScore" } ], - "createIfNotExist": true + "createIfNotExist": true, + "rudderEventsMapping": [ + { + "event": "Product Clicked", + "marketoPrimarykey": "name", + "marketoActivityId": "100001" + } + ] } } }, @@ -744,31 +715,26 @@ "clientId": "marketo_client_id_success", "clientSecret": "marketo_client_secret_success", "trackAnonymousEvents": true, - "customActivityEventMap": [ - { - "from": "Product Clicked", - "to": "100001" - } - ], "customActivityPropertyMap": [ { "from": "name", "to": "productName" } ], - "customActivityPrimaryKeyMap": [ - { - "from": "Product Clicked", - "to": "name" - } - ], "leadTraitMapping": [ { "from": "leadScore", "to": "customLeadScore" } ], - "createIfNotExist": true + "createIfNotExist": true, + "rudderEventsMapping": [ + { + "event": "Product Clicked", + "marketoPrimarykey": "name", + "marketoActivityId": "100001" + } + ] } } }, @@ -835,31 +801,26 @@ "clientId": "marketo_client_id_success", "clientSecret": "marketo_client_secret_success", "trackAnonymousEvents": true, - "customActivityEventMap": [ - { - "from": "Product Clicked", - "to": "100001" - } - ], "customActivityPropertyMap": [ { "from": "name", "to": "productName" } ], - "customActivityPrimaryKeyMap": [ - { - "from": "Product Clicked", - "to": "name" - } - ], "leadTraitMapping": [ { "from": "leadScore", "to": "customLeadScore" } ], - "createIfNotExist": true + "createIfNotExist": true, + "rudderEventsMapping": [ + { + "event": "Product Clicked", + "marketoPrimarykey": "name", + "marketoActivityId": "100001" + } + ] } } }, @@ -925,31 +886,26 @@ "clientId": "marketo_client_id_success", "clientSecret": "marketo_client_secret_success", "trackAnonymousEvents": true, - "customActivityEventMap": [ - { - "from": "Product Clicked", - "to": "100001" - } - ], "customActivityPropertyMap": [ { "from": "name", "to": "productName" } ], - "customActivityPrimaryKeyMap": [ - { - "from": "Product Clicked", - "to": "name" - } - ], "leadTraitMapping": [ { "from": "leadScore", "to": "customLeadScore" } ], - "createIfNotExist": true + "createIfNotExist": true, + "rudderEventsMapping": [ + { + "event": "Product Clicked", + "marketoPrimarykey": "name", + "marketoActivityId": "100001" + } + ] } } }, @@ -1016,31 +972,26 @@ "clientId": "marketo_client_id_success", "clientSecret": "marketo_client_secret_success", "trackAnonymousEvents": true, - "customActivityEventMap": [ - { - "from": "Product Clicked", - "to": "100001" - } - ], "customActivityPropertyMap": [ { "from": "name", "to": "productName" } ], - "customActivityPrimaryKeyMap": [ - { - "from": "Product Clicked", - "to": "name" - } - ], "leadTraitMapping": [ { "from": "leadScore", "to": "customLeadScore" } ], - "createIfNotExist": true + "createIfNotExist": true, + "rudderEventsMapping": [ + { + "event": "Product Clicked", + "marketoPrimarykey": "name", + "marketoActivityId": "100001" + } + ] } } }, @@ -1088,12 +1039,6 @@ "clientId": "marketo_client_id_success", "clientSecret": "marketo_client_secret_success", "trackAnonymousEvents": true, - "customActivityEventMap": [ - { - "from": "Product Clicked", - "to": "100001" - } - ], "customActivityPropertyMap": [ { "from": "name", @@ -1104,17 +1049,18 @@ "to": "productId" } ], - "customActivityPrimaryKeyMap": [ - { - "from": "Product Clicked", - "to": "name" - } - ], "leadTraitMapping": [ { "from": "score", "to": "customLeadScore" } + ], + "rudderEventsMapping": [ + { + "event": "Product Clicked", + "marketoPrimarykey": "name", + "marketoActivityId": "100001" + } ] } } @@ -1174,7 +1120,12 @@ "includeKeys": [], "saveDestinationResponse": true, "secretKeys": [], - "supportedMessageTypes": ["identify", "page", "screen", "track"], + "supportedMessageTypes": [ + "identify", + "page", + "screen", + "track" + ], "supportedSourceTypes": [ "android", "ios", @@ -1196,7 +1147,8 @@ "Config": { "clientId": "marketo_client_id_success", "clientSecret": "marketo_client_secret_success", - "accountId": "marketo_acct_id_success" + "accountId": "marketo_acct_id_success", + "rudderEventsMapping": [] }, "Enabled": true, "Transformations": [], @@ -1207,4 +1159,4 @@ "query": {} } } -] +] \ No newline at end of file diff --git a/test/__tests__/data/marketo_router_input.json b/test/__tests__/data/marketo_router_input.json index acf59508dd..a2ecc7f616 100644 --- a/test/__tests__/data/marketo_router_input.json +++ b/test/__tests__/data/marketo_router_input.json @@ -1,1011 +1,1046 @@ [ - { - "message": { - "anonymousId": "anon_id_success", - "channel": "mobile", - "context": { - "app": { - "build": "1", - "name": "TestAppName", - "namespace": "com.android.sample", - "version": "1.0" + { + "message": { + "anonymousId": "anon_id_success", + "channel": "mobile", + "context": { + "app": { + "build": "1", + "name": "TestAppName", + "namespace": "com.android.sample", + "version": "1.0" + }, + "device": { + "id": "anon_id_success", + "manufacturer": "Google", + "model": "Android SDK built for x86", + "name": "generic_x86", + "type": "android" + }, + "library": { + "name": "com.rudderstack.android.sdk.core", + "version": "1.0.1-beta.1" + }, + "locale": "en-US", + "network": { + "carrier": "Android", + "bluetooth": false, + "cellular": true, + "wifi": true + }, + "os": { + "name": "Android", + "version": "8.1.0" + }, + "screen": { + "density": 420, + "height": 1794, + "width": 1080 + }, + "timezone": "Asia/Kolkata", + "traits": { + "anonymousId": "anon_id_success" + }, + "userAgent": "Dalvik/2.1.0 (Linux; U; Android 8.1.0; Android SDK built for x86 Build/OSM1.180201.007)" + }, + "event": "Product Clicked", + "integrations": { + "All": true + }, + "messageId": "id1", + "properties": { + "name": "Test Product" + }, + "originalTimestamp": "2020-12-17T21:00:59.176Z", + "type": "track", + "sentAt": "2020-03-12T09:05:03.421Z" }, - "device": { - "id": "anon_id_success", - "manufacturer": "Google", - "model": "Android SDK built for x86", - "name": "generic_x86", - "type": "android" + "metadata": { + "jobId": 1 }, - "library": { - "name": "com.rudderstack.android.sdk.core", - "version": "1.0.1-beta.1" - }, - "locale": "en-US", - "network": { - "carrier": "Android", - "bluetooth": false, - "cellular": true, - "wifi": true - }, - "os": { - "name": "Android", - "version": "8.1.0" - }, - "screen": { - "density": 420, - "height": 1794, - "width": 1080 - }, - "timezone": "Asia/Kolkata", - "traits": { - "anonymousId": "anon_id_success" - }, - "userAgent": "Dalvik/2.1.0 (Linux; U; Android 8.1.0; Android SDK built for x86 Build/OSM1.180201.007)" - }, - "event": "Product Clicked", - "integrations": { - "All": true - }, - "messageId": "id1", - "properties": { - "name": "Test Product" - }, - "originalTimestamp": "2020-12-17T21:00:59.176Z", - "type": "track", - "sentAt": "2020-03-12T09:05:03.421Z" - }, - "metadata": { - "jobId": 1 - }, - "destination": { - "Config": { - "accountId": "marketo_acct_id_success", - "clientId": "marketo_client_id_success", - "clientSecret": "marketo_client_secret_success", - "trackAnonymousEvents": true, - "customActivityEventMap": [ - { - "from": "Product Clicked", - "to": "100001" - } - ], - "customActivityPropertyMap": [ - { - "from": "name", - "to": "productName" - } - ], - "customActivityPrimaryKeyMap": [ - { - "from": "Product Clicked", - "to": "name" - } - ], - "leadTraitMapping": [ - { - "from": "leadScore", - "to": "customLeadScore" - } - ] - }, - "secretConfig": {}, - "ID": "1mMy5cqbtfuaKZv1IhVQKnBdVwe", - "name": "Marketo", - "enabled": true, - "workspaceId": "1TSN08muJTZwH8iCDmnnRt1pmLd", - "deleted": false, - "createdAt": "2020-12-30T08:39:32.005Z", - "updatedAt": "2021-02-03T16:22:31.374Z", - "destinationDefinition": { - "config": { - "destConfig": { - "defaultConfig": [ - "accountId", - "clientId", - "clientSecret", - "trackAnonymousEvents", - "customActivityEventMap", - "customActivityPropertyMap", - "customActivityPrimaryKeyMap", - "leadTraitMapping" - ] - }, - "secretKeys": ["clientSecret"], - "excludeKeys": [], - "includeKeys": [], - "routerTransform": true, - "supportedSourceTypes": ["android", "ios", "web", "unity", "amp", "cloud", "reactnative"] - }, - "responseRules": { - "responseType": "JSON", - "rules": { - "retryable": [ - { - "success": "false", - "errors.0.code": 600 - }, - { - "success": "false", - "errors.0.code": 601 - }, - { - "success": "false", - "errors.0.code": 602 - }, - { - "success": "false", - "errors.0.code": 604 - }, - { - "success": "false", - "errors.0.code": 606 - }, - { - "success": "false", - "errors.0.code": 607 - }, - { - "success": "false", - "errors.0.code": 608 - }, - { - "success": "false", - "errors.0.code": 611 - } - ], - "abortable": [ - { - "success": "false", - "errors.0.code": 603 - }, - { - "success": "false", - "errors.0.code": 605 - }, - { - "success": "false", - "errors.0.code": 609 - }, - { - "success": "false", - "errors.0.code": 610 - } - ] - } - }, - "id": "1aIXqM806xAVm92nx07YwKbRrO9", - "name": "MARKETO", - "displayName": "Marketo", - "createdAt": "2020-04-09T09:24:31.794Z", - "updatedAt": "2021-01-11T11:03:28.103Z" - }, - "transformations": [], - "isConnectionEnabled": true, - "isProcessorEnabled": true - } - }, - { - "message": { - "anonymousId": "anon_id_success", - "channel": "mobile", - "context": { - "app": { - "build": "1", - "name": "TestAppName", - "namespace": "com.android.sample", - "version": "1.0" - }, - "device": { - "id": "anon_id_success", - "manufacturer": "Google", - "model": "Android SDK built for x86", - "name": "generic_x86", - "type": "android" - }, - "library": { - "name": "com.rudderstack.android.sdk.core", - "version": "1.0.1-beta.1" - }, - "locale": "en-US", - "network": { - "carrier": "Android", - "bluetooth": false, - "cellular": true, - "wifi": true - }, - "os": { - "name": "Android", - "version": "8.1.0" - }, - "screen": { - "density": 420, - "height": 1794, - "width": 1080 - }, - "timezone": "Asia/Kolkata", - "traits": { - "anonymousId": "anon_id_success" - }, - "userAgent": "Dalvik/2.1.0 (Linux; U; Android 8.1.0; Android SDK built for x86 Build/OSM1.180201.007)" - }, - "event": "Product Clicked", - "integrations": { - "All": true - }, - "messageId": "id1", - "properties": { - "name": "Test Product", - "product_id": "prod_1" - }, - "originalTimestamp": "2020-12-17T21:00:59.176Z", - "type": "track", - "sentAt": "2020-12-17T21:00:59.176Z" - }, - "metadata": { - "jobId": 2 - }, - "destination": { - "Config": { - "accountId": "marketo_acct_id_success", - "clientId": "marketo_client_id_success", - "clientSecret": "marketo_client_secret_success", - "trackAnonymousEvents": true, - "customActivityEventMap": [ - { - "from": "Product Clicked", - "to": "100001" - } - ], - "customActivityPropertyMap": [ - { - "from": "name", - "to": "productName" - } - ], - "customActivityPrimaryKeyMap": [ - { - "from": "Product Clicked", - "to": "name" - } - ], - "leadTraitMapping": [ - { - "from": "leadScore", - "to": "customLeadScore" - } - ] - }, - "secretConfig": {}, - "ID": "1mMy5cqbtfuaKZv1IhVQKnBdVwe", - "name": "Marketo", - "enabled": true, - "workspaceId": "1TSN08muJTZwH8iCDmnnRt1pmLd", - "deleted": false, - "createdAt": "2020-12-30T08:39:32.005Z", - "updatedAt": "2021-02-03T16:22:31.374Z", - "destinationDefinition": { - "config": { - "destConfig": { - "defaultConfig": [ - "accountId", - "clientId", - "clientSecret", - "trackAnonymousEvents", - "customActivityEventMap", - "customActivityPropertyMap", - "customActivityPrimaryKeyMap", - "leadTraitMapping" - ] - }, - "secretKeys": ["clientSecret"], - "excludeKeys": [], - "includeKeys": [], - "routerTransform": true, - "supportedSourceTypes": ["android", "ios", "web", "unity", "amp", "cloud", "reactnative"] - }, - "responseRules": { - "responseType": "JSON", - "rules": { - "retryable": [ - { - "success": "false", - "errors.0.code": 600 - }, - { - "success": "false", - "errors.0.code": 601 - }, - { - "success": "false", - "errors.0.code": 602 - }, - { - "success": "false", - "errors.0.code": 604 - }, - { - "success": "false", - "errors.0.code": 606 - }, - { - "success": "false", - "errors.0.code": 607 - }, - { - "success": "false", - "errors.0.code": 608 - }, - { - "success": "false", - "errors.0.code": 611 - } - ], - "abortable": [ - { - "success": "false", - "errors.0.code": 603 - }, - { - "success": "false", - "errors.0.code": 605 - }, - { - "success": "false", - "errors.0.code": 609 - }, - { - "success": "false", - "errors.0.code": 610 - } - ] - } - }, - "id": "1aIXqM806xAVm92nx07YwKbRrO9", - "name": "MARKETO", - "displayName": "Marketo", - "createdAt": "2020-04-09T09:24:31.794Z", - "updatedAt": "2021-01-11T11:03:28.103Z" - }, - "transformations": [], - "isConnectionEnabled": true, - "isProcessorEnabled": true - } - }, - { - "message": { - "type": "identify", - "sentAt": "2022-09-19T10:34:02.002Z", - "userId": "e17c5a5e-5e2f-430b-b497-fe3f1ea3a704", - "channel": "web", - "context": { - "os": { - "name": "", - "version": "" - }, - "app": { - "name": "RudderLabs JavaScript SDK", - "build": "1.0.0", - "version": "2.12.1", - "namespace": "com.rudderlabs.javascript" - }, - "page": { - "url": "https://accounts.app.t2.broken.com/home", - "path": "/home", - "title": "Home", - "search": "", - "tab_url": "https://accounts.app.t2.broken.com/home", - "referrer": "https://ts50-cvii.core.broken.org/", - "initial_referrer": "https://ts50-cvii.core.broken.org/", - "referring_domain": "ts50-cvii.core.broken.org", - "initial_referring_domain": "ts50-cvii.core.broken.org" - }, - "locale": "en-IN", - "screen": { - "width": 1728, - "height": 1117, - "density": 2, - "innerWidth": 1728, - "innerHeight": 969 - }, - "traits": { - "name": "AM", - "email": "0c7b8b80-9c43-4f8e-b2d2-5e2448a25040@j.mail", - "lastName": "M", - "firstName": "A", - "accountName": "MACDEV", - "billingName": "g g", - "companyName": "macDev", - "currentTier": "Webinar Pro 250", - "billingCycle": "Annually", - "lastBillingDate": "2022-06-29T09:40:42.000Z", - "nextBillingDate": "2023-09-09T04:00:00.000Z", - "subscriptionType": "Webinar Pro 250", - "subscriptionStatus": "ACTIVE", - "lastWebinarEventDate": "2022-09-15T20:00:00.000Z", - "nextWebinarEventDate": "2022-09-16T06:15:00.000Z" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "2.12.1" - }, - "campaign": {}, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36" - }, - "rudderId": "73dc83ef-587f-4077-90f3-c36083e64019", - "messageId": "1663583642000200-e3f31c4c-6361-4f99-b643-7755303a6007", - "timestamp": "2022-09-19T10:34:02.954Z", - "receivedAt": "2022-09-19T10:34:02.956Z", - "request_ip": "11.105.44.120", - "anonymousId": "0c7b8b80-9c43-4f8e-b2d2-5e2448a25040", - "integrations": { - "All": true - }, - "originalTimestamp": "2022-09-19T10:34:02.000Z" + "destination": { + "Config": { + "accountId": "marketo_acct_id_success", + "clientId": "marketo_client_id_success", + "clientSecret": "marketo_client_secret_success", + "trackAnonymousEvents": true, + "customActivityPropertyMap": [ + { + "from": "name", + "to": "productName" + } + ], + "leadTraitMapping": [ + { + "from": "leadScore", + "to": "customLeadScore" + } + ], + "rudderEventsMapping": [ + { + "event": "Product Clicked", + "marketoPrimarykey": "name", + "marketoActivityId": "100001" + } + ] + }, + "secretConfig": {}, + "ID": "1mMy5cqbtfuaKZv1IhVQKnBdVwe", + "name": "Marketo", + "enabled": true, + "workspaceId": "1TSN08muJTZwH8iCDmnnRt1pmLd", + "deleted": false, + "createdAt": "2020-12-30T08:39:32.005Z", + "updatedAt": "2021-02-03T16:22:31.374Z", + "destinationDefinition": { + "config": { + "destConfig": { + "defaultConfig": [ + "accountId", + "clientId", + "clientSecret", + "trackAnonymousEvents", + "rudderEventsMapping", + "customActivityPropertyMap", + "leadTraitMapping" + ] + }, + "secretKeys": [ + "clientSecret" + ], + "excludeKeys": [], + "includeKeys": [], + "routerTransform": true, + "supportedSourceTypes": [ + "android", + "ios", + "web", + "unity", + "amp", + "cloud", + "reactnative" + ] + }, + "responseRules": { + "responseType": "JSON", + "rules": { + "retryable": [ + { + "success": "false", + "errors.0.code": 600 + }, + { + "success": "false", + "errors.0.code": 601 + }, + { + "success": "false", + "errors.0.code": 602 + }, + { + "success": "false", + "errors.0.code": 604 + }, + { + "success": "false", + "errors.0.code": 606 + }, + { + "success": "false", + "errors.0.code": 607 + }, + { + "success": "false", + "errors.0.code": 608 + }, + { + "success": "false", + "errors.0.code": 611 + } + ], + "abortable": [ + { + "success": "false", + "errors.0.code": 603 + }, + { + "success": "false", + "errors.0.code": 605 + }, + { + "success": "false", + "errors.0.code": 609 + }, + { + "success": "false", + "errors.0.code": 610 + } + ] + } + }, + "id": "1aIXqM806xAVm92nx07YwKbRrO9", + "name": "MARKETO", + "displayName": "Marketo", + "createdAt": "2020-04-09T09:24:31.794Z", + "updatedAt": "2021-01-11T11:03:28.103Z" + }, + "transformations": [], + "isConnectionEnabled": true, + "isProcessorEnabled": true + } }, - "destination": { - "Config": { - "accountId": "valid_account_broken_event", - "clientId": "504300cd-76b2-a7l4-bhle-90a07420nx73", - "clientSecret": "3l3gJpzRsZagD6gu7tnTeKXz0bomLGnd", - "trackAnonymousEvents": false, - "createIfNotExist": true, - "customActivityEventMap": [ - { - "from": "acq_signup_completed", - "to": "100026" - }, - { - "from": "act_createwebinarform_submit", - "to": "100025" - }, - { - "from": "act_presentation_style", - "to": "100025" - }, - { - "from": "act_webinar_view", - "to": "100025" - }, - { - "from": "act_webinar_join", - "to": "100025" - }, - { - "from": "act_presentation_addteammember", - "to": "100025" - }, - { - "from": "act_engagement_discussions_savediscussion", - "to": "100025" - }, - { - "to": "100025", - "from": "act_engagement_networking_savetime" - } - ] - }, - "destinationDefinition": { - "config": { - "destConfig": { - "defaultConfig": [ - "accountId", - "clientId", - "clientSecret", - "trackAnonymousEvents", - "customActivityEventMap", - "customActivityPropertyMap", - "customActivityPrimaryKeyMap", - "leadTraitMapping" - ] - }, - "secretKeys": ["clientSecret"], - "excludeKeys": [], - "includeKeys": [], - "routerTransform": true, - "supportedSourceTypes": ["android", "ios", "web", "unity", "amp", "cloud", "reactnative"] + { + "message": { + "anonymousId": "anon_id_success", + "channel": "mobile", + "context": { + "app": { + "build": "1", + "name": "TestAppName", + "namespace": "com.android.sample", + "version": "1.0" + }, + "device": { + "id": "anon_id_success", + "manufacturer": "Google", + "model": "Android SDK built for x86", + "name": "generic_x86", + "type": "android" + }, + "library": { + "name": "com.rudderstack.android.sdk.core", + "version": "1.0.1-beta.1" + }, + "locale": "en-US", + "network": { + "carrier": "Android", + "bluetooth": false, + "cellular": true, + "wifi": true + }, + "os": { + "name": "Android", + "version": "8.1.0" + }, + "screen": { + "density": 420, + "height": 1794, + "width": 1080 + }, + "timezone": "Asia/Kolkata", + "traits": { + "anonymousId": "anon_id_success" + }, + "userAgent": "Dalvik/2.1.0 (Linux; U; Android 8.1.0; Android SDK built for x86 Build/OSM1.180201.007)" + }, + "event": "Product Clicked", + "integrations": { + "All": true + }, + "messageId": "id1", + "properties": { + "name": "Test Product", + "product_id": "prod_1" + }, + "originalTimestamp": "2020-12-17T21:00:59.176Z", + "type": "track", + "sentAt": "2020-12-17T21:00:59.176Z" }, - "responseRules": { - "responseType": "JSON", - "rules": { - "retryable": [ - { - "success": "false", - "errors.0.code": 600 - }, - { - "success": "false", - "errors.0.code": 601 - }, - { - "success": "false", - "errors.0.code": 602 - }, - { - "success": "false", - "errors.0.code": 604 - }, - { - "success": "false", - "errors.0.code": 606 - }, - { - "success": "false", - "errors.0.code": 607 - }, - { - "success": "false", - "errors.0.code": 608 - }, - { - "success": "false", - "errors.0.code": 611 - } - ], - "abortable": [ - { - "success": "false", - "errors.0.code": 603 - }, - { - "success": "false", - "errors.0.code": 605 - }, - { - "success": "false", - "errors.0.code": 609 - }, - { - "success": "false", - "errors.0.code": 610 - } - ] - } + "metadata": { + "jobId": 2 }, - "id": "1aIXqM806xAVm92nx07YwKbRrO9", - "name": "MARKETO", - "displayName": "Marketo", - "createdAt": "2020-04-09T09:24:31.794Z", - "updatedAt": "2021-01-11T11:03:28.103Z" - }, - "secretConfig": {}, - "ID": "1mMy5cqbtfuaKZv1IhVQKnBdVke", - "name": "Marketo", - "enabled": true, - "workspaceId": "1TSN08muJTZwH8iCDmnnRt1pmMd", - "deleted": false, - "createdAt": "2022-02-10T08:39:32.005Z", - "updatedAt": "2022-09-03T16:22:31.374Z", - "transformations": [], - "isConnectionEnabled": true, - "isProcessorEnabled": true + "destination": { + "Config": { + "accountId": "marketo_acct_id_success", + "clientId": "marketo_client_id_success", + "clientSecret": "marketo_client_secret_success", + "trackAnonymousEvents": true, + "customActivityPropertyMap": [ + { + "from": "name", + "to": "productName" + } + ], + "leadTraitMapping": [ + { + "from": "leadScore", + "to": "customLeadScore" + } + ], + "rudderEventsMapping": [ + { + "event": "Product Clicked", + "marketoPrimarykey": "name", + "marketoActivityId": "100001" + } + ] + }, + "secretConfig": {}, + "ID": "1mMy5cqbtfuaKZv1IhVQKnBdVwe", + "name": "Marketo", + "enabled": true, + "workspaceId": "1TSN08muJTZwH8iCDmnnRt1pmLd", + "deleted": false, + "createdAt": "2020-12-30T08:39:32.005Z", + "updatedAt": "2021-02-03T16:22:31.374Z", + "destinationDefinition": { + "config": { + "destConfig": { + "defaultConfig": [ + "accountId", + "clientId", + "clientSecret", + "trackAnonymousEvents", + "rudderEventsMapping", + "customActivityPropertyMap", + "leadTraitMapping" + ] + }, + "secretKeys": [ + "clientSecret" + ], + "excludeKeys": [], + "includeKeys": [], + "routerTransform": true, + "supportedSourceTypes": [ + "android", + "ios", + "web", + "unity", + "amp", + "cloud", + "reactnative" + ] + }, + "responseRules": { + "responseType": "JSON", + "rules": { + "retryable": [ + { + "success": "false", + "errors.0.code": 600 + }, + { + "success": "false", + "errors.0.code": 601 + }, + { + "success": "false", + "errors.0.code": 602 + }, + { + "success": "false", + "errors.0.code": 604 + }, + { + "success": "false", + "errors.0.code": 606 + }, + { + "success": "false", + "errors.0.code": 607 + }, + { + "success": "false", + "errors.0.code": 608 + }, + { + "success": "false", + "errors.0.code": 611 + } + ], + "abortable": [ + { + "success": "false", + "errors.0.code": 603 + }, + { + "success": "false", + "errors.0.code": 605 + }, + { + "success": "false", + "errors.0.code": 609 + }, + { + "success": "false", + "errors.0.code": 610 + } + ] + } + }, + "id": "1aIXqM806xAVm92nx07YwKbRrO9", + "name": "MARKETO", + "displayName": "Marketo", + "createdAt": "2020-04-09T09:24:31.794Z", + "updatedAt": "2021-01-11T11:03:28.103Z" + }, + "transformations": [], + "isConnectionEnabled": true, + "isProcessorEnabled": true + } }, - "metadata": { - "jobId": 3 - } - }, - { - "message": { - "type": "identify", - "sentAt": "2022-09-19T10:34:02.002Z", - "userId": "e17c5a5e-5e2f-430b-b497-fe3f1ea3a704", - "channel": "web", - "context": { - "os": { - "name": "", - "version": "" - }, - "app": { - "name": "RudderLabs JavaScript SDK", - "build": "1.0.0", - "version": "2.12.1", - "namespace": "com.rudderlabs.javascript" - }, - "page": { - "url": "https://accounts.app.t2.broken.com/home", - "path": "/home", - "title": "Home", - "search": "", - "tab_url": "https://accounts.app.t2.broken.com/home", - "referrer": "https://ts50-cvii.core.broken.org/", - "initial_referrer": "https://ts50-cvii.core.broken.org/", - "referring_domain": "ts50-cvii.core.broken.org", - "initial_referring_domain": "ts50-cvii.core.broken.org" - }, - "locale": "en-IN", - "screen": { - "width": 1728, - "height": 1117, - "density": 2, - "innerWidth": 1728, - "innerHeight": 969 + { + "message": { + "type": "identify", + "sentAt": "2022-09-19T10:34:02.002Z", + "userId": "e17c5a5e-5e2f-430b-b497-fe3f1ea3a704", + "channel": "web", + "context": { + "os": { + "name": "", + "version": "" + }, + "app": { + "name": "RudderLabs JavaScript SDK", + "build": "1.0.0", + "version": "2.12.1", + "namespace": "com.rudderlabs.javascript" + }, + "page": { + "url": "https://accounts.app.t2.broken.com/home", + "path": "/home", + "title": "Home", + "search": "", + "tab_url": "https://accounts.app.t2.broken.com/home", + "referrer": "https://ts50-cvii.core.broken.org/", + "initial_referrer": "https://ts50-cvii.core.broken.org/", + "referring_domain": "ts50-cvii.core.broken.org", + "initial_referring_domain": "ts50-cvii.core.broken.org" + }, + "locale": "en-IN", + "screen": { + "width": 1728, + "height": 1117, + "density": 2, + "innerWidth": 1728, + "innerHeight": 969 + }, + "traits": { + "name": "AM", + "email": "0c7b8b80-9c43-4f8e-b2d2-5e2448a25040@j.mail", + "lastName": "M", + "firstName": "A", + "accountName": "MACDEV", + "billingName": "g g", + "companyName": "macDev", + "currentTier": "Webinar Pro 250", + "billingCycle": "Annually", + "lastBillingDate": "2022-06-29T09:40:42.000Z", + "nextBillingDate": "2023-09-09T04:00:00.000Z", + "subscriptionType": "Webinar Pro 250", + "subscriptionStatus": "ACTIVE", + "lastWebinarEventDate": "2022-09-15T20:00:00.000Z", + "nextWebinarEventDate": "2022-09-16T06:15:00.000Z" + }, + "library": { + "name": "RudderLabs JavaScript SDK", + "version": "2.12.1" + }, + "campaign": {}, + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36" + }, + "rudderId": "73dc83ef-587f-4077-90f3-c36083e64019", + "messageId": "1663583642000200-e3f31c4c-6361-4f99-b643-7755303a6007", + "timestamp": "2022-09-19T10:34:02.954Z", + "receivedAt": "2022-09-19T10:34:02.956Z", + "request_ip": "11.105.44.120", + "anonymousId": "0c7b8b80-9c43-4f8e-b2d2-5e2448a25040", + "integrations": { + "All": true + }, + "originalTimestamp": "2022-09-19T10:34:02.000Z" }, - "traits": { - "name": "AM", - "email": "0c7b8b80-9c43-4f8e-b2d2-5e2448a25040@j.mail", - "lastName": "M", - "firstName": "A", - "accountName": "MACDEV", - "billingName": "g g", - "companyName": "macDev", - "currentTier": "Webinar Pro 250", - "billingCycle": "Annually", - "lastBillingDate": "2022-06-29T09:40:42.000Z", - "nextBillingDate": "2023-09-09T04:00:00.000Z", - "subscriptionType": "Webinar Pro 250", - "subscriptionStatus": "ACTIVE", - "lastWebinarEventDate": "2022-09-15T20:00:00.000Z", - "nextWebinarEventDate": "2022-09-16T06:15:00.000Z" + "destination": { + "Config": { + "accountId": "valid_account_broken_event", + "clientId": "504300cd-76b2-a7l4-bhle-90a07420nx73", + "clientSecret": "3l3gJpzRsZagD6gu7tnTeKXz0bomLGnd", + "trackAnonymousEvents": false, + "createIfNotExist": true, + "rudderEventsMapping": [ + { + "event": "acq_signup_completed", + "marketoActivityId": "100026" + }, + { + "event": "act_createwebinarform_submit", + "marketoActivityId": "100025" + }, + { + "event": "act_presentation_style", + "marketoActivityId": "100025" + }, + { + "event": "act_webinar_view", + "marketoActivityId": "100025" + }, + { + "event": "act_webinar_join", + "marketoActivityId": "100025" + }, + { + "event": "act_presentation_addteammember", + "marketoActivityId": "100025" + }, + { + "event": "act_engagement_discussions_savediscussion", + "marketoActivityId": "100025" + }, + { + "event": "act_engagement_networking_savetime", + "marketoActivityId": "100025" + } + ] + }, + "destinationDefinition": { + "config": { + "destConfig": { + "defaultConfig": [ + "accountId", + "clientId", + "clientSecret", + "trackAnonymousEvents", + "rudderEventsMapping", + "customActivityPropertyMap", + "leadTraitMapping" + ] + }, + "secretKeys": [ + "clientSecret" + ], + "excludeKeys": [], + "includeKeys": [], + "routerTransform": true, + "supportedSourceTypes": [ + "android", + "ios", + "web", + "unity", + "amp", + "cloud", + "reactnative" + ] + }, + "responseRules": { + "responseType": "JSON", + "rules": { + "retryable": [ + { + "success": "false", + "errors.0.code": 600 + }, + { + "success": "false", + "errors.0.code": 601 + }, + { + "success": "false", + "errors.0.code": 602 + }, + { + "success": "false", + "errors.0.code": 604 + }, + { + "success": "false", + "errors.0.code": 606 + }, + { + "success": "false", + "errors.0.code": 607 + }, + { + "success": "false", + "errors.0.code": 608 + }, + { + "success": "false", + "errors.0.code": 611 + } + ], + "abortable": [ + { + "success": "false", + "errors.0.code": 603 + }, + { + "success": "false", + "errors.0.code": 605 + }, + { + "success": "false", + "errors.0.code": 609 + }, + { + "success": "false", + "errors.0.code": 610 + } + ] + } + }, + "id": "1aIXqM806xAVm92nx07YwKbRrO9", + "name": "MARKETO", + "displayName": "Marketo", + "createdAt": "2020-04-09T09:24:31.794Z", + "updatedAt": "2021-01-11T11:03:28.103Z" + }, + "secretConfig": {}, + "ID": "1mMy5cqbtfuaKZv1IhVQKnBdVke", + "name": "Marketo", + "enabled": true, + "workspaceId": "1TSN08muJTZwH8iCDmnnRt1pmMd", + "deleted": false, + "createdAt": "2022-02-10T08:39:32.005Z", + "updatedAt": "2022-09-03T16:22:31.374Z", + "transformations": [], + "isConnectionEnabled": true, + "isProcessorEnabled": true }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "2.12.1" - }, - "campaign": {}, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36" - }, - "rudderId": "73dc83ef-587f-4077-90f3-c36083e64019", - "messageId": "1663583642000200-e3f31c4c-6361-4f99-b643-7755303a6007", - "timestamp": "2022-09-19T10:34:02.954Z", - "receivedAt": "2022-09-19T10:34:02.956Z", - "request_ip": "11.105.44.120", - "anonymousId": "0c7b8b80-9c43-4f8e-b2d2-5e2448a25040", - "integrations": { - "All": true - }, - "originalTimestamp": "2022-09-19T10:34:02.000Z" + "metadata": { + "jobId": 3 + } }, - "destination": { - "Config": { - "accountId": "unhandled_status_code", - "clientId": "504300cd-76b2-a7l4-bhle-90a07420nx73", - "clientSecret": "3l3gJpzRsZagD6gu7tnTeKXz0bomLGnd", - "trackAnonymousEvents": false, - "createIfNotExist": true, - "customActivityEventMap": [ - { - "from": "acq_signup_completed", - "to": "100026" - }, - { - "from": "act_createwebinarform_submit", - "to": "100025" - }, - { - "from": "act_presentation_style", - "to": "100025" - }, - { - "from": "act_webinar_view", - "to": "100025" - }, - { - "from": "act_webinar_join", - "to": "100025" - }, - { - "from": "act_presentation_addteammember", - "to": "100025" - }, - { - "from": "act_engagement_discussions_savediscussion", - "to": "100025" - }, - { - "to": "100025", - "from": "act_engagement_networking_savetime" - } - ] - }, - "destinationDefinition": { - "config": { - "destConfig": { - "defaultConfig": [ - "accountId", - "clientId", - "clientSecret", - "trackAnonymousEvents", - "customActivityEventMap", - "customActivityPropertyMap", - "customActivityPrimaryKeyMap", - "leadTraitMapping" - ] - }, - "secretKeys": ["clientSecret"], - "excludeKeys": [], - "includeKeys": [], - "routerTransform": true, - "supportedSourceTypes": ["android", "ios", "web", "unity", "amp", "cloud", "reactnative"] - }, - "responseRules": { - "responseType": "JSON", - "rules": { - "retryable": [ - { - "success": "false", - "errors.0.code": 600 - }, - { - "success": "false", - "errors.0.code": 601 - }, - { - "success": "false", - "errors.0.code": 602 - }, - { - "success": "false", - "errors.0.code": 604 - }, - { - "success": "false", - "errors.0.code": 606 - }, - { - "success": "false", - "errors.0.code": 607 - }, - { - "success": "false", - "errors.0.code": 608 - }, - { - "success": "false", - "errors.0.code": 611 - } - ], - "abortable": [ - { - "success": "false", - "errors.0.code": 603 - }, - { - "success": "false", - "errors.0.code": 605 - }, - { - "success": "false", - "errors.0.code": 609 - }, - { - "success": "false", - "errors.0.code": 610 - } - ] - } - }, - "id": "1aIXqM806xAVm92nx07YwKbRrO9", - "name": "MARKETO", - "displayName": "Marketo", - "createdAt": "2020-04-09T09:24:31.794Z", - "updatedAt": "2021-01-11T11:03:28.103Z" - }, - "secretConfig": {}, - "ID": "1mMy5cqbtfuaKZv1IhVQKnBdVke", - "name": "Marketo", - "enabled": true, - "workspaceId": "1TSN08muJTZwH8iCDmnnRt1pmMd", - "deleted": false, - "createdAt": "2022-02-10T08:39:32.005Z", - "updatedAt": "2022-09-03T16:22:31.374Z", - "transformations": [], - "isConnectionEnabled": true, - "isProcessorEnabled": true - }, - "metadata": { - "jobId": 4 - } - }, - { - "message": { - "type": "identify", - "sentAt": "2022-09-19T10:34:02.002Z", - "userId": "e17c5a5e-5e2f-430b-b497-fe3f1ea3a704", - "channel": "web", - "context": { - "os": { - "name": "", - "version": "" + { + "message": { + "type": "identify", + "sentAt": "2022-09-19T10:34:02.002Z", + "userId": "e17c5a5e-5e2f-430b-b497-fe3f1ea3a704", + "channel": "web", + "context": { + "os": { + "name": "", + "version": "" + }, + "app": { + "name": "RudderLabs JavaScript SDK", + "build": "1.0.0", + "version": "2.12.1", + "namespace": "com.rudderlabs.javascript" + }, + "page": { + "url": "https://accounts.app.t2.broken.com/home", + "path": "/home", + "title": "Home", + "search": "", + "tab_url": "https://accounts.app.t2.broken.com/home", + "referrer": "https://ts50-cvii.core.broken.org/", + "initial_referrer": "https://ts50-cvii.core.broken.org/", + "referring_domain": "ts50-cvii.core.broken.org", + "initial_referring_domain": "ts50-cvii.core.broken.org" + }, + "locale": "en-IN", + "screen": { + "width": 1728, + "height": 1117, + "density": 2, + "innerWidth": 1728, + "innerHeight": 969 + }, + "traits": { + "name": "AM", + "email": "0c7b8b80-9c43-4f8e-b2d2-5e2448a25040@j.mail", + "lastName": "M", + "firstName": "A", + "accountName": "MACDEV", + "billingName": "g g", + "companyName": "macDev", + "currentTier": "Webinar Pro 250", + "billingCycle": "Annually", + "lastBillingDate": "2022-06-29T09:40:42.000Z", + "nextBillingDate": "2023-09-09T04:00:00.000Z", + "subscriptionType": "Webinar Pro 250", + "subscriptionStatus": "ACTIVE", + "lastWebinarEventDate": "2022-09-15T20:00:00.000Z", + "nextWebinarEventDate": "2022-09-16T06:15:00.000Z" + }, + "library": { + "name": "RudderLabs JavaScript SDK", + "version": "2.12.1" + }, + "campaign": {}, + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36" + }, + "rudderId": "73dc83ef-587f-4077-90f3-c36083e64019", + "messageId": "1663583642000200-e3f31c4c-6361-4f99-b643-7755303a6007", + "timestamp": "2022-09-19T10:34:02.954Z", + "receivedAt": "2022-09-19T10:34:02.956Z", + "request_ip": "11.105.44.120", + "anonymousId": "0c7b8b80-9c43-4f8e-b2d2-5e2448a25040", + "integrations": { + "All": true + }, + "originalTimestamp": "2022-09-19T10:34:02.000Z" }, - "app": { - "name": "RudderLabs JavaScript SDK", - "build": "1.0.0", - "version": "2.12.1", - "namespace": "com.rudderlabs.javascript" + "destination": { + "Config": { + "accountId": "unhandled_status_code", + "clientId": "504300cd-76b2-a7l4-bhle-90a07420nx73", + "clientSecret": "3l3gJpzRsZagD6gu7tnTeKXz0bomLGnd", + "trackAnonymousEvents": false, + "createIfNotExist": true, + "rudderEventsMapping": [ + { + "event": "acq_signup_completed", + "marketoActivityId": "100026" + }, + { + "event": "act_createwebinarform_submit", + "marketoActivityId": "100025" + }, + { + "event": "act_presentation_style", + "marketoActivityId": "100025" + }, + { + "event": "act_webinar_view", + "marketoActivityId": "100025" + }, + { + "event": "act_webinar_join", + "marketoActivityId": "100025" + }, + { + "event": "act_presentation_addteammember", + "marketoActivityId": "100025" + }, + { + "event": "act_engagement_discussions_savediscussion", + "marketoActivityId": "100025" + }, + { + "event": "act_engagement_networking_savetime", + "marketoActivityId": "100025" + } + ] + }, + "destinationDefinition": { + "config": { + "destConfig": { + "defaultConfig": [ + "accountId", + "clientId", + "clientSecret", + "trackAnonymousEvents", + "rudderEventsMapping", + "customActivityPropertyMap", + "leadTraitMapping" + ] + }, + "secretKeys": [ + "clientSecret" + ], + "excludeKeys": [], + "includeKeys": [], + "routerTransform": true, + "supportedSourceTypes": [ + "android", + "ios", + "web", + "unity", + "amp", + "cloud", + "reactnative" + ] + }, + "responseRules": { + "responseType": "JSON", + "rules": { + "retryable": [ + { + "success": "false", + "errors.0.code": 600 + }, + { + "success": "false", + "errors.0.code": 601 + }, + { + "success": "false", + "errors.0.code": 602 + }, + { + "success": "false", + "errors.0.code": 604 + }, + { + "success": "false", + "errors.0.code": 606 + }, + { + "success": "false", + "errors.0.code": 607 + }, + { + "success": "false", + "errors.0.code": 608 + }, + { + "success": "false", + "errors.0.code": 611 + } + ], + "abortable": [ + { + "success": "false", + "errors.0.code": 603 + }, + { + "success": "false", + "errors.0.code": 605 + }, + { + "success": "false", + "errors.0.code": 609 + }, + { + "success": "false", + "errors.0.code": 610 + } + ] + } + }, + "id": "1aIXqM806xAVm92nx07YwKbRrO9", + "name": "MARKETO", + "displayName": "Marketo", + "createdAt": "2020-04-09T09:24:31.794Z", + "updatedAt": "2021-01-11T11:03:28.103Z" + }, + "secretConfig": {}, + "ID": "1mMy5cqbtfuaKZv1IhVQKnBdVke", + "name": "Marketo", + "enabled": true, + "workspaceId": "1TSN08muJTZwH8iCDmnnRt1pmMd", + "deleted": false, + "createdAt": "2022-02-10T08:39:32.005Z", + "updatedAt": "2022-09-03T16:22:31.374Z", + "transformations": [], + "isConnectionEnabled": true, + "isProcessorEnabled": true }, - "page": { - "url": "https://accounts.app.t2.broken.com/home", - "path": "/home", - "title": "Home", - "search": "", - "tab_url": "https://accounts.app.t2.broken.com/home", - "referrer": "https://ts50-cvii.core.broken.org/", - "initial_referrer": "https://ts50-cvii.core.broken.org/", - "referring_domain": "ts50-cvii.core.broken.org", - "initial_referring_domain": "ts50-cvii.core.broken.org" - }, - "locale": "en-IN", - "screen": { - "width": 1728, - "height": 1117, - "density": 2, - "innerWidth": 1728, - "innerHeight": 969 - }, - "traits": { - "name": "AM", - "email": "0c7b8b80-9c43-4f8e-b2d2-5e2448a25040@j.mail", - "lastName": "M", - "firstName": "A", - "accountName": "MACDEV", - "billingName": "g g", - "companyName": "macDev", - "currentTier": "Webinar Pro 250", - "billingCycle": "Annually", - "lastBillingDate": "2022-06-29T09:40:42.000Z", - "nextBillingDate": "2023-09-09T04:00:00.000Z", - "subscriptionType": "Webinar Pro 250", - "subscriptionStatus": "ACTIVE", - "lastWebinarEventDate": "2022-09-15T20:00:00.000Z", - "nextWebinarEventDate": "2022-09-16T06:15:00.000Z" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "2.12.1" - }, - "campaign": {}, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36" - }, - "rudderId": "73dc83ef-587f-4077-90f3-c36083e64019", - "messageId": "1663583642000200-e3f31c4c-6361-4f99-b643-7755303a6007", - "timestamp": "2022-09-19T10:34:02.954Z", - "receivedAt": "2022-09-19T10:34:02.956Z", - "request_ip": "11.105.44.120", - "anonymousId": "0c7b8b80-9c43-4f8e-b2d2-5e2448a25040", - "integrations": { - "All": true - }, - "originalTimestamp": "2022-09-19T10:34:02.000Z" + "metadata": { + "jobId": 4 + } }, - "destination": { - "Config": { - "accountId": "successful_identify_transformation", - "clientId": "504300cd-76b2-a7l4-bhle-90a07420nx73", - "clientSecret": "3l3gJpzRsZagD6gu7tnTeKXz0bomLGnd", - "trackAnonymousEvents": false, - "createIfNotExist": true, - "customActivityEventMap": [ - { - "from": "acq_signup_completed", - "to": "100026" - }, - { - "from": "act_createwebinarform_submit", - "to": "100025" - }, - { - "from": "act_presentation_style", - "to": "100025" - }, - { - "from": "act_webinar_view", - "to": "100025" - }, - { - "from": "act_webinar_join", - "to": "100025" - }, - { - "from": "act_presentation_addteammember", - "to": "100025" - }, - { - "from": "act_engagement_discussions_savediscussion", - "to": "100025" - }, - { - "to": "100025", - "from": "act_engagement_networking_savetime" - } - ] - }, - "destinationDefinition": { - "config": { - "destConfig": { - "defaultConfig": [ - "accountId", - "clientId", - "clientSecret", - "trackAnonymousEvents", - "customActivityEventMap", - "customActivityPropertyMap", - "customActivityPrimaryKeyMap", - "leadTraitMapping" - ] - }, - "secretKeys": ["clientSecret"], - "excludeKeys": [], - "includeKeys": [], - "routerTransform": true, - "supportedSourceTypes": ["android", "ios", "web", "unity", "amp", "cloud", "reactnative"] + { + "message": { + "type": "identify", + "sentAt": "2022-09-19T10:34:02.002Z", + "userId": "e17c5a5e-5e2f-430b-b497-fe3f1ea3a704", + "channel": "web", + "context": { + "os": { + "name": "", + "version": "" + }, + "app": { + "name": "RudderLabs JavaScript SDK", + "build": "1.0.0", + "version": "2.12.1", + "namespace": "com.rudderlabs.javascript" + }, + "page": { + "url": "https://accounts.app.t2.broken.com/home", + "path": "/home", + "title": "Home", + "search": "", + "tab_url": "https://accounts.app.t2.broken.com/home", + "referrer": "https://ts50-cvii.core.broken.org/", + "initial_referrer": "https://ts50-cvii.core.broken.org/", + "referring_domain": "ts50-cvii.core.broken.org", + "initial_referring_domain": "ts50-cvii.core.broken.org" + }, + "locale": "en-IN", + "screen": { + "width": 1728, + "height": 1117, + "density": 2, + "innerWidth": 1728, + "innerHeight": 969 + }, + "traits": { + "name": "AM", + "email": "0c7b8b80-9c43-4f8e-b2d2-5e2448a25040@j.mail", + "lastName": "M", + "firstName": "A", + "accountName": "MACDEV", + "billingName": "g g", + "companyName": "macDev", + "currentTier": "Webinar Pro 250", + "billingCycle": "Annually", + "lastBillingDate": "2022-06-29T09:40:42.000Z", + "nextBillingDate": "2023-09-09T04:00:00.000Z", + "subscriptionType": "Webinar Pro 250", + "subscriptionStatus": "ACTIVE", + "lastWebinarEventDate": "2022-09-15T20:00:00.000Z", + "nextWebinarEventDate": "2022-09-16T06:15:00.000Z" + }, + "library": { + "name": "RudderLabs JavaScript SDK", + "version": "2.12.1" + }, + "campaign": {}, + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36" + }, + "rudderId": "73dc83ef-587f-4077-90f3-c36083e64019", + "messageId": "1663583642000200-e3f31c4c-6361-4f99-b643-7755303a6007", + "timestamp": "2022-09-19T10:34:02.954Z", + "receivedAt": "2022-09-19T10:34:02.956Z", + "request_ip": "11.105.44.120", + "anonymousId": "0c7b8b80-9c43-4f8e-b2d2-5e2448a25040", + "integrations": { + "All": true + }, + "originalTimestamp": "2022-09-19T10:34:02.000Z" }, - "responseRules": { - "responseType": "JSON", - "rules": { - "retryable": [ - { - "success": "false", - "errors.0.code": 600 - }, - { - "success": "false", - "errors.0.code": 601 - }, - { - "success": "false", - "errors.0.code": 602 - }, - { - "success": "false", - "errors.0.code": 604 - }, - { - "success": "false", - "errors.0.code": 606 - }, - { - "success": "false", - "errors.0.code": 607 - }, - { - "success": "false", - "errors.0.code": 608 - }, - { - "success": "false", - "errors.0.code": 611 - } - ], - "abortable": [ - { - "success": "false", - "errors.0.code": 603 - }, - { - "success": "false", - "errors.0.code": 605 - }, - { - "success": "false", - "errors.0.code": 609 - }, - { - "success": "false", - "errors.0.code": 610 - } - ] - } + "destination": { + "Config": { + "accountId": "successful_identify_transformation", + "clientId": "504300cd-76b2-a7l4-bhle-90a07420nx73", + "clientSecret": "3l3gJpzRsZagD6gu7tnTeKXz0bomLGnd", + "trackAnonymousEvents": false, + "createIfNotExist": true, + "rudderEventsMapping": [ + { + "event": "acq_signup_completed", + "marketoActivityId": "100026" + }, + { + "event": "act_createwebinarform_submit", + "marketoActivityId": "100025" + }, + { + "event": "act_presentation_style", + "marketoActivityId": "100025" + }, + { + "event": "act_webinar_view", + "marketoActivityId": "100025" + }, + { + "event": "act_webinar_join", + "marketoActivityId": "100025" + }, + { + "event": "act_presentation_addteammember", + "marketoActivityId": "100025" + }, + { + "event": "act_engagement_discussions_savediscussion", + "marketoActivityId": "100025" + }, + { + "event": "act_engagement_networking_savetime", + "marketoActivityId": "100025" + } + ] + }, + "destinationDefinition": { + "config": { + "destConfig": { + "defaultConfig": [ + "accountId", + "clientId", + "clientSecret", + "trackAnonymousEvents", + "rudderEventsMapping", + "customActivityPropertyMap", + "leadTraitMapping" + ] + }, + "secretKeys": [ + "clientSecret" + ], + "excludeKeys": [], + "includeKeys": [], + "routerTransform": true, + "supportedSourceTypes": [ + "android", + "ios", + "web", + "unity", + "amp", + "cloud", + "reactnative" + ] + }, + "responseRules": { + "responseType": "JSON", + "rules": { + "retryable": [ + { + "success": "false", + "errors.0.code": 600 + }, + { + "success": "false", + "errors.0.code": 601 + }, + { + "success": "false", + "errors.0.code": 602 + }, + { + "success": "false", + "errors.0.code": 604 + }, + { + "success": "false", + "errors.0.code": 606 + }, + { + "success": "false", + "errors.0.code": 607 + }, + { + "success": "false", + "errors.0.code": 608 + }, + { + "success": "false", + "errors.0.code": 611 + } + ], + "abortable": [ + { + "success": "false", + "errors.0.code": 603 + }, + { + "success": "false", + "errors.0.code": 605 + }, + { + "success": "false", + "errors.0.code": 609 + }, + { + "success": "false", + "errors.0.code": 610 + } + ] + } + }, + "id": "1aIXqM806xAVm92nx07YwKbRrO9", + "name": "MARKETO", + "displayName": "Marketo", + "createdAt": "2020-04-09T09:24:31.794Z", + "updatedAt": "2021-01-11T11:03:28.103Z" + }, + "secretConfig": {}, + "ID": "1mMy5cqbtfuaKZv1IhVQKnBdVke", + "name": "Marketo", + "enabled": true, + "workspaceId": "1TSN08muJTZwH8iCDmnnRt1pmMd", + "deleted": false, + "createdAt": "2022-02-10T08:39:32.005Z", + "updatedAt": "2022-09-03T16:22:31.374Z", + "transformations": [], + "isConnectionEnabled": true, + "isProcessorEnabled": true }, - "id": "1aIXqM806xAVm92nx07YwKbRrO9", - "name": "MARKETO", - "displayName": "Marketo", - "createdAt": "2020-04-09T09:24:31.794Z", - "updatedAt": "2021-01-11T11:03:28.103Z" - }, - "secretConfig": {}, - "ID": "1mMy5cqbtfuaKZv1IhVQKnBdVke", - "name": "Marketo", - "enabled": true, - "workspaceId": "1TSN08muJTZwH8iCDmnnRt1pmMd", - "deleted": false, - "createdAt": "2022-02-10T08:39:32.005Z", - "updatedAt": "2022-09-03T16:22:31.374Z", - "transformations": [], - "isConnectionEnabled": true, - "isProcessorEnabled": true - }, - "metadata": { - "jobId": 5 + "metadata": { + "jobId": 5 + } } - } -] +] \ No newline at end of file diff --git a/test/__tests__/data/marketo_router_metadata_input.json b/test/__tests__/data/marketo_router_metadata_input.json index 1c02a9c6fd..0c481c38ea 100644 --- a/test/__tests__/data/marketo_router_metadata_input.json +++ b/test/__tests__/data/marketo_router_metadata_input.json @@ -46,10 +46,25 @@ "clientId": "marketo_client_id_success", "clientSecret": "marketo_client_secret_success", "trackAnonymousEvents": true, - "customActivityEventMap": [{ "from": "Product Clicked", "to": "100001" }], - "customActivityPropertyMap": [{ "from": "name", "to": "productName" }], - "customActivityPrimaryKeyMap": [{ "from": "Product Clicked", "to": "name" }], - "leadTraitMapping": [{ "from": "leadScore", "to": "customLeadScore" }] + "customActivityPropertyMap": [ + { + "from": "name", + "to": "productName" + } + ], + "rudderEventsMapping": [ + { + "event": "Product Clicked", + "marketoPrimarykey": "name", + "marketoActivityId": "100001" + } + ], + "leadTraitMapping": [ + { + "from": "leadScore", + "to": "customLeadScore" + } + ] }, "secretConfig": {}, "ID": "1mMy5cqbtfuaKZv1IhVQKnBdVwe", @@ -67,36 +82,81 @@ "clientId", "clientSecret", "trackAnonymousEvents", - "customActivityEventMap", "customActivityPropertyMap", - "customActivityPrimaryKeyMap", + "rudderEventsMapping", "leadTraitMapping" ] }, - "secretKeys": ["clientSecret"], + "secretKeys": [ + "clientSecret" + ], "excludeKeys": [], "includeKeys": [], "routerTransform": true, - "supportedSourceTypes": ["android", "ios", "web", "unity", "amp", "cloud", "reactnative"] + "supportedSourceTypes": [ + "android", + "ios", + "web", + "unity", + "amp", + "cloud", + "reactnative" + ] }, "responseRules": { "responseType": "JSON", "rules": { "retryable": [ - { "success": "false", "errors.0.code": 600 }, - { "success": "false", "errors.0.code": 601 }, - { "success": "false", "errors.0.code": 602 }, - { "success": "false", "errors.0.code": 604 }, - { "success": "false", "errors.0.code": 606 }, - { "success": "false", "errors.0.code": 607 }, - { "success": "false", "errors.0.code": 608 }, - { "success": "false", "errors.0.code": 611 } + { + "success": "false", + "errors.0.code": 600 + }, + { + "success": "false", + "errors.0.code": 601 + }, + { + "success": "false", + "errors.0.code": 602 + }, + { + "success": "false", + "errors.0.code": 604 + }, + { + "success": "false", + "errors.0.code": 606 + }, + { + "success": "false", + "errors.0.code": 607 + }, + { + "success": "false", + "errors.0.code": 608 + }, + { + "success": "false", + "errors.0.code": 611 + } ], "abortable": [ - { "success": "false", "errors.0.code": 603 }, - { "success": "false", "errors.0.code": 605 }, - { "success": "false", "errors.0.code": 609 }, - { "success": "false", "errors.0.code": 610 } + { + "success": "false", + "errors.0.code": 603 + }, + { + "success": "false", + "errors.0.code": 605 + }, + { + "success": "false", + "errors.0.code": 609 + }, + { + "success": "false", + "errors.0.code": 610 + } ] } }, @@ -110,4 +170,4 @@ "isConnectionEnabled": true, "isProcessorEnabled": true } -} +} \ No newline at end of file diff --git a/test/__tests__/data/marketo_router_output.json b/test/__tests__/data/marketo_router_output.json index a8877399e9..35c0d30a8e 100644 --- a/test/__tests__/data/marketo_router_output.json +++ b/test/__tests__/data/marketo_router_output.json @@ -41,29 +41,24 @@ "clientId": "marketo_client_id_success", "clientSecret": "marketo_client_secret_success", "trackAnonymousEvents": true, - "customActivityEventMap": [ - { - "from": "Product Clicked", - "to": "100001" - } - ], "customActivityPropertyMap": [ { "from": "name", "to": "productName" } ], - "customActivityPrimaryKeyMap": [ - { - "from": "Product Clicked", - "to": "name" - } - ], "leadTraitMapping": [ { "from": "leadScore", "to": "customLeadScore" } + ], + "rudderEventsMapping": [ + { + "event": "Product Clicked", + "marketoPrimarykey": "name", + "marketoActivityId": "100001" + } ] }, "secretConfig": {}, @@ -82,17 +77,26 @@ "clientId", "clientSecret", "trackAnonymousEvents", - "customActivityEventMap", + "rudderEventsMapping", "customActivityPropertyMap", - "customActivityPrimaryKeyMap", "leadTraitMapping" ] }, - "secretKeys": ["clientSecret"], + "secretKeys": [ + "clientSecret" + ], "excludeKeys": [], "includeKeys": [], "routerTransform": true, - "supportedSourceTypes": ["android", "ios", "web", "unity", "amp", "cloud", "reactnative"] + "supportedSourceTypes": [ + "android", + "ios", + "web", + "unity", + "amp", + "cloud", + "reactnative" + ] }, "responseRules": { "responseType": "JSON", @@ -204,29 +208,24 @@ "clientId": "marketo_client_id_success", "clientSecret": "marketo_client_secret_success", "trackAnonymousEvents": true, - "customActivityEventMap": [ - { - "from": "Product Clicked", - "to": "100001" - } - ], "customActivityPropertyMap": [ { "from": "name", "to": "productName" } ], - "customActivityPrimaryKeyMap": [ - { - "from": "Product Clicked", - "to": "name" - } - ], "leadTraitMapping": [ { "from": "leadScore", "to": "customLeadScore" } + ], + "rudderEventsMapping": [ + { + "event": "Product Clicked", + "marketoPrimarykey": "name", + "marketoActivityId": "100001" + } ] }, "secretConfig": {}, @@ -245,17 +244,26 @@ "clientId", "clientSecret", "trackAnonymousEvents", - "customActivityEventMap", + "rudderEventsMapping", "customActivityPropertyMap", - "customActivityPrimaryKeyMap", "leadTraitMapping" ] }, - "secretKeys": ["clientSecret"], + "secretKeys": [ + "clientSecret" + ], "excludeKeys": [], "includeKeys": [], "routerTransform": true, - "supportedSourceTypes": ["android", "ios", "web", "unity", "amp", "cloud", "reactnative"] + "supportedSourceTypes": [ + "android", + "ios", + "web", + "unity", + "amp", + "cloud", + "reactnative" + ] }, "responseRules": { "responseType": "JSON", @@ -345,38 +353,38 @@ "clientSecret": "3l3gJpzRsZagD6gu7tnTeKXz0bomLGnd", "trackAnonymousEvents": false, "createIfNotExist": true, - "customActivityEventMap": [ + "rudderEventsMapping": [ { - "from": "acq_signup_completed", - "to": "100026" + "event": "acq_signup_completed", + "marketoActivityId": "100026" }, { - "from": "act_createwebinarform_submit", - "to": "100025" + "event": "act_createwebinarform_submit", + "marketoActivityId": "100025" }, { - "from": "act_presentation_style", - "to": "100025" + "event": "act_presentation_style", + "marketoActivityId": "100025" }, { - "from": "act_webinar_view", - "to": "100025" + "event": "act_webinar_view", + "marketoActivityId": "100025" }, { - "from": "act_webinar_join", - "to": "100025" + "event": "act_webinar_join", + "marketoActivityId": "100025" }, { - "from": "act_presentation_addteammember", - "to": "100025" + "event": "act_presentation_addteammember", + "marketoActivityId": "100025" }, { - "from": "act_engagement_discussions_savediscussion", - "to": "100025" + "event": "act_engagement_discussions_savediscussion", + "marketoActivityId": "100025" }, { - "to": "100025", - "from": "act_engagement_networking_savetime" + "event": "act_engagement_networking_savetime", + "marketoActivityId": "100025" } ] }, @@ -388,17 +396,26 @@ "clientId", "clientSecret", "trackAnonymousEvents", - "customActivityEventMap", + "rudderEventsMapping", "customActivityPropertyMap", - "customActivityPrimaryKeyMap", "leadTraitMapping" ] }, - "secretKeys": ["clientSecret"], + "secretKeys": [ + "clientSecret" + ], "excludeKeys": [], "includeKeys": [], "routerTransform": true, - "supportedSourceTypes": ["android", "ios", "web", "unity", "amp", "cloud", "reactnative"] + "supportedSourceTypes": [ + "android", + "ios", + "web", + "unity", + "amp", + "cloud", + "reactnative" + ] }, "responseRules": { "responseType": "JSON", @@ -492,38 +509,38 @@ "clientSecret": "3l3gJpzRsZagD6gu7tnTeKXz0bomLGnd", "trackAnonymousEvents": false, "createIfNotExist": true, - "customActivityEventMap": [ + "rudderEventsMapping": [ { - "from": "acq_signup_completed", - "to": "100026" + "event": "acq_signup_completed", + "marketoActivityId": "100026" }, { - "from": "act_createwebinarform_submit", - "to": "100025" + "event": "act_createwebinarform_submit", + "marketoActivityId": "100025" }, { - "from": "act_presentation_style", - "to": "100025" + "event": "act_presentation_style", + "marketoActivityId": "100025" }, { - "from": "act_webinar_view", - "to": "100025" + "event": "act_webinar_view", + "marketoActivityId": "100025" }, { - "from": "act_webinar_join", - "to": "100025" + "event": "act_webinar_join", + "marketoActivityId": "100025" }, { - "from": "act_presentation_addteammember", - "to": "100025" + "event": "act_presentation_addteammember", + "marketoActivityId": "100025" }, { - "from": "act_engagement_discussions_savediscussion", - "to": "100025" + "event": "act_engagement_discussions_savediscussion", + "marketoActivityId": "100025" }, { - "to": "100025", - "from": "act_engagement_networking_savetime" + "event": "act_engagement_networking_savetime", + "marketoActivityId": "100025" } ] }, @@ -535,17 +552,26 @@ "clientId", "clientSecret", "trackAnonymousEvents", - "customActivityEventMap", + "rudderEventsMapping", "customActivityPropertyMap", - "customActivityPrimaryKeyMap", "leadTraitMapping" ] }, - "secretKeys": ["clientSecret"], + "secretKeys": [ + "clientSecret" + ], "excludeKeys": [], "includeKeys": [], "routerTransform": true, - "supportedSourceTypes": ["android", "ios", "web", "unity", "amp", "cloud", "reactnative"] + "supportedSourceTypes": [ + "android", + "ios", + "web", + "unity", + "amp", + "cloud", + "reactnative" + ] }, "responseRules": { "responseType": "JSON", @@ -673,38 +699,38 @@ "clientSecret": "3l3gJpzRsZagD6gu7tnTeKXz0bomLGnd", "trackAnonymousEvents": false, "createIfNotExist": true, - "customActivityEventMap": [ + "rudderEventsMapping": [ { - "from": "acq_signup_completed", - "to": "100026" + "event": "acq_signup_completed", + "marketoActivityId": "100026" }, { - "from": "act_createwebinarform_submit", - "to": "100025" + "event": "act_createwebinarform_submit", + "marketoActivityId": "100025" }, { - "from": "act_presentation_style", - "to": "100025" + "event": "act_presentation_style", + "marketoActivityId": "100025" }, { - "from": "act_webinar_view", - "to": "100025" + "event": "act_webinar_view", + "marketoActivityId": "100025" }, { - "from": "act_webinar_join", - "to": "100025" + "event": "act_webinar_join", + "marketoActivityId": "100025" }, { - "from": "act_presentation_addteammember", - "to": "100025" + "event": "act_presentation_addteammember", + "marketoActivityId": "100025" }, { - "from": "act_engagement_discussions_savediscussion", - "to": "100025" + "event": "act_engagement_discussions_savediscussion", + "marketoActivityId": "100025" }, { - "to": "100025", - "from": "act_engagement_networking_savetime" + "event": "act_engagement_networking_savetime", + "marketoActivityId": "100025" } ] }, @@ -716,17 +742,26 @@ "clientId", "clientSecret", "trackAnonymousEvents", - "customActivityEventMap", + "rudderEventsMapping", "customActivityPropertyMap", - "customActivityPrimaryKeyMap", "leadTraitMapping" ] }, - "secretKeys": ["clientSecret"], + "secretKeys": [ + "clientSecret" + ], "excludeKeys": [], "includeKeys": [], "routerTransform": true, - "supportedSourceTypes": ["android", "ios", "web", "unity", "amp", "cloud", "reactnative"] + "supportedSourceTypes": [ + "android", + "ios", + "web", + "unity", + "amp", + "cloud", + "reactnative" + ] }, "responseRules": { "responseType": "JSON", @@ -804,4 +839,4 @@ "isProcessorEnabled": true } } -] +] \ No newline at end of file From 4cec65e4103e99021f5108fcc7c557b952f1c5eb Mon Sep 17 00:00:00 2001 From: shrouti1507 <60211312+shrouti1507@users.noreply.github.com> Date: Tue, 5 Dec 2023 17:57:02 +0530 Subject: [PATCH 57/93] fix: salesforce transformer proxy response handling issue for authorization flow (#2873) --- .../destinations/salesforce/networkHandler.js | 2 ++ src/v0/destinations/salesforce/utils.js | 15 ++++++--- .../salesforce_oauth/networkHandler.js | 33 +++++++++++++++++++ test/__tests__/facebook_conversions.test.js | 2 ++ .../salesforce/dataDelivery/data.ts | 1 - 5 files changed, 47 insertions(+), 6 deletions(-) create mode 100644 src/v0/destinations/salesforce_oauth/networkHandler.js diff --git a/src/v0/destinations/salesforce/networkHandler.js b/src/v0/destinations/salesforce/networkHandler.js index 622d2ae731..dc67aff1b7 100644 --- a/src/v0/destinations/salesforce/networkHandler.js +++ b/src/v0/destinations/salesforce/networkHandler.js @@ -1,5 +1,6 @@ const { proxyRequest, prepareProxyRequest } = require('../../../adapters/network'); const { processAxiosResponse } = require('../../../adapters/utils/networkUtils'); +const { LEGACY } = require('./config'); const { salesforceResponseHandler } = require('./utils'); const responseHandler = (destinationResponse, destType) => { @@ -9,6 +10,7 @@ const responseHandler = (destinationResponse, destType) => { destinationResponse, 'during Salesforce Response Handling', destinationResponse?.rudderJobMetadata?.destInfo?.authKey, + LEGACY ); // else successfully return status as 200, message and original destination response diff --git a/src/v0/destinations/salesforce/utils.js b/src/v0/destinations/salesforce/utils.js index c725ec3b20..96735ecc17 100644 --- a/src/v0/destinations/salesforce/utils.js +++ b/src/v0/destinations/salesforce/utils.js @@ -33,16 +33,21 @@ const salesforceResponseHandler = (destResponse, sourceMessage, authKey, authori const matchErrorCode = (errorCode) => response && Array.isArray(response) && response.some((resp) => resp?.errorCode === errorCode); if (status === 401 && authKey && matchErrorCode('INVALID_SESSION_ID')) { - if (authorizationFlow === LEGACY) { - // checking for invalid/expired token errors and evicting cache in that case - // rudderJobMetadata contains some destination info which is being used to evict the cache - ACCESS_TOKEN_CACHE.del(authKey); + if (authorizationFlow === OAUTH) { + throw new RetryableError( + `${DESTINATION} Request Failed - due to "INVALID_SESSION_ID", (Retryable) ${sourceMessage}`, + 500, + destResponse, + getAuthErrCategoryFromStCode(status), + ); } + // checking for invalid/expired token errors and evicting cache in that case + // rudderJobMetadata contains some destination info which is being used to evict the cache + ACCESS_TOKEN_CACHE.del(authKey); throw new RetryableError( `${DESTINATION} Request Failed - due to "INVALID_SESSION_ID", (Retryable) ${sourceMessage}`, 500, destResponse, - authorizationFlow === LEGACY ? '' : getAuthErrCategoryFromStCode(status), ); } else if (status === 403 && matchErrorCode('REQUEST_LIMIT_EXCEEDED')) { // If the error code is REQUEST_LIMIT_EXCEEDED, you’ve exceeded API request limits in your org. diff --git a/src/v0/destinations/salesforce_oauth/networkHandler.js b/src/v0/destinations/salesforce_oauth/networkHandler.js new file mode 100644 index 0000000000..2042830cb1 --- /dev/null +++ b/src/v0/destinations/salesforce_oauth/networkHandler.js @@ -0,0 +1,33 @@ +const { proxyRequest, prepareProxyRequest } = require('../../../adapters/network'); +const { processAxiosResponse } = require('../../../adapters/utils/networkUtils'); +const { OAUTH } = require('../salesforce/config'); +const { salesforceResponseHandler } = require('../salesforce/utils'); + +const responseHandler = (destinationResponse, destType) => { + const message = `Request for destination: ${destType} Processed Successfully`; + + salesforceResponseHandler( + destinationResponse, + 'during Salesforce Response Handling', + destinationResponse?.rudderJobMetadata?.destInfo?.authKey, + OAUTH + ); + + // else successfully return status as 200, message and original destination response + return { + status: 200, + message, + destinationResponse, + }; +}; + +function networkHandler() { + this.responseHandler = responseHandler; + this.proxy = proxyRequest; + this.prepareProxy = prepareProxyRequest; + this.processAxiosResponse = processAxiosResponse; +} + +module.exports = { + networkHandler, +}; diff --git a/test/__tests__/facebook_conversions.test.js b/test/__tests__/facebook_conversions.test.js index a450952efe..9495a85913 100644 --- a/test/__tests__/facebook_conversions.test.js +++ b/test/__tests__/facebook_conversions.test.js @@ -23,6 +23,8 @@ const outputRouterDataFile = fs.readFileSync( const inputRouterData = JSON.parse(inputRouterDataFile); const expectedRouterData = JSON.parse(outputRouterDataFile); +Date.now = jest.fn(() => new Date("2023-11-12T15:46:51.000Z")); // 2023-11-12T15:46:51.693229+05:30 + describe(`${name} Tests`, () => { describe("Processor", () => { testData.forEach((dataPoint, index) => { diff --git a/test/integrations/destinations/salesforce/dataDelivery/data.ts b/test/integrations/destinations/salesforce/dataDelivery/data.ts index c53ce58f9e..2f1e04815b 100644 --- a/test/integrations/destinations/salesforce/dataDelivery/data.ts +++ b/test/integrations/destinations/salesforce/dataDelivery/data.ts @@ -119,7 +119,6 @@ export const data = [ body: { output: { status: 500, - authErrorCategory: 'REFRESH_TOKEN', message: 'Salesforce Request Failed - due to "INVALID_SESSION_ID", (Retryable) during Salesforce Response Handling', destinationResponse: { From a97f6db0488e4ba3e9a4b2e4cb2c87d8a23b9c77 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Tue, 5 Dec 2023 12:29:58 +0000 Subject: [PATCH 58/93] chore(release): 1.50.1 --- CHANGELOG.md | 7 +++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f990fe3b9..10f456d480 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +### [1.50.1](https://github.com/rudderlabs/rudder-transformer/compare/v1.50.0...v1.50.1) (2023-12-05) + + +### Bug Fixes + +* salesforce transformer proxy response handling issue for authorization flow ([#2873](https://github.com/rudderlabs/rudder-transformer/issues/2873)) ([4cec65e](https://github.com/rudderlabs/rudder-transformer/commit/4cec65e4103e99021f5108fcc7c557b952f1c5eb)) + ## [1.50.0](https://github.com/rudderlabs/rudder-transformer/compare/v1.49.1...v1.50.0) (2023-11-13) diff --git a/package-lock.json b/package-lock.json index 28d814c925..94246d066b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "rudder-transformer", - "version": "1.50.0", + "version": "1.50.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "rudder-transformer", - "version": "1.50.0", + "version": "1.50.1", "license": "ISC", "dependencies": { "@amplitude/ua-parser-js": "^0.7.24", diff --git a/package.json b/package.json index e4a4d9151c..60fb93acc4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rudder-transformer", - "version": "1.50.0", + "version": "1.50.1", "description": "", "homepage": "https://github.com/rudderlabs/rudder-transformer#readme", "bugs": { From be6ef2605f04e9182534b9633eeec1091cf7a431 Mon Sep 17 00:00:00 2001 From: Utsab Chowdhury Date: Wed, 6 Dec 2023 13:56:53 +0530 Subject: [PATCH 59/93] fix: add support for custom properties for braze purchase events (#2856) --- src/v0/destinations/braze/braze.util.test.js | 141 +++++++++++++++++++ src/v0/destinations/braze/config.js | 4 +- src/v0/destinations/braze/transform.js | 2 +- src/v0/destinations/braze/util.js | 7 +- test/__tests__/data/braze_input.json | 96 +++++++++++++ test/__tests__/data/braze_output.json | 71 ++++++++++ 6 files changed, 318 insertions(+), 3 deletions(-) diff --git a/src/v0/destinations/braze/braze.util.test.js b/src/v0/destinations/braze/braze.util.test.js index eb5a46fe34..9859e16152 100644 --- a/src/v0/destinations/braze/braze.util.test.js +++ b/src/v0/destinations/braze/braze.util.test.js @@ -1219,4 +1219,145 @@ describe('getPurchaseObjs', () => { ); } }); + + test('products having extra properties', () => { + const output = getPurchaseObjs( + { + properties: { + products: [ + { product_id: '123', price: 10.99, quantity: 2, random_extra_property_a: 'abc' }, + { product_id: '456', price: 5.49, quantity: 1, random_extra_property_b: 'efg' }, + { + product_id: '789', + price: 15.49, + quantity: 1, + random_extra_property_a: 'abc', + random_extra_property_b: 'efg', + random_extra_property_c: 'hij', + }, + ], + currency: 'USD', + }, + timestamp: '2023-08-04T12:34:56Z', + anonymousId: 'abc', + }, + { + sendPurchaseEventWithExtraProperties: true, + }, + ); + expect(output).toEqual([ + { + product_id: '123', + price: 10.99, + currency: 'USD', + quantity: 2, + time: '2023-08-04T12:34:56Z', + properties: { + random_extra_property_a: 'abc', + }, + _update_existing_only: false, + user_alias: { + alias_name: 'abc', + alias_label: 'rudder_id', + }, + }, + { + product_id: '456', + price: 5.49, + currency: 'USD', + quantity: 1, + time: '2023-08-04T12:34:56Z', + properties: { + random_extra_property_b: 'efg', + }, + _update_existing_only: false, + user_alias: { + alias_name: 'abc', + alias_label: 'rudder_id', + }, + }, + { + product_id: '789', + price: 15.49, + currency: 'USD', + quantity: 1, + time: '2023-08-04T12:34:56Z', + properties: { + random_extra_property_a: 'abc', + random_extra_property_b: 'efg', + random_extra_property_c: 'hij', + }, + _update_existing_only: false, + user_alias: { + alias_name: 'abc', + alias_label: 'rudder_id', + }, + }, + ]); + }); + + test('products having extra properties with sendPurchaseEventWithExtraProperties as false', () => { + const output = getPurchaseObjs( + { + properties: { + products: [ + { product_id: '123', price: 10.99, quantity: 2, random_extra_property_a: 'abc' }, + { product_id: '456', price: 5.49, quantity: 1, random_extra_property_b: 'efg' }, + { + product_id: '789', + price: 15.49, + quantity: 1, + random_extra_property_a: 'abc', + random_extra_property_b: 'efg', + random_extra_property_c: 'hij', + }, + ], + currency: 'USD', + }, + timestamp: '2023-08-04T12:34:56Z', + anonymousId: 'abc', + }, + { + sendPurchaseEventWithExtraProperties: false, + }, + ); + expect(output).toEqual([ + { + product_id: '123', + price: 10.99, + currency: 'USD', + quantity: 2, + time: '2023-08-04T12:34:56Z', + _update_existing_only: false, + user_alias: { + alias_name: 'abc', + alias_label: 'rudder_id', + }, + }, + { + product_id: '456', + price: 5.49, + currency: 'USD', + quantity: 1, + time: '2023-08-04T12:34:56Z', + _update_existing_only: false, + user_alias: { + alias_name: 'abc', + alias_label: 'rudder_id', + }, + }, + { + product_id: '789', + price: 15.49, + currency: 'USD', + quantity: 1, + time: '2023-08-04T12:34:56Z', + _update_existing_only: false, + user_alias: { + alias_name: 'abc', + alias_label: 'rudder_id', + }, + }, + ]); + }); }); diff --git a/src/v0/destinations/braze/config.js b/src/v0/destinations/braze/config.js index 2e24f43f61..2bbade2754 100644 --- a/src/v0/destinations/braze/config.js +++ b/src/v0/destinations/braze/config.js @@ -56,6 +56,7 @@ const BRAZE_NON_BILLABLE_ATTRIBUTES = [ 'subscription_groups', ]; +const BRAZE_PURCHASE_STANDARD_PROPERTIES = ['product_id', 'sku', 'price', 'quantity', 'currency']; module.exports = { ConfigCategory, mappingConfig, @@ -64,6 +65,7 @@ module.exports = { getSubscriptionGroupEndPoint, getAliasMergeEndPoint, BRAZE_PARTNER_NAME, + BRAZE_PURCHASE_STANDARD_PROPERTIES, TRACK_BRAZE_MAX_REQ_COUNT, IDENTIFY_BRAZE_MAX_REQ_COUNT, DESTINATION, @@ -71,5 +73,5 @@ module.exports = { DEL_MAX_BATCH_SIZE, BRAZE_NON_BILLABLE_ATTRIBUTES, ALIAS_BRAZE_MAX_REQ_COUNT, - SUBSCRIPTION_BRAZE_MAX_REQ_COUNT + SUBSCRIPTION_BRAZE_MAX_REQ_COUNT, }; diff --git a/src/v0/destinations/braze/transform.js b/src/v0/destinations/braze/transform.js index b939e1f414..38a5947ded 100644 --- a/src/v0/destinations/braze/transform.js +++ b/src/v0/destinations/braze/transform.js @@ -315,7 +315,7 @@ function processTrackEvent(messageType, message, destination, mappingJson, proce typeof eventName === 'string' && eventName.toLowerCase() === 'order completed' ) { - const purchaseObjs = getPurchaseObjs(message); + const purchaseObjs = getPurchaseObjs(message, destination.Config); // del used properties delete properties.products; diff --git a/src/v0/destinations/braze/util.js b/src/v0/destinations/braze/util.js index 9b5d57d6bc..3b0855b338 100644 --- a/src/v0/destinations/braze/util.js +++ b/src/v0/destinations/braze/util.js @@ -21,6 +21,7 @@ const { SUBSCRIPTION_BRAZE_MAX_REQ_COUNT, ALIAS_BRAZE_MAX_REQ_COUNT, TRACK_BRAZE_MAX_REQ_COUNT, + BRAZE_PURCHASE_STANDARD_PROPERTIES, } = require('./config'); const { JSON_MIME_TYPE, HTTP_STATUS_CODES } = require('../../util/constant'); const { isObject } = require('../../util'); @@ -539,7 +540,7 @@ function addMandatoryPurchaseProperties(productId, price, currencyCode, quantity }; } -function getPurchaseObjs(message) { +function getPurchaseObjs(message, config) { // ref:https://www.braze.com/docs/api/objects_filters/purchase_object/ const validateForPurchaseEvent = (message) => { const { properties } = message; @@ -634,6 +635,10 @@ function getPurchaseObjs(message) { parseInt(quantity, 10), timestamp, ); + const extraProperties = _.omit(product, BRAZE_PURCHASE_STANDARD_PROPERTIES); + if (Object.keys(extraProperties).length > 0 && config.sendPurchaseEventWithExtraProperties) { + purchaseObj = { ...purchaseObj, properties: extraProperties }; + } purchaseObj = setExternalIdOrAliasObject(purchaseObj, message); purchaseObjs.push(purchaseObj); }); diff --git a/test/__tests__/data/braze_input.json b/test/__tests__/data/braze_input.json index e799cf2e82..8c3294e42b 100644 --- a/test/__tests__/data/braze_input.json +++ b/test/__tests__/data/braze_input.json @@ -1814,5 +1814,101 @@ "type": "track", "userId": "mickeyMouse" } + }, + { + "destination": { + "Config": { + "restApiKey": "dummyApiKey", + "prefixProperties": true, + "useNativeSDK": false, + "sendPurchaseEventWithExtraProperties": true + }, + "DestinationDefinition": { + "DisplayName": "Braze", + "ID": "1WhbSZ6uA3H5ChVifHpfL2H6sie", + "Name": "BRAZE" + }, + "Enabled": true, + "ID": "1WhcOCGgj9asZu850HvugU2C3Aq", + "Name": "Braze", + "Transformations": [] + }, + "message": { + "anonymousId": "e6ab2c5e-2cda-44a9-a962-e2f67df78bca", + "channel": "web", + "context": { + "app": { + "build": "1.0.0", + "name": "RudderLabs JavaScript SDK", + "namespace": "com.rudderlabs.javascript", + "version": "1.0.5" + }, + "ip": "0.0.0.0", + "library": { + "name": "RudderLabs JavaScript SDK", + "version": "1.0.5" + }, + "locale": "en-GB", + "os": { + "name": "", + "version": "" + }, + "screen": { + "density": 2 + }, + "traits": { + "city": "Disney", + "country": "USA", + "email": "mickey@disney.com", + "firstname": "Mickey" + }, + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36" + }, + "event": "Order Completed", + "integrations": { + "All": true + }, + "messageId": "aa5f5e44-8756-40ad-ad1e-b0d3b9fa710a", + "originalTimestamp": "2020-01-24T06:29:02.367Z", + "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": 0, + "product_id": "507f1f77bcf86cd799439023", + "quantity": 1, + "sku": "45790-32", + "url": "https://www.example.com/product/path" + }, + { + "category": "Games", + "name": "Uno Card Game", + "price": 0, + "product_id": "505bd76785ebb509fc183724", + "quantity": 2, + "sku": "46493-32" + } + ], + "revenue": 25, + "shipping": 3, + "subtotal": 22.5, + "tax": 2, + "total": 27.5 + }, + "receivedAt": "2020-01-24T11:59:02.403+05:30", + "request_ip": "[::1]:53712", + "sentAt": "2020-01-24T06:29:02.368Z", + "timestamp": "2020-01-24T11:59:02.402+05:30", + "type": "track", + "userId": "" + } } ] diff --git a/test/__tests__/data/braze_output.json b/test/__tests__/data/braze_output.json index 10c42b1064..0575326237 100644 --- a/test/__tests__/data/braze_output.json +++ b/test/__tests__/data/braze_output.json @@ -963,5 +963,76 @@ }, "files": {}, "userId": "mickeyMouse" + }, + { + "body": { + "FORM": {}, + "JSON": { + "attributes": [ + { + "_update_existing_only": false, + "city": "Disney", + "country": "USA", + "email": "mickey@disney.com", + "firstname": "Mickey", + "user_alias": { + "alias_label": "rudder_id", + "alias_name": "e6ab2c5e-2cda-44a9-a962-e2f67df78bca" + } + } + ], + "partner": "RudderStack", + "purchases": [ + { + "_update_existing_only": false, + "currency": "USD", + "price": 0, + "product_id": "507f1f77bcf86cd799439023", + "properties": { + "category": "Games", + "image_url": "https:///www.example.com/product/path.jpg", + "name": "Monopoly: 3rd Edition", + "url": "https://www.example.com/product/path" + }, + "quantity": 1, + "time": "2020-01-24T11:59:02.402+05:30", + "user_alias": { + "alias_label": "rudder_id", + "alias_name": "e6ab2c5e-2cda-44a9-a962-e2f67df78bca" + } + }, + { + "_update_existing_only": false, + "currency": "USD", + "price": 0, + "product_id": "505bd76785ebb509fc183724", + "properties": { + "category": "Games", + "name": "Uno Card Game" + }, + "quantity": 2, + "time": "2020-01-24T11:59:02.402+05:30", + "user_alias": { + "alias_label": "rudder_id", + "alias_name": "e6ab2c5e-2cda-44a9-a962-e2f67df78bca" + } + } + ] + }, + "JSON_ARRAY": {}, + "XML": {} + }, + "endpoint": "https://rest.fra-01.braze.eu/users/track", + "files": {}, + "headers": { + "Accept": "application/json", + "Authorization": "Bearer dummyApiKey", + "Content-Type": "application/json" + }, + "method": "POST", + "params": {}, + "type": "REST", + "userId": "e6ab2c5e-2cda-44a9-a962-e2f67df78bca", + "version": "1" } ] From 669ed41702d267e90bab69f98dc7b5f984df44d8 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Wed, 6 Dec 2023 10:14:39 +0000 Subject: [PATCH 60/93] chore(release): 1.51.0 --- CHANGELOG.md | 26 ++++++++++++++++++++++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 10f456d480..451051777d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,32 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +## [1.51.0](https://github.com/rudderlabs/rudder-transformer/compare/v1.50.1...v1.51.0) (2023-12-06) + + +### Features + +* cm360 router batching ([#2836](https://github.com/rudderlabs/rudder-transformer/issues/2836)) ([4b260e4](https://github.com/rudderlabs/rudder-transformer/commit/4b260e4ec6d25875903830004b3e4975b3402b2d)) +* cm360 transformerproxy V1 flag ([#2848](https://github.com/rudderlabs/rudder-transformer/issues/2848)) ([27f0797](https://github.com/rudderlabs/rudder-transformer/commit/27f0797c6dcd626a713c11a48c6e85a69e0a4963)) +* **INT-305:** onboard gladly destination ([#2786](https://github.com/rudderlabs/rudder-transformer/issues/2786)) ([ff80b88](https://github.com/rudderlabs/rudder-transformer/commit/ff80b885fe0507c137b3c9eacffcef331010da0c)) +* marketo: migrate config fields and fix test cases ([#2789](https://github.com/rudderlabs/rudder-transformer/issues/2789)) ([7910dba](https://github.com/rudderlabs/rudder-transformer/commit/7910dba2318f92cec3be1b7c7aa6b00428ecae94)) +* mixpanel set once feature onboard ([#2820](https://github.com/rudderlabs/rudder-transformer/issues/2820)) ([9eda50e](https://github.com/rudderlabs/rudder-transformer/commit/9eda50e850c5a1ccb46f1b54c3d176edb915eb27)) +* onboard webhook to component tests ([#2837](https://github.com/rudderlabs/rudder-transformer/issues/2837)) ([284d141](https://github.com/rudderlabs/rudder-transformer/commit/284d1411514c26dda2403a4a18967e5f40e255ea)) +* update facebook destinations API version to v18.0 ([#2828](https://github.com/rudderlabs/rudder-transformer/issues/2828)) ([3127a1c](https://github.com/rudderlabs/rudder-transformer/commit/3127a1ca8dc1b887f9158a1d839c5504f40c4678)) + + +### Bug Fixes + +* add support for custom properties for braze purchase events ([#2856](https://github.com/rudderlabs/rudder-transformer/issues/2856)) ([be6ef26](https://github.com/rudderlabs/rudder-transformer/commit/be6ef2605f04e9182534b9633eeec1091cf7a431)) +* bugsnag issue in moengage identify event ([#2845](https://github.com/rudderlabs/rudder-transformer/issues/2845)) ([0e7adc6](https://github.com/rudderlabs/rudder-transformer/commit/0e7adc66ff88d9510e48a5651460b4e02cc57c78)) +* encode &, < and > to html counterparts in adobe analytics ([#2854](https://github.com/rudderlabs/rudder-transformer/issues/2854)) ([571dbf5](https://github.com/rudderlabs/rudder-transformer/commit/571dbf5bd65e7d0e261562ff3da3b393f27f27b6)) +* error handling in active_campaign ([#2843](https://github.com/rudderlabs/rudder-transformer/issues/2843)) ([a015460](https://github.com/rudderlabs/rudder-transformer/commit/a015460f0a6d2d5320f633abc151febf22561b6b)) +* make supportTransformerProxyV1 false ([#2861](https://github.com/rudderlabs/rudder-transformer/issues/2861)) ([80cf69d](https://github.com/rudderlabs/rudder-transformer/commit/80cf69dc40bb4dc7c0a6d516814f36d962018745)) +* remove errorCategory for braze dedup error ([#2850](https://github.com/rudderlabs/rudder-transformer/issues/2850)) ([91d4cd1](https://github.com/rudderlabs/rudder-transformer/commit/91d4cd16f9839b0be5a663ca5010bdd72cff9bdc)) +* sfmc bug fix for track event validations ([#2852](https://github.com/rudderlabs/rudder-transformer/issues/2852)) ([cd9a046](https://github.com/rudderlabs/rudder-transformer/commit/cd9a046f66eab8363373cb9a0fa1afeef3137d78)) +* unhandled error code in facebook_custom_audience ([#2853](https://github.com/rudderlabs/rudder-transformer/issues/2853)) ([8c02b8c](https://github.com/rudderlabs/rudder-transformer/commit/8c02b8ccb2101147ac84b4555e7fd07235ebf9fc)) +* updated transformerProxyV1 name ([#2859](https://github.com/rudderlabs/rudder-transformer/issues/2859)) ([1a8d825](https://github.com/rudderlabs/rudder-transformer/commit/1a8d825ccbb87d34d8ae5ff2cb02f4be9700eee6)) + ### [1.50.1](https://github.com/rudderlabs/rudder-transformer/compare/v1.50.0...v1.50.1) (2023-12-05) diff --git a/package-lock.json b/package-lock.json index 4c8438e746..24e6a3bc3a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "rudder-transformer", - "version": "1.50.1", + "version": "1.51.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "rudder-transformer", - "version": "1.50.1", + "version": "1.51.0", "license": "ISC", "dependencies": { "@amplitude/ua-parser-js": "^0.7.24", diff --git a/package.json b/package.json index b5a9bd9e57..457c0eecf2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rudder-transformer", - "version": "1.50.1", + "version": "1.51.0", "description": "", "homepage": "https://github.com/rudderlabs/rudder-transformer#readme", "bugs": { From cd6c3b0672a0b17078627f28f6613a2ef1898ee7 Mon Sep 17 00:00:00 2001 From: Anant Jain Date: Mon, 4 Dec 2023 14:15:18 +0530 Subject: [PATCH 61/93] fix: marketo new field introduction backward compatibility --- src/v0/destinations/marketo/config.js | 18 ++++++------------ test/__tests__/data/marketo_input.json | 13 +++++++++---- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/v0/destinations/marketo/config.js b/src/v0/destinations/marketo/config.js index 16449ebbad..604be41dc0 100644 --- a/src/v0/destinations/marketo/config.js +++ b/src/v0/destinations/marketo/config.js @@ -14,24 +14,18 @@ const DESTINATION = 'marketo'; const formatConfig = (destination) => ({ ID: destination.ID, ...destination.Config, - customActivityEventMap: getHashFromArray( - destination.Config.rudderEventsMapping, - 'event', - 'marketoActivityId', - false, - ), + customActivityEventMap: destination.Config?.rudderEventsMapping + ? getHashFromArray(destination.Config.rudderEventsMapping, 'event', 'marketoActivityId', false) + : getHashFromArray(destination.Config.customActivityEventMap, 'from', 'to', false), customActivityPropertyMap: getHashFromArray( destination.Config.customActivityPropertyMap, 'from', 'to', false, ), - customActivityPrimaryKeyMap: getHashFromArray( - destination.Config.rudderEventsMapping, - 'event', - 'marketoPrimarykey', - false, - ), + customActivityPrimaryKeyMap: destination.Config?.rudderEventsMapping + ? getHashFromArray(destination.Config.rudderEventsMapping, 'event', 'marketoPrimarykey', false) + : getHashFromArray(destination.Config.customActivityPrimaryKeyMap, 'from', 'to', false), leadTraitMapping: getHashFromArray(destination.Config.leadTraitMapping, 'from', 'to', false), responseRules: destination.DestinationDefinition ? destination.DestinationDefinition.ResponseRules diff --git a/test/__tests__/data/marketo_input.json b/test/__tests__/data/marketo_input.json index 6a891fdea0..10fff935fc 100644 --- a/test/__tests__/data/marketo_input.json +++ b/test/__tests__/data/marketo_input.json @@ -170,11 +170,16 @@ } ], "createIfNotExist": true, - "rudderEventsMapping": [ + "customActivityPrimaryKeyMap": [ { - "event": "Product Clicked", - "marketoPrimarykey": "name", - "marketoActivityId": "100001" + "from": "Product Clicked", + "to": "name" + } + ], + "customActivityEventMap": [ + { + "from": "Product Clicked", + "to": "100001" } ] } From b13f0a6340177a56417692ad7dcf3829d4990826 Mon Sep 17 00:00:00 2001 From: AASHISH MALIK Date: Mon, 4 Dec 2023 17:00:24 +0530 Subject: [PATCH 62/93] fix: remove ErrorResponse type from postTransfomration delivery --- src/services/destination/postTransformation.ts | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/services/destination/postTransformation.ts b/src/services/destination/postTransformation.ts index 1e99961045..dc5ab0644d 100644 --- a/src/services/destination/postTransformation.ts +++ b/src/services/destination/postTransformation.ts @@ -148,7 +148,7 @@ export class DestinationPostTransformationService { } public static handleDeliveryFailureEvents( - error: ErrorResponse, + error: NonNullable, metaTo: MetaTransferObject, ): DeliveryResponse { const errObj = generateErrorObject(error, metaTo.errorDetails, false); @@ -161,12 +161,6 @@ export class DestinationPostTransformationService { authErrorCategory: errObj.authErrorCategory, }), } as DeliveryResponse; - - // for transformer-proxy to maintain contract - const { response } = error; - if (response) { - resp.response = response; - } ErrorReportingService.reportError(error, metaTo.errorContext, resp); return resp; } From 24a2cd4d025b5ce01ef32a0ff3b0a43d340dd11d Mon Sep 17 00:00:00 2001 From: Utsab Chowdhury Date: Wed, 6 Dec 2023 16:32:48 +0530 Subject: [PATCH 63/93] chore: cleanup of postTransformation.ts --- src/services/destination/postTransformation.ts | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/services/destination/postTransformation.ts b/src/services/destination/postTransformation.ts index dc5ab0644d..0b91eb7cc1 100644 --- a/src/services/destination/postTransformation.ts +++ b/src/services/destination/postTransformation.ts @@ -16,15 +16,6 @@ import { ErrorReportingService } from '../errorReporting'; import tags from '../../v0/util/tags'; import stats from '../../util/stats'; -type ErrorResponse = { - status?: number; - message?: string; - destinationResponse?: object; - statTags?: object; - authErrorCategory?: string | undefined; - response?: object | undefined; -}; - export class DestinationPostTransformationService { public static handleProcessorTransformSucessEvents( event: ProcessorTransformationRequest, From 45db59067d2272d13b08c355740707e7e53a3458 Mon Sep 17 00:00:00 2001 From: Sankeerth Date: Wed, 6 Dec 2023 16:36:14 +0530 Subject: [PATCH 64/93] chore: remove logging in tiktok_audience (#2864) --- src/cdk/v2/destinations/tiktok_audience/rtWorkflow.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/src/cdk/v2/destinations/tiktok_audience/rtWorkflow.yaml b/src/cdk/v2/destinations/tiktok_audience/rtWorkflow.yaml index 3db4c405ad..a7fa855938 100644 --- a/src/cdk/v2/destinations/tiktok_audience/rtWorkflow.yaml +++ b/src/cdk/v2/destinations/tiktok_audience/rtWorkflow.yaml @@ -13,7 +13,6 @@ steps: loopOverInput: true - name: successfulEvents - debug: true template: | $.outputs.transform#idx{"output" in .}.({ "batchedRequest": .output, From 6dd0eb21a87246d9d04172715f24f09cdc50044a Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Wed, 6 Dec 2023 11:19:32 +0000 Subject: [PATCH 65/93] chore(release): 1.51.1 --- CHANGELOG.md | 9 +++++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 451051777d..b769b51a6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,15 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +### [1.51.1](https://github.com/rudderlabs/rudder-transformer/compare/v1.51.0...v1.51.1) (2023-12-06) + + +### Bug Fixes + +* marketo backward compatibility ([#2880](https://github.com/rudderlabs/rudder-transformer/issues/2880)) ([af6aebb](https://github.com/rudderlabs/rudder-transformer/commit/af6aebba9a9891fadc91fe2dc4ae4db4b1e269c9)) +* marketo new field introduction backward compatibility ([cd6c3b0](https://github.com/rudderlabs/rudder-transformer/commit/cd6c3b0672a0b17078627f28f6613a2ef1898ee7)) +* remove ErrorResponse type from postTransfomration delivery ([b13f0a6](https://github.com/rudderlabs/rudder-transformer/commit/b13f0a6340177a56417692ad7dcf3829d4990826)) + ## [1.51.0](https://github.com/rudderlabs/rudder-transformer/compare/v1.50.1...v1.51.0) (2023-12-06) diff --git a/package-lock.json b/package-lock.json index 24e6a3bc3a..27655f81ef 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "rudder-transformer", - "version": "1.51.0", + "version": "1.51.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "rudder-transformer", - "version": "1.51.0", + "version": "1.51.1", "license": "ISC", "dependencies": { "@amplitude/ua-parser-js": "^0.7.24", diff --git a/package.json b/package.json index 457c0eecf2..a36ac26e9c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rudder-transformer", - "version": "1.51.0", + "version": "1.51.1", "description": "", "homepage": "https://github.com/rudderlabs/rudder-transformer#readme", "bugs": { From 71317919aa101e2350b6d4cb58f78e9157298bfd Mon Sep 17 00:00:00 2001 From: Anant Jain <62471433+anantjain45823@users.noreply.github.com> Date: Thu, 7 Dec 2023 11:37:12 +0530 Subject: [PATCH 66/93] chore: add stats for shopify Id resolution (#2885) chore: add stats for shopify anonId resolution based on shopifyTopic and method --- src/util/prometheus.js | 6 ++++++ src/v0/sources/shopify/transform.js | 2 +- src/v0/sources/shopify/util.js | 11 +++++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/util/prometheus.js b/src/util/prometheus.js index 116f77d214..ec8ad61789 100644 --- a/src/util/prometheus.js +++ b/src/util/prometheus.js @@ -487,6 +487,12 @@ class Prometheus { type: 'counter', labelNames: ['type', 'writeKey', 'source'], }, + { + name: 'shopify_anon_id_resolve', + help: 'shopify_anon_id_resolve', + type: 'counter', + labelNames: ['method', 'writeKey', 'shopifyTopic'], + }, { name: 'shopify_redis_calls', help: 'shopify_redis_calls', diff --git a/src/v0/sources/shopify/transform.js b/src/v0/sources/shopify/transform.js index fd763eeb46..013580d7a3 100644 --- a/src/v0/sources/shopify/transform.js +++ b/src/v0/sources/shopify/transform.js @@ -175,7 +175,7 @@ const processEvent = async (inputEvent, metricMetadata) => { if (message.type !== EventType.IDENTIFY) { const { anonymousId, sessionId } = await getAnonymousIdAndSessionId( message, - metricMetadata, + { shopifyTopic, ...metricMetadata }, redisData, ); if (isDefinedAndNotNull(anonymousId)) { diff --git a/src/v0/sources/shopify/util.js b/src/v0/sources/shopify/util.js index 61501bdab6..6f31ade4a7 100644 --- a/src/v0/sources/shopify/util.js +++ b/src/v0/sources/shopify/util.js @@ -164,6 +164,10 @@ const getAnonymousIdAndSessionId = async (message, metricMetadata, redisData = n } // falling back to cartToken mapping or its hash in case no rudderAnonymousId or rudderSessionId is found if (isDefinedAndNotNull(anonymousId) && isDefinedAndNotNull(sessionId)) { + stats.increment('shopify_anon_id_resolve', { + method: 'note_attributes', + ...metricMetadata, + }); return { anonymousId, sessionId }; } const cartToken = getCartToken(message); @@ -189,6 +193,13 @@ const getAnonymousIdAndSessionId = async (message, metricMetadata, redisData = n Hash the id and use it as anonymousId (limiting 256 -> 36 chars) and sessionId is not sent as its not required field */ anonymousId = v5(cartToken, v5.URL); + } else { + // This metric let us know how many events based on event name used redis for anonId resolution + // and for how many + stats.increment('shopify_anon_id_resolve', { + method: 'database', + ...metricMetadata, + }); } return { anonymousId, sessionId }; }; From b3437a34358d5fd5b1eb63f30a5a695f39aa84ff Mon Sep 17 00:00:00 2001 From: Abhimanyu Babbar Date: Thu, 7 Dec 2023 14:45:33 +0530 Subject: [PATCH 67/93] fix(dm): add workspaceId in common metadata to be returned to the callers (#2868) Add workspaceId in common metadata to be returned to the callers --- src/services/userTransform.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/services/userTransform.ts b/src/services/userTransform.ts index ddd5c82f67..bf34e3d82a 100644 --- a/src/services/userTransform.ts +++ b/src/services/userTransform.ts @@ -65,6 +65,7 @@ export class UserTransformService { sourceId: eventsToProcess[0]?.metadata?.sourceId, destinationId: eventsToProcess[0]?.metadata.destinationId, destinationType: eventsToProcess[0]?.metadata.destinationType, + workspaceId: eventsToProcess[0]?.metadata.workspaceId, messageIds, }; From c8e5bfb34240d092fb8979f916ac770c667fb652 Mon Sep 17 00:00:00 2001 From: Anant Jain <62471433+anantjain45823@users.noreply.github.com> Date: Fri, 8 Dec 2023 10:19:01 +0530 Subject: [PATCH 68/93] chore: add user deletion stats for regulation worker at destType level (#2884) --- src/services/destination/nativeIntegration.ts | 7 +++++++ src/services/destination/postTransformation.ts | 2 +- src/util/prometheus.js | 18 +++++++++++++++--- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/services/destination/nativeIntegration.ts b/src/services/destination/nativeIntegration.ts index 510fa80362..6bb79ce27a 100644 --- a/src/services/destination/nativeIntegration.ts +++ b/src/services/destination/nativeIntegration.ts @@ -18,6 +18,7 @@ import { DestinationPostTransformationService } from './postTransformation'; import networkHandlerFactory from '../../adapters/networkHandlerFactory'; import { FetchHandler } from '../../helpers/fetchHandlers'; import tags from '../../v0/util/tags'; +import stats from '../../util/stats'; export class NativeIntegrationDestinationService implements DestinationService { public init() {} @@ -203,6 +204,7 @@ export class NativeIntegrationDestinationService implements DestinationService { ): Promise { const response = await Promise.all( requests.map(async (request) => { + const startTime = new Date(); const { destType } = request; const destUserDeletionHandler: any = FetchHandler.getDeletionHandler( destType.toLowerCase(), @@ -219,6 +221,11 @@ export class NativeIntegrationDestinationService implements DestinationService { ...request, rudderDestInfo, }); + stats.timing('regulation_worker_requests_dest_latency', startTime, { + feature: tags.FEATURES.USER_DELETION, + implementation: tags.IMPLEMENTATIONS.NATIVE, + destType, + }); return result; } catch (error: any) { const metaTO = this.getTags(destType, 'unknown', 'unknown', tags.FEATURES.USER_DELETION); diff --git a/src/services/destination/postTransformation.ts b/src/services/destination/postTransformation.ts index 0b91eb7cc1..076f5ba55e 100644 --- a/src/services/destination/postTransformation.ts +++ b/src/services/destination/postTransformation.ts @@ -161,7 +161,7 @@ export class DestinationPostTransformationService { metaTo: MetaTransferObject, ): UserDeletionResponse { const errObj = generateErrorObject(error, metaTo.errorDetails, false); - // TODO: Add stat tags here + stats.increment('regulation_worker_user_deletion_failure', metaTo.errorDetails); const resp = { statusCode: errObj.status, error: errObj.message, diff --git a/src/util/prometheus.js b/src/util/prometheus.js index ec8ad61789..d7ba3b7c61 100644 --- a/src/util/prometheus.js +++ b/src/util/prometheus.js @@ -451,6 +451,12 @@ class Prometheus { type: 'counter', labelNames: ['writeKey', 'timestamp'], }, + { + name: 'regulation_worker_user_deletion_failure', + help: 'regulation_worker_user_deletion_failure', + type: 'counter', + labelNames: ['destType', 'module', 'implementation', 'feature'], + }, { name: 'shopify_server_side_identifier_event', help: 'shopify_server_side_identifier_event', @@ -605,6 +611,12 @@ class Prometheus { type: 'histogram', labelNames: ['sourceType', 'destinationType', 'k8_namespace'], }, + { + name: 'regulation_worker_requests_dest_latency', + help: 'regulation_worker_requests_dest_latency', + type: 'histogram', + labelNames: ['feature', 'implementation', 'destType'], + }, { name: 'dest_transform_request_latency', help: 'dest_transform_request_latency', @@ -924,7 +936,7 @@ class Prometheus { 'errored', 'statusCode', 'transformationId', - 'workspaceId' + 'workspaceId', ], }, { @@ -940,9 +952,9 @@ class Prometheus { 'errored', 'statusCode', 'transformationId', - 'workspaceId' + 'workspaceId', ], - } + }, ]; metrics.forEach((metric) => { From babb89a5bf6d1b84d1319b967953c7c1b6de7c2c Mon Sep 17 00:00:00 2001 From: Ujjwal Abhishek <63387036+ujjwal-ab@users.noreply.github.com> Date: Mon, 11 Dec 2023 09:43:04 +0530 Subject: [PATCH 69/93] feat: onboard reddit cloud mode destination (#2829) * feat: onboard reddit cloud mode destination * feat: update mappings * feat: add event_type support * feat: add batching support * feat: add reddit to features.json * feat: refactor code * fix: add check for empty string in eventName * fix: use generic mapping for timestamp * chore: add test cases * fix: refactor code * fix: refactor code * feat: add networkHandler * feat: refactor networkHandler * chore: add delivery tests * fix: add additional check for accessToken failure * fix: remove extra parameter from retryable error --- src/cdk/v2/destinations/reddit/config.js | 31 + .../v2/destinations/reddit/procWorkflow.yaml | 135 ++ .../v2/destinations/reddit/rtWorkflow.yaml | 67 + src/cdk/v2/destinations/reddit/utils.js | 33 + src/features.json | 3 +- src/v0/destinations/reddit/networkHandler.js | 50 + .../destinations/reddit/delivery/data.ts | 174 ++ .../destinations/reddit/network.ts | 100 ++ .../destinations/reddit/processor/data.ts | 1532 +++++++++++++++++ .../destinations/reddit/router/data.ts | 502 ++++++ 10 files changed, 2626 insertions(+), 1 deletion(-) create mode 100644 src/cdk/v2/destinations/reddit/config.js create mode 100644 src/cdk/v2/destinations/reddit/procWorkflow.yaml create mode 100644 src/cdk/v2/destinations/reddit/rtWorkflow.yaml create mode 100644 src/cdk/v2/destinations/reddit/utils.js create mode 100644 src/v0/destinations/reddit/networkHandler.js create mode 100644 test/integrations/destinations/reddit/delivery/data.ts create mode 100644 test/integrations/destinations/reddit/network.ts create mode 100644 test/integrations/destinations/reddit/processor/data.ts create mode 100644 test/integrations/destinations/reddit/router/data.ts diff --git a/src/cdk/v2/destinations/reddit/config.js b/src/cdk/v2/destinations/reddit/config.js new file mode 100644 index 0000000000..5c2c778ea5 --- /dev/null +++ b/src/cdk/v2/destinations/reddit/config.js @@ -0,0 +1,31 @@ +const ENDPOINT = 'https://ads-api.reddit.com/api/v2.0/conversions/events/'; +const maxBatchSize = 1000; + +const ecomEventMaps = [ + { + src: ['product viewed', 'product list viewed'], + dest: 'ViewContent', + }, + { + src: ['product added'], + dest: 'AddToCart', + }, + { + src: ['product added to wishlist'], + dest: 'AddToWishlist', + }, + { + src: ['order completed'], + dest: 'Purchase', + }, + { + src: ['products searched'], + dest: 'Search', + }, +]; + +module.exports = { + ENDPOINT, + maxBatchSize, + ecomEventMaps, +}; diff --git a/src/cdk/v2/destinations/reddit/procWorkflow.yaml b/src/cdk/v2/destinations/reddit/procWorkflow.yaml new file mode 100644 index 0000000000..b07aeff962 --- /dev/null +++ b/src/cdk/v2/destinations/reddit/procWorkflow.yaml @@ -0,0 +1,135 @@ +bindings: + - name: EventType + path: ../../../../constants + - path: ../../bindings/jsontemplate + exportAll: true + - path: ./config + - name: removeUndefinedAndNullValues + path: ../../../../v0/util + - name: defaultRequestConfig + path: ../../../../v0/util + - name: isAppleFamily + path: ../../../../v0/util/index + - name: OAuthSecretError + path: '@rudderstack/integrations-lib' + +steps: + - name: validateInput + template: | + let messageType = .message.type; + $.assertConfig(.destination.Config.accountId, "Account is not present. Aborting message."); + $.assert(.message.type, "message Type is not present. Aborting message."); + $.assert(.message.type.toLowerCase() ==='track', "Event type " + .message.type.toLowerCase() + " is not supported. Aborting message."); + $.assert(.message.event, "Event is not present. Aborting message."); + $.assert(.message.().({{{{$.getGenericPaths("timestamp")}}}}), "Timestamp is not present. Aborting message."); + + - name: messageType + template: | + .message.type.toLowerCase() + + - name: prepareTrackPayload + condition: $.outputs.messageType === {{$.EventType.TRACK}} + steps: + - name: prepareUserObject + template: | + 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), + "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, + "opt_out": .properties.optOut, + "screen_dimensions": {"width": .context.screen.width, "height": .context.screen.height}, + }); + $.removeUndefinedAndNullValues(user) + + - name: eventType + template: | + let event = .message.event; + let eventInLowerCase = event.trim().toLowerCase();; + let eventNames = .destination.Config.eventsMapping.(){.from === event}.to[] ?? []; + eventNames.length === 0 ? eventNames = $.ecomEventMaps.(){eventInLowerCase in .src}.dest[] ?? []; + const event_type = (eventNames.length === 0 || eventNames[0]==="") ? ({"tracking_type": "Custom", "custom_event_name": event}): ({tracking_type: eventNames[0]}); + + - name: customFields + condition: $.outputs.eventType.tracking_type === "Purchase" + template: | + const customFields = .message.().({ + "currency": .properties.currency, + "value": .properties.revenue !== undefined ? Number(.properties.revenue) : undefined, + "item_count": (Array.isArray(.properties.products) && .properties.products.length) || (.properties.itemCount && Number(.properties.itemCount)), + "value_decimal": .properties.revenue !== undefined ? Number(.properties.revenue)/100 : undefined, + "conversion_id": .properties.conversionId || .messageId, + }); + $.removeUndefinedAndNullValues(customFields) + else: + name: nonRevenueTypeEvents + template: | + const customFields = .message.().({ + "conversion_id": .properties.conversionId || .messageId, + }); + $.removeUndefinedAndNullValues(customFields) + + - name: productFields + condition: .message.properties.products + description: When event contains multiple products + template: | + let products = .message.properties.products; + { + "item_count": $.sum(products.quantity.(Number(.))[]) || 0, + "products": .message.properties@prop.products.({ + "id": .product_id ?? prop.product_id, + "name": .name ?? prop.name, + "category": .category ?? prop.category, + })[] + } + else: + name: singleProductFields + template: | + const props = .message.properties; + const output = { + "item_count": Number(props.quantity) || 0, + "products": { + "id": props.product_id, + "name": props.name, + "category": props.category, + }[] + }; + - name: combineAllEcomFields + template: | + {...$.outputs.prepareTrackPayload.productFields, ...$.outputs.prepareTrackPayload.customFields} + + - name: prepareFinalPayload + template: | + { + events: [{ + "click_id": .message.properties.clickId, + "event_at": .message.().({{{{$.getGenericPaths("timestamp")}}}}), + "event_type": $.outputs.prepareTrackPayload.eventType, + "user": $.outputs.prepareTrackPayload.prepareUserObject, + "event_metadata": $.outputs.prepareTrackPayload.combineAllEcomFields, + }] + } + + - name: payload + condition: $.outputs.messageType === {{$.EventType.TRACK}} + template: | + const outputPayload = $.outputs.prepareTrackPayload + + - name: buildResponseForProcessTransformation + description: build response + template: | + $.assertThrow((.metadata.secret && .metadata.secret.accessToken), new $.OAuthSecretError("Secret or accessToken is not present in the metadata")) + const accessToken = .metadata.secret.accessToken + const response = $.defaultRequestConfig(); + response.body.JSON = $.outputs.payload; + response.headers = { + "Authorization": "Bearer "+ accessToken, + "Content-Type": "application/json" + } + response.endpoint = $.ENDPOINT+.destination.Config.accountId; + finalResponse = response; diff --git a/src/cdk/v2/destinations/reddit/rtWorkflow.yaml b/src/cdk/v2/destinations/reddit/rtWorkflow.yaml new file mode 100644 index 0000000000..937ff021f4 --- /dev/null +++ b/src/cdk/v2/destinations/reddit/rtWorkflow.yaml @@ -0,0 +1,67 @@ +bindings: + - path: ./utils + - path: ./config + +steps: + - name: validateInput + template: | + $.assert(Array.isArray(^) && ^.length > 0, "Invalid event array") + + - name: transform + externalWorkflow: + path: ./procWorkflow.yaml + bindings: + - name: batchMode + value: true + loopOverInput: true + - name: successfulEvents + template: | + $.outputs.transform#idx.output.({ + "message": .[], + "destination": ^ [idx].destination, + "metadata": ^ [idx].metadata + })[] + - name: failedEvents + template: | + $.outputs.transform#idx.error.({ + "metadata": ^[idx].metadata[], + "destination": ^[idx].destination, + "batched": false, + "statusCode": .status, + "error": .message, + "statTags": .originalError.statTags + })[] + + - name: batchSuccessfulEvents + description: Batches the successfulEvents using endpoint + condition: $.outputs.successfulEvents.length + template: | + let batches = $.batchEvents($.outputs.successfulEvents); + batches@batch.({ + "batchedRequest": { + "body": { + "JSON": batch.message.body.JSON, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "version": "1", + "type": "REST", + "method": "POST", + "endpoint": batch.message.endpoint, + "headers": batch.message.headers, + "params": {}, + "files": {} + }, + "metadata": batch.metadata, + "batched": true, + "statusCode": 200, + "destination": batch.destination + })[]; + else: + name: returnEmptyOuput + template: '[]' + + - name: finalPayload + template: | + [...$.outputs.batchSuccessfulEvents, ...$.outputs.failedEvents] diff --git a/src/cdk/v2/destinations/reddit/utils.js b/src/cdk/v2/destinations/reddit/utils.js new file mode 100644 index 0000000000..c108603235 --- /dev/null +++ b/src/cdk/v2/destinations/reddit/utils.js @@ -0,0 +1,33 @@ +const lodash = require('lodash'); +const { maxBatchSize } = require('./config'); + +const batchEventChunks = (eventChunks) => { + const batchedEvents = []; + if (Array.isArray(eventChunks)) { + eventChunks.forEach((chunk) => { + const response = { destination: chunk[0].destination }; + chunk.forEach((event, index) => { + if (index === 0) { + const [firstMessage] = event.message; + response.message = firstMessage; + response.destination = event.destination; + response.metadata = [event.metadata]; + } else { + response.message.body.JSON.events.push(...event.message[0].body.JSON.events); + response.metadata.push(event.metadata); + } + }); + batchedEvents.push(response); + }); + } + return batchedEvents; +}; + +const batchEvents = (successfulEvents) => { + const eventChunks = lodash.chunk(successfulEvents, maxBatchSize); + const batchedEvents = batchEventChunks(eventChunks); + return batchedEvents; +}; +module.exports = { + batchEvents, +}; diff --git a/src/features.json b/src/features.json index 0d2d71bbd9..a3d29bb325 100644 --- a/src/features.json +++ b/src/features.json @@ -62,7 +62,8 @@ "ORTTO": true, "GLADLY": true, "ONE_SIGNAL": true, - "TIKTOK_AUDIENCE": true + "TIKTOK_AUDIENCE": true, + "REDDIT": true }, "supportSourceTransformV1": true, "supportTransformerProxyV1": false diff --git a/src/v0/destinations/reddit/networkHandler.js b/src/v0/destinations/reddit/networkHandler.js new file mode 100644 index 0000000000..836c015859 --- /dev/null +++ b/src/v0/destinations/reddit/networkHandler.js @@ -0,0 +1,50 @@ +const { RetryableError } = require('@rudderstack/integrations-lib'); +const { prepareProxyRequest, proxyRequest } = require('../../../adapters/network'); +const { isHttpStatusSuccess } = require('../../util/index'); +const { REFRESH_TOKEN } = require('../../../adapters/networkhandler/authConstants'); + +const { processAxiosResponse } = require('../../../adapters/utils/networkUtils'); + +const redditRespHandler = (destResponse) => { + const { status, response } = destResponse; + + // to handle the case when authorization-token is invalid + if (status === 401 && response.includes('Authorization Required')) { + throw new RetryableError( + `Request failed due to ${response} 'during reddit response transformation'`, + 500, + destResponse, + REFRESH_TOKEN, + ); + } +}; +const responseHandler = (destinationResponse) => { + const message = `Request Processed Successfully`; + const { status } = destinationResponse; + if (!isHttpStatusSuccess(status)) { + // if error, successfully return status, message and original destination response + redditRespHandler(destinationResponse); + } + const { response } = destinationResponse; + const errorMessage = + response.invalid_events && Array.isArray(response.invalid_events) + ? response?.invalid_events[0]?.error_message + : null; + const destResp = errorMessage || destinationResponse; + // Mostly any error will not have a status of 2xx + return { + status, + message, + destResp, + }; +}; +// eslint-disable-next-line @typescript-eslint/naming-convention +class networkHandler { + constructor() { + this.responseHandler = responseHandler; + this.proxy = proxyRequest; + this.prepareProxy = prepareProxyRequest; + this.processAxiosResponse = processAxiosResponse; + } +} +module.exports = { networkHandler }; diff --git a/test/integrations/destinations/reddit/delivery/data.ts b/test/integrations/destinations/reddit/delivery/data.ts new file mode 100644 index 0000000000..66c1e2863f --- /dev/null +++ b/test/integrations/destinations/reddit/delivery/data.ts @@ -0,0 +1,174 @@ +export const data = [ + { + name: 'reddit', + description: 'Test 0', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://ads-api.reddit.com/api/v2.0/conversions/events/a2_fsddXXXfsfd', + headers: { + Authorization: 'Bearer dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + events: [ + { + event_at: '2019-10-14T09:03:17.562Z', + event_type: { + tracking_type: 'Purchase', + }, + user: { + aaid: 'c12d34889302d3c656b5699fa9190b51c50d6f62fce57e13bd56b503d66c487a', + email: 'ac144532d9e4efeab19475d9253a879173ea12a3d2238d1cb8a332a7b3a105f2', + external_id: '7b023241a3132b792a5a33915a5afb3133cbb1e13d72879689bf6504de3b036d', + ip_address: 'e80bd55a3834b7c2a34ade23c7ecb54d2a49838227080f50716151e765a619db', + user_agent: + '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', + screen_dimensions: {}, + }, + event_metadata: { + item_count: 3, + products: [ + { + id: '123', + name: 'Monopoly', + category: 'Games', + }, + { + id: '345', + name: 'UNO', + category: 'Games', + }, + ], + }, + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + destResp: { + response: { + message: 'Successfully processed 1 conversion events.', + }, + status: 200, + }, + message: 'Request Processed Successfully', + status: 200, + }, + }, + }, + }, + }, + { + name: 'reddit', + description: 'Test 1', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://ads-api.reddit.com/api/v2.0/conversions/events/a2_gsddXXXfsfd', + headers: { + Authorization: 'Bearer dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + events: [ + { + event_at: '2019-10-14T09:03:17.562Z', + event_type: { + tracking_type: 'ViewContent', + }, + user: { + aaid: 'c12d34889302d3c656b5699fa9190b51c50d6f62fce57e13bd56b503d66c487a', + email: 'ac144532d9e4efeab19475d9253a879173ea12a3d2238d1cb8a332a7b3a105f2', + external_id: '7b023241a3132b792a5a33915a5afb3133cbb1e13d72879689bf6504de3b036d', + ip_address: 'e80bd55a3834b7c2a34ade23c7ecb54d2a49838227080f50716151e765a619db', + user_agent: + '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', + screen_dimensions: {}, + }, + event_metadata: { + item_count: 3, + products: [ + { + id: '123', + name: 'Monopoly', + category: 'Games', + }, + { + id: '345', + name: 'UNO', + category: 'Games', + }, + ], + }, + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + method: 'POST', + }, + }, + output: { + response: { + status: 500, + body: { + output: { + authErrorCategory: 'REFRESH_TOKEN', + destinationResponse: { + response: 'Authorization Required', + status: 401, + }, + message: + "Request failed due to Authorization Required 'during reddit response transformation'", + statTags: { + destType: 'REDDIT', + destinationId: 'Non-determininable', + errorCategory: 'network', + errorType: 'retryable', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', + workspaceId: 'Non-determininable', + }, + status: 500, + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/reddit/network.ts b/test/integrations/destinations/reddit/network.ts new file mode 100644 index 0000000000..7c436e8fb8 --- /dev/null +++ b/test/integrations/destinations/reddit/network.ts @@ -0,0 +1,100 @@ +export const networkCallsData = [ + { + httpReq: { + url: 'https://ads-api.reddit.com/api/v2.0/conversions/events/a2_fsddXXXfsfd', + data: { + events: [ + { + event_at: '2019-10-14T09:03:17.562Z', + event_type: { + tracking_type: 'Purchase', + }, + user: { + aaid: 'c12d34889302d3c656b5699fa9190b51c50d6f62fce57e13bd56b503d66c487a', + email: 'ac144532d9e4efeab19475d9253a879173ea12a3d2238d1cb8a332a7b3a105f2', + external_id: '7b023241a3132b792a5a33915a5afb3133cbb1e13d72879689bf6504de3b036d', + ip_address: 'e80bd55a3834b7c2a34ade23c7ecb54d2a49838227080f50716151e765a619db', + user_agent: + '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', + screen_dimensions: {}, + }, + event_metadata: { + item_count: 3, + products: [ + { + id: '123', + name: 'Monopoly', + category: 'Games', + }, + { + id: '345', + name: 'UNO', + category: 'Games', + }, + ], + }, + }, + ], + }, + params: { destination: 'reddit' }, + headers: { + Authorization: 'Bearer dummyAccessToken', + 'Content-Type': 'application/json', + }, + method: 'POST', + }, + httpRes: { + data: { + message: 'Successfully processed 1 conversion events.', + }, + status: 200, + statusText: 'OK', + }, + }, + { + httpReq: { + url: 'https://ads-api.reddit.com/api/v2.0/conversions/events/a2_gsddXXXfsfd', + data: { + events: [ + { + event_at: '2019-10-14T09:03:17.562Z', + event_type: { + tracking_type: 'ViewContent', + }, + user: { + aaid: 'c12d34889302d3c656b5699fa9190b51c50d6f62fce57e13bd56b503d66c487a', + email: 'ac144532d9e4efeab19475d9253a879173ea12a3d2238d1cb8a332a7b3a105f2', + external_id: '7b023241a3132b792a5a33915a5afb3133cbb1e13d72879689bf6504de3b036d', + ip_address: 'e80bd55a3834b7c2a34ade23c7ecb54d2a49838227080f50716151e765a619db', + user_agent: + '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', + screen_dimensions: {}, + }, + event_metadata: { + item_count: 3, + products: [ + { + id: '123', + name: 'Monopoly', + category: 'Games', + }, + { + id: '345', + name: 'UNO', + category: 'Games', + }, + ], + }, + }, + ], + }, + params: { destination: 'reddit' }, + headers: { + Authorization: 'Bearer dummyAccessToken', + 'Content-Type': 'application/json', + }, + method: 'POST', + }, + httpRes: { data: 'Authorization Required', status: 401, statusText: 'Unauthorized' }, + }, +]; diff --git a/test/integrations/destinations/reddit/processor/data.ts b/test/integrations/destinations/reddit/processor/data.ts new file mode 100644 index 0000000000..91da5fbe67 --- /dev/null +++ b/test/integrations/destinations/reddit/processor/data.ts @@ -0,0 +1,1532 @@ +export const data = [ + { + name: 'reddit', + description: 'Track call with order completed event', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + context: { + traits: { + 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', + device: { + advertisingId: 'asfds7fdsihf734b34j43f', + }, + os: { + name: 'android', + }, + }, + type: 'track', + session_id: '16733896350494', + originalTimestamp: '2019-10-14T09:03:17.562Z', + anonymousId: '123456', + event: 'Order Completed', + userId: 'testuserId1', + properties: { + checkout_id: '12345', + order_id: '1234', + affiliation: 'Apple Store', + total: 20, + revenue: 15, + shipping: 4, + tax: 1, + discount: 1.5, + coupon: 'ImagePro', + currency: 'USD', + products: [ + { + product_id: '123', + sku: 'G-32', + name: 'Monopoly', + price: 14, + quantity: 1, + category: 'Games', + url: 'https://www.website.com/product/path', + image_url: 'https://www.website.com/product/path.jpg', + }, + { + product_id: '345', + sku: 'F-32', + name: 'UNO', + price: 3.45, + quantity: 2, + category: 'Games', + }, + ], + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + accountId: 'a2_fsddXXXfsfd', + hashData: true, + eventsMapping: [ + { + from: 'Order Completed', + to: 'Purchase', + }, + ], + }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + secret: { + accessToken: 'dummyAccessToken', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://ads-api.reddit.com/api/v2.0/conversions/events/a2_fsddXXXfsfd', + headers: { + Authorization: 'Bearer dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + events: [ + { + event_at: '2019-10-14T09:03:17.562Z', + event_type: { + tracking_type: 'Purchase', + }, + user: { + aaid: 'c12d34889302d3c656b5699fa9190b51c50d6f62fce57e13bd56b503d66c487a', + email: 'ac144532d9e4efeab19475d9253a879173ea12a3d2238d1cb8a332a7b3a105f2', + external_id: + '7b023241a3132b792a5a33915a5afb3133cbb1e13d72879689bf6504de3b036d', + ip_address: + 'e80bd55a3834b7c2a34ade23c7ecb54d2a49838227080f50716151e765a619db', + user_agent: + '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', + screen_dimensions: {}, + }, + event_metadata: { + item_count: 3, + products: [ + { + id: '123', + name: 'Monopoly', + category: 'Games', + }, + { + id: '345', + name: 'UNO', + category: 'Games', + }, + ], + }, + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + secret: { + accessToken: 'dummyAccessToken', + }, + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'reddit', + description: 'Track call with product list viewed event', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + context: { + traits: { + 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', + }, + type: 'track', + originalTimestamp: '2019-10-14T09:03:17.562Z', + anonymousId: '123456', + event: 'Product List Viewed', + userId: 'testuserId1', + properties: { + list_id: 'list1', + category: "What's New", + products: [ + { + product_id: '017c6f5d5cf86a4b22432066', + sku: '8732-98', + name: 'Just Another Game', + price: 22, + position: 2, + category: 'Games and Entertainment', + url: 'https://www.myecommercewebsite.com/product', + image_url: 'https://www.myecommercewebsite.com/product/path.jpg', + }, + { + product_id: '89ac6f5d5cf86a4b64eac145', + sku: '1267-01', + name: 'Wrestling Trump Cards', + price: 4, + position: 21, + category: 'Card Games', + }, + ], + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + accountId: 'a2_fsddXXXfsfd', + hashData: false, + eventsMapping: [ + { + from: 'Order Completed', + to: 'Purchase', + }, + ], + }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + secret: { + accessToken: 'dummyAccessToken', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://ads-api.reddit.com/api/v2.0/conversions/events/a2_fsddXXXfsfd', + headers: { + Authorization: 'Bearer dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + events: [ + { + event_at: '2019-10-14T09:03:17.562Z', + event_type: { + tracking_type: 'ViewContent', + }, + user: { + email: 'testone@gmail.com', + external_id: 'testuserId1', + ip_address: '54.100.200.255', + user_agent: + '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', + screen_dimensions: {}, + }, + event_metadata: { + item_count: 0, + products: [ + { + id: '017c6f5d5cf86a4b22432066', + name: 'Just Another Game', + category: 'Games and Entertainment', + }, + { + id: '89ac6f5d5cf86a4b64eac145', + name: 'Wrestling Trump Cards', + category: 'Card Games', + }, + ], + }, + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + secret: { + accessToken: 'dummyAccessToken', + }, + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'reddit', + description: 'Track call with product added event', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + context: { + traits: { + 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', + }, + type: 'track', + originalTimestamp: '2019-10-14T09:03:17.562Z', + anonymousId: '123456', + event: 'PRoduct Added ', + userId: 'testuserId1', + properties: { + product_id: '622c6f5d5cf86a4c77358033', + sku: '8472-998-0112', + category: 'Games', + name: 'Cones of Dunshire', + brand: 'Wyatt Games', + variant: 'exapansion pack', + price: 49.99, + quantity: 5, + coupon: 'PREORDER15', + position: 1, + url: 'https://www.website.com/product/path', + image_url: 'https://www.website.com/product/path.webp', + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + accountId: 'a2_fsddXXXfsfd', + hashData: true, + eventsMapping: [ + { + from: 'Order Completed', + to: 'Purchase', + }, + ], + }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + secret: { + accessToken: 'dummyAccessToken', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://ads-api.reddit.com/api/v2.0/conversions/events/a2_fsddXXXfsfd', + headers: { + Authorization: 'Bearer dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + events: [ + { + event_at: '2019-10-14T09:03:17.562Z', + event_type: { + tracking_type: 'AddToCart', + }, + user: { + email: 'ac144532d9e4efeab19475d9253a879173ea12a3d2238d1cb8a332a7b3a105f2', + external_id: + '7b023241a3132b792a5a33915a5afb3133cbb1e13d72879689bf6504de3b036d', + ip_address: + 'e80bd55a3834b7c2a34ade23c7ecb54d2a49838227080f50716151e765a619db', + user_agent: + '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', + screen_dimensions: {}, + }, + event_metadata: { + item_count: 5, + products: [ + { + id: '622c6f5d5cf86a4c77358033', + name: 'Cones of Dunshire', + category: 'Games', + }, + ], + }, + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + secret: { + accessToken: 'dummyAccessToken', + }, + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'reddit', + description: 'Track call with products searched event', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + context: { + traits: { + 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', + }, + type: 'track', + originalTimestamp: '2019-10-14T09:03:17.562Z', + anonymousId: '123456', + event: 'products searched', + userId: 'testuserId1', + properties: { + product_id: '622c6f5d5cf86a4c77358033', + sku: '8472-998-0112', + category: 'Games', + name: 'Cones of Dunshire', + brand: 'Wyatt Games', + variant: 'exapansion pack', + price: 49.99, + quantity: 5, + coupon: 'PREORDER15', + position: 1, + url: 'https://www.website.com/product/path', + image_url: 'https://www.website.com/product/path.webp', + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + accountId: 'a2_fsddXXXfsfd', + hashData: true, + eventsMapping: [ + { + from: 'Order Completed', + to: 'Purchase', + }, + ], + }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + secret: { + accessToken: 'dummyAccessToken', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://ads-api.reddit.com/api/v2.0/conversions/events/a2_fsddXXXfsfd', + headers: { + Authorization: 'Bearer dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + events: [ + { + event_at: '2019-10-14T09:03:17.562Z', + event_type: { + tracking_type: 'Search', + }, + user: { + email: 'ac144532d9e4efeab19475d9253a879173ea12a3d2238d1cb8a332a7b3a105f2', + external_id: + '7b023241a3132b792a5a33915a5afb3133cbb1e13d72879689bf6504de3b036d', + ip_address: + 'e80bd55a3834b7c2a34ade23c7ecb54d2a49838227080f50716151e765a619db', + user_agent: + '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', + screen_dimensions: {}, + }, + event_metadata: { + item_count: 5, + products: [ + { + id: '622c6f5d5cf86a4c77358033', + name: 'Cones of Dunshire', + category: 'Games', + }, + ], + }, + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + secret: { + accessToken: 'dummyAccessToken', + }, + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'reddit', + description: 'Track call with products Searched event mapped in UI', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + context: { + traits: { + 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', + }, + type: 'track', + originalTimestamp: '2019-10-14T09:03:17.562Z', + anonymousId: '123456', + event: 'Products Searched', + userId: 'testuserId1', + properties: { + product_id: '622c6f5d5cf86a4c77358033', + sku: '8472-998-0112', + category: 'Games', + name: 'Cones of Dunshire', + brand: 'Wyatt Games', + variant: 'exapansion pack', + price: 49.99, + quantity: 5, + coupon: 'PREORDER15', + position: 1, + url: 'https://www.website.com/product/path', + image_url: 'https://www.website.com/product/path.webp', + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + accountId: 'a2_fsddXXXfsfd', + hashData: true, + eventsMapping: [ + { + from: 'Products Searched', + to: 'ViewContent', + }, + ], + }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + secret: { + accessToken: 'dummyAccessToken', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://ads-api.reddit.com/api/v2.0/conversions/events/a2_fsddXXXfsfd', + headers: { + Authorization: 'Bearer dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + events: [ + { + event_at: '2019-10-14T09:03:17.562Z', + event_type: { + tracking_type: 'ViewContent', + }, + user: { + email: 'ac144532d9e4efeab19475d9253a879173ea12a3d2238d1cb8a332a7b3a105f2', + external_id: + '7b023241a3132b792a5a33915a5afb3133cbb1e13d72879689bf6504de3b036d', + ip_address: + 'e80bd55a3834b7c2a34ade23c7ecb54d2a49838227080f50716151e765a619db', + user_agent: + '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', + screen_dimensions: {}, + }, + event_metadata: { + item_count: 5, + products: [ + { + id: '622c6f5d5cf86a4c77358033', + name: 'Cones of Dunshire', + category: 'Games', + }, + ], + }, + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + secret: { + accessToken: 'dummyAccessToken', + }, + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'reddit', + description: 'Track call with product added to wishlist event', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + context: { + traits: { + 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', + }, + type: 'track', + originalTimestamp: '2019-10-14T09:03:17.562Z', + anonymousId: '123456', + event: 'product added to wishlist', + userId: 'testuserId1', + properties: { + list_id: 'list1', + category: "What's New", + products: [ + { + product_id: '017c6f5d5cf86a4b22432066', + sku: '8732-98', + name: 'Just Another Game', + price: 22, + position: 2, + category: 'Games and Entertainment', + url: 'https://www.myecommercewebsite.com/product', + image_url: 'https://www.myecommercewebsite.com/product/path.jpg', + }, + { + product_id: '89ac6f5d5cf86a4b64eac145', + sku: '1267-01', + name: 'Wrestling Trump Cards', + price: 4, + position: 21, + category: 'Card Games', + }, + ], + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + accountId: 'a2_fsddXXXfsfd', + hashData: true, + eventsMapping: [ + { + from: 'Order Completed', + to: 'Purchase', + }, + ], + }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + secret: { + accessToken: 'dummyAccessToken', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://ads-api.reddit.com/api/v2.0/conversions/events/a2_fsddXXXfsfd', + headers: { + Authorization: 'Bearer dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + events: [ + { + event_at: '2019-10-14T09:03:17.562Z', + event_type: { + tracking_type: 'AddToWishlist', + }, + user: { + email: 'ac144532d9e4efeab19475d9253a879173ea12a3d2238d1cb8a332a7b3a105f2', + external_id: + '7b023241a3132b792a5a33915a5afb3133cbb1e13d72879689bf6504de3b036d', + ip_address: + 'e80bd55a3834b7c2a34ade23c7ecb54d2a49838227080f50716151e765a619db', + user_agent: + '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', + screen_dimensions: {}, + }, + event_metadata: { + item_count: 0, + products: [ + { + id: '017c6f5d5cf86a4b22432066', + name: 'Just Another Game', + category: 'Games and Entertainment', + }, + { + id: '89ac6f5d5cf86a4b64eac145', + name: 'Wrestling Trump Cards', + category: 'Card Games', + }, + ], + }, + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + secret: { + accessToken: 'dummyAccessToken', + }, + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'reddit', + description: 'Track call with non-standard non-mapped event', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + context: { + traits: { + 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', + }, + type: 'track', + originalTimestamp: '2019-10-14T09:03:17.562Z', + anonymousId: '123456', + event: 'Watch Items', + userId: 'testuserId1', + properties: { + list_id: 'list1', + category: "What's New", + products: [ + { + product_id: '017c6f5d5cf86a4b22432066', + sku: '8732-98', + name: 'Just Another Game', + price: 22, + position: 2, + category: 'Games and Entertainment', + url: 'https://www.myecommercewebsite.com/product', + image_url: 'https://www.myecommercewebsite.com/product/path.jpg', + }, + { + product_id: '89ac6f5d5cf86a4b64eac145', + sku: '1267-01', + name: 'Wrestling Trump Cards', + price: 4, + position: 21, + category: 'Card Games', + }, + ], + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + accountId: 'a2_fsddXXXfsfd', + hashData: true, + eventsMapping: [ + { + from: 'Order Completed', + to: 'Purchase', + }, + ], + }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + secret: { + accessToken: 'dummyAccessToken', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://ads-api.reddit.com/api/v2.0/conversions/events/a2_fsddXXXfsfd', + headers: { + Authorization: 'Bearer dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + events: [ + { + event_at: '2019-10-14T09:03:17.562Z', + event_type: { + custom_event_name: 'Watch Items', + tracking_type: 'Custom', + }, + user: { + email: 'ac144532d9e4efeab19475d9253a879173ea12a3d2238d1cb8a332a7b3a105f2', + external_id: + '7b023241a3132b792a5a33915a5afb3133cbb1e13d72879689bf6504de3b036d', + ip_address: + 'e80bd55a3834b7c2a34ade23c7ecb54d2a49838227080f50716151e765a619db', + user_agent: + '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', + screen_dimensions: {}, + }, + event_metadata: { + item_count: 0, + products: [ + { + id: '017c6f5d5cf86a4b22432066', + name: 'Just Another Game', + category: 'Games and Entertainment', + }, + { + id: '89ac6f5d5cf86a4b64eac145', + name: 'Wrestling Trump Cards', + category: 'Card Games', + }, + ], + }, + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + secret: { + accessToken: 'dummyAccessToken', + }, + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'reddit', + description: 'Track call with no accountId in Config', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + context: { + traits: { + 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', + }, + type: 'track', + originalTimestamp: '2019-10-14T09:03:17.562Z', + anonymousId: '123456', + event: 'Watch Items', + userId: 'testuserId1', + properties: { + list_id: 'list1', + category: "What's New", + products: [ + { + product_id: '017c6f5d5cf86a4b22432066', + sku: '8732-98', + name: 'Just Another Game', + price: 22, + position: 2, + category: 'Games and Entertainment', + url: 'https://www.myecommercewebsite.com/product', + image_url: 'https://www.myecommercewebsite.com/product/path.jpg', + }, + { + product_id: '89ac6f5d5cf86a4b64eac145', + sku: '1267-01', + name: 'Wrestling Trump Cards', + price: 4, + position: 21, + category: 'Card Games', + }, + ], + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + eventsMapping: [ + { + from: 'Order Completed', + to: 'Purchase', + }, + ], + }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + secret: { + accessToken: 'dummyAccessToken', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + 'Account is not present. Aborting message.: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: Account is not present. Aborting message.', + statusCode: 400, + statTags: { + destType: 'REDDIT', + destinationId: 'destId', + errorCategory: 'dataValidation', + errorType: 'configuration', + feature: 'processor', + implementation: 'cdkV2', + module: 'destination', + workspaceId: 'wspId', + }, + metadata: { + destinationId: 'destId', + secret: { + accessToken: 'dummyAccessToken', + }, + workspaceId: 'wspId', + }, + }, + ], + }, + }, + }, + { + name: 'reddit', + description: 'Track call with no messageType', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + context: { + traits: { + 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', + }, + originalTimestamp: '2019-10-14T09:03:17.562Z', + anonymousId: '123456', + event: 'Watch Items', + userId: 'testuserId1', + properties: { + list_id: 'list1', + category: "What's New", + products: [ + { + product_id: '017c6f5d5cf86a4b22432066', + sku: '8732-98', + name: 'Just Another Game', + price: 22, + position: 2, + category: 'Games and Entertainment', + url: 'https://www.myecommercewebsite.com/product', + image_url: 'https://www.myecommercewebsite.com/product/path.jpg', + }, + { + product_id: '89ac6f5d5cf86a4b64eac145', + sku: '1267-01', + name: 'Wrestling Trump Cards', + price: 4, + position: 21, + category: 'Card Games', + }, + ], + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + accountId: 'a2_fsddXXXfsfd', + hashData: true, + eventsMapping: [ + { + from: 'Order Completed', + to: 'Purchase', + }, + ], + }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + secret: { + accessToken: 'dummyAccessToken', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + 'message Type is not present. Aborting message.: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: message Type is not present. Aborting message.', + statusCode: 400, + statTags: { + destType: 'REDDIT', + destinationId: 'destId', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'cdkV2', + module: 'destination', + workspaceId: 'wspId', + }, + metadata: { + destinationId: 'destId', + secret: { + accessToken: 'dummyAccessToken', + }, + workspaceId: 'wspId', + }, + }, + ], + }, + }, + }, + { + name: 'reddit', + description: 'Track call with no event', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + context: { + traits: { + 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', + }, + originalTimestamp: '2019-10-14T09:03:17.562Z', + anonymousId: '123456', + type: 'track', + userId: 'testuserId1', + properties: { + list_id: 'list1', + category: "What's New", + products: [ + { + product_id: '017c6f5d5cf86a4b22432066', + sku: '8732-98', + name: 'Just Another Game', + price: 22, + position: 2, + category: 'Games and Entertainment', + url: 'https://www.myecommercewebsite.com/product', + image_url: 'https://www.myecommercewebsite.com/product/path.jpg', + }, + { + product_id: '89ac6f5d5cf86a4b64eac145', + sku: '1267-01', + name: 'Wrestling Trump Cards', + price: 4, + position: 21, + category: 'Card Games', + }, + ], + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + accountId: 'a2_fsddXXXfsfd', + hashData: true, + eventsMapping: [ + { + from: 'Order Completed', + to: 'Purchase', + }, + ], + }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + secret: { + accessToken: 'dummyAccessToken', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + 'Event is not present. Aborting message.: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: Event is not present. Aborting message.', + statusCode: 400, + statTags: { + destType: 'REDDIT', + destinationId: 'destId', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'cdkV2', + module: 'destination', + workspaceId: 'wspId', + }, + metadata: { + destinationId: 'destId', + secret: { + accessToken: 'dummyAccessToken', + }, + workspaceId: 'wspId', + }, + }, + ], + }, + }, + }, + { + name: 'reddit', + description: 'Track call with no timestamp', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + context: { + traits: { + 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', + }, + anonymousId: '123456', + type: 'track', + event: 'Watch Items', + userId: 'testuserId1', + properties: { + list_id: 'list1', + category: "What's New", + products: [ + { + product_id: '017c6f5d5cf86a4b22432066', + sku: '8732-98', + name: 'Just Another Game', + price: 22, + position: 2, + category: 'Games and Entertainment', + url: 'https://www.myecommercewebsite.com/product', + image_url: 'https://www.myecommercewebsite.com/product/path.jpg', + }, + { + product_id: '89ac6f5d5cf86a4b64eac145', + sku: '1267-01', + name: 'Wrestling Trump Cards', + price: 4, + position: 21, + category: 'Card Games', + }, + ], + }, + integrations: { + All: true, + }, + }, + destination: { + Config: { + accountId: 'a2_fsddXXXfsfd', + hashData: true, + eventsMapping: [ + { + from: 'Order Completed', + to: 'Purchase', + }, + ], + }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + secret: { + accessToken: 'dummyAccessToken', + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + 'Timestamp is not present. Aborting message.: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: Timestamp is not present. Aborting message.', + statusCode: 400, + statTags: { + destType: 'REDDIT', + destinationId: 'destId', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'cdkV2', + module: 'destination', + workspaceId: 'wspId', + }, + metadata: { + destinationId: 'destId', + secret: { + accessToken: 'dummyAccessToken', + }, + workspaceId: 'wspId', + }, + }, + ], + }, + }, + }, + { + name: 'reddit', + description: 'Track call with no accessToken in secret in metadata', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + context: { + traits: { + 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', + }, + anonymousId: '123456', + type: 'track', + event: 'Watch Items', + userId: 'testuserId1', + originalTimestamp: '2019-10-14T09:03:17.562Z', + properties: { + list_id: 'list1', + category: "What's New", + products: [ + { + product_id: '017c6f5d5cf86a4b22432066', + sku: '8732-98', + name: 'Just Another Game', + price: 22, + position: 2, + category: 'Games and Entertainment', + url: 'https://www.myecommercewebsite.com/product', + image_url: 'https://www.myecommercewebsite.com/product/path.jpg', + }, + { + product_id: '89ac6f5d5cf86a4b64eac145', + sku: '1267-01', + name: 'Wrestling Trump Cards', + price: 4, + position: 21, + category: 'Card Games', + }, + ], + }, + integrations: { + All: true, + }, + }, + destination: { + Config: { + accountId: 'a2_fsddXXXfsfd', + hashData: true, + eventsMapping: [ + { + from: 'Order Completed', + to: 'Purchase', + }, + ], + }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + secret: {}, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + 'Secret or accessToken is not present in the metadata: Workflow: procWorkflow, Step: buildResponseForProcessTransformation, ChildStep: undefined, OriginalError: Secret or accessToken is not present in the metadata', + statusCode: 500, + statTags: { + destType: 'REDDIT', + destinationId: 'destId', + errorCategory: 'platform', + errorType: 'oAuthSecret', + feature: 'processor', + implementation: 'cdkV2', + module: 'destination', + workspaceId: 'wspId', + }, + metadata: { + destinationId: 'destId', + secret: {}, + workspaceId: 'wspId', + }, + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/reddit/router/data.ts b/test/integrations/destinations/reddit/router/data.ts new file mode 100644 index 0000000000..317bb41a14 --- /dev/null +++ b/test/integrations/destinations/reddit/router/data.ts @@ -0,0 +1,502 @@ +export const data = [ + { + name: 'reddit', + description: 'Track Events', + feature: 'router', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + input: [ + { + message: { + context: { + traits: { + 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', + }, + type: 'track', + session_id: '16733896350494', + originalTimestamp: '2019-10-14T09:03:17.562Z', + anonymousId: '123456', + event: 'Order Completed', + userId: 'testuserId1', + properties: { + checkout_id: '12345', + order_id: '1234', + affiliation: 'Apple Store', + total: 20, + revenue: 15, + shipping: 4, + tax: 1, + discount: 1.5, + coupon: 'ImagePro', + currency: 'USD', + products: [ + { + product_id: '123', + sku: 'G-32', + name: 'Monopoly', + price: 14, + quantity: 1, + category: 'Games', + url: 'https://www.website.com/product/path', + image_url: 'https://www.website.com/product/path.jpg', + }, + { + product_id: '345', + sku: 'F-32', + name: 'UNO', + price: 3.45, + quantity: 2, + category: 'Games', + }, + ], + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + accountId: 'a2_fsddXXXfsfd', + hashData: true, + eventsMapping: [ + { + from: 'Order Completed', + to: 'Purchase', + }, + ], + }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + secret: { + accessToken: 'dummyAccessToken', + }, + }, + }, + { + message: { + context: { + traits: { + 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', + }, + type: 'track', + originalTimestamp: '2019-10-14T09:03:17.562Z', + anonymousId: '123456', + event: 'Product List Viewed', + userId: 'testuserId1', + properties: { + list_id: 'list1', + category: "What's New", + products: [ + { + product_id: '017c6f5d5cf86a4b22432066', + sku: '8732-98', + name: 'Just Another Game', + price: 22, + position: 2, + category: 'Games and Entertainment', + url: 'https://www.myecommercewebsite.com/product', + image_url: 'https://www.myecommercewebsite.com/product/path.jpg', + }, + { + product_id: '89ac6f5d5cf86a4b64eac145', + sku: '1267-01', + name: 'Wrestling Trump Cards', + price: 4, + position: 21, + category: 'Card Games', + }, + ], + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + accountId: 'a2_fsddXXXfsfd', + hashData: true, + eventsMapping: [ + { + from: 'Order Completed', + to: 'Purchase', + }, + ], + }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + secret: { + accessToken: 'dummyAccessToken', + }, + }, + }, + { + message: { + context: { + traits: { + 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', + }, + type: 'track', + originalTimestamp: '2019-10-14T09:03:17.562Z', + anonymousId: '123456', + event: 'PRoduct Added ', + userId: 'testuserId1', + properties: { + product_id: '622c6f5d5cf86a4c77358033', + sku: '8472-998-0112', + category: 'Games', + name: 'Cones of Dunshire', + brand: 'Wyatt Games', + variant: 'exapansion pack', + price: 49.99, + quantity: 5, + coupon: 'PREORDER15', + position: 1, + url: 'https://www.website.com/product/path', + image_url: 'https://www.website.com/product/path.webp', + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + accountId: 'a2_fsddXXXfsfd', + hashData: true, + eventsMapping: [ + { + from: 'Order Completed', + to: 'Purchase', + }, + ], + }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + secret: { + accessToken: 'dummyAccessToken', + }, + }, + }, + ], + destType: 'reddit', + }, + }, + }, + output: { + response: { + status: 200, + body: { + output: [ + { + batchedRequest: { + body: { + JSON: { + events: [ + { + event_at: '2019-10-14T09:03:17.562Z', + event_type: { + tracking_type: 'Purchase', + }, + user: { + email: 'ac144532d9e4efeab19475d9253a879173ea12a3d2238d1cb8a332a7b3a105f2', + external_id: + '7b023241a3132b792a5a33915a5afb3133cbb1e13d72879689bf6504de3b036d', + ip_address: + 'e80bd55a3834b7c2a34ade23c7ecb54d2a49838227080f50716151e765a619db', + user_agent: + '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', + screen_dimensions: {}, + }, + event_metadata: { + item_count: 3, + products: [ + { + id: '123', + name: 'Monopoly', + category: 'Games', + }, + { + id: '345', + name: 'UNO', + category: 'Games', + }, + ], + }, + }, + { + event_at: '2019-10-14T09:03:17.562Z', + event_type: { + tracking_type: 'ViewContent', + }, + user: { + email: 'ac144532d9e4efeab19475d9253a879173ea12a3d2238d1cb8a332a7b3a105f2', + external_id: + '7b023241a3132b792a5a33915a5afb3133cbb1e13d72879689bf6504de3b036d', + ip_address: + 'e80bd55a3834b7c2a34ade23c7ecb54d2a49838227080f50716151e765a619db', + user_agent: + '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', + screen_dimensions: {}, + }, + event_metadata: { + item_count: 0, + products: [ + { + id: '017c6f5d5cf86a4b22432066', + name: 'Just Another Game', + category: 'Games and Entertainment', + }, + { + id: '89ac6f5d5cf86a4b64eac145', + name: 'Wrestling Trump Cards', + category: 'Card Games', + }, + ], + }, + }, + { + event_at: '2019-10-14T09:03:17.562Z', + event_type: { + tracking_type: 'AddToCart', + }, + user: { + email: 'ac144532d9e4efeab19475d9253a879173ea12a3d2238d1cb8a332a7b3a105f2', + external_id: + '7b023241a3132b792a5a33915a5afb3133cbb1e13d72879689bf6504de3b036d', + ip_address: + 'e80bd55a3834b7c2a34ade23c7ecb54d2a49838227080f50716151e765a619db', + user_agent: + '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', + screen_dimensions: {}, + }, + event_metadata: { + item_count: 5, + products: [ + { + id: '622c6f5d5cf86a4c77358033', + name: 'Cones of Dunshire', + category: 'Games', + }, + ], + }, + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://ads-api.reddit.com/api/v2.0/conversions/events/a2_fsddXXXfsfd', + headers: { + Authorization: 'Bearer dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + files: {}, + }, + metadata: [ + { + destinationId: 'destId', + workspaceId: 'wspId', + secret: { + accessToken: 'dummyAccessToken', + }, + }, + { + destinationId: 'destId', + workspaceId: 'wspId', + secret: { + accessToken: 'dummyAccessToken', + }, + }, + { + destinationId: 'destId', + workspaceId: 'wspId', + secret: { + accessToken: 'dummyAccessToken', + }, + }, + ], + batched: true, + statusCode: 200, + destination: { + Config: { + accountId: 'a2_fsddXXXfsfd', + hashData: true, + eventsMapping: [ + { + from: 'Order Completed', + to: 'Purchase', + }, + ], + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + }, + ], + }, + }, + }, + }, + { + name: 'reddit', + description: 'Track Events with no event name', + feature: 'router', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + input: [ + { + message: { + context: { + traits: { + 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', + }, + originalTimestamp: '2019-10-14T09:03:17.562Z', + anonymousId: '123456', + type: 'track', + userId: 'testuserId1', + properties: { + list_id: 'list1', + category: "What's New", + products: [ + { + product_id: '017c6f5d5cf86a4b22432066', + sku: '8732-98', + name: 'Just Another Game', + price: 22, + position: 2, + category: 'Games and Entertainment', + url: 'https://www.myecommercewebsite.com/product', + image_url: 'https://www.myecommercewebsite.com/product/path.jpg', + }, + { + product_id: '89ac6f5d5cf86a4b64eac145', + sku: '1267-01', + name: 'Wrestling Trump Cards', + price: 4, + position: 21, + category: 'Card Games', + }, + ], + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + accountId: 'a2_fsddXXXfsfd', + eventsMapping: [ + { + from: 'Order Completed', + to: 'Purchase', + }, + ], + }, + DestinationDefinition: { Config: { cdkV2Enabled: true } }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + secret: { + accessToken: 'dummyAccessToken', + }, + }, + }, + ], + destType: 'reddit', + }, + }, + }, + output: { + response: { + status: 200, + body: { + output: [ + { + metadata: [ + { + destinationId: 'destId', + workspaceId: 'wspId', + secret: { + accessToken: 'dummyAccessToken', + }, + }, + ], + destination: { + Config: { + accountId: 'a2_fsddXXXfsfd', + eventsMapping: [ + { + from: 'Order Completed', + to: 'Purchase', + }, + ], + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + batched: false, + statusCode: 400, + error: 'Event is not present. Aborting message.', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'REDDIT', + module: 'destination', + implementation: 'cdkV2', + feature: 'router', + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + }, + }, +]; From 776d2c4abe23cd279195064684b9ccc807d83afc Mon Sep 17 00:00:00 2001 From: AASHISH MALIK Date: Mon, 11 Dec 2023 13:24:10 +0530 Subject: [PATCH 70/93] fix: removed retry logic from v1 cm360, added adapter for v1 to v0 conversion (#2860) * fix: removed retry logic from v1 cm360 proxy handler * feat: adapter to convert v1 payload to v0 transformer Proxy --- src/adapters/networkHandlerFactory.js | 10 +- src/adapters/networkHandlerFactory.test.js | 29 +- src/controllers/delivery.ts | 68 +- src/features.json | 2 +- src/interfaces/DestinationService.ts | 7 +- src/routes/delivery.ts | 9 +- src/services/comparator.ts | 8 +- src/services/delivertTest/deliveryTest.ts | 5 +- src/services/destination/cdkV1Integration.ts | 7 +- src/services/destination/cdkV2Integration.ts | 15 +- src/services/destination/nativeIntegration.ts | 63 +- .../destination/postTransformation.ts | 34 +- src/types/index.ts | 80 +- .../campaign_manager/networkHandler.js | 2 +- .../destinations/salesforce/networkHandler.js | 2 +- .../salesforce_oauth/networkHandler.js | 2 +- src/v0/util/errorTypes/index.js | 2 + .../util/errorTypes/transformerProxyError.js | 28 + .../campaign_manager/networkHandler.js | 47 +- test/__tests__/data/marketo_input.json | 16 +- .../destinations/braze/dataDelivery/data.ts | 999 +++++++++++------- .../destinations/braze/network.ts | 29 + 22 files changed, 942 insertions(+), 522 deletions(-) create mode 100644 src/v0/util/errorTypes/transformerProxyError.js diff --git a/src/adapters/networkHandlerFactory.js b/src/adapters/networkHandlerFactory.js index f4940553f5..e8c3748d15 100644 --- a/src/adapters/networkHandlerFactory.js +++ b/src/adapters/networkHandlerFactory.js @@ -37,8 +37,14 @@ SUPPORTED_VERSIONS.forEach((version) => { }); const getNetworkHandler = (type, version) => { - const NetworkHandler = handlers[version][type] || handlers.generic; - return new NetworkHandler(); + let handlerVersion = version; + let NetworkHandler = handlers[version][type] || handlers.generic; + if (version === 'v1' && NetworkHandler === handlers.generic) { + NetworkHandler = handlers.v0[type] || handlers.generic; + handlerVersion = 'v0'; + } + const networkHandler = new NetworkHandler(); + return { networkHandler, handlerVersion }; }; module.exports = { diff --git a/src/adapters/networkHandlerFactory.test.js b/src/adapters/networkHandlerFactory.test.js index c4713e66a8..ff5f26a02d 100644 --- a/src/adapters/networkHandlerFactory.test.js +++ b/src/adapters/networkHandlerFactory.test.js @@ -3,23 +3,34 @@ const { networkHandler: GenericNetworkHandler } = require('./networkhandler/gene describe(`Network Handler Tests`, () => { it('Should return v0 networkhandler', () => { - let proxyHandler = getNetworkHandler('campaign_manager', `v0`); + let { networkHandler, handlerVersion } = getNetworkHandler('campaign_manager', `v0`); const cmProxy = require(`../v0/destinations/campaign_manager/networkHandler`).networkHandler; - expect(proxyHandler).toEqual(new cmProxy()); + expect(networkHandler).toEqual(new cmProxy()); + }); - proxyHandler = getNetworkHandler('braze', `v0`); + it('Should return v0 networkhandler braze', () => { + let { networkHandler, handlerVersion } = getNetworkHandler('braze', `v0`); const brazeProxy = require(`../v0/destinations/braze/networkHandler`).networkHandler; - expect(proxyHandler).toEqual(new brazeProxy()); + expect(networkHandler).toEqual(new brazeProxy()); }); it('Should return v1 networkhandler', () => { - let proxyHandler = getNetworkHandler('campaign_manager', `v1`); + let { networkHandler, handlerVersion } = getNetworkHandler('campaign_manager', `v1`); const cmProxy = require(`../v1/destinations/campaign_manager/networkHandler`).networkHandler; - expect(proxyHandler).toEqual(new cmProxy()); + expect(networkHandler).toEqual(new cmProxy()); }); - it('Should return genericHandler if v1 proxy and handler is not present for destination', () => { - let proxyHandler = getNetworkHandler('braze', `v1`); - expect(proxyHandler).toEqual(new GenericNetworkHandler()); + it('Should return v0 handler if v1 version and handler is present for destination in v0', () => { + const { networkHandler, handlerVersion } = getNetworkHandler('braze', `v1`); + const brazeProxy = require(`../v0/destinations/braze/networkHandler`).networkHandler; + console.log(networkHandler); + expect(networkHandler).toEqual(new brazeProxy()); + }); + + it('Should return generic handler', () => { + const { networkHandler, handlerVersion } = getNetworkHandler('abc', `v1`); + const brazeProxy = require(`../v0/destinations/braze/networkHandler`).networkHandler; + console.log(networkHandler); + expect(networkHandler).toEqual(new GenericNetworkHandler()); }); }); diff --git a/src/controllers/delivery.ts b/src/controllers/delivery.ts index 3ccc241b87..0cc5e12d78 100644 --- a/src/controllers/delivery.ts +++ b/src/controllers/delivery.ts @@ -1,6 +1,14 @@ +/* eslint-disable prefer-destructuring */ +/* eslint-disable sonarjs/no-duplicate-string */ import { Context } from 'koa'; import { MiscService } from '../services/misc'; -import { DeliveryResponse, ProcessorTransformationOutput } from '../types/index'; +import { + DeliveriesResponse, + DeliveryResponse, + ProcessorTransformationOutput, + ProxyDeliveriesRequest, + ProxyDeliveryRequest, +} from '../types/index'; import { ServiceSelector } from '../helpers/serviceSelector'; import { DeliveryTestService } from '../services/delivertTest/deliveryTest'; import { ControllerUtility } from './util'; @@ -9,30 +17,32 @@ import { DestinationPostTransformationService } from '../services/destination/po import tags from '../v0/util/tags'; import { FixMe } from '../util/types'; +const NON_DETERMINABLE = 'Non-determinable'; + export class DeliveryController { public static async deliverToDestination(ctx: Context) { logger.debug('Native(Delivery):: Request to transformer::', JSON.stringify(ctx.request.body)); let deliveryResponse: DeliveryResponse; const requestMetadata = MiscService.getRequestMetadata(ctx); - const event = ctx.request.body as ProcessorTransformationOutput; + const deliveryRequest = ctx.request.body as ProxyDeliveryRequest; const { destination }: { destination: string } = ctx.params; - const { version }: { version: string } = ctx.params; const integrationService = ServiceSelector.getNativeDestinationService(); try { - deliveryResponse = await integrationService.deliver( - event, + deliveryResponse = (await integrationService.deliver( + deliveryRequest, destination, requestMetadata, - version, - ); + 'v0', + )) as DeliveryResponse; } catch (error: any) { + const { metadata } = deliveryRequest; const metaTO = integrationService.getTags( destination, - event.metadata?.destinationId || 'Non-determininable', - event.metadata?.workspaceId || 'Non-determininable', + metadata?.destinationId || NON_DETERMINABLE, + metadata?.workspaceId || NON_DETERMINABLE, tags.FEATURES.DATA_DELIVERY, ); - metaTO.metadata = event.metadata; + metaTO.metadata = metadata; deliveryResponse = DestinationPostTransformationService.handleDeliveryFailureEvents( error, metaTO, @@ -40,6 +50,42 @@ export class DeliveryController { } ctx.body = { output: deliveryResponse }; ControllerUtility.deliveryPostProcess(ctx, deliveryResponse.status); + + logger.debug('Native(Delivery):: Response from transformer::', JSON.stringify(ctx.body)); + return ctx; + } + + public static async deliverToDestinationV1(ctx: Context) { + logger.debug('Native(Delivery):: Request to transformer::', JSON.stringify(ctx.request.body)); + let deliveryResponse: DeliveriesResponse; + const requestMetadata = MiscService.getRequestMetadata(ctx); + const deliveryRequest = ctx.request.body as ProxyDeliveriesRequest; + const { destination }: { destination: string } = ctx.params; + const integrationService = ServiceSelector.getNativeDestinationService(); + try { + deliveryResponse = (await integrationService.deliver( + deliveryRequest, + destination, + requestMetadata, + 'v1', + )) as DeliveriesResponse; + } catch (error: any) { + const { metadata } = deliveryRequest; + const metaTO = integrationService.getTags( + destination, + metadata[0].destinationId || NON_DETERMINABLE, + metadata[0].workspaceId || NON_DETERMINABLE, + tags.FEATURES.DATA_DELIVERY, + ); + metaTO.metadatas = metadata; + deliveryResponse = DestinationPostTransformationService.handlevV1DeliveriesFailureEvents( + error, + metaTO, + ); + } + ctx.body = { output: deliveryResponse }; + ControllerUtility.deliveryPostProcess(ctx); + logger.debug('Native(Delivery):: Response from transformer::', JSON.stringify(ctx.body)); return ctx; } @@ -50,6 +96,7 @@ export class DeliveryController { JSON.stringify(ctx.request.body), ); const { destination }: { destination: string } = ctx.params; + const { version }: { version: string } = ctx.params; const { deliveryPayload, destinationRequestPayload, @@ -61,6 +108,7 @@ export class DeliveryController { destination, destinationRequestPayload, deliveryPayload, + version, ); ctx.body = { output: response }; ControllerUtility.postProcess(ctx); diff --git a/src/features.json b/src/features.json index a3d29bb325..e0745c2246 100644 --- a/src/features.json +++ b/src/features.json @@ -66,5 +66,5 @@ "REDDIT": true }, "supportSourceTransformV1": true, - "supportTransformerProxyV1": false + "supportTransformerProxyV1": true } diff --git a/src/interfaces/DestinationService.ts b/src/interfaces/DestinationService.ts index 16f6b9349c..bf39024d85 100644 --- a/src/interfaces/DestinationService.ts +++ b/src/interfaces/DestinationService.ts @@ -5,9 +5,10 @@ import { ProcessorTransformationResponse, RouterTransformationRequestData, RouterTransformationResponse, - ProcessorTransformationOutput, UserDeletionRequest, UserDeletionResponse, + ProxyRequest, + DeliveriesResponse, } from '../types/index'; export interface DestinationService { @@ -44,11 +45,11 @@ export interface DestinationService { ): RouterTransformationResponse[]; deliver( - event: ProcessorTransformationOutput, + event: ProxyRequest, destinationType: string, requestMetadata: NonNullable, version: string, - ): Promise; + ): Promise; processUserDeletion( requests: UserDeletionRequest[], diff --git a/src/routes/delivery.ts b/src/routes/delivery.ts index 0591dc8b9e..30f4e2fb78 100644 --- a/src/routes/delivery.ts +++ b/src/routes/delivery.ts @@ -5,12 +5,19 @@ import { RouteActivationMiddleware } from '../middlewares/routeActivation'; const router = new Router(); router.post( - '/:version/destinations/:destination/proxy', + '/v0/destinations/:destination/proxy', RouteActivationMiddleware.isDeliveryRouteActive, RouteActivationMiddleware.destinationDeliveryFilter, DeliveryController.deliverToDestination, ); +router.post( + '/v1/destinations/:destination/proxy', + RouteActivationMiddleware.isDeliveryRouteActive, + RouteActivationMiddleware.destinationDeliveryFilter, + DeliveryController.deliverToDestinationV1, +); + router.post( '/:version/destinations/:destination/proxyTest', RouteActivationMiddleware.isDeliveryTestRouteActive, diff --git a/src/services/comparator.ts b/src/services/comparator.ts index 58c96beabb..d1e085b4bd 100644 --- a/src/services/comparator.ts +++ b/src/services/comparator.ts @@ -1,13 +1,14 @@ /* eslint-disable class-methods-use-this */ import { DestinationService } from '../interfaces/DestinationService'; import { + DeliveriesResponse, DeliveryResponse, Destination, ErrorDetailer, MetaTransferObject, - ProcessorTransformationOutput, ProcessorTransformationRequest, ProcessorTransformationResponse, + ProxyRequest, RouterTransformationRequestData, RouterTransformationResponse, UserDeletionRequest, @@ -365,11 +366,11 @@ export class ComparatorService implements DestinationService { } public async deliver( - event: ProcessorTransformationOutput, + event: ProxyRequest, destinationType: string, requestMetadata: NonNullable, version: string, - ): Promise { + ): Promise { const primaryResplist = await this.primaryService.deliver( event, destinationType, @@ -377,7 +378,6 @@ export class ComparatorService implements DestinationService { version, ); logger.error('[LIVE_COMPARE_TEST] not implemented for delivery routine'); - return primaryResplist; } diff --git a/src/services/delivertTest/deliveryTest.ts b/src/services/delivertTest/deliveryTest.ts index 0d960ade17..2f5db183e5 100644 --- a/src/services/delivertTest/deliveryTest.ts +++ b/src/services/delivertTest/deliveryTest.ts @@ -12,12 +12,13 @@ export class DeliveryTestService { destination: string, routerDestReqPayload: any, routerDeliveryPayload: any, + version, ) { let response: any; try { - const destNetworkHandler = networkHandlerFactory.getNetworkHandler(destination); + const { networkHandler } = networkHandlerFactory.getNetworkHandler(destination, version); - const proxyDestReqPayload = destNetworkHandler.prepareProxy(routerDeliveryPayload); + const proxyDestReqPayload = networkHandler.prepareProxy(routerDeliveryPayload); response = { destinationRequestPayload: proxyDestReqPayload, }; diff --git a/src/services/destination/cdkV1Integration.ts b/src/services/destination/cdkV1Integration.ts index 8ccd3341e5..197e3162ea 100644 --- a/src/services/destination/cdkV1Integration.ts +++ b/src/services/destination/cdkV1Integration.ts @@ -11,9 +11,10 @@ import { ProcessorTransformationResponse, RouterTransformationRequestData, RouterTransformationResponse, - ProcessorTransformationOutput, UserDeletionRequest, UserDeletionResponse, + ProxyRequest, + DeliveriesResponse, } from '../../types/index'; import { DestinationPostTransformationService } from './postTransformation'; import tags from '../../v0/util/tags'; @@ -117,10 +118,10 @@ export class CDKV1DestinationService implements DestinationService { } public deliver( - _event: ProcessorTransformationOutput, + _event: ProxyRequest, _destinationType: string, _requestMetadata: NonNullable, - ): Promise { + ): Promise { throw new TransformationError('CDV1 Does not Implement Delivery Routine'); } diff --git a/src/services/destination/cdkV2Integration.ts b/src/services/destination/cdkV2Integration.ts index f3be2c0144..be7f0e51d5 100644 --- a/src/services/destination/cdkV2Integration.ts +++ b/src/services/destination/cdkV2Integration.ts @@ -15,6 +15,8 @@ import { ProcessorTransformationOutput, UserDeletionRequest, UserDeletionResponse, + ProxyRequest, + DeliveriesResponse, } from '../../types/index'; import tags from '../../v0/util/tags'; import { DestinationPostTransformationService } from './postTransformation'; @@ -64,7 +66,7 @@ export class CDKV2DestinationService implements DestinationService { destinationType, event, tags.FEATURES.PROCESSOR, - requestMetadata + requestMetadata, ); stats.increment('event_transform_success', { @@ -127,7 +129,12 @@ export class CDKV2DestinationService implements DestinationService { metaTo.metadata = destInputArray[0].metadata; try { const doRouterTransformationResponse: RouterTransformationResponse[] = - await processCdkV2Workflow(destinationType, destInputArray, tags.FEATURES.ROUTER, requestMetadata); + await processCdkV2Workflow( + destinationType, + destInputArray, + tags.FEATURES.ROUTER, + requestMetadata, + ); return DestinationPostTransformationService.handleRouterTransformSuccessEvents( doRouterTransformationResponse, undefined, @@ -160,10 +167,10 @@ export class CDKV2DestinationService implements DestinationService { } public deliver( - _event: ProcessorTransformationOutput, + _event: ProxyRequest, _destinationType: string, _requestMetadata: NonNullable, - ): Promise { + ): Promise { throw new TransformationError('CDKV2 Does not Implement Delivery Routine'); } diff --git a/src/services/destination/nativeIntegration.ts b/src/services/destination/nativeIntegration.ts index 6bb79ce27a..c3b0237cdc 100644 --- a/src/services/destination/nativeIntegration.ts +++ b/src/services/destination/nativeIntegration.ts @@ -1,3 +1,5 @@ +/* eslint-disable prefer-destructuring */ +/* eslint-disable sonarjs/no-duplicate-string */ /* eslint-disable @typescript-eslint/no-unused-vars */ import groupBy from 'lodash/groupBy'; import cloneDeep from 'lodash/cloneDeep'; @@ -13,6 +15,11 @@ import { ProcessorTransformationOutput, UserDeletionRequest, UserDeletionResponse, + ProxyRequest, + ProxyDeliveriesRequest, + ProxyDeliveryRequest, + DeliveriesResponse, + DeliveryJobState, } from '../../types/index'; import { DestinationPostTransformationService } from './postTransformation'; import networkHandlerFactory from '../../adapters/networkHandlerFactory'; @@ -170,30 +177,66 @@ export class NativeIntegrationDestinationService implements DestinationService { } public async deliver( - destinationRequest: ProcessorTransformationOutput, + deliveryRequest: ProxyRequest, destinationType: string, _requestMetadata: NonNullable, version: string, - ): Promise { + ): Promise { try { - const networkHandler = networkHandlerFactory.getNetworkHandler(destinationType, version); - const rawProxyResponse = await networkHandler.proxy(destinationRequest, destinationType); + const { networkHandler, handlerVersion } = networkHandlerFactory.getNetworkHandler( + destinationType, + version, + ); + const rawProxyResponse = await networkHandler.proxy(deliveryRequest, destinationType); const processedProxyResponse = networkHandler.processAxiosResponse(rawProxyResponse); - return networkHandler.responseHandler( + let rudderJobMetadata = + version.toLowerCase() === 'v1' + ? (deliveryRequest as ProxyDeliveriesRequest).metadata + : (deliveryRequest as ProxyDeliveryRequest).metadata; + + if (version.toLowerCase() === 'v1' && handlerVersion.toLowerCase() === 'v0') { + rudderJobMetadata = rudderJobMetadata[0]; + } + + let responseProxy = networkHandler.responseHandler( { ...processedProxyResponse, - rudderJobMetadata: destinationRequest.metadata, + rudderJobMetadata, }, destinationType, - ) as DeliveryResponse; + ); + // Adaption Logic for V0 to V1 + if (handlerVersion.toLowerCase() === 'v0' && version.toLowerCase() === 'v1') { + const v0Response = responseProxy as DeliveryResponse; + const jobStates = (deliveryRequest as ProxyDeliveriesRequest).metadata.map( + (metadata) => + ({ + error: JSON.stringify(v0Response.destinationResponse?.response), + statusCode: v0Response.status, + metadata, + } as DeliveryJobState), + ); + responseProxy = { + response: jobStates, + } as DeliveriesResponse; + } + return responseProxy; } catch (err: any) { + const metadata = Array.isArray(deliveryRequest.metadata) + ? deliveryRequest.metadata[0] + : deliveryRequest.metadata; const metaTO = this.getTags( destinationType, - destinationRequest.metadata?.destinationId || 'Non-determininable', - destinationRequest.metadata?.workspaceId || 'Non-determininable', + metadata?.destinationId || 'Non-determininable', + metadata?.workspaceId || 'Non-determininable', tags.FEATURES.DATA_DELIVERY, ); - metaTO.metadata = destinationRequest.metadata; + + if (version.toLowerCase() === 'v1') { + metaTO.metadatas = (deliveryRequest as ProxyDeliveriesRequest).metadata; + return DestinationPostTransformationService.handlevV1DeliveriesFailureEvents(err, metaTO); + } + metaTO.metadata = (deliveryRequest as ProxyDeliveryRequest).metadata; return DestinationPostTransformationService.handleDeliveryFailureEvents(err, metaTO); } } diff --git a/src/services/destination/postTransformation.ts b/src/services/destination/postTransformation.ts index 076f5ba55e..de2f5f1b42 100644 --- a/src/services/destination/postTransformation.ts +++ b/src/services/destination/postTransformation.ts @@ -2,6 +2,7 @@ import cloneDeep from 'lodash/cloneDeep'; import isObject from 'lodash/isObject'; import isEmpty from 'lodash/isEmpty'; +import { PlatformError } from '@rudderstack/integrations-lib'; import { ProcessorTransformationRequest, ProcessorTransformationResponse, @@ -10,6 +11,8 @@ import { DeliveryResponse, MetaTransferObject, UserDeletionResponse, + DeliveriesResponse, + DeliveryJobState, } from '../../types/index'; import { generateErrorObject } from '../../v0/util'; import { ErrorReportingService } from '../errorReporting'; @@ -139,7 +142,7 @@ export class DestinationPostTransformationService { } public static handleDeliveryFailureEvents( - error: NonNullable, + error: any, metaTo: MetaTransferObject, ): DeliveryResponse { const errObj = generateErrorObject(error, metaTo.errorDetails, false); @@ -152,6 +155,35 @@ export class DestinationPostTransformationService { authErrorCategory: errObj.authErrorCategory, }), } as DeliveryResponse; + + ErrorReportingService.reportError(error, metaTo.errorContext, resp); + return resp; + } + + public static handlevV1DeliveriesFailureEvents( + error: NonNullable, + metaTo: MetaTransferObject, + ): DeliveriesResponse { + const errObj = generateErrorObject(error, metaTo.errorDetails, false); + const metadataArray = metaTo.metadatas; + if (!Array.isArray(metadataArray)) { + // Panic + throw new PlatformError('Proxy v1 endpoint error : metadataArray is not an array'); + } + const responses = metadataArray.map((metadata) => { + const resp = { + error: errObj.message || '[Delivery] Error occured while processing payload', + statusCode: errObj.status, + metadata, + } as DeliveryJobState; + return resp; + }); + + const resp = { + response: responses, + statTags: errObj.statTags, + } as DeliveriesResponse; + ErrorReportingService.reportError(error, metaTo.errorContext, resp); return resp; } diff --git a/src/types/index.ts b/src/types/index.ts index 7a23132173..f4432e5c2a 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -16,9 +16,46 @@ type ProcessorTransformationOutput = { FORM?: Record; }; files?: Record; - metadata?: Metadata; }; +type ProxyDeliveryRequest = { + version: string; + type: string; + method: string; + endpoint: string; + userId: string; + headers?: Record; + params?: Record; + body?: { + JSON?: Record; + JSON_ARRAY?: Record; + XML?: Record; + FORM?: Record; + }; + files?: Record; + metadata: Metadata; +}; + +type ProxyDeliveriesRequest = { + version: string; + type: string; + method: string; + endpoint: string; + userId: string; + headers?: Record; + params?: Record; + body?: { + JSON?: Record; + JSON_ARRAY?: Record; + XML?: Record; + FORM?: Record; + }; + files?: Record; + metadata: Metadata[]; +}; + +type ProxyRequest = ProxyDeliveryRequest | ProxyDeliveriesRequest; + type Metadata = { sourceId: string; workspaceId: string; @@ -50,6 +87,7 @@ type Metadata = { sourceDefinitionId: string; destinationDefinitionId: string; transformationId: string; + dontBatch?: boolean; }; type MessageIdMetadataMap = { @@ -140,7 +178,20 @@ type DeliveryResponse = { destinationResponse: any; statTags: object; authErrorCategory?: string; - response?: object; +}; + +type DeliveryJobState = { + error: string; + statusCode: number; + metadata: Metadata; +}; + +type DeliveriesResponse = { + status?: number; + message?: string; + statTags?: object; + authErrorCategory?: string; + response: DeliveryJobState[]; }; enum MessageType { @@ -254,26 +305,31 @@ type SourceInput = { source?: Source; }; export { - Metadata, + ComparatorInput, + DeliveryJobState, + DeliveryResponse, + DeliveriesResponse, + Destination, + ErrorDetailer, MessageIdMetadataMap, - UserTransformationLibrary, + MetaTransferObject, + Metadata, + ProcessorTransformationOutput, ProcessorTransformationRequest, ProcessorTransformationResponse, + ProxyDeliveriesRequest, + ProxyDeliveryRequest, + ProxyRequest, RouterTransformationRequest, RouterTransformationRequestData, RouterTransformationResponse, RudderMessage, - ProcessorTransformationOutput, SourceTransformationResponse, - DeliveryResponse, - ErrorDetailer, - UserTransformationResponse, - UserTransformationServiceResponse, - MetaTransferObject, UserDeletionRequest, UserDeletionResponse, - Destination, - ComparatorInput, SourceInput, Source, + UserTransformationLibrary, + UserTransformationResponse, + UserTransformationServiceResponse, }; diff --git a/src/v0/destinations/campaign_manager/networkHandler.js b/src/v0/destinations/campaign_manager/networkHandler.js index 63efff5b50..a1fa24835c 100644 --- a/src/v0/destinations/campaign_manager/networkHandler.js +++ b/src/v0/destinations/campaign_manager/networkHandler.js @@ -76,7 +76,7 @@ const responseHandler = (destinationResponse) => { throw new NetworkError( `Campaign Manager: ${response.error?.message} during CAMPAIGN_MANAGER response transformation 3`, - status, + 500, { [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(status), }, diff --git a/src/v0/destinations/salesforce/networkHandler.js b/src/v0/destinations/salesforce/networkHandler.js index dc67aff1b7..918084cc89 100644 --- a/src/v0/destinations/salesforce/networkHandler.js +++ b/src/v0/destinations/salesforce/networkHandler.js @@ -10,7 +10,7 @@ const responseHandler = (destinationResponse, destType) => { destinationResponse, 'during Salesforce Response Handling', destinationResponse?.rudderJobMetadata?.destInfo?.authKey, - LEGACY + LEGACY, ); // else successfully return status as 200, message and original destination response diff --git a/src/v0/destinations/salesforce_oauth/networkHandler.js b/src/v0/destinations/salesforce_oauth/networkHandler.js index 2042830cb1..2bcace31c9 100644 --- a/src/v0/destinations/salesforce_oauth/networkHandler.js +++ b/src/v0/destinations/salesforce_oauth/networkHandler.js @@ -10,7 +10,7 @@ const responseHandler = (destinationResponse, destType) => { destinationResponse, 'during Salesforce Response Handling', destinationResponse?.rudderJobMetadata?.destInfo?.authKey, - OAUTH + OAUTH, ); // else successfully return status as 200, message and original destination response diff --git a/src/v0/util/errorTypes/index.js b/src/v0/util/errorTypes/index.js index 80268c3e77..f3cef657ca 100644 --- a/src/v0/util/errorTypes/index.js +++ b/src/v0/util/errorTypes/index.js @@ -1,5 +1,7 @@ const FilteredEventsError = require('./filteredEventsError'); +const TransformerProxyError = require('./transformerProxyError'); module.exports = { FilteredEventsError, + TransformerProxyError, }; diff --git a/src/v0/util/errorTypes/transformerProxyError.js b/src/v0/util/errorTypes/transformerProxyError.js new file mode 100644 index 0000000000..9f4bb593c7 --- /dev/null +++ b/src/v0/util/errorTypes/transformerProxyError.js @@ -0,0 +1,28 @@ +const tags = require('../tags'); +const { BaseError } = require('./base'); + +const errorTypes = Object.values(tags.ERROR_TYPES); +const metaTypes = Object.values(tags.METADATA); +class TransformerProxyError extends BaseError { + constructor(message, statusCode, statTags, destResponse, authErrorCategory, response) { + const finalStatTags = { + [tags.TAG_NAMES.ERROR_CATEGORY]: tags.ERROR_CATEGORIES.NETWORK, + [tags.TAG_NAMES.ERROR_TYPE]: tags.ERROR_TYPES.ABORTED, + }; + + // Allow specifying only error type and meta tags + if (statTags && typeof statTags === 'object' && !Array.isArray(statTags)) { + if (errorTypes.includes(statTags[tags.TAG_NAMES.ERROR_TYPE])) { + finalStatTags[tags.TAG_NAMES.ERROR_TYPE] = statTags[tags.TAG_NAMES.ERROR_TYPE]; + } + + if (metaTypes.includes(statTags[tags.TAG_NAMES.META])) { + finalStatTags[tags.TAG_NAMES.META] = statTags[tags.TAG_NAMES.META]; + } + } + super(message, statusCode, finalStatTags, destResponse, authErrorCategory); + this.response = response; + } +} + +module.exports = TransformerProxyError; \ No newline at end of file diff --git a/src/v1/destinations/campaign_manager/networkHandler.js b/src/v1/destinations/campaign_manager/networkHandler.js index b3b82c8cf3..6e13a68f0a 100644 --- a/src/v1/destinations/campaign_manager/networkHandler.js +++ b/src/v1/destinations/campaign_manager/networkHandler.js @@ -1,6 +1,6 @@ /* eslint-disable no-param-reassign */ /* eslint-disable no-restricted-syntax */ -const { NetworkError } = require('@rudderstack/integrations-lib'); +const { TransformerProxyError } = require('../../../v0/util/errorTypes'); const { prepareProxyRequest, proxyRequest } = require('../../../adapters/network'); const { isHttpStatusSuccess, getAuthErrCategoryFromStCode } = require('../../../v0/util/index'); @@ -10,25 +10,6 @@ const { } = require('../../../adapters/utils/networkUtils'); const tags = require('../../../v0/util/tags'); -function isEventRetryableAndExtractErrMsg(element, proxyOutputObj) { - let isRetryable = false; - let errorMsg = ''; - // success event - if (!element.errors) { - return isRetryable; - } - for (const err of element.errors) { - errorMsg += `${err.message}, `; - if (err.code === 'INTERNAL') { - isRetryable = true; - } - } - if (errorMsg) { - proxyOutputObj.error = errorMsg; - } - return isRetryable; -} - function isEventAbortableAndExtractErrMsg(element, proxyOutputObj) { let isAbortable = false; let errorMsg = ''; @@ -68,10 +49,8 @@ const responseHandler = (destinationResponse) => { metadata: rudderJobMetadata[idx], error: 'success', }; - // update status of partial event as per retriable or abortable - if (isEventRetryableAndExtractErrMsg(element, proxyOutputObj)) { - proxyOutputObj.statusCode = 500; - } else if (isEventAbortableAndExtractErrMsg(element, proxyOutputObj)) { + // update status of partial event if abortable + if (isEventAbortableAndExtractErrMsg(element, proxyOutputObj)) { proxyOutputObj.statusCode = 400; } responseWithIndividualEvents.push(proxyOutputObj); @@ -95,16 +74,16 @@ const responseHandler = (destinationResponse) => { }); } - throw new NetworkError( - `Campaign Manager: Error transformer proxy v1 during CAMPAIGN_MANAGER response transformation`, - 500, - { - [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(status), - }, - destinationResponse, - getAuthErrCategoryFromStCode(status), - responseWithIndividualEvents, - ); + throw new TransformerProxyError( + `Campaign Manager: Error transformer proxy v1 during CAMPAIGN_MANAGER response transformation`, + 500, + { + [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(status), + }, + destinationResponse, + getAuthErrCategoryFromStCode(status), + responseWithIndividualEvents, + ); }; function networkHandler() { diff --git a/test/__tests__/data/marketo_input.json b/test/__tests__/data/marketo_input.json index 10fff935fc..122525560e 100644 --- a/test/__tests__/data/marketo_input.json +++ b/test/__tests__/data/marketo_input.json @@ -55,12 +55,7 @@ "includeKeys": [], "saveDestinationResponse": true, "secretKeys": [], - "supportedMessageTypes": [ - "identify", - "page", - "screen", - "track" - ], + "supportedMessageTypes": ["identify", "page", "screen", "track"], "supportedSourceTypes": [ "android", "ios", @@ -1125,12 +1120,7 @@ "includeKeys": [], "saveDestinationResponse": true, "secretKeys": [], - "supportedMessageTypes": [ - "identify", - "page", - "screen", - "track" - ], + "supportedMessageTypes": ["identify", "page", "screen", "track"], "supportedSourceTypes": [ "android", "ios", @@ -1164,4 +1154,4 @@ "query": {} } } -] \ No newline at end of file +] diff --git a/test/integrations/destinations/braze/dataDelivery/data.ts b/test/integrations/destinations/braze/dataDelivery/data.ts index 3e1805c01d..cd688a621b 100644 --- a/test/integrations/destinations/braze/dataDelivery/data.ts +++ b/test/integrations/destinations/braze/dataDelivery/data.ts @@ -1,395 +1,391 @@ -import MockAdapter from "axios-mock-adapter"; +import MockAdapter from 'axios-mock-adapter'; export const data = [ { - "name": "braze", - "description": "Test 0", - "feature": "dataDelivery", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": { - "type": "REST", - "endpoint": "https://rest.iad-03.braze.com/users/identify/test1", - "method": "POST", - "userId": "gabi_userId_45", - "headers": { - "Accept": "application/json", - "Authorization": "Bearer api_key", - "Content-Type": "application/json" - }, - "body": { - "FORM": {}, - "JSON": { - "aliases_to_identify": [ + name: 'braze', + description: 'Test 0', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + type: 'REST', + endpoint: 'https://rest.iad-03.braze.com/users/identify/test1', + method: 'POST', + userId: 'gabi_userId_45', + headers: { + Accept: 'application/json', + Authorization: 'Bearer api_key', + 'Content-Type': 'application/json', + }, + body: { + FORM: {}, + JSON: { + aliases_to_identify: [ { - "external_id": "gabi_userId_45", - "user_alias": { - "alias_label": "rudder_id", - "alias_name": "gabi_anonId_45" - } - } - ] + external_id: 'gabi_userId_45', + user_alias: { + alias_label: 'rudder_id', + alias_name: 'gabi_anonId_45', + }, + }, + ], }, - "JSON_ARRAY": {}, - "XML": {} + JSON_ARRAY: {}, + XML: {}, + }, + files: {}, + params: { + destination: 'braze', }, - "files": {}, - "params": { - "destination": "braze" - } }, - "method": "POST" - } + method: 'POST', + }, }, - "output": { - "response": { - "status": 200, - "body": { - "output": { - "status": 201, - "message": "Request for braze Processed Successfully", - "destinationResponse": { - "response": { - "aliases_processed": 1, - "message": "success" + output: { + response: { + status: 200, + body: { + output: { + status: 201, + message: 'Request for braze Processed Successfully', + destinationResponse: { + response: { + aliases_processed: 1, + message: 'success', }, - "status": 201 - } - } - } - } - } + status: 201, + }, + }, + }, + }, + }, }, { - "name": "braze", - "description": "Test 1", - "feature": "dataDelivery", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": { - "type": "REST", - "endpoint": "https://rest.iad-03.braze.com/users/identify/test2", - "method": "POST", - "userId": "gabi_userId_45", - "headers": { - "Accept": "application/json", - "Authorization": "Bearer api_key", - "Content-Type": "application/json" - }, - "body": { - "FORM": {}, - "JSON": { - "aliases_to_identify": [ + name: 'braze', + description: 'Test 1', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + type: 'REST', + endpoint: 'https://rest.iad-03.braze.com/users/identify/test2', + method: 'POST', + userId: 'gabi_userId_45', + headers: { + Accept: 'application/json', + Authorization: 'Bearer api_key', + 'Content-Type': 'application/json', + }, + body: { + FORM: {}, + JSON: { + aliases_to_identify: [ { - "external_id": "gabi_userId_45", - "user_alias": { - "alias_label": "rudder_id", - "alias_name": "gabi_anonId_45" - } - } - ] + external_id: 'gabi_userId_45', + user_alias: { + alias_label: 'rudder_id', + alias_name: 'gabi_anonId_45', + }, + }, + ], }, - "JSON_ARRAY": {}, - "XML": {} + JSON_ARRAY: {}, + XML: {}, + }, + files: {}, + params: { + destination: 'braze', }, - "files": {}, - "params": { - "destination": "braze" - } }, - "method": "POST" - } + method: 'POST', + }, }, - "output": { - "response": { - "status": 200, - "body": { - "output": { - "status": 201, - "message": "Request for braze Processed Successfully", - "destinationResponse": { - "response": { - "message": "success", - "errors": [ - "minor error message" - ] + output: { + response: { + status: 200, + body: { + output: { + status: 201, + message: 'Request for braze Processed Successfully', + destinationResponse: { + response: { + message: 'success', + errors: ['minor error message'], }, - "status": 201 - } - } - } - } - } + status: 201, + }, + }, + }, + }, + }, }, { - "name": "braze", - "description": "Test 2", - "feature": "dataDelivery", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": { - "type": "REST", - "endpoint": "https://rest.iad-03.braze.com/users/identify/test3", - "method": "POST", - "userId": "gabi_userId_45", - "headers": { - "Accept": "application/json", - "Authorization": "Bearer api_key", - "Content-Type": "application/json" - }, - "body": { - "FORM": {}, - "JSON": { - "aliases_to_identify": [ + name: 'braze', + description: 'Test 2', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + type: 'REST', + endpoint: 'https://rest.iad-03.braze.com/users/identify/test3', + method: 'POST', + userId: 'gabi_userId_45', + headers: { + Accept: 'application/json', + Authorization: 'Bearer api_key', + 'Content-Type': 'application/json', + }, + body: { + FORM: {}, + JSON: { + aliases_to_identify: [ { - "external_id": "gabi_userId_45", - "user_alias": { - "alias_label": "rudder_id", - "alias_name": "gabi_anonId_45" - } - } - ] + external_id: 'gabi_userId_45', + user_alias: { + alias_label: 'rudder_id', + alias_name: 'gabi_anonId_45', + }, + }, + ], }, - "JSON_ARRAY": {}, - "XML": {} + JSON_ARRAY: {}, + XML: {}, + }, + files: {}, + params: { + destination: 'braze', }, - "files": {}, - "params": { - "destination": "braze" - } }, - "method": "POST" - } + method: 'POST', + }, }, - "output": { - "response": { - "status": 200, - "body": { - "output": { - "status": 201, - "message": "Request failed for braze with status: 201", - "destinationResponse": { - "response": { - "message": "fatal error message", - "errors": [ - "minor error message" - ] + output: { + response: { + status: 200, + body: { + output: { + status: 201, + message: 'Request failed for braze with status: 201', + destinationResponse: { + response: { + message: 'fatal error message', + errors: ['minor error message'], }, - "status": 201 + status: 201, + }, + statTags: { + destType: 'BRAZE', + errorCategory: 'network', + destinationId: 'Non-determininable', + workspaceId: 'Non-determininable', + errorType: 'aborted', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', }, - "statTags": { - "destType": "BRAZE", - "errorCategory": "network", - "destinationId": "Non-determininable", - "workspaceId": "Non-determininable", - "errorType": "aborted", - "feature": "dataDelivery", - "implementation": "native", - "module": "destination" - } - } - } - } - } + }, + }, + }, + }, }, { - "name": "braze", - "description": "Test 3", - "feature": "dataDelivery", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": { - "type": "REST", - "endpoint": "https://rest.iad-03.braze.com/users/identify/test4", - "method": "POST", - "userId": "gabi_userId_45", - "headers": { - "Accept": "application/json", - "Authorization": "Bearer api_key", - "Content-Type": "application/json" - }, - "body": { - "FORM": {}, - "JSON": { - "aliases_to_identify": [ + name: 'braze', + description: 'Test 3', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + type: 'REST', + endpoint: 'https://rest.iad-03.braze.com/users/identify/test4', + method: 'POST', + userId: 'gabi_userId_45', + headers: { + Accept: 'application/json', + Authorization: 'Bearer api_key', + 'Content-Type': 'application/json', + }, + body: { + FORM: {}, + JSON: { + aliases_to_identify: [ { - "external_id": "gabi_userId_45", - "user_alias": { - "alias_label": "rudder_id", - "alias_name": "gabi_anonId_45" - } - } - ] + external_id: 'gabi_userId_45', + user_alias: { + alias_label: 'rudder_id', + alias_name: 'gabi_anonId_45', + }, + }, + ], }, - "JSON_ARRAY": {}, - "XML": {} + JSON_ARRAY: {}, + XML: {}, + }, + files: {}, + params: { + destination: 'braze', }, - "files": {}, - "params": { - "destination": "braze" - } }, - "method": "POST" - } + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + status: 201, + message: 'Request for braze Processed Successfully', + destinationResponse: { + response: '', + status: 201, + }, + }, + }, + }, }, - "output": { - "response": { - "status": 200, - "body": { - "output": { - "status": 201, - "message": "Request for braze Processed Successfully", - "destinationResponse": { - "response": "", - "status": 201 - } - } - } - } - } }, { - "name": "braze", - "description": "Test 4", - "feature": "dataDelivery", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": { - "type": "REST", - "endpoint": "https://rest.iad-03.braze.com/users/identify/test5", - "method": "POST", - "userId": "gabi_userId_45", - "headers": { - "Accept": "application/json", - "Authorization": "Bearer api_key", - "Content-Type": "application/json" - }, - "body": { - "FORM": {}, - "JSON": { - "aliases_to_identify": [ + name: 'braze', + description: 'Test 4', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + type: 'REST', + endpoint: 'https://rest.iad-03.braze.com/users/identify/test5', + method: 'POST', + userId: 'gabi_userId_45', + headers: { + Accept: 'application/json', + Authorization: 'Bearer api_key', + 'Content-Type': 'application/json', + }, + body: { + FORM: {}, + JSON: { + aliases_to_identify: [ { - "external_id": "gabi_userId_45", - "user_alias": { - "alias_label": "rudder_id", - "alias_name": "gabi_anonId_45" - } - } - ] + external_id: 'gabi_userId_45', + user_alias: { + alias_label: 'rudder_id', + alias_name: 'gabi_anonId_45', + }, + }, + ], }, - "JSON_ARRAY": {}, - "XML": {} + JSON_ARRAY: {}, + XML: {}, + }, + files: {}, + params: { + destination: 'braze', }, - "files": {}, - "params": { - "destination": "braze" - } }, - "method": "POST" - } + method: 'POST', + }, }, - "output": { - "response": { - "status": 500, - "body": { - "output": { - "status": 500, - "message": "Request failed for braze with status: 500", - "destinationResponse": { - "response": "", - "status": 500 + output: { + response: { + status: 500, + body: { + output: { + status: 500, + message: 'Request failed for braze with status: 500', + destinationResponse: { + response: '', + status: 500, + }, + statTags: { + destType: 'BRAZE', + errorCategory: 'network', + destinationId: 'Non-determininable', + workspaceId: 'Non-determininable', + errorType: 'retryable', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', }, - "statTags": { - "destType": "BRAZE", - "errorCategory": "network", - "destinationId": "Non-determininable", - "workspaceId": "Non-determininable", - "errorType": "retryable", - "feature": "dataDelivery", - "implementation": "native", - "module": "destination" - } - } - } - } - } + }, + }, + }, + }, }, { - "name": "braze", - "description": "Test 5", - "feature": "dataDelivery", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": { - "type": "REST", - "endpoint": "https://rest.iad-03.braze.com/users/identify/test6", - "method": "POST", - "userId": "gabi_userId_45", - "headers": { - "Accept": "application/json", - "Authorization": "Bearer api_key", - "Content-Type": "application/json" - }, - "body": { - "FORM": {}, - "JSON": { - "aliases_to_identify": [ + name: 'braze', + description: 'Test 5', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + type: 'REST', + endpoint: 'https://rest.iad-03.braze.com/users/identify/test6', + method: 'POST', + userId: 'gabi_userId_45', + headers: { + Accept: 'application/json', + Authorization: 'Bearer api_key', + 'Content-Type': 'application/json', + }, + body: { + FORM: {}, + JSON: { + aliases_to_identify: [ { - "external_id": "gabi_userId_45", - "user_alias": { - "alias_label": "rudder_id", - "alias_name": "gabi_anonId_45" - } - } - ] + external_id: 'gabi_userId_45', + user_alias: { + alias_label: 'rudder_id', + alias_name: 'gabi_anonId_45', + }, + }, + ], }, - "JSON_ARRAY": {}, - "XML": {} + JSON_ARRAY: {}, + XML: {}, + }, + files: {}, + params: { + destination: 'braze', }, - "files": {}, - "params": { - "destination": "braze" - } }, - "method": "POST" - } + method: 'POST', + }, }, - "output": { - "response": { - "status": 500, - "body": { - "output": { - "status": 500, - "message": "Request failed for braze with status: 500", - "destinationResponse": { - "response": "", - "status": 500 + output: { + response: { + status: 500, + body: { + output: { + status: 500, + message: 'Request failed for braze with status: 500', + destinationResponse: { + response: '', + status: 500, }, - "statTags": { - "destType": "BRAZE", - "errorCategory": "network", - "destinationId": "Non-determininable", - "workspaceId": "Non-determininable", - "errorType": "retryable", - "feature": "dataDelivery", - "implementation": "native", - "module": "destination" - } - } - } - } + statTags: { + destType: 'BRAZE', + errorCategory: 'network', + destinationId: 'Non-determininable', + workspaceId: 'Non-determininable', + errorType: 'retryable', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', + }, + }, + }, + }, }, mockFns: (mockAdapter: MockAdapter) => { // params has `{ destination: salesforce }` @@ -410,79 +406,262 @@ export const data = [ 'Content-Type': 'application/json', 'User-Agent': 'RudderLabs', }, - ).replyOnce((config) => { - // @ts-ignore - const err = AxiosError.from('DNS not found', 'ENOTFOUND', config) - return Promise.reject(err); + ) + .replyOnce((config) => { + // @ts-ignore + const err = AxiosError.from('DNS not found', 'ENOTFOUND', config); + return Promise.reject(err); }); - } + }, + }, + { + name: 'braze', + description: 'Test 6', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + type: 'REST', + endpoint: 'https://rest.iad-03.braze.com/users/identify/test7', + method: 'POST', + userId: 'gabi_userId_45', + headers: { + Accept: 'application/json', + Authorization: 'Bearer api_key', + 'Content-Type': 'application/json', + }, + body: { + FORM: {}, + JSON: { + aliases_to_identify: [ + { + external_id: 'gabi_userId_45', + user_alias: { + alias_label: 'rudder_id', + alias_name: 'gabi_anonId_45', + }, + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + }, + files: {}, + params: { + destination: 'braze', + }, + }, + method: 'POST', + }, + }, + output: { + response: { + status: 500, + body: { + output: { + status: 500, + message: 'Request failed for braze with status: 500', + destinationResponse: { + response: '', + status: 500, + }, + statTags: { + destType: 'BRAZE', + errorCategory: 'network', + destinationId: 'Non-determininable', + workspaceId: 'Non-determininable', + errorType: 'retryable', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', + }, + }, + }, + }, + }, + }, + { + name: 'braze', + description: 'Test Transformer Proxy V1 input with v0 proxy handler', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: { + type: 'REST', + endpoint: 'https://rest.iad-03.braze.com/users/identify/test1', + method: 'POST', + userId: 'gabi_userId_45', + headers: { + Accept: 'application/json', + Authorization: 'Bearer api_key', + 'Content-Type': 'application/json', + }, + body: { + FORM: {}, + JSON: { + aliases_to_identify: [ + { + external_id: 'gabi_userId_45', + user_alias: { + alias_label: 'rudder_id', + alias_name: 'gabi_anonId_45', + }, + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + }, + metadata: [ + { + jobId: 2, + attemptNum: 0, + userId: '', + sourceId: '2Vsge2uWYdrLfG7pZb5Y82eo4lr', + destinationId: '2RHh08uOsXqE9KvCDg3hoaeuK2L', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', + secret: { + access_token: 'secret', + refresh_token: 'refresh', + developer_token: 'developer_Token', + }, + }, + ], + files: {}, + params: { + destination: 'braze', + }, + }, + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: '{"aliases_processed":1,"message":"success"}', + statusCode: 201, + metadata: { + jobId: 2, + attemptNum: 0, + userId: '', + sourceId: '2Vsge2uWYdrLfG7pZb5Y82eo4lr', + destinationId: '2RHh08uOsXqE9KvCDg3hoaeuK2L', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', + secret: { + access_token: 'secret', + refresh_token: 'refresh', + developer_token: 'developer_Token', + }, + }, + }, + ], + }, + }, + }, + }, }, { - "name": "braze", - "description": "Test 6", - "feature": "dataDelivery", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": { - "type": "REST", - "endpoint": "https://rest.iad-03.braze.com/users/identify/test7", - "method": "POST", - "userId": "gabi_userId_45", - "headers": { - "Accept": "application/json", - "Authorization": "Bearer api_key", - "Content-Type": "application/json" - }, - "body": { - "FORM": {}, - "JSON": { - "aliases_to_identify": [ + name: 'braze', + description: 'Test Transformer Proxy V1 input with v0 proxy handler Error returned', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: { + type: 'REST', + endpoint: 'https://rest.iad-03.braze.com/users/identify/testV1', + method: 'POST', + userId: 'gabi_userId_45', + headers: { + Accept: 'application/json', + Authorization: 'Bearer api_key', + 'Content-Type': 'application/json', + }, + body: { + FORM: {}, + JSON: { + aliases_to_identify: [ { - "external_id": "gabi_userId_45", - "user_alias": { - "alias_label": "rudder_id", - "alias_name": "gabi_anonId_45" - } - } - ] + external_id: 'gabi_userId_45', + user_alias: { + alias_label: 'rudder_id', + alias_name: 'gabi_anonId_45', + }, + }, + ], }, - "JSON_ARRAY": {}, - "XML": {} + JSON_ARRAY: {}, + XML: {}, + }, + metadata: [ + { + jobId: 2, + attemptNum: 0, + userId: '', + sourceId: '2Vsge2uWYdrLfG7pZb5Y82eo4lr', + destinationId: '2RHh08uOsXqE9KvCDg3hoaeuK2L', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', + secret: { + access_token: 'secret', + refresh_token: 'refresh', + developer_token: 'developer_Token', + }, + }, + ], + files: {}, + params: { + destination: 'braze', }, - "files": {}, - "params": { - "destination": "braze" - } }, - "method": "POST" - } + method: 'POST', + }, }, - "output": { - "response": { - "status": 500, - "body": { - "output": { - "status": 500, - "message": "Request failed for braze with status: 500", - "destinationResponse": { - "response": "", - "status": 500 + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: 'Request failed for braze with status: 401', + statusCode: 401, + metadata: { + jobId: 2, + attemptNum: 0, + userId: '', + sourceId: '2Vsge2uWYdrLfG7pZb5Y82eo4lr', + destinationId: '2RHh08uOsXqE9KvCDg3hoaeuK2L', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', + secret: { + access_token: 'secret', + refresh_token: 'refresh', + developer_token: 'developer_Token', + }, + }, + }, + ], + statTags: { + destType: 'BRAZE', + destinationId: '2RHh08uOsXqE9KvCDg3hoaeuK2L', + errorCategory: 'network', + errorType: 'aborted', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', }, - "statTags": { - "destType": "BRAZE", - "errorCategory": "network", - "destinationId": "Non-determininable", - "workspaceId": "Non-determininable", - "errorType": "retryable", - "feature": "dataDelivery", - "implementation": "native", - "module": "destination" - } - } - } - } - } - } -] \ No newline at end of file + }, + }, + }, + }, + }, +]; diff --git a/test/integrations/destinations/braze/network.ts b/test/integrations/destinations/braze/network.ts index 1c39a247e4..0ef99b806d 100644 --- a/test/integrations/destinations/braze/network.ts +++ b/test/integrations/destinations/braze/network.ts @@ -391,5 +391,34 @@ const deleteNwData = [ }, }, }, + { + httpReq: { + url: 'https://rest.iad-03.braze.com/users/identify/testV1', + data: { + aliases_to_identify: [ + { + external_id: 'gabi_userId_45', + user_alias: { alias_label: 'rudder_id', alias_name: 'gabi_anonId_45' }, + }, + ], + }, + params: { destination: 'braze' }, + headers: { + Accept: 'application/json', + Authorization: 'Bearer api_key', + 'Content-Type': 'application/json', + 'User-Agent': 'RudderLabs', + }, + method: 'POST', + }, + httpRes: { + data: { + code: 400, + message: 'Bad Req', + status: 'Fail Case', + }, + status: 401, + }, + }, ]; export const networkCallsData = [...deleteNwData, ...dataDeliveryMocksData]; From 36d3f258ed5ea4ba1899c8b2cae8203bf73d90ed Mon Sep 17 00:00:00 2001 From: Yashasvi Bajpai <33063622+yashasvibajpai@users.noreply.github.com> Date: Mon, 11 Dec 2023 13:37:54 +0530 Subject: [PATCH 71/93] feat: onboard msl changes for new record event (#2644) * feat: onboard msl changes for new record event * chore: remove older tc for MSL * fix: metadata * fix: metadatax2 * chore: address comments * chore: address commentsx2, handle mix of audiencelist and record events * chore: address commentsx2, handle mix of audiencelist and record events * chore: add router test * fix: record to audience handling (#2813) * fix: unit case with empty request * fix: missed error lib * chore: refactor tests * refactor: address comments * chore: address commentsx2 * fix: error message, handle metadata, missing id --------- Co-authored-by: Utsab Chowdhury --- .../marketo_static_list/testData/constants.js | 45 + .../marketo_static_list/testData/testData.js | 3085 +++++++++++++++++ .../marketo_static_list/transform.js | 126 +- .../marketo_static_list/transform.test.js | 138 + .../marketo_static_list/transformV2.js | 143 + .../destinations/marketo_static_list/util.js | 1 + test/__tests__/data/marketo_static_list.json | 2542 -------------- .../marketo_static_list_router_input.json | 1209 ------- ...eto_static_list_router_metadata_input.json | 69 - ...to_static_list_router_metadata_output.json | 20 - .../marketo_static_list_router_output.json | 170 - test/__tests__/marketo_static_list.test.js | 64 - .../marketo_static_list/processor/data.ts | 8 +- .../marketo_static_list/router/data.ts | 2356 ++++++++++++- 14 files changed, 5783 insertions(+), 4193 deletions(-) create mode 100644 src/v0/destinations/marketo_static_list/testData/constants.js create mode 100644 src/v0/destinations/marketo_static_list/testData/testData.js create mode 100644 src/v0/destinations/marketo_static_list/transform.test.js create mode 100644 src/v0/destinations/marketo_static_list/transformV2.js delete mode 100644 test/__tests__/data/marketo_static_list.json delete mode 100644 test/__tests__/data/marketo_static_list_router_input.json delete mode 100644 test/__tests__/data/marketo_static_list_router_metadata_input.json delete mode 100644 test/__tests__/data/marketo_static_list_router_metadata_output.json delete mode 100644 test/__tests__/data/marketo_static_list_router_output.json delete mode 100644 test/__tests__/marketo_static_list.test.js diff --git a/src/v0/destinations/marketo_static_list/testData/constants.js b/src/v0/destinations/marketo_static_list/testData/constants.js new file mode 100644 index 0000000000..2c420c6bc2 --- /dev/null +++ b/src/v0/destinations/marketo_static_list/testData/constants.js @@ -0,0 +1,45 @@ +const EXTERNAL_ID = 'marketoStaticListId'; +const TOKEN = 'Bearer access_token_success'; +const CONTENT_TYPE = 'application/json'; +const DEST_CONFIG = { + clientId: 'marketo_client_id_success', + clientSecret: 'marketo_client_secret_success', + accountId: 'marketo_acct_id_success', + staticListId: 1234, +}; +const DEST_DEFINITION = { + ID: '1iVQvTRMsPPyJzwol0ifH93QTQ6', + Name: 'MARKETO', + DisplayName: 'Marketo', + transformAt: 'processor', + transformAtV1: 'processor', +}; +const DEST_OBJECT = { + ID: '1zwa1wKshSt81YksKmUdJnr4IOK', + Name: 'test_marketo_rc', + DestinationDefinition: DEST_DEFINITION, + Config: { + clientId: 'marketo_client_id_success', + clientSecret: 'marketo_client_secret_success', + accountId: 'marketo_acct_id_success', + staticListId: 1122, + }, + Enabled: true, + Transformations: [], + IsProcessorEnabled: true, +}; +const MESSAGE_SOURCES_CONTEXT = { + job_id: '2VsZs4hyPpq7f1p8igrpmHsibHl', + job_run_id: 'ck99nbd2kqiljdihhkh0', + task_run_id: 'ck99nbd2kqiljdihhkhg', +}; + +module.exports = { + EXTERNAL_ID, + TOKEN, + CONTENT_TYPE, + DEST_OBJECT, + DEST_DEFINITION, + MESSAGE_SOURCES_CONTEXT, + DEST_CONFIG, +}; diff --git a/src/v0/destinations/marketo_static_list/testData/testData.js b/src/v0/destinations/marketo_static_list/testData/testData.js new file mode 100644 index 0000000000..45328436ce --- /dev/null +++ b/src/v0/destinations/marketo_static_list/testData/testData.js @@ -0,0 +1,3085 @@ +const { + EXTERNAL_ID, + TOKEN, + CONTENT_TYPE, + DEST_OBJECT, + DEST_DEFINITION, + MESSAGE_SOURCES_CONTEXT, + DEST_CONFIG, +} = require('./constants'); + +const recordInputs = [ + { + destination: DEST_OBJECT, + message: { + type: 'record', + action: 'insert', + fields: { + id: 1001, + }, + channel: 'sources', + context: { + sources: MESSAGE_SOURCES_CONTEXT, + externalId: [ + { + type: EXTERNAL_ID, + id: 'id001', + }, + ], + destinationFields: 'id', + mappedToDestination: 'true', + }, + recordId: '3', + }, + metadata: { + jobId: 1, + }, + }, + { + destination: DEST_OBJECT, + message: { + type: 'record', + action: 'insert', + fields: { + id: 1002, + }, + channel: 'sources', + context: { + sources: MESSAGE_SOURCES_CONTEXT, + externalId: [ + { + type: EXTERNAL_ID, + id: 'id002', + }, + ], + destinationFields: 'id', + mappedToDestination: 'true', + }, + recordId: '3', + }, + metadata: { + jobId: 2, + }, + }, + { + destination: DEST_OBJECT, + message: { + type: 'record', + action: 'insert', + fields: { + id: 1003, + }, + channel: 'sources', + context: { + sources: MESSAGE_SOURCES_CONTEXT, + externalId: [ + { + type: EXTERNAL_ID, + id: 'id001', + }, + ], + destinationFields: 'id', + mappedToDestination: 'true', + }, + recordId: '3', + }, + metadata: { + jobId: 3, + }, + }, + { + destination: DEST_OBJECT, + message: { + action: 'delete', + context: { + destinationFields: 'id', + externalId: [ + { + id: 'id002', + type: EXTERNAL_ID, + }, + ], + mappedToDestination: 'true', + sources: { + job_id: 'sf', + job_run_id: 'ck985bve58cvnti48120', + task_run_id: 'ck985bve58cvnti4812g', + version: '', + }, + }, + recordId: '2', + rudderId: '2', + fields: { + id: '2001', + }, + type: 'record', + }, + metadata: { + jobId: 4, + }, + }, +]; + +const recordOutput = [ + { + batchedRequest: [ + { + version: '1', + type: 'REST', + method: 'POST', + endpoint: + 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/id001/leads.json?id=1001&id=1003', + headers: { + Authorization: TOKEN, + 'Content-Type': CONTENT_TYPE, + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + }, + ], + metadata: [ + { + jobId: 1, + }, + { + jobId: 3, + }, + ], + batched: true, + statusCode: 200, + destination: DEST_OBJECT, + }, + { + batchedRequest: [ + { + version: '1', + type: 'REST', + method: 'DELETE', + endpoint: + 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/id002/leads.json?id=2001', + headers: { + Authorization: TOKEN, + 'Content-Type': CONTENT_TYPE, + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + }, + ], + metadata: [ + { + jobId: 4, + }, + ], + batched: true, + statusCode: 200, + destination: DEST_OBJECT, + }, + { + batchedRequest: [ + { + version: '1', + type: 'REST', + method: 'POST', + endpoint: + 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/id002/leads.json?id=1002', + headers: { + Authorization: TOKEN, + 'Content-Type': CONTENT_TYPE, + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + }, + ], + metadata: [ + { + jobId: 2, + }, + ], + batched: true, + statusCode: 200, + destination: DEST_OBJECT, + }, +]; + +const audiencelistInputs = [ + { + destination: { + ID: '1zia9wKshXt80YksLmUdJnr7IHI', + Name: 'test_marketo', + DestinationDefinition: DEST_DEFINITION, + Config: DEST_CONFIG, + Enabled: true, + Transformations: [], + IsProcessorEnabled: true, + }, + message: { + userId: 'user 1', + anonymousId: 'anon-id-new', + event: 'event1', + type: 'audiencelist', + properties: { + listData: { + add: [ + { + id: 501, + }, + { + id: 502, + }, + { + id: 503, + }, + ], + remove: [ + { + id: 704, + }, + { + id: 705, + }, + { + id: 706, + }, + ], + }, + enablePartialFailure: true, + }, + context: { + library: { + name: 'http', + }, + }, + timestamp: '2020-02-02T00:23:09.544Z', + }, + metadata: { + jobId: 1, + }, + }, + { + destination: { + ID: '1zia9wKshXt80YksLmUdJnr7IHI', + Name: 'test_marketo', + DestinationDefinition: DEST_DEFINITION, + Config: DEST_CONFIG, + Enabled: true, + Transformations: [], + IsProcessorEnabled: true, + }, + message: { + userId: 'user 1', + anonymousId: 'anon-id-new', + event: 'event1', + type: 'audiencelist', + properties: { + listData: { + add: [ + { + id: 0, + }, + { + id: 1, + }, + { + id: 2, + }, + { + id: 3, + }, + { + id: 4, + }, + { + id: 5, + }, + { + id: 6, + }, + { + id: 7, + }, + { + id: 8, + }, + { + id: 9, + }, + { + id: 10, + }, + { + id: 11, + }, + { + id: 12, + }, + { + id: 13, + }, + { + id: 14, + }, + { + id: 15, + }, + { + id: 16, + }, + { + id: 17, + }, + { + id: 18, + }, + { + id: 19, + }, + { + id: 20, + }, + { + id: 21, + }, + { + id: 22, + }, + { + id: 23, + }, + { + id: 24, + }, + { + id: 25, + }, + { + id: 26, + }, + { + id: 27, + }, + { + id: 28, + }, + { + id: 29, + }, + { + id: 30, + }, + { + id: 31, + }, + { + id: 32, + }, + { + id: 33, + }, + { + id: 34, + }, + { + id: 35, + }, + { + id: 36, + }, + { + id: 37, + }, + { + id: 38, + }, + { + id: 39, + }, + { + id: 40, + }, + { + id: 41, + }, + { + id: 42, + }, + { + id: 43, + }, + { + id: 44, + }, + { + id: 45, + }, + { + id: 46, + }, + { + id: 47, + }, + { + id: 48, + }, + { + id: 49, + }, + { + id: 50, + }, + { + id: 51, + }, + { + id: 52, + }, + { + id: 53, + }, + { + id: 54, + }, + { + id: 55, + }, + { + id: 56, + }, + { + id: 57, + }, + { + id: 58, + }, + { + id: 59, + }, + { + id: 60, + }, + { + id: 61, + }, + { + id: 62, + }, + { + id: 63, + }, + { + id: 64, + }, + { + id: 65, + }, + { + id: 66, + }, + { + id: 67, + }, + { + id: 68, + }, + { + id: 69, + }, + { + id: 70, + }, + { + id: 71, + }, + { + id: 72, + }, + { + id: 73, + }, + { + id: 74, + }, + { + id: 75, + }, + { + id: 76, + }, + { + id: 77, + }, + { + id: 78, + }, + { + id: 79, + }, + { + id: 80, + }, + { + id: 81, + }, + { + id: 82, + }, + { + id: 83, + }, + { + id: 84, + }, + { + id: 85, + }, + { + id: 86, + }, + { + id: 87, + }, + { + id: 88, + }, + { + id: 89, + }, + { + id: 90, + }, + { + id: 91, + }, + { + id: 92, + }, + { + id: 93, + }, + { + id: 94, + }, + { + id: 95, + }, + { + id: 96, + }, + { + id: 97, + }, + { + id: 98, + }, + { + id: 99, + }, + { + id: 100, + }, + { + id: 101, + }, + { + id: 102, + }, + { + id: 103, + }, + { + id: 104, + }, + { + id: 105, + }, + { + id: 106, + }, + { + id: 107, + }, + { + id: 108, + }, + { + id: 109, + }, + { + id: 110, + }, + { + id: 111, + }, + { + id: 112, + }, + { + id: 113, + }, + { + id: 114, + }, + { + id: 115, + }, + { + id: 116, + }, + { + id: 117, + }, + { + id: 118, + }, + { + id: 119, + }, + { + id: 120, + }, + { + id: 121, + }, + { + id: 122, + }, + { + id: 123, + }, + { + id: 124, + }, + { + id: 125, + }, + { + id: 126, + }, + { + id: 127, + }, + { + id: 128, + }, + { + id: 129, + }, + { + id: 130, + }, + { + id: 131, + }, + { + id: 132, + }, + { + id: 133, + }, + { + id: 134, + }, + { + id: 135, + }, + { + id: 136, + }, + { + id: 137, + }, + { + id: 138, + }, + { + id: 139, + }, + { + id: 140, + }, + { + id: 141, + }, + { + id: 142, + }, + { + id: 143, + }, + { + id: 144, + }, + { + id: 145, + }, + { + id: 146, + }, + { + id: 147, + }, + { + id: 148, + }, + { + id: 149, + }, + { + id: 150, + }, + { + id: 151, + }, + { + id: 152, + }, + { + id: 153, + }, + { + id: 154, + }, + { + id: 155, + }, + { + id: 156, + }, + { + id: 157, + }, + { + id: 158, + }, + { + id: 159, + }, + { + id: 160, + }, + { + id: 161, + }, + { + id: 162, + }, + { + id: 163, + }, + { + id: 164, + }, + { + id: 165, + }, + { + id: 166, + }, + { + id: 167, + }, + { + id: 168, + }, + { + id: 169, + }, + { + id: 170, + }, + { + id: 171, + }, + { + id: 172, + }, + { + id: 173, + }, + { + id: 174, + }, + { + id: 175, + }, + { + id: 176, + }, + { + id: 177, + }, + { + id: 178, + }, + { + id: 179, + }, + { + id: 180, + }, + { + id: 181, + }, + { + id: 182, + }, + { + id: 183, + }, + { + id: 184, + }, + { + id: 185, + }, + { + id: 186, + }, + { + id: 187, + }, + { + id: 188, + }, + { + id: 189, + }, + { + id: 190, + }, + { + id: 191, + }, + { + id: 192, + }, + { + id: 193, + }, + { + id: 194, + }, + { + id: 195, + }, + { + id: 196, + }, + { + id: 197, + }, + { + id: 198, + }, + { + id: 199, + }, + { + id: 200, + }, + { + id: 201, + }, + { + id: 202, + }, + { + id: 203, + }, + { + id: 204, + }, + { + id: 205, + }, + { + id: 206, + }, + { + id: 207, + }, + { + id: 208, + }, + { + id: 209, + }, + { + id: 210, + }, + { + id: 211, + }, + { + id: 212, + }, + { + id: 213, + }, + { + id: 214, + }, + { + id: 215, + }, + { + id: 216, + }, + { + id: 217, + }, + { + id: 218, + }, + { + id: 219, + }, + { + id: 220, + }, + { + id: 221, + }, + { + id: 222, + }, + { + id: 223, + }, + { + id: 224, + }, + { + id: 225, + }, + { + id: 226, + }, + { + id: 227, + }, + { + id: 228, + }, + { + id: 229, + }, + { + id: 230, + }, + { + id: 231, + }, + { + id: 232, + }, + { + id: 233, + }, + { + id: 234, + }, + { + id: 235, + }, + { + id: 236, + }, + { + id: 237, + }, + { + id: 238, + }, + { + id: 239, + }, + { + id: 240, + }, + { + id: 241, + }, + { + id: 242, + }, + { + id: 243, + }, + { + id: 244, + }, + { + id: 245, + }, + { + id: 246, + }, + { + id: 247, + }, + { + id: 248, + }, + { + id: 249, + }, + { + id: 250, + }, + { + id: 251, + }, + { + id: 252, + }, + { + id: 253, + }, + { + id: 254, + }, + { + id: 255, + }, + { + id: 256, + }, + { + id: 257, + }, + { + id: 258, + }, + { + id: 259, + }, + { + id: 260, + }, + { + id: 261, + }, + { + id: 262, + }, + { + id: 263, + }, + { + id: 264, + }, + { + id: 265, + }, + { + id: 266, + }, + { + id: 267, + }, + { + id: 268, + }, + { + id: 269, + }, + { + id: 270, + }, + { + id: 271, + }, + { + id: 272, + }, + { + id: 273, + }, + { + id: 274, + }, + { + id: 275, + }, + { + id: 276, + }, + { + id: 277, + }, + { + id: 278, + }, + { + id: 279, + }, + { + id: 280, + }, + { + id: 281, + }, + { + id: 282, + }, + { + id: 283, + }, + { + id: 284, + }, + { + id: 285, + }, + { + id: 286, + }, + { + id: 287, + }, + { + id: 288, + }, + { + id: 289, + }, + { + id: 290, + }, + { + id: 291, + }, + { + id: 292, + }, + { + id: 293, + }, + { + id: 294, + }, + { + id: 295, + }, + { + id: 296, + }, + { + id: 297, + }, + { + id: 298, + }, + { + id: 299, + }, + { + id: 300, + }, + { + id: 301, + }, + { + id: 302, + }, + { + id: 303, + }, + { + id: 304, + }, + { + id: 305, + }, + { + id: 306, + }, + { + id: 307, + }, + { + id: 308, + }, + { + id: 309, + }, + { + id: 310, + }, + { + id: 311, + }, + { + id: 312, + }, + { + id: 313, + }, + { + id: 314, + }, + { + id: 315, + }, + { + id: 316, + }, + { + id: 317, + }, + { + id: 318, + }, + { + id: 319, + }, + { + id: 320, + }, + { + id: 321, + }, + { + id: 322, + }, + { + id: 323, + }, + { + id: 324, + }, + { + id: 325, + }, + { + id: 326, + }, + { + id: 327, + }, + { + id: 328, + }, + { + id: 329, + }, + { + id: 330, + }, + { + id: 331, + }, + { + id: 332, + }, + { + id: 333, + }, + { + id: 334, + }, + { + id: 335, + }, + { + id: 336, + }, + { + id: 337, + }, + { + id: 338, + }, + { + id: 339, + }, + { + id: 340, + }, + { + id: 341, + }, + { + id: 342, + }, + { + id: 343, + }, + { + id: 344, + }, + { + id: 345, + }, + { + id: 346, + }, + { + id: 347, + }, + { + id: 348, + }, + { + id: 349, + }, + { + id: 350, + }, + ], + }, + enablePartialFailure: true, + }, + context: { + library: { + name: 'http', + }, + }, + timestamp: '2020-02-02T00:23:09.544Z', + }, + metadata: { + jobId: 2, + }, + }, +]; + +const reqMetadata = { + namespace: 'Unknown', + cluster: 'Unknown', + features: {}, +}; + +const largeRecordOutput = [ + { + batchedRequest: [ + { + version: '1', + type: 'REST', + method: 'DELETE', + endpoint: + 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1122/leads.json?id=351&id=352&id=353&id=354&id=355&id=356&id=357&id=358&id=359&id=360&id=361&id=362&id=363&id=364&id=365&id=366&id=367&id=368&id=369&id=370&id=371&id=372&id=373&id=374&id=375&id=376&id=377&id=378&id=379&id=380&id=381&id=382&id=383&id=384&id=385&id=386&id=387&id=388&id=389&id=390&id=391&id=392&id=393&id=394&id=395&id=396&id=397&id=398&id=399&id=400&id=401&id=402&id=403&id=404&id=405&id=406&id=407&id=408&id=409&id=410&id=411&id=412&id=413&id=414&id=415&id=416&id=417&id=418&id=419&id=420&id=421&id=422&id=423&id=424&id=425&id=426&id=427&id=428&id=429&id=430&id=431&id=432&id=433&id=434&id=435&id=436&id=437&id=438&id=439&id=440&id=441&id=442&id=443&id=444&id=445&id=446&id=447&id=448&id=449&id=450', + headers: { + Authorization: TOKEN, + 'Content-Type': CONTENT_TYPE, + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + }, + ], + metadata: [ + { + jobId: 351, + }, + { + jobId: 352, + }, + { + jobId: 353, + }, + { + jobId: 354, + }, + { + jobId: 355, + }, + { + jobId: 356, + }, + { + jobId: 357, + }, + { + jobId: 358, + }, + { + jobId: 359, + }, + { + jobId: 360, + }, + { + jobId: 361, + }, + { + jobId: 362, + }, + { + jobId: 363, + }, + { + jobId: 364, + }, + { + jobId: 365, + }, + { + jobId: 366, + }, + { + jobId: 367, + }, + { + jobId: 368, + }, + { + jobId: 369, + }, + { + jobId: 370, + }, + { + jobId: 371, + }, + { + jobId: 372, + }, + { + jobId: 373, + }, + { + jobId: 374, + }, + { + jobId: 375, + }, + { + jobId: 376, + }, + { + jobId: 377, + }, + { + jobId: 378, + }, + { + jobId: 379, + }, + { + jobId: 380, + }, + { + jobId: 381, + }, + { + jobId: 382, + }, + { + jobId: 383, + }, + { + jobId: 384, + }, + { + jobId: 385, + }, + { + jobId: 386, + }, + { + jobId: 387, + }, + { + jobId: 388, + }, + { + jobId: 389, + }, + { + jobId: 390, + }, + { + jobId: 391, + }, + { + jobId: 392, + }, + { + jobId: 393, + }, + { + jobId: 394, + }, + { + jobId: 395, + }, + { + jobId: 396, + }, + { + jobId: 397, + }, + { + jobId: 398, + }, + { + jobId: 399, + }, + { + jobId: 400, + }, + { + jobId: 401, + }, + { + jobId: 402, + }, + { + jobId: 403, + }, + { + jobId: 404, + }, + { + jobId: 405, + }, + { + jobId: 406, + }, + { + jobId: 407, + }, + { + jobId: 408, + }, + { + jobId: 409, + }, + { + jobId: 410, + }, + { + jobId: 411, + }, + { + jobId: 412, + }, + { + jobId: 413, + }, + { + jobId: 414, + }, + { + jobId: 415, + }, + { + jobId: 416, + }, + { + jobId: 417, + }, + { + jobId: 418, + }, + { + jobId: 419, + }, + { + jobId: 420, + }, + { + jobId: 421, + }, + { + jobId: 422, + }, + { + jobId: 423, + }, + { + jobId: 424, + }, + { + jobId: 425, + }, + { + jobId: 426, + }, + { + jobId: 427, + }, + { + jobId: 428, + }, + { + jobId: 429, + }, + { + jobId: 430, + }, + { + jobId: 431, + }, + { + jobId: 432, + }, + { + jobId: 433, + }, + { + jobId: 434, + }, + { + jobId: 435, + }, + { + jobId: 436, + }, + { + jobId: 437, + }, + { + jobId: 438, + }, + { + jobId: 439, + }, + { + jobId: 440, + }, + { + jobId: 441, + }, + { + jobId: 442, + }, + { + jobId: 443, + }, + { + jobId: 444, + }, + { + jobId: 445, + }, + { + jobId: 446, + }, + { + jobId: 447, + }, + { + jobId: 448, + }, + { + jobId: 449, + }, + { + jobId: 450, + }, + ], + batched: true, + statusCode: 200, + destination: DEST_OBJECT, + }, + { + batchedRequest: [ + { + version: '1', + type: 'REST', + method: 'POST', + endpoint: + 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1122/leads.json?id=1&id=2&id=3&id=4&id=5&id=6&id=7&id=8&id=9&id=10&id=11&id=12&id=13&id=14&id=15&id=16&id=17&id=18&id=19&id=20&id=21&id=22&id=23&id=24&id=25&id=26&id=27&id=28&id=29&id=30&id=31&id=32&id=33&id=34&id=35&id=36&id=37&id=38&id=39&id=40&id=41&id=42&id=43&id=44&id=45&id=46&id=47&id=48&id=49&id=50&id=51&id=52&id=53&id=54&id=55&id=56&id=57&id=58&id=59&id=60&id=61&id=62&id=63&id=64&id=65&id=66&id=67&id=68&id=69&id=70&id=71&id=72&id=73&id=74&id=75&id=76&id=77&id=78&id=79&id=80&id=81&id=82&id=83&id=84&id=85&id=86&id=87&id=88&id=89&id=90&id=91&id=92&id=93&id=94&id=95&id=96&id=97&id=98&id=99&id=100&id=101&id=102&id=103&id=104&id=105&id=106&id=107&id=108&id=109&id=110&id=111&id=112&id=113&id=114&id=115&id=116&id=117&id=118&id=119&id=120&id=121&id=122&id=123&id=124&id=125&id=126&id=127&id=128&id=129&id=130&id=131&id=132&id=133&id=134&id=135&id=136&id=137&id=138&id=139&id=140&id=141&id=142&id=143&id=144&id=145&id=146&id=147&id=148&id=149&id=150&id=151&id=152&id=153&id=154&id=155&id=156&id=157&id=158&id=159&id=160&id=161&id=162&id=163&id=164&id=165&id=166&id=167&id=168&id=169&id=170&id=171&id=172&id=173&id=174&id=175&id=176&id=177&id=178&id=179&id=180&id=181&id=182&id=183&id=184&id=185&id=186&id=187&id=188&id=189&id=190&id=191&id=192&id=193&id=194&id=195&id=196&id=197&id=198&id=199&id=200&id=201&id=202&id=203&id=204&id=205&id=206&id=207&id=208&id=209&id=210&id=211&id=212&id=213&id=214&id=215&id=216&id=217&id=218&id=219&id=220&id=221&id=222&id=223&id=224&id=225&id=226&id=227&id=228&id=229&id=230&id=231&id=232&id=233&id=234&id=235&id=236&id=237&id=238&id=239&id=240&id=241&id=242&id=243&id=244&id=245&id=246&id=247&id=248&id=249&id=250&id=251&id=252&id=253&id=254&id=255&id=256&id=257&id=258&id=259&id=260&id=261&id=262&id=263&id=264&id=265&id=266&id=267&id=268&id=269&id=270&id=271&id=272&id=273&id=274&id=275&id=276&id=277&id=278&id=279&id=280&id=281&id=282&id=283&id=284&id=285&id=286&id=287&id=288&id=289&id=290&id=291&id=292&id=293&id=294&id=295&id=296&id=297&id=298&id=299&id=300', + headers: { + Authorization: TOKEN, + 'Content-Type': CONTENT_TYPE, + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + }, + { + version: '1', + type: 'REST', + method: 'POST', + endpoint: + 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1122/leads.json?id=301&id=302&id=303&id=304&id=305&id=306&id=307&id=308&id=309&id=310&id=311&id=312&id=313&id=314&id=315&id=316&id=317&id=318&id=319&id=320&id=321&id=322&id=323&id=324&id=325&id=326&id=327&id=328&id=329&id=330&id=331&id=332&id=333&id=334&id=335&id=336&id=337&id=338&id=339&id=340&id=341&id=342&id=343&id=344&id=345&id=346&id=347&id=348&id=349&id=350', + headers: { + Authorization: TOKEN, + 'Content-Type': CONTENT_TYPE, + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + }, + ], + metadata: [ + { + jobId: 1, + }, + { + jobId: 2, + }, + { + jobId: 3, + }, + { + jobId: 4, + }, + { + jobId: 5, + }, + { + jobId: 6, + }, + { + jobId: 7, + }, + { + jobId: 8, + }, + { + jobId: 9, + }, + { + jobId: 10, + }, + { + jobId: 11, + }, + { + jobId: 12, + }, + { + jobId: 13, + }, + { + jobId: 14, + }, + { + jobId: 15, + }, + { + jobId: 16, + }, + { + jobId: 17, + }, + { + jobId: 18, + }, + { + jobId: 19, + }, + { + jobId: 20, + }, + { + jobId: 21, + }, + { + jobId: 22, + }, + { + jobId: 23, + }, + { + jobId: 24, + }, + { + jobId: 25, + }, + { + jobId: 26, + }, + { + jobId: 27, + }, + { + jobId: 28, + }, + { + jobId: 29, + }, + { + jobId: 30, + }, + { + jobId: 31, + }, + { + jobId: 32, + }, + { + jobId: 33, + }, + { + jobId: 34, + }, + { + jobId: 35, + }, + { + jobId: 36, + }, + { + jobId: 37, + }, + { + jobId: 38, + }, + { + jobId: 39, + }, + { + jobId: 40, + }, + { + jobId: 41, + }, + { + jobId: 42, + }, + { + jobId: 43, + }, + { + jobId: 44, + }, + { + jobId: 45, + }, + { + jobId: 46, + }, + { + jobId: 47, + }, + { + jobId: 48, + }, + { + jobId: 49, + }, + { + jobId: 50, + }, + { + jobId: 51, + }, + { + jobId: 52, + }, + { + jobId: 53, + }, + { + jobId: 54, + }, + { + jobId: 55, + }, + { + jobId: 56, + }, + { + jobId: 57, + }, + { + jobId: 58, + }, + { + jobId: 59, + }, + { + jobId: 60, + }, + { + jobId: 61, + }, + { + jobId: 62, + }, + { + jobId: 63, + }, + { + jobId: 64, + }, + { + jobId: 65, + }, + { + jobId: 66, + }, + { + jobId: 67, + }, + { + jobId: 68, + }, + { + jobId: 69, + }, + { + jobId: 70, + }, + { + jobId: 71, + }, + { + jobId: 72, + }, + { + jobId: 73, + }, + { + jobId: 74, + }, + { + jobId: 75, + }, + { + jobId: 76, + }, + { + jobId: 77, + }, + { + jobId: 78, + }, + { + jobId: 79, + }, + { + jobId: 80, + }, + { + jobId: 81, + }, + { + jobId: 82, + }, + { + jobId: 83, + }, + { + jobId: 84, + }, + { + jobId: 85, + }, + { + jobId: 86, + }, + { + jobId: 87, + }, + { + jobId: 88, + }, + { + jobId: 89, + }, + { + jobId: 90, + }, + { + jobId: 91, + }, + { + jobId: 92, + }, + { + jobId: 93, + }, + { + jobId: 94, + }, + { + jobId: 95, + }, + { + jobId: 96, + }, + { + jobId: 97, + }, + { + jobId: 98, + }, + { + jobId: 99, + }, + { + jobId: 100, + }, + { + jobId: 101, + }, + { + jobId: 102, + }, + { + jobId: 103, + }, + { + jobId: 104, + }, + { + jobId: 105, + }, + { + jobId: 106, + }, + { + jobId: 107, + }, + { + jobId: 108, + }, + { + jobId: 109, + }, + { + jobId: 110, + }, + { + jobId: 111, + }, + { + jobId: 112, + }, + { + jobId: 113, + }, + { + jobId: 114, + }, + { + jobId: 115, + }, + { + jobId: 116, + }, + { + jobId: 117, + }, + { + jobId: 118, + }, + { + jobId: 119, + }, + { + jobId: 120, + }, + { + jobId: 121, + }, + { + jobId: 122, + }, + { + jobId: 123, + }, + { + jobId: 124, + }, + { + jobId: 125, + }, + { + jobId: 126, + }, + { + jobId: 127, + }, + { + jobId: 128, + }, + { + jobId: 129, + }, + { + jobId: 130, + }, + { + jobId: 131, + }, + { + jobId: 132, + }, + { + jobId: 133, + }, + { + jobId: 134, + }, + { + jobId: 135, + }, + { + jobId: 136, + }, + { + jobId: 137, + }, + { + jobId: 138, + }, + { + jobId: 139, + }, + { + jobId: 140, + }, + { + jobId: 141, + }, + { + jobId: 142, + }, + { + jobId: 143, + }, + { + jobId: 144, + }, + { + jobId: 145, + }, + { + jobId: 146, + }, + { + jobId: 147, + }, + { + jobId: 148, + }, + { + jobId: 149, + }, + { + jobId: 150, + }, + { + jobId: 151, + }, + { + jobId: 152, + }, + { + jobId: 153, + }, + { + jobId: 154, + }, + { + jobId: 155, + }, + { + jobId: 156, + }, + { + jobId: 157, + }, + { + jobId: 158, + }, + { + jobId: 159, + }, + { + jobId: 160, + }, + { + jobId: 161, + }, + { + jobId: 162, + }, + { + jobId: 163, + }, + { + jobId: 164, + }, + { + jobId: 165, + }, + { + jobId: 166, + }, + { + jobId: 167, + }, + { + jobId: 168, + }, + { + jobId: 169, + }, + { + jobId: 170, + }, + { + jobId: 171, + }, + { + jobId: 172, + }, + { + jobId: 173, + }, + { + jobId: 174, + }, + { + jobId: 175, + }, + { + jobId: 176, + }, + { + jobId: 177, + }, + { + jobId: 178, + }, + { + jobId: 179, + }, + { + jobId: 180, + }, + { + jobId: 181, + }, + { + jobId: 182, + }, + { + jobId: 183, + }, + { + jobId: 184, + }, + { + jobId: 185, + }, + { + jobId: 186, + }, + { + jobId: 187, + }, + { + jobId: 188, + }, + { + jobId: 189, + }, + { + jobId: 190, + }, + { + jobId: 191, + }, + { + jobId: 192, + }, + { + jobId: 193, + }, + { + jobId: 194, + }, + { + jobId: 195, + }, + { + jobId: 196, + }, + { + jobId: 197, + }, + { + jobId: 198, + }, + { + jobId: 199, + }, + { + jobId: 200, + }, + { + jobId: 201, + }, + { + jobId: 202, + }, + { + jobId: 203, + }, + { + jobId: 204, + }, + { + jobId: 205, + }, + { + jobId: 206, + }, + { + jobId: 207, + }, + { + jobId: 208, + }, + { + jobId: 209, + }, + { + jobId: 210, + }, + { + jobId: 211, + }, + { + jobId: 212, + }, + { + jobId: 213, + }, + { + jobId: 214, + }, + { + jobId: 215, + }, + { + jobId: 216, + }, + { + jobId: 217, + }, + { + jobId: 218, + }, + { + jobId: 219, + }, + { + jobId: 220, + }, + { + jobId: 221, + }, + { + jobId: 222, + }, + { + jobId: 223, + }, + { + jobId: 224, + }, + { + jobId: 225, + }, + { + jobId: 226, + }, + { + jobId: 227, + }, + { + jobId: 228, + }, + { + jobId: 229, + }, + { + jobId: 230, + }, + { + jobId: 231, + }, + { + jobId: 232, + }, + { + jobId: 233, + }, + { + jobId: 234, + }, + { + jobId: 235, + }, + { + jobId: 236, + }, + { + jobId: 237, + }, + { + jobId: 238, + }, + { + jobId: 239, + }, + { + jobId: 240, + }, + { + jobId: 241, + }, + { + jobId: 242, + }, + { + jobId: 243, + }, + { + jobId: 244, + }, + { + jobId: 245, + }, + { + jobId: 246, + }, + { + jobId: 247, + }, + { + jobId: 248, + }, + { + jobId: 249, + }, + { + jobId: 250, + }, + { + jobId: 251, + }, + { + jobId: 252, + }, + { + jobId: 253, + }, + { + jobId: 254, + }, + { + jobId: 255, + }, + { + jobId: 256, + }, + { + jobId: 257, + }, + { + jobId: 258, + }, + { + jobId: 259, + }, + { + jobId: 260, + }, + { + jobId: 261, + }, + { + jobId: 262, + }, + { + jobId: 263, + }, + { + jobId: 264, + }, + { + jobId: 265, + }, + { + jobId: 266, + }, + { + jobId: 267, + }, + { + jobId: 268, + }, + { + jobId: 269, + }, + { + jobId: 270, + }, + { + jobId: 271, + }, + { + jobId: 272, + }, + { + jobId: 273, + }, + { + jobId: 274, + }, + { + jobId: 275, + }, + { + jobId: 276, + }, + { + jobId: 277, + }, + { + jobId: 278, + }, + { + jobId: 279, + }, + { + jobId: 280, + }, + { + jobId: 281, + }, + { + jobId: 282, + }, + { + jobId: 283, + }, + { + jobId: 284, + }, + { + jobId: 285, + }, + { + jobId: 286, + }, + { + jobId: 287, + }, + { + jobId: 288, + }, + { + jobId: 289, + }, + { + jobId: 290, + }, + { + jobId: 291, + }, + { + jobId: 292, + }, + { + jobId: 293, + }, + { + jobId: 294, + }, + { + jobId: 295, + }, + { + jobId: 296, + }, + { + jobId: 297, + }, + { + jobId: 298, + }, + { + jobId: 299, + }, + { + jobId: 300, + }, + { + jobId: 301, + }, + { + jobId: 302, + }, + { + jobId: 303, + }, + { + jobId: 304, + }, + { + jobId: 305, + }, + { + jobId: 306, + }, + { + jobId: 307, + }, + { + jobId: 308, + }, + { + jobId: 309, + }, + { + jobId: 310, + }, + { + jobId: 311, + }, + { + jobId: 312, + }, + { + jobId: 313, + }, + { + jobId: 314, + }, + { + jobId: 315, + }, + { + jobId: 316, + }, + { + jobId: 317, + }, + { + jobId: 318, + }, + { + jobId: 319, + }, + { + jobId: 320, + }, + { + jobId: 321, + }, + { + jobId: 322, + }, + { + jobId: 323, + }, + { + jobId: 324, + }, + { + jobId: 325, + }, + { + jobId: 326, + }, + { + jobId: 327, + }, + { + jobId: 328, + }, + { + jobId: 329, + }, + { + jobId: 330, + }, + { + jobId: 331, + }, + { + jobId: 332, + }, + { + jobId: 333, + }, + { + jobId: 334, + }, + { + jobId: 335, + }, + { + jobId: 336, + }, + { + jobId: 337, + }, + { + jobId: 338, + }, + { + jobId: 339, + }, + { + jobId: 340, + }, + { + jobId: 341, + }, + { + jobId: 342, + }, + { + jobId: 343, + }, + { + jobId: 344, + }, + { + jobId: 345, + }, + { + jobId: 346, + }, + { + jobId: 347, + }, + { + jobId: 348, + }, + { + jobId: 349, + }, + { + jobId: 350, + }, + ], + batched: true, + statusCode: 200, + destination: DEST_OBJECT, + }, +]; + +const mixedBatchOutput = [ + { + batchedRequest: [ + { + version: '1', + type: 'REST', + method: 'DELETE', + endpoint: + 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1122/leads.json?id=911&id=912&id=913&id=914&id=915&id=916&id=917&id=918&id=919&id=920', + headers: { + Authorization: TOKEN, + 'Content-Type': CONTENT_TYPE, + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + }, + ], + metadata: [ + { + jobId: 911, + }, + { + jobId: 912, + }, + { + jobId: 913, + }, + { + jobId: 914, + }, + { + jobId: 915, + }, + { + jobId: 916, + }, + { + jobId: 917, + }, + { + jobId: 918, + }, + { + jobId: 919, + }, + { + jobId: 920, + }, + ], + batched: true, + statusCode: 200, + destination: DEST_OBJECT, + }, + { + batchedRequest: [ + { + version: '1', + type: 'REST', + method: 'POST', + endpoint: + 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1122/leads.json?id=901&id=902&id=903&id=904&id=905&id=906&id=907&id=908&id=909&id=910', + headers: { + Authorization: TOKEN, + 'Content-Type': CONTENT_TYPE, + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + }, + ], + metadata: [ + { + jobId: 901, + }, + { + jobId: 902, + }, + { + jobId: 903, + }, + { + jobId: 904, + }, + { + jobId: 905, + }, + { + jobId: 906, + }, + { + jobId: 907, + }, + { + jobId: 908, + }, + { + jobId: 909, + }, + { + jobId: 910, + }, + ], + batched: true, + statusCode: 200, + destination: DEST_OBJECT, + }, + { + batchedRequest: [ + { + version: '1', + type: 'REST', + method: 'DELETE', + endpoint: + 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=704&id=705&id=706', + headers: { + Authorization: TOKEN, + 'Content-Type': CONTENT_TYPE, + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + }, + { + version: '1', + type: 'REST', + method: 'POST', + endpoint: + 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=501&id=502&id=503', + headers: { + Authorization: TOKEN, + 'Content-Type': CONTENT_TYPE, + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + }, + ], + metadata: [ + { + jobId: 1, + }, + ], + batched: false, + statusCode: 200, + destination: { + ID: '1zia9wKshXt80YksLmUdJnr7IHI', + Name: 'test_marketo', + DestinationDefinition: DEST_DEFINITION, + Config: DEST_CONFIG, + Enabled: true, + Transformations: [], + IsProcessorEnabled: true, + }, + }, + { + batchedRequest: [ + { + version: '1', + type: 'REST', + method: 'POST', + endpoint: + 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=0&id=1&id=2&id=3&id=4&id=5&id=6&id=7&id=8&id=9&id=10&id=11&id=12&id=13&id=14&id=15&id=16&id=17&id=18&id=19&id=20&id=21&id=22&id=23&id=24&id=25&id=26&id=27&id=28&id=29&id=30&id=31&id=32&id=33&id=34&id=35&id=36&id=37&id=38&id=39&id=40&id=41&id=42&id=43&id=44&id=45&id=46&id=47&id=48&id=49&id=50&id=51&id=52&id=53&id=54&id=55&id=56&id=57&id=58&id=59&id=60&id=61&id=62&id=63&id=64&id=65&id=66&id=67&id=68&id=69&id=70&id=71&id=72&id=73&id=74&id=75&id=76&id=77&id=78&id=79&id=80&id=81&id=82&id=83&id=84&id=85&id=86&id=87&id=88&id=89&id=90&id=91&id=92&id=93&id=94&id=95&id=96&id=97&id=98&id=99&id=100&id=101&id=102&id=103&id=104&id=105&id=106&id=107&id=108&id=109&id=110&id=111&id=112&id=113&id=114&id=115&id=116&id=117&id=118&id=119&id=120&id=121&id=122&id=123&id=124&id=125&id=126&id=127&id=128&id=129&id=130&id=131&id=132&id=133&id=134&id=135&id=136&id=137&id=138&id=139&id=140&id=141&id=142&id=143&id=144&id=145&id=146&id=147&id=148&id=149&id=150&id=151&id=152&id=153&id=154&id=155&id=156&id=157&id=158&id=159&id=160&id=161&id=162&id=163&id=164&id=165&id=166&id=167&id=168&id=169&id=170&id=171&id=172&id=173&id=174&id=175&id=176&id=177&id=178&id=179&id=180&id=181&id=182&id=183&id=184&id=185&id=186&id=187&id=188&id=189&id=190&id=191&id=192&id=193&id=194&id=195&id=196&id=197&id=198&id=199&id=200&id=201&id=202&id=203&id=204&id=205&id=206&id=207&id=208&id=209&id=210&id=211&id=212&id=213&id=214&id=215&id=216&id=217&id=218&id=219&id=220&id=221&id=222&id=223&id=224&id=225&id=226&id=227&id=228&id=229&id=230&id=231&id=232&id=233&id=234&id=235&id=236&id=237&id=238&id=239&id=240&id=241&id=242&id=243&id=244&id=245&id=246&id=247&id=248&id=249&id=250&id=251&id=252&id=253&id=254&id=255&id=256&id=257&id=258&id=259&id=260&id=261&id=262&id=263&id=264&id=265&id=266&id=267&id=268&id=269&id=270&id=271&id=272&id=273&id=274&id=275&id=276&id=277&id=278&id=279&id=280&id=281&id=282&id=283&id=284&id=285&id=286&id=287&id=288&id=289&id=290&id=291&id=292&id=293&id=294&id=295&id=296&id=297&id=298&id=299', + headers: { + Authorization: TOKEN, + 'Content-Type': CONTENT_TYPE, + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + }, + { + version: '1', + type: 'REST', + method: 'POST', + endpoint: + 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=300&id=301&id=302&id=303&id=304&id=305&id=306&id=307&id=308&id=309&id=310&id=311&id=312&id=313&id=314&id=315&id=316&id=317&id=318&id=319&id=320&id=321&id=322&id=323&id=324&id=325&id=326&id=327&id=328&id=329&id=330&id=331&id=332&id=333&id=334&id=335&id=336&id=337&id=338&id=339&id=340&id=341&id=342&id=343&id=344&id=345&id=346&id=347&id=348&id=349&id=350', + headers: { + Authorization: TOKEN, + 'Content-Type': CONTENT_TYPE, + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + }, + ], + metadata: [ + { + jobId: 2, + }, + ], + batched: false, + statusCode: 200, + destination: { + ID: '1zia9wKshXt80YksLmUdJnr7IHI', + Name: 'test_marketo', + DestinationDefinition: DEST_DEFINITION, + Config: DEST_CONFIG, + Enabled: true, + Transformations: [], + IsProcessorEnabled: true, + }, + }, +]; + +const recordEventGenerator = (id, action, externalId) => { + // this function is used to generate record events for testing + const testRecordEvent = { + destination: { + ID: '1zwa1wKshSt81YksKmUdJnr4IOK', + Name: 'test_marketo_rc', + DestinationDefinition: DEST_DEFINITION, + Config: { + clientId: 'marketo_client_id_success', + clientSecret: 'marketo_client_secret_success', + accountId: 'marketo_acct_id_success', + staticListId: 1122, + }, + Enabled: true, + Transformations: [], + IsProcessorEnabled: true, + }, + message: { + type: 'record', + action, + fields: { + id, + }, + channel: 'sources', + context: { + sources: MESSAGE_SOURCES_CONTEXT, + externalId: [ + { + type: EXTERNAL_ID, + id: externalId, + }, + ], + destinationFields: 'id', + mappedToDestination: 'true', + }, + recordId: '3', + }, + metadata: { + jobId: id, + }, + }; + return testRecordEvent; +}; + +module.exports = { + recordInputs, + audiencelistInputs, + reqMetadata, + recordOutput, + largeRecordOutput, + mixedBatchOutput, + recordEventGenerator, +}; diff --git a/src/v0/destinations/marketo_static_list/transform.js b/src/v0/destinations/marketo_static_list/transform.js index 856947c33c..cbdb89f532 100644 --- a/src/v0/destinations/marketo_static_list/transform.js +++ b/src/v0/destinations/marketo_static_list/transform.js @@ -5,6 +5,7 @@ const { defaultPostRequestConfig, defaultDeleteRequestConfig, generateErrorObject, + simpleProcessRouterDest, } = require('../../util'); const { AUTH_CACHE_TTL, JSON_MIME_TYPE } = require('../../util/constant'); const { getIds, validateMessageType } = require('./util'); @@ -12,11 +13,11 @@ const { getDestinationExternalID, defaultRequestConfig, getErrorRespEvents, - simpleProcessRouterDest, } = require('../../util'); const { formatConfig, MAX_LEAD_IDS_SIZE } = require('./config'); const Cache = require('../../util/cache'); const { getAuthToken } = require('../marketo/transform'); +const { processRecordInputs } = require('./transformV2'); const authCache = new Cache(AUTH_CACHE_TTL); // 1 hr @@ -57,8 +58,8 @@ const batchResponseBuilder = (message, Config, token, leadIds, operation) => { return response; }; -const processEvent = (input) => { - const { token, message, destination } = input; +const processEvent = (event) => { + const { token, message, destination } = event; const { Config } = destination; validateMessageType(message, ['audiencelist']); const response = []; @@ -70,77 +71,92 @@ const processEvent = (input) => { if (message.properties?.listData?.remove) { toRemove = getIds(message.properties.listData.remove); } - if ( - (Array.isArray(toAdd) && toAdd.length > 0) || - (Array.isArray(toRemove) && toRemove.length > 0) - ) { - if (Array.isArray(toAdd) && toAdd.length > 0) { - const payload = batchResponseBuilder(message, Config, token, toAdd, 'add'); - if (payload) { - response.push(...payload); - } + if (Array.isArray(toRemove) && toRemove.length > 0) { + const payload = batchResponseBuilder(message, Config, token, toRemove, 'remove'); + if (payload) { + response.push(...payload); } - if (Array.isArray(toRemove) && toRemove.length > 0) { - const payload = batchResponseBuilder(message, Config, token, toRemove, 'remove'); - if (payload) { - response.push(...payload); - } + } + if (Array.isArray(toAdd) && toAdd.length > 0) { + const payload = batchResponseBuilder(message, Config, token, toAdd, 'add'); + if (payload) { + response.push(...payload); } - } else { + } + if (response.length === 0) { throw new InstrumentationError( 'Invalid leadIds format or no leadIds found neither to add nor to remove', ); } return response; }; -const process = async (event) => { - const token = await getAuthToken(formatConfig(event.destination)); +// eslint-disable-next-line @typescript-eslint/no-unused-vars +const process = async (event, _processParams) => { + const token = await getAuthToken(formatConfig(event.destination)); if (!token) { throw new UnauthorizedError('Authorization failed'); } - const response = processEvent({ ...event, token }); + const updatedEvent = { ...event, token }; + const response = processEvent(updatedEvent); return response; }; const processRouterDest = async (inputs, reqMetadata) => { // Token needs to be generated for marketo which will be done on input level. // If destination information is not present Error should be thrown - let token; + + const { destination } = inputs[0]; try { - token = await getAuthToken(formatConfig(inputs[0].destination)); + const token = await getAuthToken(formatConfig(destination)); if (!token) { - const errResp = { - status: 400, - message: 'Authorisation failed', - responseTransformFailure: true, - statTags: {}, - }; - const respEvents = getErrorRespEvents( - inputs.map((input) => input.metadata), - errResp.status, - errResp.message, - errResp.statTags, - ); - return [{ ...respEvents, destination: inputs?.[0]?.destination }]; + throw new UnauthorizedError('Could not retrieve authorisation token'); } } catch (error) { - // Not using handleRtTfSingleEventError here as this is for multiple events - const errObj = generateErrorObject(error); - const respEvents = getErrorRespEvents( - inputs.map((input) => input.metadata), - errObj.status, - errObj.message, - errObj.statTags, + const errorObj = generateErrorObject(error); + const errResponses = inputs.map((input) => + getErrorRespEvents(input.metadata, errorObj.status, errorObj.message, errorObj.statTags), ); - return [{ ...respEvents, destination: inputs?.[0]?.destination }]; + + return errResponses; } - // Checking previous status Code. Initially setting to false. - // If true then previous status is 500 and every subsequent event output should be - // sent with status code 500 to the router to be retried. - const tokenisedInputs = inputs.map((input) => ({ ...input, token })); - const respList = await simpleProcessRouterDest(tokenisedInputs, processEvent, reqMetadata); + // use lodash.groupby to group the inputs based on message type + const transformedRecordEvent = []; + let transformedAudienceEvent = []; + const groupedInputs = lodash.groupBy(inputs, (input) => input.message.type); + + const respList = []; + // process record events + if (groupedInputs.record) { + const groupedRecordInputs = groupedInputs.record; + const { staticListId } = destination.Config; + const externalIdGroupedRecordInputs = lodash.groupBy( + groupedRecordInputs, + (input) => getDestinationExternalID(input.message, 'marketoStaticListId') || staticListId, + ); + const alltransformedGroupedRecordEvent = await Promise.all( + Object.keys(externalIdGroupedRecordInputs).map(async (key) => { + const transformedGroupedRecordEvent = await processRecordInputs( + externalIdGroupedRecordInputs[key], + destination, + key, + ); + return transformedGroupedRecordEvent; + }), + ); + + transformedRecordEvent.push(...alltransformedGroupedRecordEvent.flat()); + } + // process audiencelist events + if (groupedInputs.audiencelist) { + transformedAudienceEvent = await simpleProcessRouterDest( + groupedInputs.audiencelist, + process, + reqMetadata, + ); + } + respList.push(...transformedRecordEvent, ...transformedAudienceEvent); return respList; }; @@ -152,16 +168,20 @@ const processRouterDest = async (inputs, reqMetadata) => { function processMetadataForRouter(output) { const { metadata, destination } = output; const clonedMetadata = cloneDeep(metadata); - clonedMetadata.forEach((metadataElement) => { - // eslint-disable-next-line no-param-reassign - metadataElement.destInfo = { authKey: destination.ID }; - }); + if (Array.isArray(clonedMetadata)) { + clonedMetadata.forEach((metadataElement) => { + // eslint-disable-next-line no-param-reassign + metadataElement.destInfo = { authKey: destination?.ID }; + }); + } return clonedMetadata; } module.exports = { process, + processEvent, processRouterDest, processMetadataForRouter, authCache, + batchResponseBuilder, }; diff --git a/src/v0/destinations/marketo_static_list/transform.test.js b/src/v0/destinations/marketo_static_list/transform.test.js new file mode 100644 index 0000000000..3c387c4295 --- /dev/null +++ b/src/v0/destinations/marketo_static_list/transform.test.js @@ -0,0 +1,138 @@ +const { processRouterDest } = require('./transform'); +const axios = require('axios'); +const MockAxiosAdapter = require('axios-mock-adapter'); +const { + recordInputs, + audiencelistInputs, + reqMetadata, + recordOutput, + largeRecordOutput, + mixedBatchOutput, + recordEventGenerator, +} = require('./testData/testData'); + +const mockAdapter = new MockAxiosAdapter(axios, { onNoMatch: 'throwException' }); +beforeAll(() => { + mockAdapter + .onGet('https://marketo_acct_id_success.mktorest.com/identity/oauth/token') + .reply(200, { access_token: 'access_token_success' }); +}); +describe('Unit cases covering the router flow for both record and audiencelist event types', () => { + it('Sending a small batch of only record events (4 events)', async () => { + const inputs = recordInputs; + const result = await processRouterDest(inputs, reqMetadata); + + // assert that the result is as expected + expect(result.length).toEqual(3); + expect(result[0].batchedRequest.length).toEqual(1); // 1 batched request for 2 record events + expect(result[1].batchedRequest.length).toEqual(1); // 1 batched request for 1 record events + expect(result[2].batchedRequest.length).toEqual(1); // 1 batched request for 1 record events + expect(result[0].batchedRequest[0].endpoint).toEqual( + 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/id001/leads.json?id=1001&id=1003', + ); // 1 api call for 2 leadIds + expect(result[1].batchedRequest[0].endpoint).toEqual( + 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/id002/leads.json?id=2001', + ); // 1 api call for 1 leadId + expect(result[2].batchedRequest[0].endpoint).toEqual( + 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/id002/leads.json?id=1002', + ); // 1 api call for 1 leadId + expect(result[1].batchedRequest[0].method).toEqual('DELETE'); // DELETE requests are sent first + expect(result[0].metadata.length).toEqual(2); // 2 metadata objects for 2 record events + expect(result[1].metadata.length).toEqual(1); // 1 metadata object for 1 record event + expect(result[2].metadata.length).toEqual(1); // 1 metadata object for 1 record event + expect(result).toEqual(recordOutput); // overall result should be equal to the expected output + }); + + it('Sending a large batch of only record events (450 events: 350 inserts | 100 deletes )', async () => { + const largeRecordInputs = []; + for (let index = 0; index < 350; index++) { + largeRecordInputs.push(recordEventGenerator(index + 1, 'insert', 1122)); + } + for (let index = 350; index < 450; index++) { + largeRecordInputs.push(recordEventGenerator(index + 1, 'delete', 1122)); + } + const result = await processRouterDest(largeRecordInputs, reqMetadata); + + // assert that the result is as expected + /* + Total 3 API calls + 1. 1 API call for 100 DELETE requests + 2. 1 API call for 100 POST requests = limit reached for Marketo, leads split to next API call + 3. 1 API call for 50 POST requests + */ + expect(result.length).toEqual(2); + expect(result[0].batchedRequest.length).toEqual(1); // 1 batched request for 1 record event + expect(result[1].batchedRequest.length).toEqual(2); // 1 batched request for 2 record events + expect(result[0].batchedRequest[0].endpoint).toEqual( + 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1122/leads.json?id=351&id=352&id=353&id=354&id=355&id=356&id=357&id=358&id=359&id=360&id=361&id=362&id=363&id=364&id=365&id=366&id=367&id=368&id=369&id=370&id=371&id=372&id=373&id=374&id=375&id=376&id=377&id=378&id=379&id=380&id=381&id=382&id=383&id=384&id=385&id=386&id=387&id=388&id=389&id=390&id=391&id=392&id=393&id=394&id=395&id=396&id=397&id=398&id=399&id=400&id=401&id=402&id=403&id=404&id=405&id=406&id=407&id=408&id=409&id=410&id=411&id=412&id=413&id=414&id=415&id=416&id=417&id=418&id=419&id=420&id=421&id=422&id=423&id=424&id=425&id=426&id=427&id=428&id=429&id=430&id=431&id=432&id=433&id=434&id=435&id=436&id=437&id=438&id=439&id=440&id=441&id=442&id=443&id=444&id=445&id=446&id=447&id=448&id=449&id=450', + ); + expect(result[1].batchedRequest[0].endpoint).toEqual( + 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1122/leads.json?id=1&id=2&id=3&id=4&id=5&id=6&id=7&id=8&id=9&id=10&id=11&id=12&id=13&id=14&id=15&id=16&id=17&id=18&id=19&id=20&id=21&id=22&id=23&id=24&id=25&id=26&id=27&id=28&id=29&id=30&id=31&id=32&id=33&id=34&id=35&id=36&id=37&id=38&id=39&id=40&id=41&id=42&id=43&id=44&id=45&id=46&id=47&id=48&id=49&id=50&id=51&id=52&id=53&id=54&id=55&id=56&id=57&id=58&id=59&id=60&id=61&id=62&id=63&id=64&id=65&id=66&id=67&id=68&id=69&id=70&id=71&id=72&id=73&id=74&id=75&id=76&id=77&id=78&id=79&id=80&id=81&id=82&id=83&id=84&id=85&id=86&id=87&id=88&id=89&id=90&id=91&id=92&id=93&id=94&id=95&id=96&id=97&id=98&id=99&id=100&id=101&id=102&id=103&id=104&id=105&id=106&id=107&id=108&id=109&id=110&id=111&id=112&id=113&id=114&id=115&id=116&id=117&id=118&id=119&id=120&id=121&id=122&id=123&id=124&id=125&id=126&id=127&id=128&id=129&id=130&id=131&id=132&id=133&id=134&id=135&id=136&id=137&id=138&id=139&id=140&id=141&id=142&id=143&id=144&id=145&id=146&id=147&id=148&id=149&id=150&id=151&id=152&id=153&id=154&id=155&id=156&id=157&id=158&id=159&id=160&id=161&id=162&id=163&id=164&id=165&id=166&id=167&id=168&id=169&id=170&id=171&id=172&id=173&id=174&id=175&id=176&id=177&id=178&id=179&id=180&id=181&id=182&id=183&id=184&id=185&id=186&id=187&id=188&id=189&id=190&id=191&id=192&id=193&id=194&id=195&id=196&id=197&id=198&id=199&id=200&id=201&id=202&id=203&id=204&id=205&id=206&id=207&id=208&id=209&id=210&id=211&id=212&id=213&id=214&id=215&id=216&id=217&id=218&id=219&id=220&id=221&id=222&id=223&id=224&id=225&id=226&id=227&id=228&id=229&id=230&id=231&id=232&id=233&id=234&id=235&id=236&id=237&id=238&id=239&id=240&id=241&id=242&id=243&id=244&id=245&id=246&id=247&id=248&id=249&id=250&id=251&id=252&id=253&id=254&id=255&id=256&id=257&id=258&id=259&id=260&id=261&id=262&id=263&id=264&id=265&id=266&id=267&id=268&id=269&id=270&id=271&id=272&id=273&id=274&id=275&id=276&id=277&id=278&id=279&id=280&id=281&id=282&id=283&id=284&id=285&id=286&id=287&id=288&id=289&id=290&id=291&id=292&id=293&id=294&id=295&id=296&id=297&id=298&id=299&id=300', + ); + expect(result[1].batchedRequest[1].endpoint).toEqual( + 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1122/leads.json?id=301&id=302&id=303&id=304&id=305&id=306&id=307&id=308&id=309&id=310&id=311&id=312&id=313&id=314&id=315&id=316&id=317&id=318&id=319&id=320&id=321&id=322&id=323&id=324&id=325&id=326&id=327&id=328&id=329&id=330&id=331&id=332&id=333&id=334&id=335&id=336&id=337&id=338&id=339&id=340&id=341&id=342&id=343&id=344&id=345&id=346&id=347&id=348&id=349&id=350', + ); + expect(result[0].batchedRequest[0].method).toEqual('DELETE'); // DELETE requests are sent first + expect(result[1].batchedRequest[0].method).toEqual('POST'); + expect(result[1].batchedRequest[1].method).toEqual('POST'); + expect(result[0].metadata.length).toEqual(100); // 100 metadata objects for 100 record events + expect(result[1].metadata.length).toEqual(350); // 350 metadata objects for 350 record events + expect(result).toEqual(largeRecordOutput); // overall result should be equal to the expected output + }); + + it('Sending a mixed batch of record and audiencelist events (22 events: 10 inserts | 10 deletes | 2 audiencelist (⌐■_■) )', async () => { + const mixedBatchInputs = []; + for (let index = 900; index < 910; index++) { + mixedBatchInputs.push(recordEventGenerator(index + 1, 'insert', 1122)); + } + for (let index = 910; index < 920; index++) { + mixedBatchInputs.push(recordEventGenerator(index + 1, 'delete', 1122)); + } + mixedBatchInputs.push(...audiencelistInputs); + const result = await processRouterDest(mixedBatchInputs, reqMetadata); + + // assert that the result is as expected + /* + Total 4 API calls + 1. 1 API call for 10 DELETE requests + 2. 1 API call for 10 POST requests = limit reached for Marketo, leads split to next API call + 3. 1 API call for 2 POST requests + 4. 1 API call for 2 POST requests + */ + expect(result.length).toEqual(4); + expect(result[0].batchedRequest.length).toEqual(1); // 1 batched request for 1 record event + expect(result[1].batchedRequest.length).toEqual(1); // 1 batched request for 1 record event + expect(result[2].batchedRequest.length).toEqual(2); // 1 batched request for 2 audiencelist events + expect(result[3].batchedRequest.length).toEqual(2); // 1 batched request for 2 audiencelist events + expect(result[0].batchedRequest[0].endpoint).toEqual( + 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1122/leads.json?id=911&id=912&id=913&id=914&id=915&id=916&id=917&id=918&id=919&id=920', + ); + expect(result[1].batchedRequest[0].endpoint).toEqual( + 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1122/leads.json?id=901&id=902&id=903&id=904&id=905&id=906&id=907&id=908&id=909&id=910', + ); + expect(result[2].batchedRequest[0].endpoint).toEqual( + 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=704&id=705&id=706', + ); + expect(result[2].batchedRequest[1].endpoint).toEqual( + 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=501&id=502&id=503', + ); + expect(result[3].batchedRequest[0].endpoint).toEqual( + 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=0&id=1&id=2&id=3&id=4&id=5&id=6&id=7&id=8&id=9&id=10&id=11&id=12&id=13&id=14&id=15&id=16&id=17&id=18&id=19&id=20&id=21&id=22&id=23&id=24&id=25&id=26&id=27&id=28&id=29&id=30&id=31&id=32&id=33&id=34&id=35&id=36&id=37&id=38&id=39&id=40&id=41&id=42&id=43&id=44&id=45&id=46&id=47&id=48&id=49&id=50&id=51&id=52&id=53&id=54&id=55&id=56&id=57&id=58&id=59&id=60&id=61&id=62&id=63&id=64&id=65&id=66&id=67&id=68&id=69&id=70&id=71&id=72&id=73&id=74&id=75&id=76&id=77&id=78&id=79&id=80&id=81&id=82&id=83&id=84&id=85&id=86&id=87&id=88&id=89&id=90&id=91&id=92&id=93&id=94&id=95&id=96&id=97&id=98&id=99&id=100&id=101&id=102&id=103&id=104&id=105&id=106&id=107&id=108&id=109&id=110&id=111&id=112&id=113&id=114&id=115&id=116&id=117&id=118&id=119&id=120&id=121&id=122&id=123&id=124&id=125&id=126&id=127&id=128&id=129&id=130&id=131&id=132&id=133&id=134&id=135&id=136&id=137&id=138&id=139&id=140&id=141&id=142&id=143&id=144&id=145&id=146&id=147&id=148&id=149&id=150&id=151&id=152&id=153&id=154&id=155&id=156&id=157&id=158&id=159&id=160&id=161&id=162&id=163&id=164&id=165&id=166&id=167&id=168&id=169&id=170&id=171&id=172&id=173&id=174&id=175&id=176&id=177&id=178&id=179&id=180&id=181&id=182&id=183&id=184&id=185&id=186&id=187&id=188&id=189&id=190&id=191&id=192&id=193&id=194&id=195&id=196&id=197&id=198&id=199&id=200&id=201&id=202&id=203&id=204&id=205&id=206&id=207&id=208&id=209&id=210&id=211&id=212&id=213&id=214&id=215&id=216&id=217&id=218&id=219&id=220&id=221&id=222&id=223&id=224&id=225&id=226&id=227&id=228&id=229&id=230&id=231&id=232&id=233&id=234&id=235&id=236&id=237&id=238&id=239&id=240&id=241&id=242&id=243&id=244&id=245&id=246&id=247&id=248&id=249&id=250&id=251&id=252&id=253&id=254&id=255&id=256&id=257&id=258&id=259&id=260&id=261&id=262&id=263&id=264&id=265&id=266&id=267&id=268&id=269&id=270&id=271&id=272&id=273&id=274&id=275&id=276&id=277&id=278&id=279&id=280&id=281&id=282&id=283&id=284&id=285&id=286&id=287&id=288&id=289&id=290&id=291&id=292&id=293&id=294&id=295&id=296&id=297&id=298&id=299', + ); + expect(result[2].batchedRequest[1].endpoint).toEqual( + 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=501&id=502&id=503', + ); + expect(result[0].batchedRequest[0].method).toEqual('DELETE'); // DELETE requests are sent first + expect(result[1].batchedRequest[0].method).toEqual('POST'); + expect(result[1].batchedRequest[0].method).toEqual('POST'); + expect(result[2].batchedRequest[0].method).toEqual('DELETE'); + expect(result[0].metadata.length).toEqual(10); + expect(result[1].metadata.length).toEqual(10); + expect(result[2].metadata.length).toEqual(1); + expect(result[3].metadata.length).toEqual(1); + expect(result).toEqual(mixedBatchOutput); // overall result should be equal to the expected output + }); +}); +afterAll(() => { + mockAdapter.restore(); +}); diff --git a/src/v0/destinations/marketo_static_list/transformV2.js b/src/v0/destinations/marketo_static_list/transformV2.js new file mode 100644 index 0000000000..912d548d09 --- /dev/null +++ b/src/v0/destinations/marketo_static_list/transformV2.js @@ -0,0 +1,143 @@ +const lodash = require('lodash'); +const { InstrumentationError, UnauthorizedError } = require('@rudderstack/integrations-lib'); +const { + defaultPostRequestConfig, + defaultDeleteRequestConfig, + defaultRequestConfig, + getSuccessRespEvents, + isDefinedAndNotNull, + generateErrorObject, + getErrorRespEvents, +} = require('../../util'); +const { JSON_MIME_TYPE } = require('../../util/constant'); +const { MAX_LEAD_IDS_SIZE } = require('./config'); +const { getAuthToken } = require('../marketo/transform'); +const { formatConfig } = require('../marketo/config'); + +/** + * Generates the final response structure to be sent to the destination + * @param {*} endPoint + * @param {*} leadIds + * @param {*} operation + * @param {*} token + * @returns batched response + */ +const responseBuilder = (endPoint, leadIds, operation, token) => { + let updatedEndpoint = endPoint; + if (leadIds.length > 0) { + leadIds.forEach((id) => { + updatedEndpoint = `${updatedEndpoint}id=${id}&`; + }); + } + updatedEndpoint = updatedEndpoint.slice(0, -1); + const response = defaultRequestConfig(); + response.endpoint = updatedEndpoint; + if (operation === 'insert') { + response.method = defaultPostRequestConfig.requestMethod; + } else { + response.method = defaultDeleteRequestConfig.requestMethod; + } + response.headers = { + Authorization: `Bearer ${token}`, + 'Content-Type': JSON_MIME_TYPE, + }; + return response; +}; + +/** + * The function is responsible for building the batched response for a given set of record inputs. + * @param {*} groupedRecordInputs + * @param {*} Config + * @param {*} token + * @param {*} leadIds + * @param {*} operation + * @returns an array of response objects, where each object represents a batched response for a chunk of lead IDs. + */ +const batchResponseBuilder = (listId, Config, token, leadIds, operation) => { + const { accountId } = Config; + const endpoint = `https://${accountId}.mktorest.com/rest/v1/lists/${listId}/leads.json?`; + const response = []; + const leadIdsChunks = lodash.chunk(leadIds, MAX_LEAD_IDS_SIZE); + leadIdsChunks.forEach((ids) => { + response.push(responseBuilder(endpoint, ids, operation, token)); + }); + return response; +}; + +/** + * A function that processes a list of grouped record inputs. + * It iterates through each input and groups the field IDs based on the action. + * @param {*} groupedRecordInputs + * @param {*} destination + * @param {*} listId + * @returns An array containing the batched responses for the insert and delete actions along with the metadata. + */ +async function processRecordInputs(groupedRecordInputs, destination, listId) { + const token = await getAuthToken(formatConfig(destination)); + if (!token) { + throw new UnauthorizedError('Authorization failed'); + } + const { Config } = destination; + + // iterate through each input and group field id based on action + const insertFields = []; + const deleteFields = []; + const successMetadataForInsert = []; + const successMetadataForDelete = []; + const errorMetadata = []; + + groupedRecordInputs.forEach((input) => { + const { fields, action } = input.message; + const fieldId = fields?.id; + if (action === 'insert' && isDefinedAndNotNull(fieldId)) { + insertFields.push(fieldId); + successMetadataForInsert.push(input.metadata); + } else if (action === 'delete' && isDefinedAndNotNull(fieldId)) { + deleteFields.push(fieldId); + successMetadataForDelete.push(input.metadata); + } else { + errorMetadata.push(input.metadata); + } + }); + const deletePayloads = batchResponseBuilder(listId, Config, token, deleteFields, 'delete'); + + const deleteResponse = getSuccessRespEvents( + deletePayloads, + successMetadataForDelete, + destination, + true, + ); + + const insertPayloads = batchResponseBuilder(listId, Config, token, insertFields, 'insert'); + + const insertResponse = getSuccessRespEvents( + insertPayloads, + successMetadataForInsert, + destination, + true, + ); + + const error = new InstrumentationError( + 'Invalid action type or no leadIds found neither to add nor to remove', + ); + const errorObj = generateErrorObject(error); + const errorResponseList = errorMetadata.map((metadata) => + getErrorRespEvents(metadata, errorObj.status, errorObj.message, errorObj.statTags), + ); + const finalResponse = []; + if (deleteResponse.batchedRequest.length > 0) { + finalResponse.push(deleteResponse); + } + if (insertResponse.batchedRequest.length > 0) { + finalResponse.push(insertResponse); + } + if (errorResponseList.length > 0) { + finalResponse.push(...errorResponseList); + } + return finalResponse; + // return [deleteResponse, insertResponse, ...errorResponseList]; +} + +module.exports = { + processRecordInputs, +}; diff --git a/src/v0/destinations/marketo_static_list/util.js b/src/v0/destinations/marketo_static_list/util.js index 3db6180d24..c6959cb256 100644 --- a/src/v0/destinations/marketo_static_list/util.js +++ b/src/v0/destinations/marketo_static_list/util.js @@ -1,3 +1,4 @@ +/* eslint-disable unicorn/consistent-destructuring */ const { InstrumentationError } = require('@rudderstack/integrations-lib'); /** diff --git a/test/__tests__/data/marketo_static_list.json b/test/__tests__/data/marketo_static_list.json deleted file mode 100644 index 701868cab0..0000000000 --- a/test/__tests__/data/marketo_static_list.json +++ /dev/null @@ -1,2542 +0,0 @@ -[ - { - "description": "adding and removing users and getting staticListId from externalId", - "input": { - "destination": { - "ID": "1zia9wKshXt80YksLmUdJnr7IHI", - "Name": "test_marketo", - "DestinationDefinition": { - "ID": "1iVQvTRMsPPyJzwol0ifH93QTQ6", - "Name": "MARKETO", - "DisplayName": "Marketo", - "transformAt": "processor", - "transformAtV1": "processor" - }, - "Config": { - "clientId": "marketo_client_id_success", - "clientSecret": "marketo_client_secret_success", - "accountId": "marketo_acct_id_success", - "staticListId": 3421 - }, - "Enabled": true, - "Transformations": [], - "IsProcessorEnabled": true - }, - "message": { - "userId": "user 1", - "anonymousId": "anon-id-new", - "event": "event1", - "type": "audiencelist", - "properties": { - "listData": { - "add": [ - { - "id": 1 - }, - { - "id": 2 - }, - { - "id": 3 - } - ], - "remove": [ - { - "id": 4 - }, - { - "id": 5 - }, - { - "id": 6 - } - ] - }, - "enablePartialFailure": true - }, - "context": { - "ip": "14.5.67.21", - "library": { - "name": "http" - }, - "externalId": [ - { - "type": "marketoStaticListId", - "id": 1234 - } - ] - }, - "timestamp": "2020-02-02T00:23:09.544Z" - } - }, - "output": [ - { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=1&id=2&id=3", - "headers": { - "Authorization": "Bearer access_token_success", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": {}, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {} - }, - { - "version": "1", - "type": "REST", - "method": "DELETE", - "endpoint": "https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=4&id=5&id=6", - "headers": { - "Authorization": "Bearer access_token_success", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": {}, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {} - } - ] - }, - { - "description": "adding more than max limit users", - "input": { - "destination": { - "ID": "1zia9wKshXt80YksLmUdJnr7IHI", - "Name": "test_marketo", - "DestinationDefinition": { - "ID": "1iVQvTRMsPPyJzwol0ifH93QTQ6", - "Name": "MARKETO", - "DisplayName": "Marketo", - "transformAt": "processor", - "transformAtV1": "processor" - }, - "Config": { - "clientId": "marketo_client_id_success", - "clientSecret": "marketo_client_secret_success", - "accountId": "marketo_acct_id_success", - "staticListId": 1234 - }, - "Enabled": true, - "Transformations": [], - "IsProcessorEnabled": true - }, - "message": { - "userId": "user 1", - "anonymousId": "anon-id-new", - "event": "event1", - "type": "audiencelist", - "properties": { - "listData": { - "add": [ - { - "id": 0 - }, - { - "id": 1 - }, - { - "id": 2 - }, - { - "id": 3 - }, - { - "id": 4 - }, - { - "id": 5 - }, - { - "id": 6 - }, - { - "id": 7 - }, - { - "id": 8 - }, - { - "id": 9 - }, - { - "id": 10 - }, - { - "id": 11 - }, - { - "id": 12 - }, - { - "id": 13 - }, - { - "id": 14 - }, - { - "id": 15 - }, - { - "id": 16 - }, - { - "id": 17 - }, - { - "id": 18 - }, - { - "id": 19 - }, - { - "id": 20 - }, - { - "id": 21 - }, - { - "id": 22 - }, - { - "id": 23 - }, - { - "id": 24 - }, - { - "id": 25 - }, - { - "id": 26 - }, - { - "id": 27 - }, - { - "id": 28 - }, - { - "id": 29 - }, - { - "id": 30 - }, - { - "id": 31 - }, - { - "id": 32 - }, - { - "id": 33 - }, - { - "id": 34 - }, - { - "id": 35 - }, - { - "id": 36 - }, - { - "id": 37 - }, - { - "id": 38 - }, - { - "id": 39 - }, - { - "id": 40 - }, - { - "id": 41 - }, - { - "id": 42 - }, - { - "id": 43 - }, - { - "id": 44 - }, - { - "id": 45 - }, - { - "id": 46 - }, - { - "id": 47 - }, - { - "id": 48 - }, - { - "id": 49 - }, - { - "id": 50 - }, - { - "id": 51 - }, - { - "id": 52 - }, - { - "id": 53 - }, - { - "id": 54 - }, - { - "id": 55 - }, - { - "id": 56 - }, - { - "id": 57 - }, - { - "id": 58 - }, - { - "id": 59 - }, - { - "id": 60 - }, - { - "id": 61 - }, - { - "id": 62 - }, - { - "id": 63 - }, - { - "id": 64 - }, - { - "id": 65 - }, - { - "id": 66 - }, - { - "id": 67 - }, - { - "id": 68 - }, - { - "id": 69 - }, - { - "id": 70 - }, - { - "id": 71 - }, - { - "id": 72 - }, - { - "id": 73 - }, - { - "id": 74 - }, - { - "id": 75 - }, - { - "id": 76 - }, - { - "id": 77 - }, - { - "id": 78 - }, - { - "id": 79 - }, - { - "id": 80 - }, - { - "id": 81 - }, - { - "id": 82 - }, - { - "id": 83 - }, - { - "id": 84 - }, - { - "id": 85 - }, - { - "id": 86 - }, - { - "id": 87 - }, - { - "id": 88 - }, - { - "id": 89 - }, - { - "id": 90 - }, - { - "id": 91 - }, - { - "id": 92 - }, - { - "id": 93 - }, - { - "id": 94 - }, - { - "id": 95 - }, - { - "id": 96 - }, - { - "id": 97 - }, - { - "id": 98 - }, - { - "id": 99 - }, - { - "id": 100 - }, - { - "id": 101 - }, - { - "id": 102 - }, - { - "id": 103 - }, - { - "id": 104 - }, - { - "id": 105 - }, - { - "id": 106 - }, - { - "id": 107 - }, - { - "id": 108 - }, - { - "id": 109 - }, - { - "id": 110 - }, - { - "id": 111 - }, - { - "id": 112 - }, - { - "id": 113 - }, - { - "id": 114 - }, - { - "id": 115 - }, - { - "id": 116 - }, - { - "id": 117 - }, - { - "id": 118 - }, - { - "id": 119 - }, - { - "id": 120 - }, - { - "id": 121 - }, - { - "id": 122 - }, - { - "id": 123 - }, - { - "id": 124 - }, - { - "id": 125 - }, - { - "id": 126 - }, - { - "id": 127 - }, - { - "id": 128 - }, - { - "id": 129 - }, - { - "id": 130 - }, - { - "id": 131 - }, - { - "id": 132 - }, - { - "id": 133 - }, - { - "id": 134 - }, - { - "id": 135 - }, - { - "id": 136 - }, - { - "id": 137 - }, - { - "id": 138 - }, - { - "id": 139 - }, - { - "id": 140 - }, - { - "id": 141 - }, - { - "id": 142 - }, - { - "id": 143 - }, - { - "id": 144 - }, - { - "id": 145 - }, - { - "id": 146 - }, - { - "id": 147 - }, - { - "id": 148 - }, - { - "id": 149 - }, - { - "id": 150 - }, - { - "id": 151 - }, - { - "id": 152 - }, - { - "id": 153 - }, - { - "id": 154 - }, - { - "id": 155 - }, - { - "id": 156 - }, - { - "id": 157 - }, - { - "id": 158 - }, - { - "id": 159 - }, - { - "id": 160 - }, - { - "id": 161 - }, - { - "id": 162 - }, - { - "id": 163 - }, - { - "id": 164 - }, - { - "id": 165 - }, - { - "id": 166 - }, - { - "id": 167 - }, - { - "id": 168 - }, - { - "id": 169 - }, - { - "id": 170 - }, - { - "id": 171 - }, - { - "id": 172 - }, - { - "id": 173 - }, - { - "id": 174 - }, - { - "id": 175 - }, - { - "id": 176 - }, - { - "id": 177 - }, - { - "id": 178 - }, - { - "id": 179 - }, - { - "id": 180 - }, - { - "id": 181 - }, - { - "id": 182 - }, - { - "id": 183 - }, - { - "id": 184 - }, - { - "id": 185 - }, - { - "id": 186 - }, - { - "id": 187 - }, - { - "id": 188 - }, - { - "id": 189 - }, - { - "id": 190 - }, - { - "id": 191 - }, - { - "id": 192 - }, - { - "id": 193 - }, - { - "id": 194 - }, - { - "id": 195 - }, - { - "id": 196 - }, - { - "id": 197 - }, - { - "id": 198 - }, - { - "id": 199 - }, - { - "id": 200 - }, - { - "id": 201 - }, - { - "id": 202 - }, - { - "id": 203 - }, - { - "id": 204 - }, - { - "id": 205 - }, - { - "id": 206 - }, - { - "id": 207 - }, - { - "id": 208 - }, - { - "id": 209 - }, - { - "id": 210 - }, - { - "id": 211 - }, - { - "id": 212 - }, - { - "id": 213 - }, - { - "id": 214 - }, - { - "id": 215 - }, - { - "id": 216 - }, - { - "id": 217 - }, - { - "id": 218 - }, - { - "id": 219 - }, - { - "id": 220 - }, - { - "id": 221 - }, - { - "id": 222 - }, - { - "id": 223 - }, - { - "id": 224 - }, - { - "id": 225 - }, - { - "id": 226 - }, - { - "id": 227 - }, - { - "id": 228 - }, - { - "id": 229 - }, - { - "id": 230 - }, - { - "id": 231 - }, - { - "id": 232 - }, - { - "id": 233 - }, - { - "id": 234 - }, - { - "id": 235 - }, - { - "id": 236 - }, - { - "id": 237 - }, - { - "id": 238 - }, - { - "id": 239 - }, - { - "id": 240 - }, - { - "id": 241 - }, - { - "id": 242 - }, - { - "id": 243 - }, - { - "id": 244 - }, - { - "id": 245 - }, - { - "id": 246 - }, - { - "id": 247 - }, - { - "id": 248 - }, - { - "id": 249 - }, - { - "id": 250 - }, - { - "id": 251 - }, - { - "id": 252 - }, - { - "id": 253 - }, - { - "id": 254 - }, - { - "id": 255 - }, - { - "id": 256 - }, - { - "id": 257 - }, - { - "id": 258 - }, - { - "id": 259 - }, - { - "id": 260 - }, - { - "id": 261 - }, - { - "id": 262 - }, - { - "id": 263 - }, - { - "id": 264 - }, - { - "id": 265 - }, - { - "id": 266 - }, - { - "id": 267 - }, - { - "id": 268 - }, - { - "id": 269 - }, - { - "id": 270 - }, - { - "id": 271 - }, - { - "id": 272 - }, - { - "id": 273 - }, - { - "id": 274 - }, - { - "id": 275 - }, - { - "id": 276 - }, - { - "id": 277 - }, - { - "id": 278 - }, - { - "id": 279 - }, - { - "id": 280 - }, - { - "id": 281 - }, - { - "id": 282 - }, - { - "id": 283 - }, - { - "id": 284 - }, - { - "id": 285 - }, - { - "id": 286 - }, - { - "id": 287 - }, - { - "id": 288 - }, - { - "id": 289 - }, - { - "id": 290 - }, - { - "id": 291 - }, - { - "id": 292 - }, - { - "id": 293 - }, - { - "id": 294 - }, - { - "id": 295 - }, - { - "id": 296 - }, - { - "id": 297 - }, - { - "id": 298 - }, - { - "id": 299 - }, - { - "id": 300 - }, - { - "id": 301 - }, - { - "id": 302 - }, - { - "id": 303 - }, - { - "id": 304 - }, - { - "id": 305 - }, - { - "id": 306 - }, - { - "id": 307 - }, - { - "id": 308 - }, - { - "id": 309 - }, - { - "id": 310 - }, - { - "id": 311 - }, - { - "id": 312 - }, - { - "id": 313 - }, - { - "id": 314 - }, - { - "id": 315 - }, - { - "id": 316 - }, - { - "id": 317 - }, - { - "id": 318 - }, - { - "id": 319 - }, - { - "id": 320 - }, - { - "id": 321 - }, - { - "id": 322 - }, - { - "id": 323 - }, - { - "id": 324 - }, - { - "id": 325 - }, - { - "id": 326 - }, - { - "id": 327 - }, - { - "id": 328 - }, - { - "id": 329 - }, - { - "id": 330 - }, - { - "id": 331 - }, - { - "id": 332 - }, - { - "id": 333 - }, - { - "id": 334 - }, - { - "id": 335 - }, - { - "id": 336 - }, - { - "id": 337 - }, - { - "id": 338 - }, - { - "id": 339 - }, - { - "id": 340 - }, - { - "id": 341 - }, - { - "id": 342 - }, - { - "id": 343 - }, - { - "id": 344 - }, - { - "id": 345 - }, - { - "id": 346 - }, - { - "id": 347 - }, - { - "id": 348 - }, - { - "id": 349 - }, - { - "id": 350 - } - ] - }, - "enablePartialFailure": true - }, - "context": { - "ip": "14.5.67.21", - "library": { - "name": "http" - } - }, - "timestamp": "2020-02-02T00:23:09.544Z" - } - }, - "output": [ - { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=0&id=1&id=2&id=3&id=4&id=5&id=6&id=7&id=8&id=9&id=10&id=11&id=12&id=13&id=14&id=15&id=16&id=17&id=18&id=19&id=20&id=21&id=22&id=23&id=24&id=25&id=26&id=27&id=28&id=29&id=30&id=31&id=32&id=33&id=34&id=35&id=36&id=37&id=38&id=39&id=40&id=41&id=42&id=43&id=44&id=45&id=46&id=47&id=48&id=49&id=50&id=51&id=52&id=53&id=54&id=55&id=56&id=57&id=58&id=59&id=60&id=61&id=62&id=63&id=64&id=65&id=66&id=67&id=68&id=69&id=70&id=71&id=72&id=73&id=74&id=75&id=76&id=77&id=78&id=79&id=80&id=81&id=82&id=83&id=84&id=85&id=86&id=87&id=88&id=89&id=90&id=91&id=92&id=93&id=94&id=95&id=96&id=97&id=98&id=99&id=100&id=101&id=102&id=103&id=104&id=105&id=106&id=107&id=108&id=109&id=110&id=111&id=112&id=113&id=114&id=115&id=116&id=117&id=118&id=119&id=120&id=121&id=122&id=123&id=124&id=125&id=126&id=127&id=128&id=129&id=130&id=131&id=132&id=133&id=134&id=135&id=136&id=137&id=138&id=139&id=140&id=141&id=142&id=143&id=144&id=145&id=146&id=147&id=148&id=149&id=150&id=151&id=152&id=153&id=154&id=155&id=156&id=157&id=158&id=159&id=160&id=161&id=162&id=163&id=164&id=165&id=166&id=167&id=168&id=169&id=170&id=171&id=172&id=173&id=174&id=175&id=176&id=177&id=178&id=179&id=180&id=181&id=182&id=183&id=184&id=185&id=186&id=187&id=188&id=189&id=190&id=191&id=192&id=193&id=194&id=195&id=196&id=197&id=198&id=199&id=200&id=201&id=202&id=203&id=204&id=205&id=206&id=207&id=208&id=209&id=210&id=211&id=212&id=213&id=214&id=215&id=216&id=217&id=218&id=219&id=220&id=221&id=222&id=223&id=224&id=225&id=226&id=227&id=228&id=229&id=230&id=231&id=232&id=233&id=234&id=235&id=236&id=237&id=238&id=239&id=240&id=241&id=242&id=243&id=244&id=245&id=246&id=247&id=248&id=249&id=250&id=251&id=252&id=253&id=254&id=255&id=256&id=257&id=258&id=259&id=260&id=261&id=262&id=263&id=264&id=265&id=266&id=267&id=268&id=269&id=270&id=271&id=272&id=273&id=274&id=275&id=276&id=277&id=278&id=279&id=280&id=281&id=282&id=283&id=284&id=285&id=286&id=287&id=288&id=289&id=290&id=291&id=292&id=293&id=294&id=295&id=296&id=297&id=298&id=299", - "headers": { - "Authorization": "Bearer access_token_success", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": {}, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {} - }, - { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=300&id=301&id=302&id=303&id=304&id=305&id=306&id=307&id=308&id=309&id=310&id=311&id=312&id=313&id=314&id=315&id=316&id=317&id=318&id=319&id=320&id=321&id=322&id=323&id=324&id=325&id=326&id=327&id=328&id=329&id=330&id=331&id=332&id=333&id=334&id=335&id=336&id=337&id=338&id=339&id=340&id=341&id=342&id=343&id=344&id=345&id=346&id=347&id=348&id=349&id=350", - "headers": { - "Authorization": "Bearer access_token_success", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": {}, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {} - } - ] - }, - { - "description": "removing more than max limit users", - "input": { - "destination": { - "ID": "1zia9wKshXt80YksLmUdJnr7IHI", - "Name": "test_marketo", - "DestinationDefinition": { - "ID": "1iVQvTRMsPPyJzwol0ifH93QTQ6", - "Name": "MARKETO", - "DisplayName": "Marketo", - "transformAt": "processor", - "transformAtV1": "processor" - }, - "Config": { - "clientId": "marketo_client_id_success", - "clientSecret": "marketo_client_secret_success", - "accountId": "marketo_acct_id_success", - "staticListId": 1234 - }, - "Enabled": true, - "Transformations": [], - "IsProcessorEnabled": true - }, - "message": { - "userId": "user 1", - "anonymousId": "anon-id-new", - "event": "event1", - "type": "audiencelist", - "properties": { - "listData": { - "remove": [ - { - "id": 0 - }, - { - "id": 1 - }, - { - "id": 2 - }, - { - "id": 3 - }, - { - "id": 4 - }, - { - "id": 5 - }, - { - "id": 6 - }, - { - "id": 7 - }, - { - "id": 8 - }, - { - "id": 9 - }, - { - "id": 10 - }, - { - "id": 11 - }, - { - "id": 12 - }, - { - "id": 13 - }, - { - "id": 14 - }, - { - "id": 15 - }, - { - "id": 16 - }, - { - "id": 17 - }, - { - "id": 18 - }, - { - "id": 19 - }, - { - "id": 20 - }, - { - "id": 21 - }, - { - "id": 22 - }, - { - "id": 23 - }, - { - "id": 24 - }, - { - "id": 25 - }, - { - "id": 26 - }, - { - "id": 27 - }, - { - "id": 28 - }, - { - "id": 29 - }, - { - "id": 30 - }, - { - "id": 31 - }, - { - "id": 32 - }, - { - "id": 33 - }, - { - "id": 34 - }, - { - "id": 35 - }, - { - "id": 36 - }, - { - "id": 37 - }, - { - "id": 38 - }, - { - "id": 39 - }, - { - "id": 40 - }, - { - "id": 41 - }, - { - "id": 42 - }, - { - "id": 43 - }, - { - "id": 44 - }, - { - "id": 45 - }, - { - "id": 46 - }, - { - "id": 47 - }, - { - "id": 48 - }, - { - "id": 49 - }, - { - "id": 50 - }, - { - "id": 51 - }, - { - "id": 52 - }, - { - "id": 53 - }, - { - "id": 54 - }, - { - "id": 55 - }, - { - "id": 56 - }, - { - "id": 57 - }, - { - "id": 58 - }, - { - "id": 59 - }, - { - "id": 60 - }, - { - "id": 61 - }, - { - "id": 62 - }, - { - "id": 63 - }, - { - "id": 64 - }, - { - "id": 65 - }, - { - "id": 66 - }, - { - "id": 67 - }, - { - "id": 68 - }, - { - "id": 69 - }, - { - "id": 70 - }, - { - "id": 71 - }, - { - "id": 72 - }, - { - "id": 73 - }, - { - "id": 74 - }, - { - "id": 75 - }, - { - "id": 76 - }, - { - "id": 77 - }, - { - "id": 78 - }, - { - "id": 79 - }, - { - "id": 80 - }, - { - "id": 81 - }, - { - "id": 82 - }, - { - "id": 83 - }, - { - "id": 84 - }, - { - "id": 85 - }, - { - "id": 86 - }, - { - "id": 87 - }, - { - "id": 88 - }, - { - "id": 89 - }, - { - "id": 90 - }, - { - "id": 91 - }, - { - "id": 92 - }, - { - "id": 93 - }, - { - "id": 94 - }, - { - "id": 95 - }, - { - "id": 96 - }, - { - "id": 97 - }, - { - "id": 98 - }, - { - "id": 99 - }, - { - "id": 100 - }, - { - "id": 101 - }, - { - "id": 102 - }, - { - "id": 103 - }, - { - "id": 104 - }, - { - "id": 105 - }, - { - "id": 106 - }, - { - "id": 107 - }, - { - "id": 108 - }, - { - "id": 109 - }, - { - "id": 110 - }, - { - "id": 111 - }, - { - "id": 112 - }, - { - "id": 113 - }, - { - "id": 114 - }, - { - "id": 115 - }, - { - "id": 116 - }, - { - "id": 117 - }, - { - "id": 118 - }, - { - "id": 119 - }, - { - "id": 120 - }, - { - "id": 121 - }, - { - "id": 122 - }, - { - "id": 123 - }, - { - "id": 124 - }, - { - "id": 125 - }, - { - "id": 126 - }, - { - "id": 127 - }, - { - "id": 128 - }, - { - "id": 129 - }, - { - "id": 130 - }, - { - "id": 131 - }, - { - "id": 132 - }, - { - "id": 133 - }, - { - "id": 134 - }, - { - "id": 135 - }, - { - "id": 136 - }, - { - "id": 137 - }, - { - "id": 138 - }, - { - "id": 139 - }, - { - "id": 140 - }, - { - "id": 141 - }, - { - "id": 142 - }, - { - "id": 143 - }, - { - "id": 144 - }, - { - "id": 145 - }, - { - "id": 146 - }, - { - "id": 147 - }, - { - "id": 148 - }, - { - "id": 149 - }, - { - "id": 150 - }, - { - "id": 151 - }, - { - "id": 152 - }, - { - "id": 153 - }, - { - "id": 154 - }, - { - "id": 155 - }, - { - "id": 156 - }, - { - "id": 157 - }, - { - "id": 158 - }, - { - "id": 159 - }, - { - "id": 160 - }, - { - "id": 161 - }, - { - "id": 162 - }, - { - "id": 163 - }, - { - "id": 164 - }, - { - "id": 165 - }, - { - "id": 166 - }, - { - "id": 167 - }, - { - "id": 168 - }, - { - "id": 169 - }, - { - "id": 170 - }, - { - "id": 171 - }, - { - "id": 172 - }, - { - "id": 173 - }, - { - "id": 174 - }, - { - "id": 175 - }, - { - "id": 176 - }, - { - "id": 177 - }, - { - "id": 178 - }, - { - "id": 179 - }, - { - "id": 180 - }, - { - "id": 181 - }, - { - "id": 182 - }, - { - "id": 183 - }, - { - "id": 184 - }, - { - "id": 185 - }, - { - "id": 186 - }, - { - "id": 187 - }, - { - "id": 188 - }, - { - "id": 189 - }, - { - "id": 190 - }, - { - "id": 191 - }, - { - "id": 192 - }, - { - "id": 193 - }, - { - "id": 194 - }, - { - "id": 195 - }, - { - "id": 196 - }, - { - "id": 197 - }, - { - "id": 198 - }, - { - "id": 199 - }, - { - "id": 200 - }, - { - "id": 201 - }, - { - "id": 202 - }, - { - "id": 203 - }, - { - "id": 204 - }, - { - "id": 205 - }, - { - "id": 206 - }, - { - "id": 207 - }, - { - "id": 208 - }, - { - "id": 209 - }, - { - "id": 210 - }, - { - "id": 211 - }, - { - "id": 212 - }, - { - "id": 213 - }, - { - "id": 214 - }, - { - "id": 215 - }, - { - "id": 216 - }, - { - "id": 217 - }, - { - "id": 218 - }, - { - "id": 219 - }, - { - "id": 220 - }, - { - "id": 221 - }, - { - "id": 222 - }, - { - "id": 223 - }, - { - "id": 224 - }, - { - "id": 225 - }, - { - "id": 226 - }, - { - "id": 227 - }, - { - "id": 228 - }, - { - "id": 229 - }, - { - "id": 230 - }, - { - "id": 231 - }, - { - "id": 232 - }, - { - "id": 233 - }, - { - "id": 234 - }, - { - "id": 235 - }, - { - "id": 236 - }, - { - "id": 237 - }, - { - "id": 238 - }, - { - "id": 239 - }, - { - "id": 240 - }, - { - "id": 241 - }, - { - "id": 242 - }, - { - "id": 243 - }, - { - "id": 244 - }, - { - "id": 245 - }, - { - "id": 246 - }, - { - "id": 247 - }, - { - "id": 248 - }, - { - "id": 249 - }, - { - "id": 250 - }, - { - "id": 251 - }, - { - "id": 252 - }, - { - "id": 253 - }, - { - "id": 254 - }, - { - "id": 255 - }, - { - "id": 256 - }, - { - "id": 257 - }, - { - "id": 258 - }, - { - "id": 259 - }, - { - "id": 260 - }, - { - "id": 261 - }, - { - "id": 262 - }, - { - "id": 263 - }, - { - "id": 264 - }, - { - "id": 265 - }, - { - "id": 266 - }, - { - "id": 267 - }, - { - "id": 268 - }, - { - "id": 269 - }, - { - "id": 270 - }, - { - "id": 271 - }, - { - "id": 272 - }, - { - "id": 273 - }, - { - "id": 274 - }, - { - "id": 275 - }, - { - "id": 276 - }, - { - "id": 277 - }, - { - "id": 278 - }, - { - "id": 279 - }, - { - "id": 280 - }, - { - "id": 281 - }, - { - "id": 282 - }, - { - "id": 283 - }, - { - "id": 284 - }, - { - "id": 285 - }, - { - "id": 286 - }, - { - "id": 287 - }, - { - "id": 288 - }, - { - "id": 289 - }, - { - "id": 290 - }, - { - "id": 291 - }, - { - "id": 292 - }, - { - "id": 293 - }, - { - "id": 294 - }, - { - "id": 295 - }, - { - "id": 296 - }, - { - "id": 297 - }, - { - "id": 298 - }, - { - "id": 299 - }, - { - "id": 300 - }, - { - "id": 301 - }, - { - "id": 302 - }, - { - "id": 303 - }, - { - "id": 304 - }, - { - "id": 305 - }, - { - "id": 306 - }, - { - "id": 307 - }, - { - "id": 308 - }, - { - "id": 309 - }, - { - "id": 310 - }, - { - "id": 311 - }, - { - "id": 312 - }, - { - "id": 313 - }, - { - "id": 314 - }, - { - "id": 315 - }, - { - "id": 316 - }, - { - "id": 317 - }, - { - "id": 318 - }, - { - "id": 319 - }, - { - "id": 320 - }, - { - "id": 321 - }, - { - "id": 322 - }, - { - "id": 323 - }, - { - "id": 324 - }, - { - "id": 325 - }, - { - "id": 326 - }, - { - "id": 327 - }, - { - "id": 328 - }, - { - "id": 329 - }, - { - "id": 330 - }, - { - "id": 331 - }, - { - "id": 332 - }, - { - "id": 333 - }, - { - "id": 334 - }, - { - "id": 335 - }, - { - "id": 336 - }, - { - "id": 337 - }, - { - "id": 338 - }, - { - "id": 339 - }, - { - "id": 340 - }, - { - "id": 341 - }, - { - "id": 342 - }, - { - "id": 343 - }, - { - "id": 344 - }, - { - "id": 345 - }, - { - "id": 346 - }, - { - "id": 347 - }, - { - "id": 348 - }, - { - "id": 349 - }, - { - "id": 350 - } - ] - }, - "enablePartialFailure": true - }, - "context": { - "ip": "14.5.67.21", - "library": { - "name": "http" - } - }, - "timestamp": "2020-02-02T00:23:09.544Z" - } - }, - "output": [ - { - "version": "1", - "type": "REST", - "method": "DELETE", - "endpoint": "https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=0&id=1&id=2&id=3&id=4&id=5&id=6&id=7&id=8&id=9&id=10&id=11&id=12&id=13&id=14&id=15&id=16&id=17&id=18&id=19&id=20&id=21&id=22&id=23&id=24&id=25&id=26&id=27&id=28&id=29&id=30&id=31&id=32&id=33&id=34&id=35&id=36&id=37&id=38&id=39&id=40&id=41&id=42&id=43&id=44&id=45&id=46&id=47&id=48&id=49&id=50&id=51&id=52&id=53&id=54&id=55&id=56&id=57&id=58&id=59&id=60&id=61&id=62&id=63&id=64&id=65&id=66&id=67&id=68&id=69&id=70&id=71&id=72&id=73&id=74&id=75&id=76&id=77&id=78&id=79&id=80&id=81&id=82&id=83&id=84&id=85&id=86&id=87&id=88&id=89&id=90&id=91&id=92&id=93&id=94&id=95&id=96&id=97&id=98&id=99&id=100&id=101&id=102&id=103&id=104&id=105&id=106&id=107&id=108&id=109&id=110&id=111&id=112&id=113&id=114&id=115&id=116&id=117&id=118&id=119&id=120&id=121&id=122&id=123&id=124&id=125&id=126&id=127&id=128&id=129&id=130&id=131&id=132&id=133&id=134&id=135&id=136&id=137&id=138&id=139&id=140&id=141&id=142&id=143&id=144&id=145&id=146&id=147&id=148&id=149&id=150&id=151&id=152&id=153&id=154&id=155&id=156&id=157&id=158&id=159&id=160&id=161&id=162&id=163&id=164&id=165&id=166&id=167&id=168&id=169&id=170&id=171&id=172&id=173&id=174&id=175&id=176&id=177&id=178&id=179&id=180&id=181&id=182&id=183&id=184&id=185&id=186&id=187&id=188&id=189&id=190&id=191&id=192&id=193&id=194&id=195&id=196&id=197&id=198&id=199&id=200&id=201&id=202&id=203&id=204&id=205&id=206&id=207&id=208&id=209&id=210&id=211&id=212&id=213&id=214&id=215&id=216&id=217&id=218&id=219&id=220&id=221&id=222&id=223&id=224&id=225&id=226&id=227&id=228&id=229&id=230&id=231&id=232&id=233&id=234&id=235&id=236&id=237&id=238&id=239&id=240&id=241&id=242&id=243&id=244&id=245&id=246&id=247&id=248&id=249&id=250&id=251&id=252&id=253&id=254&id=255&id=256&id=257&id=258&id=259&id=260&id=261&id=262&id=263&id=264&id=265&id=266&id=267&id=268&id=269&id=270&id=271&id=272&id=273&id=274&id=275&id=276&id=277&id=278&id=279&id=280&id=281&id=282&id=283&id=284&id=285&id=286&id=287&id=288&id=289&id=290&id=291&id=292&id=293&id=294&id=295&id=296&id=297&id=298&id=299", - "headers": { - "Authorization": "Bearer access_token_success", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": {}, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {} - }, - { - "version": "1", - "type": "REST", - "method": "DELETE", - "endpoint": "https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=300&id=301&id=302&id=303&id=304&id=305&id=306&id=307&id=308&id=309&id=310&id=311&id=312&id=313&id=314&id=315&id=316&id=317&id=318&id=319&id=320&id=321&id=322&id=323&id=324&id=325&id=326&id=327&id=328&id=329&id=330&id=331&id=332&id=333&id=334&id=335&id=336&id=337&id=338&id=339&id=340&id=341&id=342&id=343&id=344&id=345&id=346&id=347&id=348&id=349&id=350", - "headers": { - "Authorization": "Bearer access_token_success", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": {}, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {} - } - ] - }, - { - "description": "unsupported message Type", - "input": { - "destination": { - "ID": "1zia9wKshXt80YksLmUdJnr7IHI", - "Name": "test_marketo", - "DestinationDefinition": { - "ID": "1iVQvTRMsPPyJzwol0ifH93QTQ6", - "Name": "MARKETO", - "DisplayName": "Marketo", - "transformAt": "processor", - "transformAtV1": "processor" - }, - "Config": { - "clientId": "marketo_client_id_success", - "clientSecret": "marketo_client_secret_success", - "accountId": "marketo_acct_id_success", - "staticListId": 1234 - }, - "Enabled": true, - "Transformations": [], - "IsProcessorEnabled": true - }, - "message": { - "userId": "user 1", - "anonymousId": "anon-id-new", - "event": "event1", - "type": "track", - "properties": { - "listData": { - "remove": [1] - }, - "enablePartialFailure": true - }, - "context": { - "ip": "14.5.67.21", - "library": { - "name": "http" - } - }, - "timestamp": "2020-02-02T00:23:09.544Z" - } - }, - "output": { - "error": "Event type track is not supported" - } - }, - { - "description": "Invalid leadIds format ", - "input": { - "destination": { - "ID": "1zia9wKshXt80YksLmUdJnr7IHI", - "Name": "test_marketo", - "DestinationDefinition": { - "ID": "1iVQvTRMsPPyJzwol0ifH93QTQ6", - "Name": "MARKETO", - "DisplayName": "Marketo", - "transformAt": "processor", - "transformAtV1": "processor" - }, - "Config": { - "clientId": "marketo_client_id_success", - "clientSecret": "marketo_client_secret_success", - "accountId": "marketo_acct_id_success", - "staticListId": 1234 - }, - "Enabled": true, - "Transformations": [], - "IsProcessorEnabled": true - }, - "message": { - "userId": "user 1", - "anonymousId": "anon-id-new", - "event": "event1", - "type": "audiencelist", - "properties": { - "listData": { - "remove": 1 - }, - "enablePartialFailure": true - }, - "context": { - "ip": "14.5.67.21", - "library": { - "name": "http" - } - }, - "timestamp": "2020-02-02T00:23:09.544Z" - } - }, - "output": { - "error": "Invalid leadIds format or no leadIds found neither to add nor to remove" - } - }, - { - "description": "Only adding with remove not an array", - "input": { - "destination": { - "ID": "1zia9wKshXt80YksLmUdJnr7IHI", - "Name": "test_marketo", - "DestinationDefinition": { - "ID": "1iVQvTRMsPPyJzwol0ifH93QTQ6", - "Name": "MARKETO", - "DisplayName": "Marketo", - "transformAt": "processor", - "transformAtV1": "processor" - }, - "Config": { - "clientId": "marketo_client_id_success", - "clientSecret": "marketo_client_secret_success", - "accountId": "marketo_acct_id_success", - "staticListId": 1234 - }, - "Enabled": true, - "Transformations": [], - "IsProcessorEnabled": true - }, - "message": { - "userId": "user 1", - "anonymousId": "anon-id-new", - "event": "event1", - "type": "audiencelist", - "properties": { - "listData": { - "add": [{ "id": 1 }], - "remove": 2 - }, - "enablePartialFailure": true - }, - "context": { - "ip": "14.5.67.21", - "library": { - "name": "http" - } - }, - "timestamp": "2020-02-02T00:23:09.544Z" - } - }, - "output": [ - { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=1", - "headers": { - "Authorization": "Bearer access_token_success", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": {}, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {} - } - ] - } -] diff --git a/test/__tests__/data/marketo_static_list_router_input.json b/test/__tests__/data/marketo_static_list_router_input.json deleted file mode 100644 index ed3a7591e6..0000000000 --- a/test/__tests__/data/marketo_static_list_router_input.json +++ /dev/null @@ -1,1209 +0,0 @@ -[ - { - "destination": { - "ID": "1zia9wKshXt80YksLmUdJnr7IHI", - "Name": "test_marketo", - "DestinationDefinition": { - "ID": "1iVQvTRMsPPyJzwol0ifH93QTQ6", - "Name": "MARKETO", - "DisplayName": "Marketo", - "transformAt": "processor", - "transformAtV1": "processor" - }, - "Config": { - "clientId": "marketo_client_id_success", - "clientSecret": "marketo_client_secret_success", - "accountId": "marketo_acct_id_success", - "staticListId": 1234 - }, - "Enabled": true, - "Transformations": [], - "IsProcessorEnabled": true - }, - "message": { - "userId": "user 1", - "anonymousId": "anon-id-new", - "event": "event1", - "type": "audiencelist", - "properties": { - "listData": { - "add": [ - { - "id": 1 - }, - { - "id": 2 - }, - { - "id": 3 - } - ], - "remove": [ - { - "id": 4 - }, - { - "id": 5 - }, - { - "id": 6 - } - ] - }, - "enablePartialFailure": true - }, - "context": { - "ip": "14.5.67.21", - "library": { - "name": "http" - } - }, - "timestamp": "2020-02-02T00:23:09.544Z" - }, - "metadata": { - "jobId": 1 - } - }, - { - "destination": { - "ID": "1zia9wKshXt80YksLmUdJnr7IHI", - "Name": "test_marketo", - "DestinationDefinition": { - "ID": "1iVQvTRMsPPyJzwol0ifH93QTQ6", - "Name": "MARKETO", - "DisplayName": "Marketo", - "transformAt": "processor", - "transformAtV1": "processor" - }, - "Config": { - "clientId": "marketo_client_id_success", - "clientSecret": "marketo_client_secret_success", - "accountId": "marketo_acct_id_success", - "staticListId": 1234 - }, - "Enabled": true, - "Transformations": [], - "IsProcessorEnabled": true - }, - "message": { - "userId": "user 1", - "anonymousId": "anon-id-new", - "event": "event1", - "type": "audiencelist", - "properties": { - "listData": { - "add": [ - { - "id": 0 - }, - { - "id": 1 - }, - { - "id": 2 - }, - { - "id": 3 - }, - { - "id": 4 - }, - { - "id": 5 - }, - { - "id": 6 - }, - { - "id": 7 - }, - { - "id": 8 - }, - { - "id": 9 - }, - { - "id": 10 - }, - { - "id": 11 - }, - { - "id": 12 - }, - { - "id": 13 - }, - { - "id": 14 - }, - { - "id": 15 - }, - { - "id": 16 - }, - { - "id": 17 - }, - { - "id": 18 - }, - { - "id": 19 - }, - { - "id": 20 - }, - { - "id": 21 - }, - { - "id": 22 - }, - { - "id": 23 - }, - { - "id": 24 - }, - { - "id": 25 - }, - { - "id": 26 - }, - { - "id": 27 - }, - { - "id": 28 - }, - { - "id": 29 - }, - { - "id": 30 - }, - { - "id": 31 - }, - { - "id": 32 - }, - { - "id": 33 - }, - { - "id": 34 - }, - { - "id": 35 - }, - { - "id": 36 - }, - { - "id": 37 - }, - { - "id": 38 - }, - { - "id": 39 - }, - { - "id": 40 - }, - { - "id": 41 - }, - { - "id": 42 - }, - { - "id": 43 - }, - { - "id": 44 - }, - { - "id": 45 - }, - { - "id": 46 - }, - { - "id": 47 - }, - { - "id": 48 - }, - { - "id": 49 - }, - { - "id": 50 - }, - { - "id": 51 - }, - { - "id": 52 - }, - { - "id": 53 - }, - { - "id": 54 - }, - { - "id": 55 - }, - { - "id": 56 - }, - { - "id": 57 - }, - { - "id": 58 - }, - { - "id": 59 - }, - { - "id": 60 - }, - { - "id": 61 - }, - { - "id": 62 - }, - { - "id": 63 - }, - { - "id": 64 - }, - { - "id": 65 - }, - { - "id": 66 - }, - { - "id": 67 - }, - { - "id": 68 - }, - { - "id": 69 - }, - { - "id": 70 - }, - { - "id": 71 - }, - { - "id": 72 - }, - { - "id": 73 - }, - { - "id": 74 - }, - { - "id": 75 - }, - { - "id": 76 - }, - { - "id": 77 - }, - { - "id": 78 - }, - { - "id": 79 - }, - { - "id": 80 - }, - { - "id": 81 - }, - { - "id": 82 - }, - { - "id": 83 - }, - { - "id": 84 - }, - { - "id": 85 - }, - { - "id": 86 - }, - { - "id": 87 - }, - { - "id": 88 - }, - { - "id": 89 - }, - { - "id": 90 - }, - { - "id": 91 - }, - { - "id": 92 - }, - { - "id": 93 - }, - { - "id": 94 - }, - { - "id": 95 - }, - { - "id": 96 - }, - { - "id": 97 - }, - { - "id": 98 - }, - { - "id": 99 - }, - { - "id": 100 - }, - { - "id": 101 - }, - { - "id": 102 - }, - { - "id": 103 - }, - { - "id": 104 - }, - { - "id": 105 - }, - { - "id": 106 - }, - { - "id": 107 - }, - { - "id": 108 - }, - { - "id": 109 - }, - { - "id": 110 - }, - { - "id": 111 - }, - { - "id": 112 - }, - { - "id": 113 - }, - { - "id": 114 - }, - { - "id": 115 - }, - { - "id": 116 - }, - { - "id": 117 - }, - { - "id": 118 - }, - { - "id": 119 - }, - { - "id": 120 - }, - { - "id": 121 - }, - { - "id": 122 - }, - { - "id": 123 - }, - { - "id": 124 - }, - { - "id": 125 - }, - { - "id": 126 - }, - { - "id": 127 - }, - { - "id": 128 - }, - { - "id": 129 - }, - { - "id": 130 - }, - { - "id": 131 - }, - { - "id": 132 - }, - { - "id": 133 - }, - { - "id": 134 - }, - { - "id": 135 - }, - { - "id": 136 - }, - { - "id": 137 - }, - { - "id": 138 - }, - { - "id": 139 - }, - { - "id": 140 - }, - { - "id": 141 - }, - { - "id": 142 - }, - { - "id": 143 - }, - { - "id": 144 - }, - { - "id": 145 - }, - { - "id": 146 - }, - { - "id": 147 - }, - { - "id": 148 - }, - { - "id": 149 - }, - { - "id": 150 - }, - { - "id": 151 - }, - { - "id": 152 - }, - { - "id": 153 - }, - { - "id": 154 - }, - { - "id": 155 - }, - { - "id": 156 - }, - { - "id": 157 - }, - { - "id": 158 - }, - { - "id": 159 - }, - { - "id": 160 - }, - { - "id": 161 - }, - { - "id": 162 - }, - { - "id": 163 - }, - { - "id": 164 - }, - { - "id": 165 - }, - { - "id": 166 - }, - { - "id": 167 - }, - { - "id": 168 - }, - { - "id": 169 - }, - { - "id": 170 - }, - { - "id": 171 - }, - { - "id": 172 - }, - { - "id": 173 - }, - { - "id": 174 - }, - { - "id": 175 - }, - { - "id": 176 - }, - { - "id": 177 - }, - { - "id": 178 - }, - { - "id": 179 - }, - { - "id": 180 - }, - { - "id": 181 - }, - { - "id": 182 - }, - { - "id": 183 - }, - { - "id": 184 - }, - { - "id": 185 - }, - { - "id": 186 - }, - { - "id": 187 - }, - { - "id": 188 - }, - { - "id": 189 - }, - { - "id": 190 - }, - { - "id": 191 - }, - { - "id": 192 - }, - { - "id": 193 - }, - { - "id": 194 - }, - { - "id": 195 - }, - { - "id": 196 - }, - { - "id": 197 - }, - { - "id": 198 - }, - { - "id": 199 - }, - { - "id": 200 - }, - { - "id": 201 - }, - { - "id": 202 - }, - { - "id": 203 - }, - { - "id": 204 - }, - { - "id": 205 - }, - { - "id": 206 - }, - { - "id": 207 - }, - { - "id": 208 - }, - { - "id": 209 - }, - { - "id": 210 - }, - { - "id": 211 - }, - { - "id": 212 - }, - { - "id": 213 - }, - { - "id": 214 - }, - { - "id": 215 - }, - { - "id": 216 - }, - { - "id": 217 - }, - { - "id": 218 - }, - { - "id": 219 - }, - { - "id": 220 - }, - { - "id": 221 - }, - { - "id": 222 - }, - { - "id": 223 - }, - { - "id": 224 - }, - { - "id": 225 - }, - { - "id": 226 - }, - { - "id": 227 - }, - { - "id": 228 - }, - { - "id": 229 - }, - { - "id": 230 - }, - { - "id": 231 - }, - { - "id": 232 - }, - { - "id": 233 - }, - { - "id": 234 - }, - { - "id": 235 - }, - { - "id": 236 - }, - { - "id": 237 - }, - { - "id": 238 - }, - { - "id": 239 - }, - { - "id": 240 - }, - { - "id": 241 - }, - { - "id": 242 - }, - { - "id": 243 - }, - { - "id": 244 - }, - { - "id": 245 - }, - { - "id": 246 - }, - { - "id": 247 - }, - { - "id": 248 - }, - { - "id": 249 - }, - { - "id": 250 - }, - { - "id": 251 - }, - { - "id": 252 - }, - { - "id": 253 - }, - { - "id": 254 - }, - { - "id": 255 - }, - { - "id": 256 - }, - { - "id": 257 - }, - { - "id": 258 - }, - { - "id": 259 - }, - { - "id": 260 - }, - { - "id": 261 - }, - { - "id": 262 - }, - { - "id": 263 - }, - { - "id": 264 - }, - { - "id": 265 - }, - { - "id": 266 - }, - { - "id": 267 - }, - { - "id": 268 - }, - { - "id": 269 - }, - { - "id": 270 - }, - { - "id": 271 - }, - { - "id": 272 - }, - { - "id": 273 - }, - { - "id": 274 - }, - { - "id": 275 - }, - { - "id": 276 - }, - { - "id": 277 - }, - { - "id": 278 - }, - { - "id": 279 - }, - { - "id": 280 - }, - { - "id": 281 - }, - { - "id": 282 - }, - { - "id": 283 - }, - { - "id": 284 - }, - { - "id": 285 - }, - { - "id": 286 - }, - { - "id": 287 - }, - { - "id": 288 - }, - { - "id": 289 - }, - { - "id": 290 - }, - { - "id": 291 - }, - { - "id": 292 - }, - { - "id": 293 - }, - { - "id": 294 - }, - { - "id": 295 - }, - { - "id": 296 - }, - { - "id": 297 - }, - { - "id": 298 - }, - { - "id": 299 - }, - { - "id": 300 - }, - { - "id": 301 - }, - { - "id": 302 - }, - { - "id": 303 - }, - { - "id": 304 - }, - { - "id": 305 - }, - { - "id": 306 - }, - { - "id": 307 - }, - { - "id": 308 - }, - { - "id": 309 - }, - { - "id": 310 - }, - { - "id": 311 - }, - { - "id": 312 - }, - { - "id": 313 - }, - { - "id": 314 - }, - { - "id": 315 - }, - { - "id": 316 - }, - { - "id": 317 - }, - { - "id": 318 - }, - { - "id": 319 - }, - { - "id": 320 - }, - { - "id": 321 - }, - { - "id": 322 - }, - { - "id": 323 - }, - { - "id": 324 - }, - { - "id": 325 - }, - { - "id": 326 - }, - { - "id": 327 - }, - { - "id": 328 - }, - { - "id": 329 - }, - { - "id": 330 - }, - { - "id": 331 - }, - { - "id": 332 - }, - { - "id": 333 - }, - { - "id": 334 - }, - { - "id": 335 - }, - { - "id": 336 - }, - { - "id": 337 - }, - { - "id": 338 - }, - { - "id": 339 - }, - { - "id": 340 - }, - { - "id": 341 - }, - { - "id": 342 - }, - { - "id": 343 - }, - { - "id": 344 - }, - { - "id": 345 - }, - { - "id": 346 - }, - { - "id": 347 - }, - { - "id": 348 - }, - { - "id": 349 - }, - { - "id": 350 - } - ] - }, - "enablePartialFailure": true - }, - "context": { - "ip": "14.5.67.21", - "library": { - "name": "http" - } - }, - "timestamp": "2020-02-02T00:23:09.544Z" - }, - "metadata": { - "jobId": 2 - } - }, - { - "destination": { - "ID": "1zia9wKshXt80YksLmUdJnr7IHI", - "Name": "test_marketo", - "DestinationDefinition": { - "ID": "1iVQvTRMsPPyJzwol0ifH93QTQ6", - "Name": "MARKETO", - "DisplayName": "Marketo", - "transformAt": "processor", - "transformAtV1": "processor" - }, - "Config": { - "clientId": "marketo_client_id_success", - "clientSecret": "marketo_client_secret_success", - "accountId": "marketo_acct_id_success", - "staticListId": 1234 - }, - "Enabled": true, - "Transformations": [], - "IsProcessorEnabled": true - }, - "message": { - "userId": "user 1", - "anonymousId": "anon-id-new", - "event": "event1", - "type": "track", - "properties": { - "listData": { - "remove": [1] - }, - "enablePartialFailure": true - }, - "context": { - "ip": "14.5.67.21", - "library": { - "name": "http" - } - }, - "timestamp": "2020-02-02T00:23:09.544Z" - }, - "metadata": { - "jobId": 3 - } - } -] diff --git a/test/__tests__/data/marketo_static_list_router_metadata_input.json b/test/__tests__/data/marketo_static_list_router_metadata_input.json deleted file mode 100644 index d006aa184b..0000000000 --- a/test/__tests__/data/marketo_static_list_router_metadata_input.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "batchedRequest": { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=1&id=2&id=3", - "headers": { - "Content-Type": "application/json", - "Authorization": "Bearer access_token_success" - }, - "params": {}, - "body": { - "JSON": {}, - "XML": {}, - "JSON_ARRAY": {}, - "FORM": {} - }, - "files": {} - }, - "metadata": [ - { - "jobId": 1 - }, - { - "jobId": 2 - }, - { - "jobId": 3 - } - ], - "batched": false, - "statusCode": 200, - "destination": { - "Config": { - "accountId": "marketo_acct_id_success", - "clientId": "marketo_client_id_success", - "clientSecret": "marketo_client_secret_success", - "staticListId": 3027 - }, - "secretConfig": {}, - "ID": "1mMy5cqbtfuaKZv1IhVQKnBdVwe", - "name": "Marketo Static List", - "enabled": true, - "workspaceId": "1TSN08muJTZwH8iCDmnnRt1pmLd", - "deleted": false, - "createdAt": "2020-12-30T08:39:32.005Z", - "updatedAt": "2021-02-03T16:22:31.374Z", - "destinationDefinition": { - "config": { - "destConfig": { - "defaultConfig": ["accountId", "clientId", "clientSecret", "staticListId"] - }, - "secretKeys": ["clientSecret"], - "excludeKeys": [], - "includeKeys": [], - "routerTransform": true, - "supportedSourceTypes": ["android", "ios", "web", "unity", "amp", "cloud", "reactnative"] - }, - "id": "1aIXqM806xAVm92nx07YwKbRrO9", - "name": "MARKETO_STATIC_LIST", - "displayName": "Marketo Static List", - "createdAt": "2020-04-09T09:24:31.794Z", - "updatedAt": "2021-01-11T11:03:28.103Z" - }, - "transformations": [], - "isConnectionEnabled": true, - "isProcessorEnabled": true - } -} diff --git a/test/__tests__/data/marketo_static_list_router_metadata_output.json b/test/__tests__/data/marketo_static_list_router_metadata_output.json deleted file mode 100644 index bc560d73a7..0000000000 --- a/test/__tests__/data/marketo_static_list_router_metadata_output.json +++ /dev/null @@ -1,20 +0,0 @@ -[ - { - "destInfo": { - "authKey": "1mMy5cqbtfuaKZv1IhVQKnBdVwe" - }, - "jobId": 1 - }, - { - "destInfo": { - "authKey": "1mMy5cqbtfuaKZv1IhVQKnBdVwe" - }, - "jobId": 2 - }, - { - "destInfo": { - "authKey": "1mMy5cqbtfuaKZv1IhVQKnBdVwe" - }, - "jobId": 3 - } -] diff --git a/test/__tests__/data/marketo_static_list_router_output.json b/test/__tests__/data/marketo_static_list_router_output.json deleted file mode 100644 index 9c096b84c6..0000000000 --- a/test/__tests__/data/marketo_static_list_router_output.json +++ /dev/null @@ -1,170 +0,0 @@ -[ - { - "batchedRequest": [ - { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=1&id=2&id=3", - "headers": { - "Authorization": "Bearer access_token_success", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": {}, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {} - }, - { - "version": "1", - "type": "REST", - "method": "DELETE", - "endpoint": "https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=4&id=5&id=6", - "headers": { - "Authorization": "Bearer access_token_success", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": {}, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {} - } - ], - "metadata": [ - { - "jobId": 1 - } - ], - "batched": false, - "statusCode": 200, - "destination": { - "ID": "1zia9wKshXt80YksLmUdJnr7IHI", - "Name": "test_marketo", - "DestinationDefinition": { - "ID": "1iVQvTRMsPPyJzwol0ifH93QTQ6", - "Name": "MARKETO", - "DisplayName": "Marketo", - "transformAt": "processor", - "transformAtV1": "processor" - }, - "Config": { - "clientId": "marketo_client_id_success", - "clientSecret": "marketo_client_secret_success", - "accountId": "marketo_acct_id_success", - "staticListId": 1234 - }, - "Enabled": true, - "Transformations": [], - "IsProcessorEnabled": true - } - }, - { - "batchedRequest": [ - { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=0&id=1&id=2&id=3&id=4&id=5&id=6&id=7&id=8&id=9&id=10&id=11&id=12&id=13&id=14&id=15&id=16&id=17&id=18&id=19&id=20&id=21&id=22&id=23&id=24&id=25&id=26&id=27&id=28&id=29&id=30&id=31&id=32&id=33&id=34&id=35&id=36&id=37&id=38&id=39&id=40&id=41&id=42&id=43&id=44&id=45&id=46&id=47&id=48&id=49&id=50&id=51&id=52&id=53&id=54&id=55&id=56&id=57&id=58&id=59&id=60&id=61&id=62&id=63&id=64&id=65&id=66&id=67&id=68&id=69&id=70&id=71&id=72&id=73&id=74&id=75&id=76&id=77&id=78&id=79&id=80&id=81&id=82&id=83&id=84&id=85&id=86&id=87&id=88&id=89&id=90&id=91&id=92&id=93&id=94&id=95&id=96&id=97&id=98&id=99&id=100&id=101&id=102&id=103&id=104&id=105&id=106&id=107&id=108&id=109&id=110&id=111&id=112&id=113&id=114&id=115&id=116&id=117&id=118&id=119&id=120&id=121&id=122&id=123&id=124&id=125&id=126&id=127&id=128&id=129&id=130&id=131&id=132&id=133&id=134&id=135&id=136&id=137&id=138&id=139&id=140&id=141&id=142&id=143&id=144&id=145&id=146&id=147&id=148&id=149&id=150&id=151&id=152&id=153&id=154&id=155&id=156&id=157&id=158&id=159&id=160&id=161&id=162&id=163&id=164&id=165&id=166&id=167&id=168&id=169&id=170&id=171&id=172&id=173&id=174&id=175&id=176&id=177&id=178&id=179&id=180&id=181&id=182&id=183&id=184&id=185&id=186&id=187&id=188&id=189&id=190&id=191&id=192&id=193&id=194&id=195&id=196&id=197&id=198&id=199&id=200&id=201&id=202&id=203&id=204&id=205&id=206&id=207&id=208&id=209&id=210&id=211&id=212&id=213&id=214&id=215&id=216&id=217&id=218&id=219&id=220&id=221&id=222&id=223&id=224&id=225&id=226&id=227&id=228&id=229&id=230&id=231&id=232&id=233&id=234&id=235&id=236&id=237&id=238&id=239&id=240&id=241&id=242&id=243&id=244&id=245&id=246&id=247&id=248&id=249&id=250&id=251&id=252&id=253&id=254&id=255&id=256&id=257&id=258&id=259&id=260&id=261&id=262&id=263&id=264&id=265&id=266&id=267&id=268&id=269&id=270&id=271&id=272&id=273&id=274&id=275&id=276&id=277&id=278&id=279&id=280&id=281&id=282&id=283&id=284&id=285&id=286&id=287&id=288&id=289&id=290&id=291&id=292&id=293&id=294&id=295&id=296&id=297&id=298&id=299", - "headers": { - "Authorization": "Bearer access_token_success", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": {}, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {} - }, - { - "version": "1", - "type": "REST", - "method": "POST", - "endpoint": "https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=300&id=301&id=302&id=303&id=304&id=305&id=306&id=307&id=308&id=309&id=310&id=311&id=312&id=313&id=314&id=315&id=316&id=317&id=318&id=319&id=320&id=321&id=322&id=323&id=324&id=325&id=326&id=327&id=328&id=329&id=330&id=331&id=332&id=333&id=334&id=335&id=336&id=337&id=338&id=339&id=340&id=341&id=342&id=343&id=344&id=345&id=346&id=347&id=348&id=349&id=350", - "headers": { - "Authorization": "Bearer access_token_success", - "Content-Type": "application/json" - }, - "params": {}, - "body": { - "JSON": {}, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "files": {} - } - ], - "metadata": [ - { - "jobId": 2 - } - ], - "batched": false, - "statusCode": 200, - "destination": { - "ID": "1zia9wKshXt80YksLmUdJnr7IHI", - "Name": "test_marketo", - "DestinationDefinition": { - "ID": "1iVQvTRMsPPyJzwol0ifH93QTQ6", - "Name": "MARKETO", - "DisplayName": "Marketo", - "transformAt": "processor", - "transformAtV1": "processor" - }, - "Config": { - "clientId": "marketo_client_id_success", - "clientSecret": "marketo_client_secret_success", - "accountId": "marketo_acct_id_success", - "staticListId": 1234 - }, - "Enabled": true, - "Transformations": [], - "IsProcessorEnabled": true - } - }, - { - "metadata": [ - { - "jobId": 3 - } - ], - "destination": { - "ID": "1zia9wKshXt80YksLmUdJnr7IHI", - "Name": "test_marketo", - "DestinationDefinition": { - "ID": "1iVQvTRMsPPyJzwol0ifH93QTQ6", - "Name": "MARKETO", - "DisplayName": "Marketo", - "transformAt": "processor", - "transformAtV1": "processor" - }, - "Config": { - "clientId": "marketo_client_id_success", - "clientSecret": "marketo_client_secret_success", - "accountId": "marketo_acct_id_success", - "staticListId": 1234 - }, - "Enabled": true, - "Transformations": [], - "IsProcessorEnabled": true - }, - "batched": false, - "statusCode": 400, - "error": "Event type track is not supported", - "statTags": { - "errorCategory": "dataValidation", - "errorType": "instrumentation" - } - } -] diff --git a/test/__tests__/marketo_static_list.test.js b/test/__tests__/marketo_static_list.test.js deleted file mode 100644 index 43300f243a..0000000000 --- a/test/__tests__/marketo_static_list.test.js +++ /dev/null @@ -1,64 +0,0 @@ -const integration = "marketo_static_list"; -const name = "marketo_static_list"; -const version = "v0"; - -const fs = require("fs"); -const path = require("path"); - -const transformer = require(`../../src/${version}/destinations/${integration}/transform`); - -// Processor Test Data -const testDataFile = fs.readFileSync( - path.resolve(__dirname, `./data/${integration}.json`) -); -const testData = JSON.parse(testDataFile); - -// Router Test Data -const inputRouterDataFile = fs.readFileSync( - path.resolve(__dirname, `./data/${integration}_router_input.json`) -); -const outputRouterDataFile = fs.readFileSync( - path.resolve(__dirname, `./data/${integration}_router_output.json`) -); -const inputRouterData = JSON.parse(inputRouterDataFile); -const expectedRouterData = JSON.parse(outputRouterDataFile); - -// Router Metadata Test files -const inputRouterMetadataFile = fs.readFileSync( - path.resolve(__dirname, `./data/${integration}_router_metadata_input.json`) -); -const outputRouterMetadataFile = fs.readFileSync( - path.resolve(__dirname, `./data/${integration}_router_metadata_output.json`) -); -const inputRouterMetadata = JSON.parse(inputRouterMetadataFile); -const expectedRouterMetadata = JSON.parse(outputRouterMetadataFile); - -describe(`${name} Tests`, () => { - describe("Processor", () => { - testData.forEach((dataPoint, index) => { - it(`${index}. ${integration} - ${dataPoint.description}`, async () => { - try { - const output = await transformer.process(dataPoint.input); - expect(output).toEqual(dataPoint.output); - } catch (error) { - expect(error.message).toEqual(dataPoint.output.error); - } - }); - }); - }); - - describe("Router Tests", () => { - it("Payload", async () => { - const routerOutput = await transformer.processRouterDest(inputRouterData); - expect(routerOutput).toEqual(expectedRouterData); - }); - }); - describe("Router Metadata Tests", () => { - it("Payload", async () => { - const routerMetadataOutput = await transformer.processMetadataForRouter( - inputRouterMetadata - ); - expect(routerMetadataOutput).toEqual(expectedRouterMetadata); - }); - }); -}); diff --git a/test/integrations/destinations/marketo_static_list/processor/data.ts b/test/integrations/destinations/marketo_static_list/processor/data.ts index 51e4e87824..05fba54f6a 100644 --- a/test/integrations/destinations/marketo_static_list/processor/data.ts +++ b/test/integrations/destinations/marketo_static_list/processor/data.ts @@ -62,9 +62,9 @@ export const data = [ output: { version: '1', type: 'REST', - method: 'POST', + method: 'DELETE', endpoint: - 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=1&id=2&id=3', + 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=4&id=5&id=6', headers: { Authorization: 'Bearer access_token_success', 'Content-Type': 'application/json', @@ -80,9 +80,9 @@ export const data = [ output: { version: '1', type: 'REST', - method: 'DELETE', + method: 'POST', endpoint: - 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=4&id=5&id=6', + 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=1&id=2&id=3', headers: { Authorization: 'Bearer access_token_success', 'Content-Type': 'application/json', diff --git a/test/integrations/destinations/marketo_static_list/router/data.ts b/test/integrations/destinations/marketo_static_list/router/data.ts index 23b2ea8ea3..fa97ba49f2 100644 --- a/test/integrations/destinations/marketo_static_list/router/data.ts +++ b/test/integrations/destinations/marketo_static_list/router/data.ts @@ -1,7 +1,7 @@ export const data = [ { name: 'marketo_static_list', - description: 'Test 0', + description: 'Test 0: Test audiencelist event with add and remove', feature: 'router', module: 'destination', version: 'v0', @@ -1172,50 +1172,6 @@ export const data = [ jobId: 2, }, }, - { - destination: { - ID: '1zia9wKshXt80YksLmUdJnr7IHI', - Name: 'test_marketo', - DestinationDefinition: { - ID: '1iVQvTRMsPPyJzwol0ifH93QTQ6', - Name: 'MARKETO', - DisplayName: 'Marketo', - transformAt: 'processor', - transformAtV1: 'processor', - }, - Config: { - clientId: 'marketo_client_id_success', - clientSecret: 'marketo_client_secret_success', - accountId: 'marketo_acct_id_success', - staticListId: 1234, - }, - Enabled: true, - Transformations: [], - IsProcessorEnabled: true, - }, - message: { - userId: 'user 1', - anonymousId: 'anon-id-new', - event: 'event1', - type: 'track', - properties: { - listData: { - remove: [1], - }, - enablePartialFailure: true, - }, - context: { - ip: '14.5.67.21', - library: { - name: 'http', - }, - }, - timestamp: '2020-02-02T00:23:09.544Z', - }, - metadata: { - jobId: 3, - }, - }, ], destType: 'marketo_static_list', }, @@ -1232,9 +1188,9 @@ export const data = [ { version: '1', type: 'REST', - method: 'POST', + method: 'DELETE', endpoint: - 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=1&id=2&id=3', + 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=4&id=5&id=6', headers: { Authorization: 'Bearer access_token_success', 'Content-Type': 'application/json', @@ -1251,9 +1207,9 @@ export const data = [ { version: '1', type: 'REST', - method: 'DELETE', + method: 'POST', endpoint: - 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=4&id=5&id=6', + 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=1&id=2&id=3', headers: { Authorization: 'Bearer access_token_success', 'Content-Type': 'application/json', @@ -1371,18 +1327,325 @@ export const data = [ IsProcessorEnabled: true, }, }, + ], + }, + }, + }, + }, + { + name: 'marketo_static_list', + description: 'Test 1: Test record and audiencelist events in a single batch', + feature: 'router', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + input: [ + { + destination: { + ID: '1zwa1wKshSt81YksKmUdJnr4IOK', + Name: 'test_marketo_rc', + DestinationDefinition: { + ID: '1iVQvTRMsPPyJzwol0ifH93QTQ6', + Name: 'MARKETO', + DisplayName: 'Marketo', + transformAt: 'processor', + transformAtV1: 'processor', + }, + Config: { + clientId: 'marketo_client_id_success', + clientSecret: 'marketo_client_secret_success', + accountId: 'marketo_acct_id_success', + staticListId: 1122, + }, + Enabled: true, + Transformations: [], + IsProcessorEnabled: true, + }, + message: { + type: 'record', + action: 'insert', + fields: { + id: 1001, + }, + channel: 'sources', + context: { + sources: { + job_id: '2VsZs4hyPpq7f1p8igrpmHsibHl', + version: 'feat.mirrorRetlEvent', + job_run_id: 'ck99nbd2kqiljdihhkh0', + task_run_id: 'ck99nbd2kqiljdihhkhg', + }, + externalId: [ + { + type: 'marketoStaticListId', + identifierType: 'id', + }, + ], + destinationFields: 'id', + mappedToDestination: 'true', + }, + recordId: '3', + }, + metadata: { + jobId: 1, + }, + }, { - metadata: [ - { - destInfo: { - authKey: '1zia9wKshXt80YksLmUdJnr7IHI', + destination: { + ID: '1zwa1wKshSt81YksKmUdJnr4IOK', + Name: 'test_marketo_rc', + DestinationDefinition: { + ID: '1iVQvTRMsPPyJzwol0ifH93QTQ6', + Name: 'MARKETO', + DisplayName: 'Marketo', + transformAt: 'processor', + transformAtV1: 'processor', + }, + Config: { + clientId: 'marketo_client_id_success', + clientSecret: 'marketo_client_secret_success', + accountId: 'marketo_acct_id_success', + staticListId: 1122, + }, + Enabled: true, + Transformations: [], + IsProcessorEnabled: true, + }, + message: { + type: 'record', + action: 'insert', + fields: { + id: 1002, + }, + channel: 'sources', + context: { + sources: { + job_id: '2VsZs4hyPpq7f1p8igrpmHsibHl', + version: 'feat.mirrorRetlEvent', + job_run_id: 'ck99nbd2kqiljdihhkh0', + task_run_id: 'ck99nbd2kqiljdihhkhg', }, - jobId: 3, + externalId: [ + { + type: 'marketoStaticListId', + identifierType: 'id', + }, + ], + destinationFields: 'id', + mappedToDestination: 'true', }, - ], + recordId: '3', + }, + metadata: { + jobId: 2, + }, + }, + { + destination: { + ID: '1zwa1wKshSt81YksKmUdJnr4IOK', + Name: 'test_marketo_rc', + DestinationDefinition: { + ID: '1iVQvTRMsPPyJzwol0ifH93QTQ6', + Name: 'MARKETO', + DisplayName: 'Marketo', + transformAt: 'processor', + transformAtV1: 'processor', + }, + Config: { + clientId: 'marketo_client_id_success', + clientSecret: 'marketo_client_secret_success', + accountId: 'marketo_acct_id_success', + staticListId: 1122, + }, + Enabled: true, + Transformations: [], + IsProcessorEnabled: true, + }, + message: { + type: 'record', + action: 'insert', + fields: { + id: 1003, + }, + channel: 'sources', + context: { + sources: { + job_id: '2VsZs4hyPpq7f1p8igrpmHsibHl', + version: 'feat.mirrorRetlEvent', + job_run_id: 'ck99nbd2kqiljdihhkh0', + task_run_id: 'ck99nbd2kqiljdihhkhg', + }, + externalId: [ + { + type: 'marketoStaticListId', + identifierType: 'id', + }, + ], + destinationFields: 'id', + mappedToDestination: 'true', + }, + recordId: '3', + }, + metadata: { + jobId: 3, + }, + }, + { + destination: { + ID: '1zwa1wKshSt81YksKmUdJnr4IOK', + Name: 'test_marketo_rc', + DestinationDefinition: { + ID: '1iVQvTRMsPPyJzwol0ifH93QTQ6', + Name: 'MARKETO', + DisplayName: 'Marketo', + transformAt: 'processor', + transformAtV1: 'processor', + }, + Config: { + clientId: 'marketo_client_id_success', + clientSecret: 'marketo_client_secret_success', + accountId: 'marketo_acct_id_success', + staticListId: 1122, + }, + Enabled: true, + Transformations: [], + IsProcessorEnabled: true, + }, + message: { + action: 'delete', + context: { + destinationFields: 'id', + externalId: [ + { + identifierType: 'id', + type: 'marketoStaticListId', + }, + ], + mappedToDestination: 'true', + sources: { + job_id: 'sf', + job_run_id: 'ck985bve58cvnti48120', + task_run_id: 'ck985bve58cvnti4812g', + version: '', + }, + }, + recordId: '2', + rudderId: '2', + fields: { + id: '2001', + }, + type: 'record', + }, + metadata: { + jobId: 4, + }, + }, + { + destination: { + ID: '1zwa1wKshSt81YksKmUdJnr4IOK', + Name: 'test_marketo_rc', + DestinationDefinition: { + ID: '1iVQvTRMsPPyJzwol0ifH93QTQ6', + Name: 'MARKETO', + DisplayName: 'Marketo', + transformAt: 'processor', + transformAtV1: 'processor', + }, + Config: { + clientId: 'marketo_client_id_success', + clientSecret: 'marketo_client_secret_success', + accountId: 'marketo_acct_id_success', + staticListId: 1122, + }, + Enabled: true, + Transformations: [], + IsProcessorEnabled: true, + }, + message: { + action: 'delete', + context: { + destinationFields: 'id', + externalId: [ + { + identifierType: 'id', + type: 'marketoStaticListId', + }, + ], + mappedToDestination: 'true', + sources: { + job_id: 'sf', + job_run_id: 'ck985bve58cvnti48120', + task_run_id: 'ck985bve58cvnti4812g', + version: '', + }, + }, + recordId: '2', + rudderId: '2', + fields: { + id: '2002', + }, + type: 'record', + }, + metadata: { + jobId: 5, + }, + }, + { + destination: { + ID: '1zwa1wKshSt81YksKmUdJnr4IOK', + Name: 'test_marketo_rc', + DestinationDefinition: { + ID: '1iVQvTRMsPPyJzwol0ifH93QTQ6', + Name: 'MARKETO', + DisplayName: 'Marketo', + transformAt: 'processor', + transformAtV1: 'processor', + }, + Config: { + clientId: 'marketo_client_id_success', + clientSecret: 'marketo_client_secret_success', + accountId: 'marketo_acct_id_success', + staticListId: 1122, + }, + Enabled: true, + Transformations: [], + IsProcessorEnabled: true, + }, + message: { + action: 'delete', + context: { + destinationFields: 'id', + externalId: [ + { + identifierType: 'id', + type: 'marketoStaticListId', + }, + ], + mappedToDestination: 'true', + sources: { + job_id: 'sf', + job_run_id: 'ck985bve58cvnti48120', + task_run_id: 'ck985bve58cvnti4812g', + version: '', + }, + }, + recordId: '2', + rudderId: '2', + fields: { + id: '2003', + }, + type: 'record', + }, + metadata: { + jobId: 6, + }, + }, + { destination: { ID: '1zia9wKshXt80YksLmUdJnr7IHI', - Name: 'test_marketo', + Name: 'test_marketo_al', DestinationDefinition: { ID: '1iVQvTRMsPPyJzwol0ifH93QTQ6', Name: 'MARKETO', @@ -1400,12 +1663,1981 @@ export const data = [ Transformations: [], IsProcessorEnabled: true, }, - batched: false, - statusCode: 400, - error: 'Event type track is not supported', - statTags: { - errorCategory: 'dataValidation', - errorType: 'instrumentation', + message: { + userId: 'user 1', + anonymousId: 'anon-id-new', + event: 'event1', + type: 'audiencelist', + properties: { + listData: { + add: [ + { + id: 101, + }, + { + id: 102, + }, + { + id: 103, + }, + ], + remove: [ + { + id: 4, + }, + { + id: 5, + }, + { + id: 6, + }, + ], + }, + enablePartialFailure: true, + }, + context: { + ip: '14.5.67.21', + library: { + name: 'http', + }, + }, + timestamp: '2020-02-02T00:23:09.544Z', + }, + metadata: { + jobId: 7, + }, + }, + { + destination: { + ID: '1zia9wKshXt80YksLmUdJnr7IHI', + Name: 'test_marketo_al', + DestinationDefinition: { + ID: '1iVQvTRMsPPyJzwol0ifH93QTQ6', + Name: 'MARKETO', + DisplayName: 'Marketo', + transformAt: 'processor', + transformAtV1: 'processor', + }, + Config: { + clientId: 'marketo_client_id_success', + clientSecret: 'marketo_client_secret_success', + accountId: 'marketo_acct_id_success', + staticListId: 1234, + }, + Enabled: true, + Transformations: [], + IsProcessorEnabled: true, + }, + message: { + userId: 'user 1', + anonymousId: 'anon-id-new', + event: 'event1', + type: 'audiencelist', + properties: { + listData: { + add: [ + { + id: 0, + }, + { + id: 1, + }, + { + id: 2, + }, + { + id: 3, + }, + { + id: 4, + }, + { + id: 5, + }, + { + id: 6, + }, + { + id: 7, + }, + { + id: 8, + }, + { + id: 9, + }, + { + id: 10, + }, + { + id: 11, + }, + { + id: 12, + }, + { + id: 13, + }, + { + id: 14, + }, + { + id: 15, + }, + { + id: 16, + }, + { + id: 17, + }, + { + id: 18, + }, + { + id: 19, + }, + { + id: 20, + }, + { + id: 21, + }, + { + id: 22, + }, + { + id: 23, + }, + { + id: 24, + }, + { + id: 25, + }, + { + id: 26, + }, + { + id: 27, + }, + { + id: 28, + }, + { + id: 29, + }, + { + id: 30, + }, + { + id: 31, + }, + { + id: 32, + }, + { + id: 33, + }, + { + id: 34, + }, + { + id: 35, + }, + { + id: 36, + }, + { + id: 37, + }, + { + id: 38, + }, + { + id: 39, + }, + { + id: 40, + }, + { + id: 41, + }, + { + id: 42, + }, + { + id: 43, + }, + { + id: 44, + }, + { + id: 45, + }, + { + id: 46, + }, + { + id: 47, + }, + { + id: 48, + }, + { + id: 49, + }, + { + id: 50, + }, + { + id: 51, + }, + { + id: 52, + }, + { + id: 53, + }, + { + id: 54, + }, + { + id: 55, + }, + { + id: 56, + }, + { + id: 57, + }, + { + id: 58, + }, + { + id: 59, + }, + { + id: 60, + }, + { + id: 61, + }, + { + id: 62, + }, + { + id: 63, + }, + { + id: 64, + }, + { + id: 65, + }, + { + id: 66, + }, + { + id: 67, + }, + { + id: 68, + }, + { + id: 69, + }, + { + id: 70, + }, + { + id: 71, + }, + { + id: 72, + }, + { + id: 73, + }, + { + id: 74, + }, + { + id: 75, + }, + { + id: 76, + }, + { + id: 77, + }, + { + id: 78, + }, + { + id: 79, + }, + { + id: 80, + }, + { + id: 81, + }, + { + id: 82, + }, + { + id: 83, + }, + { + id: 84, + }, + { + id: 85, + }, + { + id: 86, + }, + { + id: 87, + }, + { + id: 88, + }, + { + id: 89, + }, + { + id: 90, + }, + { + id: 91, + }, + { + id: 92, + }, + { + id: 93, + }, + { + id: 94, + }, + { + id: 95, + }, + { + id: 96, + }, + { + id: 97, + }, + { + id: 98, + }, + { + id: 99, + }, + { + id: 100, + }, + { + id: 101, + }, + { + id: 102, + }, + { + id: 103, + }, + { + id: 104, + }, + { + id: 105, + }, + { + id: 106, + }, + { + id: 107, + }, + { + id: 108, + }, + { + id: 109, + }, + { + id: 110, + }, + { + id: 111, + }, + { + id: 112, + }, + { + id: 113, + }, + { + id: 114, + }, + { + id: 115, + }, + { + id: 116, + }, + { + id: 117, + }, + { + id: 118, + }, + { + id: 119, + }, + { + id: 120, + }, + { + id: 121, + }, + { + id: 122, + }, + { + id: 123, + }, + { + id: 124, + }, + { + id: 125, + }, + { + id: 126, + }, + { + id: 127, + }, + { + id: 128, + }, + { + id: 129, + }, + { + id: 130, + }, + { + id: 131, + }, + { + id: 132, + }, + { + id: 133, + }, + { + id: 134, + }, + { + id: 135, + }, + { + id: 136, + }, + { + id: 137, + }, + { + id: 138, + }, + { + id: 139, + }, + { + id: 140, + }, + { + id: 141, + }, + { + id: 142, + }, + { + id: 143, + }, + { + id: 144, + }, + { + id: 145, + }, + { + id: 146, + }, + { + id: 147, + }, + { + id: 148, + }, + { + id: 149, + }, + { + id: 150, + }, + { + id: 151, + }, + { + id: 152, + }, + { + id: 153, + }, + { + id: 154, + }, + { + id: 155, + }, + { + id: 156, + }, + { + id: 157, + }, + { + id: 158, + }, + { + id: 159, + }, + { + id: 160, + }, + { + id: 161, + }, + { + id: 162, + }, + { + id: 163, + }, + { + id: 164, + }, + { + id: 165, + }, + { + id: 166, + }, + { + id: 167, + }, + { + id: 168, + }, + { + id: 169, + }, + { + id: 170, + }, + { + id: 171, + }, + { + id: 172, + }, + { + id: 173, + }, + { + id: 174, + }, + { + id: 175, + }, + { + id: 176, + }, + { + id: 177, + }, + { + id: 178, + }, + { + id: 179, + }, + { + id: 180, + }, + { + id: 181, + }, + { + id: 182, + }, + { + id: 183, + }, + { + id: 184, + }, + { + id: 185, + }, + { + id: 186, + }, + { + id: 187, + }, + { + id: 188, + }, + { + id: 189, + }, + { + id: 190, + }, + { + id: 191, + }, + { + id: 192, + }, + { + id: 193, + }, + { + id: 194, + }, + { + id: 195, + }, + { + id: 196, + }, + { + id: 197, + }, + { + id: 198, + }, + { + id: 199, + }, + { + id: 200, + }, + { + id: 201, + }, + { + id: 202, + }, + { + id: 203, + }, + { + id: 204, + }, + { + id: 205, + }, + { + id: 206, + }, + { + id: 207, + }, + { + id: 208, + }, + { + id: 209, + }, + { + id: 210, + }, + { + id: 211, + }, + { + id: 212, + }, + { + id: 213, + }, + { + id: 214, + }, + { + id: 215, + }, + { + id: 216, + }, + { + id: 217, + }, + { + id: 218, + }, + { + id: 219, + }, + { + id: 220, + }, + { + id: 221, + }, + { + id: 222, + }, + { + id: 223, + }, + { + id: 224, + }, + { + id: 225, + }, + { + id: 226, + }, + { + id: 227, + }, + { + id: 228, + }, + { + id: 229, + }, + { + id: 230, + }, + { + id: 231, + }, + { + id: 232, + }, + { + id: 233, + }, + { + id: 234, + }, + { + id: 235, + }, + { + id: 236, + }, + { + id: 237, + }, + { + id: 238, + }, + { + id: 239, + }, + { + id: 240, + }, + { + id: 241, + }, + { + id: 242, + }, + { + id: 243, + }, + { + id: 244, + }, + { + id: 245, + }, + { + id: 246, + }, + { + id: 247, + }, + { + id: 248, + }, + { + id: 249, + }, + { + id: 250, + }, + { + id: 251, + }, + { + id: 252, + }, + { + id: 253, + }, + { + id: 254, + }, + { + id: 255, + }, + { + id: 256, + }, + { + id: 257, + }, + { + id: 258, + }, + { + id: 259, + }, + { + id: 260, + }, + { + id: 261, + }, + { + id: 262, + }, + { + id: 263, + }, + { + id: 264, + }, + { + id: 265, + }, + { + id: 266, + }, + { + id: 267, + }, + { + id: 268, + }, + { + id: 269, + }, + { + id: 270, + }, + { + id: 271, + }, + { + id: 272, + }, + { + id: 273, + }, + { + id: 274, + }, + { + id: 275, + }, + { + id: 276, + }, + { + id: 277, + }, + { + id: 278, + }, + { + id: 279, + }, + { + id: 280, + }, + { + id: 281, + }, + { + id: 282, + }, + { + id: 283, + }, + { + id: 284, + }, + { + id: 285, + }, + { + id: 286, + }, + { + id: 287, + }, + { + id: 288, + }, + { + id: 289, + }, + { + id: 290, + }, + { + id: 291, + }, + { + id: 292, + }, + { + id: 293, + }, + { + id: 294, + }, + { + id: 295, + }, + { + id: 296, + }, + { + id: 297, + }, + { + id: 298, + }, + { + id: 299, + }, + { + id: 300, + }, + { + id: 301, + }, + { + id: 302, + }, + { + id: 303, + }, + { + id: 304, + }, + { + id: 305, + }, + { + id: 306, + }, + { + id: 307, + }, + { + id: 308, + }, + { + id: 309, + }, + { + id: 310, + }, + { + id: 311, + }, + { + id: 312, + }, + { + id: 313, + }, + { + id: 314, + }, + { + id: 315, + }, + { + id: 316, + }, + { + id: 317, + }, + { + id: 318, + }, + { + id: 319, + }, + { + id: 320, + }, + { + id: 321, + }, + { + id: 322, + }, + { + id: 323, + }, + { + id: 324, + }, + { + id: 325, + }, + { + id: 326, + }, + { + id: 327, + }, + { + id: 328, + }, + { + id: 329, + }, + { + id: 330, + }, + { + id: 331, + }, + { + id: 332, + }, + { + id: 333, + }, + { + id: 334, + }, + { + id: 335, + }, + { + id: 336, + }, + { + id: 337, + }, + { + id: 338, + }, + { + id: 339, + }, + { + id: 340, + }, + { + id: 341, + }, + { + id: 342, + }, + { + id: 343, + }, + { + id: 344, + }, + { + id: 345, + }, + { + id: 346, + }, + { + id: 347, + }, + { + id: 348, + }, + { + id: 349, + }, + { + id: 350, + }, + ], + }, + enablePartialFailure: true, + }, + context: { + ip: '14.5.67.21', + library: { + name: 'http', + }, + }, + timestamp: '2020-02-02T00:23:09.544Z', + }, + metadata: { + jobId: 8, + }, + }, + ], + destType: 'marketo_static_list', + }, + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: [ + { + batchedRequest: [ + { + version: '1', + type: 'REST', + method: 'DELETE', + endpoint: + 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1122/leads.json?id=2001&id=2002&id=2003', + headers: { + Authorization: 'Bearer access_token_success', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + }, + ], + metadata: [ + { + jobId: 4, + destInfo: { + authKey: '1zwa1wKshSt81YksKmUdJnr4IOK', + }, + }, + { + jobId: 5, + destInfo: { + authKey: '1zwa1wKshSt81YksKmUdJnr4IOK', + }, + }, + { + jobId: 6, + destInfo: { + authKey: '1zwa1wKshSt81YksKmUdJnr4IOK', + }, + }, + ], + batched: true, + statusCode: 200, + destination: { + ID: '1zwa1wKshSt81YksKmUdJnr4IOK', + Name: 'test_marketo_rc', + DestinationDefinition: { + ID: '1iVQvTRMsPPyJzwol0ifH93QTQ6', + Name: 'MARKETO', + DisplayName: 'Marketo', + transformAt: 'processor', + transformAtV1: 'processor', + }, + Config: { + clientId: 'marketo_client_id_success', + clientSecret: 'marketo_client_secret_success', + accountId: 'marketo_acct_id_success', + staticListId: 1122, + }, + Enabled: true, + Transformations: [], + IsProcessorEnabled: true, + }, + }, + { + batchedRequest: [ + { + version: '1', + type: 'REST', + method: 'POST', + endpoint: + 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1122/leads.json?id=1001&id=1002&id=1003', + headers: { + Authorization: 'Bearer access_token_success', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + }, + ], + metadata: [ + { + jobId: 1, + destInfo: { + authKey: '1zwa1wKshSt81YksKmUdJnr4IOK', + }, + }, + { + jobId: 2, + destInfo: { + authKey: '1zwa1wKshSt81YksKmUdJnr4IOK', + }, + }, + { + jobId: 3, + destInfo: { + authKey: '1zwa1wKshSt81YksKmUdJnr4IOK', + }, + }, + ], + batched: true, + statusCode: 200, + destination: { + ID: '1zwa1wKshSt81YksKmUdJnr4IOK', + Name: 'test_marketo_rc', + DestinationDefinition: { + ID: '1iVQvTRMsPPyJzwol0ifH93QTQ6', + Name: 'MARKETO', + DisplayName: 'Marketo', + transformAt: 'processor', + transformAtV1: 'processor', + }, + Config: { + clientId: 'marketo_client_id_success', + clientSecret: 'marketo_client_secret_success', + accountId: 'marketo_acct_id_success', + staticListId: 1122, + }, + Enabled: true, + Transformations: [], + IsProcessorEnabled: true, + }, + }, + { + batchedRequest: [ + { + version: '1', + type: 'REST', + method: 'DELETE', + endpoint: + 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=4&id=5&id=6', + headers: { + Authorization: 'Bearer access_token_success', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + }, + { + version: '1', + type: 'REST', + method: 'POST', + endpoint: + 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=101&id=102&id=103', + headers: { + Authorization: 'Bearer access_token_success', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + }, + ], + metadata: [ + { + jobId: 7, + destInfo: { + authKey: '1zia9wKshXt80YksLmUdJnr7IHI', + }, + }, + ], + batched: false, + statusCode: 200, + destination: { + ID: '1zia9wKshXt80YksLmUdJnr7IHI', + Name: 'test_marketo_al', + DestinationDefinition: { + ID: '1iVQvTRMsPPyJzwol0ifH93QTQ6', + Name: 'MARKETO', + DisplayName: 'Marketo', + transformAt: 'processor', + transformAtV1: 'processor', + }, + Config: { + clientId: 'marketo_client_id_success', + clientSecret: 'marketo_client_secret_success', + accountId: 'marketo_acct_id_success', + staticListId: 1234, + }, + Enabled: true, + Transformations: [], + IsProcessorEnabled: true, + }, + }, + { + batchedRequest: [ + { + version: '1', + type: 'REST', + method: 'POST', + endpoint: + 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=0&id=1&id=2&id=3&id=4&id=5&id=6&id=7&id=8&id=9&id=10&id=11&id=12&id=13&id=14&id=15&id=16&id=17&id=18&id=19&id=20&id=21&id=22&id=23&id=24&id=25&id=26&id=27&id=28&id=29&id=30&id=31&id=32&id=33&id=34&id=35&id=36&id=37&id=38&id=39&id=40&id=41&id=42&id=43&id=44&id=45&id=46&id=47&id=48&id=49&id=50&id=51&id=52&id=53&id=54&id=55&id=56&id=57&id=58&id=59&id=60&id=61&id=62&id=63&id=64&id=65&id=66&id=67&id=68&id=69&id=70&id=71&id=72&id=73&id=74&id=75&id=76&id=77&id=78&id=79&id=80&id=81&id=82&id=83&id=84&id=85&id=86&id=87&id=88&id=89&id=90&id=91&id=92&id=93&id=94&id=95&id=96&id=97&id=98&id=99&id=100&id=101&id=102&id=103&id=104&id=105&id=106&id=107&id=108&id=109&id=110&id=111&id=112&id=113&id=114&id=115&id=116&id=117&id=118&id=119&id=120&id=121&id=122&id=123&id=124&id=125&id=126&id=127&id=128&id=129&id=130&id=131&id=132&id=133&id=134&id=135&id=136&id=137&id=138&id=139&id=140&id=141&id=142&id=143&id=144&id=145&id=146&id=147&id=148&id=149&id=150&id=151&id=152&id=153&id=154&id=155&id=156&id=157&id=158&id=159&id=160&id=161&id=162&id=163&id=164&id=165&id=166&id=167&id=168&id=169&id=170&id=171&id=172&id=173&id=174&id=175&id=176&id=177&id=178&id=179&id=180&id=181&id=182&id=183&id=184&id=185&id=186&id=187&id=188&id=189&id=190&id=191&id=192&id=193&id=194&id=195&id=196&id=197&id=198&id=199&id=200&id=201&id=202&id=203&id=204&id=205&id=206&id=207&id=208&id=209&id=210&id=211&id=212&id=213&id=214&id=215&id=216&id=217&id=218&id=219&id=220&id=221&id=222&id=223&id=224&id=225&id=226&id=227&id=228&id=229&id=230&id=231&id=232&id=233&id=234&id=235&id=236&id=237&id=238&id=239&id=240&id=241&id=242&id=243&id=244&id=245&id=246&id=247&id=248&id=249&id=250&id=251&id=252&id=253&id=254&id=255&id=256&id=257&id=258&id=259&id=260&id=261&id=262&id=263&id=264&id=265&id=266&id=267&id=268&id=269&id=270&id=271&id=272&id=273&id=274&id=275&id=276&id=277&id=278&id=279&id=280&id=281&id=282&id=283&id=284&id=285&id=286&id=287&id=288&id=289&id=290&id=291&id=292&id=293&id=294&id=295&id=296&id=297&id=298&id=299', + headers: { + Authorization: 'Bearer access_token_success', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + }, + { + version: '1', + type: 'REST', + method: 'POST', + endpoint: + 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/1234/leads.json?id=300&id=301&id=302&id=303&id=304&id=305&id=306&id=307&id=308&id=309&id=310&id=311&id=312&id=313&id=314&id=315&id=316&id=317&id=318&id=319&id=320&id=321&id=322&id=323&id=324&id=325&id=326&id=327&id=328&id=329&id=330&id=331&id=332&id=333&id=334&id=335&id=336&id=337&id=338&id=339&id=340&id=341&id=342&id=343&id=344&id=345&id=346&id=347&id=348&id=349&id=350', + headers: { + Authorization: 'Bearer access_token_success', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + }, + ], + metadata: [ + { + jobId: 8, + destInfo: { + authKey: '1zia9wKshXt80YksLmUdJnr7IHI', + }, + }, + ], + batched: false, + statusCode: 200, + destination: { + ID: '1zia9wKshXt80YksLmUdJnr7IHI', + Name: 'test_marketo_al', + DestinationDefinition: { + ID: '1iVQvTRMsPPyJzwol0ifH93QTQ6', + Name: 'MARKETO', + DisplayName: 'Marketo', + transformAt: 'processor', + transformAtV1: 'processor', + }, + Config: { + clientId: 'marketo_client_id_success', + clientSecret: 'marketo_client_secret_success', + accountId: 'marketo_acct_id_success', + staticListId: 1234, + }, + Enabled: true, + Transformations: [], + IsProcessorEnabled: true, + }, + }, + ], + }, + }, + }, + }, + { + name: 'marketo_static_list', + description: 'Test 2: Test record evemts', + feature: 'router', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + destType: 'marketo_static_list', + input: [ + { + destination: { + ID: '1zwa1wKshSt81YksKmUdJnr4IOK', + Name: 'test_marketo_rc', + DestinationDefinition: { + ID: '1iVQvTRMsPPyJzwol0ifH93QTQ6', + Name: 'MARKETO', + DisplayName: 'Marketo', + transformAt: 'processor', + transformAtV1: 'processor', + }, + Config: { + clientId: 'marketo_client_id_success', + clientSecret: 'marketo_client_secret_success', + accountId: 'marketo_acct_id_success', + staticListId: 1122, + }, + Enabled: true, + Transformations: [], + IsProcessorEnabled: true, + }, + message: { + type: 'record', + action: 'insert', + fields: { + id: 1001, + }, + channel: 'sources', + context: { + sources: { + job_id: '2VsZs4hyPpq7f1p8igrpmHsibHl', + version: 'feat.mirrorRetlEvent', + job_run_id: 'ck99nbd2kqiljdihhkh0', + task_run_id: 'ck99nbd2kqiljdihhkhg', + }, + externalId: [ + { + type: 'marketoStaticListId', + id: 'id001', + }, + ], + destinationFields: 'id', + mappedToDestination: 'true', + }, + recordId: '3', + }, + metadata: { + jobId: 1, + }, + }, + { + destination: { + ID: '1zwa1wKshSt81YksKmUdJnr4IOK', + Name: 'test_marketo_rc', + DestinationDefinition: { + ID: '1iVQvTRMsPPyJzwol0ifH93QTQ6', + Name: 'MARKETO', + DisplayName: 'Marketo', + transformAt: 'processor', + transformAtV1: 'processor', + }, + Config: { + clientId: 'marketo_client_id_success', + clientSecret: 'marketo_client_secret_success', + accountId: 'marketo_acct_id_success', + staticListId: 1122, + }, + Enabled: true, + Transformations: [], + IsProcessorEnabled: true, + }, + message: { + type: 'record', + action: 'insert', + fields: { + id: 1002, + }, + channel: 'sources', + context: { + sources: { + job_id: '2VsZs4hyPpq7f1p8igrpmHsibHl', + version: 'feat.mirrorRetlEvent', + job_run_id: 'ck99nbd2kqiljdihhkh0', + task_run_id: 'ck99nbd2kqiljdihhkhg', + }, + externalId: [ + { + type: 'marketoStaticListId', + id: 'id002', + }, + ], + destinationFields: 'id', + mappedToDestination: 'true', + }, + recordId: '3', + }, + metadata: { + jobId: 2, + }, + }, + { + destination: { + ID: '1zwa1wKshSt81YksKmUdJnr4IOK', + Name: 'test_marketo_rc', + DestinationDefinition: { + ID: '1iVQvTRMsPPyJzwol0ifH93QTQ6', + Name: 'MARKETO', + DisplayName: 'Marketo', + transformAt: 'processor', + transformAtV1: 'processor', + }, + Config: { + clientId: 'marketo_client_id_success', + clientSecret: 'marketo_client_secret_success', + accountId: 'marketo_acct_id_success', + staticListId: 1122, + }, + Enabled: true, + Transformations: [], + IsProcessorEnabled: true, + }, + message: { + type: 'record', + action: 'insert', + fields: { + id: 1003, + }, + channel: 'sources', + context: { + sources: { + job_id: '2VsZs4hyPpq7f1p8igrpmHsibHl', + version: 'feat.mirrorRetlEvent', + job_run_id: 'ck99nbd2kqiljdihhkh0', + task_run_id: 'ck99nbd2kqiljdihhkhg', + }, + externalId: [ + { + type: 'marketoStaticListId', + id: 'id001', + }, + ], + destinationFields: 'id', + mappedToDestination: 'true', + }, + recordId: '3', + }, + metadata: { + jobId: 3, + }, + }, + { + destination: { + ID: '1zwa1wKshSt81YksKmUdJnr4IOK', + Name: 'test_marketo_rc', + DestinationDefinition: { + ID: '1iVQvTRMsPPyJzwol0ifH93QTQ6', + Name: 'MARKETO', + DisplayName: 'Marketo', + transformAt: 'processor', + transformAtV1: 'processor', + }, + Config: { + clientId: 'marketo_client_id_success', + clientSecret: 'marketo_client_secret_success', + accountId: 'marketo_acct_id_success', + staticListId: 1122, + }, + Enabled: true, + Transformations: [], + IsProcessorEnabled: true, + }, + message: { + action: 'delete', + context: { + destinationFields: 'id', + externalId: [ + { + id: 'id002', + type: 'marketoStaticListId', + }, + ], + mappedToDestination: 'true', + sources: { + job_id: 'sf', + job_run_id: 'ck985bve58cvnti48120', + task_run_id: 'ck985bve58cvnti4812g', + version: '', + }, + }, + recordId: '2', + rudderId: '2', + fields: { + id: '2001', + }, + type: 'record', + }, + metadata: { + jobId: 4, + }, + }, + { + destination: { + ID: '1zwa1wKshSt81YksKmUdJnr4IOK', + Name: 'test_marketo_rc', + DestinationDefinition: { + ID: '1iVQvTRMsPPyJzwol0ifH93QTQ6', + Name: 'MARKETO', + DisplayName: 'Marketo', + transformAt: 'processor', + transformAtV1: 'processor', + }, + Config: { + clientId: 'marketo_client_id_success', + clientSecret: 'marketo_client_secret_success', + accountId: 'marketo_acct_id_success', + staticListId: 1122, + }, + Enabled: true, + Transformations: [], + IsProcessorEnabled: true, + }, + message: { + action: 'delete', + context: { + destinationFields: 'id', + externalId: [ + { + id: 'id001', + type: 'marketoStaticListId', + }, + ], + mappedToDestination: 'true', + sources: { + job_id: 'sf', + job_run_id: 'ck985bve58cvnti48120', + task_run_id: 'ck985bve58cvnti4812g', + version: '', + }, + }, + recordId: '2', + rudderId: '2', + fields: { + id: '2002', + }, + type: 'record', + }, + metadata: { + jobId: 5, + }, + }, + { + destination: { + ID: '1zwa1wKshSt81YksKmUdJnr4IOK', + Name: 'test_marketo_rc', + DestinationDefinition: { + ID: '1iVQvTRMsPPyJzwol0ifH93QTQ6', + Name: 'MARKETO', + DisplayName: 'Marketo', + transformAt: 'processor', + transformAtV1: 'processor', + }, + Config: { + clientId: 'marketo_client_id_success', + clientSecret: 'marketo_client_secret_success', + accountId: 'marketo_acct_id_success', + staticListId: 1122, + }, + Enabled: true, + Transformations: [], + IsProcessorEnabled: true, + }, + message: { + action: 'delete', + context: { + destinationFields: 'id', + externalId: [ + { + id: 'id002', + type: 'marketoStaticListId', + }, + ], + mappedToDestination: 'true', + sources: { + job_id: 'sf', + job_run_id: 'ck985bve58cvnti48120', + task_run_id: 'ck985bve58cvnti4812g', + version: '', + }, + }, + recordId: '2', + rudderId: '2', + fields: { + id: '2003', + }, + type: 'record', + }, + metadata: { + jobId: 6, + }, + }, + ], + }, + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: [ + { + batchedRequest: [ + { + version: '1', + type: 'REST', + method: 'DELETE', + endpoint: + 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/id001/leads.json?id=2002', + headers: { + Authorization: 'Bearer access_token_success', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + }, + ], + metadata: [ + { + jobId: 5, + destInfo: { + authKey: '1zwa1wKshSt81YksKmUdJnr4IOK', + }, + }, + ], + batched: true, + statusCode: 200, + destination: { + ID: '1zwa1wKshSt81YksKmUdJnr4IOK', + Name: 'test_marketo_rc', + DestinationDefinition: { + ID: '1iVQvTRMsPPyJzwol0ifH93QTQ6', + Name: 'MARKETO', + DisplayName: 'Marketo', + transformAt: 'processor', + transformAtV1: 'processor', + }, + Config: { + clientId: 'marketo_client_id_success', + clientSecret: 'marketo_client_secret_success', + accountId: 'marketo_acct_id_success', + staticListId: 1122, + }, + Enabled: true, + Transformations: [], + IsProcessorEnabled: true, + }, + }, + { + batchedRequest: [ + { + version: '1', + type: 'REST', + method: 'POST', + endpoint: + 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/id001/leads.json?id=1001&id=1003', + headers: { + Authorization: 'Bearer access_token_success', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + }, + ], + metadata: [ + { + jobId: 1, + destInfo: { + authKey: '1zwa1wKshSt81YksKmUdJnr4IOK', + }, + }, + { + jobId: 3, + destInfo: { + authKey: '1zwa1wKshSt81YksKmUdJnr4IOK', + }, + }, + ], + batched: true, + statusCode: 200, + destination: { + ID: '1zwa1wKshSt81YksKmUdJnr4IOK', + Name: 'test_marketo_rc', + DestinationDefinition: { + ID: '1iVQvTRMsPPyJzwol0ifH93QTQ6', + Name: 'MARKETO', + DisplayName: 'Marketo', + transformAt: 'processor', + transformAtV1: 'processor', + }, + Config: { + clientId: 'marketo_client_id_success', + clientSecret: 'marketo_client_secret_success', + accountId: 'marketo_acct_id_success', + staticListId: 1122, + }, + Enabled: true, + Transformations: [], + IsProcessorEnabled: true, + }, + }, + { + batchedRequest: [ + { + version: '1', + type: 'REST', + method: 'DELETE', + endpoint: + 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/id002/leads.json?id=2001&id=2003', + headers: { + Authorization: 'Bearer access_token_success', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + }, + ], + metadata: [ + { + jobId: 4, + destInfo: { + authKey: '1zwa1wKshSt81YksKmUdJnr4IOK', + }, + }, + { + jobId: 6, + destInfo: { + authKey: '1zwa1wKshSt81YksKmUdJnr4IOK', + }, + }, + ], + batched: true, + statusCode: 200, + destination: { + ID: '1zwa1wKshSt81YksKmUdJnr4IOK', + Name: 'test_marketo_rc', + DestinationDefinition: { + ID: '1iVQvTRMsPPyJzwol0ifH93QTQ6', + Name: 'MARKETO', + DisplayName: 'Marketo', + transformAt: 'processor', + transformAtV1: 'processor', + }, + Config: { + clientId: 'marketo_client_id_success', + clientSecret: 'marketo_client_secret_success', + accountId: 'marketo_acct_id_success', + staticListId: 1122, + }, + Enabled: true, + Transformations: [], + IsProcessorEnabled: true, + }, + }, + { + batchedRequest: [ + { + version: '1', + type: 'REST', + method: 'POST', + endpoint: + 'https://marketo_acct_id_success.mktorest.com/rest/v1/lists/id002/leads.json?id=1002', + headers: { + Authorization: 'Bearer access_token_success', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + }, + ], + metadata: [ + { + jobId: 2, + destInfo: { + authKey: '1zwa1wKshSt81YksKmUdJnr4IOK', + }, + }, + ], + batched: true, + statusCode: 200, + destination: { + ID: '1zwa1wKshSt81YksKmUdJnr4IOK', + Name: 'test_marketo_rc', + DestinationDefinition: { + ID: '1iVQvTRMsPPyJzwol0ifH93QTQ6', + Name: 'MARKETO', + DisplayName: 'Marketo', + transformAt: 'processor', + transformAtV1: 'processor', + }, + Config: { + clientId: 'marketo_client_id_success', + clientSecret: 'marketo_client_secret_success', + accountId: 'marketo_acct_id_success', + staticListId: 1122, + }, + Enabled: true, + Transformations: [], + IsProcessorEnabled: true, }, }, ], From e8f2d1a44e54f8eea50035d885c23bef7992ae2b Mon Sep 17 00:00:00 2001 From: Yashasvi Bajpai <33063622+yashasvibajpai@users.noreply.github.com> Date: Mon, 11 Dec 2023 16:36:13 +0530 Subject: [PATCH 72/93] chore: onboard Adobe Analytics to transformer proxy (#2858) * chore: init onboard * chore: add network handler * chore: add test * fix: adding correct mock with corrections & modify the status-code in test-case Signed-off-by: Sai Sankeerth * chore: add dummy destination id * chore: add dummy ws id * chore: add tests for success and generic error case --------- Signed-off-by: Sai Sankeerth Co-authored-by: Sai Sankeerth --- src/v0/destinations/adobe_analytics/config.js | 1 + .../adobe_analytics/networkHandler.js | 54 +++++++ .../adobe_analytics/dataDelivery/data.ts | 142 ++++++++++++++++++ .../destinations/adobe_analytics/network.ts | 47 ++++++ 4 files changed, 244 insertions(+) create mode 100644 src/v0/destinations/adobe_analytics/networkHandler.js create mode 100644 test/integrations/destinations/adobe_analytics/dataDelivery/data.ts create mode 100644 test/integrations/destinations/adobe_analytics/network.ts diff --git a/src/v0/destinations/adobe_analytics/config.js b/src/v0/destinations/adobe_analytics/config.js index 7a66b32a48..232fe61f7f 100644 --- a/src/v0/destinations/adobe_analytics/config.js +++ b/src/v0/destinations/adobe_analytics/config.js @@ -44,4 +44,5 @@ module.exports = { ECOM_PRODUCT_EVENTS, commonConfig: MAPPING_CONFIG[CONFIG_CATEGORIES.COMMON.name], formatDestinationConfig, + DESTINATION: 'ADOBE_ANALYTICS' }; diff --git a/src/v0/destinations/adobe_analytics/networkHandler.js b/src/v0/destinations/adobe_analytics/networkHandler.js new file mode 100644 index 0000000000..b5b58ade0c --- /dev/null +++ b/src/v0/destinations/adobe_analytics/networkHandler.js @@ -0,0 +1,54 @@ +const { InstrumentationError } = require('@rudderstack/integrations-lib'); +const { proxyRequest, prepareProxyRequest } = require('../../../adapters/network'); +const { + processAxiosResponse, +} = require('../../../adapters/utils/networkUtils'); +const { DESTINATION } = require('./config'); + + +/** + * Extract data inside different tags from an xml payload + * @param {*} xml + * @param {*} tagName + * @returns data inside the tagName + */ +function extractContent(xmlPayload, tagName) { + const pattern = new RegExp(`<${tagName}>(.*?)`); + const match = xmlPayload.match(pattern); + return match ? match[1] : null; +} + +const responseHandler = (destinationResponse, dest) => { + const message = `[${DESTINATION}] - Request Processed Successfully`; + const { response, status } = destinationResponse; + + // Extract values between different tags + const responseStatus = extractContent(response, 'status'); + const reason = extractContent(response, 'reason'); + + // if the status tag in XML contains FAILURE, we build and throw an explicit error + if (responseStatus === 'FAILURE') { + if (reason) { + throw new InstrumentationError(`[${DESTINATION} Response Handler] Request failed for destination ${dest} : ${reason}` ) + } else { + throw new InstrumentationError(`[${DESTINATION} Response Handler] Request failed for destination ${dest} with a general error`) + } + } + + return { + status, + message, + destinationResponse, + }; +}; + +function networkHandler() { + this.responseHandler = responseHandler; + this.proxy = proxyRequest; + this.prepareProxy = prepareProxyRequest; + this.processAxiosResponse = processAxiosResponse; +} + +module.exports = { + networkHandler, +}; diff --git a/test/integrations/destinations/adobe_analytics/dataDelivery/data.ts b/test/integrations/destinations/adobe_analytics/dataDelivery/data.ts new file mode 100644 index 0000000000..182969da73 --- /dev/null +++ b/test/integrations/destinations/adobe_analytics/dataDelivery/data.ts @@ -0,0 +1,142 @@ +export const data = [ + { + name: 'adobe_analytics', + description: 'Test 0: Failure response from Adobe Analytics with reason', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://adobe.failure.omtrdc.net/b/ss//6', + headers: { + 'Content-type': 'application/xml', + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: { + payload: + '17941080sales campaignwebUSD127.0.0.1en-USDalvik/2.1.0 (Linux; U; Android 9; Android SDK built for x86 Build/PSR1.180720.075)https://www.google.com/search?q=estore+bestsellerprodViewGames;;11;148.39failureReport', + }, + FORM: {}, + }, + files: {}, + }, + method: 'POST', + }, + }, + output: { + response: { + status: 400, + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'ADOBE_ANALYTICS', + module: 'destination', + implementation: 'native', + feature: 'dataDelivery', + destinationId: '2S3s0dXXXXXX7m0UfBwyblDrzs', + workspaceId: '1pKWrE6GXXXXXKBikka1SbRgrSN', + }, + destinationResponse: '', + authErrorCategory: '', + message: + '[ADOBE_ANALYTICS Response Handler] Request failed for destination adobe_analytics : NO pagename OR pageurl', + }, + }, + }, + { + name: 'adobe_analytics', + description: 'Test 1: Failure response from Adobe Analytics without reason (Generic error)', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://adobe.failure2.omtrdc.net/b/ss//6', + headers: { + 'Content-type': 'application/xml', + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: { + payload: + '17941080sales campaignwebUSD127.0.0.1en-USDalvik/2.1.0 (Linux; U; Android 9; Android SDK built for x86 Build/PSR1.180720.075)https://www.google.com/search?q=estore+bestsellerprodViewGames;;11;148.39failureReportgeneric', + }, + FORM: {}, + }, + files: {}, + }, + method: 'POST', + }, + }, + output: { + response: { + status: 400, + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'ADOBE_ANALYTICS', + module: 'destination', + implementation: 'native', + feature: 'dataDelivery', + destinationId: '2S3s0dXXXXXX7m0UfBwyblDrzs', + workspaceId: '1pKWrE6GXXXXXKBikka1SbRgrSN', + }, + destinationResponse: '', + authErrorCategory: '', + message: + '[ADOBE_ANALYTICS Response Handler] Request failed for destination adobe_analytics with a general error', + }, + }, + }, + { + name: 'adobe_analytics', + description: 'Test 2: Success response from Adobe Analytics', + feature: 'dataDelivery', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://adobe.success.omtrdc.net/b/ss//6', + headers: { + 'Content-type': 'application/xml', + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: { + payload: + '127.0.1.0www.google.co.inGoogleid1110011prodViewGames;Monopoly;1;14.00,Games;UNO;2;6.90successreport', + }, + FORM: {}, + }, + files: {}, + }, + method: 'POST', + }, + }, + output: { + response: { + status: 200, + destinationResponse: 'SUCCESS', + }, + }, + }, +]; diff --git a/test/integrations/destinations/adobe_analytics/network.ts b/test/integrations/destinations/adobe_analytics/network.ts new file mode 100644 index 0000000000..2fe4f0204e --- /dev/null +++ b/test/integrations/destinations/adobe_analytics/network.ts @@ -0,0 +1,47 @@ +export const networkCallsData = [ + { + httpReq: { + url: 'https://adobe.failure.omtrdc.net/b/ss//6', + data: '17941080sales campaignwebUSD127.0.0.1en-USDalvik/2.1.0 (Linux; U; Android 9; Android SDK built for x86 Build/PSR1.180720.075)https://www.google.com/search?q=estore+bestsellerprodViewGames;;11;148.39failureReport', + params: {}, + headers: { + 'Content-Type': 'application/xml', + }, + method: 'POST', + }, + httpRes: { + status: 200, + data: 'FAILURENO pagename OR pageurl', + }, + }, + { + httpReq: { + url: 'https://adobe.failure2.omtrdc.net/b/ss//6', + data: '17941080sales campaignwebUSD127.0.0.1en-USDalvik/2.1.0 (Linux; U; Android 9; Android SDK built for x86 Build/PSR1.180720.075)https://www.google.com/search?q=estore+bestsellerprodViewGames;;11;148.39failureReportgeneric', + params: {}, + headers: { + 'Content-Type': 'application/xml', + }, + method: 'POST', + }, + httpRes: { + status: 200, + data: 'FAILURE', + }, + }, + { + httpReq: { + url: 'https://adobe.success.omtrdc.net/b/ss//6', + data: '127.0.1.0www.google.co.inGoogleid1110011prodViewGames;Monopoly;1;14.00,Games;UNO;2;6.90successreport', + params: {}, + headers: { + 'Content-Type': 'application/xml', + }, + method: 'POST', + }, + httpRes: { + status: 200, + data: 'SUCCESS', + }, + }, +]; From ede22e3f8fb60a9e36e2a3f5a5e86260255c49ef Mon Sep 17 00:00:00 2001 From: Mihir Bhalala <77438541+mihir-4116@users.noreply.github.com> Date: Tue, 12 Dec 2023 10:07:21 +0530 Subject: [PATCH 73/93] fix(integrations): onboard sprig destination (#2857) * fix(integrations): onboard sprig destination * chore: code review changes * chore: code review changes --- .../v2/destinations/sprig/procWorkflow.yaml | 73 +++ .../destinations/sprig/processor/data.ts | 504 ++++++++++++++++++ 2 files changed, 577 insertions(+) create mode 100644 src/cdk/v2/destinations/sprig/procWorkflow.yaml create mode 100644 test/integrations/destinations/sprig/processor/data.ts diff --git a/src/cdk/v2/destinations/sprig/procWorkflow.yaml b/src/cdk/v2/destinations/sprig/procWorkflow.yaml new file mode 100644 index 0000000000..18b46913fd --- /dev/null +++ b/src/cdk/v2/destinations/sprig/procWorkflow.yaml @@ -0,0 +1,73 @@ +bindings: + - name: EventType + path: ../../../../constants + - path: ../../bindings/jsontemplate + - name: defaultRequestConfig + path: ../../../../v0/util + - name: removeUndefinedAndNullValues + path: ../../../../v0/util + +steps: + - name: messageType + template: | + .message.type.toLowerCase(); + + - name: validateInput + template: | + let messageType = $.outputs.messageType; + $.assert(messageType, "message Type is not present. Aborting"); + $.assert(messageType in {{$.EventType.([.IDENTIFY, .TRACK])}}, "message type " + messageType + " is not supported"); + $.assertConfig(.destination.Config.apiKey, "API Key is not present. Aborting"); + + - name: validateIdentifyPayload + condition: $.outputs.messageType === {{$.EventType.IDENTIFY}} + template: | + const userId = .message.({{{{$.getGenericPaths("userIdOnly")}}}});; + $.assert(userId, "userId is required"); + + - name: prepareIdentifyPayload + condition: $.outputs.messageType === {{$.EventType.IDENTIFY}} + template: | + $.context.payload = .message.({ + userId: {{{{$.getGenericPaths("userIdOnly")}}}}, + emailAddress: {{{{$.getGenericPaths("email")}}}}, + attributes: .context.traits + }); + $.context.payload = $.removeUndefinedAndNullValues($.context.payload); + + - name: validateTrackPayload + condition: $.outputs.messageType === {{$.EventType.TRACK}} + template: | + const userId = .message.({{{{$.getGenericPaths("userIdOnly")}}}});; + $.assert(userId, "userId is required"); + $.assert(.message.event, "event name is required"); + + - name: prepareTrackPayload + condition: $.outputs.messageType === {{$.EventType.TRACK}} + template: | + $.context.payload = .message.({ + userId: {{{{$.getGenericPaths("userIdOnly")}}}}, + emailAddress: {{{{$.getGenericPaths("email")}}}} + }); + const events = [ + { + event: .message.event, + timestamp: $.toMilliseconds(.message.().({{{{$.getGenericPaths("timestamp")}}}})) + } + ] + $.context.payload.events = events; + $.context.payload = $.removeUndefinedAndNullValues($.context.payload); + + - name: buildResponse + template: | + const response = $.defaultRequestConfig(); + response.body.JSON = $.context.payload; + response.endpoint = "https://api.sprig.com/v2/users"; + response.headers = { + "accept": "application/json", + "content-type": "application/json", + "authorization": "API-Key " + .destination.Config.apiKey + }; + response + + diff --git a/test/integrations/destinations/sprig/processor/data.ts b/test/integrations/destinations/sprig/processor/data.ts new file mode 100644 index 0000000000..6b99e5e13b --- /dev/null +++ b/test/integrations/destinations/sprig/processor/data.ts @@ -0,0 +1,504 @@ +export const data = [ + { + name: 'sprig', + description: 'No message type', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + userId: 'user@1', + channel: 'web', + context: { + traits: { + email: 'test@gmail.com', + firstName: 'Test', + lastName: 'Ruddelabs', + }, + }, + originalTimestamp: '2023-11-10T14:42:44.724Z', + timestamp: '2023-11-22T10:12:44.75705:30', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiKey: 'testApiKey', + }, + }, + metadata: { + jobId: 1, + }, + }, + ], + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + jobId: 1, + }, + statusCode: 400, + error: + 'message Type is not present. Aborting: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: message Type is not present. Aborting', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'SPRIG', + module: 'destination', + implementation: 'cdkV2', + feature: 'processor', + }, + }, + ], + }, + }, + }, + { + name: 'sprig', + description: 'Unsupported message type', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + userId: 'user@1', + groupId: 'group@1', + channel: 'web', + context: { + traits: { + email: 'test@gmail.com', + firstName: 'Test', + lastName: 'Rudderstack', + }, + }, + traits: {}, + type: 'group', + originalTimestamp: '2023-11-10T14:42:44.724Z', + timestamp: '2023-11-22T10:12:44.75705:30', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiKey: 'testApiKey', + }, + }, + metadata: { + jobId: 2, + }, + }, + ], + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + jobId: 2, + }, + statusCode: 400, + error: + 'message type group is not supported: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: message type group is not supported', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'SPRIG', + module: 'destination', + implementation: 'cdkV2', + feature: 'processor', + }, + }, + ], + }, + }, + }, + { + name: 'sprig', + description: 'Missing config', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + userId: 'user@1', + channel: 'web', + context: { + traits: { + email: 'test@gmail.com', + firstName: 'Test', + lastName: 'Rudderstack', + }, + }, + type: 'identify', + originalTimestamp: '2023-11-10T14:42:44.724Z', + timestamp: '2023-11-22T10:12:44.75705:30', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: {}, + }, + metadata: { + jobId: 3, + }, + }, + ], + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + jobId: 3, + }, + statusCode: 400, + error: + 'API Key is not present. Aborting: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: API Key is not present. Aborting', + statTags: { + errorCategory: 'dataValidation', + errorType: 'configuration', + destType: 'SPRIG', + module: 'destination', + implementation: 'cdkV2', + feature: 'processor', + }, + }, + ], + }, + }, + }, + { + name: 'sprig', + description: 'Identify call without userId', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + anonymousId: 'anon@1', + context: { + traits: { + email: 'test@gmail.com', + firstName: 'Test', + lastName: 'Rudderlabs', + }, + }, + type: 'identify', + originalTimestamp: '2023-11-10T14:42:44.724Z', + timestamp: '2023-11-22T10:12:44.75705:30', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiKey: 'testApiKey', + }, + }, + metadata: { + jobId: 4, + }, + }, + ], + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + jobId: 4, + }, + statusCode: 400, + error: + 'userId is required: Workflow: procWorkflow, Step: validateIdentifyPayload, ChildStep: undefined, OriginalError: userId is required', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'SPRIG', + module: 'destination', + implementation: 'cdkV2', + feature: 'processor', + }, + }, + ], + }, + }, + }, + { + name: 'sprig', + description: 'Successful identify call', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + userId: 'user@1', + context: { + traits: { + email: 'test@gmail.com', + firstName: 'Test', + lastName: 'Rudderlabs', + }, + }, + type: 'identify', + originalTimestamp: '2023-11-10T14:42:44.724Z', + timestamp: '2023-11-22T10:12:44.75705:30', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiKey: 'testApiKey', + }, + }, + metadata: { + jobId: 5, + }, + }, + ], + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + jobId: 5, + }, + output: { + method: 'POST', + endpoint: 'https://api.sprig.com/v2/users', + headers: { + accept: 'application/json', + authorization: 'API-Key testApiKey', + 'content-type': 'application/json', + }, + body: { + JSON: { + attributes: { + email: 'test@gmail.com', + firstName: 'Test', + lastName: 'Rudderlabs', + }, + emailAddress: 'test@gmail.com', + userId: 'user@1', + }, + XML: {}, + FORM: {}, + JSON_ARRAY: {}, + }, + files: {}, + params: {}, + type: 'REST', + userId: '', + version: '1', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'sprig', + description: 'Track call with empty event name', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + userId: 'user@1', + context: { + traits: { + email: 'test@gmail.com', + firstName: 'Test', + lastName: 'Rudderlabs', + }, + }, + properties: {}, + type: 'track', + event: '', + originalTimestamp: '2020-11-29T19:11:00.337Z', + timestamp: '2023-11-29T19:11:00.337Z', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiKey: 'testApiKey', + }, + }, + metadata: { + jobId: 6, + }, + }, + ], + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + jobId: 6, + }, + statusCode: 400, + error: + 'event name is required: Workflow: procWorkflow, Step: validateTrackPayload, ChildStep: undefined, OriginalError: event name is required', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'SPRIG', + module: 'destination', + implementation: 'cdkV2', + feature: 'processor', + }, + }, + ], + }, + }, + }, + { + name: 'sprig', + description: 'Successful track call', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + userId: 'user@1', + context: { + traits: { + email: 'test@gmail.com', + firstName: 'Test', + lastName: 'Rudderlabs', + }, + }, + properties: {}, + type: 'track', + event: 'signup', + originalTimestamp: '2020-11-29T19:11:00.337Z', + timestamp: '2023-11-29T19:11:00.337Z', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiKey: 'testApiKey', + }, + }, + metadata: { + jobId: 7, + }, + }, + ], + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + jobId: 7, + }, + output: { + method: 'POST', + endpoint: 'https://api.sprig.com/v2/users', + headers: { + accept: 'application/json', + authorization: 'API-Key testApiKey', + 'content-type': 'application/json', + }, + body: { + JSON: { + emailAddress: 'test@gmail.com', + userId: 'user@1', + events: [ + { + event: 'signup', + timestamp: 1701285060337, + }, + ], + }, + XML: {}, + FORM: {}, + JSON_ARRAY: {}, + }, + files: {}, + params: {}, + type: 'REST', + userId: '', + version: '1', + }, + statusCode: 200, + }, + ], + }, + }, + }, +]; From bf39215dd1bbed482665c837a2bfabfcb751c753 Mon Sep 17 00:00:00 2001 From: Dilip Kola <33080863+koladilip@users.noreply.github.com> Date: Tue, 12 Dec 2023 10:32:08 +0530 Subject: [PATCH 74/93] fix: adobe_analytics event field check (#2890) When message doesn't contain event field there is no meaningful process we can do so considering it as instrumenation error. --- .../destinations/adobe_analytics/transform.js | 3 ++ .../adobe_analytics/processor/data.ts | 45 +++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/src/v0/destinations/adobe_analytics/transform.js b/src/v0/destinations/adobe_analytics/transform.js index 8bac0edd70..b428138724 100644 --- a/src/v0/destinations/adobe_analytics/transform.js +++ b/src/v0/destinations/adobe_analytics/transform.js @@ -346,6 +346,9 @@ const processTrackEvent = (message, adobeEventName, destinationConfig, extras = const handleTrack = (message, destinationConfig) => { const ORDER_ID_KEY = 'properties.order_id'; const { event: rawEvent, properties } = message; + if (!rawEvent) { + throw new InstrumentationError('Event name is not present. Aborting message.'); + } let payload = null; // handle ecommerce events separately // generic events should go to the default diff --git a/test/integrations/destinations/adobe_analytics/processor/data.ts b/test/integrations/destinations/adobe_analytics/processor/data.ts index 690639c057..fa050897c9 100644 --- a/test/integrations/destinations/adobe_analytics/processor/data.ts +++ b/test/integrations/destinations/adobe_analytics/processor/data.ts @@ -3057,4 +3057,49 @@ export const data = [ }, }, }, + { + name: 'adobe_analytics', + description: 'Test 17: Event is missing for track', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: '78c53c15-32a1-4b65-adac-bec2d7bb8fab', + channel: 'web', + originalTimestamp: '2020-01-09T10:01:53.558Z', + type: 'track', + sentAt: '2020-01-09T10:02:03.257Z', + }, + destination: { + Config: {}, + }, + }, + ], + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'Event name is not present. Aborting message.', + statTags: { + destType: 'ADOBE_ANALYTICS', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, ]; From 1a86a0723e3f5fb6fdf9cf1dc716a47c6da16745 Mon Sep 17 00:00:00 2001 From: Ujjwal Abhishek <63387036+ujjwal-ab@users.noreply.github.com> Date: Tue, 12 Dec 2023 11:12:53 +0530 Subject: [PATCH 75/93] fix: add check to remove empty properties object from payload (#2896) --- src/v0/destinations/klaviyo/transform.js | 4 + test/__tests__/data/klaviyo.json | 144 +++++++++++++++++++++++ 2 files changed, 148 insertions(+) diff --git a/src/v0/destinations/klaviyo/transform.js b/src/v0/destinations/klaviyo/transform.js index 7c9061fc41..9273b6a048 100644 --- a/src/v0/destinations/klaviyo/transform.js +++ b/src/v0/destinations/klaviyo/transform.js @@ -93,6 +93,10 @@ const identifyRequestHandler = async (message, category, destination, reqMetadat data.attributes.properties = flattenProperties ? flattenJson(data.attributes.properties, '.', 'normal', false) : data.attributes.properties; + + if (isEmptyObject(data.attributes.properties)) { + delete data.attributes.properties; + } const payload = { data: removeUndefinedAndNullValues(data), }; diff --git a/test/__tests__/data/klaviyo.json b/test/__tests__/data/klaviyo.json index 796d9ed8e0..623aa78cc4 100644 --- a/test/__tests__/data/klaviyo.json +++ b/test/__tests__/data/klaviyo.json @@ -636,6 +636,150 @@ } ] }, + { + "description": "Identify call without user custom Properties", + "input": { + "destination": { + "Config": { + "publicApiKey": "dummyPublicApiKey", + "privateApiKey": "dummyPrivateApiKey", + "enforceEmailAsPrimary": false + } + }, + "message": { + "type": "identify", + "sentAt": "2021-01-03T17:02:53.195Z", + "userId": "user@1", + "channel": "web", + "context": { + "os": { + "name": "", + "version": "" + }, + "app": { + "name": "RudderLabs JavaScript SDK", + "build": "1.0.0", + "version": "1.1.11", + "namespace": "com.rudderlabs.javascript" + }, + "traits": { + "firstName": "Test", + "lastName": "Rudderlabs", + "email": "test@rudderstack.com", + "phone": "+12 345 578 900", + "userId": "user@1", + "title": "Developer", + "organization": "Rudder", + "city": "Tokyo", + "region": "Kanto", + "country": "JP", + "zip": "100-0001", + "properties": { + "listId": "XUepkK", + "subscribe": true, + "consent": ["email", "sms"] + } + }, + "locale": "en-US", + "screen": { + "density": 2 + }, + "library": { + "name": "RudderLabs JavaScript SDK", + "version": "1.1.11" + }, + "campaign": {}, + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:84.0) Gecko/20100101 Firefox/84.0" + }, + "rudderId": "8f8fa6b5-8e24-489c-8e22-61f23f2e364f", + "messageId": "2116ef8c-efc3-4ca4-851b-02ee60dad6ff", + "anonymousId": "97c46c81-3140-456d-b2a9-690d70aaca35", + "integrations": { + "All": true + }, + "originalTimestamp": "2021-01-03T17:02:53.193Z" + } + }, + "output": [ + { + "version": "1", + "type": "REST", + "method": "PATCH", + "endpoint": "https://a.klaviyo.com/api/profiles/01GW3PHVY0MTCDGS0A1612HARX", + "headers": { + "Authorization": "Klaviyo-API-Key dummyPrivateApiKey", + "Content-Type": "application/json", + "Accept": "application/json", + "revision": "2023-02-22" + }, + "params": {}, + "body": { + "JSON": { + "data": { + "type": "profile", + "attributes": { + "email": "test@rudderstack.com", + "first_name": "Test", + "last_name": "Rudderlabs", + "phone_number": "+12 345 578 900", + "external_id": "user@1", + "title": "Developer", + "organization": "Rudder", + "location": { + "city": "Tokyo", + "region": "Kanto", + "country": "JP", + "zip": "100-0001" + } + }, + "id": "01GW3PHVY0MTCDGS0A1612HARX" + } + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "files": {} + }, + { + "version": "1", + "type": "REST", + "method": "POST", + "endpoint": "https://a.klaviyo.com/api/profile-subscription-bulk-create-jobs", + "headers": { + "Content-Type": "application/json", + "Accept": "application/json", + "Authorization": "Klaviyo-API-Key dummyPrivateApiKey", + "revision": "2023-02-22" + }, + "params": {}, + "body": { + "JSON": { + "data": { + "type": "profile-subscription-bulk-create-job", + "attributes": { + "list_id": "XUepkK", + "subscriptions": [ + { + "email": "test@rudderstack.com", + "phone_number": "+12 345 578 900", + "channels": { + "email": ["MARKETING"], + "sms": ["MARKETING"] + } + } + ] + } + } + }, + "JSON_ARRAY": {}, + "XML": {}, + "FORM": {} + }, + "files": {} + } + ] + }, { "description": "Identify call without email and phone & enforceEmailAsPrimary enabled from UI", "input": { From ec974ba625ac09fb511a63304eb71ba306af67ca Mon Sep 17 00:00:00 2001 From: Dilip Kola <33080863+koladilip@users.noreply.github.com> Date: Tue, 12 Dec 2023 11:17:47 +0530 Subject: [PATCH 76/93] Update prepare-for-prod-deploy.yml --- .github/workflows/prepare-for-prod-deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/prepare-for-prod-deploy.yml b/.github/workflows/prepare-for-prod-deploy.yml index 0a2939ac2c..7750761a33 100644 --- a/.github/workflows/prepare-for-prod-deploy.yml +++ b/.github/workflows/prepare-for-prod-deploy.yml @@ -1,4 +1,4 @@ -name: Prepare for Production Environment Deployment +name: Prepare for DT Production Environment Deployment on: push: From a7df54f33ce95a2557d5234a4b79b9129afcb190 Mon Sep 17 00:00:00 2001 From: Dilip Kola <33080863+koladilip@users.noreply.github.com> Date: Tue, 12 Dec 2023 11:18:09 +0530 Subject: [PATCH 77/93] Update prepare-for-prod-ut-deploy.yml --- .github/workflows/prepare-for-prod-ut-deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/prepare-for-prod-ut-deploy.yml b/.github/workflows/prepare-for-prod-ut-deploy.yml index 1cb300512c..2da3c9d067 100644 --- a/.github/workflows/prepare-for-prod-ut-deploy.yml +++ b/.github/workflows/prepare-for-prod-ut-deploy.yml @@ -1,4 +1,4 @@ -name: Prepare for Production Environment Deployment +name: Prepare for UT Production Environment Deployment on: push: From a6641586eee8410e515269c2823a0b00fdc50306 Mon Sep 17 00:00:00 2001 From: Dilip Kola <33080863+koladilip@users.noreply.github.com> Date: Tue, 12 Dec 2023 11:18:41 +0530 Subject: [PATCH 78/93] Rename prepare-for-prod-deploy.yml to prepare-for-prod-dt-deploy.yml --- ...prepare-for-prod-deploy.yml => prepare-for-prod-dt-deploy.yml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/workflows/{prepare-for-prod-deploy.yml => prepare-for-prod-dt-deploy.yml} (100%) diff --git a/.github/workflows/prepare-for-prod-deploy.yml b/.github/workflows/prepare-for-prod-dt-deploy.yml similarity index 100% rename from .github/workflows/prepare-for-prod-deploy.yml rename to .github/workflows/prepare-for-prod-dt-deploy.yml From 69b74d4cff6f0dd112b6f2444e3a73f59e0727c2 Mon Sep 17 00:00:00 2001 From: Dilip Kola <33080863+koladilip@users.noreply.github.com> Date: Tue, 12 Dec 2023 11:20:59 +0530 Subject: [PATCH 79/93] Update build-push-docker-image.yml --- .github/workflows/build-push-docker-image.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-push-docker-image.yml b/.github/workflows/build-push-docker-image.yml index c57e74c81b..68360df6fc 100644 --- a/.github/workflows/build-push-docker-image.yml +++ b/.github/workflows/build-push-docker-image.yml @@ -151,7 +151,7 @@ jobs: docker buildx imagetools create -t ${{ inputs.push_tags }} ${{ inputs.push_tags }}-amd64 ${{ inputs.push_tags }}-arm64 - name: Create latest multi-arch manifest - # To be triggered only for release/hotfix PR merges coming from `prepare-for-prod-deploy.yaml` + # To be triggered only for release/hotfix PR merges coming from `prepare-for-prod-dt-deploy.yaml` if: ${{ inputs.build_type == 'dt' }} run: | docker buildx imagetools create -t rudderstack/rudder-transformer:latest ${{ inputs.push_tags }}-amd64 ${{ inputs.push_tags }}-arm64 From 50e921d1451bf7016e60b2e238b8f842d72b5b71 Mon Sep 17 00:00:00 2001 From: Dilip Kola <33080863+koladilip@users.noreply.github.com> Date: Tue, 12 Dec 2023 11:34:22 +0530 Subject: [PATCH 80/93] fix: missing null check in braze populateCustomAttributesWithOperation (#2897) Found logs for this error: Failure occurred during custom attributes operations TypeError: Cannot read properties of null (reading 'update') --- src/v0/destinations/braze/transform.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/v0/destinations/braze/transform.js b/src/v0/destinations/braze/transform.js index 38a5947ded..99b4a93e97 100644 --- a/src/v0/destinations/braze/transform.js +++ b/src/v0/destinations/braze/transform.js @@ -95,7 +95,10 @@ function populateCustomAttributesWithOperation( // add,update,remove on json attributes if (enableNestedArrayOperations) { Object.keys(traits) - .filter((key) => typeof traits[key] === 'object' && !Array.isArray(traits[key])) + .filter( + (key) => + traits[key] !== null && typeof traits[key] === 'object' && !Array.isArray(traits[key]), + ) .forEach((key) => { if (traits[key][CustomAttributeOperationTypes.UPDATE]) { CustomAttributeOperationUtil.customAttributeUpdateOperation( From da36d8979ee917c0030cf3f1d8b5cc38e099abc3 Mon Sep 17 00:00:00 2001 From: Dilip Kola <33080863+koladilip@users.noreply.github.com> Date: Tue, 12 Dec 2023 12:06:33 +0530 Subject: [PATCH 81/93] chore(INT-850): upgrade dependencies (#2807) chore: upgrade dependencies --- package-lock.json | 200 +++++++++++++----- package.json | 2 +- src/cdk/v2/destinations/gladly/utils.js | 27 ++- src/constants/destinationCanonicalNames.js | 2 +- src/util/openfaas/index.js | 32 +-- test/__tests__/data/am_input.json | 9 +- test/__tests__/data/am_output.json | 6 +- .../destinations/gladly/processor/data.ts | 2 +- .../destinations/gladly/router/data.ts | 2 +- .../snapchat_conversion/processor/data.ts | 26 +-- 10 files changed, 189 insertions(+), 119 deletions(-) diff --git a/package-lock.json b/package-lock.json index 27655f81ef..61501c6c08 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4805,15 +4805,73 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.22.5", - "license": "MIT", + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", "dependencies": { - "@babel/highlight": "^7.22.5" + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" }, "engines": { "node": ">=6.9.0" } }, + "node_modules/@babel/code-frame/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/code-frame/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/@babel/code-frame/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/@babel/compat-data": { "version": "7.22.6", "dev": true, @@ -4852,11 +4910,12 @@ } }, "node_modules/@babel/generator": { - "version": "7.22.5", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", + "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/types": "^7.22.5", + "@babel/types": "^7.23.0", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -4897,20 +4956,22 @@ } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.5", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.22.5", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/template": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" }, "engines": { "node": ">=6.9.0" @@ -4995,8 +5056,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.5", - "license": "MIT", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "engines": { "node": ">=6.9.0" } @@ -5023,11 +5085,12 @@ } }, "node_modules/@babel/highlight": { - "version": "7.22.5", - "license": "MIT", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", + "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", "dependencies": { - "@babel/helper-validator-identifier": "^7.22.5", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, "engines": { @@ -5036,7 +5099,8 @@ }, "node_modules/@babel/highlight/node_modules/ansi-styles": { "version": "3.2.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dependencies": { "color-convert": "^1.9.0" }, @@ -5046,7 +5110,8 @@ }, "node_modules/@babel/highlight/node_modules/chalk": { "version": "2.4.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -5058,25 +5123,29 @@ }, "node_modules/@babel/highlight/node_modules/color-convert": { "version": "1.9.3", - "license": "MIT", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dependencies": { "color-name": "1.1.3" } }, "node_modules/@babel/highlight/node_modules/color-name": { "version": "1.1.3", - "license": "MIT" + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, "node_modules/@babel/highlight/node_modules/has-flag": { "version": "3.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "engines": { "node": ">=4" } }, "node_modules/@babel/highlight/node_modules/supports-color": { "version": "5.5.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dependencies": { "has-flag": "^3.0.0" }, @@ -5085,9 +5154,10 @@ } }, "node_modules/@babel/parser": { - "version": "7.22.6", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", + "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", "dev": true, - "license": "MIT", "bin": { "parser": "bin/babel-parser.js" }, @@ -5259,31 +5329,33 @@ } }, "node_modules/@babel/template": { - "version": "7.22.5", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.22.5", - "@babel/parser": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.22.6", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", + "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.22.5", - "@babel/generator": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.22.6", - "@babel/types": "^7.22.5", + "@babel/parser": "^7.23.0", + "@babel/types": "^7.23.0", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -5300,12 +5372,13 @@ } }, "node_modules/@babel/types": { - "version": "7.22.5", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", + "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" }, "engines": { @@ -6639,9 +6712,9 @@ } }, "node_modules/@rudderstack/integrations-lib": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/@rudderstack/integrations-lib/-/integrations-lib-0.1.8.tgz", - "integrity": "sha512-f8GX78RFma3XAWPNEI6QjGk4avbE8r9aspHNaYE+YyRKsJGWrl8gw/k+Jso36C0juOGas79GWPSiypbXLu8Q/g==", + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/@rudderstack/integrations-lib/-/integrations-lib-0.1.9.tgz", + "integrity": "sha512-ROi/LfI7PXqKDrjSig+1Rf2TQ8MgxJGJ7sAD1B0PmRKELQpxK6PLt8QF+vKXl8wYILQu2gwTkZ5o+uwmNKxGzg==", "dependencies": { "@rudderstack/workflow-engine": "^0.5.7", "axios": "^1.4.0", @@ -6706,9 +6779,9 @@ } }, "node_modules/@rudderstack/json-template-engine": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/@rudderstack/json-template-engine/-/json-template-engine-0.8.2.tgz", - "integrity": "sha512-9oMBnqgNuwiXd7MUlNOAchCnJXQAy6w6XGmDqDM6iXdYDkvqYFiq7sbg5j4SdtpTTST293hahREr5PXfFVzVKg==" + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@rudderstack/json-template-engine/-/json-template-engine-0.8.1.tgz", + "integrity": "sha512-MR2ArfOXEDh9FEj/N3LVLjIxf134wq+YxUdZN4gTLEONIPdna97QeNk4hnhtlob0QQIrWr13mfPaU9FpvU2Q6Q==" }, "node_modules/@rudderstack/workflow-engine": { "version": "0.6.9", @@ -6770,9 +6843,9 @@ } }, "node_modules/@rudderstack/workflow-engine/node_modules/@smithy/util-utf8": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.0.2.tgz", - "integrity": "sha512-qOiVORSPm6Ce4/Yu6hbSgNHABLP2VMv8QOC3tTDNHHlWY19pPyc++fBTbZPtx6egPXi4HQxKDnMxVxpbtX2GoA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.0.0.tgz", + "integrity": "sha512-rctU1VkziY84n5OXe3bPNpKR001ZCME2JCaBBFgtiM2hfKbHFudc/BkMuPab8hRbLd0j3vbnBTTZ1igBf0wgiQ==", "dependencies": { "@smithy/util-buffer-from": "^2.0.0", "tslib": "^2.5.0" @@ -14903,7 +14976,8 @@ }, "node_modules/js-tokens": { "version": "4.0.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "node_modules/js-yaml": { "version": "4.1.0", @@ -16307,9 +16381,16 @@ "license": "MIT" }, "node_modules/nanoid": { - "version": "3.3.4", + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", "dev": true, - "license": "MIT", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -17071,7 +17152,9 @@ } }, "node_modules/postcss": { - "version": "8.4.21", + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", "dev": true, "funding": [ { @@ -17081,11 +17164,14 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "dependencies": { - "nanoid": "^3.3.4", + "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" }, diff --git a/package.json b/package.json index a36ac26e9c..7f4aa1c5a5 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "lint:fix": "eslint . --fix", "lint:fix:json": "eslint --ext .json --fix .", "check:merge": "npm run verify || exit 1; codecov", - "start": "node ./dist/src/index.js", + "start": "cd dist;node ./src/index.js;cd ..", "build:start": "npm run build && npm run start", "build:ci": "tsc -p tsconfig.json", "build:swagger": "npm run build && npm run setup:swagger", diff --git a/src/cdk/v2/destinations/gladly/utils.js b/src/cdk/v2/destinations/gladly/utils.js index 5abc9b6dd0..0489f410ec 100644 --- a/src/cdk/v2/destinations/gladly/utils.js +++ b/src/cdk/v2/destinations/gladly/utils.js @@ -1,9 +1,6 @@ const get = require('get-value'); const { InstrumentationError } = require('@rudderstack/integrations-lib'); -const { - base64Convertor, - getDestinationExternalID, -} = require('../../../../v0/util'); +const { base64Convertor, getDestinationExternalID } = require('../../../../v0/util'); const { MappedToDestinationKey } = require('../../../../constants'); const reservedCustomAttributes = [ @@ -35,7 +32,6 @@ const getEndpoint = (destination) => { return `https://${domain}/api/v1/customer-profiles`; }; - const getFieldValue = (field) => { if (field) { if (Array.isArray(field)) { @@ -44,7 +40,7 @@ const getFieldValue = (field) => { return [{ original: field }]; } return undefined; -} +}; const formatFieldForRETl = (message, fieldName) => { const identifierType = get(message, identifierTypeKey); @@ -70,7 +66,6 @@ const formatField = (message, fieldName) => { return formatFieldForRETl(message, fieldName); } return formatFieldForEventStream(message, fieldName); - }; const getCustomAttributes = (message) => { @@ -78,7 +73,9 @@ const getCustomAttributes = (message) => { // for rETL if (mappedToDestination) { if (message?.traits?.customAttributes && typeof message.traits.customAttributes === 'object') { - return Object.keys(message.traits.customAttributes).length > 0 ? message.traits.customAttributes : undefined; + return Object.keys(message.traits.customAttributes).length > 0 + ? message.traits.customAttributes + : undefined; } return undefined; } @@ -140,25 +137,27 @@ const getCustomerId = (message) => { const validatePayload = (payload) => { if (!(payload?.phones || payload?.emails || payload?.id || payload?.externalCustomerId)) { - throw new InstrumentationError('One of phone, email, userId or GladlyCustomerId is required for an identify call'); + throw new InstrumentationError( + 'One of phone, email, userId or GladlyCustomerId is required for an identify call', + ); } }; const getQueryParams = (payload) => { if (payload.emails && payload.emails.length > 0) { - return `email=${encodeURIComponent(payload.emails[0].original)}` + return `email=${encodeURIComponent(payload.emails[0].original)}`; } if (payload.phones && payload.phones.length > 0) { - return `phoneNumber=${encodeURIComponent(payload.phones[0].original)}` + return `phoneNumber=${encodeURIComponent(payload.phones[0].original)}`; } if (payload.externalCustomerId) { - return `externalCustomerId=${encodeURIComponent(payload.externalCustomerId)}` + return `externalCustomerId=${encodeURIComponent(payload.externalCustomerId)}`; } return undefined; -} +}; module.exports = { getHeaders, @@ -171,5 +170,5 @@ module.exports = { formatFieldForRETl, getCustomAttributes, getExternalCustomerId, - formatFieldForEventStream + formatFieldForEventStream, }; diff --git a/src/constants/destinationCanonicalNames.js b/src/constants/destinationCanonicalNames.js index 48e7c6d8bb..d1e199c9e2 100644 --- a/src/constants/destinationCanonicalNames.js +++ b/src/constants/destinationCanonicalNames.js @@ -140,7 +140,7 @@ const DestCanonicalNames = { 'twitter_ads', 'TWITTER_ADS', ], - BRAZE: ['BRAZE', 'Braze', 'braze'] + BRAZE: ['BRAZE', 'Braze', 'braze'], }; module.exports = { DestHandlerMap, DestCanonicalNames }; diff --git a/src/util/openfaas/index.js b/src/util/openfaas/index.js index 2792003f4a..878fa706d9 100644 --- a/src/util/openfaas/index.js +++ b/src/util/openfaas/index.js @@ -247,24 +247,13 @@ const executeFaasFunction = async ( try { if (testMode) await awaitFunctionReadiness(name); return await invokeFunction(name, events); - } catch (error) { logger.error(`Error while invoking ${name}: ${error.message}`); errorRaised = error; - if ( - error.statusCode === 404 && - error.message.includes(`error finding function ${name}`) - ) { + if (error.statusCode === 404 && error.message.includes(`error finding function ${name}`)) { removeFunctionFromCache(name); - await setupFaasFunction( - name, - null, - versionId, - libraryVersionIDs, - testMode, - trMetadata, - ); + await setupFaasFunction(name, null, versionId, libraryVersionIDs, testMode, trMetadata); throw new RetryRequestError(`${name} not found`); } @@ -284,22 +273,23 @@ const executeFaasFunction = async ( } finally { // delete the function created, if it's called as part of testMode if (testMode) { - deleteFunction(name).catch((err) => - logger.error(`[Faas] Error while deleting ${name}: ${err.message}`)) + deleteFunction(name).catch((err) => + logger.error(`[Faas] Error while deleting ${name}: ${err.message}`), + ); } // setup the tags for observability and then fire the stats const tags = { - identifier: "openfaas", + identifier: 'openfaas', testMode: testMode, errored: errorRaised ? true : false, statusCode: errorRaised ? errorRaised.statusCode : HTTP_STATUS_CODES.OK, // default statuscode is 200OK - ...events.length && events[0].metadata ? getMetadata(events[0].metadata) : {}, - ...events.length && events[0].metadata ? getTransformationMetadata(events[0].metadata) : {}, - } + ...(events.length && events[0].metadata ? getMetadata(events[0].metadata) : {}), + ...(events.length && events[0].metadata ? getTransformationMetadata(events[0].metadata) : {}), + }; - stats.counter('user_transform_function_input_events', events.length, tags) - stats.timing('user_transform_function_latency', startTime, tags) + stats.counter('user_transform_function_input_events', events.length, tags); + stats.timing('user_transform_function_latency', startTime, tags); } }; diff --git a/test/__tests__/data/am_input.json b/test/__tests__/data/am_input.json index 126d235787..2eecfb1d2c 100644 --- a/test/__tests__/data/am_input.json +++ b/test/__tests__/data/am_input.json @@ -1074,9 +1074,7 @@ "CHILD_KEY_102": "value_103" }, "name_trait": "Company", - "value_trait": [ - "ABC" - ] + "value_trait": ["ABC"] }, "sentAt": "2020-10-20T07:54:58.983Z" }, @@ -4313,8 +4311,7 @@ "All": true }, "messageId": "1662393883248-509420bf-b812-4f8d-bdb2-8c811bfde87f", - "properties": { - }, + "properties": {}, "originalTimestamp": "2022-09-05T16:04:43.250Z", "type": "screen", "userId": "User Android" @@ -4943,4 +4940,4 @@ } } } -] \ No newline at end of file +] diff --git a/test/__tests__/data/am_output.json b/test/__tests__/data/am_output.json index 5a9c674113..6744a9dcef 100644 --- a/test/__tests__/data/am_output.json +++ b/test/__tests__/data/am_output.json @@ -757,9 +757,7 @@ "JSON_ARRAY": {}, "FORM": { "api_key": "abcde", - "identification": [ - "{\"group_type\":\"Company\",\"group_value\":\"ABC\"}" - ] + "identification": ["{\"group_type\":\"Company\",\"group_value\":\"ABC\"}"] } }, "files": {}, @@ -4468,4 +4466,4 @@ "files": {}, "userId": "anon-id-new" } -] \ No newline at end of file +] diff --git a/test/integrations/destinations/gladly/processor/data.ts b/test/integrations/destinations/gladly/processor/data.ts index 211fa78134..e81af999fb 100644 --- a/test/integrations/destinations/gladly/processor/data.ts +++ b/test/integrations/destinations/gladly/processor/data.ts @@ -780,7 +780,7 @@ export const data = [ body: { JSON: { address: 'Pakistan', - emails: [{original: 'abc'}], + emails: [{ original: 'abc' }], id: 'user@10', }, XML: {}, diff --git a/test/integrations/destinations/gladly/router/data.ts b/test/integrations/destinations/gladly/router/data.ts index d3339d8108..413c92e247 100644 --- a/test/integrations/destinations/gladly/router/data.ts +++ b/test/integrations/destinations/gladly/router/data.ts @@ -322,7 +322,7 @@ export const data = [ identifierType: 'externalCustomerId', }, ], - mappedToDestination: true + mappedToDestination: true, }, traits: { id: 'user@1', diff --git a/test/integrations/destinations/snapchat_conversion/processor/data.ts b/test/integrations/destinations/snapchat_conversion/processor/data.ts index baa2b2b99e..b0d14208cc 100644 --- a/test/integrations/destinations/snapchat_conversion/processor/data.ts +++ b/test/integrations/destinations/snapchat_conversion/processor/data.ts @@ -4344,7 +4344,7 @@ export const data = [ }, ], userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', }, type: 'track', event: 'Order Completed', @@ -4362,7 +4362,7 @@ export const data = [ quantity: 3, }, ], - category: 'shoes' + category: 'shoes', }, integrations: { All: true, @@ -4417,16 +4417,16 @@ export const data = [ event_type: 'PURCHASE', item_ids: ['123', '124'], brands: ['brand01', 'brand02'], - item_category: "shoes", + item_category: 'shoes', price: '56', hashed_email: '73062d872926c2a556f17b36f50e328ddf9bff9d403939bd14b6c3b7f5a33fc2', hashed_phone_number: - 'bc77d64d7045fe44795ed926df37231a0cfb6ec6b74588c512790e9f143cc492', + 'bc77d64d7045fe44795ed926df37231a0cfb6ec6b74588c512790e9f143cc492', hashed_mobile_ad_id: - 'f9779d734aaee50f16ee0011260bae7048f1d9a128c62b6a661077875701edd2', + 'f9779d734aaee50f16ee0011260bae7048f1d9a128c62b6a661077875701edd2', hashed_idfv: '54bd0b26a3d39dad90f5149db49b9fd9ba885f8e35d1d94cae69273f5e657b9f', user_agent: - 'mozilla/5.0 (macintosh; intel mac os x 10_15_2) applewebkit/537.36 (khtml, like gecko) chrome/79.0.3945.88 safari/537.36', + 'mozilla/5.0 (macintosh; intel mac os x 10_15_2) applewebkit/537.36 (khtml, like gecko) chrome/79.0.3945.88 safari/537.36', timestamp: '1650625078', event_conversion_type: 'MOBILE_APP', snap_app_id: 'hfhdhfd', @@ -4498,7 +4498,7 @@ export const data = [ }, ], userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', }, type: 'track', event: 'Order Completed', @@ -4517,7 +4517,7 @@ export const data = [ }, ], category: 'shoes', - item_category: 'glass' + item_category: 'glass', }, integrations: { All: true, @@ -4572,16 +4572,16 @@ export const data = [ event_type: 'PURCHASE', item_ids: ['123', '124'], brands: ['brand01', 'brand02'], - item_category: "glass", + item_category: 'glass', price: '56', hashed_email: '73062d872926c2a556f17b36f50e328ddf9bff9d403939bd14b6c3b7f5a33fc2', hashed_phone_number: - 'bc77d64d7045fe44795ed926df37231a0cfb6ec6b74588c512790e9f143cc492', + 'bc77d64d7045fe44795ed926df37231a0cfb6ec6b74588c512790e9f143cc492', hashed_mobile_ad_id: - 'f9779d734aaee50f16ee0011260bae7048f1d9a128c62b6a661077875701edd2', + 'f9779d734aaee50f16ee0011260bae7048f1d9a128c62b6a661077875701edd2', hashed_idfv: '54bd0b26a3d39dad90f5149db49b9fd9ba885f8e35d1d94cae69273f5e657b9f', user_agent: - 'mozilla/5.0 (macintosh; intel mac os x 10_15_2) applewebkit/537.36 (khtml, like gecko) chrome/79.0.3945.88 safari/537.36', + 'mozilla/5.0 (macintosh; intel mac os x 10_15_2) applewebkit/537.36 (khtml, like gecko) chrome/79.0.3945.88 safari/537.36', timestamp: '1650625078', event_conversion_type: 'MOBILE_APP', snap_app_id: 'hfhdhfd', @@ -4599,7 +4599,7 @@ export const data = [ ], }, }, - } + }, ].map((tc) => ({ ...tc, mockFns: (_) => { From 4a7eaa09000bcb82eb7f217d500223939bd9b07b Mon Sep 17 00:00:00 2001 From: Dilip Kola <33080863+koladilip@users.noreply.github.com> Date: Tue, 12 Dec 2023 12:07:04 +0530 Subject: [PATCH 82/93] fix: mailjet source transformation by adding email exists check (#2889) mailjet code uses md5 method to hash email for using it as userId when actual userId is not found in the event and when email doesn't exists then md5 throwing an error so added check before calling md5 method. --- src/v0/sources/mailjet/transform.js | 2 +- test/__tests__/data/mailjet_source.json | 45 +++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/v0/sources/mailjet/transform.js b/src/v0/sources/mailjet/transform.js index fcc27611bb..d2719cc0ba 100644 --- a/src/v0/sources/mailjet/transform.js +++ b/src/v0/sources/mailjet/transform.js @@ -40,7 +40,7 @@ function process(event) { } message.context.externalId = externalId; - if (message.userId === null || message.userId === undefined) { + if (!message.userId && event.email) { // Treating userId as unique identifier // If userId is not present, then generating it from email using md5 hash function message.userId = md5(event.email); diff --git a/test/__tests__/data/mailjet_source.json b/test/__tests__/data/mailjet_source.json index ba7f32fb89..d9869585cb 100644 --- a/test/__tests__/data/mailjet_source.json +++ b/test/__tests__/data/mailjet_source.json @@ -200,5 +200,50 @@ "userId": "5b6a3426dba2cb24e4f0aeec43bee9d7" } } + }, + { + "description": "MailJet when no email is present", + "input": { + "event": "bounce", + "time": 1664444170, + "MessageID": 56013522696710744, + "Message_GUID": "dbe4f0a3-4a5a-4784-a724-a9794d3c0444", + "mj_campaign_id": 108892, + "mj_contact_id": 373142182, + "customcampaign": "mj.nl=58486", + "blocked": false, + "hard_bounce": false, + "error_related_to": "system", + "error": "connection issue" + }, + "output": { + "Message": { + "context": { + "library": { + "name": "unknown", + "version": "unknown" + }, + "integration": { + "name": "MailJet" + }, + "externalId": [ + { + "type": "mailjetContactId", + "id": 373142182 + } + ] + }, + "integrations": { + "MailJet": false + }, + "type": "track", + "event": "bounce", + "properties": { + "customcampaign": "mj.nl=58486", + "mj_campaign_id": 108892 + }, + "originalTimestamp": "2022-09-29T09:36:10.000Z" + } + } } ] From bed431e1de94ab28df1ee592d083a1481b960b6d Mon Sep 17 00:00:00 2001 From: AASHISH MALIK Date: Tue, 12 Dec 2023 13:42:43 +0530 Subject: [PATCH 83/93] fix: covert toString before toLowercase (#2830) * fix: covert toString before toLowercase * fix: throw error if not valid email --- src/v0/destinations/active_campaign/util.js | 2 +- src/v0/destinations/adobe_analytics/config.js | 2 +- .../adobe_analytics/networkHandler.js | 17 +- src/v0/destinations/braze/transform.js | 10 +- .../util/errorTypes/transformerProxyError.js | 2 +- .../campaign_manager/networkHandler.js | 18 +- test/__tests__/data/braze_input.json | 45 + test/__tests__/data/braze_output.json | 4 + test/__tests__/data/marketo_router_input.json | 2006 +++--- .../data/marketo_router_metadata_input.json | 16 +- .../__tests__/data/marketo_router_output.json | 72 +- .../destinations/webhook/processor/data.ts | 5520 ++++++++--------- .../destinations/webhook/router/data.ts | 2 +- 13 files changed, 3831 insertions(+), 3885 deletions(-) diff --git a/src/v0/destinations/active_campaign/util.js b/src/v0/destinations/active_campaign/util.js index 457413c3e2..40e15f95b3 100644 --- a/src/v0/destinations/active_campaign/util.js +++ b/src/v0/destinations/active_campaign/util.js @@ -6,7 +6,7 @@ const { const tags = require('../../util/tags'); const errorHandler = (httpCallError, message) => { - const {response, status} = processAxiosResponse(httpCallError); + const { response, status } = processAxiosResponse(httpCallError); let msg = message; if (response) { msg = `${message} (${httpCallError.response?.statusText},${JSON.stringify(response)})`; diff --git a/src/v0/destinations/adobe_analytics/config.js b/src/v0/destinations/adobe_analytics/config.js index 232fe61f7f..ed5852f5a5 100644 --- a/src/v0/destinations/adobe_analytics/config.js +++ b/src/v0/destinations/adobe_analytics/config.js @@ -44,5 +44,5 @@ module.exports = { ECOM_PRODUCT_EVENTS, commonConfig: MAPPING_CONFIG[CONFIG_CATEGORIES.COMMON.name], formatDestinationConfig, - DESTINATION: 'ADOBE_ANALYTICS' + DESTINATION: 'ADOBE_ANALYTICS', }; diff --git a/src/v0/destinations/adobe_analytics/networkHandler.js b/src/v0/destinations/adobe_analytics/networkHandler.js index b5b58ade0c..0ec1fad286 100644 --- a/src/v0/destinations/adobe_analytics/networkHandler.js +++ b/src/v0/destinations/adobe_analytics/networkHandler.js @@ -1,15 +1,12 @@ const { InstrumentationError } = require('@rudderstack/integrations-lib'); const { proxyRequest, prepareProxyRequest } = require('../../../adapters/network'); -const { - processAxiosResponse, -} = require('../../../adapters/utils/networkUtils'); +const { processAxiosResponse } = require('../../../adapters/utils/networkUtils'); const { DESTINATION } = require('./config'); - /** * Extract data inside different tags from an xml payload - * @param {*} xml - * @param {*} tagName + * @param {*} xml + * @param {*} tagName * @returns data inside the tagName */ function extractContent(xmlPayload, tagName) { @@ -29,9 +26,13 @@ const responseHandler = (destinationResponse, dest) => { // if the status tag in XML contains FAILURE, we build and throw an explicit error if (responseStatus === 'FAILURE') { if (reason) { - throw new InstrumentationError(`[${DESTINATION} Response Handler] Request failed for destination ${dest} : ${reason}` ) + throw new InstrumentationError( + `[${DESTINATION} Response Handler] Request failed for destination ${dest} : ${reason}`, + ); } else { - throw new InstrumentationError(`[${DESTINATION} Response Handler] Request failed for destination ${dest} with a general error`) + throw new InstrumentationError( + `[${DESTINATION} Response Handler] Request failed for destination ${dest} with a general error`, + ); } } diff --git a/src/v0/destinations/braze/transform.js b/src/v0/destinations/braze/transform.js index 99b4a93e97..38c4b348db 100644 --- a/src/v0/destinations/braze/transform.js +++ b/src/v0/destinations/braze/transform.js @@ -22,6 +22,7 @@ const { getFieldValueFromMessage, removeUndefinedValues, isHttpStatusSuccess, + isDefinedAndNotNull, simpleProcessRouterDestSync, simpleProcessRouterDest, isNewStatusCodesAccepted, @@ -153,11 +154,16 @@ function getUserAttributesObject(message, mappingJson, destination) { Object.keys(mappingJson).forEach((destKey) => { let value = get(traits, mappingJson[destKey]); if (value || (value === null && reservedKeys.includes(destKey))) { + // if email is not string remove it from attributes + if (destKey === 'email' && typeof value !== 'string') { + throw new InstrumentationError('Invalid email, email must be a valid string'); + } + // handle gender special case if (destKey === 'gender') { value = formatGender(value); - } else if (destKey === 'email' && value !== null) { - value = value?.toLowerCase(); + } else if (destKey === 'email' && isDefinedAndNotNull(value)) { + value = value.toString().toLowerCase(); } data[destKey] = value; } diff --git a/src/v0/util/errorTypes/transformerProxyError.js b/src/v0/util/errorTypes/transformerProxyError.js index 9f4bb593c7..42ccdea490 100644 --- a/src/v0/util/errorTypes/transformerProxyError.js +++ b/src/v0/util/errorTypes/transformerProxyError.js @@ -25,4 +25,4 @@ class TransformerProxyError extends BaseError { } } -module.exports = TransformerProxyError; \ No newline at end of file +module.exports = TransformerProxyError; diff --git a/src/v1/destinations/campaign_manager/networkHandler.js b/src/v1/destinations/campaign_manager/networkHandler.js index 6e13a68f0a..431cbd6966 100644 --- a/src/v1/destinations/campaign_manager/networkHandler.js +++ b/src/v1/destinations/campaign_manager/networkHandler.js @@ -75,15 +75,15 @@ const responseHandler = (destinationResponse) => { } throw new TransformerProxyError( - `Campaign Manager: Error transformer proxy v1 during CAMPAIGN_MANAGER response transformation`, - 500, - { - [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(status), - }, - destinationResponse, - getAuthErrCategoryFromStCode(status), - responseWithIndividualEvents, - ); + `Campaign Manager: Error transformer proxy v1 during CAMPAIGN_MANAGER response transformation`, + 500, + { + [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(status), + }, + destinationResponse, + getAuthErrCategoryFromStCode(status), + responseWithIndividualEvents, + ); }; function networkHandler() { diff --git a/test/__tests__/data/braze_input.json b/test/__tests__/data/braze_input.json index 8c3294e42b..fb4e41b189 100644 --- a/test/__tests__/data/braze_input.json +++ b/test/__tests__/data/braze_input.json @@ -1910,5 +1910,50 @@ "type": "track", "userId": "" } + }, + { + "destination": { + "Config": { + "restApiKey": "dummyApiKey", + "prefixProperties": true, + "useNativeSDK": false, + "dataCenter": "us-01" + }, + "DestinationDefinition": { + "DisplayName": "Braze", + "ID": "1WhbSZ6uA3H5ChVifHpfL2H6sie", + "Name": "BRAZE" + }, + "Enabled": true, + "ID": "1WhcOCGgj9asZu850HvugU2C3Aq", + "Name": "Braze", + "Transformations": [] + }, + "message": { + "anonymousId": "e6ab2c5e-2cda-44a9-a962-e2f67df78bca", + "channel": "web", + "context": { + "traits": { + "city": "Disney", + "country": "USA", + "email": 123, + "firstname": "Mickey", + "closed_at": null, + "orderTotal": 0 + }, + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36" + }, + "integrations": { + "All": true + }, + "messageId": "2536eda4-d638-4c93-8014-8ffe3f083214", + "originalTimestamp": "2020-01-24T06:29:02.362Z", + "receivedAt": "2020-01-24T11:59:02.403+05:30", + "request_ip": "[::1]:53709", + "sentAt": "2020-01-24T06:29:02.363Z", + "timestamp": "2020-01-24T11:59:02.402+05:30", + "type": "identify", + "userId": "" + } } ] diff --git a/test/__tests__/data/braze_output.json b/test/__tests__/data/braze_output.json index 0575326237..ed39930569 100644 --- a/test/__tests__/data/braze_output.json +++ b/test/__tests__/data/braze_output.json @@ -1034,5 +1034,9 @@ "type": "REST", "userId": "e6ab2c5e-2cda-44a9-a962-e2f67df78bca", "version": "1" + }, + { + "statusCode": 400, + "message": "Invalid email, email must be a valid string" } ] diff --git a/test/__tests__/data/marketo_router_input.json b/test/__tests__/data/marketo_router_input.json index a2ecc7f616..a7a40a221a 100644 --- a/test/__tests__/data/marketo_router_input.json +++ b/test/__tests__/data/marketo_router_input.json @@ -1,1046 +1,996 @@ [ - { - "message": { - "anonymousId": "anon_id_success", - "channel": "mobile", - "context": { - "app": { - "build": "1", - "name": "TestAppName", - "namespace": "com.android.sample", - "version": "1.0" - }, - "device": { - "id": "anon_id_success", - "manufacturer": "Google", - "model": "Android SDK built for x86", - "name": "generic_x86", - "type": "android" - }, - "library": { - "name": "com.rudderstack.android.sdk.core", - "version": "1.0.1-beta.1" - }, - "locale": "en-US", - "network": { - "carrier": "Android", - "bluetooth": false, - "cellular": true, - "wifi": true - }, - "os": { - "name": "Android", - "version": "8.1.0" - }, - "screen": { - "density": 420, - "height": 1794, - "width": 1080 - }, - "timezone": "Asia/Kolkata", - "traits": { - "anonymousId": "anon_id_success" - }, - "userAgent": "Dalvik/2.1.0 (Linux; U; Android 8.1.0; Android SDK built for x86 Build/OSM1.180201.007)" - }, + { + "message": { + "anonymousId": "anon_id_success", + "channel": "mobile", + "context": { + "app": { + "build": "1", + "name": "TestAppName", + "namespace": "com.android.sample", + "version": "1.0" + }, + "device": { + "id": "anon_id_success", + "manufacturer": "Google", + "model": "Android SDK built for x86", + "name": "generic_x86", + "type": "android" + }, + "library": { + "name": "com.rudderstack.android.sdk.core", + "version": "1.0.1-beta.1" + }, + "locale": "en-US", + "network": { + "carrier": "Android", + "bluetooth": false, + "cellular": true, + "wifi": true + }, + "os": { + "name": "Android", + "version": "8.1.0" + }, + "screen": { + "density": 420, + "height": 1794, + "width": 1080 + }, + "timezone": "Asia/Kolkata", + "traits": { + "anonymousId": "anon_id_success" + }, + "userAgent": "Dalvik/2.1.0 (Linux; U; Android 8.1.0; Android SDK built for x86 Build/OSM1.180201.007)" + }, + "event": "Product Clicked", + "integrations": { + "All": true + }, + "messageId": "id1", + "properties": { + "name": "Test Product" + }, + "originalTimestamp": "2020-12-17T21:00:59.176Z", + "type": "track", + "sentAt": "2020-03-12T09:05:03.421Z" + }, + "metadata": { + "jobId": 1 + }, + "destination": { + "Config": { + "accountId": "marketo_acct_id_success", + "clientId": "marketo_client_id_success", + "clientSecret": "marketo_client_secret_success", + "trackAnonymousEvents": true, + "customActivityPropertyMap": [ + { + "from": "name", + "to": "productName" + } + ], + "leadTraitMapping": [ + { + "from": "leadScore", + "to": "customLeadScore" + } + ], + "rudderEventsMapping": [ + { "event": "Product Clicked", - "integrations": { - "All": true - }, - "messageId": "id1", - "properties": { - "name": "Test Product" - }, - "originalTimestamp": "2020-12-17T21:00:59.176Z", - "type": "track", - "sentAt": "2020-03-12T09:05:03.421Z" + "marketoPrimarykey": "name", + "marketoActivityId": "100001" + } + ] + }, + "secretConfig": {}, + "ID": "1mMy5cqbtfuaKZv1IhVQKnBdVwe", + "name": "Marketo", + "enabled": true, + "workspaceId": "1TSN08muJTZwH8iCDmnnRt1pmLd", + "deleted": false, + "createdAt": "2020-12-30T08:39:32.005Z", + "updatedAt": "2021-02-03T16:22:31.374Z", + "destinationDefinition": { + "config": { + "destConfig": { + "defaultConfig": [ + "accountId", + "clientId", + "clientSecret", + "trackAnonymousEvents", + "rudderEventsMapping", + "customActivityPropertyMap", + "leadTraitMapping" + ] + }, + "secretKeys": ["clientSecret"], + "excludeKeys": [], + "includeKeys": [], + "routerTransform": true, + "supportedSourceTypes": ["android", "ios", "web", "unity", "amp", "cloud", "reactnative"] }, - "metadata": { - "jobId": 1 + "responseRules": { + "responseType": "JSON", + "rules": { + "retryable": [ + { + "success": "false", + "errors.0.code": 600 + }, + { + "success": "false", + "errors.0.code": 601 + }, + { + "success": "false", + "errors.0.code": 602 + }, + { + "success": "false", + "errors.0.code": 604 + }, + { + "success": "false", + "errors.0.code": 606 + }, + { + "success": "false", + "errors.0.code": 607 + }, + { + "success": "false", + "errors.0.code": 608 + }, + { + "success": "false", + "errors.0.code": 611 + } + ], + "abortable": [ + { + "success": "false", + "errors.0.code": 603 + }, + { + "success": "false", + "errors.0.code": 605 + }, + { + "success": "false", + "errors.0.code": 609 + }, + { + "success": "false", + "errors.0.code": 610 + } + ] + } + }, + "id": "1aIXqM806xAVm92nx07YwKbRrO9", + "name": "MARKETO", + "displayName": "Marketo", + "createdAt": "2020-04-09T09:24:31.794Z", + "updatedAt": "2021-01-11T11:03:28.103Z" + }, + "transformations": [], + "isConnectionEnabled": true, + "isProcessorEnabled": true + } + }, + { + "message": { + "anonymousId": "anon_id_success", + "channel": "mobile", + "context": { + "app": { + "build": "1", + "name": "TestAppName", + "namespace": "com.android.sample", + "version": "1.0" }, - "destination": { - "Config": { - "accountId": "marketo_acct_id_success", - "clientId": "marketo_client_id_success", - "clientSecret": "marketo_client_secret_success", - "trackAnonymousEvents": true, - "customActivityPropertyMap": [ - { - "from": "name", - "to": "productName" - } - ], - "leadTraitMapping": [ - { - "from": "leadScore", - "to": "customLeadScore" - } - ], - "rudderEventsMapping": [ - { - "event": "Product Clicked", - "marketoPrimarykey": "name", - "marketoActivityId": "100001" - } - ] - }, - "secretConfig": {}, - "ID": "1mMy5cqbtfuaKZv1IhVQKnBdVwe", - "name": "Marketo", - "enabled": true, - "workspaceId": "1TSN08muJTZwH8iCDmnnRt1pmLd", - "deleted": false, - "createdAt": "2020-12-30T08:39:32.005Z", - "updatedAt": "2021-02-03T16:22:31.374Z", - "destinationDefinition": { - "config": { - "destConfig": { - "defaultConfig": [ - "accountId", - "clientId", - "clientSecret", - "trackAnonymousEvents", - "rudderEventsMapping", - "customActivityPropertyMap", - "leadTraitMapping" - ] - }, - "secretKeys": [ - "clientSecret" - ], - "excludeKeys": [], - "includeKeys": [], - "routerTransform": true, - "supportedSourceTypes": [ - "android", - "ios", - "web", - "unity", - "amp", - "cloud", - "reactnative" - ] - }, - "responseRules": { - "responseType": "JSON", - "rules": { - "retryable": [ - { - "success": "false", - "errors.0.code": 600 - }, - { - "success": "false", - "errors.0.code": 601 - }, - { - "success": "false", - "errors.0.code": 602 - }, - { - "success": "false", - "errors.0.code": 604 - }, - { - "success": "false", - "errors.0.code": 606 - }, - { - "success": "false", - "errors.0.code": 607 - }, - { - "success": "false", - "errors.0.code": 608 - }, - { - "success": "false", - "errors.0.code": 611 - } - ], - "abortable": [ - { - "success": "false", - "errors.0.code": 603 - }, - { - "success": "false", - "errors.0.code": 605 - }, - { - "success": "false", - "errors.0.code": 609 - }, - { - "success": "false", - "errors.0.code": 610 - } - ] - } - }, - "id": "1aIXqM806xAVm92nx07YwKbRrO9", - "name": "MARKETO", - "displayName": "Marketo", - "createdAt": "2020-04-09T09:24:31.794Z", - "updatedAt": "2021-01-11T11:03:28.103Z" - }, - "transformations": [], - "isConnectionEnabled": true, - "isProcessorEnabled": true - } + "device": { + "id": "anon_id_success", + "manufacturer": "Google", + "model": "Android SDK built for x86", + "name": "generic_x86", + "type": "android" + }, + "library": { + "name": "com.rudderstack.android.sdk.core", + "version": "1.0.1-beta.1" + }, + "locale": "en-US", + "network": { + "carrier": "Android", + "bluetooth": false, + "cellular": true, + "wifi": true + }, + "os": { + "name": "Android", + "version": "8.1.0" + }, + "screen": { + "density": 420, + "height": 1794, + "width": 1080 + }, + "timezone": "Asia/Kolkata", + "traits": { + "anonymousId": "anon_id_success" + }, + "userAgent": "Dalvik/2.1.0 (Linux; U; Android 8.1.0; Android SDK built for x86 Build/OSM1.180201.007)" + }, + "event": "Product Clicked", + "integrations": { + "All": true + }, + "messageId": "id1", + "properties": { + "name": "Test Product", + "product_id": "prod_1" + }, + "originalTimestamp": "2020-12-17T21:00:59.176Z", + "type": "track", + "sentAt": "2020-12-17T21:00:59.176Z" + }, + "metadata": { + "jobId": 2 }, - { - "message": { - "anonymousId": "anon_id_success", - "channel": "mobile", - "context": { - "app": { - "build": "1", - "name": "TestAppName", - "namespace": "com.android.sample", - "version": "1.0" - }, - "device": { - "id": "anon_id_success", - "manufacturer": "Google", - "model": "Android SDK built for x86", - "name": "generic_x86", - "type": "android" - }, - "library": { - "name": "com.rudderstack.android.sdk.core", - "version": "1.0.1-beta.1" - }, - "locale": "en-US", - "network": { - "carrier": "Android", - "bluetooth": false, - "cellular": true, - "wifi": true - }, - "os": { - "name": "Android", - "version": "8.1.0" - }, - "screen": { - "density": 420, - "height": 1794, - "width": 1080 - }, - "timezone": "Asia/Kolkata", - "traits": { - "anonymousId": "anon_id_success" - }, - "userAgent": "Dalvik/2.1.0 (Linux; U; Android 8.1.0; Android SDK built for x86 Build/OSM1.180201.007)" - }, + "destination": { + "Config": { + "accountId": "marketo_acct_id_success", + "clientId": "marketo_client_id_success", + "clientSecret": "marketo_client_secret_success", + "trackAnonymousEvents": true, + "customActivityPropertyMap": [ + { + "from": "name", + "to": "productName" + } + ], + "leadTraitMapping": [ + { + "from": "leadScore", + "to": "customLeadScore" + } + ], + "rudderEventsMapping": [ + { "event": "Product Clicked", - "integrations": { - "All": true - }, - "messageId": "id1", - "properties": { - "name": "Test Product", - "product_id": "prod_1" - }, - "originalTimestamp": "2020-12-17T21:00:59.176Z", - "type": "track", - "sentAt": "2020-12-17T21:00:59.176Z" + "marketoPrimarykey": "name", + "marketoActivityId": "100001" + } + ] + }, + "secretConfig": {}, + "ID": "1mMy5cqbtfuaKZv1IhVQKnBdVwe", + "name": "Marketo", + "enabled": true, + "workspaceId": "1TSN08muJTZwH8iCDmnnRt1pmLd", + "deleted": false, + "createdAt": "2020-12-30T08:39:32.005Z", + "updatedAt": "2021-02-03T16:22:31.374Z", + "destinationDefinition": { + "config": { + "destConfig": { + "defaultConfig": [ + "accountId", + "clientId", + "clientSecret", + "trackAnonymousEvents", + "rudderEventsMapping", + "customActivityPropertyMap", + "leadTraitMapping" + ] + }, + "secretKeys": ["clientSecret"], + "excludeKeys": [], + "includeKeys": [], + "routerTransform": true, + "supportedSourceTypes": ["android", "ios", "web", "unity", "amp", "cloud", "reactnative"] + }, + "responseRules": { + "responseType": "JSON", + "rules": { + "retryable": [ + { + "success": "false", + "errors.0.code": 600 + }, + { + "success": "false", + "errors.0.code": 601 + }, + { + "success": "false", + "errors.0.code": 602 + }, + { + "success": "false", + "errors.0.code": 604 + }, + { + "success": "false", + "errors.0.code": 606 + }, + { + "success": "false", + "errors.0.code": 607 + }, + { + "success": "false", + "errors.0.code": 608 + }, + { + "success": "false", + "errors.0.code": 611 + } + ], + "abortable": [ + { + "success": "false", + "errors.0.code": 603 + }, + { + "success": "false", + "errors.0.code": 605 + }, + { + "success": "false", + "errors.0.code": 609 + }, + { + "success": "false", + "errors.0.code": 610 + } + ] + } + }, + "id": "1aIXqM806xAVm92nx07YwKbRrO9", + "name": "MARKETO", + "displayName": "Marketo", + "createdAt": "2020-04-09T09:24:31.794Z", + "updatedAt": "2021-01-11T11:03:28.103Z" + }, + "transformations": [], + "isConnectionEnabled": true, + "isProcessorEnabled": true + } + }, + { + "message": { + "type": "identify", + "sentAt": "2022-09-19T10:34:02.002Z", + "userId": "e17c5a5e-5e2f-430b-b497-fe3f1ea3a704", + "channel": "web", + "context": { + "os": { + "name": "", + "version": "" }, - "metadata": { - "jobId": 2 + "app": { + "name": "RudderLabs JavaScript SDK", + "build": "1.0.0", + "version": "2.12.1", + "namespace": "com.rudderlabs.javascript" }, - "destination": { - "Config": { - "accountId": "marketo_acct_id_success", - "clientId": "marketo_client_id_success", - "clientSecret": "marketo_client_secret_success", - "trackAnonymousEvents": true, - "customActivityPropertyMap": [ - { - "from": "name", - "to": "productName" - } - ], - "leadTraitMapping": [ - { - "from": "leadScore", - "to": "customLeadScore" - } - ], - "rudderEventsMapping": [ - { - "event": "Product Clicked", - "marketoPrimarykey": "name", - "marketoActivityId": "100001" - } - ] - }, - "secretConfig": {}, - "ID": "1mMy5cqbtfuaKZv1IhVQKnBdVwe", - "name": "Marketo", - "enabled": true, - "workspaceId": "1TSN08muJTZwH8iCDmnnRt1pmLd", - "deleted": false, - "createdAt": "2020-12-30T08:39:32.005Z", - "updatedAt": "2021-02-03T16:22:31.374Z", - "destinationDefinition": { - "config": { - "destConfig": { - "defaultConfig": [ - "accountId", - "clientId", - "clientSecret", - "trackAnonymousEvents", - "rudderEventsMapping", - "customActivityPropertyMap", - "leadTraitMapping" - ] - }, - "secretKeys": [ - "clientSecret" - ], - "excludeKeys": [], - "includeKeys": [], - "routerTransform": true, - "supportedSourceTypes": [ - "android", - "ios", - "web", - "unity", - "amp", - "cloud", - "reactnative" - ] - }, - "responseRules": { - "responseType": "JSON", - "rules": { - "retryable": [ - { - "success": "false", - "errors.0.code": 600 - }, - { - "success": "false", - "errors.0.code": 601 - }, - { - "success": "false", - "errors.0.code": 602 - }, - { - "success": "false", - "errors.0.code": 604 - }, - { - "success": "false", - "errors.0.code": 606 - }, - { - "success": "false", - "errors.0.code": 607 - }, - { - "success": "false", - "errors.0.code": 608 - }, - { - "success": "false", - "errors.0.code": 611 - } - ], - "abortable": [ - { - "success": "false", - "errors.0.code": 603 - }, - { - "success": "false", - "errors.0.code": 605 - }, - { - "success": "false", - "errors.0.code": 609 - }, - { - "success": "false", - "errors.0.code": 610 - } - ] - } - }, - "id": "1aIXqM806xAVm92nx07YwKbRrO9", - "name": "MARKETO", - "displayName": "Marketo", - "createdAt": "2020-04-09T09:24:31.794Z", - "updatedAt": "2021-01-11T11:03:28.103Z" - }, - "transformations": [], - "isConnectionEnabled": true, - "isProcessorEnabled": true - } + "page": { + "url": "https://accounts.app.t2.broken.com/home", + "path": "/home", + "title": "Home", + "search": "", + "tab_url": "https://accounts.app.t2.broken.com/home", + "referrer": "https://ts50-cvii.core.broken.org/", + "initial_referrer": "https://ts50-cvii.core.broken.org/", + "referring_domain": "ts50-cvii.core.broken.org", + "initial_referring_domain": "ts50-cvii.core.broken.org" + }, + "locale": "en-IN", + "screen": { + "width": 1728, + "height": 1117, + "density": 2, + "innerWidth": 1728, + "innerHeight": 969 + }, + "traits": { + "name": "AM", + "email": "0c7b8b80-9c43-4f8e-b2d2-5e2448a25040@j.mail", + "lastName": "M", + "firstName": "A", + "accountName": "MACDEV", + "billingName": "g g", + "companyName": "macDev", + "currentTier": "Webinar Pro 250", + "billingCycle": "Annually", + "lastBillingDate": "2022-06-29T09:40:42.000Z", + "nextBillingDate": "2023-09-09T04:00:00.000Z", + "subscriptionType": "Webinar Pro 250", + "subscriptionStatus": "ACTIVE", + "lastWebinarEventDate": "2022-09-15T20:00:00.000Z", + "nextWebinarEventDate": "2022-09-16T06:15:00.000Z" + }, + "library": { + "name": "RudderLabs JavaScript SDK", + "version": "2.12.1" + }, + "campaign": {}, + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36" + }, + "rudderId": "73dc83ef-587f-4077-90f3-c36083e64019", + "messageId": "1663583642000200-e3f31c4c-6361-4f99-b643-7755303a6007", + "timestamp": "2022-09-19T10:34:02.954Z", + "receivedAt": "2022-09-19T10:34:02.956Z", + "request_ip": "11.105.44.120", + "anonymousId": "0c7b8b80-9c43-4f8e-b2d2-5e2448a25040", + "integrations": { + "All": true + }, + "originalTimestamp": "2022-09-19T10:34:02.000Z" }, - { - "message": { - "type": "identify", - "sentAt": "2022-09-19T10:34:02.002Z", - "userId": "e17c5a5e-5e2f-430b-b497-fe3f1ea3a704", - "channel": "web", - "context": { - "os": { - "name": "", - "version": "" - }, - "app": { - "name": "RudderLabs JavaScript SDK", - "build": "1.0.0", - "version": "2.12.1", - "namespace": "com.rudderlabs.javascript" - }, - "page": { - "url": "https://accounts.app.t2.broken.com/home", - "path": "/home", - "title": "Home", - "search": "", - "tab_url": "https://accounts.app.t2.broken.com/home", - "referrer": "https://ts50-cvii.core.broken.org/", - "initial_referrer": "https://ts50-cvii.core.broken.org/", - "referring_domain": "ts50-cvii.core.broken.org", - "initial_referring_domain": "ts50-cvii.core.broken.org" - }, - "locale": "en-IN", - "screen": { - "width": 1728, - "height": 1117, - "density": 2, - "innerWidth": 1728, - "innerHeight": 969 - }, - "traits": { - "name": "AM", - "email": "0c7b8b80-9c43-4f8e-b2d2-5e2448a25040@j.mail", - "lastName": "M", - "firstName": "A", - "accountName": "MACDEV", - "billingName": "g g", - "companyName": "macDev", - "currentTier": "Webinar Pro 250", - "billingCycle": "Annually", - "lastBillingDate": "2022-06-29T09:40:42.000Z", - "nextBillingDate": "2023-09-09T04:00:00.000Z", - "subscriptionType": "Webinar Pro 250", - "subscriptionStatus": "ACTIVE", - "lastWebinarEventDate": "2022-09-15T20:00:00.000Z", - "nextWebinarEventDate": "2022-09-16T06:15:00.000Z" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "2.12.1" - }, - "campaign": {}, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36" - }, - "rudderId": "73dc83ef-587f-4077-90f3-c36083e64019", - "messageId": "1663583642000200-e3f31c4c-6361-4f99-b643-7755303a6007", - "timestamp": "2022-09-19T10:34:02.954Z", - "receivedAt": "2022-09-19T10:34:02.956Z", - "request_ip": "11.105.44.120", - "anonymousId": "0c7b8b80-9c43-4f8e-b2d2-5e2448a25040", - "integrations": { - "All": true - }, - "originalTimestamp": "2022-09-19T10:34:02.000Z" + "destination": { + "Config": { + "accountId": "valid_account_broken_event", + "clientId": "504300cd-76b2-a7l4-bhle-90a07420nx73", + "clientSecret": "3l3gJpzRsZagD6gu7tnTeKXz0bomLGnd", + "trackAnonymousEvents": false, + "createIfNotExist": true, + "rudderEventsMapping": [ + { + "event": "acq_signup_completed", + "marketoActivityId": "100026" + }, + { + "event": "act_createwebinarform_submit", + "marketoActivityId": "100025" + }, + { + "event": "act_presentation_style", + "marketoActivityId": "100025" + }, + { + "event": "act_webinar_view", + "marketoActivityId": "100025" + }, + { + "event": "act_webinar_join", + "marketoActivityId": "100025" + }, + { + "event": "act_presentation_addteammember", + "marketoActivityId": "100025" + }, + { + "event": "act_engagement_discussions_savediscussion", + "marketoActivityId": "100025" + }, + { + "event": "act_engagement_networking_savetime", + "marketoActivityId": "100025" + } + ] + }, + "destinationDefinition": { + "config": { + "destConfig": { + "defaultConfig": [ + "accountId", + "clientId", + "clientSecret", + "trackAnonymousEvents", + "rudderEventsMapping", + "customActivityPropertyMap", + "leadTraitMapping" + ] + }, + "secretKeys": ["clientSecret"], + "excludeKeys": [], + "includeKeys": [], + "routerTransform": true, + "supportedSourceTypes": ["android", "ios", "web", "unity", "amp", "cloud", "reactnative"] }, - "destination": { - "Config": { - "accountId": "valid_account_broken_event", - "clientId": "504300cd-76b2-a7l4-bhle-90a07420nx73", - "clientSecret": "3l3gJpzRsZagD6gu7tnTeKXz0bomLGnd", - "trackAnonymousEvents": false, - "createIfNotExist": true, - "rudderEventsMapping": [ - { - "event": "acq_signup_completed", - "marketoActivityId": "100026" - }, - { - "event": "act_createwebinarform_submit", - "marketoActivityId": "100025" - }, - { - "event": "act_presentation_style", - "marketoActivityId": "100025" - }, - { - "event": "act_webinar_view", - "marketoActivityId": "100025" - }, - { - "event": "act_webinar_join", - "marketoActivityId": "100025" - }, - { - "event": "act_presentation_addteammember", - "marketoActivityId": "100025" - }, - { - "event": "act_engagement_discussions_savediscussion", - "marketoActivityId": "100025" - }, - { - "event": "act_engagement_networking_savetime", - "marketoActivityId": "100025" - } - ] - }, - "destinationDefinition": { - "config": { - "destConfig": { - "defaultConfig": [ - "accountId", - "clientId", - "clientSecret", - "trackAnonymousEvents", - "rudderEventsMapping", - "customActivityPropertyMap", - "leadTraitMapping" - ] - }, - "secretKeys": [ - "clientSecret" - ], - "excludeKeys": [], - "includeKeys": [], - "routerTransform": true, - "supportedSourceTypes": [ - "android", - "ios", - "web", - "unity", - "amp", - "cloud", - "reactnative" - ] - }, - "responseRules": { - "responseType": "JSON", - "rules": { - "retryable": [ - { - "success": "false", - "errors.0.code": 600 - }, - { - "success": "false", - "errors.0.code": 601 - }, - { - "success": "false", - "errors.0.code": 602 - }, - { - "success": "false", - "errors.0.code": 604 - }, - { - "success": "false", - "errors.0.code": 606 - }, - { - "success": "false", - "errors.0.code": 607 - }, - { - "success": "false", - "errors.0.code": 608 - }, - { - "success": "false", - "errors.0.code": 611 - } - ], - "abortable": [ - { - "success": "false", - "errors.0.code": 603 - }, - { - "success": "false", - "errors.0.code": 605 - }, - { - "success": "false", - "errors.0.code": 609 - }, - { - "success": "false", - "errors.0.code": 610 - } - ] - } - }, - "id": "1aIXqM806xAVm92nx07YwKbRrO9", - "name": "MARKETO", - "displayName": "Marketo", - "createdAt": "2020-04-09T09:24:31.794Z", - "updatedAt": "2021-01-11T11:03:28.103Z" - }, - "secretConfig": {}, - "ID": "1mMy5cqbtfuaKZv1IhVQKnBdVke", - "name": "Marketo", - "enabled": true, - "workspaceId": "1TSN08muJTZwH8iCDmnnRt1pmMd", - "deleted": false, - "createdAt": "2022-02-10T08:39:32.005Z", - "updatedAt": "2022-09-03T16:22:31.374Z", - "transformations": [], - "isConnectionEnabled": true, - "isProcessorEnabled": true + "responseRules": { + "responseType": "JSON", + "rules": { + "retryable": [ + { + "success": "false", + "errors.0.code": 600 + }, + { + "success": "false", + "errors.0.code": 601 + }, + { + "success": "false", + "errors.0.code": 602 + }, + { + "success": "false", + "errors.0.code": 604 + }, + { + "success": "false", + "errors.0.code": 606 + }, + { + "success": "false", + "errors.0.code": 607 + }, + { + "success": "false", + "errors.0.code": 608 + }, + { + "success": "false", + "errors.0.code": 611 + } + ], + "abortable": [ + { + "success": "false", + "errors.0.code": 603 + }, + { + "success": "false", + "errors.0.code": 605 + }, + { + "success": "false", + "errors.0.code": 609 + }, + { + "success": "false", + "errors.0.code": 610 + } + ] + } }, - "metadata": { - "jobId": 3 - } + "id": "1aIXqM806xAVm92nx07YwKbRrO9", + "name": "MARKETO", + "displayName": "Marketo", + "createdAt": "2020-04-09T09:24:31.794Z", + "updatedAt": "2021-01-11T11:03:28.103Z" + }, + "secretConfig": {}, + "ID": "1mMy5cqbtfuaKZv1IhVQKnBdVke", + "name": "Marketo", + "enabled": true, + "workspaceId": "1TSN08muJTZwH8iCDmnnRt1pmMd", + "deleted": false, + "createdAt": "2022-02-10T08:39:32.005Z", + "updatedAt": "2022-09-03T16:22:31.374Z", + "transformations": [], + "isConnectionEnabled": true, + "isProcessorEnabled": true }, - { - "message": { - "type": "identify", - "sentAt": "2022-09-19T10:34:02.002Z", - "userId": "e17c5a5e-5e2f-430b-b497-fe3f1ea3a704", - "channel": "web", - "context": { - "os": { - "name": "", - "version": "" - }, - "app": { - "name": "RudderLabs JavaScript SDK", - "build": "1.0.0", - "version": "2.12.1", - "namespace": "com.rudderlabs.javascript" - }, - "page": { - "url": "https://accounts.app.t2.broken.com/home", - "path": "/home", - "title": "Home", - "search": "", - "tab_url": "https://accounts.app.t2.broken.com/home", - "referrer": "https://ts50-cvii.core.broken.org/", - "initial_referrer": "https://ts50-cvii.core.broken.org/", - "referring_domain": "ts50-cvii.core.broken.org", - "initial_referring_domain": "ts50-cvii.core.broken.org" - }, - "locale": "en-IN", - "screen": { - "width": 1728, - "height": 1117, - "density": 2, - "innerWidth": 1728, - "innerHeight": 969 - }, - "traits": { - "name": "AM", - "email": "0c7b8b80-9c43-4f8e-b2d2-5e2448a25040@j.mail", - "lastName": "M", - "firstName": "A", - "accountName": "MACDEV", - "billingName": "g g", - "companyName": "macDev", - "currentTier": "Webinar Pro 250", - "billingCycle": "Annually", - "lastBillingDate": "2022-06-29T09:40:42.000Z", - "nextBillingDate": "2023-09-09T04:00:00.000Z", - "subscriptionType": "Webinar Pro 250", - "subscriptionStatus": "ACTIVE", - "lastWebinarEventDate": "2022-09-15T20:00:00.000Z", - "nextWebinarEventDate": "2022-09-16T06:15:00.000Z" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "2.12.1" - }, - "campaign": {}, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36" - }, - "rudderId": "73dc83ef-587f-4077-90f3-c36083e64019", - "messageId": "1663583642000200-e3f31c4c-6361-4f99-b643-7755303a6007", - "timestamp": "2022-09-19T10:34:02.954Z", - "receivedAt": "2022-09-19T10:34:02.956Z", - "request_ip": "11.105.44.120", - "anonymousId": "0c7b8b80-9c43-4f8e-b2d2-5e2448a25040", - "integrations": { - "All": true - }, - "originalTimestamp": "2022-09-19T10:34:02.000Z" + "metadata": { + "jobId": 3 + } + }, + { + "message": { + "type": "identify", + "sentAt": "2022-09-19T10:34:02.002Z", + "userId": "e17c5a5e-5e2f-430b-b497-fe3f1ea3a704", + "channel": "web", + "context": { + "os": { + "name": "", + "version": "" + }, + "app": { + "name": "RudderLabs JavaScript SDK", + "build": "1.0.0", + "version": "2.12.1", + "namespace": "com.rudderlabs.javascript" }, - "destination": { - "Config": { - "accountId": "unhandled_status_code", - "clientId": "504300cd-76b2-a7l4-bhle-90a07420nx73", - "clientSecret": "3l3gJpzRsZagD6gu7tnTeKXz0bomLGnd", - "trackAnonymousEvents": false, - "createIfNotExist": true, - "rudderEventsMapping": [ - { - "event": "acq_signup_completed", - "marketoActivityId": "100026" - }, - { - "event": "act_createwebinarform_submit", - "marketoActivityId": "100025" - }, - { - "event": "act_presentation_style", - "marketoActivityId": "100025" - }, - { - "event": "act_webinar_view", - "marketoActivityId": "100025" - }, - { - "event": "act_webinar_join", - "marketoActivityId": "100025" - }, - { - "event": "act_presentation_addteammember", - "marketoActivityId": "100025" - }, - { - "event": "act_engagement_discussions_savediscussion", - "marketoActivityId": "100025" - }, - { - "event": "act_engagement_networking_savetime", - "marketoActivityId": "100025" - } - ] - }, - "destinationDefinition": { - "config": { - "destConfig": { - "defaultConfig": [ - "accountId", - "clientId", - "clientSecret", - "trackAnonymousEvents", - "rudderEventsMapping", - "customActivityPropertyMap", - "leadTraitMapping" - ] - }, - "secretKeys": [ - "clientSecret" - ], - "excludeKeys": [], - "includeKeys": [], - "routerTransform": true, - "supportedSourceTypes": [ - "android", - "ios", - "web", - "unity", - "amp", - "cloud", - "reactnative" - ] - }, - "responseRules": { - "responseType": "JSON", - "rules": { - "retryable": [ - { - "success": "false", - "errors.0.code": 600 - }, - { - "success": "false", - "errors.0.code": 601 - }, - { - "success": "false", - "errors.0.code": 602 - }, - { - "success": "false", - "errors.0.code": 604 - }, - { - "success": "false", - "errors.0.code": 606 - }, - { - "success": "false", - "errors.0.code": 607 - }, - { - "success": "false", - "errors.0.code": 608 - }, - { - "success": "false", - "errors.0.code": 611 - } - ], - "abortable": [ - { - "success": "false", - "errors.0.code": 603 - }, - { - "success": "false", - "errors.0.code": 605 - }, - { - "success": "false", - "errors.0.code": 609 - }, - { - "success": "false", - "errors.0.code": 610 - } - ] - } - }, - "id": "1aIXqM806xAVm92nx07YwKbRrO9", - "name": "MARKETO", - "displayName": "Marketo", - "createdAt": "2020-04-09T09:24:31.794Z", - "updatedAt": "2021-01-11T11:03:28.103Z" - }, - "secretConfig": {}, - "ID": "1mMy5cqbtfuaKZv1IhVQKnBdVke", - "name": "Marketo", - "enabled": true, - "workspaceId": "1TSN08muJTZwH8iCDmnnRt1pmMd", - "deleted": false, - "createdAt": "2022-02-10T08:39:32.005Z", - "updatedAt": "2022-09-03T16:22:31.374Z", - "transformations": [], - "isConnectionEnabled": true, - "isProcessorEnabled": true + "page": { + "url": "https://accounts.app.t2.broken.com/home", + "path": "/home", + "title": "Home", + "search": "", + "tab_url": "https://accounts.app.t2.broken.com/home", + "referrer": "https://ts50-cvii.core.broken.org/", + "initial_referrer": "https://ts50-cvii.core.broken.org/", + "referring_domain": "ts50-cvii.core.broken.org", + "initial_referring_domain": "ts50-cvii.core.broken.org" }, - "metadata": { - "jobId": 4 - } + "locale": "en-IN", + "screen": { + "width": 1728, + "height": 1117, + "density": 2, + "innerWidth": 1728, + "innerHeight": 969 + }, + "traits": { + "name": "AM", + "email": "0c7b8b80-9c43-4f8e-b2d2-5e2448a25040@j.mail", + "lastName": "M", + "firstName": "A", + "accountName": "MACDEV", + "billingName": "g g", + "companyName": "macDev", + "currentTier": "Webinar Pro 250", + "billingCycle": "Annually", + "lastBillingDate": "2022-06-29T09:40:42.000Z", + "nextBillingDate": "2023-09-09T04:00:00.000Z", + "subscriptionType": "Webinar Pro 250", + "subscriptionStatus": "ACTIVE", + "lastWebinarEventDate": "2022-09-15T20:00:00.000Z", + "nextWebinarEventDate": "2022-09-16T06:15:00.000Z" + }, + "library": { + "name": "RudderLabs JavaScript SDK", + "version": "2.12.1" + }, + "campaign": {}, + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36" + }, + "rudderId": "73dc83ef-587f-4077-90f3-c36083e64019", + "messageId": "1663583642000200-e3f31c4c-6361-4f99-b643-7755303a6007", + "timestamp": "2022-09-19T10:34:02.954Z", + "receivedAt": "2022-09-19T10:34:02.956Z", + "request_ip": "11.105.44.120", + "anonymousId": "0c7b8b80-9c43-4f8e-b2d2-5e2448a25040", + "integrations": { + "All": true + }, + "originalTimestamp": "2022-09-19T10:34:02.000Z" }, - { - "message": { - "type": "identify", - "sentAt": "2022-09-19T10:34:02.002Z", - "userId": "e17c5a5e-5e2f-430b-b497-fe3f1ea3a704", - "channel": "web", - "context": { - "os": { - "name": "", - "version": "" - }, - "app": { - "name": "RudderLabs JavaScript SDK", - "build": "1.0.0", - "version": "2.12.1", - "namespace": "com.rudderlabs.javascript" - }, - "page": { - "url": "https://accounts.app.t2.broken.com/home", - "path": "/home", - "title": "Home", - "search": "", - "tab_url": "https://accounts.app.t2.broken.com/home", - "referrer": "https://ts50-cvii.core.broken.org/", - "initial_referrer": "https://ts50-cvii.core.broken.org/", - "referring_domain": "ts50-cvii.core.broken.org", - "initial_referring_domain": "ts50-cvii.core.broken.org" - }, - "locale": "en-IN", - "screen": { - "width": 1728, - "height": 1117, - "density": 2, - "innerWidth": 1728, - "innerHeight": 969 - }, - "traits": { - "name": "AM", - "email": "0c7b8b80-9c43-4f8e-b2d2-5e2448a25040@j.mail", - "lastName": "M", - "firstName": "A", - "accountName": "MACDEV", - "billingName": "g g", - "companyName": "macDev", - "currentTier": "Webinar Pro 250", - "billingCycle": "Annually", - "lastBillingDate": "2022-06-29T09:40:42.000Z", - "nextBillingDate": "2023-09-09T04:00:00.000Z", - "subscriptionType": "Webinar Pro 250", - "subscriptionStatus": "ACTIVE", - "lastWebinarEventDate": "2022-09-15T20:00:00.000Z", - "nextWebinarEventDate": "2022-09-16T06:15:00.000Z" - }, - "library": { - "name": "RudderLabs JavaScript SDK", - "version": "2.12.1" - }, - "campaign": {}, - "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36" - }, - "rudderId": "73dc83ef-587f-4077-90f3-c36083e64019", - "messageId": "1663583642000200-e3f31c4c-6361-4f99-b643-7755303a6007", - "timestamp": "2022-09-19T10:34:02.954Z", - "receivedAt": "2022-09-19T10:34:02.956Z", - "request_ip": "11.105.44.120", - "anonymousId": "0c7b8b80-9c43-4f8e-b2d2-5e2448a25040", - "integrations": { - "All": true - }, - "originalTimestamp": "2022-09-19T10:34:02.000Z" + "destination": { + "Config": { + "accountId": "unhandled_status_code", + "clientId": "504300cd-76b2-a7l4-bhle-90a07420nx73", + "clientSecret": "3l3gJpzRsZagD6gu7tnTeKXz0bomLGnd", + "trackAnonymousEvents": false, + "createIfNotExist": true, + "rudderEventsMapping": [ + { + "event": "acq_signup_completed", + "marketoActivityId": "100026" + }, + { + "event": "act_createwebinarform_submit", + "marketoActivityId": "100025" + }, + { + "event": "act_presentation_style", + "marketoActivityId": "100025" + }, + { + "event": "act_webinar_view", + "marketoActivityId": "100025" + }, + { + "event": "act_webinar_join", + "marketoActivityId": "100025" + }, + { + "event": "act_presentation_addteammember", + "marketoActivityId": "100025" + }, + { + "event": "act_engagement_discussions_savediscussion", + "marketoActivityId": "100025" + }, + { + "event": "act_engagement_networking_savetime", + "marketoActivityId": "100025" + } + ] + }, + "destinationDefinition": { + "config": { + "destConfig": { + "defaultConfig": [ + "accountId", + "clientId", + "clientSecret", + "trackAnonymousEvents", + "rudderEventsMapping", + "customActivityPropertyMap", + "leadTraitMapping" + ] + }, + "secretKeys": ["clientSecret"], + "excludeKeys": [], + "includeKeys": [], + "routerTransform": true, + "supportedSourceTypes": ["android", "ios", "web", "unity", "amp", "cloud", "reactnative"] }, - "destination": { - "Config": { - "accountId": "successful_identify_transformation", - "clientId": "504300cd-76b2-a7l4-bhle-90a07420nx73", - "clientSecret": "3l3gJpzRsZagD6gu7tnTeKXz0bomLGnd", - "trackAnonymousEvents": false, - "createIfNotExist": true, - "rudderEventsMapping": [ - { - "event": "acq_signup_completed", - "marketoActivityId": "100026" - }, - { - "event": "act_createwebinarform_submit", - "marketoActivityId": "100025" - }, - { - "event": "act_presentation_style", - "marketoActivityId": "100025" - }, - { - "event": "act_webinar_view", - "marketoActivityId": "100025" - }, - { - "event": "act_webinar_join", - "marketoActivityId": "100025" - }, - { - "event": "act_presentation_addteammember", - "marketoActivityId": "100025" - }, - { - "event": "act_engagement_discussions_savediscussion", - "marketoActivityId": "100025" - }, - { - "event": "act_engagement_networking_savetime", - "marketoActivityId": "100025" - } - ] - }, - "destinationDefinition": { - "config": { - "destConfig": { - "defaultConfig": [ - "accountId", - "clientId", - "clientSecret", - "trackAnonymousEvents", - "rudderEventsMapping", - "customActivityPropertyMap", - "leadTraitMapping" - ] - }, - "secretKeys": [ - "clientSecret" - ], - "excludeKeys": [], - "includeKeys": [], - "routerTransform": true, - "supportedSourceTypes": [ - "android", - "ios", - "web", - "unity", - "amp", - "cloud", - "reactnative" - ] - }, - "responseRules": { - "responseType": "JSON", - "rules": { - "retryable": [ - { - "success": "false", - "errors.0.code": 600 - }, - { - "success": "false", - "errors.0.code": 601 - }, - { - "success": "false", - "errors.0.code": 602 - }, - { - "success": "false", - "errors.0.code": 604 - }, - { - "success": "false", - "errors.0.code": 606 - }, - { - "success": "false", - "errors.0.code": 607 - }, - { - "success": "false", - "errors.0.code": 608 - }, - { - "success": "false", - "errors.0.code": 611 - } - ], - "abortable": [ - { - "success": "false", - "errors.0.code": 603 - }, - { - "success": "false", - "errors.0.code": 605 - }, - { - "success": "false", - "errors.0.code": 609 - }, - { - "success": "false", - "errors.0.code": 610 - } - ] - } - }, - "id": "1aIXqM806xAVm92nx07YwKbRrO9", - "name": "MARKETO", - "displayName": "Marketo", - "createdAt": "2020-04-09T09:24:31.794Z", - "updatedAt": "2021-01-11T11:03:28.103Z" - }, - "secretConfig": {}, - "ID": "1mMy5cqbtfuaKZv1IhVQKnBdVke", - "name": "Marketo", - "enabled": true, - "workspaceId": "1TSN08muJTZwH8iCDmnnRt1pmMd", - "deleted": false, - "createdAt": "2022-02-10T08:39:32.005Z", - "updatedAt": "2022-09-03T16:22:31.374Z", - "transformations": [], - "isConnectionEnabled": true, - "isProcessorEnabled": true + "responseRules": { + "responseType": "JSON", + "rules": { + "retryable": [ + { + "success": "false", + "errors.0.code": 600 + }, + { + "success": "false", + "errors.0.code": 601 + }, + { + "success": "false", + "errors.0.code": 602 + }, + { + "success": "false", + "errors.0.code": 604 + }, + { + "success": "false", + "errors.0.code": 606 + }, + { + "success": "false", + "errors.0.code": 607 + }, + { + "success": "false", + "errors.0.code": 608 + }, + { + "success": "false", + "errors.0.code": 611 + } + ], + "abortable": [ + { + "success": "false", + "errors.0.code": 603 + }, + { + "success": "false", + "errors.0.code": 605 + }, + { + "success": "false", + "errors.0.code": 609 + }, + { + "success": "false", + "errors.0.code": 610 + } + ] + } }, - "metadata": { - "jobId": 5 - } + "id": "1aIXqM806xAVm92nx07YwKbRrO9", + "name": "MARKETO", + "displayName": "Marketo", + "createdAt": "2020-04-09T09:24:31.794Z", + "updatedAt": "2021-01-11T11:03:28.103Z" + }, + "secretConfig": {}, + "ID": "1mMy5cqbtfuaKZv1IhVQKnBdVke", + "name": "Marketo", + "enabled": true, + "workspaceId": "1TSN08muJTZwH8iCDmnnRt1pmMd", + "deleted": false, + "createdAt": "2022-02-10T08:39:32.005Z", + "updatedAt": "2022-09-03T16:22:31.374Z", + "transformations": [], + "isConnectionEnabled": true, + "isProcessorEnabled": true + }, + "metadata": { + "jobId": 4 + } + }, + { + "message": { + "type": "identify", + "sentAt": "2022-09-19T10:34:02.002Z", + "userId": "e17c5a5e-5e2f-430b-b497-fe3f1ea3a704", + "channel": "web", + "context": { + "os": { + "name": "", + "version": "" + }, + "app": { + "name": "RudderLabs JavaScript SDK", + "build": "1.0.0", + "version": "2.12.1", + "namespace": "com.rudderlabs.javascript" + }, + "page": { + "url": "https://accounts.app.t2.broken.com/home", + "path": "/home", + "title": "Home", + "search": "", + "tab_url": "https://accounts.app.t2.broken.com/home", + "referrer": "https://ts50-cvii.core.broken.org/", + "initial_referrer": "https://ts50-cvii.core.broken.org/", + "referring_domain": "ts50-cvii.core.broken.org", + "initial_referring_domain": "ts50-cvii.core.broken.org" + }, + "locale": "en-IN", + "screen": { + "width": 1728, + "height": 1117, + "density": 2, + "innerWidth": 1728, + "innerHeight": 969 + }, + "traits": { + "name": "AM", + "email": "0c7b8b80-9c43-4f8e-b2d2-5e2448a25040@j.mail", + "lastName": "M", + "firstName": "A", + "accountName": "MACDEV", + "billingName": "g g", + "companyName": "macDev", + "currentTier": "Webinar Pro 250", + "billingCycle": "Annually", + "lastBillingDate": "2022-06-29T09:40:42.000Z", + "nextBillingDate": "2023-09-09T04:00:00.000Z", + "subscriptionType": "Webinar Pro 250", + "subscriptionStatus": "ACTIVE", + "lastWebinarEventDate": "2022-09-15T20:00:00.000Z", + "nextWebinarEventDate": "2022-09-16T06:15:00.000Z" + }, + "library": { + "name": "RudderLabs JavaScript SDK", + "version": "2.12.1" + }, + "campaign": {}, + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36" + }, + "rudderId": "73dc83ef-587f-4077-90f3-c36083e64019", + "messageId": "1663583642000200-e3f31c4c-6361-4f99-b643-7755303a6007", + "timestamp": "2022-09-19T10:34:02.954Z", + "receivedAt": "2022-09-19T10:34:02.956Z", + "request_ip": "11.105.44.120", + "anonymousId": "0c7b8b80-9c43-4f8e-b2d2-5e2448a25040", + "integrations": { + "All": true + }, + "originalTimestamp": "2022-09-19T10:34:02.000Z" + }, + "destination": { + "Config": { + "accountId": "successful_identify_transformation", + "clientId": "504300cd-76b2-a7l4-bhle-90a07420nx73", + "clientSecret": "3l3gJpzRsZagD6gu7tnTeKXz0bomLGnd", + "trackAnonymousEvents": false, + "createIfNotExist": true, + "rudderEventsMapping": [ + { + "event": "acq_signup_completed", + "marketoActivityId": "100026" + }, + { + "event": "act_createwebinarform_submit", + "marketoActivityId": "100025" + }, + { + "event": "act_presentation_style", + "marketoActivityId": "100025" + }, + { + "event": "act_webinar_view", + "marketoActivityId": "100025" + }, + { + "event": "act_webinar_join", + "marketoActivityId": "100025" + }, + { + "event": "act_presentation_addteammember", + "marketoActivityId": "100025" + }, + { + "event": "act_engagement_discussions_savediscussion", + "marketoActivityId": "100025" + }, + { + "event": "act_engagement_networking_savetime", + "marketoActivityId": "100025" + } + ] + }, + "destinationDefinition": { + "config": { + "destConfig": { + "defaultConfig": [ + "accountId", + "clientId", + "clientSecret", + "trackAnonymousEvents", + "rudderEventsMapping", + "customActivityPropertyMap", + "leadTraitMapping" + ] + }, + "secretKeys": ["clientSecret"], + "excludeKeys": [], + "includeKeys": [], + "routerTransform": true, + "supportedSourceTypes": ["android", "ios", "web", "unity", "amp", "cloud", "reactnative"] + }, + "responseRules": { + "responseType": "JSON", + "rules": { + "retryable": [ + { + "success": "false", + "errors.0.code": 600 + }, + { + "success": "false", + "errors.0.code": 601 + }, + { + "success": "false", + "errors.0.code": 602 + }, + { + "success": "false", + "errors.0.code": 604 + }, + { + "success": "false", + "errors.0.code": 606 + }, + { + "success": "false", + "errors.0.code": 607 + }, + { + "success": "false", + "errors.0.code": 608 + }, + { + "success": "false", + "errors.0.code": 611 + } + ], + "abortable": [ + { + "success": "false", + "errors.0.code": 603 + }, + { + "success": "false", + "errors.0.code": 605 + }, + { + "success": "false", + "errors.0.code": 609 + }, + { + "success": "false", + "errors.0.code": 610 + } + ] + } + }, + "id": "1aIXqM806xAVm92nx07YwKbRrO9", + "name": "MARKETO", + "displayName": "Marketo", + "createdAt": "2020-04-09T09:24:31.794Z", + "updatedAt": "2021-01-11T11:03:28.103Z" + }, + "secretConfig": {}, + "ID": "1mMy5cqbtfuaKZv1IhVQKnBdVke", + "name": "Marketo", + "enabled": true, + "workspaceId": "1TSN08muJTZwH8iCDmnnRt1pmMd", + "deleted": false, + "createdAt": "2022-02-10T08:39:32.005Z", + "updatedAt": "2022-09-03T16:22:31.374Z", + "transformations": [], + "isConnectionEnabled": true, + "isProcessorEnabled": true + }, + "metadata": { + "jobId": 5 } -] \ No newline at end of file + } +] diff --git a/test/__tests__/data/marketo_router_metadata_input.json b/test/__tests__/data/marketo_router_metadata_input.json index 0c481c38ea..b1e3a26f69 100644 --- a/test/__tests__/data/marketo_router_metadata_input.json +++ b/test/__tests__/data/marketo_router_metadata_input.json @@ -87,21 +87,11 @@ "leadTraitMapping" ] }, - "secretKeys": [ - "clientSecret" - ], + "secretKeys": ["clientSecret"], "excludeKeys": [], "includeKeys": [], "routerTransform": true, - "supportedSourceTypes": [ - "android", - "ios", - "web", - "unity", - "amp", - "cloud", - "reactnative" - ] + "supportedSourceTypes": ["android", "ios", "web", "unity", "amp", "cloud", "reactnative"] }, "responseRules": { "responseType": "JSON", @@ -170,4 +160,4 @@ "isConnectionEnabled": true, "isProcessorEnabled": true } -} \ No newline at end of file +} diff --git a/test/__tests__/data/marketo_router_output.json b/test/__tests__/data/marketo_router_output.json index 35c0d30a8e..c4b59b396d 100644 --- a/test/__tests__/data/marketo_router_output.json +++ b/test/__tests__/data/marketo_router_output.json @@ -82,21 +82,11 @@ "leadTraitMapping" ] }, - "secretKeys": [ - "clientSecret" - ], + "secretKeys": ["clientSecret"], "excludeKeys": [], "includeKeys": [], "routerTransform": true, - "supportedSourceTypes": [ - "android", - "ios", - "web", - "unity", - "amp", - "cloud", - "reactnative" - ] + "supportedSourceTypes": ["android", "ios", "web", "unity", "amp", "cloud", "reactnative"] }, "responseRules": { "responseType": "JSON", @@ -249,21 +239,11 @@ "leadTraitMapping" ] }, - "secretKeys": [ - "clientSecret" - ], + "secretKeys": ["clientSecret"], "excludeKeys": [], "includeKeys": [], "routerTransform": true, - "supportedSourceTypes": [ - "android", - "ios", - "web", - "unity", - "amp", - "cloud", - "reactnative" - ] + "supportedSourceTypes": ["android", "ios", "web", "unity", "amp", "cloud", "reactnative"] }, "responseRules": { "responseType": "JSON", @@ -401,21 +381,11 @@ "leadTraitMapping" ] }, - "secretKeys": [ - "clientSecret" - ], + "secretKeys": ["clientSecret"], "excludeKeys": [], "includeKeys": [], "routerTransform": true, - "supportedSourceTypes": [ - "android", - "ios", - "web", - "unity", - "amp", - "cloud", - "reactnative" - ] + "supportedSourceTypes": ["android", "ios", "web", "unity", "amp", "cloud", "reactnative"] }, "responseRules": { "responseType": "JSON", @@ -557,21 +527,11 @@ "leadTraitMapping" ] }, - "secretKeys": [ - "clientSecret" - ], + "secretKeys": ["clientSecret"], "excludeKeys": [], "includeKeys": [], "routerTransform": true, - "supportedSourceTypes": [ - "android", - "ios", - "web", - "unity", - "amp", - "cloud", - "reactnative" - ] + "supportedSourceTypes": ["android", "ios", "web", "unity", "amp", "cloud", "reactnative"] }, "responseRules": { "responseType": "JSON", @@ -747,21 +707,11 @@ "leadTraitMapping" ] }, - "secretKeys": [ - "clientSecret" - ], + "secretKeys": ["clientSecret"], "excludeKeys": [], "includeKeys": [], "routerTransform": true, - "supportedSourceTypes": [ - "android", - "ios", - "web", - "unity", - "amp", - "cloud", - "reactnative" - ] + "supportedSourceTypes": ["android", "ios", "web", "unity", "amp", "cloud", "reactnative"] }, "responseRules": { "responseType": "JSON", @@ -839,4 +789,4 @@ "isProcessorEnabled": true } } -] \ No newline at end of file +] diff --git a/test/integrations/destinations/webhook/processor/data.ts b/test/integrations/destinations/webhook/processor/data.ts index 8f37a26da2..dbe83a79a5 100644 --- a/test/integrations/destinations/webhook/processor/data.ts +++ b/test/integrations/destinations/webhook/processor/data.ts @@ -1,2761 +1,2761 @@ export const data = [ - { - "name": "webhook", - "description": "Test 0", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "context": { - "device": { - "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", - "manufacturer": "Xiaomi", - "model": "Redmi 6", - "name": "xiaomi" - }, - "network": { - "carrier": "Banglalink" - }, - "os": { - "name": "android", - "version": "8.1.0" - }, - "traits": { - "address": { - "city": "Dhaka", - "country": "Bangladesh" - }, - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" - } - }, - "event": "spin_result", - "integrations": { - "All": true - }, - "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", - "properties": { - "additional_bet_index": 0, - "battle_id": "N/A", - "bet_amount": 9, - "bet_level": 1, - "bet_multiplier": 1, - "coin_balance": 9466052, - "current_module_name": "CasinoGameModule", - "days_in_game": 0, - "extra_param": "N/A", - "fb_profile": "0", - "featureGameType": "N/A", - "game_fps": 30, - "game_id": "fireEagleBase", - "game_name": "FireEagleSlots", - "gem_balance": 0, - "graphicsQuality": "HD", - "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", - "internetReachability": "ReachableViaLocalAreaNetwork", - "isLowEndDevice": "False", - "is_auto_spin": "False", - "is_turbo": "False", - "isf": "False", - "ishighroller": "False", - "jackpot_win_amount": 90, - "jackpot_win_type": "Silver", - "level": 6, - "lifetime_gem_balance": 0, - "no_of_spin": 1, - "player_total_battles": 0, - "player_total_shields": 0, - "start_date": "2019-08-01", - "total_payments": 0, - "tournament_id": "T1561970819", - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "versionSessionCount": 2, - "win_amount": 0 - }, - "timestamp": "2019-09-01T15:46:51.693229+05:30", - "type": "track", - "user_properties": { - "coin_balance": 9466052, - "current_module_name": "CasinoGameModule", - "fb_profile": "0", - "game_fps": 30, - "game_name": "FireEagleSlots", - "gem_balance": 0, - "graphicsQuality": "HD", - "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", - "internetReachability": "ReachableViaLocalAreaNetwork", - "isLowEndDevice": false, - "level": 6, - "lifetime_gem_balance": 0, - "player_total_battles": 0, - "player_total_shields": 0, - "start_date": "2019-08-01", - "total_payments": 0, - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "versionSessionCount": 2 - } - }, - "destination": { - "Config": { - "webhookUrl": "http://6b0e6a60.ngrok.io", - "headers": [ - { - "from": "", - "to": "" - }, - { - "from": "test2", - "to": "value2" - } - ] - }, - "DestinationDefinition": { - "Config": { - "cdkV2Enabled": true - } - } - }, - "metadata": { - "destinationId": "destId", - "workspaceId": "wspId" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "body": { - "JSON": { - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "context": { - "device": { - "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", - "manufacturer": "Xiaomi", - "model": "Redmi 6", - "name": "xiaomi" - }, - "network": { - "carrier": "Banglalink" - }, - "os": { - "name": "android", - "version": "8.1.0" - }, - "traits": { - "address": { - "city": "Dhaka", - "country": "Bangladesh" - }, - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" - } - }, - "event": "spin_result", - "integrations": { - "All": true - }, - "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", - "properties": { - "additional_bet_index": 0, - "battle_id": "N/A", - "bet_amount": 9, - "bet_level": 1, - "bet_multiplier": 1, - "coin_balance": 9466052, - "current_module_name": "CasinoGameModule", - "days_in_game": 0, - "extra_param": "N/A", - "fb_profile": "0", - "featureGameType": "N/A", - "game_fps": 30, - "game_id": "fireEagleBase", - "game_name": "FireEagleSlots", - "gem_balance": 0, - "graphicsQuality": "HD", - "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", - "internetReachability": "ReachableViaLocalAreaNetwork", - "isLowEndDevice": "False", - "is_auto_spin": "False", - "is_turbo": "False", - "isf": "False", - "ishighroller": "False", - "jackpot_win_amount": 90, - "jackpot_win_type": "Silver", - "level": 6, - "lifetime_gem_balance": 0, - "no_of_spin": 1, - "player_total_battles": 0, - "player_total_shields": 0, - "start_date": "2019-08-01", - "total_payments": 0, - "tournament_id": "T1561970819", - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "versionSessionCount": 2, - "win_amount": 0 - }, - "timestamp": "2019-09-01T15:46:51.693229+05:30", - "type": "track", - "user_properties": { - "coin_balance": 9466052, - "current_module_name": "CasinoGameModule", - "fb_profile": "0", - "game_fps": 30, - "game_name": "FireEagleSlots", - "gem_balance": 0, - "graphicsQuality": "HD", - "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", - "internetReachability": "ReachableViaLocalAreaNetwork", - "isLowEndDevice": false, - "level": 6, - "lifetime_gem_balance": 0, - "player_total_battles": 0, - "player_total_shields": 0, - "start_date": "2019-08-01", - "total_payments": 0, - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "versionSessionCount": 2 - } - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "version": "1", - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "type": "REST", - "method": "POST", - "endpoint": "http://6b0e6a60.ngrok.io", - "headers": { - "content-type": "application/json", - "test2": "value2" - }, - "params": {}, - "files": {} - }, - "metadata": { - "destinationId": "destId", - "workspaceId": "wspId" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "webhook", - "description": "Test 1", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "context": { - "device": { - "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", - "manufacturer": "Xiaomi", - "model": "Redmi 6", - "name": "xiaomi" - }, - "network": { - "carrier": "Banglalink" - }, - "os": { - "name": "android", - "version": "8.1.0" - }, - "traits": { - "address": { - "city": "Dhaka", - "country": "Bangladesh" - }, - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" - } - }, - "event": "spin_result", - "integrations": { - "All": true - }, - "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", - "properties": { - "additional_bet_index": 0, - "battle_id": "N/A", - "bet_amount": 9, - "bet_level": 1, - "bet_multiplier": 1, - "coin_balance": 9466052, - "current_module_name": "CasinoGameModule", - "days_in_game": 0, - "extra_param": "N/A", - "fb_profile": "0", - "featureGameType": "N/A", - "game_fps": 30, - "game_id": "fireEagleBase", - "game_name": "FireEagleSlots", - "gem_balance": 0, - "graphicsQuality": "HD", - "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", - "internetReachability": "ReachableViaLocalAreaNetwork", - "isLowEndDevice": "False", - "is_auto_spin": "False", - "is_turbo": "False", - "isf": "False", - "ishighroller": "False", - "jackpot_win_amount": 90, - "jackpot_win_type": "Silver", - "level": 6, - "lifetime_gem_balance": 0, - "no_of_spin": 1, - "player_total_battles": 0, - "player_total_shields": 0, - "start_date": "2019-08-01", - "total_payments": 0, - "tournament_id": "T1561970819", - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "versionSessionCount": 2, - "win_amount": 0 - }, - "timestamp": "2019-09-01T15:46:51.693229+05:30", - "type": "track", - "user_properties": { - "coin_balance": 9466052, - "current_module_name": "CasinoGameModule", - "fb_profile": "0", - "game_fps": 30, - "game_name": "FireEagleSlots", - "gem_balance": 0, - "graphicsQuality": "HD", - "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", - "internetReachability": "ReachableViaLocalAreaNetwork", - "isLowEndDevice": false, - "level": 6, - "lifetime_gem_balance": 0, - "player_total_battles": 0, - "player_total_shields": 0, - "start_date": "2019-08-01", - "total_payments": 0, - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "versionSessionCount": 2 - } - }, - "destination": { - "Config": { - "webhookUrl": "https://6b0e6a60.ngrok.io/n" - }, - "DestinationDefinition": { - "Config": { - "cdkV2Enabled": true - } - } - }, - "metadata": { - "destinationId": "destId", - "workspaceId": "wspId" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "body": { - "JSON": { - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "context": { - "device": { - "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", - "manufacturer": "Xiaomi", - "model": "Redmi 6", - "name": "xiaomi" - }, - "network": { - "carrier": "Banglalink" - }, - "os": { - "name": "android", - "version": "8.1.0" - }, - "traits": { - "address": { - "city": "Dhaka", - "country": "Bangladesh" - }, - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" - } - }, - "event": "spin_result", - "integrations": { - "All": true - }, - "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", - "properties": { - "additional_bet_index": 0, - "battle_id": "N/A", - "bet_amount": 9, - "bet_level": 1, - "bet_multiplier": 1, - "coin_balance": 9466052, - "current_module_name": "CasinoGameModule", - "days_in_game": 0, - "extra_param": "N/A", - "fb_profile": "0", - "featureGameType": "N/A", - "game_fps": 30, - "game_id": "fireEagleBase", - "game_name": "FireEagleSlots", - "gem_balance": 0, - "graphicsQuality": "HD", - "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", - "internetReachability": "ReachableViaLocalAreaNetwork", - "isLowEndDevice": "False", - "is_auto_spin": "False", - "is_turbo": "False", - "isf": "False", - "ishighroller": "False", - "jackpot_win_amount": 90, - "jackpot_win_type": "Silver", - "level": 6, - "lifetime_gem_balance": 0, - "no_of_spin": 1, - "player_total_battles": 0, - "player_total_shields": 0, - "start_date": "2019-08-01", - "total_payments": 0, - "tournament_id": "T1561970819", - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "versionSessionCount": 2, - "win_amount": 0 - }, - "timestamp": "2019-09-01T15:46:51.693229+05:30", - "type": "track", - "user_properties": { - "coin_balance": 9466052, - "current_module_name": "CasinoGameModule", - "fb_profile": "0", - "game_fps": 30, - "game_name": "FireEagleSlots", - "gem_balance": 0, - "graphicsQuality": "HD", - "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", - "internetReachability": "ReachableViaLocalAreaNetwork", - "isLowEndDevice": false, - "level": 6, - "lifetime_gem_balance": 0, - "player_total_battles": 0, - "player_total_shields": 0, - "start_date": "2019-08-01", - "total_payments": 0, - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "versionSessionCount": 2 - } - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "version": "1", - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "type": "REST", - "method": "POST", - "endpoint": "https://6b0e6a60.ngrok.io/n", - "headers": { - "content-type": "application/json" - }, - "params": {}, - "files": {} - }, - "metadata": { - "destinationId": "destId", - "workspaceId": "wspId" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "webhook", - "description": "Test 2", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "context": { - "device": { - "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", - "manufacturer": "Xiaomi", - "model": "Redmi 6", - "name": "xiaomi" - }, - "network": { - "carrier": "Banglalink" - }, - "os": { - "name": "android", - "version": "8.1.0" - }, - "traits": { - "address": { - "city": "Dhaka", - "country": "Bangladesh" - }, - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" - } - }, - "event": "spin_result", - "integrations": { - "All": true - }, - "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", - "properties": { - "additional_bet_index": 0, - "battle_id": "N/A", - "bet_amount": 9, - "bet_level": 1, - "bet_multiplier": 1, - "coin_balance": 9466052, - "current_module_name": "CasinoGameModule", - "days_in_game": 0, - "extra_param": "N/A", - "fb_profile": "0", - "featureGameType": "N/A", - "game_fps": 30, - "game_id": "fireEagleBase", - "game_name": "FireEagleSlots", - "gem_balance": 0, - "graphicsQuality": "HD", - "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", - "internetReachability": "ReachableViaLocalAreaNetwork", - "isLowEndDevice": "False", - "is_auto_spin": "False", - "is_turbo": "False", - "isf": "False", - "ishighroller": "False", - "jackpot_win_amount": 90, - "jackpot_win_type": "Silver", - "level": 6, - "lifetime_gem_balance": 0, - "no_of_spin": 1, - "player_total_battles": 0, - "player_total_shields": 0, - "start_date": "2019-08-01", - "total_payments": 0, - "tournament_id": "T1561970819", - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "versionSessionCount": 2, - "win_amount": 0 - }, - "timestamp": "2019-09-01T15:46:51.693229+05:30", - "type": "track", - "user_properties": { - "coin_balance": 9466052, - "current_module_name": "CasinoGameModule", - "fb_profile": "0", - "game_fps": 30, - "game_name": "FireEagleSlots", - "gem_balance": 0, - "graphicsQuality": "HD", - "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", - "internetReachability": "ReachableViaLocalAreaNetwork", - "isLowEndDevice": false, - "level": 6, - "lifetime_gem_balance": 0, - "player_total_battles": 0, - "player_total_shields": 0, - "start_date": "2019-08-01", - "total_payments": 0, - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "versionSessionCount": 2 - } - }, - "destination": { - "Config": { - "webhookUrl": "https://6b0e6a60." - }, - "DestinationDefinition": { - "Config": { - "cdkV2Enabled": true - } - } - }, - "metadata": { - "destinationId": "destId", - "workspaceId": "wspId" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "body": { - "JSON": { - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "context": { - "device": { - "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", - "manufacturer": "Xiaomi", - "model": "Redmi 6", - "name": "xiaomi" - }, - "network": { - "carrier": "Banglalink" - }, - "os": { - "name": "android", - "version": "8.1.0" - }, - "traits": { - "address": { - "city": "Dhaka", - "country": "Bangladesh" - }, - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" - } - }, - "event": "spin_result", - "integrations": { - "All": true - }, - "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", - "properties": { - "additional_bet_index": 0, - "battle_id": "N/A", - "bet_amount": 9, - "bet_level": 1, - "bet_multiplier": 1, - "coin_balance": 9466052, - "current_module_name": "CasinoGameModule", - "days_in_game": 0, - "extra_param": "N/A", - "fb_profile": "0", - "featureGameType": "N/A", - "game_fps": 30, - "game_id": "fireEagleBase", - "game_name": "FireEagleSlots", - "gem_balance": 0, - "graphicsQuality": "HD", - "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", - "internetReachability": "ReachableViaLocalAreaNetwork", - "isLowEndDevice": "False", - "is_auto_spin": "False", - "is_turbo": "False", - "isf": "False", - "ishighroller": "False", - "jackpot_win_amount": 90, - "jackpot_win_type": "Silver", - "level": 6, - "lifetime_gem_balance": 0, - "no_of_spin": 1, - "player_total_battles": 0, - "player_total_shields": 0, - "start_date": "2019-08-01", - "total_payments": 0, - "tournament_id": "T1561970819", - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "versionSessionCount": 2, - "win_amount": 0 - }, - "timestamp": "2019-09-01T15:46:51.693229+05:30", - "type": "track", - "user_properties": { - "coin_balance": 9466052, - "current_module_name": "CasinoGameModule", - "fb_profile": "0", - "game_fps": 30, - "game_name": "FireEagleSlots", - "gem_balance": 0, - "graphicsQuality": "HD", - "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", - "internetReachability": "ReachableViaLocalAreaNetwork", - "isLowEndDevice": false, - "level": 6, - "lifetime_gem_balance": 0, - "player_total_battles": 0, - "player_total_shields": 0, - "start_date": "2019-08-01", - "total_payments": 0, - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "versionSessionCount": 2 - } - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "version": "1", - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "type": "REST", - "method": "POST", - "endpoint": "https://6b0e6a60.", - "headers": { - "content-type": "application/json" - }, - "params": {}, - "files": {} - }, - "metadata": { - "destinationId": "destId", - "workspaceId": "wspId" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "webhook", - "description": "Test 3", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "context": { - "device": { - "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", - "manufacturer": "Xiaomi", - "model": "Redmi 6", - "name": "xiaomi" - }, - "network": { - "carrier": "Banglalink" - }, - "os": { - "name": "android", - "version": "8.1.0" - }, - "traits": { - "address": { - "city": "Dhaka", - "country": "Bangladesh" - }, - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" - } - }, - "event": "spin_result", - "integrations": { - "All": true - }, - "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", - "properties": { - "k1": "v1", - "k2": { - "k3": "c3", - "k4": { - "k5": "c5" - } - } - }, - "timestamp": "2019-09-01T15:46:51.693229+05:30", - "type": "track" - }, - "destination": { - "Config": { - "webhookUrl": "https://6b0e6a60.", - "webhookMethod": "GET", - "headers": [ - { - "from": "X-customHeader", - "to": "customHeaderVal" - } - ] - }, - "DestinationDefinition": { - "Config": { - "cdkV2Enabled": true - } - } - }, - "metadata": { - "destinationId": "destId", - "workspaceId": "wspId" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "body": { - "JSON": {}, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "version": "1", - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "type": "REST", - "method": "GET", - "endpoint": "https://6b0e6a60.", - "headers": { - "x-customheader": "customHeaderVal" - }, - "params": { - "k1": "v1", - "k2.k3": "c3", - "k2.k4.k5": "c5" - }, - "files": {} - }, - "metadata": { - "destinationId": "destId", - "workspaceId": "wspId" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "webhook", - "description": "Test 4", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "context": { - "device": { - "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", - "manufacturer": "Xiaomi", - "model": "Redmi 6", - "name": "xiaomi" - }, - "network": { - "carrier": "Banglalink" - }, - "os": { - "name": "android", - "version": "8.1.0" - }, - "traits": { - "address": { - "city": "Dhaka", - "country": "Bangladesh" - }, - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" - } - }, - "event": "spin_result", - "integrations": { - "All": true - }, - "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", - "properties": { - "k1": "v1", - "k2": { - "k3": "c3", - "k4": { - "k5": "c5" - } - } - }, - "timestamp": "2019-09-01T15:46:51.693229+05:30", - "type": "track" - }, - "destination": { - "Config": { - "webhookUrl": "https://6b0e6a60.", - "webhookMethod": "GET" - }, - "DestinationDefinition": { - "Config": { - "cdkV2Enabled": true - } - } - }, - "metadata": { - "destinationId": "destId", - "workspaceId": "wspId" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "body": { - "JSON": {}, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "version": "1", - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "type": "REST", - "method": "GET", - "endpoint": "https://6b0e6a60.", - "headers": {}, - "params": { - "k1": "v1", - "k2.k3": "c3", - "k2.k4.k5": "c5" - }, - "files": {} - }, - "metadata": { - "destinationId": "destId", - "workspaceId": "wspId" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "webhook", - "description": "Test 5", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "context": { - "device": { - "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", - "manufacturer": "Xiaomi", - "model": "Redmi 6", - "name": "xiaomi" - }, - "network": { - "carrier": "Banglalink" - }, - "os": { - "name": "android", - "version": "8.1.0" - }, - "traits": { - "address": { - "city": "Dhaka", - "country": "Bangladesh" - }, - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" - } - }, - "event": "spin_result", - "integrations": { - "All": true - }, - "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", - "properties": { - "additional_bet_index": 0, - "battle_id": "N/A", - "bet_amount": 9, - "bet_level": 1, - "bet_multiplier": 1, - "coin_balance": 9466052, - "current_module_name": "CasinoGameModule", - "days_in_game": 0, - "extra_param": "N/A", - "fb_profile": "0", - "featureGameType": "N/A", - "game_fps": 30, - "game_id": "fireEagleBase", - "game_name": "FireEagleSlots", - "gem_balance": 0, - "graphicsQuality": "HD", - "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", - "internetReachability": "ReachableViaLocalAreaNetwork", - "isLowEndDevice": "False", - "is_auto_spin": "False", - "is_turbo": "False", - "isf": "False", - "ishighroller": "False", - "jackpot_win_amount": 90, - "jackpot_win_type": "Silver", - "level": 6, - "lifetime_gem_balance": 0, - "no_of_spin": 1, - "player_total_battles": 0, - "player_total_shields": 0, - "start_date": "2019-08-01", - "total_payments": 0, - "tournament_id": "T1561970819", - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "versionSessionCount": 2, - "win_amount": 0 - }, - "timestamp": "2019-09-01T15:46:51.693229+05:30", - "type": "track", - "request_ip": "127.0.0.1" - }, - "destination": { - "Config": { - "webhookUrl": "http://6b0e6a60.ngrok.io", - "header": [ - { - "from": "test1", - "to": "value1" - }, - { - "from": "test2", - "to": "value2" - } - ] - }, - "DestinationDefinition": { - "Config": { - "cdkV2Enabled": true - } - } - }, - "metadata": { - "destinationId": "destId", - "workspaceId": "wspId" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "body": { - "JSON": { - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "context": { - "device": { - "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", - "manufacturer": "Xiaomi", - "model": "Redmi 6", - "name": "xiaomi" - }, - "network": { - "carrier": "Banglalink" - }, - "os": { - "name": "android", - "version": "8.1.0" - }, - "traits": { - "address": { - "city": "Dhaka", - "country": "Bangladesh" - }, - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" - }, - "ip": "127.0.0.1" - }, - "event": "spin_result", - "integrations": { - "All": true - }, - "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", - "properties": { - "additional_bet_index": 0, - "battle_id": "N/A", - "bet_amount": 9, - "bet_level": 1, - "bet_multiplier": 1, - "coin_balance": 9466052, - "current_module_name": "CasinoGameModule", - "days_in_game": 0, - "extra_param": "N/A", - "fb_profile": "0", - "featureGameType": "N/A", - "game_fps": 30, - "game_id": "fireEagleBase", - "game_name": "FireEagleSlots", - "gem_balance": 0, - "graphicsQuality": "HD", - "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", - "internetReachability": "ReachableViaLocalAreaNetwork", - "isLowEndDevice": "False", - "is_auto_spin": "False", - "is_turbo": "False", - "isf": "False", - "ishighroller": "False", - "jackpot_win_amount": 90, - "jackpot_win_type": "Silver", - "level": 6, - "lifetime_gem_balance": 0, - "no_of_spin": 1, - "player_total_battles": 0, - "player_total_shields": 0, - "start_date": "2019-08-01", - "total_payments": 0, - "tournament_id": "T1561970819", - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "versionSessionCount": 2, - "win_amount": 0 - }, - "timestamp": "2019-09-01T15:46:51.693229+05:30", - "type": "track", - "request_ip": "127.0.0.1" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "version": "1", - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "type": "REST", - "method": "POST", - "endpoint": "http://6b0e6a60.ngrok.io", - "headers": { - "content-type": "application/json" - }, - "params": {}, - "files": {} - }, - "metadata": { - "destinationId": "destId", - "workspaceId": "wspId" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "webhook", - "description": "Test 6", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "context": { - "device": { - "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", - "manufacturer": "Xiaomi", - "model": "Redmi 6", - "name": "xiaomi" - }, - "network": { - "carrier": "Banglalink" - }, - "os": { - "name": "android", - "version": "8.1.0" - }, - "traits": { - "address": { - "city": "Dhaka", - "country": "Bangladesh" - }, - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" - } - }, - "event": "spin_result", - "integrations": { - "All": true - }, - "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", - "properties": { - "additional_bet_index": 0, - "battle_id": "N/A", - "bet_amount": 9, - "bet_level": 1, - "bet_multiplier": 1, - "coin_balance": 9466052, - "current_module_name": "CasinoGameModule", - "days_in_game": 0, - "extra_param": "N/A", - "fb_profile": "0", - "featureGameType": "N/A", - "game_fps": 30, - "game_id": "fireEagleBase", - "game_name": "FireEagleSlots", - "gem_balance": 0, - "graphicsQuality": "HD", - "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", - "internetReachability": "ReachableViaLocalAreaNetwork", - "isLowEndDevice": "False", - "is_auto_spin": "False", - "is_turbo": "False", - "isf": "False", - "ishighroller": "False", - "jackpot_win_amount": 90, - "jackpot_win_type": "Silver", - "level": 6, - "lifetime_gem_balance": 0, - "no_of_spin": 1, - "player_total_battles": 0, - "player_total_shields": 0, - "start_date": "2019-08-01", - "total_payments": 0, - "tournament_id": "T1561970819", - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "versionSessionCount": 2, - "win_amount": 0 - }, - "timestamp": "2019-09-01T15:46:51.693229+05:30", - "type": "track", - "request_ip": "127.0.0.1" - }, - "destination": { - "Config": { - "webhookUrl": "http://6b0e6a60.ngrok.io", - "headers": [ - { - "from": "Content-Type", - "to": "application/xml" - }, - { - "from": "test2", - "to": "value2" - } - ] - }, - "DestinationDefinition": { - "Config": { - "cdkV2Enabled": true - } - } - }, - "metadata": { - "destinationId": "destId", - "workspaceId": "wspId" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "body": { - "JSON": { - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "context": { - "device": { - "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", - "manufacturer": "Xiaomi", - "model": "Redmi 6", - "name": "xiaomi" - }, - "network": { - "carrier": "Banglalink" - }, - "os": { - "name": "android", - "version": "8.1.0" - }, - "traits": { - "address": { - "city": "Dhaka", - "country": "Bangladesh" - }, - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" - }, - "ip": "127.0.0.1" - }, - "event": "spin_result", - "integrations": { - "All": true - }, - "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", - "properties": { - "additional_bet_index": 0, - "battle_id": "N/A", - "bet_amount": 9, - "bet_level": 1, - "bet_multiplier": 1, - "coin_balance": 9466052, - "current_module_name": "CasinoGameModule", - "days_in_game": 0, - "extra_param": "N/A", - "fb_profile": "0", - "featureGameType": "N/A", - "game_fps": 30, - "game_id": "fireEagleBase", - "game_name": "FireEagleSlots", - "gem_balance": 0, - "graphicsQuality": "HD", - "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", - "internetReachability": "ReachableViaLocalAreaNetwork", - "isLowEndDevice": "False", - "is_auto_spin": "False", - "is_turbo": "False", - "isf": "False", - "ishighroller": "False", - "jackpot_win_amount": 90, - "jackpot_win_type": "Silver", - "level": 6, - "lifetime_gem_balance": 0, - "no_of_spin": 1, - "player_total_battles": 0, - "player_total_shields": 0, - "start_date": "2019-08-01", - "total_payments": 0, - "tournament_id": "T1561970819", - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "versionSessionCount": 2, - "win_amount": 0 - }, - "timestamp": "2019-09-01T15:46:51.693229+05:30", - "type": "track", - "request_ip": "127.0.0.1" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "version": "1", - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "type": "REST", - "method": "POST", - "endpoint": "http://6b0e6a60.ngrok.io", - "headers": { - "content-type": "application/xml", - "test2": "value2" - }, - "params": {}, - "files": {} - }, - "metadata": { - "destinationId": "destId", - "workspaceId": "wspId" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "webhook", - "description": "Test 7", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "event": "spin_result", - "integrations": { - "All": true - }, - "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", - "properties": { - "additional_bet_index": 0, - "battle_id": "N/A", - "bet_amount": 9, - "bet_level": 1, - "bet_multiplier": 1, - "coin_balance": 9466052, - "current_module_name": "CasinoGameModule", - "days_in_game": 0, - "extra_param": "N/A", - "fb_profile": "0", - "featureGameType": "N/A", - "game_fps": 30, - "game_id": "fireEagleBase", - "game_name": "FireEagleSlots", - "gem_balance": 0, - "graphicsQuality": "HD", - "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", - "internetReachability": "ReachableViaLocalAreaNetwork", - "isLowEndDevice": "False", - "is_auto_spin": "False", - "is_turbo": "False", - "isf": "False", - "ishighroller": "False", - "jackpot_win_amount": 90, - "jackpot_win_type": "Silver", - "level": 6, - "lifetime_gem_balance": 0, - "no_of_spin": 1, - "player_total_battles": 0, - "player_total_shields": 0, - "start_date": "2019-08-01", - "total_payments": 0, - "tournament_id": "T1561970819", - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "versionSessionCount": 2, - "win_amount": 0 - }, - "timestamp": "2019-09-01T15:46:51.693229+05:30", - "type": "track" - }, - "destination": { - "Config": { - "webhookUrl": "http://6b0e6a60.ngrok.io", - "headers": [ - { - "from": "Content-Type", - "to": "application/xml" - }, - { - "from": "test2", - "to": "value2" - } - ] - }, - "DestinationDefinition": { - "Config": { - "cdkV2Enabled": true - } - } - }, - "metadata": { - "destinationId": "destId", - "workspaceId": "wspId" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "body": { - "JSON": { - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "event": "spin_result", - "integrations": { - "All": true - }, - "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", - "properties": { - "additional_bet_index": 0, - "battle_id": "N/A", - "bet_amount": 9, - "bet_level": 1, - "bet_multiplier": 1, - "coin_balance": 9466052, - "current_module_name": "CasinoGameModule", - "days_in_game": 0, - "extra_param": "N/A", - "fb_profile": "0", - "featureGameType": "N/A", - "game_fps": 30, - "game_id": "fireEagleBase", - "game_name": "FireEagleSlots", - "gem_balance": 0, - "graphicsQuality": "HD", - "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", - "internetReachability": "ReachableViaLocalAreaNetwork", - "isLowEndDevice": "False", - "is_auto_spin": "False", - "is_turbo": "False", - "isf": "False", - "ishighroller": "False", - "jackpot_win_amount": 90, - "jackpot_win_type": "Silver", - "level": 6, - "lifetime_gem_balance": 0, - "no_of_spin": 1, - "player_total_battles": 0, - "player_total_shields": 0, - "start_date": "2019-08-01", - "total_payments": 0, - "tournament_id": "T1561970819", - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "versionSessionCount": 2, - "win_amount": 0 - }, - "timestamp": "2019-09-01T15:46:51.693229+05:30", - "type": "track" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "version": "1", - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "type": "REST", - "method": "POST", - "endpoint": "http://6b0e6a60.ngrok.io", - "headers": { - "content-type": "application/xml", - "test2": "value2" - }, - "params": {}, - "files": {} - }, - "metadata": { - "destinationId": "destId", - "workspaceId": "wspId" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "webhook", - "description": "Test 8", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "context": { - "device": { - "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", - "manufacturer": "Xiaomi", - "model": "Redmi 6", - "name": "xiaomi" - }, - "network": { - "carrier": "Banglalink" - }, - "os": { - "name": "android", - "version": "8.1.0" - }, - "traits": { - "address": { - "city": "Dhaka", - "country": "Bangladesh" - }, - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" - } - }, - "event": "spin_result", - "integrations": { - "All": true - }, - "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", - "properties": { - "additional_bet_index": 0, - "battle_id": "N/A", - "featureGameType": "N/A", - "win_amount": 0 - }, - "timestamp": "2019-09-01T15:46:51.693229+05:30", - "type": "track", - "header": { - "dynamic_header_key_string": "dynamic_header_value_string", - "dynamic_header_key_num": 10, - "dynamic_header_key_object": { - "k1": "v1" - } - }, - "appendPath": "/product/search?string=value" - }, - "destination": { - "Config": { - "webhookUrl": "http://6b0e6a60.ngrok.io", - "headers": [ - { - "from": "", - "to": "" - }, - { - "from": "test2", - "to": "value2" - } - ] - }, - "DestinationDefinition": { - "Config": { - "cdkV2Enabled": true - } - } - }, - "metadata": { - "destinationId": "destId", - "workspaceId": "wspId" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "body": { - "JSON": { - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "context": { - "device": { - "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", - "manufacturer": "Xiaomi", - "model": "Redmi 6", - "name": "xiaomi" - }, - "network": { - "carrier": "Banglalink" - }, - "os": { - "name": "android", - "version": "8.1.0" - }, - "traits": { - "address": { - "city": "Dhaka", - "country": "Bangladesh" - }, - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" - } - }, - "event": "spin_result", - "integrations": { - "All": true - }, - "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", - "properties": { - "additional_bet_index": 0, - "battle_id": "N/A", - "featureGameType": "N/A", - "win_amount": 0 - }, - "timestamp": "2019-09-01T15:46:51.693229+05:30", - "type": "track" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "version": "1", - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "type": "REST", - "method": "POST", - "endpoint": "http://6b0e6a60.ngrok.io/product/search?string=value", - "headers": { - "content-type": "application/json", - "test2": "value2", - "dynamic_header_key_string": "dynamic_header_value_string" - }, - "params": {}, - "files": {} - }, - "metadata": { - "destinationId": "destId", - "workspaceId": "wspId" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "webhook", - "description": "Test 9", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "context": { - "device": { - "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", - "manufacturer": "Xiaomi", - "model": "Redmi 6", - "name": "xiaomi" - }, - "network": { - "carrier": "Banglalink" - }, - "os": { - "name": "android", - "version": "8.1.0" - }, - "traits": { - "address": { - "city": "Dhaka", - "country": "Bangladesh" - }, - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" - } - }, - "event": "spin_result", - "integrations": { - "All": true - }, - "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", - "properties": { - "additional_bet_index": 0, - "battle_id": "N/A", - "featureGameType": "N/A", - "win_amount": 0 - }, - "timestamp": "2019-09-01T15:46:51.693229+05:30", - "type": "track", - "fullPath": "https://www.google.com" - }, - "destination": { - "Config": { - "webhookUrl": "http://6b0e6a60.ngrok.io", - "headers": [ - { - "from": "", - "to": "" - }, - { - "from": "test2", - "to": "value2" - } - ] - }, - "DestinationDefinition": { - "Config": { - "cdkV2Enabled": true - } - } - }, - "metadata": { - "destinationId": "destId", - "workspaceId": "wspId" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "body": { - "JSON": { - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "context": { - "device": { - "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", - "manufacturer": "Xiaomi", - "model": "Redmi 6", - "name": "xiaomi" - }, - "network": { - "carrier": "Banglalink" - }, - "os": { - "name": "android", - "version": "8.1.0" - }, - "traits": { - "address": { - "city": "Dhaka", - "country": "Bangladesh" - }, - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" - } - }, - "event": "spin_result", - "integrations": { - "All": true - }, - "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", - "properties": { - "additional_bet_index": 0, - "battle_id": "N/A", - "featureGameType": "N/A", - "win_amount": 0 - }, - "timestamp": "2019-09-01T15:46:51.693229+05:30", - "type": "track" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "version": "1", - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google.com", - "headers": { - "content-type": "application/json", - "test2": "value2" - }, - "params": {}, - "files": {} - }, - "metadata": { - "destinationId": "destId", - "workspaceId": "wspId" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "webhook", - "description": "Test 10", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "context": { - "device": { - "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", - "manufacturer": "Xiaomi", - "model": "Redmi 6", - "name": "xiaomi" - }, - "network": { - "carrier": "Banglalink" - }, - "os": { - "name": "android", - "version": "8.1.0" - }, - "traits": { - "address": { - "city": "Dhaka", - "country": "Bangladesh" - }, - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" - } - }, - "event": "spin_result", - "integrations": { - "All": true - }, - "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", - "properties": { - "additional_bet_index": 0, - "battle_id": "N/A", - "featureGameType": "N/A", - "win_amount": 0 - }, - "timestamp": "2019-09-01T15:46:51.693229+05:30", - "type": "track", - "fullPath": "https://www.google.com/", - "appendPath": "?searchTerms=cats" - }, - "destination": { - "Config": { - "webhookUrl": "http://6b0e6a60.ngrok.io", - "headers": [ - { - "from": "", - "to": "" - }, - { - "from": "test2", - "to": "value2" - } - ] - }, - "DestinationDefinition": { - "Config": { - "cdkV2Enabled": true - } - } - }, - "metadata": { - "destinationId": "destId", - "workspaceId": "wspId" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "body": { - "JSON": { - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "context": { - "device": { - "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", - "manufacturer": "Xiaomi", - "model": "Redmi 6", - "name": "xiaomi" - }, - "network": { - "carrier": "Banglalink" - }, - "os": { - "name": "android", - "version": "8.1.0" - }, - "traits": { - "address": { - "city": "Dhaka", - "country": "Bangladesh" - }, - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" - } - }, - "event": "spin_result", - "integrations": { - "All": true - }, - "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", - "properties": { - "additional_bet_index": 0, - "battle_id": "N/A", - "featureGameType": "N/A", - "win_amount": 0 - }, - "timestamp": "2019-09-01T15:46:51.693229+05:30", - "type": "track" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "version": "1", - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "type": "REST", - "method": "POST", - "endpoint": "https://www.google.com/?searchTerms=cats", - "headers": { - "content-type": "application/json", - "test2": "value2" - }, - "params": {}, - "files": {} - }, - "metadata": { - "destinationId": "destId", - "workspaceId": "wspId" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "webhook", - "description": "Test 11", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "context": { - "device": { - "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", - "manufacturer": "Xiaomi", - "model": "Redmi 6", - "name": "xiaomi" - }, - "network": { - "carrier": "Banglalink" - }, - "os": { - "name": "android", - "version": "8.1.0" - }, - "traits": { - "address": { - "city": "Dhaka", - "country": "Bangladesh" - }, - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" - } - }, - "event": "spin_result", - "integrations": { - "All": true - }, - "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", - "properties": { - "additional_bet_index": 0, - "battle_id": "N/A", - "featureGameType": "N/A", - "win_amount": 0 - }, - "timestamp": "2019-09-01T15:46:51.693229+05:30", - "type": "track", - "fullPath": "https://www.google.com/", - "appendPath": "?searchTerms=cats" - }, - "destination": { - "Config": { - "webhookUrl": "http://6b0e6a60.ngrok.io", - "webhookMethod": "PUT", - "headers": [ - { - "from": "", - "to": "" - }, - { - "from": "test2", - "to": "value2" - } - ] - }, - "DestinationDefinition": { - "Config": { - "cdkV2Enabled": true - } - } - }, - "metadata": { - "destinationId": "destId", - "workspaceId": "wspId" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "body": { - "JSON": { - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "context": { - "device": { - "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", - "manufacturer": "Xiaomi", - "model": "Redmi 6", - "name": "xiaomi" - }, - "network": { - "carrier": "Banglalink" - }, - "os": { - "name": "android", - "version": "8.1.0" - }, - "traits": { - "address": { - "city": "Dhaka", - "country": "Bangladesh" - }, - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" - } - }, - "event": "spin_result", - "integrations": { - "All": true - }, - "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", - "properties": { - "additional_bet_index": 0, - "battle_id": "N/A", - "featureGameType": "N/A", - "win_amount": 0 - }, - "timestamp": "2019-09-01T15:46:51.693229+05:30", - "type": "track" - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "version": "1", - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "type": "REST", - "method": "PUT", - "endpoint": "https://www.google.com/?searchTerms=cats", - "headers": { - "content-type": "application/json", - "test2": "value2" - }, - "params": {}, - "files": {} - }, - "metadata": { - "destinationId": "destId", - "workspaceId": "wspId" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "webhook", - "description": "Test 12", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "context": { - "device": { - "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", - "manufacturer": "Xiaomi", - "model": "Redmi 6", - "name": "xiaomi" - }, - "network": { - "carrier": "Banglalink" - }, - "os": { - "name": "android", - "version": "8.1.0" - }, - "traits": { - "address": { - "city": "Dhaka", - "country": "Bangladesh" - }, - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" - } - }, - "event": "spin_result", - "integrations": { - "All": true - }, - "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", - "properties": { - "additional_bet_index": 0, - "battle_id": "N/A", - "featureGameType": "N/A", - "win_amount": 0 - }, - "timestamp": "2019-09-01T15:46:51.693229+05:30", - "type": "track", - "fullPath": "https://www.google.com/", - "appendPath": "?searchTerms=cats" - }, - "destination": { - "Config": { - "webhookUrl": "http://6b0e6a60.ngrok.io", - "webhookMethod": "DELETE", - "headers": [ - { - "from": "", - "to": "" - }, - { - "from": "test2", - "to": "value2" - } - ] - }, - "DestinationDefinition": { - "Config": { - "cdkV2Enabled": true - } - } - }, - "metadata": { - "destinationId": "destId", - "workspaceId": "wspId" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "body": { - "JSON": {}, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "version": "1", - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "type": "REST", - "method": "DELETE", - "endpoint": "https://www.google.com/?searchTerms=cats", - "headers": { - "test2": "value2" - }, - "params": { - "additional_bet_index": 0, - "battle_id": "N/A", - "featureGameType": "N/A", - "win_amount": 0 - }, - "files": {} - }, - "metadata": { - "destinationId": "destId", - "workspaceId": "wspId" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "webhook", - "description": "Test 13", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "context": { - "device": { - "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", - "manufacturer": "Xiaomi", - "model": "Redmi 6", - "name": "xiaomi" - }, - "network": { - "carrier": "Banglalink" - }, - "os": { - "name": "android", - "version": "8.1.0" - }, - "traits": { - "address": { - "city": "Dhaka", - "country": "Bangladesh" - }, - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" - } - }, - "event": "spin_result", - "integrations": { - "All": true - }, - "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", - "properties": { - "additional_bet_index": 0, - "battle_id": "N/A", - "bet_amount": 9, - "bet_level": 1, - "bet_multiplier": 1, - "coin_balance": 9466052, - "current_module_name": "CasinoGameModule", - "days_in_game": 0, - "extra_param": "N/A", - "fb_profile": "0", - "featureGameType": "N/A", - "game_fps": 30, - "game_id": "fireEagleBase", - "game_name": "FireEagleSlots", - "gem_balance": 0, - "graphicsQuality": "HD", - "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", - "internetReachability": "ReachableViaLocalAreaNetwork", - "isLowEndDevice": "False", - "is_auto_spin": "False", - "is_turbo": "False", - "isf": "False", - "ishighroller": "False", - "jackpot_win_amount": 90, - "jackpot_win_type": "Silver", - "level": 6, - "lifetime_gem_balance": 0, - "no_of_spin": 1, - "player_total_battles": 0, - "player_total_shields": 0, - "start_date": "2019-08-01", - "total_payments": 0, - "tournament_id": "T1561970819", - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "versionSessionCount": 2, - "win_amount": 0 - }, - "timestamp": "2019-09-01T15:46:51.693229+05:30", - "type": "track", - "user_properties": { - "coin_balance": 9466052, - "current_module_name": "CasinoGameModule", - "fb_profile": "0", - "game_fps": 30, - "game_name": "FireEagleSlots", - "gem_balance": 0, - "graphicsQuality": "HD", - "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", - "internetReachability": "ReachableViaLocalAreaNetwork", - "isLowEndDevice": false, - "level": 6, - "lifetime_gem_balance": 0, - "player_total_battles": 0, - "player_total_shields": 0, - "start_date": "2019-08-01", - "total_payments": 0, - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "versionSessionCount": 2 - } - }, - "destination": { - "Config": { - "webhookUrl": "http://6b0e6a60.ngrok.io", - "webhookMethod": "POST", - "headers": [ - { - "from": "test2", - "to": "value2" - } - ] - }, - "DestinationDefinition": { - "Config": { - "cdkV2Enabled": true - } - } - }, - "metadata": { - "destinationId": "destId", - "workspaceId": "wspId" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "body": { - "JSON": { - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "context": { - "device": { - "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", - "manufacturer": "Xiaomi", - "model": "Redmi 6", - "name": "xiaomi" - }, - "network": { - "carrier": "Banglalink" - }, - "os": { - "name": "android", - "version": "8.1.0" - }, - "traits": { - "address": { - "city": "Dhaka", - "country": "Bangladesh" - }, - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" - } - }, - "event": "spin_result", - "integrations": { - "All": true - }, - "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", - "properties": { - "additional_bet_index": 0, - "battle_id": "N/A", - "bet_amount": 9, - "bet_level": 1, - "bet_multiplier": 1, - "coin_balance": 9466052, - "current_module_name": "CasinoGameModule", - "days_in_game": 0, - "extra_param": "N/A", - "fb_profile": "0", - "featureGameType": "N/A", - "game_fps": 30, - "game_id": "fireEagleBase", - "game_name": "FireEagleSlots", - "gem_balance": 0, - "graphicsQuality": "HD", - "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", - "internetReachability": "ReachableViaLocalAreaNetwork", - "isLowEndDevice": "False", - "is_auto_spin": "False", - "is_turbo": "False", - "isf": "False", - "ishighroller": "False", - "jackpot_win_amount": 90, - "jackpot_win_type": "Silver", - "level": 6, - "lifetime_gem_balance": 0, - "no_of_spin": 1, - "player_total_battles": 0, - "player_total_shields": 0, - "start_date": "2019-08-01", - "total_payments": 0, - "tournament_id": "T1561970819", - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "versionSessionCount": 2, - "win_amount": 0 - }, - "timestamp": "2019-09-01T15:46:51.693229+05:30", - "type": "track", - "user_properties": { - "coin_balance": 9466052, - "current_module_name": "CasinoGameModule", - "fb_profile": "0", - "game_fps": 30, - "game_name": "FireEagleSlots", - "gem_balance": 0, - "graphicsQuality": "HD", - "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", - "internetReachability": "ReachableViaLocalAreaNetwork", - "isLowEndDevice": false, - "level": 6, - "lifetime_gem_balance": 0, - "player_total_battles": 0, - "player_total_shields": 0, - "start_date": "2019-08-01", - "total_payments": 0, - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "versionSessionCount": 2 - } - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "version": "1", - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "type": "REST", - "method": "POST", - "endpoint": "http://6b0e6a60.ngrok.io", - "headers": { - "content-type": "application/json", - "test2": "value2" - }, - "params": {}, - "files": {} - }, - "metadata": { - "destinationId": "destId", - "workspaceId": "wspId" - }, - "statusCode": 200 - } - ] - } - } - }, - { - "name": "webhook", - "description": "Test 14", - "feature": "processor", - "module": "destination", - "version": "v0", - "input": { - "request": { - "body": [ - { - "message": { - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "context": { - "device": { - "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", - "manufacturer": "Xiaomi", - "model": "Redmi 6", - "name": "xiaomi" - }, - "network": { - "carrier": "Banglalink" - }, - "os": { - "name": "android", - "version": "8.1.0" - }, - "traits": { - "address": { - "city": "Dhaka", - "country": "Bangladesh" - }, - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" - } - }, - "event": "spin_result", - "integrations": { - "All": true - }, - "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", - "properties": { - "additional_bet_index": 0, - "battle_id": "N/A", - "bet_amount": 9, - "bet_level": 1, - "bet_multiplier": 1, - "coin_balance": 9466052, - "current_module_name": "CasinoGameModule", - "days_in_game": 0, - "extra_param": "N/A", - "fb_profile": "0", - "featureGameType": "N/A", - "game_fps": 30, - "game_id": "fireEagleBase", - "game_name": "FireEagleSlots", - "gem_balance": 0, - "graphicsQuality": "HD", - "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", - "internetReachability": "ReachableViaLocalAreaNetwork", - "isLowEndDevice": "False", - "is_auto_spin": "False", - "is_turbo": "False", - "isf": "False", - "ishighroller": "False", - "jackpot_win_amount": 90, - "jackpot_win_type": "Silver", - "level": 6, - "lifetime_gem_balance": 0, - "no_of_spin": 1, - "player_total_battles": 0, - "player_total_shields": 0, - "start_date": "2019-08-01", - "total_payments": 0, - "tournament_id": "T1561970819", - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "versionSessionCount": 2, - "win_amount": 0 - }, - "timestamp": "2019-09-01T15:46:51.693229+05:30", - "type": "track", - "user_properties": { - "coin_balance": 9466052, - "current_module_name": "CasinoGameModule", - "fb_profile": "0", - "game_fps": 30, - "game_name": "FireEagleSlots", - "gem_balance": 0, - "graphicsQuality": "HD", - "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", - "internetReachability": "ReachableViaLocalAreaNetwork", - "isLowEndDevice": false, - "level": 6, - "lifetime_gem_balance": 0, - "player_total_battles": 0, - "player_total_shields": 0, - "start_date": "2019-08-01", - "total_payments": 0, - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "versionSessionCount": 2 - } - }, - "destination": { - "Config": { - "webhookUrl": "http://6b0e6a60.ngrok.io", - "webhookMethod": "PATCH", - "headers": [ - { - "from": "test2", - "to": "value2" - } - ] - }, - "DestinationDefinition": { - "Config": { - "cdkV2Enabled": true - } - } - }, - "metadata": { - "destinationId": "destId", - "workspaceId": "wspId" - } - } - ] - } - }, - "output": { - "response": { - "status": 200, - "body": [ - { - "output": { - "body": { - "JSON": { - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "context": { - "device": { - "id": "df16bffa-5c3d-4fbb-9bce-3bab098129a7R", - "manufacturer": "Xiaomi", - "model": "Redmi 6", - "name": "xiaomi" - }, - "network": { - "carrier": "Banglalink" - }, - "os": { - "name": "android", - "version": "8.1.0" - }, - "traits": { - "address": { - "city": "Dhaka", - "country": "Bangladesh" - }, - "anonymousId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1" - } - }, - "event": "spin_result", - "integrations": { - "All": true - }, - "message_id": "a80f82be-9bdc-4a9f-b2a5-15621ee41df8", - "properties": { - "additional_bet_index": 0, - "battle_id": "N/A", - "bet_amount": 9, - "bet_level": 1, - "bet_multiplier": 1, - "coin_balance": 9466052, - "current_module_name": "CasinoGameModule", - "days_in_game": 0, - "extra_param": "N/A", - "fb_profile": "0", - "featureGameType": "N/A", - "game_fps": 30, - "game_id": "fireEagleBase", - "game_name": "FireEagleSlots", - "gem_balance": 0, - "graphicsQuality": "HD", - "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", - "internetReachability": "ReachableViaLocalAreaNetwork", - "isLowEndDevice": "False", - "is_auto_spin": "False", - "is_turbo": "False", - "isf": "False", - "ishighroller": "False", - "jackpot_win_amount": 90, - "jackpot_win_type": "Silver", - "level": 6, - "lifetime_gem_balance": 0, - "no_of_spin": 1, - "player_total_battles": 0, - "player_total_shields": 0, - "start_date": "2019-08-01", - "total_payments": 0, - "tournament_id": "T1561970819", - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "versionSessionCount": 2, - "win_amount": 0 - }, - "timestamp": "2019-09-01T15:46:51.693229+05:30", - "type": "track", - "user_properties": { - "coin_balance": 9466052, - "current_module_name": "CasinoGameModule", - "fb_profile": "0", - "game_fps": 30, - "game_name": "FireEagleSlots", - "gem_balance": 0, - "graphicsQuality": "HD", - "idfa": "2bf99787-33d2-4ae2-a76a-c49672f97252", - "internetReachability": "ReachableViaLocalAreaNetwork", - "isLowEndDevice": false, - "level": 6, - "lifetime_gem_balance": 0, - "player_total_battles": 0, - "player_total_shields": 0, - "start_date": "2019-08-01", - "total_payments": 0, - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "versionSessionCount": 2 - } - }, - "JSON_ARRAY": {}, - "XML": {}, - "FORM": {} - }, - "version": "1", - "userId": "c82cbdff-e5be-4009-ac78-cdeea09ab4b1", - "type": "REST", - "method": "PATCH", - "endpoint": "http://6b0e6a60.ngrok.io", - "headers": { - "content-type": "application/json", - "test2": "value2" - }, - "params": {}, - "files": {} - }, - "metadata": { - "destinationId": "destId", - "workspaceId": "wspId" - }, - "statusCode": 200 - } - ] - } - } - } -] \ No newline at end of file + { + name: 'webhook', + description: 'Test 0', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + context: { + device: { + id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', + manufacturer: 'Xiaomi', + model: 'Redmi 6', + name: 'xiaomi', + }, + network: { + carrier: 'Banglalink', + }, + os: { + name: 'android', + version: '8.1.0', + }, + traits: { + address: { + city: 'Dhaka', + country: 'Bangladesh', + }, + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + }, + }, + event: 'spin_result', + integrations: { + All: true, + }, + message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', + properties: { + additional_bet_index: 0, + battle_id: 'N/A', + bet_amount: 9, + bet_level: 1, + bet_multiplier: 1, + coin_balance: 9466052, + current_module_name: 'CasinoGameModule', + days_in_game: 0, + extra_param: 'N/A', + fb_profile: '0', + featureGameType: 'N/A', + game_fps: 30, + game_id: 'fireEagleBase', + game_name: 'FireEagleSlots', + gem_balance: 0, + graphicsQuality: 'HD', + idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', + internetReachability: 'ReachableViaLocalAreaNetwork', + isLowEndDevice: 'False', + is_auto_spin: 'False', + is_turbo: 'False', + isf: 'False', + ishighroller: 'False', + jackpot_win_amount: 90, + jackpot_win_type: 'Silver', + level: 6, + lifetime_gem_balance: 0, + no_of_spin: 1, + player_total_battles: 0, + player_total_shields: 0, + start_date: '2019-08-01', + total_payments: 0, + tournament_id: 'T1561970819', + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + versionSessionCount: 2, + win_amount: 0, + }, + timestamp: '2019-09-01T15:46:51.693229+05:30', + type: 'track', + user_properties: { + coin_balance: 9466052, + current_module_name: 'CasinoGameModule', + fb_profile: '0', + game_fps: 30, + game_name: 'FireEagleSlots', + gem_balance: 0, + graphicsQuality: 'HD', + idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', + internetReachability: 'ReachableViaLocalAreaNetwork', + isLowEndDevice: false, + level: 6, + lifetime_gem_balance: 0, + player_total_battles: 0, + player_total_shields: 0, + start_date: '2019-08-01', + total_payments: 0, + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + versionSessionCount: 2, + }, + }, + destination: { + Config: { + webhookUrl: 'http://6b0e6a60.ngrok.io', + headers: [ + { + from: '', + to: '', + }, + { + from: 'test2', + to: 'value2', + }, + ], + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + JSON: { + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + context: { + device: { + id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', + manufacturer: 'Xiaomi', + model: 'Redmi 6', + name: 'xiaomi', + }, + network: { + carrier: 'Banglalink', + }, + os: { + name: 'android', + version: '8.1.0', + }, + traits: { + address: { + city: 'Dhaka', + country: 'Bangladesh', + }, + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + }, + }, + event: 'spin_result', + integrations: { + All: true, + }, + message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', + properties: { + additional_bet_index: 0, + battle_id: 'N/A', + bet_amount: 9, + bet_level: 1, + bet_multiplier: 1, + coin_balance: 9466052, + current_module_name: 'CasinoGameModule', + days_in_game: 0, + extra_param: 'N/A', + fb_profile: '0', + featureGameType: 'N/A', + game_fps: 30, + game_id: 'fireEagleBase', + game_name: 'FireEagleSlots', + gem_balance: 0, + graphicsQuality: 'HD', + idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', + internetReachability: 'ReachableViaLocalAreaNetwork', + isLowEndDevice: 'False', + is_auto_spin: 'False', + is_turbo: 'False', + isf: 'False', + ishighroller: 'False', + jackpot_win_amount: 90, + jackpot_win_type: 'Silver', + level: 6, + lifetime_gem_balance: 0, + no_of_spin: 1, + player_total_battles: 0, + player_total_shields: 0, + start_date: '2019-08-01', + total_payments: 0, + tournament_id: 'T1561970819', + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + versionSessionCount: 2, + win_amount: 0, + }, + timestamp: '2019-09-01T15:46:51.693229+05:30', + type: 'track', + user_properties: { + coin_balance: 9466052, + current_module_name: 'CasinoGameModule', + fb_profile: '0', + game_fps: 30, + game_name: 'FireEagleSlots', + gem_balance: 0, + graphicsQuality: 'HD', + idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', + internetReachability: 'ReachableViaLocalAreaNetwork', + isLowEndDevice: false, + level: 6, + lifetime_gem_balance: 0, + player_total_battles: 0, + player_total_shields: 0, + start_date: '2019-08-01', + total_payments: 0, + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + versionSessionCount: 2, + }, + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + version: '1', + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + type: 'REST', + method: 'POST', + endpoint: 'http://6b0e6a60.ngrok.io', + headers: { + 'content-type': 'application/json', + test2: 'value2', + }, + params: {}, + files: {}, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'webhook', + description: 'Test 1', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + context: { + device: { + id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', + manufacturer: 'Xiaomi', + model: 'Redmi 6', + name: 'xiaomi', + }, + network: { + carrier: 'Banglalink', + }, + os: { + name: 'android', + version: '8.1.0', + }, + traits: { + address: { + city: 'Dhaka', + country: 'Bangladesh', + }, + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + }, + }, + event: 'spin_result', + integrations: { + All: true, + }, + message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', + properties: { + additional_bet_index: 0, + battle_id: 'N/A', + bet_amount: 9, + bet_level: 1, + bet_multiplier: 1, + coin_balance: 9466052, + current_module_name: 'CasinoGameModule', + days_in_game: 0, + extra_param: 'N/A', + fb_profile: '0', + featureGameType: 'N/A', + game_fps: 30, + game_id: 'fireEagleBase', + game_name: 'FireEagleSlots', + gem_balance: 0, + graphicsQuality: 'HD', + idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', + internetReachability: 'ReachableViaLocalAreaNetwork', + isLowEndDevice: 'False', + is_auto_spin: 'False', + is_turbo: 'False', + isf: 'False', + ishighroller: 'False', + jackpot_win_amount: 90, + jackpot_win_type: 'Silver', + level: 6, + lifetime_gem_balance: 0, + no_of_spin: 1, + player_total_battles: 0, + player_total_shields: 0, + start_date: '2019-08-01', + total_payments: 0, + tournament_id: 'T1561970819', + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + versionSessionCount: 2, + win_amount: 0, + }, + timestamp: '2019-09-01T15:46:51.693229+05:30', + type: 'track', + user_properties: { + coin_balance: 9466052, + current_module_name: 'CasinoGameModule', + fb_profile: '0', + game_fps: 30, + game_name: 'FireEagleSlots', + gem_balance: 0, + graphicsQuality: 'HD', + idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', + internetReachability: 'ReachableViaLocalAreaNetwork', + isLowEndDevice: false, + level: 6, + lifetime_gem_balance: 0, + player_total_battles: 0, + player_total_shields: 0, + start_date: '2019-08-01', + total_payments: 0, + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + versionSessionCount: 2, + }, + }, + destination: { + Config: { + webhookUrl: 'https://6b0e6a60.ngrok.io/n', + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + JSON: { + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + context: { + device: { + id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', + manufacturer: 'Xiaomi', + model: 'Redmi 6', + name: 'xiaomi', + }, + network: { + carrier: 'Banglalink', + }, + os: { + name: 'android', + version: '8.1.0', + }, + traits: { + address: { + city: 'Dhaka', + country: 'Bangladesh', + }, + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + }, + }, + event: 'spin_result', + integrations: { + All: true, + }, + message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', + properties: { + additional_bet_index: 0, + battle_id: 'N/A', + bet_amount: 9, + bet_level: 1, + bet_multiplier: 1, + coin_balance: 9466052, + current_module_name: 'CasinoGameModule', + days_in_game: 0, + extra_param: 'N/A', + fb_profile: '0', + featureGameType: 'N/A', + game_fps: 30, + game_id: 'fireEagleBase', + game_name: 'FireEagleSlots', + gem_balance: 0, + graphicsQuality: 'HD', + idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', + internetReachability: 'ReachableViaLocalAreaNetwork', + isLowEndDevice: 'False', + is_auto_spin: 'False', + is_turbo: 'False', + isf: 'False', + ishighroller: 'False', + jackpot_win_amount: 90, + jackpot_win_type: 'Silver', + level: 6, + lifetime_gem_balance: 0, + no_of_spin: 1, + player_total_battles: 0, + player_total_shields: 0, + start_date: '2019-08-01', + total_payments: 0, + tournament_id: 'T1561970819', + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + versionSessionCount: 2, + win_amount: 0, + }, + timestamp: '2019-09-01T15:46:51.693229+05:30', + type: 'track', + user_properties: { + coin_balance: 9466052, + current_module_name: 'CasinoGameModule', + fb_profile: '0', + game_fps: 30, + game_name: 'FireEagleSlots', + gem_balance: 0, + graphicsQuality: 'HD', + idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', + internetReachability: 'ReachableViaLocalAreaNetwork', + isLowEndDevice: false, + level: 6, + lifetime_gem_balance: 0, + player_total_battles: 0, + player_total_shields: 0, + start_date: '2019-08-01', + total_payments: 0, + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + versionSessionCount: 2, + }, + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + version: '1', + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + type: 'REST', + method: 'POST', + endpoint: 'https://6b0e6a60.ngrok.io/n', + headers: { + 'content-type': 'application/json', + }, + params: {}, + files: {}, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'webhook', + description: 'Test 2', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + context: { + device: { + id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', + manufacturer: 'Xiaomi', + model: 'Redmi 6', + name: 'xiaomi', + }, + network: { + carrier: 'Banglalink', + }, + os: { + name: 'android', + version: '8.1.0', + }, + traits: { + address: { + city: 'Dhaka', + country: 'Bangladesh', + }, + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + }, + }, + event: 'spin_result', + integrations: { + All: true, + }, + message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', + properties: { + additional_bet_index: 0, + battle_id: 'N/A', + bet_amount: 9, + bet_level: 1, + bet_multiplier: 1, + coin_balance: 9466052, + current_module_name: 'CasinoGameModule', + days_in_game: 0, + extra_param: 'N/A', + fb_profile: '0', + featureGameType: 'N/A', + game_fps: 30, + game_id: 'fireEagleBase', + game_name: 'FireEagleSlots', + gem_balance: 0, + graphicsQuality: 'HD', + idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', + internetReachability: 'ReachableViaLocalAreaNetwork', + isLowEndDevice: 'False', + is_auto_spin: 'False', + is_turbo: 'False', + isf: 'False', + ishighroller: 'False', + jackpot_win_amount: 90, + jackpot_win_type: 'Silver', + level: 6, + lifetime_gem_balance: 0, + no_of_spin: 1, + player_total_battles: 0, + player_total_shields: 0, + start_date: '2019-08-01', + total_payments: 0, + tournament_id: 'T1561970819', + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + versionSessionCount: 2, + win_amount: 0, + }, + timestamp: '2019-09-01T15:46:51.693229+05:30', + type: 'track', + user_properties: { + coin_balance: 9466052, + current_module_name: 'CasinoGameModule', + fb_profile: '0', + game_fps: 30, + game_name: 'FireEagleSlots', + gem_balance: 0, + graphicsQuality: 'HD', + idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', + internetReachability: 'ReachableViaLocalAreaNetwork', + isLowEndDevice: false, + level: 6, + lifetime_gem_balance: 0, + player_total_battles: 0, + player_total_shields: 0, + start_date: '2019-08-01', + total_payments: 0, + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + versionSessionCount: 2, + }, + }, + destination: { + Config: { + webhookUrl: 'https://6b0e6a60.', + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + JSON: { + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + context: { + device: { + id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', + manufacturer: 'Xiaomi', + model: 'Redmi 6', + name: 'xiaomi', + }, + network: { + carrier: 'Banglalink', + }, + os: { + name: 'android', + version: '8.1.0', + }, + traits: { + address: { + city: 'Dhaka', + country: 'Bangladesh', + }, + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + }, + }, + event: 'spin_result', + integrations: { + All: true, + }, + message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', + properties: { + additional_bet_index: 0, + battle_id: 'N/A', + bet_amount: 9, + bet_level: 1, + bet_multiplier: 1, + coin_balance: 9466052, + current_module_name: 'CasinoGameModule', + days_in_game: 0, + extra_param: 'N/A', + fb_profile: '0', + featureGameType: 'N/A', + game_fps: 30, + game_id: 'fireEagleBase', + game_name: 'FireEagleSlots', + gem_balance: 0, + graphicsQuality: 'HD', + idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', + internetReachability: 'ReachableViaLocalAreaNetwork', + isLowEndDevice: 'False', + is_auto_spin: 'False', + is_turbo: 'False', + isf: 'False', + ishighroller: 'False', + jackpot_win_amount: 90, + jackpot_win_type: 'Silver', + level: 6, + lifetime_gem_balance: 0, + no_of_spin: 1, + player_total_battles: 0, + player_total_shields: 0, + start_date: '2019-08-01', + total_payments: 0, + tournament_id: 'T1561970819', + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + versionSessionCount: 2, + win_amount: 0, + }, + timestamp: '2019-09-01T15:46:51.693229+05:30', + type: 'track', + user_properties: { + coin_balance: 9466052, + current_module_name: 'CasinoGameModule', + fb_profile: '0', + game_fps: 30, + game_name: 'FireEagleSlots', + gem_balance: 0, + graphicsQuality: 'HD', + idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', + internetReachability: 'ReachableViaLocalAreaNetwork', + isLowEndDevice: false, + level: 6, + lifetime_gem_balance: 0, + player_total_battles: 0, + player_total_shields: 0, + start_date: '2019-08-01', + total_payments: 0, + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + versionSessionCount: 2, + }, + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + version: '1', + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + type: 'REST', + method: 'POST', + endpoint: 'https://6b0e6a60.', + headers: { + 'content-type': 'application/json', + }, + params: {}, + files: {}, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'webhook', + description: 'Test 3', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + context: { + device: { + id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', + manufacturer: 'Xiaomi', + model: 'Redmi 6', + name: 'xiaomi', + }, + network: { + carrier: 'Banglalink', + }, + os: { + name: 'android', + version: '8.1.0', + }, + traits: { + address: { + city: 'Dhaka', + country: 'Bangladesh', + }, + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + }, + }, + event: 'spin_result', + integrations: { + All: true, + }, + message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', + properties: { + k1: 'v1', + k2: { + k3: 'c3', + k4: { + k5: 'c5', + }, + }, + }, + timestamp: '2019-09-01T15:46:51.693229+05:30', + type: 'track', + }, + destination: { + Config: { + webhookUrl: 'https://6b0e6a60.', + webhookMethod: 'GET', + headers: [ + { + from: 'X-customHeader', + to: 'customHeaderVal', + }, + ], + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + version: '1', + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + type: 'REST', + method: 'GET', + endpoint: 'https://6b0e6a60.', + headers: { + 'x-customheader': 'customHeaderVal', + }, + params: { + k1: 'v1', + 'k2.k3': 'c3', + 'k2.k4.k5': 'c5', + }, + files: {}, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'webhook', + description: 'Test 4', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + context: { + device: { + id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', + manufacturer: 'Xiaomi', + model: 'Redmi 6', + name: 'xiaomi', + }, + network: { + carrier: 'Banglalink', + }, + os: { + name: 'android', + version: '8.1.0', + }, + traits: { + address: { + city: 'Dhaka', + country: 'Bangladesh', + }, + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + }, + }, + event: 'spin_result', + integrations: { + All: true, + }, + message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', + properties: { + k1: 'v1', + k2: { + k3: 'c3', + k4: { + k5: 'c5', + }, + }, + }, + timestamp: '2019-09-01T15:46:51.693229+05:30', + type: 'track', + }, + destination: { + Config: { + webhookUrl: 'https://6b0e6a60.', + webhookMethod: 'GET', + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + version: '1', + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + type: 'REST', + method: 'GET', + endpoint: 'https://6b0e6a60.', + headers: {}, + params: { + k1: 'v1', + 'k2.k3': 'c3', + 'k2.k4.k5': 'c5', + }, + files: {}, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'webhook', + description: 'Test 5', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + context: { + device: { + id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', + manufacturer: 'Xiaomi', + model: 'Redmi 6', + name: 'xiaomi', + }, + network: { + carrier: 'Banglalink', + }, + os: { + name: 'android', + version: '8.1.0', + }, + traits: { + address: { + city: 'Dhaka', + country: 'Bangladesh', + }, + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + }, + }, + event: 'spin_result', + integrations: { + All: true, + }, + message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', + properties: { + additional_bet_index: 0, + battle_id: 'N/A', + bet_amount: 9, + bet_level: 1, + bet_multiplier: 1, + coin_balance: 9466052, + current_module_name: 'CasinoGameModule', + days_in_game: 0, + extra_param: 'N/A', + fb_profile: '0', + featureGameType: 'N/A', + game_fps: 30, + game_id: 'fireEagleBase', + game_name: 'FireEagleSlots', + gem_balance: 0, + graphicsQuality: 'HD', + idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', + internetReachability: 'ReachableViaLocalAreaNetwork', + isLowEndDevice: 'False', + is_auto_spin: 'False', + is_turbo: 'False', + isf: 'False', + ishighroller: 'False', + jackpot_win_amount: 90, + jackpot_win_type: 'Silver', + level: 6, + lifetime_gem_balance: 0, + no_of_spin: 1, + player_total_battles: 0, + player_total_shields: 0, + start_date: '2019-08-01', + total_payments: 0, + tournament_id: 'T1561970819', + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + versionSessionCount: 2, + win_amount: 0, + }, + timestamp: '2019-09-01T15:46:51.693229+05:30', + type: 'track', + request_ip: '127.0.0.1', + }, + destination: { + Config: { + webhookUrl: 'http://6b0e6a60.ngrok.io', + header: [ + { + from: 'test1', + to: 'value1', + }, + { + from: 'test2', + to: 'value2', + }, + ], + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + JSON: { + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + context: { + device: { + id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', + manufacturer: 'Xiaomi', + model: 'Redmi 6', + name: 'xiaomi', + }, + network: { + carrier: 'Banglalink', + }, + os: { + name: 'android', + version: '8.1.0', + }, + traits: { + address: { + city: 'Dhaka', + country: 'Bangladesh', + }, + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + }, + ip: '127.0.0.1', + }, + event: 'spin_result', + integrations: { + All: true, + }, + message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', + properties: { + additional_bet_index: 0, + battle_id: 'N/A', + bet_amount: 9, + bet_level: 1, + bet_multiplier: 1, + coin_balance: 9466052, + current_module_name: 'CasinoGameModule', + days_in_game: 0, + extra_param: 'N/A', + fb_profile: '0', + featureGameType: 'N/A', + game_fps: 30, + game_id: 'fireEagleBase', + game_name: 'FireEagleSlots', + gem_balance: 0, + graphicsQuality: 'HD', + idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', + internetReachability: 'ReachableViaLocalAreaNetwork', + isLowEndDevice: 'False', + is_auto_spin: 'False', + is_turbo: 'False', + isf: 'False', + ishighroller: 'False', + jackpot_win_amount: 90, + jackpot_win_type: 'Silver', + level: 6, + lifetime_gem_balance: 0, + no_of_spin: 1, + player_total_battles: 0, + player_total_shields: 0, + start_date: '2019-08-01', + total_payments: 0, + tournament_id: 'T1561970819', + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + versionSessionCount: 2, + win_amount: 0, + }, + timestamp: '2019-09-01T15:46:51.693229+05:30', + type: 'track', + request_ip: '127.0.0.1', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + version: '1', + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + type: 'REST', + method: 'POST', + endpoint: 'http://6b0e6a60.ngrok.io', + headers: { + 'content-type': 'application/json', + }, + params: {}, + files: {}, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'webhook', + description: 'Test 6', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + context: { + device: { + id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', + manufacturer: 'Xiaomi', + model: 'Redmi 6', + name: 'xiaomi', + }, + network: { + carrier: 'Banglalink', + }, + os: { + name: 'android', + version: '8.1.0', + }, + traits: { + address: { + city: 'Dhaka', + country: 'Bangladesh', + }, + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + }, + }, + event: 'spin_result', + integrations: { + All: true, + }, + message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', + properties: { + additional_bet_index: 0, + battle_id: 'N/A', + bet_amount: 9, + bet_level: 1, + bet_multiplier: 1, + coin_balance: 9466052, + current_module_name: 'CasinoGameModule', + days_in_game: 0, + extra_param: 'N/A', + fb_profile: '0', + featureGameType: 'N/A', + game_fps: 30, + game_id: 'fireEagleBase', + game_name: 'FireEagleSlots', + gem_balance: 0, + graphicsQuality: 'HD', + idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', + internetReachability: 'ReachableViaLocalAreaNetwork', + isLowEndDevice: 'False', + is_auto_spin: 'False', + is_turbo: 'False', + isf: 'False', + ishighroller: 'False', + jackpot_win_amount: 90, + jackpot_win_type: 'Silver', + level: 6, + lifetime_gem_balance: 0, + no_of_spin: 1, + player_total_battles: 0, + player_total_shields: 0, + start_date: '2019-08-01', + total_payments: 0, + tournament_id: 'T1561970819', + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + versionSessionCount: 2, + win_amount: 0, + }, + timestamp: '2019-09-01T15:46:51.693229+05:30', + type: 'track', + request_ip: '127.0.0.1', + }, + destination: { + Config: { + webhookUrl: 'http://6b0e6a60.ngrok.io', + headers: [ + { + from: 'Content-Type', + to: 'application/xml', + }, + { + from: 'test2', + to: 'value2', + }, + ], + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + JSON: { + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + context: { + device: { + id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', + manufacturer: 'Xiaomi', + model: 'Redmi 6', + name: 'xiaomi', + }, + network: { + carrier: 'Banglalink', + }, + os: { + name: 'android', + version: '8.1.0', + }, + traits: { + address: { + city: 'Dhaka', + country: 'Bangladesh', + }, + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + }, + ip: '127.0.0.1', + }, + event: 'spin_result', + integrations: { + All: true, + }, + message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', + properties: { + additional_bet_index: 0, + battle_id: 'N/A', + bet_amount: 9, + bet_level: 1, + bet_multiplier: 1, + coin_balance: 9466052, + current_module_name: 'CasinoGameModule', + days_in_game: 0, + extra_param: 'N/A', + fb_profile: '0', + featureGameType: 'N/A', + game_fps: 30, + game_id: 'fireEagleBase', + game_name: 'FireEagleSlots', + gem_balance: 0, + graphicsQuality: 'HD', + idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', + internetReachability: 'ReachableViaLocalAreaNetwork', + isLowEndDevice: 'False', + is_auto_spin: 'False', + is_turbo: 'False', + isf: 'False', + ishighroller: 'False', + jackpot_win_amount: 90, + jackpot_win_type: 'Silver', + level: 6, + lifetime_gem_balance: 0, + no_of_spin: 1, + player_total_battles: 0, + player_total_shields: 0, + start_date: '2019-08-01', + total_payments: 0, + tournament_id: 'T1561970819', + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + versionSessionCount: 2, + win_amount: 0, + }, + timestamp: '2019-09-01T15:46:51.693229+05:30', + type: 'track', + request_ip: '127.0.0.1', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + version: '1', + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + type: 'REST', + method: 'POST', + endpoint: 'http://6b0e6a60.ngrok.io', + headers: { + 'content-type': 'application/xml', + test2: 'value2', + }, + params: {}, + files: {}, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'webhook', + description: 'Test 7', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + event: 'spin_result', + integrations: { + All: true, + }, + message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', + properties: { + additional_bet_index: 0, + battle_id: 'N/A', + bet_amount: 9, + bet_level: 1, + bet_multiplier: 1, + coin_balance: 9466052, + current_module_name: 'CasinoGameModule', + days_in_game: 0, + extra_param: 'N/A', + fb_profile: '0', + featureGameType: 'N/A', + game_fps: 30, + game_id: 'fireEagleBase', + game_name: 'FireEagleSlots', + gem_balance: 0, + graphicsQuality: 'HD', + idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', + internetReachability: 'ReachableViaLocalAreaNetwork', + isLowEndDevice: 'False', + is_auto_spin: 'False', + is_turbo: 'False', + isf: 'False', + ishighroller: 'False', + jackpot_win_amount: 90, + jackpot_win_type: 'Silver', + level: 6, + lifetime_gem_balance: 0, + no_of_spin: 1, + player_total_battles: 0, + player_total_shields: 0, + start_date: '2019-08-01', + total_payments: 0, + tournament_id: 'T1561970819', + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + versionSessionCount: 2, + win_amount: 0, + }, + timestamp: '2019-09-01T15:46:51.693229+05:30', + type: 'track', + }, + destination: { + Config: { + webhookUrl: 'http://6b0e6a60.ngrok.io', + headers: [ + { + from: 'Content-Type', + to: 'application/xml', + }, + { + from: 'test2', + to: 'value2', + }, + ], + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + JSON: { + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + event: 'spin_result', + integrations: { + All: true, + }, + message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', + properties: { + additional_bet_index: 0, + battle_id: 'N/A', + bet_amount: 9, + bet_level: 1, + bet_multiplier: 1, + coin_balance: 9466052, + current_module_name: 'CasinoGameModule', + days_in_game: 0, + extra_param: 'N/A', + fb_profile: '0', + featureGameType: 'N/A', + game_fps: 30, + game_id: 'fireEagleBase', + game_name: 'FireEagleSlots', + gem_balance: 0, + graphicsQuality: 'HD', + idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', + internetReachability: 'ReachableViaLocalAreaNetwork', + isLowEndDevice: 'False', + is_auto_spin: 'False', + is_turbo: 'False', + isf: 'False', + ishighroller: 'False', + jackpot_win_amount: 90, + jackpot_win_type: 'Silver', + level: 6, + lifetime_gem_balance: 0, + no_of_spin: 1, + player_total_battles: 0, + player_total_shields: 0, + start_date: '2019-08-01', + total_payments: 0, + tournament_id: 'T1561970819', + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + versionSessionCount: 2, + win_amount: 0, + }, + timestamp: '2019-09-01T15:46:51.693229+05:30', + type: 'track', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + version: '1', + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + type: 'REST', + method: 'POST', + endpoint: 'http://6b0e6a60.ngrok.io', + headers: { + 'content-type': 'application/xml', + test2: 'value2', + }, + params: {}, + files: {}, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'webhook', + description: 'Test 8', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + context: { + device: { + id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', + manufacturer: 'Xiaomi', + model: 'Redmi 6', + name: 'xiaomi', + }, + network: { + carrier: 'Banglalink', + }, + os: { + name: 'android', + version: '8.1.0', + }, + traits: { + address: { + city: 'Dhaka', + country: 'Bangladesh', + }, + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + }, + }, + event: 'spin_result', + integrations: { + All: true, + }, + message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', + properties: { + additional_bet_index: 0, + battle_id: 'N/A', + featureGameType: 'N/A', + win_amount: 0, + }, + timestamp: '2019-09-01T15:46:51.693229+05:30', + type: 'track', + header: { + dynamic_header_key_string: 'dynamic_header_value_string', + dynamic_header_key_num: 10, + dynamic_header_key_object: { + k1: 'v1', + }, + }, + appendPath: '/product/search?string=value', + }, + destination: { + Config: { + webhookUrl: 'http://6b0e6a60.ngrok.io', + headers: [ + { + from: '', + to: '', + }, + { + from: 'test2', + to: 'value2', + }, + ], + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + JSON: { + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + context: { + device: { + id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', + manufacturer: 'Xiaomi', + model: 'Redmi 6', + name: 'xiaomi', + }, + network: { + carrier: 'Banglalink', + }, + os: { + name: 'android', + version: '8.1.0', + }, + traits: { + address: { + city: 'Dhaka', + country: 'Bangladesh', + }, + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + }, + }, + event: 'spin_result', + integrations: { + All: true, + }, + message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', + properties: { + additional_bet_index: 0, + battle_id: 'N/A', + featureGameType: 'N/A', + win_amount: 0, + }, + timestamp: '2019-09-01T15:46:51.693229+05:30', + type: 'track', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + version: '1', + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + type: 'REST', + method: 'POST', + endpoint: 'http://6b0e6a60.ngrok.io/product/search?string=value', + headers: { + 'content-type': 'application/json', + test2: 'value2', + dynamic_header_key_string: 'dynamic_header_value_string', + }, + params: {}, + files: {}, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'webhook', + description: 'Test 9', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + context: { + device: { + id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', + manufacturer: 'Xiaomi', + model: 'Redmi 6', + name: 'xiaomi', + }, + network: { + carrier: 'Banglalink', + }, + os: { + name: 'android', + version: '8.1.0', + }, + traits: { + address: { + city: 'Dhaka', + country: 'Bangladesh', + }, + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + }, + }, + event: 'spin_result', + integrations: { + All: true, + }, + message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', + properties: { + additional_bet_index: 0, + battle_id: 'N/A', + featureGameType: 'N/A', + win_amount: 0, + }, + timestamp: '2019-09-01T15:46:51.693229+05:30', + type: 'track', + fullPath: 'https://www.google.com', + }, + destination: { + Config: { + webhookUrl: 'http://6b0e6a60.ngrok.io', + headers: [ + { + from: '', + to: '', + }, + { + from: 'test2', + to: 'value2', + }, + ], + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + JSON: { + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + context: { + device: { + id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', + manufacturer: 'Xiaomi', + model: 'Redmi 6', + name: 'xiaomi', + }, + network: { + carrier: 'Banglalink', + }, + os: { + name: 'android', + version: '8.1.0', + }, + traits: { + address: { + city: 'Dhaka', + country: 'Bangladesh', + }, + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + }, + }, + event: 'spin_result', + integrations: { + All: true, + }, + message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', + properties: { + additional_bet_index: 0, + battle_id: 'N/A', + featureGameType: 'N/A', + win_amount: 0, + }, + timestamp: '2019-09-01T15:46:51.693229+05:30', + type: 'track', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + version: '1', + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google.com', + headers: { + 'content-type': 'application/json', + test2: 'value2', + }, + params: {}, + files: {}, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'webhook', + description: 'Test 10', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + context: { + device: { + id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', + manufacturer: 'Xiaomi', + model: 'Redmi 6', + name: 'xiaomi', + }, + network: { + carrier: 'Banglalink', + }, + os: { + name: 'android', + version: '8.1.0', + }, + traits: { + address: { + city: 'Dhaka', + country: 'Bangladesh', + }, + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + }, + }, + event: 'spin_result', + integrations: { + All: true, + }, + message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', + properties: { + additional_bet_index: 0, + battle_id: 'N/A', + featureGameType: 'N/A', + win_amount: 0, + }, + timestamp: '2019-09-01T15:46:51.693229+05:30', + type: 'track', + fullPath: 'https://www.google.com/', + appendPath: '?searchTerms=cats', + }, + destination: { + Config: { + webhookUrl: 'http://6b0e6a60.ngrok.io', + headers: [ + { + from: '', + to: '', + }, + { + from: 'test2', + to: 'value2', + }, + ], + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + JSON: { + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + context: { + device: { + id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', + manufacturer: 'Xiaomi', + model: 'Redmi 6', + name: 'xiaomi', + }, + network: { + carrier: 'Banglalink', + }, + os: { + name: 'android', + version: '8.1.0', + }, + traits: { + address: { + city: 'Dhaka', + country: 'Bangladesh', + }, + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + }, + }, + event: 'spin_result', + integrations: { + All: true, + }, + message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', + properties: { + additional_bet_index: 0, + battle_id: 'N/A', + featureGameType: 'N/A', + win_amount: 0, + }, + timestamp: '2019-09-01T15:46:51.693229+05:30', + type: 'track', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + version: '1', + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.google.com/?searchTerms=cats', + headers: { + 'content-type': 'application/json', + test2: 'value2', + }, + params: {}, + files: {}, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'webhook', + description: 'Test 11', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + context: { + device: { + id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', + manufacturer: 'Xiaomi', + model: 'Redmi 6', + name: 'xiaomi', + }, + network: { + carrier: 'Banglalink', + }, + os: { + name: 'android', + version: '8.1.0', + }, + traits: { + address: { + city: 'Dhaka', + country: 'Bangladesh', + }, + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + }, + }, + event: 'spin_result', + integrations: { + All: true, + }, + message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', + properties: { + additional_bet_index: 0, + battle_id: 'N/A', + featureGameType: 'N/A', + win_amount: 0, + }, + timestamp: '2019-09-01T15:46:51.693229+05:30', + type: 'track', + fullPath: 'https://www.google.com/', + appendPath: '?searchTerms=cats', + }, + destination: { + Config: { + webhookUrl: 'http://6b0e6a60.ngrok.io', + webhookMethod: 'PUT', + headers: [ + { + from: '', + to: '', + }, + { + from: 'test2', + to: 'value2', + }, + ], + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + JSON: { + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + context: { + device: { + id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', + manufacturer: 'Xiaomi', + model: 'Redmi 6', + name: 'xiaomi', + }, + network: { + carrier: 'Banglalink', + }, + os: { + name: 'android', + version: '8.1.0', + }, + traits: { + address: { + city: 'Dhaka', + country: 'Bangladesh', + }, + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + }, + }, + event: 'spin_result', + integrations: { + All: true, + }, + message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', + properties: { + additional_bet_index: 0, + battle_id: 'N/A', + featureGameType: 'N/A', + win_amount: 0, + }, + timestamp: '2019-09-01T15:46:51.693229+05:30', + type: 'track', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + version: '1', + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + type: 'REST', + method: 'PUT', + endpoint: 'https://www.google.com/?searchTerms=cats', + headers: { + 'content-type': 'application/json', + test2: 'value2', + }, + params: {}, + files: {}, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'webhook', + description: 'Test 12', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + context: { + device: { + id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', + manufacturer: 'Xiaomi', + model: 'Redmi 6', + name: 'xiaomi', + }, + network: { + carrier: 'Banglalink', + }, + os: { + name: 'android', + version: '8.1.0', + }, + traits: { + address: { + city: 'Dhaka', + country: 'Bangladesh', + }, + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + }, + }, + event: 'spin_result', + integrations: { + All: true, + }, + message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', + properties: { + additional_bet_index: 0, + battle_id: 'N/A', + featureGameType: 'N/A', + win_amount: 0, + }, + timestamp: '2019-09-01T15:46:51.693229+05:30', + type: 'track', + fullPath: 'https://www.google.com/', + appendPath: '?searchTerms=cats', + }, + destination: { + Config: { + webhookUrl: 'http://6b0e6a60.ngrok.io', + webhookMethod: 'DELETE', + headers: [ + { + from: '', + to: '', + }, + { + from: 'test2', + to: 'value2', + }, + ], + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + version: '1', + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + type: 'REST', + method: 'DELETE', + endpoint: 'https://www.google.com/?searchTerms=cats', + headers: { + test2: 'value2', + }, + params: { + additional_bet_index: 0, + battle_id: 'N/A', + featureGameType: 'N/A', + win_amount: 0, + }, + files: {}, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'webhook', + description: 'Test 13', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + context: { + device: { + id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', + manufacturer: 'Xiaomi', + model: 'Redmi 6', + name: 'xiaomi', + }, + network: { + carrier: 'Banglalink', + }, + os: { + name: 'android', + version: '8.1.0', + }, + traits: { + address: { + city: 'Dhaka', + country: 'Bangladesh', + }, + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + }, + }, + event: 'spin_result', + integrations: { + All: true, + }, + message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', + properties: { + additional_bet_index: 0, + battle_id: 'N/A', + bet_amount: 9, + bet_level: 1, + bet_multiplier: 1, + coin_balance: 9466052, + current_module_name: 'CasinoGameModule', + days_in_game: 0, + extra_param: 'N/A', + fb_profile: '0', + featureGameType: 'N/A', + game_fps: 30, + game_id: 'fireEagleBase', + game_name: 'FireEagleSlots', + gem_balance: 0, + graphicsQuality: 'HD', + idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', + internetReachability: 'ReachableViaLocalAreaNetwork', + isLowEndDevice: 'False', + is_auto_spin: 'False', + is_turbo: 'False', + isf: 'False', + ishighroller: 'False', + jackpot_win_amount: 90, + jackpot_win_type: 'Silver', + level: 6, + lifetime_gem_balance: 0, + no_of_spin: 1, + player_total_battles: 0, + player_total_shields: 0, + start_date: '2019-08-01', + total_payments: 0, + tournament_id: 'T1561970819', + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + versionSessionCount: 2, + win_amount: 0, + }, + timestamp: '2019-09-01T15:46:51.693229+05:30', + type: 'track', + user_properties: { + coin_balance: 9466052, + current_module_name: 'CasinoGameModule', + fb_profile: '0', + game_fps: 30, + game_name: 'FireEagleSlots', + gem_balance: 0, + graphicsQuality: 'HD', + idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', + internetReachability: 'ReachableViaLocalAreaNetwork', + isLowEndDevice: false, + level: 6, + lifetime_gem_balance: 0, + player_total_battles: 0, + player_total_shields: 0, + start_date: '2019-08-01', + total_payments: 0, + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + versionSessionCount: 2, + }, + }, + destination: { + Config: { + webhookUrl: 'http://6b0e6a60.ngrok.io', + webhookMethod: 'POST', + headers: [ + { + from: 'test2', + to: 'value2', + }, + ], + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + JSON: { + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + context: { + device: { + id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', + manufacturer: 'Xiaomi', + model: 'Redmi 6', + name: 'xiaomi', + }, + network: { + carrier: 'Banglalink', + }, + os: { + name: 'android', + version: '8.1.0', + }, + traits: { + address: { + city: 'Dhaka', + country: 'Bangladesh', + }, + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + }, + }, + event: 'spin_result', + integrations: { + All: true, + }, + message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', + properties: { + additional_bet_index: 0, + battle_id: 'N/A', + bet_amount: 9, + bet_level: 1, + bet_multiplier: 1, + coin_balance: 9466052, + current_module_name: 'CasinoGameModule', + days_in_game: 0, + extra_param: 'N/A', + fb_profile: '0', + featureGameType: 'N/A', + game_fps: 30, + game_id: 'fireEagleBase', + game_name: 'FireEagleSlots', + gem_balance: 0, + graphicsQuality: 'HD', + idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', + internetReachability: 'ReachableViaLocalAreaNetwork', + isLowEndDevice: 'False', + is_auto_spin: 'False', + is_turbo: 'False', + isf: 'False', + ishighroller: 'False', + jackpot_win_amount: 90, + jackpot_win_type: 'Silver', + level: 6, + lifetime_gem_balance: 0, + no_of_spin: 1, + player_total_battles: 0, + player_total_shields: 0, + start_date: '2019-08-01', + total_payments: 0, + tournament_id: 'T1561970819', + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + versionSessionCount: 2, + win_amount: 0, + }, + timestamp: '2019-09-01T15:46:51.693229+05:30', + type: 'track', + user_properties: { + coin_balance: 9466052, + current_module_name: 'CasinoGameModule', + fb_profile: '0', + game_fps: 30, + game_name: 'FireEagleSlots', + gem_balance: 0, + graphicsQuality: 'HD', + idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', + internetReachability: 'ReachableViaLocalAreaNetwork', + isLowEndDevice: false, + level: 6, + lifetime_gem_balance: 0, + player_total_battles: 0, + player_total_shields: 0, + start_date: '2019-08-01', + total_payments: 0, + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + versionSessionCount: 2, + }, + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + version: '1', + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + type: 'REST', + method: 'POST', + endpoint: 'http://6b0e6a60.ngrok.io', + headers: { + 'content-type': 'application/json', + test2: 'value2', + }, + params: {}, + files: {}, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'webhook', + description: 'Test 14', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + context: { + device: { + id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', + manufacturer: 'Xiaomi', + model: 'Redmi 6', + name: 'xiaomi', + }, + network: { + carrier: 'Banglalink', + }, + os: { + name: 'android', + version: '8.1.0', + }, + traits: { + address: { + city: 'Dhaka', + country: 'Bangladesh', + }, + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + }, + }, + event: 'spin_result', + integrations: { + All: true, + }, + message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', + properties: { + additional_bet_index: 0, + battle_id: 'N/A', + bet_amount: 9, + bet_level: 1, + bet_multiplier: 1, + coin_balance: 9466052, + current_module_name: 'CasinoGameModule', + days_in_game: 0, + extra_param: 'N/A', + fb_profile: '0', + featureGameType: 'N/A', + game_fps: 30, + game_id: 'fireEagleBase', + game_name: 'FireEagleSlots', + gem_balance: 0, + graphicsQuality: 'HD', + idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', + internetReachability: 'ReachableViaLocalAreaNetwork', + isLowEndDevice: 'False', + is_auto_spin: 'False', + is_turbo: 'False', + isf: 'False', + ishighroller: 'False', + jackpot_win_amount: 90, + jackpot_win_type: 'Silver', + level: 6, + lifetime_gem_balance: 0, + no_of_spin: 1, + player_total_battles: 0, + player_total_shields: 0, + start_date: '2019-08-01', + total_payments: 0, + tournament_id: 'T1561970819', + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + versionSessionCount: 2, + win_amount: 0, + }, + timestamp: '2019-09-01T15:46:51.693229+05:30', + type: 'track', + user_properties: { + coin_balance: 9466052, + current_module_name: 'CasinoGameModule', + fb_profile: '0', + game_fps: 30, + game_name: 'FireEagleSlots', + gem_balance: 0, + graphicsQuality: 'HD', + idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', + internetReachability: 'ReachableViaLocalAreaNetwork', + isLowEndDevice: false, + level: 6, + lifetime_gem_balance: 0, + player_total_battles: 0, + player_total_shields: 0, + start_date: '2019-08-01', + total_payments: 0, + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + versionSessionCount: 2, + }, + }, + destination: { + Config: { + webhookUrl: 'http://6b0e6a60.ngrok.io', + webhookMethod: 'PATCH', + headers: [ + { + from: 'test2', + to: 'value2', + }, + ], + }, + DestinationDefinition: { + Config: { + cdkV2Enabled: true, + }, + }, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + body: { + JSON: { + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + context: { + device: { + id: 'df16bffa-5c3d-4fbb-9bce-3bab098129a7R', + manufacturer: 'Xiaomi', + model: 'Redmi 6', + name: 'xiaomi', + }, + network: { + carrier: 'Banglalink', + }, + os: { + name: 'android', + version: '8.1.0', + }, + traits: { + address: { + city: 'Dhaka', + country: 'Bangladesh', + }, + anonymousId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + }, + }, + event: 'spin_result', + integrations: { + All: true, + }, + message_id: 'a80f82be-9bdc-4a9f-b2a5-15621ee41df8', + properties: { + additional_bet_index: 0, + battle_id: 'N/A', + bet_amount: 9, + bet_level: 1, + bet_multiplier: 1, + coin_balance: 9466052, + current_module_name: 'CasinoGameModule', + days_in_game: 0, + extra_param: 'N/A', + fb_profile: '0', + featureGameType: 'N/A', + game_fps: 30, + game_id: 'fireEagleBase', + game_name: 'FireEagleSlots', + gem_balance: 0, + graphicsQuality: 'HD', + idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', + internetReachability: 'ReachableViaLocalAreaNetwork', + isLowEndDevice: 'False', + is_auto_spin: 'False', + is_turbo: 'False', + isf: 'False', + ishighroller: 'False', + jackpot_win_amount: 90, + jackpot_win_type: 'Silver', + level: 6, + lifetime_gem_balance: 0, + no_of_spin: 1, + player_total_battles: 0, + player_total_shields: 0, + start_date: '2019-08-01', + total_payments: 0, + tournament_id: 'T1561970819', + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + versionSessionCount: 2, + win_amount: 0, + }, + timestamp: '2019-09-01T15:46:51.693229+05:30', + type: 'track', + user_properties: { + coin_balance: 9466052, + current_module_name: 'CasinoGameModule', + fb_profile: '0', + game_fps: 30, + game_name: 'FireEagleSlots', + gem_balance: 0, + graphicsQuality: 'HD', + idfa: '2bf99787-33d2-4ae2-a76a-c49672f97252', + internetReachability: 'ReachableViaLocalAreaNetwork', + isLowEndDevice: false, + level: 6, + lifetime_gem_balance: 0, + player_total_battles: 0, + player_total_shields: 0, + start_date: '2019-08-01', + total_payments: 0, + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + versionSessionCount: 2, + }, + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + version: '1', + userId: 'c82cbdff-e5be-4009-ac78-cdeea09ab4b1', + type: 'REST', + method: 'PATCH', + endpoint: 'http://6b0e6a60.ngrok.io', + headers: { + 'content-type': 'application/json', + test2: 'value2', + }, + params: {}, + files: {}, + }, + metadata: { + destinationId: 'destId', + workspaceId: 'wspId', + }, + statusCode: 200, + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/webhook/router/data.ts b/test/integrations/destinations/webhook/router/data.ts index ec0bf5634e..291fc5ffba 100644 --- a/test/integrations/destinations/webhook/router/data.ts +++ b/test/integrations/destinations/webhook/router/data.ts @@ -375,7 +375,7 @@ export const data = [ cdkV2Enabled: true, }, }, - } + }, }, { batchedRequest: { From 091354c4427b33c9f8ac2678db3a4ab38b008e7d Mon Sep 17 00:00:00 2001 From: Anant Jain <62471433+anantjain45823@users.noreply.github.com> Date: Tue, 12 Dec 2023 14:09:07 +0530 Subject: [PATCH 84/93] feat: tiktok_ads: add support for custom events (#2891) * feat: tiktok_ads: add support for custom events * chore: added doc link --- src/v0/destinations/tiktok_ads/transform.js | 12 +- .../destinations/tiktok_ads/processor/data.ts | 292 ++++++++++++++++++ 2 files changed, 299 insertions(+), 5 deletions(-) diff --git a/src/v0/destinations/tiktok_ads/transform.js b/src/v0/destinations/tiktok_ads/transform.js index f0ed04a120..09f0d95dcc 100644 --- a/src/v0/destinations/tiktok_ads/transform.js +++ b/src/v0/destinations/tiktok_ads/transform.js @@ -128,7 +128,7 @@ const getTrackResponse = (message, Config, event) => { }; const trackResponseBuilder = async (message, { Config }) => { - const { eventsToStandard } = Config; + const { eventsToStandard, sendCustomEvents } = Config; let event = message.event?.toLowerCase().trim(); if (!event) { @@ -137,7 +137,7 @@ const trackResponseBuilder = async (message, { Config }) => { const standardEventsMap = getHashFromArrayWithDuplicate(eventsToStandard); - if (eventNameMapping[event] === undefined && !standardEventsMap[event]) { + if (!sendCustomEvents && eventNameMapping[event] === undefined && !standardEventsMap[event]) { throw new InstrumentationError( `Event name (${event}) is not valid, must be mapped to one of standard events`, ); @@ -152,10 +152,12 @@ const trackResponseBuilder = async (message, { Config }) => { }); } }); - } else { - event = eventNameMapping[event]; - responseList.push(getTrackResponse(message, Config, event)); + return responseList; } + // Doc https://ads.tiktok.com/help/article/standard-events-parameters?lang=en + event = eventNameMapping[event] || event; + // if there exists no event mapping we will build payload with custom event recieved + responseList.push(getTrackResponse(message, Config, event)); return responseList; }; diff --git a/test/integrations/destinations/tiktok_ads/processor/data.ts b/test/integrations/destinations/tiktok_ads/processor/data.ts index 453a875af2..46128f46b8 100644 --- a/test/integrations/destinations/tiktok_ads/processor/data.ts +++ b/test/integrations/destinations/tiktok_ads/processor/data.ts @@ -4660,4 +4660,296 @@ export const data = [ }, }, }, + { + name: 'tiktok_ads', + description: 'Test 29 -> custom_event Pass', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: '21e13f4bc7ceddad', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + ip: '13.57.97.131', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + externalId: [ + { + type: 'tiktokExternalId', + id: 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ], + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + timestamp: '2020-09-17T19:49:27Z', + type: 'track', + event: 'custom_event', + properties: { + eventId: '1616318632825_357', + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + clickId: 'dummyclickId', + currency: 'USD', + value: 46, + context: { + ad: { + callback: '123ATXSfe', + }, + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + }, + }, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + accessToken: 'dummyAccessToken', + pixelCode: 'A1T8T4UYGVIQA8ORZMX9', + hashUserProperties: false, + sendCustomEvents: true, + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://business-api.tiktok.com/open_api/v1.3/pixel/track/', + headers: { + 'Access-Token': 'dummyAccessToken', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + pixel_code: 'A1T8T4UYGVIQA8ORZMX9', + event: 'custom_event', + event_id: '1616318632825_357', + timestamp: '2020-09-17T19:49:27Z', + properties: { + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + currency: 'USD', + value: 46, + }, + context: { + ad: { + callback: 'dummyclickId', + }, + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + external_id: + 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ip: '13.57.97.131', + user_agent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + }, + partner_name: 'RudderStack', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'tiktok_ads', + description: 'Test 30 -> custom_event Failure case for flag set as false', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + anonymousId: '21e13f4bc7ceddad', + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.0.0', + }, + userAgent: + 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion', + ip: '13.57.97.131', + locale: 'en-US', + os: { + name: '', + version: '', + }, + screen: { + density: 2, + }, + externalId: [ + { + type: 'tiktokExternalId', + id: 'f0e388f53921a51f0bb0fc8a2944109ec188b59172935d8f23020b1614cc44bc', + }, + ], + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + timestamp: '2020-09-17T19:49:27Z', + type: 'track', + event: 'custom_event', + properties: { + eventId: '1616318632825_357', + contents: [ + { + price: 8, + quantity: 2, + content_type: 'socks', + content_id: '1077218', + }, + { + price: 30, + quantity: 1, + content_type: 'dress', + content_id: '1197218', + }, + ], + clickId: 'dummyclickId', + currency: 'USD', + value: 46, + context: { + ad: { + callback: '123ATXSfe', + }, + page: { + url: 'http://demo.mywebsite.com/purchase', + referrer: 'http://demo.mywebsite.com', + }, + user: { + phone_number: + '2f9d2b4df907e5c9a7b3434351b55700167b998a83dc479b825096486ffcf4ea', + email: 'dd6ff77f54e2106661089bae4d40cdb600979bf7edc9eb65c0942ba55c7c2d7f', + }, + }, + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + destination: { + Config: { + accessToken: 'dummyAccessToken', + pixelCode: 'A1T8T4UYGVIQA8ORZMX9', + hashUserProperties: false, + sendCustomEvents: false, + }, + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + statusCode: 400, + error: + 'Event name (custom_event) is not valid, must be mapped to one of standard events', + statTags: { + errorCategory: 'dataValidation', + errorType: 'instrumentation', + destType: 'TIKTOK_ADS', + module: 'destination', + implementation: 'native', + feature: 'processor', + }, + }, + ], + }, + }, + }, ]; From 5a6d296b0ce83f3b6b4e215839fb65d4e0f2de41 Mon Sep 17 00:00:00 2001 From: Sankeerth Date: Tue, 12 Dec 2023 14:39:08 +0530 Subject: [PATCH 85/93] fix: active_campaign error handler (#2895) * fix: send response object captured after API call to active_campaign error handler Signed-off-by: Sai Sankeerth * fix: add test-cases for 5xx, 4xx failures Signed-off-by: Sai Sankeerth --------- Signed-off-by: Sai Sankeerth Co-authored-by: Sai Sankeerth --- .../destinations/active_campaign/transform.js | 32 +- .../active_campaign/processor/data.ts | 388 ++++++++++++++++++ 2 files changed, 404 insertions(+), 16 deletions(-) diff --git a/src/v0/destinations/active_campaign/transform.js b/src/v0/destinations/active_campaign/transform.js index 973a928472..70caf47ea8 100644 --- a/src/v0/destinations/active_campaign/transform.js +++ b/src/v0/destinations/active_campaign/transform.js @@ -62,11 +62,11 @@ const syncContact = async (contactPayload, category, destination) => { feature: 'transformation', }); if (res.success === false) { - errorHandler(res.response, 'Failed to create new contact'); + errorHandler(res, 'Failed to create new contact'); } const createdContact = get(res, 'response.data.contact'); // null safe if (!createdContact) { - errorHandler(res.response, 'Failed to create new contact'); + errorHandler(res, 'Failed to create new contact'); } return createdContact.id; }; @@ -98,7 +98,7 @@ const customTagProcessor = async (message, category, destination, contactId) => feature: 'transformation', }); if (res.success === false) { - errorHandler(res.response, 'Failed to fetch already created tags'); + errorHandler(res, 'Failed to fetch already created tags'); } const storedTags = {}; @@ -169,7 +169,7 @@ const customTagProcessor = async (message, category, destination, contactId) => feature: 'transformation', }); if (res.success === false) { - errorHandler(res.response, 'Failed to create new tag'); + errorHandler(res, 'Failed to create new tag'); // For each tags successfully created the response id is pushed to tagIds } if (res.response.status === 201) tagIds.push(res.response.data.tag.id); @@ -201,7 +201,7 @@ const customTagProcessor = async (message, category, destination, contactId) => ); responsesArr.forEach((respItem) => { if (respItem.success === false) - errorHandler(respItem.response, 'Failed to merge created contact with created tags'); + errorHandler(respItem, 'Failed to merge created contact with created tags'); }); }; @@ -219,7 +219,7 @@ const customFieldProcessor = async (message, category, destination) => { // Step - 2 // Get the existing field data from dest and store it in responseStaging // Ref - https://developers.activecampaign.com/reference/retrieve-fields - let endpoint = `${destination.Config.apiUrl}${`${category.fieldEndPoint}?limit=100`}`; + let endpoint = `${destination.Config.apiUrl}${category.fieldEndPoint}?limit=100`; const requestOptions = { headers: { 'Api-Token': destination.Config.apiKey, @@ -230,7 +230,7 @@ const customFieldProcessor = async (message, category, destination) => { feature: 'transformation', }); if (res.success === false) { - errorHandler(res.response, 'Failed to get existing field data'); + errorHandler(res, 'Failed to get existing field data'); } responseStaging.push(res.response.status === 200 ? res.response.data.fields : []); @@ -257,7 +257,7 @@ const customFieldProcessor = async (message, category, destination) => { if (resp.success === true && resp.response.status === 200) { responseStaging.push(resp.response.data.fields); } else { - errorHandler(resp.response, 'Failed to get existing field data'); + errorHandler(resp, 'Failed to get existing field data'); } }); } @@ -352,7 +352,7 @@ const customListProcessor = async (message, category, destination, contactId) => const responses = await Promise.all(promises); responses.forEach((respItem) => { if (respItem.success === false) { - errorHandler(respItem.response, 'Failed to map created contact with the list'); + errorHandler(respItem, 'Failed to map created contact with the list'); } }); }; @@ -404,11 +404,11 @@ const screenRequestHandler = async (message, category, destination) => { feature: 'transformation', }); if (res.success === false) { - errorHandler(res.response, 'Failed to retrieve events'); + errorHandler(res, 'Failed to retrieve events'); } if (res?.response?.status !== 200) { - errorHandler(res.response, 'Unable to create event'); + errorHandler(res, 'Unable to create event'); } const storedEventsArr = res.response?.data?.eventTrackingEvents; @@ -431,11 +431,11 @@ const screenRequestHandler = async (message, category, destination) => { feature: 'transformation', }); if (res.success === false) { - errorHandler(res.response, 'Failed to create event'); + errorHandler(res, 'Failed to create event'); } if (res.response.status !== 201) { - errorHandler(res.response, 'Unable to create event'); + errorHandler(res, 'Unable to create event'); } } // Previous operations successfull then @@ -468,11 +468,11 @@ const trackRequestHandler = async (message, category, destination) => { }); if (res.success === false) { - errorHandler(res.response, 'Failed to retrieve events'); + errorHandler(res, 'Failed to retrieve events'); } if (res.response.status !== 200) { - errorHandler(res.response, 'Unable to fetch events. Aborting'); + errorHandler(res, 'Unable to fetch events. Aborting'); } const storedEventsArr = res.response?.data?.eventTrackingEvents; @@ -495,7 +495,7 @@ const trackRequestHandler = async (message, category, destination) => { feature: 'transformation', }); if (res.response?.status !== 201) { - errorHandler(res.response, 'Unable to create event. Aborting'); + errorHandler(res, 'Unable to create event. Aborting'); } } diff --git a/test/integrations/destinations/active_campaign/processor/data.ts b/test/integrations/destinations/active_campaign/processor/data.ts index 09499a9eee..cef8c2a3a8 100644 --- a/test/integrations/destinations/active_campaign/processor/data.ts +++ b/test/integrations/destinations/active_campaign/processor/data.ts @@ -1,3 +1,6 @@ +import MockAdapter from 'axios-mock-adapter'; +import { isMatch } from 'lodash'; + export const data = [ { name: 'active_campaign', @@ -765,4 +768,389 @@ export const data = [ }, }, }, + + { + name: 'active_campaign', + description: + 'Test 7: node error(ECONNABORTED) where there is no response coming from dest. server', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKey', + apiUrl: 'https://active.campaigns.dumber.com', + actid: '476550467', + eventKey: 'f8a866fddc721350fdc2fbbd2e5c43a6dddaaa03', + }, + }, + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { name: 'RudderLabs JavaScript SDK', version: '1.0.0' }, + 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', + locale: 'en-US', + ip: '0.0.0.0', + os: { name: '', version: '' }, + screen: { density: 2 }, + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + anonymousId: 'anon_id', + userId: '123456', + type: 'identify', + traits: { + anonymousId: 'anon_id', + email: 'patjane@gmail.com', + phone: '92374162213', + tags: ['Test_User', 'Interested_User', 'DIY_Hobby'], + fieldInfo: { + Office: 'Trastkiv', + Country: 'Russia', + Likes: ['Potato', 'Onion'], + Random: 'random', + }, + lists: [ + { id: 2, status: 'subscribe' }, + { id: 3, status: 'unsubscribe' }, + { id: 3, status: 'unsubscribexyz' }, + ], + address: { + city: 'kolkata', + country: 'India', + postalCode: 789223, + state: 'WB', + street: '', + }, + }, + integrations: { All: true }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + }, + ], + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + '{"message":"Failed to create new contact (undefined,\\"[ECONNABORTED] :: Connection aborted\\")","destinationResponse":"[ECONNABORTED] :: Connection aborted"}', + statTags: { + destType: 'ACTIVE_CAMPAIGN', + errorCategory: 'network', + errorType: 'retryable', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 500, + }, + ], + }, + }, + mockFns: (mockAdapter: MockAdapter) => { + mockAdapter + .onPost( + 'https://active.campaigns.dumber.com/api/3/contact/sync', + { + asymmetricMatch: (actual) => { + return isMatch(actual, { + contact: { + email: 'patjane@gmail.com', + phone: '92374162213', + }, + }); + }, + }, + { + asymmetricMatch: (actual) => { + return isMatch(actual, { + 'Api-Token': 'dummyApiKey', + 'Content-Type': 'application/json', + }); + }, + }, + ) + .abortRequest(); + }, + }, + { + name: 'active_campaign', + description: 'Test 8: erreneous response from active_campaign server(5xx)', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKey', + apiUrl: 'https://active.campaigns.dumber2.com', + actid: '476550467', + eventKey: 'f8a866fddc721350fdc2fbbd2e5c43a6dddaaa03', + }, + }, + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { name: 'RudderLabs JavaScript SDK', version: '1.0.0' }, + 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', + locale: 'en-US', + ip: '0.0.0.0', + os: { name: '', version: '' }, + screen: { density: 2 }, + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + anonymousId: 'anon_id', + userId: '123456', + type: 'identify', + traits: { + anonymousId: 'anon_id', + email: 'patjane1@gmail.com', + phone: '92374162213', + tags: ['Test_User', 'Interested_User', 'DIY_Hobby'], + fieldInfo: { + Office: 'Trastkiv', + Country: 'Russia', + Likes: ['Potato', 'Onion'], + Random: 'random', + }, + lists: [ + { id: 2, status: 'subscribe' }, + { id: 3, status: 'unsubscribe' }, + { id: 3, status: 'unsubscribexyz' }, + ], + address: { + city: 'kolkata', + country: 'India', + postalCode: 789223, + state: 'WB', + street: '', + }, + }, + integrations: { All: true }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + }, + ], + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + '{"message":"Failed to create new contact (undefined,\\"\\\\\\\\n\\\\\\\\n\\\\\\\\n\\\\\\\\n \\\\\\\\n\\\\\\\\n\\\\\\\\n\\\\\\\\naccurx.api-us1.com | 504: Gateway time-out\\\\\\\\n\\\\\\\\n\\\\\\\\n\\\\\\\\n\\\\\\\\n\\\\\\\\n\\\\\\\\n\\\\\\\\n\\\\\\\\n\\\\\\\\n\\\\\\\\n
\\\\\\\\n
\\\\\\\\n
\\\\\\\\n

\\\\\\\\n Gateway time-out\\\\\\\\n Error code 504\\\\\\\\n

\\\\\\\\n
\\\\\\\\n Visit cloudflare.com for more information.\\\\\\\\n
\\\\\\\\n
2023-12-06 10:33:27 UTC
\\\\\\\\n
\\\\\\\\n
\\\\\\\\n
\\\\\\\\n
\\\\\\\\n \\\\\\\\n
\\\\\\\\n
\\\\\\\\n \\\\\\\\n \\\\\\\\n \\\\\\\\n \\\\\\\\n
\\\\\\\\n You\\\\\\\\n

\\\\\\\\n \\\\\\\\n Browser\\\\\\\\n \\\\\\\\n

\\\\\\\\n Working\\\\\\\\n
\\\\\\\\n\\\\\\\\n
\\\\\\\\n
\\\\\\\\n \\\\\\\\n \\\\\\\\n \\\\\\\\n \\\\\\\\n
\\\\\\\\n Frankfurt\\\\\\\\n

\\\\\\\\n \\\\\\\\n Cloudflare\\\\\\\\n \\\\\\\\n

\\\\\\\\n Working\\\\\\\\n
\\\\\\\\n\\\\\\\\n
\\\\\\\\n
\\\\\\\\n \\\\\\\\n \\\\\\\\n \\\\\\\\n \\\\\\\\n
\\\\\\\\n accurx.api-us1.com\\\\\\\\n

\\\\\\\\n \\\\\\\\n Host\\\\\\\\n \\\\\\\\n

\\\\\\\\n Error\\\\\\\\n
\\\\\\\\n\\\\\\\\n
\\\\\\\\n
\\\\\\\\n
\\\\\\\\n\\\\\\\\n
\\\\\\\\n
\\\\\\\\n
\\\\\\\\n

What happened?

\\\\\\\\n

The web server reported a gateway time-out error.

\\\\\\\\n
\\\\\\\\n
\\\\\\\\n

What can I do?

\\\\\\\\n

Please try again in a few minutes.

\\\\\\\\n
\\\\\\\\n
\\\\\\\\n
\\\\\\\\n\\\\\\\\n \\\\\\\\n\\\\\\\\n\\\\\\\\n
\\\\\\\\n
\\\\\\\\n\\\\\\\\n\\\\\\\\n\\\\\\")\\")","destinationResponse":"\\\\n\\\\n\\\\n\\\\n \\\\n\\\\n\\\\n\\\\naccurx.api-us1.com | 504: Gateway time-out\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n
\\\\n
\\\\n
\\\\n

\\\\n Gateway time-out\\\\n Error code 504\\\\n

\\\\n
\\\\n Visit cloudflare.com for more information.\\\\n
\\\\n
2023-12-06 10:33:27 UTC
\\\\n
\\\\n
\\\\n
\\\\n
\\\\n \\\\n
\\\\n
\\\\n \\\\n \\\\n \\\\n \\\\n
\\\\n You\\\\n

\\\\n \\\\n Browser\\\\n \\\\n

\\\\n Working\\\\n
\\\\n\\\\n
\\\\n
\\\\n \\\\n \\\\n \\\\n \\\\n
\\\\n Frankfurt\\\\n

\\\\n \\\\n Cloudflare\\\\n \\\\n

\\\\n Working\\\\n
\\\\n\\\\n
\\\\n
\\\\n \\\\n \\\\n \\\\n \\\\n
\\\\n accurx.api-us1.com\\\\n

\\\\n \\\\n Host\\\\n \\\\n

\\\\n Error\\\\n
\\\\n\\\\n
\\\\n
\\\\n
\\\\n\\\\n
\\\\n
\\\\n
\\\\n

What happened?

\\\\n

The web server reported a gateway time-out error.

\\\\n
\\\\n
\\\\n

What can I do?

\\\\n

Please try again in a few minutes.

\\\\n
\\\\n
\\\\n
\\\\n\\\\n \\\\n\\\\n\\\\n
\\\\n
\\\\n\\\\n\\\\n\\")"}', + statTags: { + destType: 'ACTIVE_CAMPAIGN', + errorCategory: 'network', + errorType: 'retryable', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 504, + }, + ], + }, + }, + mockFns: (mockAdapter: MockAdapter) => { + mockAdapter + .onPost( + 'https://active.campaigns.dumber2.com/api/3/contact/sync', + { + asymmetricMatch: (actual) => { + return isMatch(actual, { + contact: { + email: 'patjane1@gmail.com', + phone: '92374162213', + }, + }); + }, + }, + { + asymmetricMatch: (actual) => { + return isMatch(actual, { + 'Api-Token': 'dummyApiKey', + 'Content-Type': 'application/json', + }); + }, + }, + ) + .replyOnce( + 504, + '\\n\\n\\n\\n \\n\\n\\n\\naccurx.api-us1.com | 504: Gateway time-out\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n
\\n
\\n
\\n

\\n Gateway time-out\\n Error code 504\\n

\\n
\\n Visit cloudflare.com for more information.\\n
\\n
2023-12-06 10:33:27 UTC
\\n
\\n
\\n
\\n
\\n \\n
\\n
\\n \\n \\n \\n \\n
\\n You\\n

\\n \\n Browser\\n \\n

\\n Working\\n
\\n\\n
\\n
\\n \\n \\n \\n \\n
\\n Frankfurt\\n

\\n \\n Cloudflare\\n \\n

\\n Working\\n
\\n\\n
\\n
\\n \\n \\n \\n \\n
\\n accurx.api-us1.com\\n

\\n \\n Host\\n \\n

\\n Error\\n
\\n\\n
\\n
\\n
\\n\\n
\\n
\\n
\\n

What happened?

\\n

The web server reported a gateway time-out error.

\\n
\\n
\\n

What can I do?

\\n

Please try again in a few minutes.

\\n
\\n
\\n
\\n\\n \\n\\n\\n
\\n
\\n\\n\\n")', + { + Accept: 'application/json, text/plain, */*', + 'Api-Token': 'dummyApiKey', + }, + ); + }, + }, + { + name: 'active_campaign', + description: 'Test 9: erreneous response from active_campaign server(4xx)', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKey', + apiUrl: 'https://active.campaigns.dumber2.com', + actid: '476550467', + eventKey: 'f8a866fddc721350fdc2fbbd2e5c43a6dddaaa03', + }, + }, + message: { + channel: 'web', + context: { + app: { + build: '1.0.0', + name: 'RudderLabs JavaScript SDK', + namespace: 'com.rudderlabs.javascript', + version: '1.0.0', + }, + library: { name: 'RudderLabs JavaScript SDK', version: '1.0.0' }, + 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', + locale: 'en-US', + ip: '0.0.0.0', + os: { name: '', version: '' }, + screen: { density: 2 }, + }, + messageId: '84e26acc-56a5-4835-8233-591137fca468', + session_id: '3049dc4c-5a95-4ccd-a3e7-d74a7e411f22', + originalTimestamp: '2019-10-14T09:03:17.562Z', + anonymousId: 'anon_id', + userId: '123456', + type: 'identify', + traits: { + anonymousId: 'anon_id', + email: 'patjane2@gmail.com', + phone: '92374162213', + tags: ['Test_User', 'Interested_User', 'DIY_Hobby'], + fieldInfo: { + Office: 'Trastkiv', + Country: 'Russia', + Likes: ['Potato', 'Onion'], + Random: 'random', + }, + lists: [ + { id: 2, status: 'subscribe' }, + { id: 3, status: 'unsubscribe' }, + { id: 3, status: 'unsubscribexyz' }, + ], + address: { + city: 'kolkata', + country: 'India', + postalCode: 789223, + state: 'WB', + street: '', + }, + }, + integrations: { All: true }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + }, + ], + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + '{"message":"Failed to create new contact (undefined,{\\"errors\\":[{\\"title\\":\\"Contact Email Address is not valid.\\",\\"detail\\":\\"\\",\\"code\\":\\"email_invalid\\",\\"error\\":\\"must_be_valid_email_address\\",\\"source\\":{\\"pointer\\":\\"/data/attributes/email\\"}}]})","destinationResponse":{"errors":[{"title":"Contact Email Address is not valid.","detail":"","code":"email_invalid","error":"must_be_valid_email_address","source":{"pointer":"/data/attributes/email"}}]}}', + statTags: { + destType: 'ACTIVE_CAMPAIGN', + errorCategory: 'network', + errorType: 'aborted', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 422, + }, + ], + }, + }, + mockFns: (mockAdapter: MockAdapter) => { + mockAdapter + .onPost( + 'https://active.campaigns.dumber2.com/api/3/contact/sync', + { + asymmetricMatch: (actual) => { + return isMatch(actual, { + contact: { + email: 'patjane2@gmail.com', + phone: '92374162213', + }, + }); + }, + }, + { + asymmetricMatch: (actual) => { + return isMatch(actual, { + 'Api-Token': 'dummyApiKey', + 'Content-Type': 'application/json', + }); + }, + }, + ) + .replyOnce( + 422, + { + errors: [ + { + title: 'Contact Email Address is not valid.', + detail: '', + code: 'email_invalid', + error: 'must_be_valid_email_address', + source: { + pointer: '/data/attributes/email', + }, + }, + ], + }, + { + Accept: 'application/json, text/plain, */*', + 'Api-Token': 'dummyApiKey', + }, + ); + }, + }, ]; From eb28f4a94d1e204c5aaf547c7cb5d48ac2d96fd4 Mon Sep 17 00:00:00 2001 From: Dilip Kola <33080863+koladilip@users.noreply.github.com> Date: Tue, 12 Dec 2023 15:00:59 +0530 Subject: [PATCH 86/93] Update draft-new-release.yml --- .github/workflows/draft-new-release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/draft-new-release.yml b/.github/workflows/draft-new-release.yml index 23e243918f..57dd33f0b4 100644 --- a/.github/workflows/draft-new-release.yml +++ b/.github/workflows/draft-new-release.yml @@ -8,7 +8,7 @@ jobs: runs-on: ubuntu-latest # Only allow release stakeholders to initiate releases - if: (github.ref == 'refs/heads/develop' || startsWith(github.ref, 'refs/heads/hotfix/')) && (github.actor == 'ItsSudip' || github.actor == 'krishna2020' || github.actor == 'saikumarrs' || github.actor == 'sandeepdsvs' || github.actor == 'shrouti1507' || github.actor == 'anantjain45823' || github.actor == 'chandumlg' || github.actor == 'mihir-4116' || github.actor == 'yashasvibajpai' || github.actor == 'sanpj2292' || github.actor == 'ujjwal-ab') && (github.triggering_actor == 'ItsSudip' || github.triggering_actor == 'krishna2020' || github.triggering_actor == 'saikumarrs' || github.triggering_actor == 'sandeepdsvs' || github.triggering_actor == 'shrouti1507' || github.triggering_actor == 'anantjain45823' || github.triggering_actor == 'chandumlg' || github.triggering_actor == 'mihir-4116' || github.triggering_actor == 'yashasvibajpai' || github.triggering_actor == 'sanpj2292' || github.triggering_actor == 'ujjwal-ab') + if: (github.ref == 'refs/heads/develop' || startsWith(github.ref, 'refs/heads/hotfix/')) && (github.actor == 'ItsSudip' || github.actor == 'krishna2020' || github.actor == 'saikumarrs' || github.actor == 'sandeepdsvs' || github.actor == 'koladilip' || github.actor == 'shrouti1507' || github.actor == 'anantjain45823' || github.actor == 'chandumlg' || github.actor == 'mihir-4116' || github.actor == 'yashasvibajpai' || github.actor == 'sanpj2292' || github.actor == 'ujjwal-ab') && (github.triggering_actor == 'ItsSudip' || github.triggering_actor == 'krishna2020' || github.triggering_actor == 'koladilip' || github.triggering_actor == 'saikumarrs' || github.triggering_actor == 'sandeepdsvs' || github.triggering_actor == 'shrouti1507' || github.triggering_actor == 'anantjain45823' || github.triggering_actor == 'chandumlg' || github.triggering_actor == 'mihir-4116' || github.triggering_actor == 'yashasvibajpai' || github.triggering_actor == 'sanpj2292' || github.triggering_actor == 'ujjwal-ab') steps: - name: Checkout uses: actions/checkout@v3.5.3 From b55feed4f8f18f88b20a452cc8ef826a10162e1d Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Tue, 12 Dec 2023 09:33:34 +0000 Subject: [PATCH 87/93] chore(release): 1.52.0 --- CHANGELOG.md | 22 ++++++++++++++++++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b769b51a6d..1e0c6ffb14 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,28 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +## [1.52.0](https://github.com/rudderlabs/rudder-transformer/compare/v1.51.1...v1.52.0) (2023-12-12) + + +### Features + +* onboard msl changes for new record event ([#2644](https://github.com/rudderlabs/rudder-transformer/issues/2644)) ([36d3f25](https://github.com/rudderlabs/rudder-transformer/commit/36d3f258ed5ea4ba1899c8b2cae8203bf73d90ed)), closes [#2813](https://github.com/rudderlabs/rudder-transformer/issues/2813) +* onboard reddit cloud mode destination ([#2829](https://github.com/rudderlabs/rudder-transformer/issues/2829)) ([babb89a](https://github.com/rudderlabs/rudder-transformer/commit/babb89a5bf6d1b84d1319b967953c7c1b6de7c2c)) +* tiktok_ads: add support for custom events ([#2891](https://github.com/rudderlabs/rudder-transformer/issues/2891)) ([091354c](https://github.com/rudderlabs/rudder-transformer/commit/091354c4427b33c9f8ac2678db3a4ab38b008e7d)) + + +### Bug Fixes + +* active_campaign error handler ([#2895](https://github.com/rudderlabs/rudder-transformer/issues/2895)) ([5a6d296](https://github.com/rudderlabs/rudder-transformer/commit/5a6d296b0ce83f3b6b4e215839fb65d4e0f2de41)) +* add check to remove empty properties object from payload ([#2896](https://github.com/rudderlabs/rudder-transformer/issues/2896)) ([1a86a07](https://github.com/rudderlabs/rudder-transformer/commit/1a86a0723e3f5fb6fdf9cf1dc716a47c6da16745)) +* adobe_analytics event field check ([#2890](https://github.com/rudderlabs/rudder-transformer/issues/2890)) ([bf39215](https://github.com/rudderlabs/rudder-transformer/commit/bf39215dd1bbed482665c837a2bfabfcb751c753)) +* covert toString before toLowercase ([#2830](https://github.com/rudderlabs/rudder-transformer/issues/2830)) ([bed431e](https://github.com/rudderlabs/rudder-transformer/commit/bed431e1de94ab28df1ee592d083a1481b960b6d)) +* **dm:** add workspaceId in common metadata to be returned to the callers ([#2868](https://github.com/rudderlabs/rudder-transformer/issues/2868)) ([b3437a3](https://github.com/rudderlabs/rudder-transformer/commit/b3437a34358d5fd5b1eb63f30a5a695f39aa84ff)) +* **integrations:** onboard sprig destination ([#2857](https://github.com/rudderlabs/rudder-transformer/issues/2857)) ([ede22e3](https://github.com/rudderlabs/rudder-transformer/commit/ede22e3f8fb60a9e36e2a3f5a5e86260255c49ef)) +* mailjet source transformation by adding email exists check ([#2889](https://github.com/rudderlabs/rudder-transformer/issues/2889)) ([4a7eaa0](https://github.com/rudderlabs/rudder-transformer/commit/4a7eaa09000bcb82eb7f217d500223939bd9b07b)) +* missing null check in braze populateCustomAttributesWithOperation ([#2897](https://github.com/rudderlabs/rudder-transformer/issues/2897)) ([50e921d](https://github.com/rudderlabs/rudder-transformer/commit/50e921d1451bf7016e60b2e238b8f842d72b5b71)) +* removed retry logic from v1 cm360, added adapter for v1 to v0 conversion ([#2860](https://github.com/rudderlabs/rudder-transformer/issues/2860)) ([776d2c4](https://github.com/rudderlabs/rudder-transformer/commit/776d2c4abe23cd279195064684b9ccc807d83afc)) + ### [1.51.1](https://github.com/rudderlabs/rudder-transformer/compare/v1.51.0...v1.51.1) (2023-12-06) diff --git a/package-lock.json b/package-lock.json index 61501c6c08..440bb9ea46 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "rudder-transformer", - "version": "1.51.1", + "version": "1.52.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "rudder-transformer", - "version": "1.51.1", + "version": "1.52.0", "license": "ISC", "dependencies": { "@amplitude/ua-parser-js": "^0.7.24", diff --git a/package.json b/package.json index 7f4aa1c5a5..fe3c9f51b3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rudder-transformer", - "version": "1.51.1", + "version": "1.52.0", "description": "", "homepage": "https://github.com/rudderlabs/rudder-transformer#readme", "bugs": { From 439ba73195ddab06eb4bbaafb94b104d2f77d533 Mon Sep 17 00:00:00 2001 From: Abhimanyu Babbar Date: Tue, 12 Dec 2023 19:34:56 +0530 Subject: [PATCH 88/93] fix(dm): dropped support of useClones for trackingplans cache (#2899) * dropped support of useClones for trackingplans cache * updated the changelog --- CHANGELOG.md | 1 + src/util/trackingPlan.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e0c6ffb14..561aaa900f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ All notable changes to this project will be documented in this file. See [standa * mailjet source transformation by adding email exists check ([#2889](https://github.com/rudderlabs/rudder-transformer/issues/2889)) ([4a7eaa0](https://github.com/rudderlabs/rudder-transformer/commit/4a7eaa09000bcb82eb7f217d500223939bd9b07b)) * missing null check in braze populateCustomAttributesWithOperation ([#2897](https://github.com/rudderlabs/rudder-transformer/issues/2897)) ([50e921d](https://github.com/rudderlabs/rudder-transformer/commit/50e921d1451bf7016e60b2e238b8f842d72b5b71)) * removed retry logic from v1 cm360, added adapter for v1 to v0 conversion ([#2860](https://github.com/rudderlabs/rudder-transformer/issues/2860)) ([776d2c4](https://github.com/rudderlabs/rudder-transformer/commit/776d2c4abe23cd279195064684b9ccc807d83afc)) +* **dm:** use clones as false for tracking plan node cache ([#2899](https://github.com/rudderlabs/rudder-transformer/issues/2899)) ([8f47db8](https://github.com/rudderlabs/rudder-transformer/commit/8f47db8bcf581d1807cfa2aa823ef400a30a09e3)) ### [1.51.1](https://github.com/rudderlabs/rudder-transformer/compare/v1.51.0...v1.51.1) (2023-12-06) diff --git a/src/util/trackingPlan.js b/src/util/trackingPlan.js index 0c03820308..a77265a5b8 100644 --- a/src/util/trackingPlan.js +++ b/src/util/trackingPlan.js @@ -4,7 +4,7 @@ const logger = require('../logger'); const { responseStatusHandler } = require('./utils'); const stats = require('./stats'); -const tpCache = new NodeCache(); +const tpCache = new NodeCache({ useClones: false }); const CONFIG_BACKEND_URL = process.env.CONFIG_BACKEND_URL || 'https://api.rudderlabs.com'; const TRACKING_PLAN_URL = `${CONFIG_BACKEND_URL}/workspaces`; From be208501db5e978f66e09f09a05058289539ad70 Mon Sep 17 00:00:00 2001 From: Yashasvi Bajpai <33063622+yashasvibajpai@users.noreply.github.com> Date: Wed, 13 Dec 2023 09:08:54 +0530 Subject: [PATCH 89/93] chore: add stringtype check to escapehtml in adobe (#2900) --- src/v0/destinations/adobe_analytics/utils.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/v0/destinations/adobe_analytics/utils.js b/src/v0/destinations/adobe_analytics/utils.js index bcb138d77b..97dc6e90bb 100644 --- a/src/v0/destinations/adobe_analytics/utils.js +++ b/src/v0/destinations/adobe_analytics/utils.js @@ -83,6 +83,9 @@ function handleContextData(payload, destinationConfig, message) { */ function escapeToHTML(inputString) { + if (typeof inputString !== 'string') { + return inputString; + } return inputString.replace( /[&<>]/g, (match) => From 90c725e3ecd6c4476d66a54b84f34e0f4a7b205c Mon Sep 17 00:00:00 2001 From: Sankeerth Date: Wed, 13 Dec 2023 13:17:09 +0530 Subject: [PATCH 90/93] fix: braze transformation error due to wrong import (#2901) --- src/v0/util/errorTypes/filteredEventsError.js | 2 +- src/v0/util/errorTypes/transformerProxyError.js | 2 +- src/v0/util/index.js | 2 +- src/v0/util/index.test.js | 10 ++++++++++ test/__tests__/data/braze_router.json | 4 +--- 5 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/v0/util/errorTypes/filteredEventsError.js b/src/v0/util/errorTypes/filteredEventsError.js index cb0236f342..990ca76670 100644 --- a/src/v0/util/errorTypes/filteredEventsError.js +++ b/src/v0/util/errorTypes/filteredEventsError.js @@ -1,4 +1,4 @@ -const { BaseError } = require('./base'); +const { BaseError } = require('@rudderstack/integrations-lib'); const { HTTP_STATUS_CODES } = require('../constant'); class FilteredEventsError extends BaseError { diff --git a/src/v0/util/errorTypes/transformerProxyError.js b/src/v0/util/errorTypes/transformerProxyError.js index 42ccdea490..2fefb6fb92 100644 --- a/src/v0/util/errorTypes/transformerProxyError.js +++ b/src/v0/util/errorTypes/transformerProxyError.js @@ -1,5 +1,5 @@ +const { BaseError } = require('@rudderstack/integrations-lib'); const tags = require('../tags'); -const { BaseError } = require('./base'); const errorTypes = Object.values(tags.ERROR_TYPES); const metaTypes = Object.values(tags.METADATA); diff --git a/src/v0/util/index.js b/src/v0/util/index.js index fee1d7a96d..34182a7685 100644 --- a/src/v0/util/index.js +++ b/src/v0/util/index.js @@ -83,7 +83,7 @@ const isPrimitive = (arg) => { const isNewStatusCodesAccepted = (reqMetadata = {}) => { if (reqMetadata && typeof reqMetadata === 'object' && !Array.isArray(reqMetadata)) { const { features } = reqMetadata; - return !!(features && features[FEATURE_FILTER_CODE]); + return !!features?.[FEATURE_FILTER_CODE]; } return false; }; diff --git a/src/v0/util/index.test.js b/src/v0/util/index.test.js index e39c583aab..65d6313e30 100644 --- a/src/v0/util/index.test.js +++ b/src/v0/util/index.test.js @@ -1,5 +1,7 @@ +const { TAG_NAMES } = require('@rudderstack/integrations-lib'); const utilities = require('.'); const { getFuncTestData } = require('../../../test/testHelper'); +const { FilteredEventsError } = require('./errorTypes'); const { hasCircularReference, flattenJson } = require('./index'); // Names of the utility functions to test @@ -116,3 +118,11 @@ describe('flattenJson', () => { ); }); }); + +describe('tests for generateErrorObject', () => { + test('test-0', () => { + const myErr = new FilteredEventsError('error-1'); + const outputErrObj = utilities.generateErrorObject(myErr); + expect(outputErrObj.statTags).toEqual({}); + }); +}); diff --git a/test/__tests__/data/braze_router.json b/test/__tests__/data/braze_router.json index 8bfd7c7d42..33c66bca6d 100644 --- a/test/__tests__/data/braze_router.json +++ b/test/__tests__/data/braze_router.json @@ -841,9 +841,7 @@ }, { "error": "[Braze Deduplication]: Duplicate user detected, the user is dropped", - "statTags": { - "errorCategory": "transformation" - }, + "statTags": {}, "statusCode": 298, "batched": false, "metadata": [ From aad248077b5036b64d5700f8dbf61260ea36a2de Mon Sep 17 00:00:00 2001 From: Yashasvi Bajpai <33063622+yashasvibajpai@users.noreply.github.com> Date: Wed, 13 Dec 2023 13:29:15 +0530 Subject: [PATCH 91/93] chore: add lowercase check to MSL for event type audiencelist (#2904) * chore: add lowercase check to MSL for event type audiencelist * chore: fix optional chaining Co-authored-by: Utsab Chowdhury * chore: update test --------- Co-authored-by: Utsab Chowdhury --- src/v0/destinations/marketo_static_list/transform.js | 2 +- .../destinations/marketo_static_list/router/data.ts | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/v0/destinations/marketo_static_list/transform.js b/src/v0/destinations/marketo_static_list/transform.js index cbdb89f532..294e34f91b 100644 --- a/src/v0/destinations/marketo_static_list/transform.js +++ b/src/v0/destinations/marketo_static_list/transform.js @@ -124,7 +124,7 @@ const processRouterDest = async (inputs, reqMetadata) => { // use lodash.groupby to group the inputs based on message type const transformedRecordEvent = []; let transformedAudienceEvent = []; - const groupedInputs = lodash.groupBy(inputs, (input) => input.message.type); + const groupedInputs = lodash.groupBy(inputs, (input) => input.message.type?.toLowerCase()); const respList = []; // process record events diff --git a/test/integrations/destinations/marketo_static_list/router/data.ts b/test/integrations/destinations/marketo_static_list/router/data.ts index fa97ba49f2..840ad773b3 100644 --- a/test/integrations/destinations/marketo_static_list/router/data.ts +++ b/test/integrations/destinations/marketo_static_list/router/data.ts @@ -1,7 +1,8 @@ export const data = [ { name: 'marketo_static_list', - description: 'Test 0: Test audiencelist event with add and remove', + description: + 'Test 0: Test audiencelist event with add and remove: Test eventtype lowercase and uppercase', feature: 'router', module: 'destination', version: 'v0', @@ -99,7 +100,7 @@ export const data = [ userId: 'user 1', anonymousId: 'anon-id-new', event: 'event1', - type: 'audiencelist', + type: 'audienceList', properties: { listData: { add: [ From 7825c19f6d8ba633a8a81160aceb7560ce293e41 Mon Sep 17 00:00:00 2001 From: AASHISH MALIK Date: Wed, 13 Dec 2023 14:42:57 +0530 Subject: [PATCH 92/93] fix: updated error response of v1 proxy (#2906) --- .../destination/postTransformation.ts | 8 +- .../destinations/braze/dataDelivery/data.ts | 177 +++++++++++++++++- .../destinations/braze/network.ts | 43 +++++ 3 files changed, 225 insertions(+), 3 deletions(-) diff --git a/src/services/destination/postTransformation.ts b/src/services/destination/postTransformation.ts index de2f5f1b42..7e9cd52aed 100644 --- a/src/services/destination/postTransformation.ts +++ b/src/services/destination/postTransformation.ts @@ -18,6 +18,7 @@ import { generateErrorObject } from '../../v0/util'; import { ErrorReportingService } from '../errorReporting'; import tags from '../../v0/util/tags'; import stats from '../../util/stats'; +import { FixMe } from '../../util/types'; export class DestinationPostTransformationService { public static handleProcessorTransformSucessEvents( @@ -161,7 +162,7 @@ export class DestinationPostTransformationService { } public static handlevV1DeliveriesFailureEvents( - error: NonNullable, + error: FixMe, metaTo: MetaTransferObject, ): DeliveriesResponse { const errObj = generateErrorObject(error, metaTo.errorDetails, false); @@ -172,7 +173,10 @@ export class DestinationPostTransformationService { } const responses = metadataArray.map((metadata) => { const resp = { - error: errObj.message || '[Delivery] Error occured while processing payload', + error: + JSON.stringify(error.destinationResponse?.response) || + errObj.message || + '[Delivery] Error occured while processing payload', statusCode: errObj.status, metadata, } as DeliveryJobState; diff --git a/test/integrations/destinations/braze/dataDelivery/data.ts b/test/integrations/destinations/braze/dataDelivery/data.ts index cd688a621b..d62361e7f9 100644 --- a/test/integrations/destinations/braze/dataDelivery/data.ts +++ b/test/integrations/destinations/braze/dataDelivery/data.ts @@ -632,7 +632,7 @@ export const data = [ output: { response: [ { - error: 'Request failed for braze with status: 401', + error: '{"code":400,"message":"Bad Req","status":"Fail Case"}', statusCode: 401, metadata: { jobId: 2, @@ -664,4 +664,179 @@ export const data = [ }, }, }, + { + name: 'braze', + description: + 'Test Transformer Proxy V1 input with v0 proxy handler Error returned Multiple metadata Track Event', + feature: 'dataDelivery', + module: 'destination', + version: 'v1', + input: { + request: { + body: { + type: 'REST', + endpoint: 'https://rest.iad-03.braze.com/users/track/testV1', + method: 'POST', + userId: 'gabi_userId_45', + headers: { + Accept: 'application/json', + Authorization: 'Bearer api_key', + 'Content-Type': 'application/json', + }, + body: { + FORM: {}, + JSON: { + partner: 'RudderStack', + attributes: [ + { + email: '123@a.com', + city: 'Disney', + country: 'USA', + firstname: 'Mickey', + external_id: '456345345', + }, + { + email: '123@a.com', + city: 'Disney', + country: 'USA', + firstname: 'Mickey', + external_id: '456345345', + }, + { + email: '123@a.com', + city: 'Disney', + country: 'USA', + firstname: 'Mickey', + external_id: '456345345', + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + }, + metadata: [ + { + jobId: 2, + attemptNum: 0, + userId: '', + sourceId: '2Vsge2uWYdrLfG7pZb5Y82eo4lr', + destinationId: '2RHh08uOsXqE9KvCDg3hoaeuK2L', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', + secret: { + access_token: 'secret', + refresh_token: 'refresh', + developer_token: 'developer_Token', + }, + }, + { + jobId: 3, + attemptNum: 0, + userId: '', + sourceId: '2Vsge2uWYdrLfG7pZb5Y82eo4lr', + destinationId: '2RHh08uOsXqE9KvCDg3hoaeuK2L', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', + secret: { + access_token: 'secret', + refresh_token: 'refresh', + developer_token: 'developer_Token', + }, + }, + { + jobId: 4, + attemptNum: 0, + userId: '', + sourceId: '2Vsge2uWYdrLfG7pZb5Y82eo4lr', + destinationId: '2RHh08uOsXqE9KvCDg3hoaeuK2L', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', + secret: { + access_token: 'secret', + refresh_token: 'refresh', + developer_token: 'developer_Token', + }, + }, + ], + files: {}, + params: { + destination: 'braze', + }, + }, + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: { + response: [ + { + error: + '{"message":"Valid data must be provided in the \'attributes\', \'events\', or \'purchases\' fields.","errors":[{"type":"The value provided for the \'email\' field is not a valid email.","input_array":"attributes","index":0},{"type":"The value provided for the \'email\' field is not a valid email.","input_array":"attributes","index":1}]}', + statusCode: 401, + metadata: { + jobId: 2, + attemptNum: 0, + userId: '', + sourceId: '2Vsge2uWYdrLfG7pZb5Y82eo4lr', + destinationId: '2RHh08uOsXqE9KvCDg3hoaeuK2L', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', + secret: { + access_token: 'secret', + refresh_token: 'refresh', + developer_token: 'developer_Token', + }, + }, + }, + { + error: + '{"message":"Valid data must be provided in the \'attributes\', \'events\', or \'purchases\' fields.","errors":[{"type":"The value provided for the \'email\' field is not a valid email.","input_array":"attributes","index":0},{"type":"The value provided for the \'email\' field is not a valid email.","input_array":"attributes","index":1}]}', + statusCode: 401, + metadata: { + jobId: 3, + attemptNum: 0, + userId: '', + sourceId: '2Vsge2uWYdrLfG7pZb5Y82eo4lr', + destinationId: '2RHh08uOsXqE9KvCDg3hoaeuK2L', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', + secret: { + access_token: 'secret', + refresh_token: 'refresh', + developer_token: 'developer_Token', + }, + }, + }, + { + error: + '{"message":"Valid data must be provided in the \'attributes\', \'events\', or \'purchases\' fields.","errors":[{"type":"The value provided for the \'email\' field is not a valid email.","input_array":"attributes","index":0},{"type":"The value provided for the \'email\' field is not a valid email.","input_array":"attributes","index":1}]}', + statusCode: 401, + metadata: { + jobId: 4, + attemptNum: 0, + userId: '', + sourceId: '2Vsge2uWYdrLfG7pZb5Y82eo4lr', + destinationId: '2RHh08uOsXqE9KvCDg3hoaeuK2L', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', + secret: { + access_token: 'secret', + refresh_token: 'refresh', + developer_token: 'developer_Token', + }, + }, + }, + ], + statTags: { + destType: 'BRAZE', + destinationId: '2RHh08uOsXqE9KvCDg3hoaeuK2L', + errorCategory: 'network', + errorType: 'aborted', + feature: 'dataDelivery', + implementation: 'native', + module: 'destination', + workspaceId: '2Csl0lSTbuM3qyHdaOQB2GcDH8o', + }, + }, + }, + }, + }, + }, ]; diff --git a/test/integrations/destinations/braze/network.ts b/test/integrations/destinations/braze/network.ts index 0ef99b806d..3db50ca32c 100644 --- a/test/integrations/destinations/braze/network.ts +++ b/test/integrations/destinations/braze/network.ts @@ -420,5 +420,48 @@ const deleteNwData = [ status: 401, }, }, + { + httpReq: { + url: 'https://rest.iad-03.braze.com/users/track/testV1', + data: { + partner: 'RudderStack', + attributes: [ + { + email: '123@a.com', + city: 'Disney', + country: 'USA', + firstname: 'Mickey', + external_id: '456345345', + }, + { + email: '123@a.com', + city: 'Disney', + country: 'USA', + firstname: 'Mickey', + external_id: '456345345', + }, + { + email: '123@a.com', + city: 'Disney', + country: 'USA', + firstname: 'Mickey', + external_id: '456345345', + }, + ], + }, + params: { destination: 'braze' }, + headers: { + Accept: 'application/json', + Authorization: 'Bearer api_key', + 'Content-Type': 'application/json', + 'User-Agent': 'RudderLabs', + }, + method: 'POST', + }, + httpRes: { + data: '{"message":"Valid data must be provided in the \'attributes\', \'events\', or \'purchases\' fields.","errors":[{"type":"The value provided for the \'email\' field is not a valid email.","input_array":"attributes","index":0},{"type":"The value provided for the \'email\' field is not a valid email.","input_array":"attributes","index":1}]}', + status: 401, + }, + }, ]; export const networkCallsData = [...deleteNwData, ...dataDeliveryMocksData]; From a606ec1ff138eed291a68fa78fd03e19c02b1622 Mon Sep 17 00:00:00 2001 From: Ujjwal Abhishek <63387036+ujjwal-ab@users.noreply.github.com> Date: Wed, 13 Dec 2023 14:46:19 +0530 Subject: [PATCH 93/93] fix(reddit): add undefined check for eventsMapping field (#2905) feat: add undefined check for evensMapping field --- src/cdk/v2/destinations/reddit/procWorkflow.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cdk/v2/destinations/reddit/procWorkflow.yaml b/src/cdk/v2/destinations/reddit/procWorkflow.yaml index b07aeff962..65b466bc7c 100644 --- a/src/cdk/v2/destinations/reddit/procWorkflow.yaml +++ b/src/cdk/v2/destinations/reddit/procWorkflow.yaml @@ -51,7 +51,7 @@ steps: template: | let event = .message.event; let eventInLowerCase = event.trim().toLowerCase();; - let eventNames = .destination.Config.eventsMapping.(){.from === event}.to[] ?? []; + let eventNames = .destination.Config.eventsMapping? .destination.Config.eventsMapping.(){.from === event}.to[] ?? []: []; eventNames.length === 0 ? eventNames = $.ecomEventMaps.(){eventInLowerCase in .src}.dest[] ?? []; const event_type = (eventNames.length === 0 || eventNames[0]==="") ? ({"tracking_type": "Custom", "custom_event_name": event}): ({tracking_type: eventNames[0]});