From 808727de17e400ed102a843ab3b30f81f8900f24 Mon Sep 17 00:00:00 2001 From: Sankeerth Date: Tue, 26 Mar 2024 19:01:27 +0530 Subject: [PATCH 01/47] fix: deployment file paths (#3216) --- .github/workflows/prepare-for-prod-dt-deploy.yml | 7 +++---- .github/workflows/prepare-for-prod-ut-deploy.yml | 7 +++---- .github/workflows/prepare-for-staging-deploy.yml | 8 ++++---- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/.github/workflows/prepare-for-prod-dt-deploy.yml b/.github/workflows/prepare-for-prod-dt-deploy.yml index a5ca48e3f8..fedbac8ba1 100644 --- a/.github/workflows/prepare-for-prod-dt-deploy.yml +++ b/.github/workflows/prepare-for-prod-dt-deploy.yml @@ -118,10 +118,9 @@ jobs: yq eval -i ".user-transformer.image.repository=\"$TF_IMAGE_REPOSITORY\"" multi-tenant/multi-tenant.yaml git add multi-tenant/multi-tenant.yaml - cd ../../../../config-be-rudder-transformer - yq eval -i ".config-be-rudder-transformer.image.tag=\"$TAG_NAME\"" values.prod.yaml - yq eval -i ".config-be-rudder-transformer.image.repository=\"$TF_IMAGE_REPOSITORY\"" values.prod.yaml - git add values.prod.yaml + cd ../../../../config-be-rudder-transformer/environment/prod + yq eval -i ".config-be-rudder-transformer.image.tag=\"$TAG_NAME\"" base.yaml + git add base.yaml git commit -m "chore: upgrade shared transformers to $TAG_NAME" git push -u origin shared-transformer-$TAG_NAME diff --git a/.github/workflows/prepare-for-prod-ut-deploy.yml b/.github/workflows/prepare-for-prod-ut-deploy.yml index c2900d61da..a6f7271d9c 100644 --- a/.github/workflows/prepare-for-prod-ut-deploy.yml +++ b/.github/workflows/prepare-for-prod-ut-deploy.yml @@ -102,11 +102,10 @@ jobs: cd rudder-devops git checkout -b shared-user-transformer-$UT_TAG_NAME - cd helm-charts/config-be-rudder-transformer + cd helm-charts/config-be-rudder-transformer/environment/prod - yq eval -i ".config-be-user-transformer.image.tag=\"$UT_TAG_NAME\"" values.prod.yaml - yq eval -i ".config-be-user-transformer.image.repository=\"$TF_IMAGE_REPOSITORY\"" values.prod.yaml - git add values.prod.yaml + yq eval -i ".config-be-user-transformer.image.tag=\"$UT_TAG_NAME\"" base.yaml + git add base.yaml git commit -m "chore: upgrade shared user-transformers to $UT_TAG_NAME" git push -u origin shared-user-transformer-$UT_TAG_NAME diff --git a/.github/workflows/prepare-for-staging-deploy.yml b/.github/workflows/prepare-for-staging-deploy.yml index 1bd7e276f4..46cd731d19 100644 --- a/.github/workflows/prepare-for-staging-deploy.yml +++ b/.github/workflows/prepare-for-staging-deploy.yml @@ -112,10 +112,10 @@ jobs: yq eval -i ".user-transformer.image.tag=\"$TAG_NAME\"" staging.yaml git add staging.yaml - cd ../../../../config-be-rudder-transformer - yq eval -i ".config-be-rudder-transformer.image.tag=\"$TAG_NAME\"" values.staging.yaml - yq eval -i ".config-be-user-transformer.image.tag=\"$TAG_NAME\"" values.staging.yaml - git add values.staging.yaml + cd ../../../../config-be-rudder-transformer/environment/staging + yq eval -i ".config-be-rudder-transformer.image.tag=\"$TAG_NAME\"" base.yaml + yq eval -i ".config-be-user-transformer.image.tag=\"$TAG_NAME\"" base.yaml + git add base.yaml git commit -m "chore: upgrade staging env transformers to \"$TAG_NAME\"" git push -u origin $BRANCH_NAME From 73701915b8e24b0a00afc48ddef7c687ecf02055 Mon Sep 17 00:00:00 2001 From: Anant Jain Date: Mon, 1 Apr 2024 21:32:44 +0530 Subject: [PATCH 02/47] feat: snapchat conversion: add event level_complete --- .../snapchat_conversion/config.js | 1 + .../snapchat_conversion/processor/data.ts | 134 ++++++++++++++++++ 2 files changed, 135 insertions(+) diff --git a/src/v0/destinations/snapchat_conversion/config.js b/src/v0/destinations/snapchat_conversion/config.js index e0126ea3b1..1cce713fbb 100644 --- a/src/v0/destinations/snapchat_conversion/config.js +++ b/src/v0/destinations/snapchat_conversion/config.js @@ -55,6 +55,7 @@ const eventNameMapping = { save: 'SAVE', subscribe: 'SUBSCRIBE', complete_tutorial: 'COMPLETE_TUTORIAL', + level_complete: 'LEVEL_COMPLETE', invite: 'INVITE', login: 'LOGIN', share: 'SHARE', diff --git a/test/integrations/destinations/snapchat_conversion/processor/data.ts b/test/integrations/destinations/snapchat_conversion/processor/data.ts index b0d14208cc..7f01dbac26 100644 --- a/test/integrations/destinations/snapchat_conversion/processor/data.ts +++ b/test/integrations/destinations/snapchat_conversion/processor/data.ts @@ -4600,6 +4600,140 @@ export const data = [ }, }, }, + { + name: 'snapchat_conversion', + description: 'test event mapping from destination config', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + messageId: 'ec5481b6-a926-4d2e-b293-0b3a77c4d3be', + originalTimestamp: '2022-04-22T10:57:58Z', + 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, + }, + 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: 'Custom Event', + properties: { + query: 't-shirts', + event_conversion_type: 'web', + }, + integrations: { + All: true, + }, + sentAt: '2022-04-22T10:57:58Z', + }, + destination: { + DestinationDefinition: { + Config: { + cdkV2Enabled: false, + }, + }, + Config: { + pixelId: 'dummyPixelId', + apiKey: 'dummyApiKey', + rudderEventsToSnapEvents: [ + { + from: 'Custom Event', + to: 'LEVEL_COMPLETE', + }, + ], + }, + }, + metadata: { + jobId: 47, + destinationId: 'd2', + workspaceId: 'w2', + }, + }, + ], + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + jobId: 47, + destinationId: 'd2', + workspaceId: 'w2', + }, + output: { + version: '1', + type: 'REST', + userId: '', + method: 'POST', + endpoint: 'https://tr.snapchat.com/v2/conversion', + headers: { + Authorization: 'Bearer dummyApiKey', + 'Content-Type': 'application/json', + }, + params: {}, + body: { + JSON: { + event_type: 'LEVEL_COMPLETE', + 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: 'OFFLINE', + pixel_id: 'dummyPixelId', + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + }, + statusCode: 200, + }, + ], + }, + }, + }, ].map((tc) => ({ ...tc, mockFns: (_) => { From d93bb9f88fc4f543d6f28299d52be6c1c5b8bb89 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Tue, 2 Apr 2024 04:07:06 +0000 Subject: [PATCH 03/47] chore(release): 1.61.0 --- CHANGELOG.md | 21 +++++++++++++++++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d3a37e122..12e0da0674 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,27 @@ 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.61.0](https://github.com/rudderlabs/rudder-transformer/compare/v1.60.0...v1.61.0) (2024-04-02) + + +### Features + +* consent field support for ga4 ([#3213](https://github.com/rudderlabs/rudder-transformer/issues/3213)) ([92515a5](https://github.com/rudderlabs/rudder-transformer/commit/92515a5fd8a2798c48010078f62b360ec6a49979)) +* consent field support for gaoc for API v15 and upgrade the api version from v14 to v16 ([#3121](https://github.com/rudderlabs/rudder-transformer/issues/3121)) ([2aac2a6](https://github.com/rudderlabs/rudder-transformer/commit/2aac2a62547b7a7c617735fc3d6e88e0a1bed76e)), closes [#3190](https://github.com/rudderlabs/rudder-transformer/issues/3190) +* onboard new destination bloomreach ([#3185](https://github.com/rudderlabs/rudder-transformer/issues/3185)) ([d9b7e1f](https://github.com/rudderlabs/rudder-transformer/commit/d9b7e1f70565d59979aee3e62f60e39edb9a23c7)) +* onboarding linkedin conversion api ([#3194](https://github.com/rudderlabs/rudder-transformer/issues/3194)) ([eb7b197](https://github.com/rudderlabs/rudder-transformer/commit/eb7b197322c617b14c2579de8cb4d4dacf8e1df3)) +* update movable ink batch size ([#3223](https://github.com/rudderlabs/rudder-transformer/issues/3223)) ([667095f](https://github.com/rudderlabs/rudder-transformer/commit/667095fa8316cd95a066f15b848ad503c6b4af80)) + + +### Bug Fixes + +* deployment file paths ([#3216](https://github.com/rudderlabs/rudder-transformer/issues/3216)) ([808727d](https://github.com/rudderlabs/rudder-transformer/commit/808727de17e400ed102a843ab3b30f81f8900f24)) +* fixed userId mapping, now mapping to uid instead of id ([#3192](https://github.com/rudderlabs/rudder-transformer/issues/3192)) ([70a468b](https://github.com/rudderlabs/rudder-transformer/commit/70a468bf16ecd5ee0b6fecee4b837895d19c525f)) +* merge conflict with main ([#3233](https://github.com/rudderlabs/rudder-transformer/issues/3233)) ([042dd6d](https://github.com/rudderlabs/rudder-transformer/commit/042dd6d16236dede8126984ea590fa167d4a4a87)), closes [#3216](https://github.com/rudderlabs/rudder-transformer/issues/3216) +* ninetailed: remove page support ([#3218](https://github.com/rudderlabs/rudder-transformer/issues/3218)) ([2f30c56](https://github.com/rudderlabs/rudder-transformer/commit/2f30c56af62e983d09b5d4f2da9a0ba22f5c1612)) +* shopify invalid_event metric prometheus label ([#3200](https://github.com/rudderlabs/rudder-transformer/issues/3200)) ([345c87d](https://github.com/rudderlabs/rudder-transformer/commit/345c87d7c530c621ae3fd6c504d64e5a14e31f22)) +* update correct staging deployment file ([#3189](https://github.com/rudderlabs/rudder-transformer/issues/3189)) ([ac7e887](https://github.com/rudderlabs/rudder-transformer/commit/ac7e8879fcd230dae09f757a759fb42e4cdc09d0)) + ## [1.60.0](https://github.com/rudderlabs/rudder-transformer/compare/v1.57.1...v1.60.0) (2024-03-20) diff --git a/package-lock.json b/package-lock.json index 463f86ab61..6d708b6f51 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "rudder-transformer", - "version": "1.60.0", + "version": "1.61.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "rudder-transformer", - "version": "1.60.0", + "version": "1.61.0", "license": "ISC", "dependencies": { "@amplitude/ua-parser-js": "0.7.24", diff --git a/package.json b/package.json index 6fb75c3e39..1f933cd1fa 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rudder-transformer", - "version": "1.60.0", + "version": "1.61.0", "description": "", "homepage": "https://github.com/rudderlabs/rudder-transformer#readme", "bugs": { From 4651af42982fd82541b9cacd2f79101a9b977e97 Mon Sep 17 00:00:00 2001 From: Anant Jain <62471433+anantjain45823@users.noreply.github.com> Date: Tue, 2 Apr 2024 10:30:14 +0530 Subject: [PATCH 04/47] chore:update mapping name value --- .../destinations/snapchat_conversion/processor/data.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integrations/destinations/snapchat_conversion/processor/data.ts b/test/integrations/destinations/snapchat_conversion/processor/data.ts index 7f01dbac26..7de7ed9b8d 100644 --- a/test/integrations/destinations/snapchat_conversion/processor/data.ts +++ b/test/integrations/destinations/snapchat_conversion/processor/data.ts @@ -4671,7 +4671,7 @@ export const data = [ rudderEventsToSnapEvents: [ { from: 'Custom Event', - to: 'LEVEL_COMPLETE', + to: 'level_complete', }, ], }, From bcde02127cdbc1a2cb370a645f8dc88b66557b95 Mon Sep 17 00:00:00 2001 From: Yashasvi Bajpai <33063622+yashasvibajpai@users.noreply.github.com> Date: Tue, 2 Apr 2024 11:07:59 +0530 Subject: [PATCH 05/47] chore: cleanup changelogs --- CHANGELOG.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 12e0da0674..64257f99ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,12 +16,9 @@ All notable changes to this project will be documented in this file. See [standa ### Bug Fixes -* deployment file paths ([#3216](https://github.com/rudderlabs/rudder-transformer/issues/3216)) ([808727d](https://github.com/rudderlabs/rudder-transformer/commit/808727de17e400ed102a843ab3b30f81f8900f24)) * fixed userId mapping, now mapping to uid instead of id ([#3192](https://github.com/rudderlabs/rudder-transformer/issues/3192)) ([70a468b](https://github.com/rudderlabs/rudder-transformer/commit/70a468bf16ecd5ee0b6fecee4b837895d19c525f)) -* merge conflict with main ([#3233](https://github.com/rudderlabs/rudder-transformer/issues/3233)) ([042dd6d](https://github.com/rudderlabs/rudder-transformer/commit/042dd6d16236dede8126984ea590fa167d4a4a87)), closes [#3216](https://github.com/rudderlabs/rudder-transformer/issues/3216) * ninetailed: remove page support ([#3218](https://github.com/rudderlabs/rudder-transformer/issues/3218)) ([2f30c56](https://github.com/rudderlabs/rudder-transformer/commit/2f30c56af62e983d09b5d4f2da9a0ba22f5c1612)) * shopify invalid_event metric prometheus label ([#3200](https://github.com/rudderlabs/rudder-transformer/issues/3200)) ([345c87d](https://github.com/rudderlabs/rudder-transformer/commit/345c87d7c530c621ae3fd6c504d64e5a14e31f22)) -* update correct staging deployment file ([#3189](https://github.com/rudderlabs/rudder-transformer/issues/3189)) ([ac7e887](https://github.com/rudderlabs/rudder-transformer/commit/ac7e8879fcd230dae09f757a759fb42e4cdc09d0)) ## [1.60.0](https://github.com/rudderlabs/rudder-transformer/compare/v1.57.1...v1.60.0) (2024-03-20) From 476b401d204544c4e146ab0ea806127b0828d1a6 Mon Sep 17 00:00:00 2001 From: Yashasvi Bajpai <33063622+yashasvibajpai@users.noreply.github.com> Date: Tue, 2 Apr 2024 11:13:39 +0530 Subject: [PATCH 06/47] chore: update changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 64257f99ea..8cd19561b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ All notable changes to this project will be documented in this file. See [standa ### Features * consent field support for ga4 ([#3213](https://github.com/rudderlabs/rudder-transformer/issues/3213)) ([92515a5](https://github.com/rudderlabs/rudder-transformer/commit/92515a5fd8a2798c48010078f62b360ec6a49979)) -* consent field support for gaoc for API v15 and upgrade the api version from v14 to v16 ([#3121](https://github.com/rudderlabs/rudder-transformer/issues/3121)) ([2aac2a6](https://github.com/rudderlabs/rudder-transformer/commit/2aac2a62547b7a7c617735fc3d6e88e0a1bed76e)), closes [#3190](https://github.com/rudderlabs/rudder-transformer/issues/3190) +* consent field support for gaoc and upgrade the api version from v14 to v16 ([#3121](https://github.com/rudderlabs/rudder-transformer/issues/3121)) ([2aac2a6](https://github.com/rudderlabs/rudder-transformer/commit/2aac2a62547b7a7c617735fc3d6e88e0a1bed76e)), closes [#3190](https://github.com/rudderlabs/rudder-transformer/issues/3190) * onboard new destination bloomreach ([#3185](https://github.com/rudderlabs/rudder-transformer/issues/3185)) ([d9b7e1f](https://github.com/rudderlabs/rudder-transformer/commit/d9b7e1f70565d59979aee3e62f60e39edb9a23c7)) * onboarding linkedin conversion api ([#3194](https://github.com/rudderlabs/rudder-transformer/issues/3194)) ([eb7b197](https://github.com/rudderlabs/rudder-transformer/commit/eb7b197322c617b14c2579de8cb4d4dacf8e1df3)) * update movable ink batch size ([#3223](https://github.com/rudderlabs/rudder-transformer/issues/3223)) ([667095f](https://github.com/rudderlabs/rudder-transformer/commit/667095fa8316cd95a066f15b848ad503c6b4af80)) From aaddac148350edc092675377981098ce63f2771e Mon Sep 17 00:00:00 2001 From: shrouti1507 <60211312+shrouti1507@users.noreply.github.com> Date: Tue, 2 Apr 2024 19:06:13 +0530 Subject: [PATCH 07/47] chore: no success should return empty array for linkedin ads (#3238) chore: no success should return empty array --- .../v2/destinations/linkedin_ads/rtWorkflow.yaml | 13 +++++-------- src/cdk/v2/destinations/linkedin_ads/utils.js | 3 +++ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/cdk/v2/destinations/linkedin_ads/rtWorkflow.yaml b/src/cdk/v2/destinations/linkedin_ads/rtWorkflow.yaml index 8b81790de2..dda322e45e 100644 --- a/src/cdk/v2/destinations/linkedin_ads/rtWorkflow.yaml +++ b/src/cdk/v2/destinations/linkedin_ads/rtWorkflow.yaml @@ -1,6 +1,8 @@ bindings: - path: ./utils - path: ./config + - name: handleRtTfSingleEventError + path: ../../../../v0/util/index steps: - name: validateInput @@ -23,14 +25,9 @@ steps: })[] - name: failedEvents template: | - $.outputs.transform#idx.error.({ - "metadata": ^[idx].metadata[], - "destination": ^[idx].destination, - "batched": false, - "statusCode": .status, - "error": .message, - "statTags": .originalError.statTags - })[] + $.outputs.transform#idx.error.( + $.handleRtTfSingleEventError(^[idx], .originalError ?? ., {}) + )[] - name: batchSuccessfulEvents description: Batches the successfulEvents diff --git a/src/cdk/v2/destinations/linkedin_ads/utils.js b/src/cdk/v2/destinations/linkedin_ads/utils.js index f3f7783962..69fea4299d 100644 --- a/src/cdk/v2/destinations/linkedin_ads/utils.js +++ b/src/cdk/v2/destinations/linkedin_ads/utils.js @@ -162,6 +162,9 @@ const fetchAndVerifyConversionHappenedAt = (message) => { }; function batchResponseBuilder(successfulEvents) { + if (successfulEvents.length === 0) { + return []; + } const constants = { version: successfulEvents[0].message[0].version, type: successfulEvents[0].message[0].type, From a96d954d348e63464acff3756f0a0006eac6cd1c Mon Sep 17 00:00:00 2001 From: Anant Jain <62471433+anantjain45823@users.noreply.github.com> Date: Wed, 3 Apr 2024 10:50:35 +0530 Subject: [PATCH 08/47] chore: update CHANGELOG.md with snapchat changes --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8cd19561b1..b7a83098ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ All notable changes to this project will be documented in this file. See [standa * fixed userId mapping, now mapping to uid instead of id ([#3192](https://github.com/rudderlabs/rudder-transformer/issues/3192)) ([70a468b](https://github.com/rudderlabs/rudder-transformer/commit/70a468bf16ecd5ee0b6fecee4b837895d19c525f)) * ninetailed: remove page support ([#3218](https://github.com/rudderlabs/rudder-transformer/issues/3218)) ([2f30c56](https://github.com/rudderlabs/rudder-transformer/commit/2f30c56af62e983d09b5d4f2da9a0ba22f5c1612)) * shopify invalid_event metric prometheus label ([#3200](https://github.com/rudderlabs/rudder-transformer/issues/3200)) ([345c87d](https://github.com/rudderlabs/rudder-transformer/commit/345c87d7c530c621ae3fd6c504d64e5a14e31f22)) +* fix: snapchat conversion: add event level_complete ([#3231](https://github.com/rudderlabs/rudder-transformer/issues/3231)) ([39368a0](https://github.com/rudderlabs/rudder-transformer/commit/39368a09e48acc324faa855186bc623e5c347881)) ## [1.60.0](https://github.com/rudderlabs/rudder-transformer/compare/v1.57.1...v1.60.0) (2024-03-20) From db55624703f00f4e4716d95cddff3b097267161f Mon Sep 17 00:00:00 2001 From: Sandeep Digumarty Date: Wed, 3 Apr 2024 12:29:40 +0530 Subject: [PATCH 09/47] chore: revert "fix: fixed userId mapping, now mapping to uid instead of id" (#3243) --- src/cdk/v2/destinations/fullstory/procWorkflow.yaml | 2 +- test/integrations/destinations/fullstory/processor/data.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cdk/v2/destinations/fullstory/procWorkflow.yaml b/src/cdk/v2/destinations/fullstory/procWorkflow.yaml index 26da955623..1a54e8688c 100644 --- a/src/cdk/v2/destinations/fullstory/procWorkflow.yaml +++ b/src/cdk/v2/destinations/fullstory/procWorkflow.yaml @@ -76,7 +76,7 @@ steps: "use_most_recent": .message.properties.useMostRecent, }; $.context.payload.user = { - "uid": .message.properties.userId ?? .message.userId, + "id": .message.properties.userId ?? .message.userId, } - name: cleanPayload diff --git a/test/integrations/destinations/fullstory/processor/data.ts b/test/integrations/destinations/fullstory/processor/data.ts index 9c8d29c7e8..d206b4a84f 100644 --- a/test/integrations/destinations/fullstory/processor/data.ts +++ b/test/integrations/destinations/fullstory/processor/data.ts @@ -149,7 +149,7 @@ export const data = [ id: 's001', }, user: { - uid: 'u001', + id: 'u001', }, }, JSON_ARRAY: {}, From 626e771881f5857995ad3748f8d62bc7afd949fa Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Wed, 3 Apr 2024 07:01:18 +0000 Subject: [PATCH 10/47] chore(release): 1.61.1 --- CHANGELOG.md | 2 ++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b7a83098ce..1670fa232d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ 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.61.1](https://github.com/rudderlabs/rudder-transformer/compare/v1.61.0...v1.61.1) (2024-04-03) + ## [1.61.0](https://github.com/rudderlabs/rudder-transformer/compare/v1.60.0...v1.61.0) (2024-04-02) diff --git a/package-lock.json b/package-lock.json index 6d708b6f51..a223d51eec 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "rudder-transformer", - "version": "1.61.0", + "version": "1.61.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "rudder-transformer", - "version": "1.61.0", + "version": "1.61.1", "license": "ISC", "dependencies": { "@amplitude/ua-parser-js": "0.7.24", diff --git a/package.json b/package.json index 1f933cd1fa..84a0a1ad14 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rudder-transformer", - "version": "1.61.0", + "version": "1.61.1", "description": "", "homepage": "https://github.com/rudderlabs/rudder-transformer#readme", "bugs": { From be041a649b4447e352a531ac8da59814c3c66dc5 Mon Sep 17 00:00:00 2001 From: krishnachaitanya Date: Wed, 3 Apr 2024 12:39:49 +0530 Subject: [PATCH 11/47] chore: update slack mention --- .github/workflows/publish-new-release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish-new-release.yml b/.github/workflows/publish-new-release.yml index 233e99577d..15d7b20fd1 100644 --- a/.github/workflows/publish-new-release.yml +++ b/.github/workflows/publish-new-release.yml @@ -99,7 +99,7 @@ jobs: channel-id: ${{ secrets.SLACK_RELEASE_CHANNEL_ID }} payload: | { - "text": "*<${{env.RELEASES_URL}}v${{ steps.extract-version.outputs.release_version }}|v${{ steps.extract-version.outputs.release_version }}>*\nCC: <@U03KG4BK1L1> <@U02AE5GMMHV> <@U01LVJ30QEB>", + "text": "*<${{env.RELEASES_URL}}v${{ steps.extract-version.outputs.release_version }}|v${{ steps.extract-version.outputs.release_version }}>*\nCC: <@U03KG4BK1L1> <@U024YF8CR53> <@U01LVJ30QEB>", "blocks": [ { "type": "header", @@ -115,7 +115,7 @@ jobs: "type": "section", "text": { "type": "mrkdwn", - "text": "*<${{env.RELEASES_URL}}v${{ steps.extract-version.outputs.release_version }}|v${{ steps.extract-version.outputs.release_version }}>*\nCC: <@U03KG4BK1L1> <@U02AE5GMMHV> <@U01LVJ30QEB>" + "text": "*<${{env.RELEASES_URL}}v${{ steps.extract-version.outputs.release_version }}|v${{ steps.extract-version.outputs.release_version }}>*\nCC: <@U03KG4BK1L1> <@U024YF8CR53> <@U01LVJ30QEB>" } } ] From 5d654b326b8a2e39413f9541da541ab86b2a56fa Mon Sep 17 00:00:00 2001 From: Dilip Kola Date: Wed, 3 Apr 2024 14:59:11 +0530 Subject: [PATCH 12/47] fix: email mappings --- .../v2/destinations/bluecore/data/bluecoreCommonConfig.json | 2 +- src/v0/destinations/active_campaign/data/ACIdentify.json | 2 +- src/v0/destinations/blueshift/data/blueshiftGroupConfig.json | 2 +- .../destinations/blueshift/data/blueshiftIdentifyConfig.json | 2 +- src/v0/destinations/blueshift/data/blueshiftTrackConfig.json | 2 +- src/v0/destinations/custify/data/CUSTIFYIdentifyConfig.json | 2 +- src/v0/destinations/custify/data/CUSTIFYTrackConfig.json | 2 +- .../data/FbOfflineConversionsTrackConfig.json | 2 +- .../freshmarketer/data/FRESHMARKETERIdentifyConfig.json | 2 +- src/v0/destinations/freshsales/data/identifyConfig.json | 2 +- .../google_adwords_enhanced_conversions/data/trackConfig.json | 2 +- src/v0/destinations/impact/data/ImpactConversionConfig.json | 2 +- src/v0/destinations/impact/data/ImpactPageLoadConfig.json | 2 +- src/v0/destinations/klaviyo/data/KlaviyoGroup.json | 2 +- src/v0/destinations/klaviyo/data/KlaviyoIdentify.json | 2 +- src/v0/destinations/klaviyo/data/KlaviyoProfile.json | 2 +- src/v0/destinations/mailjet/data/MailJetIdentifyConfig.json | 2 +- src/v0/destinations/mp/data/MPIdentifyConfig.json | 2 +- .../destinations/pinterest_tag/data/pinterestUserConfig.json | 2 +- src/v0/destinations/revenue_cat/data/RCIdentifyConfig.json | 2 +- src/v0/destinations/rockerbox/data/RockerboxTrackConfig.json | 2 +- src/v0/destinations/sendgrid/data/SendgridIdentify.json | 2 +- .../serenytics/data/SerenyticsIdentifyConfig.json | 2 +- src/v0/destinations/user/data/USERGroupConfig.json | 2 +- src/v0/destinations/user/data/USERIdentifyConfig.json | 2 +- src/v0/destinations/vero/data/VeroIdentifyConfig.json | 2 +- src/v0/destinations/vero/data/VeroTrackConfig.json | 2 +- .../destinations/webengage/data/WEBENGAGEIdentifyConfig.json | 2 +- test/integrations/destinations/blueshift/processor/data.ts | 2 +- .../integrations/destinations/freshmarketer/processor/data.ts | 4 ++-- test/integrations/destinations/freshsales/processor/data.ts | 4 ++-- test/integrations/destinations/mailjet/processor/data.ts | 2 +- 32 files changed, 34 insertions(+), 34 deletions(-) diff --git a/src/cdk/v2/destinations/bluecore/data/bluecoreCommonConfig.json b/src/cdk/v2/destinations/bluecore/data/bluecoreCommonConfig.json index be74c7c4b3..536f77a045 100644 --- a/src/cdk/v2/destinations/bluecore/data/bluecoreCommonConfig.json +++ b/src/cdk/v2/destinations/bluecore/data/bluecoreCommonConfig.json @@ -35,7 +35,7 @@ }, { "destKey": "properties.customer.email", - "sourceKeys": "email", + "sourceKeys": "emailOnly", "required": false, "sourceFromGenericMap": true }, diff --git a/src/v0/destinations/active_campaign/data/ACIdentify.json b/src/v0/destinations/active_campaign/data/ACIdentify.json index 6cee9e72c6..134955d52e 100644 --- a/src/v0/destinations/active_campaign/data/ACIdentify.json +++ b/src/v0/destinations/active_campaign/data/ACIdentify.json @@ -1,7 +1,7 @@ [ { "destKey": "email", - "sourceKeys": "email", + "sourceKeys": "emailOnly", "sourceFromGenericMap": true, "required": true }, diff --git a/src/v0/destinations/blueshift/data/blueshiftGroupConfig.json b/src/v0/destinations/blueshift/data/blueshiftGroupConfig.json index 41e846c509..e246a059d9 100644 --- a/src/v0/destinations/blueshift/data/blueshiftGroupConfig.json +++ b/src/v0/destinations/blueshift/data/blueshiftGroupConfig.json @@ -13,7 +13,7 @@ }, { "destKey": "email", - "sourceKeys": "email", + "sourceKeys": "emailOnly", "sourceFromGenericMap": true, "required": false }, diff --git a/src/v0/destinations/blueshift/data/blueshiftIdentifyConfig.json b/src/v0/destinations/blueshift/data/blueshiftIdentifyConfig.json index cd099b2cc3..506c313aa1 100644 --- a/src/v0/destinations/blueshift/data/blueshiftIdentifyConfig.json +++ b/src/v0/destinations/blueshift/data/blueshiftIdentifyConfig.json @@ -1,7 +1,7 @@ [ { "destKey": "email", - "sourceKeys": "email", + "sourceKeys": "emailOnly", "sourceFromGenericMap": true, "required": true }, diff --git a/src/v0/destinations/blueshift/data/blueshiftTrackConfig.json b/src/v0/destinations/blueshift/data/blueshiftTrackConfig.json index 5fb1be691a..9841450754 100644 --- a/src/v0/destinations/blueshift/data/blueshiftTrackConfig.json +++ b/src/v0/destinations/blueshift/data/blueshiftTrackConfig.json @@ -7,7 +7,7 @@ }, { "destKey": "email", - "sourceKeys": "email", + "sourceKeys": "emailOnly", "sourceFromGenericMap": true, "required": false }, diff --git a/src/v0/destinations/custify/data/CUSTIFYIdentifyConfig.json b/src/v0/destinations/custify/data/CUSTIFYIdentifyConfig.json index 4a7a785e1d..00a8ea0584 100644 --- a/src/v0/destinations/custify/data/CUSTIFYIdentifyConfig.json +++ b/src/v0/destinations/custify/data/CUSTIFYIdentifyConfig.json @@ -7,7 +7,7 @@ }, { "destKey": "email", - "sourceKeys": "email", + "sourceKeys": "emailOnly", "sourceFromGenericMap": true, "required": false }, diff --git a/src/v0/destinations/custify/data/CUSTIFYTrackConfig.json b/src/v0/destinations/custify/data/CUSTIFYTrackConfig.json index f68e9f18ac..1751c84230 100644 --- a/src/v0/destinations/custify/data/CUSTIFYTrackConfig.json +++ b/src/v0/destinations/custify/data/CUSTIFYTrackConfig.json @@ -7,7 +7,7 @@ }, { "destKey": "email", - "sourceKeys": "email", + "sourceKeys": "emailOnly", "sourceFromGenericMap": true, "required": false }, diff --git a/src/v0/destinations/facebook_offline_conversions/data/FbOfflineConversionsTrackConfig.json b/src/v0/destinations/facebook_offline_conversions/data/FbOfflineConversionsTrackConfig.json index fc5f6c48fa..3f2fa1875f 100644 --- a/src/v0/destinations/facebook_offline_conversions/data/FbOfflineConversionsTrackConfig.json +++ b/src/v0/destinations/facebook_offline_conversions/data/FbOfflineConversionsTrackConfig.json @@ -39,7 +39,7 @@ }, { "destKey": "email", - "sourceKeys": "email", + "sourceKeys": "emailOnly", "required": false, "sourceFromGenericMap": true }, diff --git a/src/v0/destinations/freshmarketer/data/FRESHMARKETERIdentifyConfig.json b/src/v0/destinations/freshmarketer/data/FRESHMARKETERIdentifyConfig.json index da1a8bccbe..d8abb484b2 100644 --- a/src/v0/destinations/freshmarketer/data/FRESHMARKETERIdentifyConfig.json +++ b/src/v0/destinations/freshmarketer/data/FRESHMARKETERIdentifyConfig.json @@ -1,7 +1,7 @@ [ { "destKey": "emails", - "sourceKeys": "email", + "sourceKeys": "emailOnly", "sourceFromGenericMap": true, "required": true }, diff --git a/src/v0/destinations/freshsales/data/identifyConfig.json b/src/v0/destinations/freshsales/data/identifyConfig.json index 9be9d9d855..94a15fd43d 100644 --- a/src/v0/destinations/freshsales/data/identifyConfig.json +++ b/src/v0/destinations/freshsales/data/identifyConfig.json @@ -1,7 +1,7 @@ [ { "destKey": "emails", - "sourceKeys": "email", + "sourceKeys": "emailOnly", "sourceFromGenericMap": true, "required": true }, diff --git a/src/v0/destinations/google_adwords_enhanced_conversions/data/trackConfig.json b/src/v0/destinations/google_adwords_enhanced_conversions/data/trackConfig.json index 562a77f0e8..bf5485270b 100644 --- a/src/v0/destinations/google_adwords_enhanced_conversions/data/trackConfig.json +++ b/src/v0/destinations/google_adwords_enhanced_conversions/data/trackConfig.json @@ -51,7 +51,7 @@ }, { "destKey": "conversionAdjustments[0].userIdentifiers[0].hashedEmail", - "sourceKeys": "email", + "sourceKeys": "emailOnly", "sourceFromGenericMap": true, "required": false, "metadata": { diff --git a/src/v0/destinations/impact/data/ImpactConversionConfig.json b/src/v0/destinations/impact/data/ImpactConversionConfig.json index 7ae0cc72eb..a898e6a98c 100644 --- a/src/v0/destinations/impact/data/ImpactConversionConfig.json +++ b/src/v0/destinations/impact/data/ImpactConversionConfig.json @@ -120,7 +120,7 @@ }, { "destKey": "CustomerEmail", - "sourceKeys": "email", + "sourceKeys": "emailOnly", "sourceFromGenericMap": true, "required": false }, diff --git a/src/v0/destinations/impact/data/ImpactPageLoadConfig.json b/src/v0/destinations/impact/data/ImpactPageLoadConfig.json index 0ca0a26e69..700557d3e0 100644 --- a/src/v0/destinations/impact/data/ImpactPageLoadConfig.json +++ b/src/v0/destinations/impact/data/ImpactPageLoadConfig.json @@ -7,7 +7,7 @@ }, { "destKey": "CustomerEmail", - "sourceKeys": "email", + "sourceKeys": "emailOnly", "sourceFromGenericMap": true, "required": false }, diff --git a/src/v0/destinations/klaviyo/data/KlaviyoGroup.json b/src/v0/destinations/klaviyo/data/KlaviyoGroup.json index baf6bcee86..b03cc9ee0a 100644 --- a/src/v0/destinations/klaviyo/data/KlaviyoGroup.json +++ b/src/v0/destinations/klaviyo/data/KlaviyoGroup.json @@ -1,7 +1,7 @@ [ { "destKey": "email", - "sourceKeys": "email", + "sourceKeys": "emailOnly", "required": false, "sourceFromGenericMap": true }, diff --git a/src/v0/destinations/klaviyo/data/KlaviyoIdentify.json b/src/v0/destinations/klaviyo/data/KlaviyoIdentify.json index b358919bc1..fd46b6cda9 100644 --- a/src/v0/destinations/klaviyo/data/KlaviyoIdentify.json +++ b/src/v0/destinations/klaviyo/data/KlaviyoIdentify.json @@ -7,7 +7,7 @@ }, { "destKey": "email", - "sourceKeys": "email", + "sourceKeys": "emailOnly", "required": false, "sourceFromGenericMap": true }, diff --git a/src/v0/destinations/klaviyo/data/KlaviyoProfile.json b/src/v0/destinations/klaviyo/data/KlaviyoProfile.json index 329ecd978f..03f155e787 100644 --- a/src/v0/destinations/klaviyo/data/KlaviyoProfile.json +++ b/src/v0/destinations/klaviyo/data/KlaviyoProfile.json @@ -1,7 +1,7 @@ [ { "destKey": "$email", - "sourceKeys": "email", + "sourceKeys": "emailOnly", "required": false, "sourceFromGenericMap": true }, diff --git a/src/v0/destinations/mailjet/data/MailJetIdentifyConfig.json b/src/v0/destinations/mailjet/data/MailJetIdentifyConfig.json index e32463e034..106560a447 100644 --- a/src/v0/destinations/mailjet/data/MailJetIdentifyConfig.json +++ b/src/v0/destinations/mailjet/data/MailJetIdentifyConfig.json @@ -1,7 +1,7 @@ [ { "destKey": "email", - "sourceKeys": "email", + "sourceKeys": "emailOnly", "required": true, "sourceFromGenericMap": true }, diff --git a/src/v0/destinations/mp/data/MPIdentifyConfig.json b/src/v0/destinations/mp/data/MPIdentifyConfig.json index 679ce66d7f..b5e4f51970 100644 --- a/src/v0/destinations/mp/data/MPIdentifyConfig.json +++ b/src/v0/destinations/mp/data/MPIdentifyConfig.json @@ -7,7 +7,7 @@ }, { "destKey": "$email", - "sourceKeys": "email", + "sourceKeys": "emailOnly", "required": false, "sourceFromGenericMap": true }, diff --git a/src/v0/destinations/pinterest_tag/data/pinterestUserConfig.json b/src/v0/destinations/pinterest_tag/data/pinterestUserConfig.json index 0ab963ac3c..b95f539e7c 100644 --- a/src/v0/destinations/pinterest_tag/data/pinterestUserConfig.json +++ b/src/v0/destinations/pinterest_tag/data/pinterestUserConfig.json @@ -1,7 +1,7 @@ [ { "destKey": "em", - "sourceKeys": "email", + "sourceKeys": "emailOnly", "sourceFromGenericMap": true, "required": false }, diff --git a/src/v0/destinations/revenue_cat/data/RCIdentifyConfig.json b/src/v0/destinations/revenue_cat/data/RCIdentifyConfig.json index f7e6fa7acc..b31f1355a6 100644 --- a/src/v0/destinations/revenue_cat/data/RCIdentifyConfig.json +++ b/src/v0/destinations/revenue_cat/data/RCIdentifyConfig.json @@ -13,7 +13,7 @@ }, { "destKey": "$email.value", - "sourceKeys": "email", + "sourceKeys": "emailOnly", "sourceFromGenericMap": true, "required": false }, diff --git a/src/v0/destinations/rockerbox/data/RockerboxTrackConfig.json b/src/v0/destinations/rockerbox/data/RockerboxTrackConfig.json index e405f1477d..cc3a4d5ec5 100644 --- a/src/v0/destinations/rockerbox/data/RockerboxTrackConfig.json +++ b/src/v0/destinations/rockerbox/data/RockerboxTrackConfig.json @@ -12,7 +12,7 @@ "sourceFromGenericMap": false }, { - "sourceKeys": "email", + "sourceKeys": "emailOnly", "destKey": "email", "required": false, "sourceFromGenericMap": true diff --git a/src/v0/destinations/sendgrid/data/SendgridIdentify.json b/src/v0/destinations/sendgrid/data/SendgridIdentify.json index e70378dd28..bfafd0da01 100644 --- a/src/v0/destinations/sendgrid/data/SendgridIdentify.json +++ b/src/v0/destinations/sendgrid/data/SendgridIdentify.json @@ -1,7 +1,7 @@ [ { "destKey": "email", - "sourceKeys": "email", + "sourceKeys": "emailOnly", "required": true, "sourceFromGenericMap": true }, diff --git a/src/v0/destinations/serenytics/data/SerenyticsIdentifyConfig.json b/src/v0/destinations/serenytics/data/SerenyticsIdentifyConfig.json index 4c50cb4a54..9161a7c698 100644 --- a/src/v0/destinations/serenytics/data/SerenyticsIdentifyConfig.json +++ b/src/v0/destinations/serenytics/data/SerenyticsIdentifyConfig.json @@ -35,7 +35,7 @@ }, { "destKey": "email", - "sourceKeys": "email", + "sourceKeys": "emailOnly", "sourceFromGenericMap": true, "required": false }, diff --git a/src/v0/destinations/user/data/USERGroupConfig.json b/src/v0/destinations/user/data/USERGroupConfig.json index c87653442d..c31020b68f 100644 --- a/src/v0/destinations/user/data/USERGroupConfig.json +++ b/src/v0/destinations/user/data/USERGroupConfig.json @@ -17,7 +17,7 @@ "required": true }, { - "sourceKeys": "email", + "sourceKeys": "emailOnly", "destKey": "email", "required": false, "sourceFromGenericMap": true diff --git a/src/v0/destinations/user/data/USERIdentifyConfig.json b/src/v0/destinations/user/data/USERIdentifyConfig.json index 2b89c2a3a6..f87bdd01fd 100644 --- a/src/v0/destinations/user/data/USERIdentifyConfig.json +++ b/src/v0/destinations/user/data/USERIdentifyConfig.json @@ -7,7 +7,7 @@ }, { "destKey": "email", - "sourceKeys": "email", + "sourceKeys": "emailOnly", "required": false, "sourceFromGenericMap": true }, diff --git a/src/v0/destinations/vero/data/VeroIdentifyConfig.json b/src/v0/destinations/vero/data/VeroIdentifyConfig.json index 8ea456cc1c..8ec589aaed 100644 --- a/src/v0/destinations/vero/data/VeroIdentifyConfig.json +++ b/src/v0/destinations/vero/data/VeroIdentifyConfig.json @@ -5,7 +5,7 @@ "sourceFromGenericMap": true }, { - "sourceKeys": "email", + "sourceKeys": "emailOnly", "destKey": "email", "sourceFromGenericMap": true }, diff --git a/src/v0/destinations/vero/data/VeroTrackConfig.json b/src/v0/destinations/vero/data/VeroTrackConfig.json index a3a23a6e66..04974c5eb2 100644 --- a/src/v0/destinations/vero/data/VeroTrackConfig.json +++ b/src/v0/destinations/vero/data/VeroTrackConfig.json @@ -5,7 +5,7 @@ "sourceFromGenericMap": true }, { - "sourceKeys": "email", + "sourceKeys": "emailOnly", "destKey": "identity.email", "sourceFromGenericMap": true }, diff --git a/src/v0/destinations/webengage/data/WEBENGAGEIdentifyConfig.json b/src/v0/destinations/webengage/data/WEBENGAGEIdentifyConfig.json index a99fc47a3f..4e04703fc0 100644 --- a/src/v0/destinations/webengage/data/WEBENGAGEIdentifyConfig.json +++ b/src/v0/destinations/webengage/data/WEBENGAGEIdentifyConfig.json @@ -55,7 +55,7 @@ }, { "destKey": "email", - "sourceKeys": "email", + "sourceKeys": "emailOnly", "sourceFromGenericMap": true, "required": false }, diff --git a/test/integrations/destinations/blueshift/processor/data.ts b/test/integrations/destinations/blueshift/processor/data.ts index d489a38bd6..be23521621 100644 --- a/test/integrations/destinations/blueshift/processor/data.ts +++ b/test/integrations/destinations/blueshift/processor/data.ts @@ -739,7 +739,7 @@ export const data = [ body: [ { statusCode: 400, - error: 'Missing required value from "email"', + error: 'Missing required value from "emailOnly"', statTags: { errorCategory: 'dataValidation', errorType: 'instrumentation', diff --git a/test/integrations/destinations/freshmarketer/processor/data.ts b/test/integrations/destinations/freshmarketer/processor/data.ts index ed920faef0..07112d762f 100644 --- a/test/integrations/destinations/freshmarketer/processor/data.ts +++ b/test/integrations/destinations/freshmarketer/processor/data.ts @@ -375,7 +375,7 @@ export const data = [ status: 200, body: [ { - error: 'Missing required value from "email"', + error: 'Missing required value from "emailOnly"', statTags: { destType: 'FRESHMARKETER', errorCategory: 'dataValidation', @@ -964,7 +964,7 @@ export const data = [ status: 200, body: [ { - error: 'Missing required value from "email"', + error: 'Missing required value from "emailOnly"', statTags: { destType: 'FRESHMARKETER', errorCategory: 'dataValidation', diff --git a/test/integrations/destinations/freshsales/processor/data.ts b/test/integrations/destinations/freshsales/processor/data.ts index eca3b88d9d..7c0eca0926 100644 --- a/test/integrations/destinations/freshsales/processor/data.ts +++ b/test/integrations/destinations/freshsales/processor/data.ts @@ -505,7 +505,7 @@ export const data = [ status: 200, body: [ { - error: 'Missing required value from "email"', + error: 'Missing required value from "emailOnly"', statTags: { destType: 'FRESHSALES', errorCategory: 'dataValidation', @@ -1094,7 +1094,7 @@ export const data = [ status: 200, body: [ { - error: 'Missing required value from "email"', + error: 'Missing required value from "emailOnly"', statTags: { destType: 'FRESHSALES', errorCategory: 'dataValidation', diff --git a/test/integrations/destinations/mailjet/processor/data.ts b/test/integrations/destinations/mailjet/processor/data.ts index 71e06dc14e..03c3232e72 100644 --- a/test/integrations/destinations/mailjet/processor/data.ts +++ b/test/integrations/destinations/mailjet/processor/data.ts @@ -141,7 +141,7 @@ export const data = [ status: 200, body: [ { - error: 'Missing required value from "email"', + error: 'Missing required value from "emailOnly"', statTags: { destType: 'MAILJET', errorCategory: 'dataValidation', From e18b1c48c9add98440cf7e6b0a996284bffde559 Mon Sep 17 00:00:00 2001 From: Sandeep Digumarty Date: Thu, 4 Apr 2024 11:08:16 +0530 Subject: [PATCH 13/47] chore: resolves high packag vulnerabilities (#3202) chore: update @pyroscope/nodejs to 0.2.9 --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index a223d51eec..65659a745c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,7 +18,7 @@ "@datadog/pprof": "^3.1.0", "@koa/router": "^12.0.0", "@ndhoule/extend": "^2.0.0", - "@pyroscope/nodejs": "^0.2.6", + "@pyroscope/nodejs": "^0.2.9", "@rudderstack/integrations-lib": "^0.2.7", "@rudderstack/workflow-engine": "^0.7.5", "@shopify/jest-koa-mocks": "^5.1.1", @@ -4462,9 +4462,9 @@ } }, "node_modules/@pyroscope/nodejs/node_modules/axios": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.28.0.tgz", - "integrity": "sha512-Tu7NYoGY4Yoc7I+Npf9HhUMtEEpV7ZiLH9yndTCoNhcpBH0kwcvFbzYN9/u5QKI5A6uefjsNNWaz5olJVYS62Q==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.28.1.tgz", + "integrity": "sha512-iUcGA5a7p0mVb4Gm/sy+FSECNkPFT4y7wt6OM/CDpO/OnNCvSs3PoMG8ibrC9jRoGYU0gUK5pXVC4NPXq6lHRQ==", "dependencies": { "follow-redirects": "^1.15.0", "form-data": "^4.0.0", diff --git a/package.json b/package.json index 84a0a1ad14..c91d836c34 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ "@datadog/pprof": "^3.1.0", "@koa/router": "^12.0.0", "@ndhoule/extend": "^2.0.0", - "@pyroscope/nodejs": "^0.2.6", + "@pyroscope/nodejs": "^0.2.9", "@rudderstack/integrations-lib": "^0.2.7", "@rudderstack/workflow-engine": "^0.7.5", "@shopify/jest-koa-mocks": "^5.1.1", From d1a8e2f1a5bbddc11ccfab3261590f5642aff4b5 Mon Sep 17 00:00:00 2001 From: Lokesh Date: Mon, 8 Apr 2024 13:31:51 +0530 Subject: [PATCH 14/47] Add cost tracking labels to openfaas fn pods --- src/util/openfaas/index.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/util/openfaas/index.js b/src/util/openfaas/index.js index 878fa706d9..8a9623d9c8 100644 --- a/src/util/openfaas/index.js +++ b/src/util/openfaas/index.js @@ -27,6 +27,7 @@ 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(','); +const CUSTOMER_TIER = process.env.CUSTOMER_TIER || 'shared'; // Initialise node cache const functionListCache = new NodeCache(); @@ -151,6 +152,10 @@ const deployFaasFunction = async ( 'com.openfaas.scale.min': FAAS_MIN_PODS_IN_TEXT, transformationId: trMetadata.transformationId, workspaceId: trMetadata.workspaceId, + team: 'data-managment', + service: 'openfaas', + customer: 'shared', + 'customer-tier': CUSTOMER_TIER }; if ( trMetadata.workspaceId && From 58aec0a036f10d2020fecf9f8f1f83ee96ff315c Mon Sep 17 00:00:00 2001 From: lokey Date: Mon, 8 Apr 2024 13:43:52 +0530 Subject: [PATCH 15/47] Update src/util/openfaas/index.js Co-authored-by: Jayachand --- src/util/openfaas/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/util/openfaas/index.js b/src/util/openfaas/index.js index 8a9623d9c8..ff95a93903 100644 --- a/src/util/openfaas/index.js +++ b/src/util/openfaas/index.js @@ -152,8 +152,8 @@ const deployFaasFunction = async ( 'com.openfaas.scale.min': FAAS_MIN_PODS_IN_TEXT, transformationId: trMetadata.transformationId, workspaceId: trMetadata.workspaceId, - team: 'data-managment', - service: 'openfaas', + team: 'data-management', + service: 'openfaas-fn', customer: 'shared', 'customer-tier': CUSTOMER_TIER }; From 218f08c61662950df05946ea0cf59b9e1e0f6b62 Mon Sep 17 00:00:00 2001 From: Jayc Date: Mon, 8 Apr 2024 14:28:28 +0530 Subject: [PATCH 16/47] chore: adding cost labels to openfaas fn pods --- 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 ff95a93903..00b3720e13 100644 --- a/src/util/openfaas/index.js +++ b/src/util/openfaas/index.js @@ -155,7 +155,7 @@ const deployFaasFunction = async ( team: 'data-management', service: 'openfaas-fn', customer: 'shared', - 'customer-tier': CUSTOMER_TIER + 'customer-tier': CUSTOMER_TIER, }; if ( trMetadata.workspaceId && From 8eb4c4e9b8daebbaeb1d12ff0c17915fe19c2b50 Mon Sep 17 00:00:00 2001 From: Anant Jain <62471433+anantjain45823@users.noreply.github.com> Date: Mon, 8 Apr 2024 17:10:16 +0530 Subject: [PATCH 17/47] fix: shopify: send 500 for identifier call in case of failure (#3235) Co-authored-by: Krishna Chaitanya --- src/util/redis/testData/shopify_source.json | 7 ++----- src/v0/sources/shopify/transform.js | 12 ++++-------- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/src/util/redis/testData/shopify_source.json b/src/util/redis/testData/shopify_source.json index 04b80b8fc9..2120475baf 100644 --- a/src/util/redis/testData/shopify_source.json +++ b/src/util/redis/testData/shopify_source.json @@ -65,11 +65,8 @@ } }, "output": { - "outputToSource": { - "body": "T0s=", - "contentType": "text/plain" - }, - "statusCode": 200 + "error": "Error: Error setting value in Redis due Error: Connection is Closed", + "statusCode": 500 } }, { diff --git a/src/v0/sources/shopify/transform.js b/src/v0/sources/shopify/transform.js index 93e3ed0c72..b6d2a4c6cf 100644 --- a/src/v0/sources/shopify/transform.js +++ b/src/v0/sources/shopify/transform.js @@ -1,6 +1,7 @@ /* eslint-disable @typescript-eslint/naming-convention */ const lodash = require('lodash'); const get = require('get-value'); +const { RedisError } = require('@rudderstack/integrations-lib'); const stats = require('../../../util/stats'); const { getShopifyTopic, @@ -249,16 +250,11 @@ const processIdentifierEvent = async (event, metricMetadata) => { source: metricMetadata.source, writeKey: metricMetadata.writeKey, }); + // returning 500 as status code in case of redis failure + throw new RedisError(`${e}`, 500); } } - const result = { - outputToSource: { - body: Buffer.from('OK').toString('base64'), - contentType: 'text/plain', - }, - statusCode: 200, - }; - return result; + return NO_OPERATION_SUCCESS; }; const process = async (event) => { const metricMetadata = { From 9daf1c989258bd410d5780c1b11c4f6df9654af5 Mon Sep 17 00:00:00 2001 From: shrouti1507 <60211312+shrouti1507@users.noreply.github.com> Date: Mon, 8 Apr 2024 18:19:49 +0530 Subject: [PATCH 18/47] fix: hs bugsnag error (#3252) * fix: hs bugsnag error * fix: addressed review comments --- src/v0/destinations/hs/util.js | 2 + .../destinations/hs/processor/data.ts | 53 +++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/src/v0/destinations/hs/util.js b/src/v0/destinations/hs/util.js index 359c93dc1a..838da08b3b 100644 --- a/src/v0/destinations/hs/util.js +++ b/src/v0/destinations/hs/util.js @@ -20,6 +20,7 @@ const { getDestinationExternalIDInfoForRetl, getValueFromMessage, isNull, + validateEventName, } = require('../../util'); const { CONTACT_PROPERTY_MAP_ENDPOINT, @@ -435,6 +436,7 @@ const getEventAndPropertiesFromConfig = (message, destination, payload) => { if (!hubspotEvents) { throw new InstrumentationError('Event and property mappings are required for track call'); } + validateEventName(event); event = event.trim().toLowerCase(); let eventName; let eventProperties; diff --git a/test/integrations/destinations/hs/processor/data.ts b/test/integrations/destinations/hs/processor/data.ts index f45f3a719b..0867f2cb54 100644 --- a/test/integrations/destinations/hs/processor/data.ts +++ b/test/integrations/destinations/hs/processor/data.ts @@ -5373,4 +5373,57 @@ export const data = [ }, }, }, + { + name: 'hs', + description: 'if event name is anything other than string we throw error', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + channel: 'web', + context: { + traits: { + email: 'testhubspot2@email.com', + firstname: 'Test Hubspot', + }, + }, + type: 'track', + originalTimestamp: '2019-10-15T09:35:31.291Z', + userId: '12345', + event: { name: 'event' }, + properties: { + user_actual_role: 'system_admin, system_user', + user_actual_id: 12345, + }, + sentAt: '2019-10-14T11:15:53.296Z', + }, + destination: destination, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'Event is a required field and should be a string', + statTags: { + destType: 'HS', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, ]; From ad235e785bf6039e11231a915be098130b25ec3b Mon Sep 17 00:00:00 2001 From: shrouti1507 <60211312+shrouti1507@users.noreply.github.com> Date: Mon, 8 Apr 2024 18:30:41 +0530 Subject: [PATCH 19/47] feat: for reddit adding currency and value for addToCart, viewConent event as well (#3239) * feat: adding currency and value for addToCart, viewConent event as well * fix: addressed review comments * fix: util test cases update --- .../v2/destinations/reddit/procWorkflow.yaml | 7 +- src/cdk/v2/destinations/reddit/utils.js | 53 ++++++++ src/cdk/v2/destinations/reddit/utils.test.js | 121 ++++++++++++++++++ .../destinations/reddit/processor/data.ts | 6 + .../destinations/reddit/router/data.ts | 8 ++ 5 files changed, 192 insertions(+), 3 deletions(-) create mode 100644 src/cdk/v2/destinations/reddit/utils.test.js diff --git a/src/cdk/v2/destinations/reddit/procWorkflow.yaml b/src/cdk/v2/destinations/reddit/procWorkflow.yaml index 59725c1257..7b989f15e4 100644 --- a/src/cdk/v2/destinations/reddit/procWorkflow.yaml +++ b/src/cdk/v2/destinations/reddit/procWorkflow.yaml @@ -12,6 +12,7 @@ bindings: path: ../../../../v0/util/index - name: OAuthSecretError path: '@rudderstack/integrations-lib' + - path: ./utils steps: - name: validateInput @@ -56,14 +57,14 @@ steps: const event_type = (eventNames.length === 0 || eventNames[0]==="") ? ({"tracking_type": "Custom", "custom_event_name": event}): ({tracking_type: eventNames[0]}); - name: customFields - condition: $.outputs.prepareTrackPayload.eventType.tracking_type === "Purchase" + condition: $.outputs.prepareTrackPayload.eventType.tracking_type in ['Purchase', 'AddToCart', 'ViewContent'] reference: 'https://ads-api.reddit.com/docs/v2/#tag/Conversions/paths/~1api~1v2.0~1conversions~1events~1%7Baccount_id%7D/post' template: | - const revenue_in_cents = .message.properties.revenue ? Math.round(Number(.message.properties.revenue)*100) + const revenue_in_cents = $.populateRevenueField($.outputs.prepareTrackPayload.eventType.tracking_type,^.message.properties) const customFields = .message.().({ "currency": .properties.currency, "value_decimal": revenue_in_cents ? revenue_in_cents / 100, - "item_count": (Array.isArray(.properties.products) && .properties.products.length) || (.properties.itemCount && Number(.properties.itemCount)), + "item_count": $.outputs.prepareTrackPayload.eventType.tracking_type === 'Purchase' ? (Array.isArray(.properties.products) && .properties.products.length) || (.properties.itemCount && Number(.properties.itemCount)) : null, "value": revenue_in_cents, "conversion_id": .properties.conversionId || .messageId, }); diff --git a/src/cdk/v2/destinations/reddit/utils.js b/src/cdk/v2/destinations/reddit/utils.js index c108603235..f562d31313 100644 --- a/src/cdk/v2/destinations/reddit/utils.js +++ b/src/cdk/v2/destinations/reddit/utils.js @@ -28,6 +28,59 @@ const batchEvents = (successfulEvents) => { const batchedEvents = batchEventChunks(eventChunks); return batchedEvents; }; + +const calculateDefaultRevenue = (properties) => { + // Check if working with products array + if (properties?.products && properties.products.length > 0) { + // Check if all product prices are undefined + if (properties.products.every((product) => product.price === undefined)) { + return null; // Return null if all product prices are undefined + } + // Proceed with calculation if not all prices are undefined + return properties.products.reduce( + (acc, product) => acc + (product.price || 0) * (product.quantity || 1), + 0, + ); + } + // For single product scenario, check if price is undefined + if (properties.price === undefined) { + return null; // Return null if price is undefined + } + // Proceed with calculation if price is defined + return properties.price * (properties.quantity ?? 1); +}; + +const populateRevenueField = (eventType, properties) => { + let revenueInCents; + switch (eventType) { + case 'Purchase': + revenueInCents = + properties.revenue && !Number.isNaN(properties.revenue) + ? Math.round(Number(properties?.revenue) * 100) + : null; + break; + case 'AddToCart': + revenueInCents = + properties.price && !Number.isNaN(properties.price) + ? Math.round(Number(properties?.price) * Number(properties?.quantity || 1) * 100) + : null; + break; + default: + // for viewContent + // eslint-disable-next-line no-case-declarations + const revenue = calculateDefaultRevenue(properties); + revenueInCents = revenue ? revenue * 100 : null; + break; + } + + if (lodash.isNaN(revenueInCents)) { + return null; + } + // Return the value as it is if it's not NaN + return revenueInCents; +}; module.exports = { batchEvents, + populateRevenueField, + calculateDefaultRevenue, }; diff --git a/src/cdk/v2/destinations/reddit/utils.test.js b/src/cdk/v2/destinations/reddit/utils.test.js new file mode 100644 index 0000000000..7cfa87e38f --- /dev/null +++ b/src/cdk/v2/destinations/reddit/utils.test.js @@ -0,0 +1,121 @@ +const { calculateDefaultRevenue, populateRevenueField } = require('./utils'); + +describe('calculateDefaultRevenue', () => { + // Calculates revenue for a single product with defined price and quantity + it('should calculate revenue for a single product with defined price and quantity', () => { + const properties = { + price: 10, + quantity: 2, + }; + + const result = calculateDefaultRevenue(properties); + + expect(result).toBe(20); + }); + + // Returns null for properties parameter being undefined + it('should return null for price parameter being undefined', () => { + const properties = { products: [{ quantity: 1 }] }; + + const result = calculateDefaultRevenue(properties); + + expect(result).toBeNull(); + }); + + // Calculates revenue for a single product with defined price and default quantity + it('should calculate revenue for a single product with defined price and default quantity', () => { + const properties = { + price: 10, + }; + + const result = calculateDefaultRevenue(properties); + + expect(result).toBe(10); + }); + + // Calculates revenue for multiple products with defined prices and quantities + it('should calculate revenue for multiple products with defined prices and quantities', () => { + const properties = { + products: [{ price: 10, quantity: 2 }, { quantity: 3 }], + }; + + const result = calculateDefaultRevenue(properties); + + expect(result).toBe(20); + }); + + // Calculates revenue for multiple products with defined prices and default quantities + it('should calculate revenue for multiple products with defined prices and default quantities', () => { + const properties = { + products: [{ price: 10 }, { price: 5 }], + }; + + const result = calculateDefaultRevenue(properties); + + expect(result).toBe(15); + }); +}); + +describe('populateRevenueField', () => { + // Returns revenue in cents for Purchase event type with valid revenue property + it('should return revenue in cents when Purchase event type has valid revenue property', () => { + const eventType = 'Purchase'; + const properties = { + revenue: '10.50', + }; + const expected = 1050; + + const result = populateRevenueField(eventType, properties); + + expect(result).toBe(expected); + }); + + // Returns null for Purchase event type with revenue property as non-numeric string + it('should return null when Purchase event type has revenue property as non-numeric string', () => { + const eventType = 'Purchase'; + const properties = { + revenue: 'invalid', + }; + const expected = null; + + const result = populateRevenueField(eventType, properties); + + expect(result).toBe(expected); + }); + + // Returns revenue in cents for AddToCart event type with valid price and quantity properties + it('should return revenue in cents when AddToCart event type has valid price and quantity properties', () => { + const eventType = 'AddToCart'; + const properties = { + price: '10.50', + quantity: 2, + }; + const expected = 2100; + + const result = populateRevenueField(eventType, properties); + + expect(result).toBe(expected); + }); + + // Returns revenue in cents for ViewContent event type with valid properties + it('should return revenue in cents when ViewContent event type has valid properties', () => { + const eventType = 'ViewContent'; + const properties = { + products: [ + { + price: '10.50', + quantity: 2, + }, + { + price: '5.25', + quantity: 3, + }, + ], + }; + const expected = 3675; + + const result = populateRevenueField(eventType, properties); + + expect(result).toBe(expected); + }); +}); diff --git a/test/integrations/destinations/reddit/processor/data.ts b/test/integrations/destinations/reddit/processor/data.ts index 49e0cd2baa..a97ae23d2a 100644 --- a/test/integrations/destinations/reddit/processor/data.ts +++ b/test/integrations/destinations/reddit/processor/data.ts @@ -443,6 +443,8 @@ export const data = [ }, event_metadata: { item_count: 0, + value: 2600, + value_decimal: 26, products: [ { id: '017c6f5d5cf86a4b22432066', @@ -581,6 +583,8 @@ export const data = [ }, event_metadata: { item_count: 5, + value: 24995, + value_decimal: 249.95, products: [ { id: '622c6f5d5cf86a4c77358033', @@ -847,6 +851,8 @@ export const data = [ }, event_metadata: { item_count: 5, + value: 24995, + value_decimal: 249.95, products: [ { id: '622c6f5d5cf86a4c77358033', diff --git a/test/integrations/destinations/reddit/router/data.ts b/test/integrations/destinations/reddit/router/data.ts index 723afff374..b5bed48ae7 100644 --- a/test/integrations/destinations/reddit/router/data.ts +++ b/test/integrations/destinations/reddit/router/data.ts @@ -90,6 +90,8 @@ export const data = [ properties: { list_id: 'list1', category: "What's New", + value: 2600, + value_decimal: 26, products: [ { product_id: '017c6f5d5cf86a4b22432066', @@ -230,6 +232,8 @@ export const data = [ }, event_metadata: { item_count: 0, + value: 2600, + value_decimal: 26, products: [ { id: '017c6f5d5cf86a4b22432066', @@ -259,6 +263,8 @@ export const data = [ }, event_metadata: { item_count: 5, + value: 24995, + value_decimal: 249.95, products: [ { id: '622c6f5d5cf86a4c77358033', @@ -349,6 +355,8 @@ export const data = [ properties: { list_id: 'list1', category: "What's New", + value: 2600, + value_decimal: 26, products: [ { product_id: '017c6f5d5cf86a4b22432066', From 48cf9f282b803382dd2961b4b834d08a06eaab63 Mon Sep 17 00:00:00 2001 From: shrouti1507 <60211312+shrouti1507@users.noreply.github.com> Date: Mon, 8 Apr 2024 19:08:58 +0530 Subject: [PATCH 20/47] feat: adding product level tracking for awin (#3246) * feat: adding product level tracking for awin * fix: address review comments --- src/v0/destinations/awin/transform.js | 14 +- src/v0/destinations/awin/utils.js | 51 ++++ src/v0/destinations/awin/utils.test.js | 165 ++++++++++ test/integrations/destinations/awin/data.ts | 315 ++++++++++++++++++++ 4 files changed, 542 insertions(+), 3 deletions(-) create mode 100644 src/v0/destinations/awin/utils.test.js diff --git a/src/v0/destinations/awin/transform.js b/src/v0/destinations/awin/transform.js index 49a115c1ff..0d7fd95c33 100644 --- a/src/v0/destinations/awin/transform.js +++ b/src/v0/destinations/awin/transform.js @@ -2,10 +2,12 @@ const { InstrumentationError, ConfigurationError } = require('@rudderstack/integ const { BASE_URL, ConfigCategory, mappingConfig } = require('./config'); const { defaultRequestConfig, constructPayload, simpleProcessRouterDest } = require('../../util'); -const { getParams } = require('./utils'); +const { getParams, trackProduct } = require('./utils'); const responseBuilder = (message, { Config }) => { const { advertiserId, eventsToTrack } = Config; + const { event, properties } = message; + let finalParams = {}; const payload = constructPayload(message, mappingConfig[ConfigCategory.TRACK.name]); @@ -17,8 +19,14 @@ const responseBuilder = (message, { Config }) => { }); // if the event is present in eventsList - if (eventsList.includes(message.event)) { + if (eventsList.includes(event)) { params = getParams(payload.params, advertiserId); + const productTrackObject = trackProduct(properties, advertiserId, params.parts); + + finalParams = { + ...params, + ...productTrackObject, + }; } else { throw new InstrumentationError( "Event is not present in 'Events to Track' list. Aborting message.", @@ -27,7 +35,7 @@ const responseBuilder = (message, { Config }) => { } } const response = defaultRequestConfig(); - response.params = params; + response.params = finalParams; response.endpoint = BASE_URL; return response; diff --git a/src/v0/destinations/awin/utils.js b/src/v0/destinations/awin/utils.js index 1616227c55..be5f22474d 100644 --- a/src/v0/destinations/awin/utils.js +++ b/src/v0/destinations/awin/utils.js @@ -1,3 +1,5 @@ +const lodash = require('lodash'); + /** * Returns final params * @param {*} params @@ -24,6 +26,55 @@ const getParams = (parameters, advertiserId) => { return params; }; +const areAllValuesDefined = (obj) => + lodash.every(lodash.values(obj), (value) => !lodash.isUndefined(value)); + +const buildProductPayloadString = (payload) => { + // URL-encode each value, and join back with the same key. + const encodedPayload = Object.entries(payload).reduce((acc, [key, value]) => { + // Encode each value. Assuming that all values are either strings or can be + // safely converted to strings. + acc[key] = encodeURIComponent(value); + return acc; + }, {}); + + return `AW:P|${encodedPayload.advertiserId}|${encodedPayload.orderReference}|${encodedPayload.productId}|${encodedPayload.productName}|${encodedPayload.productItemPrice}|${encodedPayload.productQuantity}|${encodedPayload.productSku}|${encodedPayload.commissionGroupCode}|${encodedPayload.productCategory}`; +}; + +// ref: https://wiki.awin.com/index.php/Advertiser_Tracking_Guide/Product_Level_Tracking#PLT_Via_Conversion_Pixel +const trackProduct = (properties, advertiserId, commissionParts) => { + const transformedProductInfoObj = {}; + if ( + properties?.products && + Array.isArray(properties?.products) && + properties.products.length > 0 + ) { + const productsArray = properties.products; + let productIndex = 0; + productsArray.forEach((product) => { + const productPayloadNew = { + advertiserId, + orderReference: properties.order_id || properties.orderId, + productId: product.product_id || product.productId, + productName: product.name, + productItemPrice: product.price, + productQuantity: product.quantity, + productSku: product.sku || '', + commissionGroupCode: commissionParts || 'DEFAULT', + productCategory: product.category || '', + }; + if (areAllValuesDefined(productPayloadNew)) { + transformedProductInfoObj[`bd[${productIndex}]`] = + buildProductPayloadString(productPayloadNew); + productIndex += 1; + } + }); + } + return transformedProductInfoObj; +}; + module.exports = { getParams, + trackProduct, + buildProductPayloadString, }; diff --git a/src/v0/destinations/awin/utils.test.js b/src/v0/destinations/awin/utils.test.js new file mode 100644 index 0000000000..e60c07e96c --- /dev/null +++ b/src/v0/destinations/awin/utils.test.js @@ -0,0 +1,165 @@ +const { buildProductPayloadString, trackProduct } = require('./utils'); + +describe('buildProductPayloadString', () => { + // Should correctly build the payload string with all fields provided + it('should correctly build the payload string with all fields provided', () => { + const payload = { + advertiserId: '123', + orderReference: 'order123', + productId: 'prod123', + productName: 'Product 1', + productItemPrice: '10.99', + productQuantity: '2', + productSku: 'sku123', + commissionGroupCode: 'DEFAULT', + productCategory: 'Category 1', + }; + + const expected = 'AW:P|123|order123|prod123|Product%201|10.99|2|sku123|DEFAULT|Category%201'; + const result = buildProductPayloadString(payload); + + expect(result).toBe(expected); + }); + + // Should correctly handle extremely long string values for all fields + it('should correctly handle extremely long string values for all fields', () => { + const payload = { + advertiserId: '123', + orderReference: 'order123', + productId: 'prod123', + productName: 'Product 1'.repeat(100000), + productItemPrice: '10.99'.repeat(100000), + productQuantity: '2'.repeat(100000), + productSku: 'sku123'.repeat(100000), + commissionGroupCode: 'DEFAULT', + productCategory: 'Category 1'.repeat(100000), + }; + + const expected = `AW:P|123|order123|prod123|${encodeURIComponent('Product 1'.repeat(100000))}|${encodeURIComponent('10.99'.repeat(100000))}|${encodeURIComponent('2'.repeat(100000))}|${encodeURIComponent('sku123'.repeat(100000))}|DEFAULT|${encodeURIComponent('Category 1'.repeat(100000))}`; + const result = buildProductPayloadString(payload); + + expect(result).toBe(expected); + }); +}); + +describe('trackProduct', () => { + // Given a valid 'properties' object with a non-empty 'products' array, it should transform each product into a valid payload string and return an object with the transformed products. + it("should transform each product into a valid payload string and return an object with the transformed products when given a valid 'properties' object with a non-empty 'products' array", () => { + // Arrange + const properties = { + products: [ + { + product_id: '123', + name: 'Product 1', + price: 10, + quantity: 1, + sku: 'SKU123', + category: 'Category 1', + }, + { + product_id: '456', + name: 'Product 2', + price: 20, + quantity: 2, + sku: 'SKU456', + category: 'Category 2', + }, + ], + order_id: 'order123', + }; + const advertiserId = 'advertiser123'; + const commissionParts = 'COMMISSION'; + + // Act + const result = trackProduct(properties, advertiserId, commissionParts); + + // Assert + expect(result).toEqual({ + 'bd[0]': 'AW:P|advertiser123|order123|123|Product%201|10|1|SKU123|COMMISSION|Category%201', + 'bd[1]': 'AW:P|advertiser123|order123|456|Product%202|20|2|SKU456|COMMISSION|Category%202', + }); + }); + + // Given an invalid 'properties' object, it should return an empty object. + it("should return an empty object when given an invalid 'properties' object", () => { + // Arrange + const properties = {}; + const advertiserId = 'advertiser123'; + const commissionParts = 'COMMISSION'; + + // Act + const result = trackProduct(properties, advertiserId, commissionParts); + + // Assert + expect(result).toEqual({}); + }); + + it('should ignore the product which has missing properties', () => { + // Arrange + const properties = { + products: [ + { + price: 10, + quantity: 1, + sku: 'SKU123', + category: 'Category 1', + }, + { + product_id: '456', + name: 'Product 2', + price: 20, + quantity: 2, + sku: 'SKU456', + category: 'Category 2', + }, + ], + order_id: 'order123', + }; + const advertiserId = 'advertiser123'; + const commissionParts = 'COMMISSION'; + + // Act + const result = trackProduct(properties, advertiserId, commissionParts); + + // Assert + expect(result).toEqual({ + 'bd[0]': 'AW:P|advertiser123|order123|456|Product%202|20|2|SKU456|COMMISSION|Category%202', + }); + }); + + it('category and sku if undefined we put blank', () => { + // Arrange + const properties = { + products: [ + { + product_id: '123', + name: 'Product 1', + price: 10, + quantity: 1, + sku: undefined, + category: 'Category 1', + }, + { + product_id: '456', + name: 'Product 2', + price: 20, + quantity: 2, + sku: 'SKU456', + category: undefined, + }, + ], + order_id: 'order123', + }; + const advertiserId = 'advertiser123'; + const commissionParts = 'COMMISSION'; + + // Act + const result = trackProduct(properties, advertiserId, commissionParts); + + // Assert + expect(result).toEqual({ + 'bd[0]': 'AW:P|advertiser123|order123|123|Product%201|10|1||COMMISSION|Category%201', + 'bd[1]': 'AW:P|advertiser123|order123|456|Product%202|20|2|SKU456|COMMISSION|', + }); + }); +}); diff --git a/test/integrations/destinations/awin/data.ts b/test/integrations/destinations/awin/data.ts index 64c8fbc2a1..8ca294b5fb 100644 --- a/test/integrations/destinations/awin/data.ts +++ b/test/integrations/destinations/awin/data.ts @@ -843,4 +843,319 @@ export const data = [ }, }, }, + { + name: 'awin', + description: 'Track call- with product array', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + advertiserId: '1234', + eventsToTrack: [ + { + eventName: 'abc', + }, + { + eventName: 'prop2', + }, + { + eventName: 'prop3', + }, + ], + }, + }, + message: { + type: 'track', + event: 'prop2', + sentAt: '2022-01-20T13:39:21.033Z', + userId: 'user123456001', + channel: 'web', + properties: { + currency: 'INR', + voucherCode: '1bcu1', + amount: 500, + commissionGroup: 'sales', + cks: 'new', + testMode: '1', + order_id: 'QW123', + products: [ + { + product_id: '123', + name: 'Product 1', + price: 10, + quantity: 1, + sku: undefined, + category: 'Category 1', + }, + { + product_id: '456', + name: 'Product 2', + price: 20, + quantity: 2, + sku: 'SKU456', + category: undefined, + }, + ], + }, + context: { + os: { + name: '', + version: '', + }, + app: { + name: 'RudderLabs JavaScript SDK', + build: '1.0.0', + version: '1.2.20', + namespace: 'com.rudderlabs.javascript', + }, + page: { + url: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html', + path: '/Testing/App_for_LaunchDarkly/ourSdk.html', + title: 'Document', + search: '', + tab_url: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html', + referrer: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/', + initial_referrer: '$direct', + referring_domain: '127.0.0.1:7307', + initial_referring_domain: '', + }, + locale: 'en-US', + screen: { + width: 1440, + height: 900, + density: 2, + innerWidth: 536, + innerHeight: 689, + }, + traits: { + city: 'Pune', + name: 'First User', + email: 'firstUser@testmail.com', + title: 'VP', + gender: 'female', + avatar: 'https://i.pravatar.cc/300', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.2.20', + }, + campaign: {}, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36', + }, + rudderId: '553b5522-c575-40a7-8072-9741c5f9a647', + messageId: '831f1fa5-de84-4f22-880a-4c3f23fc3f04', + anonymousId: 'bf412108-0357-4330-b119-7305e767823c', + integrations: { + All: true, + }, + originalTimestamp: '2022-01-20T13:39:21.032Z', + }, + }, + ], + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.awin1.com/sread.php', + headers: {}, + params: { + amount: 500, + ch: 'aw', + parts: 'sales:500', + cr: 'INR', + tt: 'ss', + tv: '2', + vc: '1bcu1', + cks: 'new', + merchant: '1234', + testmode: '1', + ref: 'QW123', + 'bd[0]': 'AW:P|1234|QW123|123|Product%201|10|1||sales%3A500|Category%201', + 'bd[1]': 'AW:P|1234|QW123|456|Product%202|20|2|SKU456|sales%3A500|', + }, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, + { + name: 'awin', + description: 'Track call- with product array where important keys might be missing.', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + advertiserId: '1234', + eventsToTrack: [ + { + eventName: 'abc', + }, + { + eventName: 'prop2', + }, + { + eventName: 'prop3', + }, + ], + }, + }, + message: { + type: 'track', + event: 'prop2', + sentAt: '2022-01-20T13:39:21.033Z', + userId: 'user123456001', + channel: 'web', + properties: { + currency: 'INR', + voucherCode: '1bcu1', + amount: 500, + commissionGroup: 'sales', + cks: 'new', + testMode: '1', + order_id: 'QW123', + products: [ + { + price: 10, + quantity: 1, + sku: undefined, + category: 'Category 1', + }, + { + product_id: '456', + name: 'Product 2', + price: 20, + quantity: 2, + sku: 'SKU456', + category: undefined, + }, + ], + }, + context: { + os: { + name: '', + version: '', + }, + app: { + name: 'RudderLabs JavaScript SDK', + build: '1.0.0', + version: '1.2.20', + namespace: 'com.rudderlabs.javascript', + }, + page: { + url: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html', + path: '/Testing/App_for_LaunchDarkly/ourSdk.html', + title: 'Document', + search: '', + tab_url: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/ourSdk.html', + referrer: 'http://127.0.0.1:7307/Testing/App_for_LaunchDarkly/', + initial_referrer: '$direct', + referring_domain: '127.0.0.1:7307', + initial_referring_domain: '', + }, + locale: 'en-US', + screen: { + width: 1440, + height: 900, + density: 2, + innerWidth: 536, + innerHeight: 689, + }, + traits: { + city: 'Pune', + name: 'First User', + email: 'firstUser@testmail.com', + title: 'VP', + gender: 'female', + avatar: 'https://i.pravatar.cc/300', + }, + library: { + name: 'RudderLabs JavaScript SDK', + version: '1.2.20', + }, + campaign: {}, + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36', + }, + rudderId: '553b5522-c575-40a7-8072-9741c5f9a647', + messageId: '831f1fa5-de84-4f22-880a-4c3f23fc3f04', + anonymousId: 'bf412108-0357-4330-b119-7305e767823c', + integrations: { + All: true, + }, + originalTimestamp: '2022-01-20T13:39:21.032Z', + }, + }, + ], + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://www.awin1.com/sread.php', + headers: {}, + params: { + amount: 500, + ch: 'aw', + parts: 'sales:500', + cr: 'INR', + tt: 'ss', + tv: '2', + vc: '1bcu1', + cks: 'new', + merchant: '1234', + testmode: '1', + ref: 'QW123', + 'bd[0]': 'AW:P|1234|QW123|456|Product%202|20|2|SKU456|sales%3A500|', + }, + body: { + JSON: {}, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + userId: '', + }, + statusCode: 200, + }, + ], + }, + }, + }, ]; From 3748f24e21634fc74c5e5b3761551c64c8e69942 Mon Sep 17 00:00:00 2001 From: Anant Jain <62471433+anantjain45823@users.noreply.github.com> Date: Mon, 8 Apr 2024 23:42:22 +0530 Subject: [PATCH 21/47] feat: rakuten: adding a default value for tr (#3240) * feat: rakuten: adding a default value for tr * chore: add common config * fix: use empty space as default value * chore: address comments --- .../rakuten/data/propertiesMapping.json | 6 +- .../rakuten/processor/commonConfig.ts | 24 ++++ .../destinations/rakuten/processor/track.ts | 126 ++++++++++++++++++ .../processor/transformationFailure.ts | 6 +- 4 files changed, 157 insertions(+), 5 deletions(-) diff --git a/src/cdk/v2/destinations/rakuten/data/propertiesMapping.json b/src/cdk/v2/destinations/rakuten/data/propertiesMapping.json index db5d36fc4d..1a69f53205 100644 --- a/src/cdk/v2/destinations/rakuten/data/propertiesMapping.json +++ b/src/cdk/v2/destinations/rakuten/data/propertiesMapping.json @@ -6,8 +6,10 @@ }, { "sourceKeys": ["properties.tr", "properties.ran_site_id", "properties.ranSiteID"], - "required": true, - "destKey": "tr" + "destKey": "tr", + "metadata": { + "defaultValue": " " + } }, { "sourceKeys": ["properties.land", "properties.land_time", "properties.landTime"], diff --git a/test/integrations/destinations/rakuten/processor/commonConfig.ts b/test/integrations/destinations/rakuten/processor/commonConfig.ts index e7e2af7fbd..96bc6669c2 100644 --- a/test/integrations/destinations/rakuten/processor/commonConfig.ts +++ b/test/integrations/destinations/rakuten/processor/commonConfig.ts @@ -63,3 +63,27 @@ export const commonProperties = { storeId: '12345', storecat: 'Electronics', }; +export const commonPropertiesWithoutRansiteID = { + orderId: 'SampleOrderId', + landTime: '20240129_1200', + date: '20240129_1300', + altord: 'SampleAlternateOrderId', + currency: 'INR', + creditCardType: 'Visa', + commReason: 'SampleCommReason', + isComm: 'Y', + consumed: '20240129_1400', + coupon: 'SampleCoupon', + custId: 'SampleCustomerId', + custScore: 'A', + custStatus: 'New', + dId: 'SampleDeviceId', + disamt: '50.00', + ordStatus: 'Pending', + segment: 'SampleSegment', + shipcountry: 'USA', + shipped: '20240129_1500', + sitename: 'SampleSiteName', + storeId: '12345', + storecat: 'Electronics', +}; diff --git a/test/integrations/destinations/rakuten/processor/track.ts b/test/integrations/destinations/rakuten/processor/track.ts index 49b26e4658..74d09b8d4c 100644 --- a/test/integrations/destinations/rakuten/processor/track.ts +++ b/test/integrations/destinations/rakuten/processor/track.ts @@ -4,6 +4,7 @@ import { commonProperties, endpoint, singleProductWithAllProperties, + commonPropertiesWithoutRansiteID, } from './commonConfig'; import { transformResultBuilder } from '../../../testUtils'; export const trackSuccess = [ @@ -449,4 +450,129 @@ export const trackSuccess = [ }, }, }, + { + id: 'rakuten-test-track-success-5', + name: 'rakuten', + description: 'Track call no ranSiteId in input', + scenario: 'Business', + successCriteria: + 'Response should contain only properties with tr as empty string (ransiteId) and product payload and status code should be 200', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: { + type: 'track', + event: 'product purchased', + sentAt: '2021-01-25T16:12:02.048Z', + userId: 'sajal12', + channel: 'mobile', + rudderId: 'b7b24f86-f7bf-46d8-b2b4-ccafc080239c', + messageId: '1611588776408-ee5a3212-fbf9-4cbb-bbad-3ed0f7c6a2ce', + properties: { + ...commonPropertiesWithoutRansiteID, + products: [ + { ...singleProductWithAllProperties }, + { + sku: 'custom sku 1', + quantity: 5, + amount: 25, + name: 'name_1', + }, + { + sku: 'custom sku 2', + name: 'SampleProduct', + quantity: 1, + amount: 30, + coupon: 'SALE50', + }, + ], + }, + anonymousId: '9c6bd77ea9da3e68', + integrations: { + All: true, + }, + originalTimestamp: '2021-01-25T15:32:56.409Z', + }, + metadata: { + destinationId: 'dummyDestId', + jobId: '1', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + metadata: { + destinationId: 'dummyDestId', + jobId: '1', + }, + output: transformResultBuilder({ + method: 'GET', + endpoint, + headers: commonOutputHeaders, + params: { + mid: 'dummyMarketingId', + xml: 1, + source: 'rudderstack', + amtlist: '2000|2500|3000', + brandlist: 'SampleBrand||', + catidlist: '12345||', + catlist: 'Electronics||', + couponlist: 'SALE20||SALE50', + disamtlist: '10.5||', + distypelist: 'Percentage||', + ismarketplacelist: 'N||', + sequencelist: '123||', + shipbylist: 'Express||', + shipidlist: 'SHIP123||', + qlist: '5|5|1', + marginlist: '0.15||', + markdownlist: '5||', + taxexemptlist: 'N||', + namelist: 'SampleProduct|name_1|SampleProduct', + skulist: 'ABC123|custom sku 1|custom sku 2', + issalelist: 'Y||', + itmstatuslist: 'In Stock||', + isclearancelist: 'Y||', + ord: 'SampleOrderId', + tr: ' ', + land: '20240129_1200', + date: '20240129_1300', + altord: 'SampleAlternateOrderId', + cur: 'INR', + cc: 'Visa', + commreason: 'SampleCommReason', + iscomm: 'Y', + consumed: '20240129_1400', + coupon: 'SampleCoupon', + custid: 'SampleCustomerId', + custscore: 'A', + custstatus: 'New', + did: 'SampleDeviceId', + disamt: '50.00', + ordstatus: 'Pending', + segment: 'SampleSegment', + shipcountry: 'USA', + shipped: '20240129_1500', + sitename: 'SampleSiteName', + storeid: '12345', + storecat: 'Electronics', + }, + userId: '', + }), + statusCode: 200, + }, + ], + }, + }, + }, ]; diff --git a/test/integrations/destinations/rakuten/processor/transformationFailure.ts b/test/integrations/destinations/rakuten/processor/transformationFailure.ts index e35ab26b69..5485efae03 100644 --- a/test/integrations/destinations/rakuten/processor/transformationFailure.ts +++ b/test/integrations/destinations/rakuten/processor/transformationFailure.ts @@ -202,9 +202,9 @@ export const transformationFailures = [ { id: 'rakuten-test-5', name: 'rakuten', - description: 'No eligible property available for required field tr present', + description: 'No eligible property available for required field land present', scenario: 'Framework', - successCriteria: 'Transformationn Error for required field tr not present', + successCriteria: 'Transformationn Error for required field land not present', feature: 'processor', module: 'destination', version: 'v0', @@ -245,7 +245,7 @@ export const transformationFailures = [ body: [ { error: - 'Missing required value from ["properties.tr","properties.ran_site_id","properties.ranSiteID"]: Workflow: procWorkflow, Step: prepareTrackPayload, ChildStep: undefined, OriginalError: Missing required value from ["properties.tr","properties.ran_site_id","properties.ranSiteID"]', + 'Missing required value from ["properties.land","properties.land_time","properties.landTime"]: Workflow: procWorkflow, Step: prepareTrackPayload, ChildStep: undefined, OriginalError: Missing required value from ["properties.land","properties.land_time","properties.landTime"]', metadata: { destinationId: 'dummyDestId', jobId: '1', From 9214594bab2c86a4ae6f75e12531f778490cf127 Mon Sep 17 00:00:00 2001 From: AASHISH MALIK Date: Tue, 9 Apr 2024 13:18:09 +0530 Subject: [PATCH 22/47] feat: do away myaxios (#3222) * feat: do away myaxios --- src/v0/destinations/sfmc/transform.js | 73 ++-- .../integrations/destinations/sfmc/network.ts | 50 +++ .../destinations/sfmc/processor/data.ts | 322 ++++++++++++++++++ 3 files changed, 401 insertions(+), 44 deletions(-) diff --git a/src/v0/destinations/sfmc/transform.js b/src/v0/destinations/sfmc/transform.js index 53925bc7ed..bf474ff3f0 100644 --- a/src/v0/destinations/sfmc/transform.js +++ b/src/v0/destinations/sfmc/transform.js @@ -7,8 +7,8 @@ const { isDefinedAndNotNull, isEmpty, } = require('@rudderstack/integrations-lib'); -const myAxios = require('../../../util/myAxios'); const { EventType } = require('../../../constants'); +const { handleHttpRequest } = require('../../../adapters/network'); const { CONFIG_CATEGORIES, MAPPING_CONFIG, ENDPOINTS } = require('./config'); const { removeUndefinedAndNullValues, @@ -22,10 +22,8 @@ const { getHashFromArray, simpleProcessRouterDest, } = require('../../util'); -const { - getDynamicErrorType, - nodeSysErrorToStatus, -} = require('../../../adapters/utils/networkUtils'); +const { getDynamicErrorType } = require('../../../adapters/utils/networkUtils'); +const { isHttpStatusSuccess } = require('../../util'); const tags = require('../../util/tags'); const { JSON_MIME_TYPE } = require('../../util/constant'); @@ -34,51 +32,38 @@ const CONTACT_KEY_KEY = 'Contact Key'; // DOC: https://developer.salesforce.com/docs/atlas.en-us.mc-app-development.meta/mc-app-development/access-token-s2s.htm const getToken = async (clientId, clientSecret, subdomain) => { - try { - const resp = await myAxios.post( - `https://${subdomain}.${ENDPOINTS.GET_TOKEN}`, - { - grant_type: 'client_credentials', - client_id: clientId, - client_secret: clientSecret, - }, - { - 'Content-Type': JSON_MIME_TYPE, - }, - { - destType: 'sfmc', - feature: 'transformation', - endpointPath: '/token', - requestMethod: 'POST', - module: 'router', - }, - ); - if (resp && resp.data) { - return resp.data.access_token; - } - const status = resp.status || 400; + const { processedResponse: processedResponseSfmc } = await handleHttpRequest( + 'post', + `https://${subdomain}.${ENDPOINTS.GET_TOKEN}`, + { + grant_type: 'client_credentials', + client_id: clientId, + client_secret: clientSecret, + }, + { + 'Content-Type': JSON_MIME_TYPE, + }, + { + destType: 'sfmc', + feature: 'transformation', + endpointPath: '/token', + requestMethod: 'POST', + module: 'router', + }, + ); + + if (!isHttpStatusSuccess(processedResponseSfmc.status)) { throw new NetworkError( 'Could not retrieve access token', - status, + processedResponseSfmc.status || 400, { - [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(status), + [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(processedResponseSfmc.status || 400), }, - resp, + processedResponseSfmc.response, ); - } catch (error) { - if (!isEmpty(error.response)) { - const status = error.status || 400; - throw new NetworkError(`Authorization Failed ${error.response.statusText}`, status, { - [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(status), - }); - } else { - const httpError = nodeSysErrorToStatus(error.code); - const status = httpError.status || 400; - throw new NetworkError(`Authorization Failed ${httpError.message}`, status, { - [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(status), - }); - } } + + return processedResponseSfmc.response.access_token; }; // DOC : https://developer.salesforce.com/docs/atlas.en-us.noversion.mc-apis.meta/mc-apis/createContacts.htm diff --git a/test/integrations/destinations/sfmc/network.ts b/test/integrations/destinations/sfmc/network.ts index 7564d8c6d5..93854e3691 100644 --- a/test/integrations/destinations/sfmc/network.ts +++ b/test/integrations/destinations/sfmc/network.ts @@ -11,4 +11,54 @@ export const networkCallsData = [ }, }, }, + { + httpReq: { + url: 'https://testHandleHttpRequest401.auth.marketingcloudapis.com/v2/token', + method: 'POST', + }, + httpRes: { + status: 401, + data: { + error: 'invalid_client', + error_description: + 'Invalid client ID. Use the client ID in Marketing Cloud Installed Packages.', + error_uri: 'https://developer.salesforce.com/docs', + }, + }, + }, + { + httpReq: { + url: 'https://testHandleHttpRequest429.auth.marketingcloudapis.com/v2/token', + method: 'POST', + }, + httpRes: { + status: 429, + data: { + message: 'Your requests are temporarily blocked.', + errorcode: 50200, + documentation: + 'https://developer.salesforce.com/docs/atlas.en-us.mc-apis.meta/mc-apis/error-handling.htm', + }, + }, + }, + { + httpReq: { + url: 'https://testHandleHttpRequest-dns.auth.marketingcloudapis.com/v2/token', + method: 'POST', + }, + httpRes: { + data: {}, + status: 400, + }, + }, + { + httpReq: { + url: 'https://testHandleHttpRequest-null.auth.marketingcloudapis.com/v2/token', + method: 'POST', + }, + httpRes: { + data: null, + status: 500, + }, + }, ]; diff --git a/test/integrations/destinations/sfmc/processor/data.ts b/test/integrations/destinations/sfmc/processor/data.ts index b2839908ad..883032d223 100644 --- a/test/integrations/destinations/sfmc/processor/data.ts +++ b/test/integrations/destinations/sfmc/processor/data.ts @@ -1894,4 +1894,326 @@ export const data = [ }, }, }, + { + name: 'sfmc', + description: 'Tests 401 un authenticated code from sfmc', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + event: 'message event', + type: 'track', + userId: '12345', + properties: { + id: 'id101', + contactId: 'cid101', + email: 'testemail@gmail.com', + accountNumber: '99110099', + patronName: 'SP', + }, + }, + destination: { + ID: '1pYpzzvcn7AQ2W9GGIAZSsN6Mfq', + Name: 'SFMC', + DestinationDefinition: { + ID: '1pYpYSeQd8OeN6xPdw6VGDzqUd1', + Name: 'SFMC', + DisplayName: 'Salesforce Marketing Cloud', + Config: { + destConfig: [], + excludeKeys: [], + includeKeys: [], + saveDestinationResponse: false, + supportedSourceTypes: [], + transformAt: 'processor', + }, + ResponseRules: {}, + }, + Config: { + clientId: 'testHandleHttpRequest401', + clientSecret: 'testHandleHttpRequest401', + createOrUpdateContacts: false, + eventDelivery: true, + eventDeliveryTS: 1615371070621, + eventToExternalKey: [ + { + from: 'Event Name', + to: 'C500FD37-155C-49BD-A21B-AFCEF3D1A9CB', + }, + { + from: 'Watch', + to: 'C500FD37-155C-49BD-A21B-AFCEF3D1A9CB', + }, + ], + eventToPrimaryKey: [ + { + from: 'userId', + to: 'User Key', + }, + { + from: 'watch', + to: 'Guest Key, Contact Key', + }, + ], + eventToUUID: [ + { + event: 'Event Name', + uuid: true, + }, + ], + eventToDefinitionMapping: [ + { + from: 'message event', + to: 'test-event-definition', + }, + ], + externalKey: 'f3ffa19b-e0b3-4967-829f-549b781080e6', + subDomain: 'testHandleHttpRequest401', + }, + Enabled: true, + Transformations: [], + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + '{"message":"Could not retrieve access token","destinationResponse":{"error":"invalid_client","error_description":"Invalid client ID. Use the client ID in Marketing Cloud Installed Packages.","error_uri":"https://developer.salesforce.com/docs"}}', + statTags: { + destType: 'SFMC', + errorCategory: 'network', + errorType: 'aborted', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 401, + }, + ], + }, + }, + }, + { + name: 'sfmc', + description: 'Tests 429 status code from sfmc', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + event: 'message event', + type: 'track', + userId: '12345', + properties: { + id: 'id101', + contactId: 'cid101', + email: 'testemail@gmail.com', + accountNumber: '99110099', + patronName: 'SP', + }, + }, + destination: { + ID: '1pYpzzvcn7AQ2W9GGIAZSsN6Mfq', + Name: 'SFMC', + DestinationDefinition: { + ID: '1pYpYSeQd8OeN6xPdw6VGDzqUd1', + Name: 'SFMC', + DisplayName: 'Salesforce Marketing Cloud', + Config: { + destConfig: [], + excludeKeys: [], + includeKeys: [], + saveDestinationResponse: false, + supportedSourceTypes: [], + transformAt: 'processor', + }, + ResponseRules: {}, + }, + Config: { + clientId: 'testHandleHttpRequest429', + clientSecret: 'testHandleHttpRequest429', + subDomain: 'testHandleHttpRequest429', + }, + Enabled: true, + Transformations: [], + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + '{"message":"Could not retrieve access token","destinationResponse":{"message":"Your requests are temporarily blocked.","errorcode":50200,"documentation":"https://developer.salesforce.com/docs/atlas.en-us.mc-apis.meta/mc-apis/error-handling.htm"}}', + statTags: { + destType: 'SFMC', + errorCategory: 'network', + errorType: 'throttled', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 429, + }, + ], + }, + }, + }, + { + name: 'sfmc', + description: 'Tests DNS lookup failure for sfmc', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + event: 'message event', + type: 'track', + userId: '12345', + properties: { + id: 'id101', + contactId: 'cid101', + email: 'testemail@gmail.com', + accountNumber: '99110099', + patronName: 'SP', + }, + }, + destination: { + ID: '1pYpzzvcn7AQ2W9GGIAZSsN6Mfq', + Name: 'SFMC', + DestinationDefinition: { + ID: '1pYpYSeQd8OeN6xPdw6VGDzqUd1', + Name: 'SFMC', + DisplayName: 'Salesforce Marketing Cloud', + Config: { + destConfig: [], + excludeKeys: [], + includeKeys: [], + saveDestinationResponse: false, + supportedSourceTypes: [], + transformAt: 'processor', + }, + ResponseRules: {}, + }, + Config: { + clientId: 'testHandleHttpRequest-dns', + clientSecret: 'testHandleHttpRequest-dns', + subDomain: 'testHandleHttpRequest-dns', + }, + Enabled: true, + Transformations: [], + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: '{"message":"Could not retrieve access token","destinationResponse":{}}', + statTags: { + destType: 'SFMC', + errorCategory: 'network', + errorType: 'aborted', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 400, + }, + ], + }, + }, + }, + { + name: 'sfmc', + description: 'Test 500 status failure for sfmc', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + message: { + event: 'message event', + type: 'track', + userId: '12345', + properties: { + id: 'id101', + contactId: 'cid101', + email: 'testemail@gmail.com', + accountNumber: '99110099', + patronName: 'SP', + }, + }, + destination: { + ID: '1pYpzzvcn7AQ2W9GGIAZSsN6Mfq', + Name: 'SFMC', + DestinationDefinition: { + ID: '1pYpYSeQd8OeN6xPdw6VGDzqUd1', + Name: 'SFMC', + DisplayName: 'Salesforce Marketing Cloud', + Config: { + destConfig: [], + excludeKeys: [], + includeKeys: [], + saveDestinationResponse: false, + supportedSourceTypes: [], + transformAt: 'processor', + }, + ResponseRules: {}, + }, + Config: { + clientId: 'testHandleHttpRequest-null', + clientSecret: 'testHandleHttpRequest-null', + subDomain: 'testHandleHttpRequest-null', + }, + Enabled: true, + Transformations: [], + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: 'Could not retrieve access token', + statTags: { + destType: 'SFMC', + errorCategory: 'network', + errorType: 'retryable', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 500, + }, + ], + }, + }, + }, ]; From 9c6b251a6c784cc391f27e846a008fbe2901e2c8 Mon Sep 17 00:00:00 2001 From: Sandeep Digumarty Date: Tue, 9 Apr 2024 17:24:41 +0530 Subject: [PATCH 23/47] fix: fixed userId mapping, now mapping to uid instead of id (#3262) --- src/cdk/v2/destinations/fullstory/procWorkflow.yaml | 2 +- test/integrations/destinations/fullstory/processor/data.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cdk/v2/destinations/fullstory/procWorkflow.yaml b/src/cdk/v2/destinations/fullstory/procWorkflow.yaml index 1a54e8688c..26da955623 100644 --- a/src/cdk/v2/destinations/fullstory/procWorkflow.yaml +++ b/src/cdk/v2/destinations/fullstory/procWorkflow.yaml @@ -76,7 +76,7 @@ steps: "use_most_recent": .message.properties.useMostRecent, }; $.context.payload.user = { - "id": .message.properties.userId ?? .message.userId, + "uid": .message.properties.userId ?? .message.userId, } - name: cleanPayload diff --git a/test/integrations/destinations/fullstory/processor/data.ts b/test/integrations/destinations/fullstory/processor/data.ts index d206b4a84f..9c8d29c7e8 100644 --- a/test/integrations/destinations/fullstory/processor/data.ts +++ b/test/integrations/destinations/fullstory/processor/data.ts @@ -149,7 +149,7 @@ export const data = [ id: 's001', }, user: { - id: 'u001', + uid: 'u001', }, }, JSON_ARRAY: {}, From 6e3274bfba9e7838d1f81d845a070427b67e75f5 Mon Sep 17 00:00:00 2001 From: shrouti1507 <60211312+shrouti1507@users.noreply.github.com> Date: Tue, 9 Apr 2024 17:31:10 +0530 Subject: [PATCH 24/47] fix: marketo bulk ignore null while checking data type mismatch (#3263) --- .../marketo_bulk_upload/marketo_bulk_upload.util.test.js | 6 ++---- src/v0/destinations/marketo_bulk_upload/util.js | 8 ++++++-- 2 files changed, 8 insertions(+), 6 deletions(-) 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 aa4b3aacc4..13e1b3a09a 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 @@ -514,7 +514,7 @@ describe('checkEventStatusViaSchemaMatching', () => { }); // The function correctly handles events with null values. - it('should correctly handle events with null values', () => { + it('should ignore event properties with null values', () => { const event = { input: [ { @@ -537,8 +537,6 @@ describe('checkEventStatusViaSchemaMatching', () => { const result = checkEventStatusViaSchemaMatching(event, fieldSchemaMapping); - expect(result).toEqual({ - job1: 'invalid id', - }); + expect(result).toEqual({}); }); }); diff --git a/src/v0/destinations/marketo_bulk_upload/util.js b/src/v0/destinations/marketo_bulk_upload/util.js index 4c99ba7483..033239b5e4 100644 --- a/src/v0/destinations/marketo_bulk_upload/util.js +++ b/src/v0/destinations/marketo_bulk_upload/util.js @@ -3,6 +3,7 @@ const { RetryableError, NetworkError, TransformationError, + isDefinedAndNotNull, } = require('@rudderstack/integrations-lib'); const { handleHttpRequest } = require('../../../adapters/network'); const tags = require('../../util/tags'); @@ -360,7 +361,6 @@ const getFieldSchemaMap = async (accessToken, munchkinId) => { module: 'router', }, ); - if (fieldSchemaMapping.response.errors) { handleCommonErrorResponse( fieldSchemaMapping, @@ -411,7 +411,11 @@ const checkEventStatusViaSchemaMatching = (event, fieldMap) => { const expectedDataType = SCHEMA_DATA_TYPE_MAP[fieldMap[paramName]]; const actualDataType = typeof paramValue; - if (!mismatchedFields[job_id] && actualDataType !== expectedDataType) { + if ( + isDefinedAndNotNull(paramValue) && + !mismatchedFields[job_id] && + actualDataType !== expectedDataType + ) { mismatchedFields[job_id] = `invalid ${paramName}`; } }); From c204113eab37a782f217488d0d626a8d6df345d3 Mon Sep 17 00:00:00 2001 From: AASHISH MALIK Date: Tue, 9 Apr 2024 18:05:33 +0530 Subject: [PATCH 25/47] feat: logger upgrade in services, dest, source (#3228) * feat: logger upgrade in services, dest, source --- .eslintrc.json | 1 + package-lock.json | 43 +---------- package.json | 2 +- src/cdk/v2/handler.ts | 10 ++- src/controllers/bulkUpload.ts | 38 +++------- src/controllers/delivery.ts | 33 ++++---- src/controllers/destination.ts | 59 +++++++------- src/controllers/regulation.ts | 13 ++-- src/controllers/source.ts | 18 ++--- src/controllers/userTransform.ts | 26 +++---- src/index.ts | 14 ++-- src/interfaces/DestinationService.ts | 7 +- src/interfaces/SourceService.ts | 2 + src/services/comparator.ts | 9 ++- .../__tests__/nativeIntegration.test.ts | 11 ++- src/services/destination/cdkV2Integration.ts | 36 +++++---- src/services/destination/nativeIntegration.ts | 76 ++++++++++++------- .../destination/postTransformation.ts | 46 +++++++---- src/services/misc.ts | 22 +++++- .../__tests__/nativeIntegration.test.ts | 23 ++++-- src/services/source/nativeIntegration.ts | 14 ++-- src/util/redis/redisConnector.test.js | 3 +- .../campaign_manager/transform.js | 3 +- src/v0/destinations/mailchimp/utils.js | 7 +- src/v0/destinations/twitter_ads/transform.js | 3 +- src/v0/sources/canny/transform.js | 11 ++- src/v0/sources/shopify/transform.js | 7 +- src/v0/sources/shopify/util.js | 3 +- .../__tests__/pinterestConversion-cdk.test.ts | 25 +++++- test/apitests/service.api.test.ts | 8 +- 30 files changed, 311 insertions(+), 262 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 7258c5c536..556470697d 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -26,6 +26,7 @@ "off", { "cases": { "camelCase": true, "pascalCase": true, "kebabCase": true } } ], + "import/no-import-module-exports": "off", "unicorn/no-instanceof-array": "error", "unicorn/no-static-only-class": "error", "unicorn/consistent-destructuring": "error", diff --git a/package-lock.json b/package-lock.json index 65659a745c..fd42692109 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,7 +19,7 @@ "@koa/router": "^12.0.0", "@ndhoule/extend": "^2.0.0", "@pyroscope/nodejs": "^0.2.9", - "@rudderstack/integrations-lib": "^0.2.7", + "@rudderstack/integrations-lib": "^0.2.8", "@rudderstack/workflow-engine": "^0.7.5", "@shopify/jest-koa-mocks": "^5.1.1", "ajv": "^8.12.0", @@ -118,41 +118,6 @@ "typescript": "^5.0.4" } }, - "../rudder-integrations-lib": { - "name": "@rudderstack/integrations-lib", - "version": "0.1.10", - "extraneous": true, - "license": "MIT", - "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", - "winston": "^3.11.0" - }, - "devDependencies": { - "@types/get-value": "^3.0.3", - "@types/jest": "^29.5.4", - "@types/lodash": "^4.14.195", - "@types/node": "^20.3.3", - "@types/set-value": "^4.0.1", - "@types/sha256": "^0.2.0", - "jest": "^29.4.3", - "pre-commit": "^1.2.2", - "prettier": "^2.8.4", - "ts-jest": "^29.0.5", - "ts-node": "^10.9.1", - "typescript": "^5.1.6" - } - }, "node_modules/@aashutoshrathi/word-wrap": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", @@ -4472,9 +4437,9 @@ } }, "node_modules/@rudderstack/integrations-lib": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/@rudderstack/integrations-lib/-/integrations-lib-0.2.7.tgz", - "integrity": "sha512-F0QVIT2vpSeI+GcUk7AwxMJrmM5SsRk8AS6oH4nHkjjfDoKjdh9rrDVzhXKUYF//FAi32ecmSsW+/6ioB8louw==", + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/@rudderstack/integrations-lib/-/integrations-lib-0.2.8.tgz", + "integrity": "sha512-5CJoFFCRDhG7busCGVktKqEEXO0DbFqJ56TOT+jyDdoTf8sZ7SsSJ4NCZYmSplZrbQGj2R+aArnQnpxA4hPGmA==", "dependencies": { "axios": "^1.4.0", "axios-mock-adapter": "^1.22.0", diff --git a/package.json b/package.json index c91d836c34..c839bc8acc 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,7 @@ "@koa/router": "^12.0.0", "@ndhoule/extend": "^2.0.0", "@pyroscope/nodejs": "^0.2.9", - "@rudderstack/integrations-lib": "^0.2.7", + "@rudderstack/integrations-lib": "^0.2.8", "@rudderstack/workflow-engine": "^0.7.5", "@shopify/jest-koa-mocks": "^5.1.1", "ajv": "^8.12.0", diff --git a/src/cdk/v2/handler.ts b/src/cdk/v2/handler.ts index edd14e7298..c437247f74 100644 --- a/src/cdk/v2/handler.ts +++ b/src/cdk/v2/handler.ts @@ -1,9 +1,9 @@ import { - WorkflowEngine, - WorkflowEngineFactory, - TemplateType, ExecutionBindings, StepOutput, + TemplateType, + WorkflowEngine, + WorkflowEngineFactory, } from '@rudderstack/workflow-engine'; import { FixMe } from '../../util/types'; @@ -11,9 +11,9 @@ import tags from '../../v0/util/tags'; import { getErrorInfo, + getPlatformBindingsPaths, getRootPathForDestination, getWorkflowPath, - getPlatformBindingsPaths, isCdkV2Destination, } from './utils'; @@ -82,10 +82,12 @@ export async function processCdkV2Workflow( destType: string, parsedEvent: FixMe, feature: string, + logger: FixMe, requestMetadata: NonNullable = {}, bindings: Record = {}, ) { try { + logger.debug(`Processing cdkV2 workflow`); const workflowEngine = await getCachedWorkflowEngine(destType, feature, bindings); return await executeWorkflow(workflowEngine, parsedEvent, requestMetadata); } catch (error) { diff --git a/src/controllers/bulkUpload.ts b/src/controllers/bulkUpload.ts index dbd77dc07f..28556dd5df 100644 --- a/src/controllers/bulkUpload.ts +++ b/src/controllers/bulkUpload.ts @@ -1,10 +1,10 @@ /* eslint-disable global-require, import/no-dynamic-require, @typescript-eslint/no-unused-vars */ +import { structuredLogger as logger } from '@rudderstack/integrations-lib'; import { client as errNotificationClient } from '../util/errorNotifier'; -import logger from '../logger'; import { + getDestFileUploadHandler, getJobStatusHandler, getPollStatusHandler, - getDestFileUploadHandler, } from '../util/fetchDestinationHandlers'; import { CatchErr, ContextBodySimple } from '../util/types'; // TODO: To be refactored and redisgned @@ -31,10 +31,7 @@ const getReqMetadata = (ctx) => { }; export const fileUpload = async (ctx) => { - logger.debug( - 'Native(Bulk-Upload): Request to transformer:: /fileUpload route', - JSON.stringify(ctx.request.body), - ); + logger.debug('Native(Bulk-Upload): Request to transformer:: /fileUpload route', ctx.request.body); const getReqMetadataFileUpload = () => { try { const reqBody = ctx.request.body; @@ -69,18 +66,12 @@ export const fileUpload = async (ctx) => { }); } ctx.body = response; - logger.debug( - 'Native(Bulk-Upload): Response from transformer:: /fileUpload route', - JSON.stringify(ctx.body), - ); + logger.debug('Native(Bulk-Upload): Response from transformer:: /fileUpload route', ctx.body); return ctx.body; }; export const pollStatus = async (ctx) => { - logger.debug( - 'Native(Bulk-Upload): Request to transformer:: /pollStatus route', - JSON.stringify(ctx.request.body), - ); + logger.debug('Native(Bulk-Upload): Request to transformer:: /pollStatus route', ctx.request.body); const { destType }: ContextBodySimple = ctx.request.body; const destFileUploadHandler = getPollStatusHandler('v0', destType.toLowerCase()); @@ -104,17 +95,14 @@ export const pollStatus = async (ctx) => { }); } ctx.body = response; - logger.debug( - 'Native(Bulk-Upload): Request from transformer:: /pollStatus route', - JSON.stringify(ctx.body), - ); + logger.debug('Native(Bulk-Upload): Request from transformer:: /pollStatus route', ctx.body); return ctx.body; }; export const getWarnJobStatus = async (ctx) => { logger.debug( 'Native(Bulk-Upload): Request to transformer:: /getWarningJobs route', - JSON.stringify(ctx.request.body), + ctx.request.body, ); const { destType }: ContextBodySimple = ctx.request.body; @@ -140,17 +128,14 @@ export const getWarnJobStatus = async (ctx) => { }); } ctx.body = response; - logger.debug( - 'Native(Bulk-Upload): Request from transformer:: /getWarningJobs route', - JSON.stringify(ctx.body), - ); + logger.debug('Native(Bulk-Upload): Request from transformer:: /getWarningJobs route', ctx.body); return ctx.body; }; export const getFailedJobStatus = async (ctx) => { logger.debug( 'Native(Bulk-Upload): Request to transformer:: /getFailedJobs route', - JSON.stringify(ctx.request.body), + ctx.request.body, ); const { destType }: ContextBodySimple = ctx.request.body; @@ -176,9 +161,6 @@ export const getFailedJobStatus = async (ctx) => { }); } ctx.body = response; - logger.debug( - 'Native(Bulk-Upload): Request from transformer:: /getFailedJobs route', - JSON.stringify(ctx.body), - ); + logger.debug('Native(Bulk-Upload): Request from transformer:: /getFailedJobs route', ctx.body); return ctx.body; }; diff --git a/src/controllers/delivery.ts b/src/controllers/delivery.ts index 4334dc33b2..8ac7c9902a 100644 --- a/src/controllers/delivery.ts +++ b/src/controllers/delivery.ts @@ -1,28 +1,30 @@ /* eslint-disable prefer-destructuring */ /* eslint-disable sonarjs/no-duplicate-string */ +import { + isDefinedAndNotNullAndNotEmpty, + structuredLogger as logger, +} from '@rudderstack/integrations-lib'; import { Context } from 'koa'; -import { isDefinedAndNotNullAndNotEmpty } from '@rudderstack/integrations-lib'; +import { ServiceSelector } from '../helpers/serviceSelector'; +import { DeliveryTestService } from '../services/delivertTest/deliveryTest'; +import { DestinationPostTransformationService } from '../services/destination/postTransformation'; import { MiscService } from '../services/misc'; import { - DeliveryV1Response, DeliveryV0Response, + DeliveryV1Response, ProcessorTransformationOutput, ProxyV0Request, ProxyV1Request, } from '../types/index'; -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 tags from '../v0/util/tags'; import { FixMe } from '../util/types'; +import tags from '../v0/util/tags'; +import { ControllerUtility } from './util'; 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)); + logger.info('Native(Delivery):: Request to transformer::', ctx.request.body); let deliveryResponse: DeliveryV0Response; const requestMetadata = MiscService.getRequestMetadata(ctx); const deliveryRequest = ctx.request.body as ProxyV0Request; @@ -52,12 +54,12 @@ export class DeliveryController { ctx.body = { output: deliveryResponse }; ControllerUtility.deliveryPostProcess(ctx, deliveryResponse.status); - logger.debug('Native(Delivery):: Response from transformer::', JSON.stringify(ctx.body)); + logger.debug('Native(Delivery):: Response from transformer::', ctx.body); return ctx; } public static async deliverToDestinationV1(ctx: Context) { - logger.debug('Native(Delivery):: Request to transformer::', JSON.stringify(ctx.request.body)); + logger.debug('Native(Delivery):: Request to transformer::', ctx.request.body); let deliveryResponse: DeliveryV1Response; const requestMetadata = MiscService.getRequestMetadata(ctx); const deliveryRequest = ctx.request.body as ProxyV1Request; @@ -91,15 +93,12 @@ export class DeliveryController { ControllerUtility.deliveryPostProcess(ctx); } - logger.debug('Native(Delivery):: Response from transformer::', JSON.stringify(ctx.body)); + logger.debug('Native(Delivery):: Response from transformer::', ctx.body); return ctx; } public static async testDestinationDelivery(ctx: Context) { - logger.debug( - 'Native(Delivery-Test):: Request to transformer::', - JSON.stringify(ctx.request.body), - ); + logger.debug('Native(Delivery-Test):: Request to transformer::', ctx.request.body); const { destination }: { destination: string } = ctx.params; const { version }: { version: string } = ctx.params; const { @@ -117,7 +116,7 @@ export class DeliveryController { ); ctx.body = { output: response }; ControllerUtility.postProcess(ctx); - logger.debug('Native(Delivery-Test):: Response from transformer::', JSON.stringify(ctx.body)); + logger.debug('Native(Delivery-Test):: Response from transformer::', ctx.body); return ctx; } } diff --git a/src/controllers/destination.ts b/src/controllers/destination.ts index d8b3c94524..35606ea62e 100644 --- a/src/controllers/destination.ts +++ b/src/controllers/destination.ts @@ -1,29 +1,27 @@ +import { structuredLogger as logger } from '@rudderstack/integrations-lib'; import { Context } from 'koa'; -import { MiscService } from '../services/misc'; -import { DestinationPreTransformationService } from '../services/destination/preTransformation'; +import { ServiceSelector } from '../helpers/serviceSelector'; import { DestinationPostTransformationService } from '../services/destination/postTransformation'; +import { DestinationPreTransformationService } from '../services/destination/preTransformation'; +import { MiscService } from '../services/misc'; import { + ErrorDetailer, ProcessorTransformationRequest, - RouterTransformationRequest, ProcessorTransformationResponse, + RouterTransformationRequest, RouterTransformationResponse, } from '../types/index'; -import { ServiceSelector } from '../helpers/serviceSelector'; -import { ControllerUtility } from './util'; +import { DynamicConfigParser } from '../util/dynamicConfigParser'; 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 { checkInvalidRtTfEvents } from '../v0/util'; +import tags from '../v0/util/tags'; +import { ControllerUtility } from './util'; export class DestinationController { public static async destinationTransformAtProcessor(ctx: Context) { const startTime = new Date(); - logger.debug( - 'Native(Process-Transform):: Requst to transformer::', - JSON.stringify(ctx.request.body), - ); + logger.debug('Native(Process-Transform):: Requst to transformer::', ctx.request.body); let resplist: ProcessorTransformationResponse[]; const requestMetadata = MiscService.getRequestMetadata(ctx); let events = ctx.request.body as ProcessorTransformationRequest[]; @@ -35,6 +33,9 @@ export class DestinationController { ...metaTags, }); const integrationService = ServiceSelector.getDestinationService(events); + const loggerWithCtx = logger.child({ + ...MiscService.getLoggableData(events[0]?.metadata as unknown as ErrorDetailer), + }); try { integrationService.init(); events = DestinationPreTransformationService.preProcess( @@ -50,6 +51,7 @@ export class DestinationController { destination, version, requestMetadata, + loggerWithCtx, ); } catch (error: any) { resplist = events.map((ev) => { @@ -69,10 +71,7 @@ export class DestinationController { } ctx.body = resplist; ControllerUtility.postProcess(ctx); - logger.debug( - 'Native(Process-Transform):: Response from transformer::', - JSON.stringify(ctx.body), - ); + loggerWithCtx.debug('Native(Process-Transform):: Response from transformer::', ctx.body); stats.histogram('dest_transform_output_events', resplist.length, { destination, version, @@ -94,10 +93,7 @@ export class DestinationController { public static async destinationTransformAtRouter(ctx: Context) { const startTime = new Date(); - logger.debug( - 'Native(Router-Transform):: Requst to transformer::', - JSON.stringify(ctx.request.body), - ); + logger.debug('Native(Router-Transform):: Requst to transformer::', ctx.request.body); const requestMetadata = MiscService.getRequestMetadata(ctx); const routerRequest = ctx.request.body as RouterTransformationRequest; const destination = routerRequest.destType; @@ -117,6 +113,9 @@ export class DestinationController { return ctx; } const metaTags = MiscService.getMetaTags(events[0].metadata); + const loggerWithCtx = logger.child({ + ...MiscService.getLoggableData(events[0]?.metadata as unknown as ErrorDetailer), + }); stats.histogram('dest_transform_input_events', events.length, { destination, version: 'v0', @@ -133,6 +132,7 @@ export class DestinationController { destination, getIntegrationVersion(), requestMetadata, + loggerWithCtx, ); } catch (error: any) { const metaTO = integrationService.getTags( @@ -155,10 +155,7 @@ export class DestinationController { version: 'v0', ...metaTags, }); - logger.debug( - 'Native(Router-Transform):: Response from transformer::', - JSON.stringify(ctx.body), - ); + loggerWithCtx.debug('Native(Router-Transform):: Response from transformer::', ctx.body); stats.timing('dest_transform_request_latency', startTime, { destination, version: 'v0', @@ -169,15 +166,15 @@ export class DestinationController { } public static batchProcess(ctx: Context) { - logger.debug( - 'Native(Process-Transform-Batch):: Requst to transformer::', - JSON.stringify(ctx.request.body), - ); + logger.info('Native(Process-Transform-Batch):: Requst to transformer::', ctx.request.body); const startTime = new Date(); const requestMetadata = MiscService.getRequestMetadata(ctx); const routerRequest = ctx.request.body as RouterTransformationRequest; const destination = routerRequest.destType; let events = routerRequest.input; + const loggerWithCtx = logger.child({ + ...MiscService.getLoggableData(events[0]?.metadata as unknown as ErrorDetailer), + }); const integrationService = ServiceSelector.getDestinationService(events); try { events = DestinationPreTransformationService.preProcess(events, ctx); @@ -187,6 +184,7 @@ export class DestinationController { destination, getIntegrationVersion(), requestMetadata, + loggerWithCtx, ); ctx.body = resplist; } catch (error: any) { @@ -204,10 +202,7 @@ export class DestinationController { ctx.body = [errResp]; } ControllerUtility.postProcess(ctx); - logger.debug( - 'Native(Process-Transform-Batch):: Response from transformer::', - JSON.stringify(ctx.body), - ); + loggerWithCtx.debug('Native(Process-Transform-Batch):: Response from transformer::', ctx.body); stats.timing('dest_transform_request_latency', startTime, { destination, feature: tags.FEATURES.BATCH, diff --git a/src/controllers/regulation.ts b/src/controllers/regulation.ts index 318b5ed4e7..4b8f87e3fa 100644 --- a/src/controllers/regulation.ts +++ b/src/controllers/regulation.ts @@ -1,19 +1,16 @@ +import { structuredLogger as logger } from '@rudderstack/integrations-lib'; import { Context } from 'koa'; -import logger from '../logger'; -import { UserDeletionRequest, UserDeletionResponse } from '../types'; import { ServiceSelector } from '../helpers/serviceSelector'; -import tags from '../v0/util/tags'; -import stats from '../util/stats'; import { DestinationPostTransformationService } from '../services/destination/postTransformation'; +import { UserDeletionRequest, UserDeletionResponse } from '../types'; +import stats from '../util/stats'; +import tags from '../v0/util/tags'; // eslint-disable-next-line @typescript-eslint/no-unused-vars import { CatchErr } from '../util/types'; export class RegulationController { public static async deleteUsers(ctx: Context) { - logger.debug( - 'Native(Process-Transform):: Requst to transformer::', - JSON.stringify(ctx.request.body), - ); + logger.debug('Native(Process-Transform):: Requst to transformer::', ctx.request.body); const startTime = new Date(); let rudderDestInfo: any; try { diff --git a/src/controllers/source.ts b/src/controllers/source.ts index ef5483a756..e1a4931371 100644 --- a/src/controllers/source.ts +++ b/src/controllers/source.ts @@ -1,20 +1,18 @@ +import { structuredLogger as logger } from '@rudderstack/integrations-lib'; import { Context } from 'koa'; -import { MiscService } from '../services/misc'; import { ServiceSelector } from '../helpers/serviceSelector'; -import { ControllerUtility } from './util'; -import logger from '../logger'; +import { MiscService } from '../services/misc'; import { SourcePostTransformationService } from '../services/source/postTransformation'; +import { ControllerUtility } from './util'; export class SourceController { public static async sourceTransform(ctx: Context) { - logger.debug( - 'Native(Source-Transform):: Request to transformer::', - JSON.stringify(ctx.request.body), - ); + logger.debug('Native(Source-Transform):: Request to transformer::', ctx.request.body); const requestMetadata = MiscService.getRequestMetadata(ctx); const events = ctx.request.body as object[]; const { version, source }: { version: string; source: string } = ctx.params; const integrationService = ServiceSelector.getNativeSourceService(); + const loggerWithCtx = logger.child({ version, source }); try { const { implementationVersion, input } = ControllerUtility.adaptInputToVersion( source, @@ -26,6 +24,7 @@ export class SourceController { source, implementationVersion, requestMetadata, + loggerWithCtx, ); ctx.body = resplist; } catch (err: any) { @@ -34,10 +33,7 @@ export class SourceController { ctx.body = [resp]; } ControllerUtility.postProcess(ctx); - logger.debug( - 'Native(Source-Transform):: Response from transformer::', - JSON.stringify(ctx.body), - ); + loggerWithCtx.debug('Native(Source-Transform):: Response from transformer::', ctx.body); return ctx; } } diff --git a/src/controllers/userTransform.ts b/src/controllers/userTransform.ts index 3e01686a52..0e288c6f04 100644 --- a/src/controllers/userTransform.ts +++ b/src/controllers/userTransform.ts @@ -1,10 +1,10 @@ +import { structuredLogger as logger } from '@rudderstack/integrations-lib'; import { Context } from 'koa'; -import { ProcessorTransformationRequest, UserTransformationServiceResponse } from '../types/index'; import { UserTransformService } from '../services/userTransform'; -import logger from '../logger'; +import { ProcessorTransformationRequest, UserTransformationServiceResponse } from '../types/index'; import { - setupUserTransformHandler, extractLibraries, + setupUserTransformHandler, validateCode, } from '../util/customTransformer'; import { ControllerUtility } from './util'; @@ -13,7 +13,7 @@ export class UserTransformController { public static async transform(ctx: Context) { logger.debug( '(User transform - router:/customTransform ):: Request to transformer', - JSON.stringify(ctx.request.body), + ctx.request.body, ); const requestSize = Number(ctx.request.get('content-length')); const events = ctx.request.body as ProcessorTransformationRequest[]; @@ -23,7 +23,7 @@ export class UserTransformController { ControllerUtility.postProcess(ctx, processedRespone.retryStatus); logger.debug( '(User transform - router:/customTransform ):: Response from transformer', - JSON.stringify(ctx.response.body), + ctx.response.body, ); return ctx; } @@ -31,7 +31,7 @@ export class UserTransformController { public static async testTransform(ctx: Context) { logger.debug( '(User transform - router:/transformation/test ):: Request to transformer', - JSON.stringify(ctx.request.body), + ctx.request.body, ); const { events, trRevCode, libraryVersionIDs = [] } = ctx.request.body as any; const response = await UserTransformService.testTransformRoutine( @@ -43,7 +43,7 @@ export class UserTransformController { ControllerUtility.postProcess(ctx, response.status); logger.debug( '(User transform - router:/transformation/test ):: Response from transformer', - JSON.stringify(ctx.response.body), + ctx.response.body, ); return ctx; } @@ -51,7 +51,7 @@ export class UserTransformController { public static async testTransformLibrary(ctx: Context) { logger.debug( '(User transform - router:/transformationLibrary/test ):: Request to transformer', - JSON.stringify(ctx.request.body), + ctx.request.body, ); try { const { code, language = 'javascript' } = ctx.request.body as any; @@ -66,7 +66,7 @@ export class UserTransformController { } logger.debug( '(User transform - router:/transformationLibrary/test ):: Response from transformer', - JSON.stringify(ctx.response.body), + ctx.response.body, ); return ctx; } @@ -74,7 +74,7 @@ export class UserTransformController { public static async testTransformSethandle(ctx: Context) { logger.debug( '(User transform - router:/transformation/sethandle ):: Request to transformer', - JSON.stringify(ctx.request.body), + ctx.request.body, ); try { const { trRevCode, libraryVersionIDs = [] } = ctx.request.body as any; @@ -96,7 +96,7 @@ export class UserTransformController { } logger.debug( '(User transform - router:/transformation/sethandle ):: Response from transformer', - JSON.stringify(ctx.request.body), + ctx.request.body, ); return ctx; } @@ -104,7 +104,7 @@ export class UserTransformController { public static async extractLibhandle(ctx: Context) { logger.debug( '(User transform - router:/extractLibs ):: Request to transformer', - JSON.stringify(ctx.request.body), + ctx.request.body, ); try { const { @@ -134,7 +134,7 @@ export class UserTransformController { } logger.debug( '(User transform - router:/extractLibs ):: Response from transformer', - JSON.stringify(ctx.request.body), + ctx.request.body, ); return ctx; } diff --git a/src/index.ts b/src/index.ts index 36f32f1aed..5557994b2e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,14 +1,14 @@ +import { structuredLogger as logger } from '@rudderstack/integrations-lib'; +import dotenv from 'dotenv'; +import gracefulShutdown from 'http-graceful-shutdown'; import Koa from 'koa'; import bodyParser from 'koa-bodyparser'; -import gracefulShutdown from 'http-graceful-shutdown'; -import dotenv from 'dotenv'; -import logger from './logger'; -import cluster from './util/cluster'; +import { addRequestSizeMiddleware, addStatMiddleware, initPyroscope } from './middleware'; +import { addSwaggerRoutes, applicationRoutes } from './routes'; import { metricsRouter } from './routes/metricsRouter'; -import { addStatMiddleware, addRequestSizeMiddleware, initPyroscope } from './middleware'; -import { logProcessInfo } from './util/utils'; -import { applicationRoutes, addSwaggerRoutes } from './routes'; +import cluster from './util/cluster'; import { RedisDB } from './util/redis/redisConnector'; +import { logProcessInfo } from './util/utils'; dotenv.config(); const clusterEnabled = process.env.CLUSTER_ENABLED !== 'false'; diff --git a/src/interfaces/DestinationService.ts b/src/interfaces/DestinationService.ts index 4947089b5d..5d7596dac5 100644 --- a/src/interfaces/DestinationService.ts +++ b/src/interfaces/DestinationService.ts @@ -1,14 +1,14 @@ import { DeliveryV0Response, + DeliveryV1Response, MetaTransferObject, ProcessorTransformationRequest, ProcessorTransformationResponse, + ProxyRequest, RouterTransformationRequestData, RouterTransformationResponse, UserDeletionRequest, UserDeletionResponse, - ProxyRequest, - DeliveryV1Response, } from '../types/index'; export interface DestinationService { @@ -28,6 +28,7 @@ export interface DestinationService { destinationType: string, version: string, requestMetadata: NonNullable, + logger: NonNullable, ): Promise; doRouterTransformation( @@ -35,6 +36,7 @@ export interface DestinationService { destinationType: string, version: string, requestMetadata: NonNullable, + logger: NonNullable, ): Promise; doBatchTransformation( @@ -42,6 +44,7 @@ export interface DestinationService { destinationType: string, version: string, requestMetadata: NonNullable, + logger: NonNullable, ): RouterTransformationResponse[]; deliver( diff --git a/src/interfaces/SourceService.ts b/src/interfaces/SourceService.ts index c7de8cfe8b..fab6490264 100644 --- a/src/interfaces/SourceService.ts +++ b/src/interfaces/SourceService.ts @@ -1,4 +1,5 @@ import { MetaTransferObject, SourceTransformationResponse } from '../types/index'; +import { FixMe } from '../util/types'; export interface SourceService { getTags(): MetaTransferObject; @@ -8,5 +9,6 @@ export interface SourceService { sourceType: string, version: string, requestMetadata: NonNullable, + logger: FixMe, ): Promise; } diff --git a/src/services/comparator.ts b/src/services/comparator.ts index 36cb0ebd5a..511436dfd1 100644 --- a/src/services/comparator.ts +++ b/src/services/comparator.ts @@ -1,4 +1,5 @@ /* eslint-disable class-methods-use-this */ +import { structuredLogger as logger } from '@rudderstack/integrations-lib'; import { DestinationService } from '../interfaces/DestinationService'; import { DeliveryV0Response, @@ -14,10 +15,9 @@ import { UserDeletionRequest, UserDeletionResponse, } from '../types'; -import tags from '../v0/util/tags'; -import stats from '../util/stats'; -import logger from '../logger'; import { CommonUtils } from '../util/common'; +import stats from '../util/stats'; +import tags from '../v0/util/tags'; const NS_PER_SEC = 1e9; @@ -204,6 +204,7 @@ export class ComparatorService implements DestinationService { destinationType, version, requestMetadata, + logger, ); const primaryTimeDiff = process.hrtime(primaryStartTime); const primaryTime = primaryTimeDiff[0] * NS_PER_SEC + primaryTimeDiff[1]; @@ -262,6 +263,7 @@ export class ComparatorService implements DestinationService { destinationType, version, requestMetadata, + logger, ); const primaryTimeDiff = process.hrtime(primaryStartTime); const primaryTime = primaryTimeDiff[0] * NS_PER_SEC + primaryTimeDiff[1]; @@ -320,6 +322,7 @@ export class ComparatorService implements DestinationService { destinationType, version, requestMetadata, + {}, ); const primaryTimeDiff = process.hrtime(primaryStartTime); const primaryTime = primaryTimeDiff[0] * NS_PER_SEC + primaryTimeDiff[1]; diff --git a/src/services/destination/__tests__/nativeIntegration.test.ts b/src/services/destination/__tests__/nativeIntegration.test.ts index 59c8b41881..85d099d292 100644 --- a/src/services/destination/__tests__/nativeIntegration.test.ts +++ b/src/services/destination/__tests__/nativeIntegration.test.ts @@ -1,11 +1,12 @@ -import { NativeIntegrationDestinationService } from '../nativeIntegration'; -import { DestinationPostTransformationService } from '../postTransformation'; +import { structuredLogger as logger } from '@rudderstack/integrations-lib'; +import { FetchHandler } from '../../../helpers/fetchHandlers'; import { - ProcessorTransformationRequest, ProcessorTransformationOutput, + ProcessorTransformationRequest, ProcessorTransformationResponse, } from '../../../types/index'; -import { FetchHandler } from '../../../helpers/fetchHandlers'; +import { NativeIntegrationDestinationService } from '../nativeIntegration'; +import { DestinationPostTransformationService } from '../postTransformation'; afterEach(() => { jest.clearAllMocks(); @@ -47,6 +48,7 @@ describe('NativeIntegration Service', () => { destType, version, requestMetadata, + logger, ); expect(resp).toEqual(tresponse); @@ -77,6 +79,7 @@ describe('NativeIntegration Service', () => { destType, version, requestMetadata, + logger, ); const expected = [ diff --git a/src/services/destination/cdkV2Integration.ts b/src/services/destination/cdkV2Integration.ts index c18a5cd936..a649da9154 100644 --- a/src/services/destination/cdkV2Integration.ts +++ b/src/services/destination/cdkV2Integration.ts @@ -1,27 +1,28 @@ /* 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 groupBy from 'lodash/groupBy'; import { processCdkV2Workflow } from '../../cdk/v2/handler'; import { DestinationService } from '../../interfaces/DestinationService'; import { DeliveryV0Response, + DeliveryV1Response, ErrorDetailer, MetaTransferObject, + ProcessorTransformationOutput, ProcessorTransformationRequest, ProcessorTransformationResponse, + ProxyRequest, RouterTransformationRequestData, RouterTransformationResponse, - ProcessorTransformationOutput, UserDeletionRequest, UserDeletionResponse, - ProxyRequest, - DeliveryV1Response, } from '../../types/index'; +import stats from '../../util/stats'; +import { CatchErr, FixMe } from '../../util/types'; import tags from '../../v0/util/tags'; +import { MiscService } from '../misc'; import { DestinationPostTransformationService } from './postTransformation'; -import stats from '../../util/stats'; -import { CatchErr } from '../../util/types'; export class CDKV2DestinationService implements DestinationService { public init() {} @@ -55,10 +56,19 @@ export class CDKV2DestinationService implements DestinationService { destinationType: string, _version: string, requestMetadata: NonNullable, + logger: any, ): Promise { // TODO: Change the promise type const respList: ProcessorTransformationResponse[][] = await Promise.all( events.map(async (event) => { + const metaTo = this.getTags( + destinationType, + event.metadata.destinationId, + event.metadata.workspaceId, + tags.FEATURES.PROCESSOR, + ); + metaTo.metadata = event.metadata; + const loggerWithCtx = logger.child({ ...MiscService.getLoggableData(metaTo.errorDetails) }); try { const transformedPayloads: | ProcessorTransformationOutput @@ -66,9 +76,9 @@ export class CDKV2DestinationService implements DestinationService { destinationType, event, tags.FEATURES.PROCESSOR, + loggerWithCtx, requestMetadata, ); - stats.increment('event_transform_success', { destType: destinationType, module: tags.MODULES.DESTINATION, @@ -85,13 +95,6 @@ export class CDKV2DestinationService implements DestinationService { undefined, ); } catch (error: CatchErr) { - const metaTo = this.getTags( - destinationType, - event.metadata.destinationId, - event.metadata.workspaceId, - tags.FEATURES.PROCESSOR, - ); - metaTo.metadata = event.metadata; const erroredResp = DestinationPostTransformationService.handleProcessorTransformFailureEvents( error, @@ -112,6 +115,7 @@ export class CDKV2DestinationService implements DestinationService { destinationType: string, _version: string, requestMetadata: NonNullable, + logger: FixMe, ): Promise { const allDestEvents: object = groupBy( events, @@ -127,12 +131,16 @@ export class CDKV2DestinationService implements DestinationService { tags.FEATURES.ROUTER, ); metaTo.metadata = destInputArray[0].metadata; + const loggerWithCtx = logger.child({ + ...MiscService.getLoggableData(metaTo.errorDetails), + }); try { const doRouterTransformationResponse: RouterTransformationResponse[] = await processCdkV2Workflow( destinationType, destInputArray, tags.FEATURES.ROUTER, + loggerWithCtx, requestMetadata, ); return DestinationPostTransformationService.handleRouterTransformSuccessEvents( diff --git a/src/services/destination/nativeIntegration.ts b/src/services/destination/nativeIntegration.ts index 2bb82fc602..0bc9308fcd 100644 --- a/src/services/destination/nativeIntegration.ts +++ b/src/services/destination/nativeIntegration.ts @@ -1,31 +1,32 @@ /* 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'; +import groupBy from 'lodash/groupBy'; +import networkHandlerFactory from '../../adapters/networkHandlerFactory'; +import { FetchHandler } from '../../helpers/fetchHandlers'; import { DestinationService } from '../../interfaces/DestinationService'; import { + DeliveryJobState, DeliveryV0Response, + DeliveryV1Response, ErrorDetailer, MetaTransferObject, + ProcessorTransformationOutput, ProcessorTransformationRequest, ProcessorTransformationResponse, + ProxyRequest, + ProxyV0Request, + ProxyV1Request, RouterTransformationRequestData, RouterTransformationResponse, - ProcessorTransformationOutput, UserDeletionRequest, UserDeletionResponse, - ProxyRequest, - ProxyV0Request, - ProxyV1Request, - DeliveryV1Response, - DeliveryJobState, } from '../../types/index'; -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'; +import tags from '../../v0/util/tags'; +import { MiscService } from '../misc'; +import { DestinationPostTransformationService } from './postTransformation'; export class NativeIntegrationDestinationService implements DestinationService { public init() {} @@ -59,27 +60,33 @@ export class NativeIntegrationDestinationService implements DestinationService { destinationType: string, version: string, requestMetadata: NonNullable, + logger: any, ): Promise { const destHandler = FetchHandler.getDestHandler(destinationType, version); const respList: ProcessorTransformationResponse[][] = await Promise.all( events.map(async (event) => { + const metaTO = this.getTags( + destinationType, + event.metadata?.destinationId, + event.metadata?.workspaceId, + tags.FEATURES.PROCESSOR, + ); + metaTO.metadata = event.metadata; + const loggerWithCtx = logger.child({ ...MiscService.getLoggableData(metaTO.errorDetails) }); try { const transformedPayloads: | ProcessorTransformationOutput - | ProcessorTransformationOutput[] = await destHandler.process(event, requestMetadata); + | ProcessorTransformationOutput[] = await destHandler.process( + event, + requestMetadata, + loggerWithCtx, + ); return DestinationPostTransformationService.handleProcessorTransformSucessEvents( event, transformedPayloads, destHandler, ); } catch (error: any) { - const metaTO = this.getTags( - destinationType, - event.metadata?.destinationId, - event.metadata?.workspaceId, - tags.FEATURES.PROCESSOR, - ); - metaTO.metadata = event.metadata; const erroredResp = DestinationPostTransformationService.handleProcessorTransformFailureEvents( error, @@ -97,6 +104,7 @@ export class NativeIntegrationDestinationService implements DestinationService { destinationType: string, version: string, requestMetadata: NonNullable, + logger: any, ): Promise { const destHandler = FetchHandler.getDestHandler(destinationType, version); const allDestEvents: NonNullable = groupBy( @@ -112,9 +120,16 @@ export class NativeIntegrationDestinationService implements DestinationService { destInputArray[0].metadata?.workspaceId, tags.FEATURES.ROUTER, ); + const loggerWithCtx = logger.child({ + ...MiscService.getLoggableData(metaTO.errorDetails), + }); try { const doRouterTransformationResponse: RouterTransformationResponse[] = - await destHandler.processRouterDest(cloneDeep(destInputArray), requestMetadata); + await destHandler.processRouterDest( + cloneDeep(destInputArray), + requestMetadata, + loggerWithCtx, + ); metaTO.metadata = destInputArray[0].metadata; return DestinationPostTransformationService.handleRouterTransformSuccessEvents( doRouterTransformationResponse, @@ -141,6 +156,7 @@ export class NativeIntegrationDestinationService implements DestinationService { destinationType: string, version: any, requestMetadata: NonNullable, + logger: any, ): RouterTransformationResponse[] { const destHandler = FetchHandler.getDestHandler(destinationType, version); if (!destHandler.batch) { @@ -152,20 +168,24 @@ export class NativeIntegrationDestinationService implements DestinationService { ); const groupedEvents: RouterTransformationRequestData[][] = Object.values(allDestEvents); const response = groupedEvents.map((destEvents) => { + const metaTO = this.getTags( + destinationType, + destEvents[0].metadata.destinationId, + destEvents[0].metadata.workspaceId, + tags.FEATURES.BATCH, + ); + metaTO.metadatas = events.map((event) => event.metadata); + const loggerWithCtx = logger.child({ + ...MiscService.getLoggableData(metaTO.errorDetails), + }); try { const destBatchedRequests: RouterTransformationResponse[] = destHandler.batch( destEvents, requestMetadata, + loggerWithCtx, ); return destBatchedRequests; } catch (error: any) { - const metaTO = this.getTags( - destinationType, - destEvents[0].metadata.destinationId, - destEvents[0].metadata.workspaceId, - tags.FEATURES.BATCH, - ); - metaTO.metadatas = events.map((event) => event.metadata); const errResp = DestinationPostTransformationService.handleBatchTransformFailureEvents( error, metaTO, @@ -264,6 +284,7 @@ export class NativeIntegrationDestinationService implements DestinationService { error: `${destType}: Doesn't support deletion of users`, } as UserDeletionResponse; } + const metaTO = this.getTags(destType, 'unknown', 'unknown', tags.FEATURES.USER_DELETION); try { const result: UserDeletionResponse = await destUserDeletionHandler.processDeleteUsers({ ...request, @@ -276,7 +297,6 @@ export class NativeIntegrationDestinationService implements DestinationService { }); return result; } catch (error: any) { - const metaTO = this.getTags(destType, 'unknown', 'unknown', tags.FEATURES.USER_DELETION); return DestinationPostTransformationService.handleUserDeletionFailureEvents( error, metaTO, diff --git a/src/services/destination/postTransformation.ts b/src/services/destination/postTransformation.ts index 161547683b..40cee61e66 100644 --- a/src/services/destination/postTransformation.ts +++ b/src/services/destination/postTransformation.ts @@ -1,24 +1,30 @@ /* eslint-disable no-param-reassign */ +import { PlatformError } from '@rudderstack/integrations-lib'; import cloneDeep from 'lodash/cloneDeep'; -import isObject from 'lodash/isObject'; import isEmpty from 'lodash/isEmpty'; -import { PlatformError } from '@rudderstack/integrations-lib'; +import isObject from 'lodash/isObject'; import { + DeliveryJobState, + DeliveryV0Response, + DeliveryV1Response, + MetaTransferObject, + ProcessorTransformationOutput, ProcessorTransformationRequest, ProcessorTransformationResponse, RouterTransformationResponse, - ProcessorTransformationOutput, - DeliveryV0Response, - MetaTransferObject, UserDeletionResponse, - DeliveryV1Response, - DeliveryJobState, } from '../../types/index'; -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'; +import { generateErrorObject } from '../../v0/util'; +import tags from '../../v0/util/tags'; +import { ErrorReportingService } from '../errorReporting'; +import { MiscService } from '../misc'; + +const defaultErrorMessages = { + router: '[Router Transform] Error occurred while processing the payload.', + delivery: '[Delivery] Error occured while processing payload', +} as const; export class DestinationPostTransformationService { public static handleProcessorTransformSucessEvents( @@ -62,6 +68,10 @@ export class DestinationPostTransformationService { error: errObj.message || '[Processor Transform] Error occurred while processing the payload.', statTags: errObj.statTags, } as ProcessorTransformationResponse; + MiscService.logError( + errObj.message || '[Processor Transform] Error occurred while processing the payload.', + metaTo.errorDetails, + ); ErrorReportingService.reportError(error, metaTo.errorContext, resp); return resp; } @@ -99,6 +109,7 @@ export class DestinationPostTransformationService { ...resp.statTags, ...metaTo.errorDetails, }; + MiscService.logError(resp.error || defaultErrorMessages.router, metaTo.errorDetails); stats.increment('event_transform_failure', metaTo.errorDetails); } else { stats.increment('event_transform_success', { @@ -124,9 +135,10 @@ export class DestinationPostTransformationService { metadata: metaTo.metadatas, batched: false, statusCode: errObj.status, - error: errObj.message || '[Router Transform] Error occurred while processing the payload.', + error: errObj.message || defaultErrorMessages.router, statTags: errObj.statTags, } as RouterTransformationResponse; + MiscService.logError(errObj.message || defaultErrorMessages.router, metaTo.errorDetails); ErrorReportingService.reportError(error, metaTo.errorContext, resp); stats.increment('event_transform_failure', metaTo.errorDetails); return resp; @@ -141,9 +153,10 @@ export class DestinationPostTransformationService { metadata: metaTo.metadatas, batched: false, statusCode: 500, // for batch we should consider code error hence keeping retryable - error: errObj.message || '[Batch Transform] Error occurred while processing payload.', + error: errObj.message || defaultErrorMessages.delivery, statTags: errObj.statTags, } as RouterTransformationResponse; + MiscService.logError(error as string, metaTo.errorDetails); ErrorReportingService.reportError(error, metaTo.errorContext, resp); return resp; } @@ -174,6 +187,10 @@ export class DestinationPostTransformationService { const errObj = generateErrorObject(error, metaTo.errorDetails, false); const metadataArray = metaTo.metadatas; if (!Array.isArray(metadataArray)) { + MiscService.logError( + 'Proxy v1 endpoint error : metadataArray is not an array', + metaTo.errorDetails, + ); // Panic throw new PlatformError('Proxy v1 endpoint error : metadataArray is not an array'); } @@ -182,7 +199,7 @@ export class DestinationPostTransformationService { error: JSON.stringify(error.destinationResponse?.response) || errObj.message || - '[Delivery] Error occured while processing payload', + defaultErrorMessages.delivery, statusCode: errObj.status, metadata, } as DeliveryJobState; @@ -198,7 +215,7 @@ export class DestinationPostTransformationService { authErrorCategory: errObj.authErrorCategory, }), } as DeliveryV1Response; - + MiscService.logError(errObj.message, metaTo.errorDetails); ErrorReportingService.reportError(error, metaTo.errorContext, resp); return resp; } @@ -216,6 +233,7 @@ export class DestinationPostTransformationService { authErrorCategory: errObj.authErrorCategory, }), } as UserDeletionResponse; + MiscService.logError(errObj.message, metaTo.errorDetails); ErrorReportingService.reportError(error, metaTo.errorContext, resp); return resp; } diff --git a/src/services/misc.ts b/src/services/misc.ts index e0953d08bf..3df1196c1d 100644 --- a/src/services/misc.ts +++ b/src/services/misc.ts @@ -1,10 +1,11 @@ /* eslint-disable global-require, import/no-dynamic-require */ +import { LoggableExtraData, structuredLogger as logger } from '@rudderstack/integrations-lib'; import fs from 'fs'; -import path from 'path'; import { Context } from 'koa'; +import path from 'path'; import { DestHandlerMap } from '../constants/destinationCanonicalNames'; -import { Metadata } from '../types'; import { getCPUProfile, getHeapProfile } from '../middleware'; +import { ErrorDetailer, Metadata } from '../types'; export class MiscService { public static getDestHandler(dest: string, version: string) { @@ -74,4 +75,21 @@ export class MiscService { public static async getHeapProfile() { return getHeapProfile(); } + + public static getLoggableData(errorDetailer: ErrorDetailer): Partial { + return { + ...(errorDetailer?.destinationId && { destinationId: errorDetailer.destinationId }), + ...(errorDetailer?.sourceId && { sourceId: errorDetailer.sourceId }), + ...(errorDetailer?.workspaceId && { workspaceId: errorDetailer.workspaceId }), + ...(errorDetailer?.destType && { destType: errorDetailer.destType }), + ...(errorDetailer?.module && { module: errorDetailer.module }), + ...(errorDetailer?.implementation && { implementation: errorDetailer.implementation }), + ...(errorDetailer?.feature && { feature: errorDetailer.feature }), + }; + } + + public static logError(message: string, errorDetailer: ErrorDetailer) { + const loggableExtraData: Partial = this.getLoggableData(errorDetailer); + logger.errorw(message || '', loggableExtraData); + } } diff --git a/src/services/source/__tests__/nativeIntegration.test.ts b/src/services/source/__tests__/nativeIntegration.test.ts index bb40438811..77e355fd1a 100644 --- a/src/services/source/__tests__/nativeIntegration.test.ts +++ b/src/services/source/__tests__/nativeIntegration.test.ts @@ -1,8 +1,9 @@ +import { structuredLogger as logger } from '@rudderstack/integrations-lib'; +import { FetchHandler } from '../../../helpers/fetchHandlers'; +import { RudderMessage, SourceTransformationResponse } from '../../../types/index'; +import stats from '../../../util/stats'; import { NativeIntegrationSourceService } from '../nativeIntegration'; import { SourcePostTransformationService } from '../postTransformation'; -import { SourceTransformationResponse, RudderMessage } from '../../../types/index'; -import stats from '../../../util/stats'; -import { FetchHandler } from '../../../helpers/fetchHandlers'; afterEach(() => { jest.clearAllMocks(); @@ -43,7 +44,13 @@ describe('NativeIntegration Source Service', () => { }); const service = new NativeIntegrationSourceService(); - const resp = await service.sourceTransformRoutine(events, sourceType, version, requestMetadata); + const resp = await service.sourceTransformRoutine( + events, + sourceType, + version, + requestMetadata, + logger, + ); expect(resp).toEqual(tresponse); @@ -80,7 +87,13 @@ describe('NativeIntegration Source Service', () => { jest.spyOn(stats, 'increment').mockImplementation(() => {}); const service = new NativeIntegrationSourceService(); - const resp = await service.sourceTransformRoutine(events, sourceType, version, requestMetadata); + const resp = await service.sourceTransformRoutine( + events, + sourceType, + version, + requestMetadata, + logger, + ); expect(resp).toEqual(tresponse); diff --git a/src/services/source/nativeIntegration.ts b/src/services/source/nativeIntegration.ts index 6eaef2f835..2ecfc30066 100644 --- a/src/services/source/nativeIntegration.ts +++ b/src/services/source/nativeIntegration.ts @@ -1,3 +1,4 @@ +import { FetchHandler } from '../../helpers/fetchHandlers'; import { SourceService } from '../../interfaces/SourceService'; import { ErrorDetailer, @@ -5,11 +6,11 @@ import { RudderMessage, SourceTransformationResponse, } from '../../types/index'; +import stats from '../../util/stats'; import { FixMe } from '../../util/types'; -import { SourcePostTransformationService } from './postTransformation'; -import { FetchHandler } from '../../helpers/fetchHandlers'; import tags from '../../v0/util/tags'; -import stats from '../../util/stats'; +import { MiscService } from '../misc'; +import { SourcePostTransformationService } from './postTransformation'; export class NativeIntegrationSourceService implements SourceService { public getTags(): MetaTransferObject { @@ -31,20 +32,23 @@ export class NativeIntegrationSourceService implements SourceService { version: string, // eslint-disable-next-line @typescript-eslint/no-unused-vars _requestMetadata: NonNullable, + logger: FixMe, ): Promise { const sourceHandler = FetchHandler.getSourceHandler(sourceType, version); + const metaTO = this.getTags(); + const loggerWithCtx = logger.child({ ...MiscService.getLoggableData(metaTO.errorDetails) }); const respList: SourceTransformationResponse[] = await Promise.all( sourceEvents.map(async (sourceEvent) => { try { const respEvents: RudderMessage | RudderMessage[] | SourceTransformationResponse = - await sourceHandler.process(sourceEvent); + await sourceHandler.process(sourceEvent, loggerWithCtx); return SourcePostTransformationService.handleSuccessEventsSource(respEvents); } catch (error: FixMe) { - const metaTO = this.getTags(); stats.increment('source_transform_errors', { source: sourceType, version, }); + logger.debug('Error during source Transform', error); return SourcePostTransformationService.handleFailureEventsSource(error, metaTO); } }), diff --git a/src/util/redis/redisConnector.test.js b/src/util/redis/redisConnector.test.js index e0491132ff..7cf2ccbbcf 100644 --- a/src/util/redis/redisConnector.test.js +++ b/src/util/redis/redisConnector.test.js @@ -2,6 +2,7 @@ const fs = require('fs'); const path = require('path'); const version = 'v0'; const { RedisDB } = require('./redisConnector'); +const { structuredLogger: logger } = require('@rudderstack/integrations-lib'); jest.mock('ioredis', () => require('../../../test/__mocks__/redis')); const sourcesList = ['shopify']; process.env.USE_REDIS_DB = 'true'; @@ -54,7 +55,7 @@ describe(`Source Tests`, () => { data.forEach((dataPoint, index) => { it(`${index}. ${source} - ${dataPoint.description}`, async () => { try { - const output = await transformer.process(dataPoint.input); + const output = await transformer.process(dataPoint.input, logger); expect(output).toEqual(dataPoint.output); } catch (error) { expect(error.message).toEqual(dataPoint.output.error); diff --git a/src/v0/destinations/campaign_manager/transform.js b/src/v0/destinations/campaign_manager/transform.js index 14bc6d2c19..403a79a971 100644 --- a/src/v0/destinations/campaign_manager/transform.js +++ b/src/v0/destinations/campaign_manager/transform.js @@ -243,7 +243,8 @@ const batchEvents = (eventChunksArray) => { return batchedResponseList; }; -const processRouterDest = async (inputs, reqMetadata) => { +const processRouterDest = async (inputs, reqMetadata, logger) => { + logger.debug(`Transformation router request received with size ${inputs.length}`); const batchErrorRespList = []; const eventChunksArray = []; const { destination } = inputs[0]; diff --git a/src/v0/destinations/mailchimp/utils.js b/src/v0/destinations/mailchimp/utils.js index 1f4fc03ee5..a726f23a39 100644 --- a/src/v0/destinations/mailchimp/utils.js +++ b/src/v0/destinations/mailchimp/utils.js @@ -1,9 +1,12 @@ const get = require('get-value'); const md5 = require('md5'); -const { InstrumentationError, NetworkError } = require('@rudderstack/integrations-lib'); +const { + InstrumentationError, + NetworkError, + structuredLogger: logger, +} = require('@rudderstack/integrations-lib'); const myAxios = require('../../../util/myAxios'); const { MappedToDestinationKey } = require('../../../constants'); -const logger = require('../../../logger'); const { isDefinedAndNotNull, isDefined, diff --git a/src/v0/destinations/twitter_ads/transform.js b/src/v0/destinations/twitter_ads/transform.js index 268dca3636..365663925e 100644 --- a/src/v0/destinations/twitter_ads/transform.js +++ b/src/v0/destinations/twitter_ads/transform.js @@ -156,7 +156,8 @@ function validateRequest(message) { } } -function process(event) { +function process(event, requestMetadata, logger) { + logger.info(`[TWITTER ADS]: Transforming request received with info`); const { message, metadata, destination } = event; validateRequest(message); diff --git a/src/v0/sources/canny/transform.js b/src/v0/sources/canny/transform.js index 9188f5ac34..38ed5e137e 100644 --- a/src/v0/sources/canny/transform.js +++ b/src/v0/sources/canny/transform.js @@ -2,7 +2,6 @@ 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 CannyOperation = { VOTE_CREATED: 'vote.created', @@ -15,7 +14,7 @@ const CannyOperation = { * @param {*} event * @param {*} typeOfUser */ -function settingIds(message, event, typeOfUser) { +function settingIds(message, event, typeOfUser, logger) { const clonedMessage = { ...message }; try { // setting up userId @@ -48,7 +47,7 @@ function settingIds(message, event, typeOfUser) { * @param {*} typeOfUser * @returns message */ -function createMessage(event, typeOfUser) { +function createMessage(event, typeOfUser, logger) { const message = new Message(`Canny`); message.setEventType('track'); @@ -61,7 +60,7 @@ function createMessage(event, typeOfUser) { message.context.integration.version = '1.0.0'; - const finalMessage = settingIds(message, event, typeOfUser); + const finalMessage = settingIds(message, event, typeOfUser, logger); checkForRequiredFields(finalMessage); @@ -73,7 +72,7 @@ function createMessage(event, typeOfUser) { return finalMessage; } -function process(event) { +function process(event, logger) { let typeOfUser; switch (event.type) { @@ -86,6 +85,6 @@ function process(event) { typeOfUser = 'author'; } - return createMessage(event, typeOfUser); + return createMessage(event, typeOfUser, logger); } module.exports = { process }; diff --git a/src/v0/sources/shopify/transform.js b/src/v0/sources/shopify/transform.js index b6d2a4c6cf..4886fb3df1 100644 --- a/src/v0/sources/shopify/transform.js +++ b/src/v0/sources/shopify/transform.js @@ -16,7 +16,6 @@ const { const { RedisDB } = require('../../../util/redis/redisConnector'); const { removeUndefinedAndNullValues, isDefinedAndNotNull } = require('../../util'); const Message = require('../message'); -const logger = require('../../../logger'); const { EventType } = require('../../../constants'); const { INTEGERATION, @@ -206,7 +205,7 @@ const processEvent = async (inputEvent, metricMetadata) => { }; const isIdentifierEvent = (event) => ['rudderIdentifier', 'rudderSessionIdentifier'].includes(event?.event); -const processIdentifierEvent = async (event, metricMetadata) => { +const processIdentifierEvent = async (event, metricMetadata, logger) => { if (useRedisDatabase) { let value; let field; @@ -256,13 +255,13 @@ const processIdentifierEvent = async (event, metricMetadata) => { } return NO_OPERATION_SUCCESS; }; -const process = async (event) => { +const process = async (event, logger) => { const metricMetadata = { writeKey: event.query_parameters?.writeKey?.[0], source: 'SHOPIFY', }; if (isIdentifierEvent(event)) { - return processIdentifierEvent(event, metricMetadata); + return processIdentifierEvent(event, metricMetadata, logger); } const response = await processEvent(event, metricMetadata); return response; diff --git a/src/v0/sources/shopify/util.js b/src/v0/sources/shopify/util.js index c4bbb61b9c..3dc54cc434 100644 --- a/src/v0/sources/shopify/util.js +++ b/src/v0/sources/shopify/util.js @@ -2,7 +2,7 @@ /* eslint-disable @typescript-eslint/naming-convention */ const { v5 } = require('uuid'); const sha256 = require('sha256'); -const { TransformationError } = require('@rudderstack/integrations-lib'); +const { TransformationError, structuredLogger: logger } = require('@rudderstack/integrations-lib'); const stats = require('../../../util/stats'); const { constructPayload, @@ -12,7 +12,6 @@ const { isDefinedAndNotNull, } = require('../../util'); const { RedisDB } = require('../../../util/redis/redisConnector'); -const logger = require('../../../logger'); const { lineItemsMappingJSON, productMappingJSON, diff --git a/test/__tests__/pinterestConversion-cdk.test.ts b/test/__tests__/pinterestConversion-cdk.test.ts index f4da92eea9..6aaa710ed7 100644 --- a/test/__tests__/pinterestConversion-cdk.test.ts +++ b/test/__tests__/pinterestConversion-cdk.test.ts @@ -1,6 +1,7 @@ +import { structuredLogger as logger } from '@rudderstack/integrations-lib'; import fs from 'fs'; import path from 'path'; -import { processCdkV2Workflow, getWorkflowEngine, executeWorkflow } from '../../src/cdk/v2/handler'; +import { executeWorkflow, getWorkflowEngine, processCdkV2Workflow } from '../../src/cdk/v2/handler'; import tags from '../../src/v0/util/tags'; const integration = 'pinterest_tag'; @@ -22,7 +23,12 @@ describe(`${name} Tests`, () => { it(`${name} - payload: ${index}`, async () => { const expected = expectedData[index]; try { - const output = await processCdkV2Workflow(integration, input, tags.FEATURES.PROCESSOR); + const output = await processCdkV2Workflow( + integration, + input, + tags.FEATURES.PROCESSOR, + logger, + ); expect(output).toEqual(expected); } catch (error: any) { expect(error.message).toEqual(expected.error); @@ -46,7 +52,12 @@ describe(`${name} Tests`, () => { it(`${name} - payload: ${index}`, async () => { const expected = expectedData[index]; try { - const output = await processCdkV2Workflow(integration, input, tags.FEATURES.PROCESSOR); + const output = await processCdkV2Workflow( + integration, + input, + tags.FEATURES.PROCESSOR, + logger, + ); expect(output).toEqual(expected); } catch (error: any) { expect(error.message).toEqual(expected.error); @@ -91,6 +102,7 @@ describe(`${name} Tests`, () => { integration, inputRouterErrorData, tags.FEATURES.ROUTER, + logger, ); expect(output).toEqual(expectedRouterErrorData); }); @@ -98,7 +110,12 @@ describe(`${name} Tests`, () => { describe('Default Batch size', () => { inputRouterData.forEach((input, index) => { it(`Payload: ${index}`, async () => { - const output = await processCdkV2Workflow(integration, input, tags.FEATURES.ROUTER); + const output = await processCdkV2Workflow( + integration, + input, + tags.FEATURES.ROUTER, + logger, + ); expect(output).toEqual(expectedRouterData[index]); }); }); diff --git a/test/apitests/service.api.test.ts b/test/apitests/service.api.test.ts index 266619b6ac..e46357f824 100644 --- a/test/apitests/service.api.test.ts +++ b/test/apitests/service.api.test.ts @@ -1,13 +1,13 @@ import fs from 'fs'; -import path from 'path'; -import request from 'supertest'; import { createHttpTerminator } from 'http-terminator'; import Koa from 'koa'; import bodyParser from 'koa-bodyparser'; +import path from 'path'; import setValue from 'set-value'; -import { applicationRoutes } from '../../src/routes'; -import { FetchHandler } from '../../src/helpers/fetchHandlers'; +import request from 'supertest'; import networkHandlerFactory from '../../src/adapters/networkHandlerFactory'; +import { FetchHandler } from '../../src/helpers/fetchHandlers'; +import { applicationRoutes } from '../../src/routes'; let server: any; const OLD_ENV = process.env; From 007009f7a6da2576f340ce965a4d6f190def7760 Mon Sep 17 00:00:00 2001 From: Siva Shanmukh Vetcha Date: Tue, 9 Apr 2024 10:20:22 -0400 Subject: [PATCH 26/47] chore: add logs on dns errors (#3257) --- src/util/utils.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/util/utils.js b/src/util/utils.js index 0ba6008368..d74603dd7a 100644 --- a/src/util/utils.js +++ b/src/util/utils.js @@ -22,6 +22,7 @@ const staticLookup = (transformerVersionId) => async (hostname, _, cb) => { try { ips = await resolver.resolve4(hostname); } catch (error) { + logger.error(`DNS Error Code: ${error.code} | Message : ${error.message}`); stats.timing('fetch_dns_resolve_time', resolveStartTime, { transformerVersionId, error: 'true', From 3399c47fdce1b3d19e29306ca3c5692a2fbc30fb Mon Sep 17 00:00:00 2001 From: shrouti1507 <60211312+shrouti1507@users.noreply.github.com> Date: Fri, 12 Apr 2024 12:58:54 +0530 Subject: [PATCH 27/47] fix: adding check for reserved key words in extract custom fields (#3264) * fix: adding check for reserved key words * fix: review comments addressed --- src/v0/util/index.js | 13 ++- src/v0/util/index.test.js | 184 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 195 insertions(+), 2 deletions(-) diff --git a/src/v0/util/index.js b/src/v0/util/index.js index 32872cc5d9..ac1bacf404 100644 --- a/src/v0/util/index.js +++ b/src/v0/util/index.js @@ -1328,12 +1328,19 @@ const generateExclusionList = (mappingConfig) => */ function extractCustomFields(message, payload, keys, exclusionFields) { const mappingKeys = []; + // Define reserved words + const reservedWords = ['__proto__', 'constructor', 'prototype']; + + const isReservedWord = (key) => reservedWords.includes(key); + if (Array.isArray(keys)) { keys.forEach((key) => { const messageContext = get(message, key); if (messageContext) { Object.keys(messageContext).forEach((k) => { - if (!exclusionFields.includes(k)) mappingKeys.push(k); + if (!exclusionFields.includes(k) && !isReservedWord(k)) { + mappingKeys.push(k); + } }); mappingKeys.forEach((mappingKey) => { if (!(typeof messageContext[mappingKey] === 'undefined')) { @@ -1344,7 +1351,9 @@ function extractCustomFields(message, payload, keys, exclusionFields) { }); } else if (keys === 'root') { Object.keys(message).forEach((k) => { - if (!exclusionFields.includes(k)) mappingKeys.push(k); + if (!exclusionFields.includes(k) && !isReservedWord(k)) { + mappingKeys.push(k); + } }); mappingKeys.forEach((mappingKey) => { if (!(typeof message[mappingKey] === 'undefined')) { diff --git a/src/v0/util/index.test.js b/src/v0/util/index.test.js index 810eb5a9d4..c34d513325 100644 --- a/src/v0/util/index.test.js +++ b/src/v0/util/index.test.js @@ -506,3 +506,187 @@ describe('validateEventAndLowerCaseConversion Tests', () => { }).toThrow(InstrumentationError); }); }); + +describe('extractCustomFields', () => { + // Handle reserved words in message keys + it('should handle reserved word "prototype" in message keys when keys are provided', () => { + const message = { + traits: { + firstName: 'John', + lastName: 'Doe', + email: 'john.doe@example.com', + prototype: 'reserved', + }, + context: { + traits: { + phone: '1234567890', + city: 'New York', + country: 'USA', + prototype: 'reserved', + }, + }, + properties: { + title: 'Developer', + organization: 'ABC Company', + zip: '12345', + prototype: 'reserved', + }, + }; + + const payload = {}; + + const keys = ['properties', 'context.traits', 'traits']; + + const exclusionFields = [ + 'firstName', + 'lastName', + 'phone', + 'title', + 'organization', + 'city', + 'region', + 'country', + 'zip', + 'image', + 'timezone', + ]; + + const result = utilities.extractCustomFields(message, payload, keys, exclusionFields); + + expect(result).toEqual({ + email: 'john.doe@example.com', + }); + }); + + it('should handle reserved word "__proto__" in message keys when keys are provided', () => { + const message = { + traits: { + firstName: 'John', + lastName: 'Doe', + email: 'john.doe@example.com', + __proto__: 'reserved', + }, + context: { + traits: { + phone: '1234567890', + city: 'New York', + country: 'USA', + __proto__: 'reserved', + }, + }, + properties: { + title: 'Developer', + organization: 'ABC Company', + zip: '12345', + __proto__: 'reserved', + }, + }; + + const payload = {}; + + const keys = ['properties', 'context.traits', 'traits']; + + const exclusionFields = [ + 'firstName', + 'lastName', + 'phone', + 'title', + 'organization', + 'city', + 'region', + 'country', + 'zip', + 'image', + 'timezone', + ]; + const result = utilities.extractCustomFields(message, payload, keys, exclusionFields); + expect(result).toEqual({ + email: 'john.doe@example.com', + }); + }); + + it('should handle reserved word "constructor" in message keys when keys are provided', () => { + const message = { + traits: { + firstName: 'John', + lastName: 'Doe', + email: 'john.doe@example.com', + constructor: 'reserved', + }, + context: { + traits: { + phone: '1234567890', + city: 'New York', + country: 'USA', + constructor: 'reserved', + }, + }, + properties: { + title: 'Developer', + organization: 'ABC Company', + zip: '12345', + constructor: 'reserved', + }, + }; + + const payload = {}; + + const keys = ['properties', 'context.traits', 'traits']; + + const exclusionFields = [ + 'firstName', + 'lastName', + 'phone', + 'title', + 'organization', + 'city', + 'region', + 'country', + 'zip', + 'image', + 'timezone', + ]; + const result = utilities.extractCustomFields(message, payload, keys, exclusionFields); + expect(result).toEqual({ + email: 'john.doe@example.com', + }); + }); + + it('should handle reserved words in message keys when key is root', () => { + const message = { + firstName: 'John', + lastName: 'Doe', + email: 'john.doe@example.com', + prototype: 'reserved', + phone: '1234567890', + city: 'New York', + country: 'USA', + __proto__: 'reserved', + constructor: 'reserved', + }; + + const payload = {}; + + const keys = 'root'; + + const exclusionFields = [ + 'firstName', + 'lastName', + 'phone', + 'title', + 'organization', + 'city', + 'region', + 'country', + 'zip', + 'image', + 'timezone', + ]; + + const result = utilities.extractCustomFields(message, payload, keys, exclusionFields); + + expect(result).toEqual({ + email: 'john.doe@example.com', + }); + }); +}); From 3721a4475a7caa89635839b2234e0574ffeea69b Mon Sep 17 00:00:00 2001 From: Abhimanyu Babbar Date: Sat, 13 Apr 2024 00:59:38 +0530 Subject: [PATCH 28/47] chore: setup transformer code with openfaas pro deployment changes (#3180) --- src/util/openfaas/faasApi.js | 36 +++++++++++++++------- src/util/openfaas/index.js | 12 +++++++- test/__tests__/user_transformation.test.js | 22 +++++++++---- 3 files changed, 52 insertions(+), 18 deletions(-) diff --git a/src/util/openfaas/faasApi.js b/src/util/openfaas/faasApi.js index 4db5e2a81c..f8f830f6e4 100644 --- a/src/util/openfaas/faasApi.js +++ b/src/util/openfaas/faasApi.js @@ -2,6 +2,13 @@ const axios = require('axios'); const { RespStatusError, RetryRequestError } = require('../utils'); const OPENFAAS_GATEWAY_URL = process.env.OPENFAAS_GATEWAY_URL || 'http://localhost:8080'; +const OPENFAAS_GATEWAY_USERNAME = process.env.OPENFAAS_GATEWAY_USERNAME || ''; +const OPENFAAS_GATEWAY_PASSWORD = process.env.OPENFAAS_GATEWAY_PASSWORD || ''; + +const basicAuth = { + username: OPENFAAS_GATEWAY_USERNAME, + password: OPENFAAS_GATEWAY_PASSWORD, +}; const parseAxiosError = (error) => { if (error.response) { @@ -21,7 +28,7 @@ const deleteFunction = async (functionName) => new Promise((resolve, reject) => { const url = `${OPENFAAS_GATEWAY_URL}/system/functions`; axios - .delete(url, { data: { functionName } }) + .delete(url, { data: { functionName }, auth: basicAuth }) .then(() => resolve()) .catch((err) => reject(parseAxiosError(err))); }); @@ -30,7 +37,7 @@ const getFunction = async (functionName) => new Promise((resolve, reject) => { const url = `${OPENFAAS_GATEWAY_URL}/system/function/${functionName}`; axios - .get(url) + .get(url, { auth: basicAuth }) .then((resp) => resolve(resp.data)) .catch((err) => reject(parseAxiosError(err))); }); @@ -39,7 +46,7 @@ const getFunctionList = async () => new Promise((resolve, reject) => { const url = `${OPENFAAS_GATEWAY_URL}/system/functions`; axios - .get(url) + .get(url, { auth: basicAuth }) .then((resp) => resolve(resp.data)) .catch((err) => reject(parseAxiosError(err))); }); @@ -48,29 +55,36 @@ const invokeFunction = async (functionName, payload) => new Promise((resolve, reject) => { const url = `${OPENFAAS_GATEWAY_URL}/function/${functionName}`; axios - .post(url, payload) + .post(url, payload, { auth: basicAuth }) .then((resp) => resolve(resp.data)) .catch((err) => reject(parseAxiosError(err))); }); -const checkFunctionHealth = async (functionName) => - new Promise((resolve, reject) => { +const checkFunctionHealth = async (functionName) => { + return new Promise((resolve, reject) => { const url = `${OPENFAAS_GATEWAY_URL}/function/${functionName}`; axios - .get(url, { - headers: { 'X-REQUEST-TYPE': 'HEALTH-CHECK' }, - }) + .get( + url, + { + headers: { 'X-REQUEST-TYPE': 'HEALTH-CHECK' }, + }, + { auth: basicAuth }, + ) .then((resp) => resolve(resp)) .catch((err) => reject(parseAxiosError(err))); }); +}; const deployFunction = async (payload) => new Promise((resolve, reject) => { const url = `${OPENFAAS_GATEWAY_URL}/system/functions`; axios - .post(url, payload) + .post(url, payload, { auth: basicAuth }) .then((resp) => resolve(resp.data)) - .catch((err) => reject(parseAxiosError(err))); + .catch((err) => { + reject(parseAxiosError(err)); + }); }); module.exports = { diff --git a/src/util/openfaas/index.js b/src/util/openfaas/index.js index 00b3720e13..7a1fce3cfa 100644 --- a/src/util/openfaas/index.js +++ b/src/util/openfaas/index.js @@ -11,6 +11,11 @@ const stats = require('../stats'); const { getMetadata, getTransformationMetadata } = require('../../v0/util'); const { HTTP_STATUS_CODES } = require('../../v0/util/constant'); +const FAAS_SCALE_TYPE = process.env.FAAS_SCALE_TYPE || 'capacity'; +const FAAS_SCALE_TARGET = process.env.FAAS_SCALE_TARGET || '4'; +const FAAS_SCALE_TARGET_PROPORTION = process.env.FAAS_SCALE_TARGET_PROPORTION || '0.70'; +const FAAS_SCALE_ZERO = process.env.FAAS_SCALE_ZERO || 'false'; +const FAAS_SCALE_ZERO_DURATION = process.env.FAAS_SCALE_ZERO_DURATION || '15m'; 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'; const FAAS_MIN_PODS_IN_TEXT = process.env.FAAS_MIN_PODS_IN_TEXT || '1'; @@ -125,7 +130,7 @@ const deployFaasFunction = async ( trMetadata = {}, ) => { try { - logger.debug('[Faas] Deploying a faas function'); + logger.debug(`[Faas] Deploying a faas function: ${functionName}`); let envProcess = 'python index.py'; const lvidsString = libraryVersionIDs.join(','); @@ -150,6 +155,11 @@ const deployFaasFunction = async ( 'parent-component': 'openfaas', 'com.openfaas.scale.max': FAAS_MAX_PODS_IN_TEXT, 'com.openfaas.scale.min': FAAS_MIN_PODS_IN_TEXT, + 'com.openfaas.scale.zero': FAAS_SCALE_ZERO, + 'com.openfaas.scale.zero-duration': FAAS_SCALE_ZERO_DURATION, + 'com.openfaas.scale.target': FAAS_SCALE_TARGET, + 'com.openfaas.scale.target-proportion': FAAS_SCALE_TARGET_PROPORTION, + 'com.openfaas.scale.type': FAAS_SCALE_TYPE, transformationId: trMetadata.transformationId, workspaceId: trMetadata.workspaceId, team: 'data-management', diff --git a/test/__tests__/user_transformation.test.js b/test/__tests__/user_transformation.test.js index 8b781cda9a..924bf4f791 100644 --- a/test/__tests__/user_transformation.test.js +++ b/test/__tests__/user_transformation.test.js @@ -37,6 +37,10 @@ const { parserForImport } = require("../../src/util/parser"); const { RetryRequestError, RespStatusError } = require("../../src/util/utils"); const OPENFAAS_GATEWAY_URL = "http://localhost:8080"; +const defaultBasicAuth = { + "username": "", + "password": "" +}; const randomID = () => Math.random() @@ -1400,12 +1404,14 @@ describe("Python transformations", () => { expect(axios.post).toHaveBeenCalledTimes(1); expect(axios.post).toHaveBeenCalledWith( `${OPENFAAS_GATEWAY_URL}/system/functions`, - expect.objectContaining({ name: funcName, service: funcName }) + expect.objectContaining({ name: funcName, service: funcName }), + { auth: defaultBasicAuth }, ); expect(axios.get).toHaveBeenCalledTimes(1); expect(axios.get).toHaveBeenCalledWith( `${OPENFAAS_GATEWAY_URL}/function/${funcName}`, - {"headers": {"X-REQUEST-TYPE": "HEALTH-CHECK"}} + {"headers": {"X-REQUEST-TYPE": "HEALTH-CHECK"}}, + { auth: defaultBasicAuth }, ); }); @@ -1622,7 +1628,8 @@ describe("Python transformations", () => { expect(axios.post).toHaveBeenCalledTimes(1); expect(axios.post).toHaveBeenCalledWith( `${OPENFAAS_GATEWAY_URL}/function/${funcName}`, - inputData + inputData, + { auth: defaultBasicAuth }, ); }); @@ -1655,17 +1662,20 @@ describe("Python transformations", () => { expect(axios.post).toHaveBeenCalledTimes(2); expect(axios.post).toHaveBeenCalledWith( `${OPENFAAS_GATEWAY_URL}/function/${funcName}`, - inputData + inputData, + { auth: defaultBasicAuth }, ); expect(axios.post).toHaveBeenCalledWith( `${OPENFAAS_GATEWAY_URL}/system/functions`, - expect.objectContaining({ name: funcName, service: funcName }) + expect.objectContaining({ name: funcName, service: funcName }), + { auth: defaultBasicAuth }, ); expect(axios.get).toHaveBeenCalledTimes(1); expect(axios.get).toHaveBeenCalledWith( `${OPENFAAS_GATEWAY_URL}/function/${funcName}`, - {"headers": {"X-REQUEST-TYPE": "HEALTH-CHECK"}} + {"headers": {"X-REQUEST-TYPE": "HEALTH-CHECK"}}, + { auth: defaultBasicAuth }, ); }); From cb8ff2fb943c49df4ac083bd179d9674b40eb602 Mon Sep 17 00:00:00 2001 From: Anant Jain <62471433+anantjain45823@users.noreply.github.com> Date: Mon, 15 Apr 2024 11:11:44 +0530 Subject: [PATCH 29/47] fix: impact: support custom product mapping (#3249) * fix: impact: support custom product mapping * chore: add util test file * chore: address comments --- src/v0/destinations/impact/util.js | 9 ++ src/v0/destinations/impact/utils.test.js | 134 ++++++++++++++++++ .../destinations/impact/processor/data.ts | 6 + 3 files changed, 149 insertions(+) create mode 100644 src/v0/destinations/impact/utils.test.js diff --git a/src/v0/destinations/impact/util.js b/src/v0/destinations/impact/util.js index b8c6e92e76..8fb43a8df6 100644 --- a/src/v0/destinations/impact/util.js +++ b/src/v0/destinations/impact/util.js @@ -78,6 +78,7 @@ const populateProductProperties = (productsMapping, properties) => { const productProperties = {}; if (products && Array.isArray(products)) { products.forEach((item, index) => { + // Following product properties have a default mapping as well in config.js as itemMapping productProperties[getPropertyName('ItemBrand', index + 1)] = item[getProductsMapping(productsMapping, 'ItemBrand')]; productProperties[getPropertyName('ItemCategory', index + 1)] = @@ -92,8 +93,16 @@ const populateProductProperties = (productsMapping, properties) => { item[getProductsMapping(productsMapping, 'ItemQuantity')]; productProperties[getPropertyName('ItemSku', index + 1)] = item[getProductsMapping(productsMapping, 'ItemSku')]; + + // Following product properties are build from configuration in RudderStack dashboard + if (productsMapping && Array.isArray(productsMapping)) { + productsMapping.forEach((mapping) => { + productProperties[getPropertyName(mapping.to, index + 1)] = item[mapping.from]; + }); + } }); } else { + // Not providing product level mapping here as following are fetched from properties level const index = 1; productProperties[getPropertyName('ItemBrand', index)] = brand; productProperties[getPropertyName('ItemCategory', index)] = category; diff --git a/src/v0/destinations/impact/utils.test.js b/src/v0/destinations/impact/utils.test.js new file mode 100644 index 0000000000..17f90bbc5d --- /dev/null +++ b/src/v0/destinations/impact/utils.test.js @@ -0,0 +1,134 @@ +const { populateProductProperties } = require('./util'); +// Generated by CodiumAI + +describe('populateProductProperties', () => { + // Given a valid productsMapping and properties, it should return product properties with default mappings and configured mappings from RudderStack dashboard + it('should return product properties with default and configured mappings', () => { + // Arrange + const productsMapping = [ + { to: 'ItemBrand', from: 'Brand' }, + { to: 'ItemCategory', from: 'Category' }, + { to: 'ItemName', from: 'Name' }, + { to: 'ItemPrice', from: 'Price' }, + { to: 'ItemPromoCode', from: 'PromoCode' }, + { to: 'ItemQuantity', from: 'Quantity' }, + { to: 'ItemSku', from: 'Sku' }, + { to: 'dummyRHS', from: 'dummyLHS' }, + ]; + const properties = { + products: [ + { + Brand: 'Brand1', + Category: 'Category1', + Name: 'Name1', + Price: 10, + PromoCode: 'PromoCode1', + Quantity: 1, + Sku: 'Sku1', + dummyLHS: 'DummyValue', + }, + { + Brand: 'Brand2', + Category: 'Category2', + Name: 'Name2', + Price: 20, + PromoCode: 'PromoCode2', + Quantity: 2, + }, + ], + brand: 'Brand3', + category: 'Category3', + name: 'Name3', + price: 30, + coupon: 'PromoCode3', + quantity: 3, + sku: 'Sku3', + }; + + // Act + const result = populateProductProperties(productsMapping, properties); + + // Assert + expect(result).toEqual({ + ItemBrand1: 'Brand1', + ItemCategory1: 'Category1', + ItemName1: 'Name1', + ItemPrice1: 10, + ItemPromoCode1: 'PromoCode1', + ItemQuantity1: 1, + ItemSku1: 'Sku1', + ItemBrand2: 'Brand2', + ItemCategory2: 'Category2', + ItemName2: 'Name2', + ItemPrice2: 20, + ItemPromoCode2: 'PromoCode2', + ItemQuantity2: 2, + dummyRHS1: 'DummyValue', + }); + }); + + // Given an empty productsMapping and valid properties, it should return product properties with default mappings from properties + it('should return product properties with default mappings from properties when products array is not available', () => { + // Arrange + const productsMapping = []; + const properties = { + brand: 'Brand3', + category: 'Category3', + name: 'Name3', + price: 30, + coupon: 'PromoCode3', + quantity: 3, + sku: 'Sku3', + }; + + // Act + const result = populateProductProperties(productsMapping, properties); + + // Assert + expect(result).toEqual({ + ItemBrand1: 'Brand3', + ItemCategory1: 'Category3', + ItemName1: 'Name3', + ItemPrice1: 30, + ItemPromoCode1: 'PromoCode3', + ItemQuantity1: 3, + ItemSku1: 'Sku3', + }); + }); + it('should return product properties with custom mappings', () => { + const productsMapping = [ + { + from: 'dummy_LHS', + to: 'dummy_RHS', + }, + ]; + const properties = { + products: [ + { + brand: 'Brand3', + category: 'Category3', + name: 'Name3', + price: 30, + coupon: 'PromoCode3', + quantity: 3, + sku: 'Sku3', + dummy_LHS: 'DummyValue', + }, + ], + }; + + const result = populateProductProperties(productsMapping, properties); + + // Assert + expect(result).toEqual({ + ItemBrand1: 'Brand3', + ItemCategory1: 'Category3', + ItemName1: 'Name3', + ItemPrice1: 30, + ItemPromoCode1: 'PromoCode3', + ItemQuantity1: 3, + ItemSku1: 'Sku3', + dummy_RHS1: 'DummyValue', + }); + }); +}); diff --git a/test/integrations/destinations/impact/processor/data.ts b/test/integrations/destinations/impact/processor/data.ts index e467956d62..1e4e91e7ad 100644 --- a/test/integrations/destinations/impact/processor/data.ts +++ b/test/integrations/destinations/impact/processor/data.ts @@ -891,6 +891,7 @@ export const data = [ price: 332, quantity: 1, sku: 'G-32', + customRSProductField: 'customRSVal', }, ], }, @@ -941,6 +942,10 @@ export const data = [ from: 'variant', to: 'ItemCategory', }, + { + from: 'customRSProductField', + to: 'customImpactProductField', + }, ], enableIdentifyEvents: false, enablePageEvents: false, @@ -990,6 +995,7 @@ export const data = [ DeviceLocale: 'en-US', EventTypeCode: 'Order Completed', ItemQuantity1: 1, + customImpactProductField1: 'customRSVal', OrderPromoCode: '10OFF-ROCKET', CustomProfileId: '97c46c81-3140-456d-b2a9-690d70aaca35', }, From 1bfcd27a21ad224880f59001efbac728e356afe1 Mon Sep 17 00:00:00 2001 From: Gauravudia <60897972+Gauravudia@users.noreply.github.com> Date: Mon, 15 Apr 2024 12:02:07 +0530 Subject: [PATCH 30/47] refactor: deprecate mixpanel /track endpoint (#2833) * refactor: deprecate mixpanel /track endpoint * fix: used token in place of apiSecret for merge call * fix: no-case-declarations --- src/util/prometheus.js | 6 - src/v0/destinations/mp/config.js | 2 - src/v0/destinations/mp/transform.js | 69 ++-- src/v0/destinations/mp/util.js | 8 +- src/v0/destinations/mp/util.test.js | 14 - test/integrations/destinations/mp/common.ts | 2 +- .../destinations/mp/processor/data.ts | 360 ++++++++++-------- .../destinations/mp/router/data.ts | 12 +- 8 files changed, 243 insertions(+), 230 deletions(-) diff --git a/src/util/prometheus.js b/src/util/prometheus.js index 882dff9e75..a46eae12c9 100644 --- a/src/util/prometheus.js +++ b/src/util/prometheus.js @@ -587,12 +587,6 @@ class Prometheus { type: 'gauge', labelNames: ['destination_id'], }, - { - name: 'mixpanel_batch_track_pack_size', - help: 'mixpanel_batch_track_pack_size', - type: 'gauge', - labelNames: ['destination_id'], - }, { name: 'mixpanel_batch_import_pack_size', help: 'mixpanel_batch_import_pack_size', diff --git a/src/v0/destinations/mp/config.js b/src/v0/destinations/mp/config.js index 35b40294f5..3abdf2eebb 100644 --- a/src/v0/destinations/mp/config.js +++ b/src/v0/destinations/mp/config.js @@ -49,7 +49,6 @@ const MP_IDENTIFY_EXCLUSION_LIST = [ ]; const GEO_SOURCE_ALLOWED_VALUES = [null, 'reverse_geocoding']; -const TRACK_MAX_BATCH_SIZE = 50; const IMPORT_MAX_BATCH_SIZE = 2000; const ENGAGE_MAX_BATCH_SIZE = 2000; const GROUPS_MAX_BATCH_SIZE = 200; @@ -68,7 +67,6 @@ module.exports = { MP_IDENTIFY_EXCLUSION_LIST, getCreateDeletionTaskEndpoint, DISTINCT_ID_MAX_BATCH_SIZE, - TRACK_MAX_BATCH_SIZE, IMPORT_MAX_BATCH_SIZE, ENGAGE_MAX_BATCH_SIZE, GROUPS_MAX_BATCH_SIZE, diff --git a/src/v0/destinations/mp/transform.js b/src/v0/destinations/mp/transform.js index a2c40a5672..195c42fbee 100644 --- a/src/v0/destinations/mp/transform.js +++ b/src/v0/destinations/mp/transform.js @@ -25,7 +25,6 @@ const { BASE_ENDPOINT, BASE_ENDPOINT_EU, IMPORT_MAX_BATCH_SIZE, - TRACK_MAX_BATCH_SIZE, ENGAGE_MAX_BATCH_SIZE, GROUPS_MAX_BATCH_SIZE, } = require('./config'); @@ -47,21 +46,19 @@ const mPEventPropertiesConfigJson = mappingConfig[ConfigCategory.EVENT_PROPERTIE const setImportCredentials = (destConfig) => { const endpoint = destConfig.dataResidency === 'eu' ? `${BASE_ENDPOINT_EU}/import/` : `${BASE_ENDPOINT}/import/`; - const headers = { 'Content-Type': 'application/json' }; const params = { strict: destConfig.strictMode ? 1 : 0 }; - const { apiSecret, serviceAccountUserName, serviceAccountSecret, projectId } = destConfig; - if (apiSecret) { - headers.Authorization = `Basic ${base64Convertor(`${apiSecret}:`)}`; + const { serviceAccountUserName, serviceAccountSecret, projectId, token } = destConfig; + let credentials; + if (token) { + credentials = `${token}:`; } else if (serviceAccountUserName && serviceAccountSecret && projectId) { - headers.Authorization = `Basic ${base64Convertor( - `${serviceAccountUserName}:${serviceAccountSecret}`, - )}`; + credentials = `${serviceAccountUserName}:${serviceAccountSecret}`; params.projectId = projectId; - } else { - throw new InstrumentationError( - 'Event timestamp is older than 5 days and no API secret or service account credentials (i.e. username, secret and projectId) are provided in destination configuration', - ); } + const headers = { + 'Content-Type': 'application/json', + Authorization: `Basic ${base64Convertor(credentials)}`, + }; return { endpoint, headers, params }; }; @@ -70,37 +67,26 @@ const responseBuilderSimple = (payload, message, eventType, destConfig) => { response.method = defaultPostRequestConfig.requestMethod; response.userId = message.userId || message.anonymousId; response.body.JSON_ARRAY = { batch: JSON.stringify([removeUndefinedValues(payload)]) }; - const { apiSecret, serviceAccountUserName, serviceAccountSecret, projectId, dataResidency } = - destConfig; + const { dataResidency } = destConfig; const duration = getTimeDifference(message.timestamp); switch (eventType) { case EventType.ALIAS: case EventType.TRACK: case EventType.SCREEN: - case EventType.PAGE: - if ( - !apiSecret && - !(serviceAccountUserName && serviceAccountSecret && projectId) && - duration.days <= 5 - ) { - response.endpoint = - dataResidency === 'eu' ? `${BASE_ENDPOINT_EU}/track/` : `${BASE_ENDPOINT}/track/`; - response.headers = {}; - } else if (duration.years > 5) { + case EventType.PAGE: { + if (duration.years > 5) { throw new InstrumentationError('Event timestamp should be within last 5 years'); - } else { - const credentials = setImportCredentials(destConfig); - response.endpoint = credentials.endpoint; - response.headers = credentials.headers; - response.params = { - project_id: credentials.params?.projectId, - strict: credentials.params.strict, - }; - break; } + const credentials = setImportCredentials(destConfig); + response.endpoint = credentials.endpoint; + response.headers = credentials.headers; + response.params = { + project_id: credentials.params?.projectId, + strict: credentials.params.strict, + }; break; - case 'merge': - // eslint-disable-next-line no-case-declarations + } + case 'merge': { const credentials = setImportCredentials(destConfig); response.endpoint = credentials.endpoint; response.headers = credentials.headers; @@ -109,6 +95,7 @@ const responseBuilderSimple = (payload, message, eventType, destConfig) => { strict: credentials.params.strict, }; break; + } default: response.endpoint = dataResidency === 'eu' ? `${BASE_ENDPOINT_EU}/engage/` : `${BASE_ENDPOINT}/engage/`; @@ -483,7 +470,6 @@ const processRouterDest = async (inputs, reqMetadata) => { const batchSize = { engage: 0, groups: 0, - track: 0, import: 0, }; @@ -515,23 +501,16 @@ const processRouterDest = async (inputs, reqMetadata) => { ); transformedPayloads = lodash.flatMap(transformedPayloads); - const { engageEvents, groupsEvents, trackEvents, importEvents, batchErrorRespList } = + const { engageEvents, groupsEvents, importEvents, batchErrorRespList } = groupEventsByEndpoint(transformedPayloads); const engageRespList = batchEvents(engageEvents, ENGAGE_MAX_BATCH_SIZE, reqMetadata); const groupsRespList = batchEvents(groupsEvents, GROUPS_MAX_BATCH_SIZE, reqMetadata); - const trackRespList = batchEvents(trackEvents, TRACK_MAX_BATCH_SIZE, reqMetadata); const importRespList = batchEvents(importEvents, IMPORT_MAX_BATCH_SIZE, reqMetadata); - const batchSuccessRespList = [ - ...engageRespList, - ...groupsRespList, - ...trackRespList, - ...importRespList, - ]; + const batchSuccessRespList = [...engageRespList, ...groupsRespList, ...importRespList]; batchSize.engage += engageRespList.length; batchSize.groups += groupsRespList.length; - batchSize.track += trackRespList.length; batchSize.import += importRespList.length; return [...batchSuccessRespList, ...batchErrorRespList]; diff --git a/src/v0/destinations/mp/util.js b/src/v0/destinations/mp/util.js index d564e805ad..b2807d6e11 100644 --- a/src/v0/destinations/mp/util.js +++ b/src/v0/destinations/mp/util.js @@ -136,7 +136,7 @@ const createIdentifyResponse = (message, type, destination, responseBuilderSimpl * @returns */ const isImportAuthCredentialsAvailable = (destination) => - destination.Config.apiSecret || + destination.Config.token || (destination.Config.serviceAccountSecret && destination.Config.serviceAccountUserName && destination.Config.projectId); @@ -179,7 +179,6 @@ const groupEventsByEndpoint = (events) => { const eventMap = { engage: [], groups: [], - track: [], import: [], }; const batchErrorRespList = []; @@ -204,7 +203,6 @@ const groupEventsByEndpoint = (events) => { return { engageEvents: eventMap.engage, groupsEvents: eventMap.groups, - trackEvents: eventMap.track, importEvents: eventMap.import, batchErrorRespList, }; @@ -349,7 +347,6 @@ const generatePageOrScreenCustomEventName = (message, userDefinedEventTemplate) * @param {Object} batchSize - The object containing the batch size for different endpoints. * @param {number} batchSize.engage - The batch size for engage endpoint. * @param {number} batchSize.groups - The batch size for group endpoint. - * @param {number} batchSize.track - The batch size for track endpoint. * @param {number} batchSize.import - The batch size for import endpoint. * @param {string} destinationId - The ID of the destination. * @returns {void} @@ -361,9 +358,6 @@ const recordBatchSizeMetrics = (batchSize, destinationId) => { stats.gauge('mixpanel_batch_group_pack_size', batchSize.groups, { destination_id: destinationId, }); - stats.gauge('mixpanel_batch_track_pack_size', batchSize.track, { - destination_id: destinationId, - }); stats.gauge('mixpanel_batch_import_pack_size', batchSize.import, { destination_id: destinationId, }); diff --git a/src/v0/destinations/mp/util.test.js b/src/v0/destinations/mp/util.test.js index 40cdb34649..3666081f59 100644 --- a/src/v0/destinations/mp/util.test.js +++ b/src/v0/destinations/mp/util.test.js @@ -18,7 +18,6 @@ describe('Unit test cases for groupEventsByEndpoint', () => { expect(result).toEqual({ engageEvents: [], groupsEvents: [], - trackEvents: [], importEvents: [], batchErrorRespList: [], }); @@ -122,19 +121,6 @@ describe('Unit test cases for groupEventsByEndpoint', () => { }, }, ], - trackEvents: [ - { - message: { - endpoint: '/track', - body: { - JSON_ARRAY: { - batch: '[{prop:4}]', - }, - }, - userId: 'user1', - }, - }, - ], importEvents: [ { message: { diff --git a/test/integrations/destinations/mp/common.ts b/test/integrations/destinations/mp/common.ts index 82f0e3202b..d40afa0c02 100644 --- a/test/integrations/destinations/mp/common.ts +++ b/test/integrations/destinations/mp/common.ts @@ -7,7 +7,7 @@ const defaultMockFns = () => { const sampleDestination: Destination = { Config: { apiKey: 'dummyApiKey', - token: 'dummyApiKey', + token: 'test_api_token', prefixProperties: true, useNativeSDK: false, }, diff --git a/test/integrations/destinations/mp/processor/data.ts b/test/integrations/destinations/mp/processor/data.ts index 5b2d0fbfff..db5bc840c2 100644 --- a/test/integrations/destinations/mp/processor/data.ts +++ b/test/integrations/destinations/mp/processor/data.ts @@ -12,7 +12,7 @@ export const data = [ request: { body: [ { - destination: overrideDestination(sampleDestination, { token: 'dummyApiKey' }), + destination: overrideDestination(sampleDestination, { token: 'test_api_token' }), message: { anonymousId: 'e6ab2c5e-2cda-44a9-a962-e2f67df78bca', channel: 'web', @@ -87,14 +87,17 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/track/', - headers: {}, - params: {}, + endpoint: 'https://api.mixpanel.com/import/', + headers: { + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + 'Content-Type': 'application/json', + }, + params: { strict: 0 }, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"Loaded a Page","properties":{"ip":"0.0.0.0","campaign_id":"test_name","$user_id":"hjikl","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"dd266c67-9199-4a52-ba32-f46ddde67312","token":"dummyApiKey","distinct_id":"hjikl","time":1579847342402,"utm_campaign":"test_name","utm_source":"rudder","utm_medium":"test_medium","utm_term":"test_tem","utm_content":"test_content","utm_test":"test","utm_keyword":"test_keyword","name":"Contact Us","$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', + '[{"event":"Loaded a Page","properties":{"ip":"0.0.0.0","campaign_id":"test_name","$user_id":"hjikl","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"dd266c67-9199-4a52-ba32-f46ddde67312","token":"test_api_token","distinct_id":"hjikl","time":1579847342402,"utm_campaign":"test_name","utm_source":"rudder","utm_medium":"test_medium","utm_term":"test_tem","utm_content":"test_content","utm_test":"test","utm_keyword":"test_keyword","name":"Contact Us","$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', }, XML: {}, FORM: {}, @@ -191,14 +194,17 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/track/', - headers: {}, - params: {}, + endpoint: 'https://api.mixpanel.com/import/', + headers: { + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + 'Content-Type': 'application/json', + }, + params: { strict: 0 }, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"Viewed a Contact Us page","properties":{"ip":"0.0.0.0","$user_id":"hjikl","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"dd266c67-9199-4a52-ba32-f46ddde67312","token":"dummyApiKey","distinct_id":"hjikl","time":1579847342402,"name":"Contact Us","category":"Contact","$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', + '[{"event":"Viewed a Contact Us page","properties":{"ip":"0.0.0.0","$user_id":"hjikl","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"dd266c67-9199-4a52-ba32-f46ddde67312","token":"test_api_token","distinct_id":"hjikl","time":1579847342402,"name":"Contact Us","category":"Contact","$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', }, XML: {}, FORM: {}, @@ -272,14 +278,17 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/track/', - headers: {}, - params: {}, + endpoint: 'https://api.mixpanel.com/import/', + headers: { + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + 'Content-Type': 'application/json', + }, + params: { strict: 0 }, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"Loaded a Screen","properties":{"category":"communication","ip":"0.0.0.0","$user_id":"hjikl","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"dd266c67-9199-4a52-ba32-f46ddde67312","token":"dummyApiKey","distinct_id":"hjikl","time":1579847342402,"name":"Contact Us"}}]', + '[{"event":"Loaded a Screen","properties":{"category":"communication","ip":"0.0.0.0","$user_id":"hjikl","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"dd266c67-9199-4a52-ba32-f46ddde67312","token":"test_api_token","distinct_id":"hjikl","time":1579847342402,"name":"Contact Us"}}]', }, XML: {}, FORM: {}, @@ -360,14 +369,17 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/track/', - headers: {}, - params: {}, + endpoint: 'https://api.mixpanel.com/import/', + headers: { + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + 'Content-Type': 'application/json', + }, + params: { strict: 0 }, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"Loaded a Screen","properties":{"path":"/tests/html/index2.html","referrer":"","search":"","title":"","url":"http://localhost/tests/html/index2.html","ip":"0.0.0.0","$user_id":"hjiklmk","$screen_dpi":2,"mp_lib":"RudderLabs Android SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"dd266c67-9199-4a52-ba32-f46ddde67312","token":"dummyApiKey","distinct_id":"hjiklmk","time":1579847342402,"name":"Contact Us","category":"Contact"}}]', + '[{"event":"Loaded a Screen","properties":{"path":"/tests/html/index2.html","referrer":"","search":"","title":"","url":"http://localhost/tests/html/index2.html","ip":"0.0.0.0","$user_id":"hjiklmk","$screen_dpi":2,"mp_lib":"RudderLabs Android SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"dd266c67-9199-4a52-ba32-f46ddde67312","token":"test_api_token","distinct_id":"hjiklmk","time":1579847342402,"name":"Contact Us","category":"Contact"}}]', }, XML: {}, FORM: {}, @@ -440,14 +452,17 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/track/', - headers: {}, - params: {}, + endpoint: 'https://api.mixpanel.com/import/', + headers: { + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + 'Content-Type': 'application/json', + }, + params: { strict: 0 }, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"Loaded a Screen","properties":{"ip":"0.0.0.0","$user_id":"hjikl","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"dd266c67-9199-4a52-ba32-f46ddde67312","token":"dummyApiKey","distinct_id":"hjikl","time":1579847342402,"name":"Contact Us"}}]', + '[{"event":"Loaded a Screen","properties":{"ip":"0.0.0.0","$user_id":"hjikl","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"dd266c67-9199-4a52-ba32-f46ddde67312","token":"test_api_token","distinct_id":"hjikl","time":1579847342402,"name":"Contact Us"}}]', }, XML: {}, FORM: {}, @@ -550,7 +565,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$created":"2020-01-23T08:54:02.362Z","$email":"mickey@disney.com","$first_name":"Mickey","$last_name":"Mouse","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', + '[{"$set":{"$created":"2020-01-23T08:54:02.362Z","$email":"mickey@disney.com","$first_name":"Mickey","$last_name":"Mouse","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', }, XML: {}, FORM: {}, @@ -664,7 +679,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$append":{"$transactions":{"$time":"2020-01-24T06:29:02.403Z","$amount":45.89}},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca"}]', + '[{"$append":{"$transactions":{"$time":"2020-01-24T06:29:02.403Z","$amount":45.89}},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca"}]', }, XML: {}, FORM: {}, @@ -686,7 +701,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$add":{"counter":1,"item_purchased":"2"},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca"}]', + '[{"$add":{"counter":1,"item_purchased":"2"},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca"}]', }, XML: {}, FORM: {}, @@ -701,14 +716,17 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/track/', - headers: {}, - params: {}, + endpoint: 'https://api.mixpanel.com/import/', + headers: { + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + 'Content-Type': 'application/json', + }, + params: { strict: 0 }, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"test revenue MIXPANEL","properties":{"currency":"USD","revenue":45.89,"counter":1,"item_purchased":"2","number_of_logins":"","city":"Disney","country":"USA","email":"mickey@disney.com","firstName":"Mickey","ip":"0.0.0.0","campaign_id":"test_name","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"a6a0ad5a-bd26-4f19-8f75-38484e580fc7","token":"dummyApiKey","distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","time":1579847342403,"utm_campaign":"test_name","utm_source":"rudder","utm_medium":"test_medium","utm_term":"test_tem","utm_content":"test_content","utm_test":"test","utm_keyword":"test_keyword","$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', + '[{"event":"test revenue MIXPANEL","properties":{"currency":"USD","revenue":45.89,"counter":1,"item_purchased":"2","number_of_logins":"","city":"Disney","country":"USA","email":"mickey@disney.com","firstName":"Mickey","ip":"0.0.0.0","campaign_id":"test_name","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"a6a0ad5a-bd26-4f19-8f75-38484e580fc7","token":"test_api_token","distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","time":1579847342403,"utm_campaign":"test_name","utm_source":"rudder","utm_medium":"test_medium","utm_term":"test_tem","utm_content":"test_content","utm_test":"test","utm_keyword":"test_keyword","$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', }, XML: {}, FORM: {}, @@ -796,14 +814,17 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/track/', - headers: {}, - params: {}, + endpoint: 'https://api.mixpanel.com/import/', + headers: { + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + 'Content-Type': 'application/json', + }, + params: { strict: 0 }, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"$create_alias","properties":{"distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","alias":"1234abc","token":"dummyApiKey"}}]', + '[{"event":"$create_alias","properties":{"distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","alias":"1234abc","token":"test_api_token"}}]', }, XML: {}, FORM: {}, @@ -933,7 +954,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$append":{"$transactions":{"$time":"2020-01-24T06:29:02.402Z","$amount":25}},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca"}]', + '[{"$append":{"$transactions":{"$time":"2020-01-24T06:29:02.402Z","$amount":25}},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca"}]', }, XML: {}, FORM: {}, @@ -948,14 +969,17 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/track/', - headers: {}, - params: {}, + endpoint: 'https://api.mixpanel.com/import/', + headers: { + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + 'Content-Type': 'application/json', + }, + params: { strict: 0 }, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"KM Order Completed","properties":{"affiliation":"Google Store","checkout_id":"fksdjfsdjfisjf9sdfjsd9f","coupon":"hasbros","currency":"USD","discount":2.5,"order_id":"50314b8e9bcf000000000000","products":[{"category":"Games","image_url":"https:///www.example.com/product/path.jpg","name":"Monopoly: 3rd Edition","price":19,"product_id":"507f1f77bcf86cd799439011","quantity":1,"sku":"45790-32","url":"https://www.example.com/product/path"},{"category":"Games","name":"Uno Card Game","price":3,"product_id":"505bd76785ebb509fc183733","quantity":2,"sku":"46493-32"}],"revenue":25,"shipping":3,"subtotal":22.5,"tax":2,"total":27.5,"city":"Disney","country":"USA","email":"mickey@disney.com","firstName":"Mickey","ip":"0.0.0.0","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"aa5f5e44-8756-40ad-ad1e-b0d3b9fa710a","token":"dummyApiKey","distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","time":1579847342402,"$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', + '[{"event":"KM Order Completed","properties":{"affiliation":"Google Store","checkout_id":"fksdjfsdjfisjf9sdfjsd9f","coupon":"hasbros","currency":"USD","discount":2.5,"order_id":"50314b8e9bcf000000000000","products":[{"category":"Games","image_url":"https:///www.example.com/product/path.jpg","name":"Monopoly: 3rd Edition","price":19,"product_id":"507f1f77bcf86cd799439011","quantity":1,"sku":"45790-32","url":"https://www.example.com/product/path"},{"category":"Games","name":"Uno Card Game","price":3,"product_id":"505bd76785ebb509fc183733","quantity":2,"sku":"46493-32"}],"revenue":25,"shipping":3,"subtotal":22.5,"tax":2,"total":27.5,"city":"Disney","country":"USA","email":"mickey@disney.com","firstName":"Mickey","ip":"0.0.0.0","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"aa5f5e44-8756-40ad-ad1e-b0d3b9fa710a","token":"test_api_token","distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","time":1579847342402,"$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', }, XML: {}, FORM: {}, @@ -1089,7 +1113,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$append":{"$transactions":{"$time":"2020-01-24T06:29:02.402Z","$amount":34}},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca"}]', + '[{"$append":{"$transactions":{"$time":"2020-01-24T06:29:02.402Z","$amount":34}},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca"}]', }, XML: {}, FORM: {}, @@ -1104,14 +1128,17 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/track/', - headers: {}, - params: {}, + endpoint: 'https://api.mixpanel.com/import/', + headers: { + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + 'Content-Type': 'application/json', + }, + params: { strict: 0 }, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"KM Order Completed","properties":{"affiliation":"Google Store","checkout_id":"fksdjfsdjfisjf9sdfjsd9f","coupon":"hasbros","currency":"USD","discount":2.5,"order_id":"50314b8e9bcf000000000000","revenue":34,"key_1":{"child_key1":"child_value1","child_key2":{"child_key21":"child_value21","child_key22":"child_value22"}},"products":[{"category":"Games","image_url":"https:///www.example.com/product/path.jpg","name":"Monopoly: 3rd Edition","price":19,"product_id":"507f1f77bcf86cd799439011","quantity":1,"sku":"45790-32","url":"https://www.example.com/product/path"},{"category":"Games","name":"Uno Card Game","price":3,"product_id":"505bd76785ebb509fc183733","quantity":2,"sku":"46493-32"}],"shipping":3,"subtotal":22.5,"tax":2,"total":27.5,"city":"Disney","country":"USA","email":"mickey@disney.com","first_name":"Mickey","lastName":"Mouse","name":"Mickey Mouse","ip":"0.0.0.0","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"aa5f5e44-8756-40ad-ad1e-b0d3b9fa710a","token":"dummyApiKey","distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","time":1579847342402,"$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', + '[{"event":"KM Order Completed","properties":{"affiliation":"Google Store","checkout_id":"fksdjfsdjfisjf9sdfjsd9f","coupon":"hasbros","currency":"USD","discount":2.5,"order_id":"50314b8e9bcf000000000000","revenue":34,"key_1":{"child_key1":"child_value1","child_key2":{"child_key21":"child_value21","child_key22":"child_value22"}},"products":[{"category":"Games","image_url":"https:///www.example.com/product/path.jpg","name":"Monopoly: 3rd Edition","price":19,"product_id":"507f1f77bcf86cd799439011","quantity":1,"sku":"45790-32","url":"https://www.example.com/product/path"},{"category":"Games","name":"Uno Card Game","price":3,"product_id":"505bd76785ebb509fc183733","quantity":2,"sku":"46493-32"}],"shipping":3,"subtotal":22.5,"tax":2,"total":27.5,"city":"Disney","country":"USA","email":"mickey@disney.com","first_name":"Mickey","lastName":"Mouse","name":"Mickey Mouse","ip":"0.0.0.0","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"aa5f5e44-8756-40ad-ad1e-b0d3b9fa710a","token":"test_api_token","distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","time":1579847342402,"$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', }, XML: {}, FORM: {}, @@ -1235,14 +1262,17 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/track/', - headers: {}, - params: {}, + endpoint: 'https://api.mixpanel.com/import/', + headers: { + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + 'Content-Type': 'application/json', + }, + params: { strict: 0 }, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":" new Order Completed totally","properties":{"affiliation":"Google Store","checkout_id":"fksdjfsdjfisjf9sdfjsd9f","coupon":"hasbros","currency":"USD","discount":2.5,"total":23,"order_id":"50314b8e9bcf000000000000","key_1":{"child_key1":"child_value1","child_key2":{"child_key21":"child_value21","child_key22":"child_value22"}},"products":[{"category":"Games","image_url":"https:///www.example.com/product/path.jpg","name":"Monopoly: 3rd Edition","price":19,"product_id":"507f1f77bcf86cd799439011","quantity":1,"sku":"45790-32","url":"https://www.example.com/product/path"},{"category":"Games","name":"Uno Card Game","price":3,"product_id":"505bd76785ebb509fc183733","quantity":2,"sku":"46493-32"}],"shipping":3,"subtotal":22.5,"tax":2,"city":"Disney","country":"USA","email":"mickey@disney.com","firstName":"Mickey","ip":"0.0.0.0","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"aa5f5e44-8756-40ad-ad1e-b0d3b9fa710a","token":"dummyApiKey","distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","time":1579847342402,"$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', + '[{"event":" new Order Completed totally","properties":{"affiliation":"Google Store","checkout_id":"fksdjfsdjfisjf9sdfjsd9f","coupon":"hasbros","currency":"USD","discount":2.5,"total":23,"order_id":"50314b8e9bcf000000000000","key_1":{"child_key1":"child_value1","child_key2":{"child_key21":"child_value21","child_key22":"child_value22"}},"products":[{"category":"Games","image_url":"https:///www.example.com/product/path.jpg","name":"Monopoly: 3rd Edition","price":19,"product_id":"507f1f77bcf86cd799439011","quantity":1,"sku":"45790-32","url":"https://www.example.com/product/path"},{"category":"Games","name":"Uno Card Game","price":3,"product_id":"505bd76785ebb509fc183733","quantity":2,"sku":"46493-32"}],"shipping":3,"subtotal":22.5,"tax":2,"city":"Disney","country":"USA","email":"mickey@disney.com","firstName":"Mickey","ip":"0.0.0.0","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"aa5f5e44-8756-40ad-ad1e-b0d3b9fa710a","token":"test_api_token","distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","time":1579847342402,"$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', }, XML: {}, FORM: {}, @@ -1366,14 +1396,17 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/track/', - headers: {}, - params: {}, + endpoint: 'https://api.mixpanel.com/import/', + headers: { + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + 'Content-Type': 'application/json', + }, + params: { strict: 0 }, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":" Order Completed ","properties":{"affiliation":"Google Store","checkout_id":"fksdjfsdjfisjf9sdfjsd9f","coupon":"hasbros","currency":"USD","discount":2.5,"total":23,"order_id":"50314b8e9bcf000000000000","key_1":{"child_key1":"child_value1","child_key2":{"child_key21":"child_value21","child_key22":"child_value22"}},"products":[{"category":"Games","image_url":"https:///www.example.com/product/path.jpg","name":"Monopoly: 3rd Edition","price":19,"product_id":"507f1f77bcf86cd799439011","quantity":1,"sku":"45790-32","url":"https://www.example.com/product/path"},{"category":"Games","name":"Uno Card Game","price":3,"product_id":"505bd76785ebb509fc183733","quantity":2,"sku":"46493-32"}],"shipping":3,"subtotal":22.5,"tax":2,"Billing Amount":"77","city":"Disney","country":"USA","email":"mickey@disney.com","firstName":"Mickey","ip":"0.0.0.0","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"aa5f5e44-8756-40ad-ad1e-b0d3b9fa710a","token":"dummyApiKey","distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","time":1579847342402,"$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', + '[{"event":" Order Completed ","properties":{"affiliation":"Google Store","checkout_id":"fksdjfsdjfisjf9sdfjsd9f","coupon":"hasbros","currency":"USD","discount":2.5,"total":23,"order_id":"50314b8e9bcf000000000000","key_1":{"child_key1":"child_value1","child_key2":{"child_key21":"child_value21","child_key22":"child_value22"}},"products":[{"category":"Games","image_url":"https:///www.example.com/product/path.jpg","name":"Monopoly: 3rd Edition","price":19,"product_id":"507f1f77bcf86cd799439011","quantity":1,"sku":"45790-32","url":"https://www.example.com/product/path"},{"category":"Games","name":"Uno Card Game","price":3,"product_id":"505bd76785ebb509fc183733","quantity":2,"sku":"46493-32"}],"shipping":3,"subtotal":22.5,"tax":2,"Billing Amount":"77","city":"Disney","country":"USA","email":"mickey@disney.com","firstName":"Mickey","ip":"0.0.0.0","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"aa5f5e44-8756-40ad-ad1e-b0d3b9fa710a","token":"test_api_token","distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","time":1579847342402,"$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', }, XML: {}, FORM: {}, @@ -1541,7 +1574,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$email":"mickey@disney.com","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$firstName":"Mickey","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', + '[{"$set":{"$email":"mickey@disney.com","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$firstName":"Mickey","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', }, XML: {}, FORM: {}, @@ -1628,7 +1661,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$token":"dummyApiKey","$distinct_id":"hjikl","$set":{"company":["testComp"]},"$ip":"0.0.0.0"}]', + '[{"$token":"test_api_token","$distinct_id":"hjikl","$set":{"company":["testComp"]},"$ip":"0.0.0.0"}]', }, XML: {}, FORM: {}, @@ -1650,7 +1683,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$token":"dummyApiKey","$group_key":"company","$group_id":"testComp","$set":{"company":"testComp"}}]', + '[{"$token":"test_api_token","$group_key":"company","$group_id":"testComp","$set":{"company":"testComp"}}]', }, XML: {}, FORM: {}, @@ -1737,7 +1770,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$token":"dummyApiKey","$distinct_id":"hjikl","$set":{"company":["testComp","testComp1"]},"$ip":"0.0.0.0"}]', + '[{"$token":"test_api_token","$distinct_id":"hjikl","$set":{"company":["testComp","testComp1"]},"$ip":"0.0.0.0"}]', }, XML: {}, FORM: {}, @@ -1759,7 +1792,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$token":"dummyApiKey","$group_key":"company","$group_id":"testComp","$set":{"company":["testComp","testComp1"]}}]', + '[{"$token":"test_api_token","$group_key":"company","$group_id":"testComp","$set":{"company":["testComp","testComp1"]}}]', }, XML: {}, FORM: {}, @@ -1781,7 +1814,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$token":"dummyApiKey","$group_key":"company","$group_id":"testComp1","$set":{"company":["testComp","testComp1"]}}]', + '[{"$token":"test_api_token","$group_key":"company","$group_id":"testComp1","$set":{"company":["testComp","testComp1"]}}]', }, XML: {}, FORM: {}, @@ -1869,7 +1902,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$token":"dummyApiKey","$distinct_id":"hjikl","$set":{"company":["testComp"]},"$ip":"0.0.0.0"}]', + '[{"$token":"test_api_token","$distinct_id":"hjikl","$set":{"company":["testComp"]},"$ip":"0.0.0.0"}]', }, XML: {}, FORM: {}, @@ -1891,7 +1924,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$token":"dummyApiKey","$group_key":"company","$group_id":"testComp","$set":{"company":"testComp"}}]', + '[{"$token":"test_api_token","$group_key":"company","$group_id":"testComp","$set":{"company":"testComp"}}]', }, XML: {}, FORM: {}, @@ -2019,7 +2052,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$append":{"$transactions":{"$time":"2020-01-24T06:29:02.402Z","$amount":25}},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca"}]', + '[{"$append":{"$transactions":{"$time":"2020-01-24T06:29:02.402Z","$amount":25}},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca"}]', }, XML: {}, FORM: {}, @@ -2034,14 +2067,17 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api-eu.mixpanel.com/track/', - headers: {}, - params: {}, + endpoint: 'https://api-eu.mixpanel.com/import/', + headers: { + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + 'Content-Type': 'application/json', + }, + params: { strict: 0 }, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"KM Order Completed","properties":{"affiliation":"Google Store","checkout_id":"fksdjfsdjfisjf9sdfjsd9f","coupon":"hasbros","currency":"USD","discount":2.5,"order_id":"50314b8e9bcf000000000000","products":[{"category":"Games","image_url":"https:///www.example.com/product/path.jpg","name":"Monopoly: 3rd Edition","price":19,"product_id":"507f1f77bcf86cd799439011","quantity":1,"sku":"45790-32","url":"https://www.example.com/product/path"},{"category":"Games","name":"Uno Card Game","price":3,"product_id":"505bd76785ebb509fc183733","quantity":2,"sku":"46493-32"}],"revenue":25,"shipping":3,"subtotal":22.5,"tax":2,"total":27.5,"city":"Disney","country":"USA","email":"mickey@disney.com","firstname":"Mickey","lastname":"Mouse","ip":"0.0.0.0","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"aa5f5e44-8756-40ad-ad1e-b0d3b9fa710a","token":"dummyApiKey","distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","time":1579847342402,"$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', + '[{"event":"KM Order Completed","properties":{"affiliation":"Google Store","checkout_id":"fksdjfsdjfisjf9sdfjsd9f","coupon":"hasbros","currency":"USD","discount":2.5,"order_id":"50314b8e9bcf000000000000","products":[{"category":"Games","image_url":"https:///www.example.com/product/path.jpg","name":"Monopoly: 3rd Edition","price":19,"product_id":"507f1f77bcf86cd799439011","quantity":1,"sku":"45790-32","url":"https://www.example.com/product/path"},{"category":"Games","name":"Uno Card Game","price":3,"product_id":"505bd76785ebb509fc183733","quantity":2,"sku":"46493-32"}],"revenue":25,"shipping":3,"subtotal":22.5,"tax":2,"total":27.5,"city":"Disney","country":"USA","email":"mickey@disney.com","firstname":"Mickey","lastname":"Mouse","ip":"0.0.0.0","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"aa5f5e44-8756-40ad-ad1e-b0d3b9fa710a","token":"test_api_token","distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","time":1579847342402,"$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', }, XML: {}, FORM: {}, @@ -2129,7 +2165,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$carrier":"Android","$manufacturer":"Google","$model":"Android SDK built for x86","$screen_height":1794,"$screen_width":1080,"$wifi":true,"anonymousId":"5094f5704b9cf2b3","$android_devices":["test_device_token"],"$os":"Android","$android_model":"Android SDK built for x86","$android_os_version":"8.1.0","$android_manufacturer":"Google","$android_app_version":"1.0","$android_app_version_code":"1.0","$android_brand":"Google"},"$token":"dummyApiKey","$distinct_id":"5094f5704b9cf2b3","$time":1584003903421}]', + '[{"$set":{"$carrier":"Android","$manufacturer":"Google","$model":"Android SDK built for x86","$screen_height":1794,"$screen_width":1080,"$wifi":true,"anonymousId":"5094f5704b9cf2b3","$android_devices":["test_device_token"],"$os":"Android","$android_model":"Android SDK built for x86","$android_os_version":"8.1.0","$android_manufacturer":"Google","$android_app_version":"1.0","$android_app_version_code":"1.0","$android_brand":"Google"},"$token":"test_api_token","$distinct_id":"5094f5704b9cf2b3","$time":1584003903421}]', }, XML: {}, FORM: {}, @@ -2216,7 +2252,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$carrier":"Android","$manufacturer":"Google","$model":"Android SDK built for x86","$screen_height":1794,"$screen_width":1080,"$wifi":true,"anonymousId":"5094f5704b9cf2b3","userId":"test_user_id","$ios_devices":["test_device_token"],"$os":"iOS","$ios_device_model":"Android SDK built for x86","$ios_version":"8.1.0","$ios_app_release":"1","$ios_app_version":"1.0"},"$token":"dummyApiKey","$distinct_id":"test_user_id","$time":1584003903421}]', + '[{"$set":{"$carrier":"Android","$manufacturer":"Google","$model":"Android SDK built for x86","$screen_height":1794,"$screen_width":1080,"$wifi":true,"anonymousId":"5094f5704b9cf2b3","userId":"test_user_id","$ios_devices":["test_device_token"],"$os":"iOS","$ios_device_model":"Android SDK built for x86","$ios_version":"8.1.0","$ios_app_release":"1","$ios_app_version":"1.0"},"$token":"test_api_token","$distinct_id":"test_user_id","$time":1584003903421}]', }, XML: {}, FORM: {}, @@ -2233,7 +2269,7 @@ export const data = [ method: 'POST', endpoint: 'https://api-eu.mixpanel.com/import/', headers: { - Authorization: 'Basic c29tZV9hcGlfc2VjcmV0Og==', + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', 'Content-Type': 'application/json', }, params: { strict: 0 }, @@ -2241,7 +2277,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"event":"$merge","properties":{"$distinct_ids":["test_user_id","5094f5704b9cf2b3"],"token":"dummyApiKey"}}]', + '[{"event":"$merge","properties":{"$distinct_ids":["test_user_id","5094f5704b9cf2b3"],"token":"test_api_token"}}]', }, XML: {}, FORM: {}, @@ -2328,14 +2364,17 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/track/', - headers: {}, - params: {}, + endpoint: 'https://api.mixpanel.com/import/', + headers: { + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + 'Content-Type': 'application/json', + }, + params: { strict: 0 }, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"Loaded a Page","properties":{"path":"/tests/html/index2.html","referrer":"","search":"","title":"","url":"http://localhost/tests/html/index2.html","category":"communication","ip":"0.0.0.0","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"dd266c67-9199-4a52-ba32-f46ddde67312","token":"dummyApiKey","distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","time":1579847342402,"name":"Contact Us","$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', + '[{"event":"Loaded a Page","properties":{"path":"/tests/html/index2.html","referrer":"","search":"","title":"","url":"http://localhost/tests/html/index2.html","category":"communication","ip":"0.0.0.0","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"dd266c67-9199-4a52-ba32-f46ddde67312","token":"test_api_token","distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","time":1579847342402,"name":"Contact Us","$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', }, XML: {}, FORM: {}, @@ -2423,14 +2462,17 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/track/', - headers: {}, - params: {}, + endpoint: 'https://api.mixpanel.com/import/', + headers: { + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + 'Content-Type': 'application/json', + }, + params: { strict: 0 }, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"$create_alias","properties":{"distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","alias":"1234abc","token":"dummyApiKey"}}]', + '[{"event":"$create_alias","properties":{"distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","alias":"1234abc","token":"test_api_token"}}]', }, XML: {}, FORM: {}, @@ -2523,7 +2565,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$carrier":"Android","$manufacturer":"Google","$model":"Android SDK built for x86","$screen_height":1794,"$screen_width":1080,"$wifi":true,"anonymousId":"5094f5704b9cf2b3","userId":"test_user_id","createdat":"2020-01-23T08:54:02.362Z","$ios_devices":["test_device_token"],"$ios_device_model":"Android SDK built for x86","$ios_app_release":"1","$ios_app_version":"1.0"},"$token":"dummyApiKey","$distinct_id":"test_user_id","$time":1584003903421}]', + '[{"$set":{"$carrier":"Android","$manufacturer":"Google","$model":"Android SDK built for x86","$screen_height":1794,"$screen_width":1080,"$wifi":true,"anonymousId":"5094f5704b9cf2b3","userId":"test_user_id","createdat":"2020-01-23T08:54:02.362Z","$ios_devices":["test_device_token"],"$ios_device_model":"Android SDK built for x86","$ios_app_release":"1","$ios_app_version":"1.0"},"$token":"test_api_token","$distinct_id":"test_user_id","$time":1584003903421}]', }, XML: {}, FORM: {}, @@ -2540,7 +2582,7 @@ export const data = [ method: 'POST', endpoint: 'https://api-eu.mixpanel.com/import/', headers: { - Authorization: 'Basic c29tZV9hcGlfc2VjcmV0Og==', + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', 'Content-Type': 'application/json', }, params: { strict: 0 }, @@ -2548,7 +2590,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"event":"$merge","properties":{"$distinct_ids":["test_user_id","5094f5704b9cf2b3"],"token":"dummyApiKey"}}]', + '[{"event":"$merge","properties":{"$distinct_ids":["test_user_id","5094f5704b9cf2b3"],"token":"test_api_token"}}]', }, XML: {}, FORM: {}, @@ -2641,7 +2683,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$email":"mickey@disney.com","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$firstName":"Mickey","$lastName":"Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', + '[{"$set":{"$email":"mickey@disney.com","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$firstName":"Mickey","$lastName":"Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', }, XML: {}, FORM: {}, @@ -2733,7 +2775,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$email":"mickey@disney.com","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$firstName":"Mickey","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', + '[{"$set":{"$email":"mickey@disney.com","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$firstName":"Mickey","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', }, XML: {}, FORM: {}, @@ -2826,7 +2868,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$email":"mickey@disney.com","$name":"Mickey Mouse","$country_code":"USA","$city":"Disney","$region":"US","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$firstName":"Mickey","$lastName":"Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', + '[{"$set":{"$email":"mickey@disney.com","$name":"Mickey Mouse","$country_code":"USA","$city":"Disney","$region":"US","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$firstName":"Mickey","$lastName":"Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', }, XML: {}, FORM: {}, @@ -2924,7 +2966,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$email":"mickey@disney.com","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$firstName":"Mickey","$lastName":"Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', + '[{"$set":{"$email":"mickey@disney.com","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$firstName":"Mickey","$lastName":"Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', }, XML: {}, FORM: {}, @@ -3020,7 +3062,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$email":"mickey@disney.com","$name":"Mouse","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$firstName":"Mickey","$lastName":"Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', + '[{"$set":{"$email":"mickey@disney.com","$name":"Mouse","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$firstName":"Mickey","$lastName":"Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', }, XML: {}, FORM: {}, @@ -3115,7 +3157,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$email":"mickey@disney.com","$first_name":"Mickey","$last_name":"Mouse","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', + '[{"$set":{"$email":"mickey@disney.com","$first_name":"Mickey","$last_name":"Mouse","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', }, XML: {}, FORM: {}, @@ -3209,7 +3251,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$email":"mickey@disney.com","$first_name":"Mickey","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', + '[{"$set":{"$email":"mickey@disney.com","$first_name":"Mickey","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', }, XML: {}, FORM: {}, @@ -3304,7 +3346,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$email":"mickey@disney.com","$first_name":"Mickey","$last_name":"Mouse","$name":"Mickey Mouse","$country_code":"USA","$city":"Disney","$region":"US","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', + '[{"$set":{"$email":"mickey@disney.com","$first_name":"Mickey","$last_name":"Mouse","$name":"Mickey Mouse","$country_code":"USA","$city":"Disney","$region":"US","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', }, XML: {}, FORM: {}, @@ -3405,7 +3447,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$email":"mickey@disney.com","$first_name":"Mickey","$last_name":"Mouse","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', + '[{"$set":{"$email":"mickey@disney.com","$first_name":"Mickey","$last_name":"Mouse","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', }, XML: {}, FORM: {}, @@ -3502,17 +3544,29 @@ export const data = [ status: 200, body: [ { - error: - 'Event timestamp is older than 5 days and no API secret or service account credentials (i.e. username, secret and projectId) are provided in destination configuration', - statTags: { - destType: 'MP', - errorCategory: 'dataValidation', - errorType: 'instrumentation', - feature: 'processor', - implementation: 'native', - module: 'destination', + output: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.mixpanel.com/import/', + headers: { + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + 'Content-Type': 'application/json', + }, + params: { strict: 0 }, + body: { + JSON: {}, + JSON_ARRAY: { + batch: + '[{"event":"FirstTrackCall12","properties":{"foo":"bar","$deviceId":"nkasdnkasd","anonymousId":"ea776ad0-3136-44fb-9216-5b1578609a2b","userId":"as09sufa09usaf09as0f9uasf","id":"as09sufa09usaf09as0f9uasf","firstName":"Bob","lastName":"Marley","name":"Bob Marley","age":43,"email":"bob@marleymail.com","phone":"+447748544123","birthday":"1987-01-01T20:08:59+0000","createdAt":"2022-01-21T14:10:12+0000","address":"51,B.L.T road, Kolkata-700060","description":"I am great","gender":"male","title":"Founder","username":"bobm","website":"https://bobm.com","randomProperty":"randomValue","$user_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$current_url":"http://127.0.0.1:7307/Testing/App_for_testingTool/","$referrer":"http://127.0.0.1:7307/Testing/","$screen_height":900,"$screen_width":1440,"$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.1.18","$insert_id":"0d5c1a4a-27e4-41da-a246-4d01f44e74bd","token":"test_api_token","distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","time":1632986123523,"$browser":"Chrome","$browser_version":"93.0.4577.82"}}]', + }, + XML: {}, + FORM: {}, + }, + files: {}, + userId: 'e6ab2c5e-2cda-44a9-a962-e2f67df78bca', }, - statusCode: 400, + statusCode: 200, }, ], }, @@ -3686,7 +3740,7 @@ export const data = [ method: 'POST', endpoint: 'https://api-eu.mixpanel.com/import/', headers: { - Authorization: 'Basic c29tZV9hcGlfc2VjcmV0Og==', + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', 'Content-Type': 'application/json', }, params: { strict: 0 }, @@ -3694,7 +3748,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"event":"MainActivity","properties":{"name":"MainActivity","automatic":true,"anonymousId":"5094f5704b9cf2b3","userId":"test_user_id","$user_id":"test_user_id","$os":"iOS","$screen_height":1794,"$screen_width":1080,"$screen_dpi":420,"$carrier":"Android","$os_version":"8.1.0","$device":"generic_x86","$manufacturer":"Google","$model":"Android SDK built for x86","mp_device_model":"Android SDK built for x86","$wifi":true,"$bluetooth_enabled":false,"mp_lib":"com.rudderstack.android.sdk.core","$app_build_number":"1","$app_version_string":"1.0","$insert_id":"id2","token":"dummyApiKey","distinct_id":"test_user_id","time":1520845503421}}]', + '[{"event":"MainActivity","properties":{"name":"MainActivity","automatic":true,"anonymousId":"5094f5704b9cf2b3","userId":"test_user_id","$user_id":"test_user_id","$os":"iOS","$screen_height":1794,"$screen_width":1080,"$screen_dpi":420,"$carrier":"Android","$os_version":"8.1.0","$device":"generic_x86","$manufacturer":"Google","$model":"Android SDK built for x86","mp_device_model":"Android SDK built for x86","$wifi":true,"$bluetooth_enabled":false,"mp_lib":"com.rudderstack.android.sdk.core","$app_build_number":"1","$app_version_string":"1.0","$insert_id":"id2","token":"test_api_token","distinct_id":"test_user_id","time":1520845503421}}]', }, XML: {}, FORM: {}, @@ -3965,7 +4019,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$created":"2020-01-23T08:54:02.362Z","$email":"mickey@disney.com","$first_name":"Mickey","$last_name":"Mouse","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402,"$ignore_time":true}]', + '[{"$set":{"$created":"2020-01-23T08:54:02.362Z","$email":"mickey@disney.com","$first_name":"Mickey","$last_name":"Mouse","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402,"$ignore_time":true}]', }, XML: {}, FORM: {}, @@ -4071,7 +4125,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$created":"2020-01-23T08:54:02.362Z","$email":"mickey@disney.com","$first_name":"Mickey","$last_name":"Mouse","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', + '[{"$set":{"$created":"2020-01-23T08:54:02.362Z","$email":"mickey@disney.com","$first_name":"Mickey","$last_name":"Mouse","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', }, XML: {}, FORM: {}, @@ -4276,7 +4330,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$created":"2020-01-23T08:54:02.362Z","$email":"mickey@disney.com","$first_name":"Mickey","$last_name":"Mouse","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyApiKey","$distinct_id":"user1234","$ip":"0.0.0.0","$time":1579847342402}]', + '[{"$set":{"$created":"2020-01-23T08:54:02.362Z","$email":"mickey@disney.com","$first_name":"Mickey","$last_name":"Mouse","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"user1234","$ip":"0.0.0.0","$time":1579847342402}]', }, XML: {}, FORM: {}, @@ -4294,15 +4348,14 @@ export const data = [ endpoint: 'https://api.mixpanel.com/import/', headers: { 'Content-Type': 'application/json', - Authorization: - 'Basic cnVkZGVyLmQyYTNmMS5tcC1zZXJ2aWNlLWFjY291bnQ6amF0cFF4Y2pNaDhlZXRrMXhySDNLalFJYnp5NGlYOGI=', + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', }, - params: { project_id: '123456', strict: 0 }, + params: { strict: 0 }, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"$merge","properties":{"$distinct_ids":["user1234","e6ab2c5e-2cda-44a9-a962-e2f67df78bca"],"token":"dummyApiKey"}}]', + '[{"event":"$merge","properties":{"$distinct_ids":["user1234","e6ab2c5e-2cda-44a9-a962-e2f67df78bca"],"token":"test_api_token"}}]', }, XML: {}, FORM: {}, @@ -4387,7 +4440,7 @@ export const data = [ method: 'POST', endpoint: 'https://api.mixpanel.com/import/', headers: { - Authorization: 'Basic ZHVtbXlBcGlLZXk6', + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', 'Content-Type': 'application/json', }, params: { strict: 0 }, @@ -4395,7 +4448,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"event":"Application Installed","properties":{"build":4,"version":"1.0","anonymousId":"39da706ec83d0e90","$os":"Android","$screen_height":2984,"$screen_width":1440,"$screen_dpi":560,"$carrier":"T-Mobile","$os_version":"12","$device":"emu64a","$manufacturer":"Google","$model":"sdk_gphone64_arm64","mp_device_model":"sdk_gphone64_arm64","$wifi":true,"$bluetooth_enabled":true,"mp_lib":"com.rudderstack.android.sdk.core","$app_build_number":"4","$app_version_string":"1.0","$insert_id":"168cf720-6227-4b56-a98e-c49bdc7279e9","$session_id":"1662363980","token":"dummyApiKey","distinct_id":"39da706ec83d0e90","time":1662363980290}}]', + '[{"event":"Application Installed","properties":{"build":4,"version":"1.0","anonymousId":"39da706ec83d0e90","$os":"Android","$screen_height":2984,"$screen_width":1440,"$screen_dpi":560,"$carrier":"T-Mobile","$os_version":"12","$device":"emu64a","$manufacturer":"Google","$model":"sdk_gphone64_arm64","mp_device_model":"sdk_gphone64_arm64","$wifi":true,"$bluetooth_enabled":true,"mp_lib":"com.rudderstack.android.sdk.core","$app_build_number":"4","$app_version_string":"1.0","$insert_id":"168cf720-6227-4b56-a98e-c49bdc7279e9","$session_id":"1662363980","token":"test_api_token","distinct_id":"39da706ec83d0e90","time":1662363980290}}]', }, XML: {}, FORM: {}, @@ -4477,7 +4530,7 @@ export const data = [ method: 'POST', endpoint: 'https://api.mixpanel.com/import/', headers: { - Authorization: 'Basic ZHVtbXlBcGlLZXk6', + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', 'Content-Type': 'application/json', }, params: { strict: 0 }, @@ -4485,7 +4538,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"event":"Application Opened","properties":{"build":4,"version":"1.0","anonymousId":"39da706ec83d0e90","$os":"Android","$screen_height":2984,"$screen_width":1440,"$screen_dpi":560,"$carrier":"T-Mobile","$os_version":"12","$device":"emu64a","$manufacturer":"Google","$model":"sdk_gphone64_arm64","mp_device_model":"sdk_gphone64_arm64","$wifi":true,"$bluetooth_enabled":true,"mp_lib":"com.rudderstack.android.sdk.core","$app_build_number":"4","$app_version_string":"1.0","$insert_id":"168cf720-6227-4b56-a98e-c49bdc7279e9","$session_id":"1662363980","token":"dummyApiKey","distinct_id":"39da706ec83d0e90","time":1662363980290}}]', + '[{"event":"Application Opened","properties":{"build":4,"version":"1.0","anonymousId":"39da706ec83d0e90","$os":"Android","$screen_height":2984,"$screen_width":1440,"$screen_dpi":560,"$carrier":"T-Mobile","$os_version":"12","$device":"emu64a","$manufacturer":"Google","$model":"sdk_gphone64_arm64","mp_device_model":"sdk_gphone64_arm64","$wifi":true,"$bluetooth_enabled":true,"mp_lib":"com.rudderstack.android.sdk.core","$app_build_number":"4","$app_version_string":"1.0","$insert_id":"168cf720-6227-4b56-a98e-c49bdc7279e9","$session_id":"1662363980","token":"test_api_token","distinct_id":"39da706ec83d0e90","time":1662363980290}}]', }, XML: {}, FORM: {}, @@ -4573,7 +4626,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$token":"dummyApiKey","$distinct_id":"hjikl","$set":{"groupId":["testGroupId"]},"$ip":"0.0.0.0"}]', + '[{"$token":"test_api_token","$distinct_id":"hjikl","$set":{"groupId":["testGroupId"]},"$ip":"0.0.0.0"}]', }, XML: {}, FORM: {}, @@ -4595,7 +4648,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$token":"dummyApiKey","$group_key":"groupId","$group_id":"testGroupId","$set":{"company":"testComp","groupId":"groupIdInTraits"}}]', + '[{"$token":"test_api_token","$group_key":"groupId","$group_id":"testGroupId","$set":{"company":"testComp","groupId":"groupIdInTraits"}}]', }, XML: {}, FORM: {}, @@ -4622,7 +4675,7 @@ export const data = [ description: 'Track: set device id and user id when simplified id merge api is selected', destination: overrideDestination(sampleDestination, { - token: 'apiToken123', + token: 'test_api_token', identityMergeApi: 'simplified', }), message: { @@ -4678,14 +4731,17 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/track/', - headers: {}, - params: {}, + endpoint: 'https://api.mixpanel.com/import/', + headers: { + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + 'Content-Type': 'application/json', + }, + params: { strict: 0 }, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"Product Viewed","properties":{"name":"T-Shirt","$user_id":"userId01","$os":"iOS","$screen_height":1794,"$screen_width":1080,"$screen_dpi":420,"$carrier":"Android","$os_version":"8.1.0","$device":"generic_x86","$manufacturer":"Google","$model":"Android SDK built for x86","mp_device_model":"Android SDK built for x86","$wifi":true,"$bluetooth_enabled":false,"mp_lib":"com.rudderstack.android.sdk.core","$app_build_number":"1","$app_version_string":"1.0","$insert_id":"id2","token":"apiToken123","distinct_id":"userId01","time":1579847342402,"$device_id":"anonId01"}}]', + '[{"event":"Product Viewed","properties":{"name":"T-Shirt","$user_id":"userId01","$os":"iOS","$screen_height":1794,"$screen_width":1080,"$screen_dpi":420,"$carrier":"Android","$os_version":"8.1.0","$device":"generic_x86","$manufacturer":"Google","$model":"Android SDK built for x86","mp_device_model":"Android SDK built for x86","$wifi":true,"$bluetooth_enabled":false,"mp_lib":"com.rudderstack.android.sdk.core","$app_build_number":"1","$app_version_string":"1.0","$insert_id":"id2","token":"test_api_token","distinct_id":"userId01","time":1579847342402,"$device_id":"anonId01"}}]', }, XML: {}, FORM: {}, @@ -4714,7 +4770,7 @@ export const data = [ { description: 'Identify: skip merge event when simplified id merge api is selected', destination: overrideDestination(sampleDestination, { - token: 'apiToken123', + token: 'test_api_token', identityMergeApi: 'simplified', }), message: { @@ -4795,7 +4851,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$created":"2020-01-23T08:54:02.362Z","$email":"mickey@disney.com","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$firstName":"Mickey","$lastName":"Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"apiToken123","$distinct_id":"userId01","$ip":"0.0.0.0","$time":1579847342402}]', + '[{"$set":{"$created":"2020-01-23T08:54:02.362Z","$email":"mickey@disney.com","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$firstName":"Mickey","$lastName":"Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"userId01","$ip":"0.0.0.0","$time":1579847342402}]', }, XML: {}, FORM: {}, @@ -4823,7 +4879,7 @@ export const data = [ 'Identify: append $device: to deviceId while creating the user when simplified id merge api is selected', destination: overrideDestination(sampleDestination, { apiKey: 'apiKey123', - token: 'apiToken123', + token: 'test_api_token', identityMergeApi: 'simplified', }), message: { @@ -4903,7 +4959,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$created":"2020-01-23T08:54:02.362Z","$email":"mickey@disney.com","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$firstName":"Mickey","$lastName":"Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"apiToken123","$distinct_id":"$device:anonId01","$ip":"0.0.0.0","$time":1579847342402}]', + '[{"$set":{"$created":"2020-01-23T08:54:02.362Z","$email":"mickey@disney.com","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$firstName":"Mickey","$lastName":"Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"$device:anonId01","$ip":"0.0.0.0","$time":1579847342402}]', }, XML: {}, FORM: {}, @@ -4930,7 +4986,7 @@ export const data = [ description: 'Unsupported alias call when simplified id merge api is selected', destination: overrideDestination(sampleDestination, { apiKey: 'apiKey123', - token: 'apiToken123', + token: 'test_api_token', identityMergeApi: 'simplified', }), message: { @@ -5019,7 +5075,7 @@ export const data = [ 'Track revenue event: set device id and user id when simplified id merge api is selected', destination: overrideDestination(sampleDestination, { apiKey: 'apiKey123', - token: 'apiToken123', + token: 'test_api_token', identityMergeApi: 'simplified', }), message: { @@ -5090,7 +5146,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$append":{"$transactions":{"$time":"2020-01-24T06:29:02.403Z","$amount":18.9}},"$token":"apiToken123","$distinct_id":"userId01"}]', + '[{"$append":{"$transactions":{"$time":"2020-01-24T06:29:02.403Z","$amount":18.9}},"$token":"test_api_token","$distinct_id":"userId01"}]', }, XML: {}, FORM: {}, @@ -5105,14 +5161,17 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/track/', - headers: {}, - params: {}, + endpoint: 'https://api.mixpanel.com/import/', + headers: { + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + 'Content-Type': 'application/json', + }, + params: { strict: 0 }, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"test revenue MIXPANEL","properties":{"currency":"USD","revenue":18.9,"city":"Disney","country":"USA","email":"mickey@disney.com","firstName":"Mickey","ip":"0.0.0.0","$user_id":"userId01","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"a6a0ad5a-bd26-4f19-8f75-38484e580fc7","token":"apiToken123","distinct_id":"userId01","time":1579847342403,"$device_id":"anonId01","$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', + '[{"event":"test revenue MIXPANEL","properties":{"currency":"USD","revenue":18.9,"city":"Disney","country":"USA","email":"mickey@disney.com","firstName":"Mickey","ip":"0.0.0.0","$user_id":"userId01","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"a6a0ad5a-bd26-4f19-8f75-38484e580fc7","token":"test_api_token","distinct_id":"userId01","time":1579847342403,"$device_id":"anonId01","$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', }, XML: {}, FORM: {}, @@ -5142,7 +5201,7 @@ export const data = [ description: 'Page with anonymous user when simplified api is selected', destination: overrideDestination(sampleDestination, { apiKey: 'apiKey123', - token: 'apiToken123', + token: 'test_api_token', identityMergeApi: 'simplified', }), message: { @@ -5209,14 +5268,17 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/track/', - headers: {}, - params: {}, + endpoint: 'https://api.mixpanel.com/import/', + headers: { + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + 'Content-Type': 'application/json', + }, + params: { strict: 0 }, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"Loaded a Page","properties":{"ip":"0.0.0.0","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"dd266c67-9199-4a52-ba32-f46ddde67312","token":"apiToken123","distinct_id":"$device:anonId01","time":1579847342402,"$device_id":"anonId01","name":"Contact Us","$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', + '[{"event":"Loaded a Page","properties":{"ip":"0.0.0.0","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"dd266c67-9199-4a52-ba32-f46ddde67312","token":"test_api_token","distinct_id":"$device:anonId01","time":1579847342402,"$device_id":"anonId01","name":"Contact Us","$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', }, XML: {}, FORM: {}, @@ -5246,7 +5308,7 @@ export const data = [ description: 'Group call with anonymous user when simplified api is selected', destination: overrideDestination(sampleDestination, { apiKey: 'apiKey123', - token: 'apiToken123', + token: 'test_api_token', identityMergeApi: 'simplified', groupKeySettings: [{ groupKey: 'company' }], }), @@ -5309,7 +5371,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$token":"apiToken123","$distinct_id":"$device:anonId01","$set":{"company":["testComp"]},"$ip":"0.0.0.0"}]', + '[{"$token":"test_api_token","$distinct_id":"$device:anonId01","$set":{"company":["testComp"]},"$ip":"0.0.0.0"}]', }, XML: {}, FORM: {}, @@ -5331,7 +5393,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$token":"apiToken123","$group_key":"company","$group_id":"testComp","$set":{"company":"testComp"}}]', + '[{"$token":"test_api_token","$group_key":"company","$group_id":"testComp","$set":{"company":"testComp"}}]', }, XML: {}, FORM: {}, @@ -5357,7 +5419,7 @@ export const data = [ { destination: overrideDestination(sampleDestination, { apiKey: 'apiKey123', - token: 'apiToken123', + token: 'test_api_token', identityMergeApi: 'simplified', groupKeySettings: [{ groupKey: 'company' }], }), @@ -5476,7 +5538,7 @@ export const data = [ }, destination: overrideDestination(sampleDestination, { apiKey: 'dummyApiKey', - token: 'dummyApiKey', + token: 'test_api_token', apiSecret: 'dummyApiKey', useNewMapping: true, }), @@ -5502,7 +5564,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$append":{"$transactions":{"$time":"2022-09-05T07:46:20.290Z","$amount":12.13}},"$token":"dummyApiKey","$distinct_id":"39da706ec83d0e90"}]', + '[{"$append":{"$transactions":{"$time":"2022-09-05T07:46:20.290Z","$amount":12.13}},"$token":"test_api_token","$distinct_id":"39da706ec83d0e90"}]', }, XML: {}, FORM: {}, @@ -5519,7 +5581,7 @@ export const data = [ method: 'POST', endpoint: 'https://api.mixpanel.com/import/', headers: { - Authorization: 'Basic ZHVtbXlBcGlLZXk6', + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', 'Content-Type': 'application/json', }, params: { strict: 0 }, @@ -5527,7 +5589,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"event":"Application Installed","properties":{"build":4,"version":"1.0","revenue":12.13,"anonymousId":"39da706ec83d0e90","$os":"Android","$screen_height":2984,"$screen_width":1440,"$screen_dpi":560,"$carrier":"T-Mobile","$os_version":"12","$device":"emu64a","$manufacturer":"Google","$model":"sdk_gphone64_arm64","mp_device_model":"sdk_gphone64_arm64","$wifi":true,"$bluetooth_enabled":true,"mp_lib":"com.rudderstack.android.sdk.core","$app_build_number":"4","$app_version_string":"1.0","$insert_id":"168cf720-6227-4b56-a98e-c49bdc7279e9","$session_id":"1662363980","token":"dummyApiKey","distinct_id":"39da706ec83d0e90","time":1662363980290}}]', + '[{"event":"Application Installed","properties":{"build":4,"version":"1.0","revenue":12.13,"anonymousId":"39da706ec83d0e90","$os":"Android","$screen_height":2984,"$screen_width":1440,"$screen_dpi":560,"$carrier":"T-Mobile","$os_version":"12","$device":"emu64a","$manufacturer":"Google","$model":"sdk_gphone64_arm64","mp_device_model":"sdk_gphone64_arm64","$wifi":true,"$bluetooth_enabled":true,"mp_lib":"com.rudderstack.android.sdk.core","$app_build_number":"4","$app_version_string":"1.0","$insert_id":"168cf720-6227-4b56-a98e-c49bdc7279e9","$session_id":"1662363980","token":"test_api_token","distinct_id":"39da706ec83d0e90","time":1662363980290}}]', }, XML: {}, FORM: {}, @@ -5591,7 +5653,7 @@ export const data = [ }, destination: overrideDestination(sampleDestination, { apiKey: 'dummyApiKey', - token: 'dummyApiKey', + token: 'test_api_token', apiSecret: 'dummyApiKey', useNewMapping: true, }), @@ -5617,7 +5679,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$append":{"$transactions":{"$time":"2022-09-05T07:46:20.290Z","$amount":23.45}},"$token":"dummyApiKey","$distinct_id":"39da706ec83d0e90"}]', + '[{"$append":{"$transactions":{"$time":"2022-09-05T07:46:20.290Z","$amount":23.45}},"$token":"test_api_token","$distinct_id":"39da706ec83d0e90"}]', }, XML: {}, FORM: {}, @@ -5634,7 +5696,7 @@ export const data = [ method: 'POST', endpoint: 'https://api.mixpanel.com/import/', headers: { - Authorization: 'Basic ZHVtbXlBcGlLZXk6', + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', 'Content-Type': 'application/json', }, params: { strict: 0 }, @@ -5642,7 +5704,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"event":"Application Installed","properties":{"build":4,"version":"1.0","revenue":23.45,"anonymousId":"39da706ec83d0e90","$os":"Android","$screen_height":2984,"$screen_width":1440,"$screen_dpi":560,"$carrier":"T-Mobile","$os_version":"12","$device":"emu64a","$manufacturer":"Google","$model":"sdk_gphone64_arm64","mp_device_model":"sdk_gphone64_arm64","$wifi":true,"$bluetooth_enabled":true,"mp_lib":"com.rudderstack.android.sdk.core","$app_build_number":"4","$app_version_string":"1.0","$insert_id":"168cf720-6227-4b56-a98e-c49bdc7279e9","$session_id":"1662363980","token":"dummyApiKey","distinct_id":"39da706ec83d0e90","time":null}}]', + '[{"event":"Application Installed","properties":{"build":4,"version":"1.0","revenue":23.45,"anonymousId":"39da706ec83d0e90","$os":"Android","$screen_height":2984,"$screen_width":1440,"$screen_dpi":560,"$carrier":"T-Mobile","$os_version":"12","$device":"emu64a","$manufacturer":"Google","$model":"sdk_gphone64_arm64","mp_device_model":"sdk_gphone64_arm64","$wifi":true,"$bluetooth_enabled":true,"mp_lib":"com.rudderstack.android.sdk.core","$app_build_number":"4","$app_version_string":"1.0","$insert_id":"168cf720-6227-4b56-a98e-c49bdc7279e9","$session_id":"1662363980","token":"test_api_token","distinct_id":"39da706ec83d0e90","time":null}}]', }, XML: {}, FORM: {}, @@ -5669,7 +5731,7 @@ export const data = [ description: 'Track: with strict mode enabled', destination: overrideDestination(sampleDestination, { apiKey: 'dummyApiKey', - token: 'dummyApiKey', + token: 'test_api_token', apiSecret: 'some_api_secret', dataResidency: 'eu', strictMode: true, @@ -5733,7 +5795,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$carrier":"Android","$manufacturer":"Google","$model":"Android SDK built for x86","$screen_height":1794,"$screen_width":1080,"$wifi":true,"anonymousId":"5094f5704b9cf2b3","userId":"test_user_id","$ios_devices":["test_device_token"],"$os":"iOS","$ios_device_model":"Android SDK built for x86","$ios_version":"8.1.0","$ios_app_release":"1","$ios_app_version":"1.0"},"$token":"dummyApiKey","$distinct_id":"test_user_id","$time":1584003903421}]', + '[{"$set":{"$carrier":"Android","$manufacturer":"Google","$model":"Android SDK built for x86","$screen_height":1794,"$screen_width":1080,"$wifi":true,"anonymousId":"5094f5704b9cf2b3","userId":"test_user_id","$ios_devices":["test_device_token"],"$os":"iOS","$ios_device_model":"Android SDK built for x86","$ios_version":"8.1.0","$ios_app_release":"1","$ios_app_version":"1.0"},"$token":"test_api_token","$distinct_id":"test_user_id","$time":1584003903421}]', }, XML: {}, FORM: {}, @@ -5750,7 +5812,7 @@ export const data = [ method: 'POST', endpoint: 'https://api-eu.mixpanel.com/import/', headers: { - Authorization: 'Basic c29tZV9hcGlfc2VjcmV0Og==', + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', 'Content-Type': 'application/json', }, params: { strict: 1 }, @@ -5758,7 +5820,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"event":"$merge","properties":{"$distinct_ids":["test_user_id","5094f5704b9cf2b3"],"token":"dummyApiKey"}}]', + '[{"event":"$merge","properties":{"$distinct_ids":["test_user_id","5094f5704b9cf2b3"],"token":"test_api_token"}}]', }, XML: {}, FORM: {}, diff --git a/test/integrations/destinations/mp/router/data.ts b/test/integrations/destinations/mp/router/data.ts index 059e222e92..8716c9daa0 100644 --- a/test/integrations/destinations/mp/router/data.ts +++ b/test/integrations/destinations/mp/router/data.ts @@ -442,7 +442,7 @@ export const data = [ endpoint: 'https://api.mixpanel.com/import/', headers: { 'Content-Type': 'application/json', - Authorization: 'Basic dGVzdF9hcGlfc2VjcmV0Og==', + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', }, params: { strict: 1 }, body: { @@ -509,7 +509,7 @@ export const data = [ endpoint: 'https://api.mixpanel.com/import/', headers: { 'Content-Type': 'application/json', - Authorization: 'Basic dGVzdF9hcGlfc2VjcmV0Og==', + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', }, params: { strict: 1 }, body: { @@ -577,7 +577,7 @@ export const data = [ endpoint: 'https://api.mixpanel.com/import/', headers: { 'Content-Type': 'application/json', - Authorization: 'Basic dGVzdF9hcGlfc2VjcmV0Og==', + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', }, params: { strict: 1 }, body: { @@ -1166,7 +1166,7 @@ export const data = [ endpoint: 'https://api.mixpanel.com/import/', headers: { 'Content-Type': 'application/json', - Authorization: 'Basic dGVzdF9hcGlfc2VjcmV0Og==', + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', }, params: { strict: 1 }, body: { @@ -1232,7 +1232,7 @@ export const data = [ endpoint: 'https://api.mixpanel.com/import/', headers: { 'Content-Type': 'application/json', - Authorization: 'Basic dGVzdF9hcGlfc2VjcmV0Og==', + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', }, params: { strict: 1 }, body: { @@ -1299,7 +1299,7 @@ export const data = [ endpoint: 'https://api.mixpanel.com/import/', headers: { 'Content-Type': 'application/json', - Authorization: 'Basic dGVzdF9hcGlfc2VjcmV0Og==', + Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', }, params: { strict: 1 }, body: { From 0b5720446693efe1fd0ccdfc141bd7f21b2c32ae Mon Sep 17 00:00:00 2001 From: Anant Jain <62471433+anantjain45823@users.noreply.github.com> Date: Mon, 15 Apr 2024 13:57:09 +0530 Subject: [PATCH 31/47] fix: hubspot: search for contact using secondary prop (#3258) * fix: hubspot: search for contact using secondary prop * chore: include network.ts file * chore: address comments --- src/v0/destinations/hs/HSTransform-v2.js | 4 +- src/v0/destinations/hs/config.js | 4 + src/v0/destinations/hs/util.js | 113 ++++++++++++-- src/v0/destinations/hs/util.test.js | 14 +- test/integrations/destinations/hs/network.ts | 31 ++++ .../destinations/hs/router/data.ts | 141 ++++++++++++++++++ 6 files changed, 288 insertions(+), 19 deletions(-) diff --git a/src/v0/destinations/hs/HSTransform-v2.js b/src/v0/destinations/hs/HSTransform-v2.js index 2acdd82152..3699e1c789 100644 --- a/src/v0/destinations/hs/HSTransform-v2.js +++ b/src/v0/destinations/hs/HSTransform-v2.js @@ -12,7 +12,6 @@ const { defaultPatchRequestConfig, getFieldValueFromMessage, getSuccessRespEvents, - addExternalIdToTraits, defaultBatchRequestConfig, removeUndefinedAndNullValues, getDestinationExternalID, @@ -42,6 +41,7 @@ const { getEventAndPropertiesFromConfig, getHsSearchId, populateTraits, + addExternalIdToHSTraits, } = require('./util'); const { JSON_MIME_TYPE } = require('../../util/constant'); @@ -110,7 +110,7 @@ const processIdentify = async (message, destination, propertyMap) => { GENERIC_TRUE_VALUES.includes(mappedToDestination.toString()) && operation ) { - addExternalIdToTraits(message); + addExternalIdToHSTraits(message); if (!objectType) { throw new InstrumentationError('objectType not found'); } diff --git a/src/v0/destinations/hs/config.js b/src/v0/destinations/hs/config.js index fb9790f0e5..67ad3b5bed 100644 --- a/src/v0/destinations/hs/config.js +++ b/src/v0/destinations/hs/config.js @@ -84,6 +84,9 @@ const RETL_SOURCE = 'rETL'; const mappingConfig = getMappingConfig(ConfigCategory, __dirname); const hsCommonConfigJson = mappingConfig[ConfigCategory.COMMON.name]; +const primaryToSecondaryFields = { + email: 'hs_additional_emails', +}; module.exports = { BASE_ENDPOINT, CONTACT_PROPERTY_MAP_ENDPOINT, @@ -112,5 +115,6 @@ module.exports = { RETL_SOURCE, RETL_CREATE_ASSOCIATION_OPERATION, MAX_CONTACTS_PER_REQUEST, + primaryToSecondaryFields, DESTINATION: 'HS', }; diff --git a/src/v0/destinations/hs/util.js b/src/v0/destinations/hs/util.js index 838da08b3b..ffb2df5237 100644 --- a/src/v0/destinations/hs/util.js +++ b/src/v0/destinations/hs/util.js @@ -1,5 +1,6 @@ /* eslint-disable no-await-in-loop */ const lodash = require('lodash'); +const set = require('set-value'); const get = require('get-value'); const { NetworkInstrumentationError, @@ -28,6 +29,7 @@ const { IDENTIFY_CRM_SEARCH_ALL_OBJECTS, SEARCH_LIMIT_VALUE, hsCommonConfigJson, + primaryToSecondaryFields, DESTINATION, MAX_CONTACTS_PER_REQUEST, } = require('./config'); @@ -576,16 +578,30 @@ const performHubSpotSearch = async ( checkAfter = after; // assigning to the new value if no after we assign it to 0 and no more calls will take place const results = processedResponse.response?.results; + const extraProp = primaryToSecondaryFields[identifierType]; if (results) { searchResults.push( - ...results.map((result) => ({ - id: result.id, - property: result.properties[identifierType], - })), + ...results.map((result) => { + const contact = { + id: result.id, + property: result.properties[identifierType], + }; + // Following maps the extra property to the contact object which + // help us to know if the contact was found using secondary property + if (extraProp) { + contact[extraProp] = result.properties?.[extraProp]; + } + return contact; + }), ); } } - + /* + searchResults = { + id: 'existing_contact_id', + property: 'existing_contact_email', // when email is identifier + hs_additional_emails: ['secondary_email'] // when email is identifier + } */ return searchResults; }; @@ -612,7 +628,25 @@ const getRequestData = (identifierType, chunk) => { limit: SEARCH_LIMIT_VALUE, after: 0, }; - + /* In case of email as identifier we add a filter for hs_additional_emails field + * and append hs_additional_emails to properties list + * We are doing this because there might be emails exisitng as hs_additional_emails for some conatct but + * will not come up in search API until we search with hs_additional_emails as well. + * Not doing this resulted in erro 409 Duplicate records found + */ + const secondaryProp = primaryToSecondaryFields[identifierType]; + if (secondaryProp) { + requestData.filterGroups.push({ + filters: [ + { + propertyName: secondaryProp, + values: chunk, + operator: 'IN', + }, + ], + }); + requestData.properties.push(secondaryProp); + } return requestData; }; @@ -623,7 +657,7 @@ const getRequestData = (identifierType, chunk) => { */ const getExistingContactsData = async (inputs, destination) => { const { Config } = destination; - const updateHubspotIds = []; + const hsIdsToBeUpdated = []; const firstMessage = inputs[0].message; if (!firstMessage) { @@ -651,13 +685,19 @@ const getExistingContactsData = async (inputs, destination) => { destination, ); if (searchResults.length > 0) { - updateHubspotIds.push(...searchResults); + hsIdsToBeUpdated.push(...searchResults); } } - return updateHubspotIds; + return hsIdsToBeUpdated; }; - -const setHsSearchId = (input, id) => { +/** + * This functions sets HsSearchId in the externalId array + * @param {*} input -> Input message + * @param {*} id -> Id to be added + * @param {*} useSecondaryProp -> Let us know if that id was found using secondary property and not primnary + * @returns + */ +const setHsSearchId = (input, id, useSecondaryProp = false) => { const { message } = input; const resultExternalId = []; const externalIdArray = message.context?.externalId; @@ -668,6 +708,11 @@ const setHsSearchId = (input, id) => { if (type.includes(DESTINATION)) { extIdObjParam.hsSearchId = id; } + if (useSecondaryProp) { + // we are using it so that when final payload is made + // then primary key shouldn't be overidden + extIdObjParam.useSecondaryObject = useSecondaryProp; + } resultExternalId.push(extIdObjParam); }); } @@ -680,20 +725,24 @@ const setHsSearchId = (input, id) => { * We do search for all the objects before router transform and assign the type (create/update) * accordingly to context.hubspotOperation * + * For email as primary key we use `hs_additional_emails` as well property to search existing contacts * */ const splitEventsForCreateUpdate = async (inputs, destination) => { // get all the id and properties of already existing objects needed for update. - const updateHubspotIds = await getExistingContactsData(inputs, destination); + const hsIdsToBeUpdated = await getExistingContactsData(inputs, destination); const resultInput = inputs.map((input) => { const { message } = input; const inputParam = input; - const { destinationExternalId } = getDestinationExternalIDInfoForRetl(message, DESTINATION); + const { destinationExternalId, identifierType } = getDestinationExternalIDInfoForRetl( + message, + DESTINATION, + ); - const filteredInfo = updateHubspotIds.filter( + const filteredInfo = hsIdsToBeUpdated.filter( (update) => - update.property.toString().toLowerCase() === destinationExternalId.toString().toLowerCase(), + update.property.toString().toLowerCase() === destinationExternalId.toString().toLowerCase(), // second condition is for secondary property for identifier type ); if (filteredInfo.length > 0) { @@ -701,6 +750,26 @@ const splitEventsForCreateUpdate = async (inputs, destination) => { inputParam.message.context.hubspotOperation = 'updateObject'; return inputParam; } + const secondaryProp = primaryToSecondaryFields[identifierType]; + if (secondaryProp) { + // second condition is for secondary property for identifier type + const filteredInfoForSecondaryProp = hsIdsToBeUpdated.filter((update) => + update[secondaryProp] + ?.toString() + .toLowerCase() + .includes(destinationExternalId.toString().toLowerCase()), + ); + if (filteredInfoForSecondaryProp.length > 0) { + inputParam.message.context.externalId = setHsSearchId( + input, + filteredInfoForSecondaryProp[0].id, + true, + ); + inputParam.message.context.hubspotOperation = 'updateObject'; + return inputParam; + } + } + // if not found in the existing contacts, then it's a new contact inputParam.message.context.hubspotOperation = 'createObject'; return inputParam; }); @@ -748,8 +817,22 @@ const populateTraits = async (propertyMap, traits, destination) => { return populatedTraits; }; +const addExternalIdToHSTraits = (message) => { + const externalIdObj = message.context?.externalId?.[0]; + if (externalIdObj.useSecondaryObject) { + /* this condition help us to NOT override the primary key value with the secondary key value + example: + for `email` as primary key and `hs_additonal_emails` as secondary key we don't want to override `email` with `hs_additional_emails`. + neither we want to map anything for `hs_additional_emails` as this property can not be set + */ + return; + } + set(getFieldValueFromMessage(message, 'traits'), externalIdObj.identifierType, externalIdObj.id); +}; + module.exports = { validateDestinationConfig, + addExternalIdToHSTraits, formatKey, fetchFinalSetOfTraits, getProperties, diff --git a/src/v0/destinations/hs/util.test.js b/src/v0/destinations/hs/util.test.js index 30e89d3aee..ea2e10dc3d 100644 --- a/src/v0/destinations/hs/util.test.js +++ b/src/v0/destinations/hs/util.test.js @@ -4,6 +4,7 @@ const { validatePayloadDataTypes, getObjectAndIdentifierType, } = require('./util'); +const { primaryToSecondaryFields } = require('./config'); const propertyMap = { firstName: 'string', @@ -205,7 +206,7 @@ describe('extractUniqueValues utility test cases', () => { describe('getRequestDataAndRequestOptions utility test cases', () => { it('Should return an object with requestData and requestOptions', () => { const identifierType = 'email'; - const chunk = 'test1@gmail.com'; + const chunk = ['test1@gmail.com']; const accessToken = 'dummyAccessToken'; const expectedRequestData = { @@ -219,8 +220,17 @@ describe('getRequestDataAndRequestOptions utility test cases', () => { }, ], }, + { + filters: [ + { + propertyName: primaryToSecondaryFields[identifierType], + values: chunk, + operator: 'IN', + }, + ], + }, ], - properties: [identifierType], + properties: [identifierType, primaryToSecondaryFields[identifierType]], limit: 100, after: 0, }; diff --git a/test/integrations/destinations/hs/network.ts b/test/integrations/destinations/hs/network.ts index e29cc27562..3d3b8fd83f 100644 --- a/test/integrations/destinations/hs/network.ts +++ b/test/integrations/destinations/hs/network.ts @@ -460,6 +460,37 @@ export const networkCallsData = [ status: 200, }, }, + { + httpReq: { + url: 'https://api.hubapi.com/crm/v3/objects/contacts/search', + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: 'Bearer dummy-access-token-hs-additonal-email', + }, + }, + httpRes: { + data: { + total: 1, + results: [ + { + id: '103689', + properties: { + createdate: '2022-07-15T15:25:08.975Z', + email: 'primary@email.com', + hs_object_id: '103604', + hs_additional_emails: 'abc@extraemail.com;secondary@email.com', + lastmodifieddate: '2022-07-15T15:26:49.590Z', + }, + createdAt: '2022-07-15T15:25:08.975Z', + updatedAt: '2022-07-15T15:26:49.590Z', + archived: false, + }, + ], + }, + status: 200, + }, + }, { httpReq: { url: 'https://api.hubapi.com/crm/v3/objects/contacts/search', diff --git a/test/integrations/destinations/hs/router/data.ts b/test/integrations/destinations/hs/router/data.ts index 3a30232f9f..e1c3e04356 100644 --- a/test/integrations/destinations/hs/router/data.ts +++ b/test/integrations/destinations/hs/router/data.ts @@ -1688,4 +1688,145 @@ export const data = [ }, }, }, + { + name: 'hs', + description: 'getting duplicate records for secondary property', + feature: 'router', + module: 'destination', + version: 'v0', + scenario: 'buisness', + successCriteria: + 'should return 200 status code with contact needs to be updated and no email property', + input: { + request: { + body: { + input: [ + { + message: { + type: 'identify', + sentAt: '2024-03-19T18:46:36.348Z', + traits: { + lastname: 'Peñarete', + firstname: 'Karen', + }, + userId: 'secondary@email.com', + channel: 'sources', + context: { + externalId: [ + { + id: 'secondary@email.com', + type: 'HS-contacts', + identifierType: 'email', + }, + ], + mappedToDestination: 'true', + }, + originalTimestamp: '2024-03-19T18:46:36.348Z', + }, + metadata: { jobId: 3, userId: 'u1' }, + destination: { + Config: { + authorizationType: 'newPrivateAppApi', + accessToken: 'dummy-access-token-hs-additonal-email', + hubID: 'dummy-hubId', + apiKey: 'dummy-apikey', + apiVersion: 'newApi', + lookupField: 'email', + hubspotEvents: [], + }, + secretConfig: {}, + ID: '1mMy5cqbtfuaKZv1IhVQKnBdVwe', + name: 'Hubspot', + enabled: true, + workspaceId: '1TSN08muJTZwH8iCDmnnRt1pmLd', + deleted: false, + createdAt: '2020-12-30T08:39:32.005Z', + updatedAt: '2021-02-03T16:22:31.374Z', + destinationDefinition: { + id: '1aIXqM806xAVm92nx07YwKbRrO9', + name: 'HS', + displayName: 'Hubspot', + createdAt: '2020-04-09T09:24:31.794Z', + updatedAt: '2021-01-11T11:03:28.103Z', + }, + transformations: [], + isConnectionEnabled: true, + isProcessorEnabled: true, + }, + }, + ], + destType: 'hs', + }, + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: [ + { + batchedRequest: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'https://api.hubapi.com/crm/v3/objects/contacts/batch/update', + headers: { + 'Content-Type': 'application/json', + Authorization: 'Bearer dummy-access-token-hs-additonal-email', + }, + params: {}, + body: { + JSON: { + inputs: [ + { + properties: { lastname: 'Peñarete', firstname: 'Karen' }, + id: '103689', + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + FORM: {}, + }, + files: {}, + }, + metadata: [{ jobId: 3, userId: 'u1' }], + batched: true, + statusCode: 200, + destination: { + Config: { + authorizationType: 'newPrivateAppApi', + accessToken: 'dummy-access-token-hs-additonal-email', + hubID: 'dummy-hubId', + apiKey: 'dummy-apikey', + apiVersion: 'newApi', + lookupField: 'email', + hubspotEvents: [], + }, + secretConfig: {}, + ID: '1mMy5cqbtfuaKZv1IhVQKnBdVwe', + name: 'Hubspot', + enabled: true, + workspaceId: '1TSN08muJTZwH8iCDmnnRt1pmLd', + deleted: false, + createdAt: '2020-12-30T08:39:32.005Z', + updatedAt: '2021-02-03T16:22:31.374Z', + destinationDefinition: { + id: '1aIXqM806xAVm92nx07YwKbRrO9', + name: 'HS', + displayName: 'Hubspot', + createdAt: '2020-04-09T09:24:31.794Z', + updatedAt: '2021-01-11T11:03:28.103Z', + }, + transformations: [], + isConnectionEnabled: true, + isProcessorEnabled: true, + }, + }, + ], + }, + }, + }, + }, ]; From a0d4ca82f67ed3a8f73c539c96f678e9af748ad2 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Mon, 15 Apr 2024 09:03:08 +0000 Subject: [PATCH 32/47] chore(release): 1.62.0 --- CHANGELOG.md | 37 +++++++++++++++++++++++++++++++++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1670fa232d..27b65204f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,43 @@ 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.62.0](https://github.com/rudderlabs/rudder-transformer/compare/v1.60.0...v1.62.0) (2024-04-15) + + +### Features + +* adding product level tracking for awin ([#3246](https://github.com/rudderlabs/rudder-transformer/issues/3246)) ([48cf9f2](https://github.com/rudderlabs/rudder-transformer/commit/48cf9f282b803382dd2961b4b834d08a06eaab63)) +* consent field support for ga4 ([#3213](https://github.com/rudderlabs/rudder-transformer/issues/3213)) ([92515a5](https://github.com/rudderlabs/rudder-transformer/commit/92515a5fd8a2798c48010078f62b360ec6a49979)) +* consent field support for gaoc for API v15 and upgrade the api version from v14 to v16 ([#3121](https://github.com/rudderlabs/rudder-transformer/issues/3121)) ([2aac2a6](https://github.com/rudderlabs/rudder-transformer/commit/2aac2a62547b7a7c617735fc3d6e88e0a1bed76e)), closes [#3190](https://github.com/rudderlabs/rudder-transformer/issues/3190) +* do away myaxios ([#3222](https://github.com/rudderlabs/rudder-transformer/issues/3222)) ([9214594](https://github.com/rudderlabs/rudder-transformer/commit/9214594bab2c86a4ae6f75e12531f778490cf127)) +* for reddit adding currency and value for addToCart, viewConent event as well ([#3239](https://github.com/rudderlabs/rudder-transformer/issues/3239)) ([ad235e7](https://github.com/rudderlabs/rudder-transformer/commit/ad235e785bf6039e11231a915be098130b25ec3b)) +* logger upgrade in services, dest, source ([#3228](https://github.com/rudderlabs/rudder-transformer/issues/3228)) ([c204113](https://github.com/rudderlabs/rudder-transformer/commit/c204113eab37a782f217488d0d626a8d6df345d3)) +* onboard new destination bloomreach ([#3185](https://github.com/rudderlabs/rudder-transformer/issues/3185)) ([d9b7e1f](https://github.com/rudderlabs/rudder-transformer/commit/d9b7e1f70565d59979aee3e62f60e39edb9a23c7)) +* onboarding linkedin conversion api ([#3194](https://github.com/rudderlabs/rudder-transformer/issues/3194)) ([eb7b197](https://github.com/rudderlabs/rudder-transformer/commit/eb7b197322c617b14c2579de8cb4d4dacf8e1df3)) +* rakuten: adding a default value for tr ([#3240](https://github.com/rudderlabs/rudder-transformer/issues/3240)) ([3748f24](https://github.com/rudderlabs/rudder-transformer/commit/3748f24e21634fc74c5e5b3761551c64c8e69942)) +* snapchat conversion: add event level_complete ([7370191](https://github.com/rudderlabs/rudder-transformer/commit/73701915b8e24b0a00afc48ddef7c687ecf02055)) +* update movable ink batch size ([#3223](https://github.com/rudderlabs/rudder-transformer/issues/3223)) ([667095f](https://github.com/rudderlabs/rudder-transformer/commit/667095fa8316cd95a066f15b848ad503c6b4af80)) + + +### Bug Fixes + +* adding check for reserved key words in extract custom fields ([#3264](https://github.com/rudderlabs/rudder-transformer/issues/3264)) ([3399c47](https://github.com/rudderlabs/rudder-transformer/commit/3399c47fdce1b3d19e29306ca3c5692a2fbc30fb)) +* deployment file paths ([#3216](https://github.com/rudderlabs/rudder-transformer/issues/3216)) ([808727d](https://github.com/rudderlabs/rudder-transformer/commit/808727de17e400ed102a843ab3b30f81f8900f24)) +* email mappings ([5d654b3](https://github.com/rudderlabs/rudder-transformer/commit/5d654b326b8a2e39413f9541da541ab86b2a56fa)) +* email mappings ([#3247](https://github.com/rudderlabs/rudder-transformer/issues/3247)) ([791cbf5](https://github.com/rudderlabs/rudder-transformer/commit/791cbf55fc6940af4e3208212b82c891c6618fc3)) +* fixed userId mapping, now mapping to uid instead of id ([#3192](https://github.com/rudderlabs/rudder-transformer/issues/3192)) ([70a468b](https://github.com/rudderlabs/rudder-transformer/commit/70a468bf16ecd5ee0b6fecee4b837895d19c525f)) +* fixed userId mapping, now mapping to uid instead of id ([#3262](https://github.com/rudderlabs/rudder-transformer/issues/3262)) ([9c6b251](https://github.com/rudderlabs/rudder-transformer/commit/9c6b251a6c784cc391f27e846a008fbe2901e2c8)) +* hs bugsnag error ([#3252](https://github.com/rudderlabs/rudder-transformer/issues/3252)) ([9daf1c9](https://github.com/rudderlabs/rudder-transformer/commit/9daf1c989258bd410d5780c1b11c4f6df9654af5)) +* hubspot: search for contact using secondary prop ([#3258](https://github.com/rudderlabs/rudder-transformer/issues/3258)) ([0b57204](https://github.com/rudderlabs/rudder-transformer/commit/0b5720446693efe1fd0ccdfc141bd7f21b2c32ae)) +* impact: support custom product mapping ([#3249](https://github.com/rudderlabs/rudder-transformer/issues/3249)) ([cb8ff2f](https://github.com/rudderlabs/rudder-transformer/commit/cb8ff2fb943c49df4ac083bd179d9674b40eb602)) +* marketo bulk ignore null while checking data type mismatch ([#3263](https://github.com/rudderlabs/rudder-transformer/issues/3263)) ([6e3274b](https://github.com/rudderlabs/rudder-transformer/commit/6e3274bfba9e7838d1f81d845a070427b67e75f5)) +* merge conflict with main ([#3233](https://github.com/rudderlabs/rudder-transformer/issues/3233)) ([042dd6d](https://github.com/rudderlabs/rudder-transformer/commit/042dd6d16236dede8126984ea590fa167d4a4a87)), closes [#3216](https://github.com/rudderlabs/rudder-transformer/issues/3216) +* ninetailed: remove page support ([#3218](https://github.com/rudderlabs/rudder-transformer/issues/3218)) ([2f30c56](https://github.com/rudderlabs/rudder-transformer/commit/2f30c56af62e983d09b5d4f2da9a0ba22f5c1612)) +* shopify invalid_event metric prometheus label ([#3200](https://github.com/rudderlabs/rudder-transformer/issues/3200)) ([345c87d](https://github.com/rudderlabs/rudder-transformer/commit/345c87d7c530c621ae3fd6c504d64e5a14e31f22)) +* shopify: send 500 for identifier call in case of failure ([#3235](https://github.com/rudderlabs/rudder-transformer/issues/3235)) ([8eb4c4e](https://github.com/rudderlabs/rudder-transformer/commit/8eb4c4e9b8daebbaeb1d12ff0c17915fe19c2b50)) +* snapchat conversion: add event level_complete ([#3231](https://github.com/rudderlabs/rudder-transformer/issues/3231)) ([39368a0](https://github.com/rudderlabs/rudder-transformer/commit/39368a09e48acc324faa855186bc623e5c347881)) +* update correct staging deployment file ([#3189](https://github.com/rudderlabs/rudder-transformer/issues/3189)) ([ac7e887](https://github.com/rudderlabs/rudder-transformer/commit/ac7e8879fcd230dae09f757a759fb42e4cdc09d0)) + ### [1.61.1](https://github.com/rudderlabs/rudder-transformer/compare/v1.61.0...v1.61.1) (2024-04-03) ## [1.61.0](https://github.com/rudderlabs/rudder-transformer/compare/v1.60.0...v1.61.0) (2024-04-02) diff --git a/package-lock.json b/package-lock.json index fd42692109..fdfab6703c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "rudder-transformer", - "version": "1.61.1", + "version": "1.62.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "rudder-transformer", - "version": "1.61.1", + "version": "1.62.0", "license": "ISC", "dependencies": { "@amplitude/ua-parser-js": "0.7.24", diff --git a/package.json b/package.json index c839bc8acc..1343f27fbe 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rudder-transformer", - "version": "1.61.1", + "version": "1.62.0", "description": "", "homepage": "https://github.com/rudderlabs/rudder-transformer#readme", "bugs": { From 54eabc6b1c0f49bb3388e45bc27505bbd51b66c0 Mon Sep 17 00:00:00 2001 From: Anant Jain <62471433+anantjain45823@users.noreply.github.com> Date: Tue, 16 Apr 2024 12:23:31 +0530 Subject: [PATCH 33/47] fix: hubspot: hs_additional_email comparision logic (#3277) --- src/v0/destinations/hs/util.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/v0/destinations/hs/util.js b/src/v0/destinations/hs/util.js index ffb2df5237..b30207fe15 100644 --- a/src/v0/destinations/hs/util.js +++ b/src/v0/destinations/hs/util.js @@ -752,11 +752,18 @@ const splitEventsForCreateUpdate = async (inputs, destination) => { } const secondaryProp = primaryToSecondaryFields[identifierType]; if (secondaryProp) { - // second condition is for secondary property for identifier type + /* second condition is for secondary property for identifier type + For example: + update[secondaryProp] = "abc@e.com;cd@e.com;k@w.com" + destinationExternalId = "cd@e.com" + So we are splitting all the emails in update[secondaryProp] into an array using ';' + and then checking if array includes destinationExternalId + */ const filteredInfoForSecondaryProp = hsIdsToBeUpdated.filter((update) => update[secondaryProp] ?.toString() .toLowerCase() + .split(';') .includes(destinationExternalId.toString().toLowerCase()), ); if (filteredInfoForSecondaryProp.length > 0) { From 2e6f8e5d0f24b287daebbdb68f672b29ef46351b Mon Sep 17 00:00:00 2001 From: AASHISH MALIK Date: Tue, 16 Apr 2024 13:45:07 +0530 Subject: [PATCH 34/47] chore: cleaned changelog --- CHANGELOG.md | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 27b65204f0..6ec145991f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,29 +2,21 @@ 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.62.0](https://github.com/rudderlabs/rudder-transformer/compare/v1.60.0...v1.62.0) (2024-04-15) +## [1.62.0](https://github.com/rudderlabs/rudder-transformer/compare/v1.61.1...v1.62.0) (2024-04-15) ### Features -* adding product level tracking for awin ([#3246](https://github.com/rudderlabs/rudder-transformer/issues/3246)) ([48cf9f2](https://github.com/rudderlabs/rudder-transformer/commit/48cf9f282b803382dd2961b4b834d08a06eaab63)) -* consent field support for ga4 ([#3213](https://github.com/rudderlabs/rudder-transformer/issues/3213)) ([92515a5](https://github.com/rudderlabs/rudder-transformer/commit/92515a5fd8a2798c48010078f62b360ec6a49979)) -* consent field support for gaoc for API v15 and upgrade the api version from v14 to v16 ([#3121](https://github.com/rudderlabs/rudder-transformer/issues/3121)) ([2aac2a6](https://github.com/rudderlabs/rudder-transformer/commit/2aac2a62547b7a7c617735fc3d6e88e0a1bed76e)), closes [#3190](https://github.com/rudderlabs/rudder-transformer/issues/3190) * do away myaxios ([#3222](https://github.com/rudderlabs/rudder-transformer/issues/3222)) ([9214594](https://github.com/rudderlabs/rudder-transformer/commit/9214594bab2c86a4ae6f75e12531f778490cf127)) * for reddit adding currency and value for addToCart, viewConent event as well ([#3239](https://github.com/rudderlabs/rudder-transformer/issues/3239)) ([ad235e7](https://github.com/rudderlabs/rudder-transformer/commit/ad235e785bf6039e11231a915be098130b25ec3b)) * logger upgrade in services, dest, source ([#3228](https://github.com/rudderlabs/rudder-transformer/issues/3228)) ([c204113](https://github.com/rudderlabs/rudder-transformer/commit/c204113eab37a782f217488d0d626a8d6df345d3)) -* onboard new destination bloomreach ([#3185](https://github.com/rudderlabs/rudder-transformer/issues/3185)) ([d9b7e1f](https://github.com/rudderlabs/rudder-transformer/commit/d9b7e1f70565d59979aee3e62f60e39edb9a23c7)) -* onboarding linkedin conversion api ([#3194](https://github.com/rudderlabs/rudder-transformer/issues/3194)) ([eb7b197](https://github.com/rudderlabs/rudder-transformer/commit/eb7b197322c617b14c2579de8cb4d4dacf8e1df3)) * rakuten: adding a default value for tr ([#3240](https://github.com/rudderlabs/rudder-transformer/issues/3240)) ([3748f24](https://github.com/rudderlabs/rudder-transformer/commit/3748f24e21634fc74c5e5b3761551c64c8e69942)) -* snapchat conversion: add event level_complete ([7370191](https://github.com/rudderlabs/rudder-transformer/commit/73701915b8e24b0a00afc48ddef7c687ecf02055)) -* update movable ink batch size ([#3223](https://github.com/rudderlabs/rudder-transformer/issues/3223)) ([667095f](https://github.com/rudderlabs/rudder-transformer/commit/667095fa8316cd95a066f15b848ad503c6b4af80)) ### Bug Fixes * adding check for reserved key words in extract custom fields ([#3264](https://github.com/rudderlabs/rudder-transformer/issues/3264)) ([3399c47](https://github.com/rudderlabs/rudder-transformer/commit/3399c47fdce1b3d19e29306ca3c5692a2fbc30fb)) * deployment file paths ([#3216](https://github.com/rudderlabs/rudder-transformer/issues/3216)) ([808727d](https://github.com/rudderlabs/rudder-transformer/commit/808727de17e400ed102a843ab3b30f81f8900f24)) -* email mappings ([5d654b3](https://github.com/rudderlabs/rudder-transformer/commit/5d654b326b8a2e39413f9541da541ab86b2a56fa)) * email mappings ([#3247](https://github.com/rudderlabs/rudder-transformer/issues/3247)) ([791cbf5](https://github.com/rudderlabs/rudder-transformer/commit/791cbf55fc6940af4e3208212b82c891c6618fc3)) * fixed userId mapping, now mapping to uid instead of id ([#3192](https://github.com/rudderlabs/rudder-transformer/issues/3192)) ([70a468b](https://github.com/rudderlabs/rudder-transformer/commit/70a468bf16ecd5ee0b6fecee4b837895d19c525f)) * fixed userId mapping, now mapping to uid instead of id ([#3262](https://github.com/rudderlabs/rudder-transformer/issues/3262)) ([9c6b251](https://github.com/rudderlabs/rudder-transformer/commit/9c6b251a6c784cc391f27e846a008fbe2901e2c8)) @@ -32,12 +24,7 @@ All notable changes to this project will be documented in this file. See [standa * hubspot: search for contact using secondary prop ([#3258](https://github.com/rudderlabs/rudder-transformer/issues/3258)) ([0b57204](https://github.com/rudderlabs/rudder-transformer/commit/0b5720446693efe1fd0ccdfc141bd7f21b2c32ae)) * impact: support custom product mapping ([#3249](https://github.com/rudderlabs/rudder-transformer/issues/3249)) ([cb8ff2f](https://github.com/rudderlabs/rudder-transformer/commit/cb8ff2fb943c49df4ac083bd179d9674b40eb602)) * marketo bulk ignore null while checking data type mismatch ([#3263](https://github.com/rudderlabs/rudder-transformer/issues/3263)) ([6e3274b](https://github.com/rudderlabs/rudder-transformer/commit/6e3274bfba9e7838d1f81d845a070427b67e75f5)) -* merge conflict with main ([#3233](https://github.com/rudderlabs/rudder-transformer/issues/3233)) ([042dd6d](https://github.com/rudderlabs/rudder-transformer/commit/042dd6d16236dede8126984ea590fa167d4a4a87)), closes [#3216](https://github.com/rudderlabs/rudder-transformer/issues/3216) -* ninetailed: remove page support ([#3218](https://github.com/rudderlabs/rudder-transformer/issues/3218)) ([2f30c56](https://github.com/rudderlabs/rudder-transformer/commit/2f30c56af62e983d09b5d4f2da9a0ba22f5c1612)) -* shopify invalid_event metric prometheus label ([#3200](https://github.com/rudderlabs/rudder-transformer/issues/3200)) ([345c87d](https://github.com/rudderlabs/rudder-transformer/commit/345c87d7c530c621ae3fd6c504d64e5a14e31f22)) * shopify: send 500 for identifier call in case of failure ([#3235](https://github.com/rudderlabs/rudder-transformer/issues/3235)) ([8eb4c4e](https://github.com/rudderlabs/rudder-transformer/commit/8eb4c4e9b8daebbaeb1d12ff0c17915fe19c2b50)) -* snapchat conversion: add event level_complete ([#3231](https://github.com/rudderlabs/rudder-transformer/issues/3231)) ([39368a0](https://github.com/rudderlabs/rudder-transformer/commit/39368a09e48acc324faa855186bc623e5c347881)) -* update correct staging deployment file ([#3189](https://github.com/rudderlabs/rudder-transformer/issues/3189)) ([ac7e887](https://github.com/rudderlabs/rudder-transformer/commit/ac7e8879fcd230dae09f757a759fb42e4cdc09d0)) ### [1.61.1](https://github.com/rudderlabs/rudder-transformer/compare/v1.61.0...v1.61.1) (2024-04-03) From 34e861d4821fed6699b90ee6be663b02504b98fd Mon Sep 17 00:00:00 2001 From: AASHISH MALIK Date: Tue, 16 Apr 2024 14:14:48 +0530 Subject: [PATCH 35/47] chore: change log info to debug --- src/controllers/delivery.ts | 2 +- src/controllers/destination.ts | 2 +- src/v0/destinations/twitter_ads/transform.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/controllers/delivery.ts b/src/controllers/delivery.ts index 8ac7c9902a..0dc27553cb 100644 --- a/src/controllers/delivery.ts +++ b/src/controllers/delivery.ts @@ -24,7 +24,7 @@ const NON_DETERMINABLE = 'Non-determinable'; export class DeliveryController { public static async deliverToDestination(ctx: Context) { - logger.info('Native(Delivery):: Request to transformer::', ctx.request.body); + logger.debug('Native(Delivery):: Request to transformer::', ctx.request.body); let deliveryResponse: DeliveryV0Response; const requestMetadata = MiscService.getRequestMetadata(ctx); const deliveryRequest = ctx.request.body as ProxyV0Request; diff --git a/src/controllers/destination.ts b/src/controllers/destination.ts index 35606ea62e..92ef4b4c19 100644 --- a/src/controllers/destination.ts +++ b/src/controllers/destination.ts @@ -166,7 +166,7 @@ export class DestinationController { } public static batchProcess(ctx: Context) { - logger.info('Native(Process-Transform-Batch):: Requst to transformer::', ctx.request.body); + logger.debug('Native(Process-Transform-Batch):: Requst to transformer::', ctx.request.body); const startTime = new Date(); const requestMetadata = MiscService.getRequestMetadata(ctx); const routerRequest = ctx.request.body as RouterTransformationRequest; diff --git a/src/v0/destinations/twitter_ads/transform.js b/src/v0/destinations/twitter_ads/transform.js index 365663925e..328d8c4a9f 100644 --- a/src/v0/destinations/twitter_ads/transform.js +++ b/src/v0/destinations/twitter_ads/transform.js @@ -157,7 +157,7 @@ function validateRequest(message) { } function process(event, requestMetadata, logger) { - logger.info(`[TWITTER ADS]: Transforming request received with info`); + logger.debug(`[TWITTER ADS]: Transforming request received with info`); const { message, metadata, destination } = event; validateRequest(message); From f0dff674d8661eb348bb39b46376fe232ac86789 Mon Sep 17 00:00:00 2001 From: Sandeep Digumarty Date: Tue, 16 Apr 2024 14:15:48 +0530 Subject: [PATCH 36/47] chore: minor CHANGELOG.md cleanup --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ec145991f..9e221a32f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,6 @@ All notable changes to this project will be documented in this file. See [standa * adding check for reserved key words in extract custom fields ([#3264](https://github.com/rudderlabs/rudder-transformer/issues/3264)) ([3399c47](https://github.com/rudderlabs/rudder-transformer/commit/3399c47fdce1b3d19e29306ca3c5692a2fbc30fb)) * deployment file paths ([#3216](https://github.com/rudderlabs/rudder-transformer/issues/3216)) ([808727d](https://github.com/rudderlabs/rudder-transformer/commit/808727de17e400ed102a843ab3b30f81f8900f24)) * email mappings ([#3247](https://github.com/rudderlabs/rudder-transformer/issues/3247)) ([791cbf5](https://github.com/rudderlabs/rudder-transformer/commit/791cbf55fc6940af4e3208212b82c891c6618fc3)) -* fixed userId mapping, now mapping to uid instead of id ([#3192](https://github.com/rudderlabs/rudder-transformer/issues/3192)) ([70a468b](https://github.com/rudderlabs/rudder-transformer/commit/70a468bf16ecd5ee0b6fecee4b837895d19c525f)) * fixed userId mapping, now mapping to uid instead of id ([#3262](https://github.com/rudderlabs/rudder-transformer/issues/3262)) ([9c6b251](https://github.com/rudderlabs/rudder-transformer/commit/9c6b251a6c784cc391f27e846a008fbe2901e2c8)) * hs bugsnag error ([#3252](https://github.com/rudderlabs/rudder-transformer/issues/3252)) ([9daf1c9](https://github.com/rudderlabs/rudder-transformer/commit/9daf1c989258bd410d5780c1b11c4f6df9654af5)) * hubspot: search for contact using secondary prop ([#3258](https://github.com/rudderlabs/rudder-transformer/issues/3258)) ([0b57204](https://github.com/rudderlabs/rudder-transformer/commit/0b5720446693efe1fd0ccdfc141bd7f21b2c32ae)) From ec3eda85866bbba7813a8007408dac0c57c27c65 Mon Sep 17 00:00:00 2001 From: AASHISH MALIK Date: Wed, 17 Apr 2024 04:07:51 +0530 Subject: [PATCH 37/47] fix: send group_id as string in monday destination (#3278) --- src/v0/destinations/monday/util.js | 17 +++++++++-------- .../destinations/monday/processor/data.ts | 10 +++++----- .../destinations/monday/router/data.ts | 4 ++-- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/v0/destinations/monday/util.js b/src/v0/destinations/monday/util.js index 872fad42a7..0694028eb2 100644 --- a/src/v0/destinations/monday/util.js +++ b/src/v0/destinations/monday/util.js @@ -27,7 +27,7 @@ const getGroupId = (groupTitle, board) => { } }); if (groupId) { - return groupId; + return JSON.stringify(groupId); } throw new ConfigurationError(`Group ${groupTitle} doesn't exist in the board`); }; @@ -239,19 +239,20 @@ const populatePayload = (message, Config, boardDeatailsResponse) => { columnToPropertyMapping, boardDeatailsResponse.response?.data, ); + const items = [ + `board_id: ${boardId}`, + `item_name: ${JSON.stringify(message.properties?.name)}`, + `column_values: ${JSON.stringify(columnValues)}`, + ]; if (groupTitle) { if (!message.properties?.name) { throw new InstrumentationError('Item name is required to create an item'); } const groupId = getGroupId(groupTitle, boardDeatailsResponse.response?.data); - payload.query = `mutation { create_item (board_id: ${boardId}, group_id: ${groupId} item_name: ${JSON.stringify( - message.properties?.name, - )}, column_values: ${JSON.stringify(columnValues)}) {id}}`; - } else { - payload.query = `mutation { create_item (board_id: ${boardId}, item_name: ${JSON.stringify( - message.properties?.name, - )}, column_values: ${JSON.stringify(columnValues)}) {id}}`; + items.push(`group_id: ${groupId}`); } + const itemsQuery = items.join(', '); + payload.query = `mutation { create_item (${itemsQuery}) {id}}`; return payload; }; diff --git a/test/integrations/destinations/monday/processor/data.ts b/test/integrations/destinations/monday/processor/data.ts index 4e5280efcb..082ff822fd 100644 --- a/test/integrations/destinations/monday/processor/data.ts +++ b/test/integrations/destinations/monday/processor/data.ts @@ -74,7 +74,7 @@ export const data = [ FORM: {}, JSON: { query: - 'mutation { create_item (board_id: 339283933, item_name: "Task 1", column_values: "{}") {id}}', + 'mutation { create_item (board_id: 339283933, item_name: "Task 1", column_values: "{}") {id}}', }, JSON_ARRAY: {}, XML: {}, @@ -172,7 +172,7 @@ export const data = [ FORM: {}, JSON: { query: - 'mutation { create_item (board_id: 339283933, item_name: "Task 1", column_values: "{}") {id}}', + 'mutation { create_item (board_id: 339283933, item_name: "Task 1", column_values: "{}") {id}}', }, JSON_ARRAY: {}, XML: {}, @@ -716,7 +716,7 @@ export const data = [ body: { JSON: { query: - 'mutation { create_item (board_id: 339283933, item_name: "Task 1", column_values: "{\\"status\\":{\\"label\\":\\"Done\\"},\\"email\\":{\\"email\\":\\"abc@email.com\\",\\"text\\":\\"emailId\\"}}") {id}}', + 'mutation { create_item (board_id: 339283933, item_name: "Task 1", column_values: "{\\"status\\":{\\"label\\":\\"Done\\"},\\"email\\":{\\"email\\":\\"abc@email.com\\",\\"text\\":\\"emailId\\"}}") {id}}', }, JSON_ARRAY: {}, XML: {}, @@ -827,7 +827,7 @@ export const data = [ body: { JSON: { query: - 'mutation { create_item (board_id: 339283933, group_id: group_title item_name: "Task 1", column_values: "{\\"status\\":{\\"label\\":\\"Done\\"},\\"email\\":{\\"email\\":\\"abc@email.com\\",\\"text\\":\\"emailId\\"}}") {id}}', + 'mutation { create_item (board_id: 339283933, item_name: "Task 1", column_values: "{\\"status\\":{\\"label\\":\\"Done\\"},\\"email\\":{\\"email\\":\\"abc@email.com\\",\\"text\\":\\"emailId\\"}}", group_id: "group_title") {id}}', }, JSON_ARRAY: {}, XML: {}, @@ -1188,7 +1188,7 @@ export const data = [ body: { JSON: { query: - 'mutation { create_item (board_id: 339283933, group_id: group_title item_name: "Task 1", column_values: "{\\"status\\":{\\"label\\":\\"Done\\"},\\"email\\":{\\"email\\":\\"abc@email.com\\",\\"text\\":\\"emailId\\"},\\"checkbox\\":{\\"checked\\":true},\\"numbers\\":\\"45\\",\\"text\\":\\"texting\\",\\"country\\":{\\"countryName\\":\\"Unites States\\",\\"countryCode\\":\\"US\\"},\\"location\\":{\\"address\\":\\"New York\\",\\"lat\\":\\"51.23\\",\\"lng\\":\\"35.3\\"},\\"phone\\":{\\"phone\\":\\"2626277272\\",\\"countryShortName\\":\\"US\\"},\\"rating\\":3,\\"link\\":{\\"url\\":\\"demo.com\\",\\"text\\":\\"websiteLink\\"},\\"long_text\\":{\\"text\\":\\"property description\\"},\\"world_clock\\":{\\"timezone\\":\\"America/New_York\\"}}") {id}}', + 'mutation { create_item (board_id: 339283933, item_name: "Task 1", column_values: "{\\"status\\":{\\"label\\":\\"Done\\"},\\"email\\":{\\"email\\":\\"abc@email.com\\",\\"text\\":\\"emailId\\"},\\"checkbox\\":{\\"checked\\":true},\\"numbers\\":\\"45\\",\\"text\\":\\"texting\\",\\"country\\":{\\"countryName\\":\\"Unites States\\",\\"countryCode\\":\\"US\\"},\\"location\\":{\\"address\\":\\"New York\\",\\"lat\\":\\"51.23\\",\\"lng\\":\\"35.3\\"},\\"phone\\":{\\"phone\\":\\"2626277272\\",\\"countryShortName\\":\\"US\\"},\\"rating\\":3,\\"link\\":{\\"url\\":\\"demo.com\\",\\"text\\":\\"websiteLink\\"},\\"long_text\\":{\\"text\\":\\"property description\\"},\\"world_clock\\":{\\"timezone\\":\\"America/New_York\\"}}", group_id: "group_title") {id}}', }, JSON_ARRAY: {}, XML: {}, diff --git a/test/integrations/destinations/monday/router/data.ts b/test/integrations/destinations/monday/router/data.ts index 3be8b129c5..abd649d805 100644 --- a/test/integrations/destinations/monday/router/data.ts +++ b/test/integrations/destinations/monday/router/data.ts @@ -113,7 +113,7 @@ export const data = [ FORM: {}, JSON: { query: - 'mutation { create_item (board_id: 339283933, item_name: "Task 1", column_values: "{}") {id}}', + 'mutation { create_item (board_id: 339283933, item_name: "Task 1", column_values: "{}") {id}}', }, JSON_ARRAY: {}, XML: {}, @@ -159,7 +159,7 @@ export const data = [ body: { JSON: { query: - 'mutation { create_item (board_id: 339283933, group_id: group_title item_name: "Task 1", column_values: "{\\"status\\":{\\"label\\":\\"Done\\"},\\"email\\":{\\"email\\":\\"abc@email.com\\",\\"text\\":\\"emailId\\"}}") {id}}', + 'mutation { create_item (board_id: 339283933, item_name: "Task 1", column_values: "{\\"status\\":{\\"label\\":\\"Done\\"},\\"email\\":{\\"email\\":\\"abc@email.com\\",\\"text\\":\\"emailId\\"}}", group_id: "group_title") {id}}', }, JSON_ARRAY: {}, XML: {}, From 44b29caf2537b7dc0bd178aa346ca92d143e79d0 Mon Sep 17 00:00:00 2001 From: shrouti1507 <60211312+shrouti1507@users.noreply.github.com> Date: Wed, 17 Apr 2024 11:16:30 +0530 Subject: [PATCH 38/47] fix: awin product_id mapping backward compatible (#3285) --- src/v0/destinations/awin/utils.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/v0/destinations/awin/utils.js b/src/v0/destinations/awin/utils.js index be5f22474d..f0daea9b99 100644 --- a/src/v0/destinations/awin/utils.js +++ b/src/v0/destinations/awin/utils.js @@ -54,7 +54,11 @@ const trackProduct = (properties, advertiserId, commissionParts) => { productsArray.forEach((product) => { const productPayloadNew = { advertiserId, - orderReference: properties.order_id || properties.orderId, + orderReference: + properties.order_id || + properties.orderId || + properties.orderReference || + properties.order_reference, productId: product.product_id || product.productId, productName: product.name, productItemPrice: product.price, From 8592e664eb568e70a00261e275ab2faed8f6f618 Mon Sep 17 00:00:00 2001 From: shrouti1507 <60211312+shrouti1507@users.noreply.github.com> Date: Wed, 17 Apr 2024 13:39:24 +0530 Subject: [PATCH 39/47] feat: adding custom properties support to bluecore (#3282) * feat: adding custom properties support to bluecore * Update src/cdk/v2/destinations/bluecore/utils.js Co-authored-by: Sankeerth * fix: small fix --------- Co-authored-by: Sankeerth --- src/cdk/v2/destinations/bluecore/config.js | 22 ++++++++- .../destinations/bluecore/procWorkflow.yaml | 6 +-- src/cdk/v2/destinations/bluecore/utils.js | 45 ++++++++++++++++++- .../destinations/bluecore/ecommTestData.ts | 24 ++++++++-- .../destinations/bluecore/identifyTestData.ts | 13 ++++-- .../destinations/bluecore/trackTestData.ts | 39 +++++++++++++--- 6 files changed, 129 insertions(+), 20 deletions(-) diff --git a/src/cdk/v2/destinations/bluecore/config.js b/src/cdk/v2/destinations/bluecore/config.js index 9b9cde9c66..98e1bb4b23 100644 --- a/src/cdk/v2/destinations/bluecore/config.js +++ b/src/cdk/v2/destinations/bluecore/config.js @@ -1,6 +1,6 @@ const { getMappingConfig } = require('../../../../v0/util'); -const BASE_URL = 'https://api.bluecore.com/api/track/mobile/v1'; +const BASE_URL = 'https://api.bluecore.app/api/track/mobile/v1'; const CONFIG_CATEGORIES = { IDENTIFY: { @@ -46,6 +46,24 @@ const EVENT_NAME_MAPPING = [ const BLUECORE_EXCLUSION_FIELDS = ['query', 'order_id', 'total']; +const IDENTIFY_EXCLUSION_LIST = [ + 'name', + 'firstName', + 'first_name', + 'firstname', + 'lastName', + 'last_name', + 'lastname', + 'email', + 'age', + 'sex', + 'address', + 'action', + 'event', +]; + +const TRACK_EXCLUSION_LIST = [...IDENTIFY_EXCLUSION_LIST, 'query', 'order_id', 'total', 'products']; + const MAPPING_CONFIG = getMappingConfig(CONFIG_CATEGORIES, __dirname); module.exports = { CONFIG_CATEGORIES, @@ -53,4 +71,6 @@ module.exports = { EVENT_NAME_MAPPING, BASE_URL, BLUECORE_EXCLUSION_FIELDS, + IDENTIFY_EXCLUSION_LIST, + TRACK_EXCLUSION_LIST, }; diff --git a/src/cdk/v2/destinations/bluecore/procWorkflow.yaml b/src/cdk/v2/destinations/bluecore/procWorkflow.yaml index 480bced699..9828ac593c 100644 --- a/src/cdk/v2/destinations/bluecore/procWorkflow.yaml +++ b/src/cdk/v2/destinations/bluecore/procWorkflow.yaml @@ -26,7 +26,7 @@ steps: condition: $.outputs.messageType === {{$.EventType.IDENTIFY}} template: | const payload = $.constructProperties(.message); - payload.token = .destination.Config.bluecoreNamespace; + payload.properties.token = .destination.Config.bluecoreNamespace; $.verifyPayload(payload, .message); payload.event = payload.event ?? 'customer_patch'; payload.properties.distinct_id = $.populateAccurateDistinctId(payload, .message); @@ -50,7 +50,7 @@ steps: const temporaryProductArray = newPayload.properties.products ?? $.createProductForStandardEcommEvent(^.message, eventName); newPayload.properties.products = $.normalizeProductArray(temporaryProductArray); newPayload.event = eventName; - newPayload.token = ^.destination.Config.bluecoreNamespace; + newPayload.properties.token = ^.destination.Config.bluecoreNamespace; $.verifyPayload(newPayload, ^.message); $.removeUndefinedNullValuesAndEmptyObjectArray(newPayload) )[]; @@ -61,7 +61,7 @@ steps: const response = $.defaultRequestConfig(); response.body.JSON = .; response.method = "POST"; - response.endpoint = "https://api.bluecore.com/api/track/mobile/v1"; + response.endpoint = "https://api.bluecore.app/api/track/mobile/v1"; response.headers = { "Content-Type": "application/json" }; diff --git a/src/cdk/v2/destinations/bluecore/utils.js b/src/cdk/v2/destinations/bluecore/utils.js index 22ec254fe2..91eda60d0d 100644 --- a/src/cdk/v2/destinations/bluecore/utils.js +++ b/src/cdk/v2/destinations/bluecore/utils.js @@ -12,9 +12,10 @@ const { validateEventName, constructPayload, getDestinationExternalID, + extractCustomFields, } = require('../../../../v0/util'); const { CommonUtils } = require('../../../../util/common'); -const { EVENT_NAME_MAPPING } = require('./config'); +const { EVENT_NAME_MAPPING, IDENTIFY_EXCLUSION_LIST, TRACK_EXCLUSION_LIST } = require('./config'); const { EventType } = require('../../../../constants'); const { MAPPING_CONFIG, CONFIG_CATEGORIES } = require('./config'); @@ -167,6 +168,41 @@ const normalizeProductArray = (products) => { return finalProductArray; }; +const mapCustomProperties = (message) => { + let customerProperties; + const customProperties = { properties: {} }; + const messageType = message.type.toUpperCase(); + switch (messageType) { + case 'IDENTIFY': + customerProperties = extractCustomFields( + message, + {}, + ['traits', 'context.traits'], + IDENTIFY_EXCLUSION_LIST, + ); + customProperties.properties.customer = customerProperties; + break; + case 'TRACK': + customerProperties = extractCustomFields( + message, + {}, + ['traits', 'context.traits'], + IDENTIFY_EXCLUSION_LIST, + ); + customProperties.properties = extractCustomFields( + message, + {}, + ['properties'], + TRACK_EXCLUSION_LIST, + ); + customProperties.properties.customer = customerProperties; + break; + default: + break; + } + return customProperties; +}; + /** * Constructs properties based on the given message. * @@ -178,7 +214,12 @@ const constructProperties = (message) => { const commonPayload = constructPayload(message, MAPPING_CONFIG[commonCategory.name]); const category = CONFIG_CATEGORIES[message.type.toUpperCase()]; const typeSpecificPayload = constructPayload(message, MAPPING_CONFIG[category.name]); - const finalPayload = lodash.merge(commonPayload, typeSpecificPayload); + const typeSpecificCustomProperties = mapCustomProperties(message); + const finalPayload = lodash.merge( + commonPayload, + typeSpecificPayload, + typeSpecificCustomProperties, + ); return finalPayload; }; diff --git a/test/integrations/destinations/bluecore/ecommTestData.ts b/test/integrations/destinations/bluecore/ecommTestData.ts index de7584df78..19b63e7bda 100644 --- a/test/integrations/destinations/bluecore/ecommTestData.ts +++ b/test/integrations/destinations/bluecore/ecommTestData.ts @@ -73,7 +73,7 @@ const commonOutputHeaders = { 'Content-Type': 'application/json', }; -const eventEndPoint = 'https://api.bluecore.com/api/track/mobile/v1'; +const eventEndPoint = 'https://api.bluecore.app/api/track/mobile/v1'; export const ecomTestData = [ { @@ -296,7 +296,11 @@ export const ecomTestData = [ customer: { age: '22', email: 'test@rudderstack.com', + anonymousId: '9c6bd77ea9da3e68', + id: 'user@1', + phone: '9112340375', }, + product_id: '123', products: [ { id: '123', @@ -304,9 +308,11 @@ export const ecomTestData = [ property2: 'value2', }, ], + property1: 'value1', + property2: 'value2', + token: 'dummy_sandbox', }, event: 'viewed_product', - token: 'dummy_sandbox', }, userId: '', }), @@ -379,8 +385,11 @@ export const ecomTestData = [ JSON: { properties: { distinct_id: 'user@1', + product_id: '123', customer: { age: '22', + anonymousId: '9c6bd77ea9da3e68', + id: 'user@1', }, products: [ { @@ -389,9 +398,11 @@ export const ecomTestData = [ property2: 'value2', }, ], + property1: 'value1', + property2: 'value2', + token: 'dummy_sandbox', }, event: 'wishlist', - token: 'dummy_sandbox', }, userId: '', }), @@ -406,8 +417,11 @@ export const ecomTestData = [ JSON: { properties: { distinct_id: 'user@1', + product_id: '123', customer: { age: '22', + anonymousId: '9c6bd77ea9da3e68', + id: 'user@1', }, products: [ { @@ -416,9 +430,11 @@ export const ecomTestData = [ property2: 'value2', }, ], + token: 'dummy_sandbox', + property1: 'value1', + property2: 'value2', }, event: 'add_to_cart', - token: 'dummy_sandbox', }, userId: '', }), diff --git a/test/integrations/destinations/bluecore/identifyTestData.ts b/test/integrations/destinations/bluecore/identifyTestData.ts index 660e335bc6..fee27ccf0f 100644 --- a/test/integrations/destinations/bluecore/identifyTestData.ts +++ b/test/integrations/destinations/bluecore/identifyTestData.ts @@ -55,6 +55,10 @@ const commonOutputCustomerProperties = { first_name: 'Test', last_name: 'Rudderlabs', sex: 'non-binary', + anonymousId: '50be5c78-6c3f-4b60-be84-97805a316fb1', + db: '19950715', + gender: 'non-binary', + phone: '+1234589947', address: { city: 'Kolkata', state: 'WB', @@ -71,7 +75,7 @@ const anonymousId = '97c46c81-3140-456d-b2a9-690d70aaca35'; const userId = 'user@1'; const sentAt = '2021-01-03T17:02:53.195Z'; const originalTimestamp = '2021-01-03T17:02:53.193Z'; -const commonEndpoint = 'https://api.bluecore.com/api/track/mobile/v1'; +const commonEndpoint = 'https://api.bluecore.app/api/track/mobile/v1'; export const identifyData = [ { @@ -118,8 +122,8 @@ export const identifyData = [ properties: { distinct_id: 'abc@gmail.com', customer: { ...commonOutputCustomerProperties, email: 'abc@gmail.com' }, + token: 'dummy_sandbox', }, - token: 'dummy_sandbox', event: 'customer_patch', }, }), @@ -302,8 +306,9 @@ export const identifyData = [ properties: { distinct_id: 'user@1', customer: { ...commonOutputCustomerProperties, email: 'abc@gmail.com' }, + token: 'dummy_sandbox', }, - token: 'dummy_sandbox', + event: 'identify', }, }), @@ -361,8 +366,8 @@ export const identifyData = [ properties: { distinct_id: '54321', customer: { ...commonOutputCustomerProperties, email: 'abc@gmail.com' }, + token: 'dummy_sandbox', }, - token: 'dummy_sandbox', event: 'customer_patch', }, }), diff --git a/test/integrations/destinations/bluecore/trackTestData.ts b/test/integrations/destinations/bluecore/trackTestData.ts index 72d48bf93d..7474127558 100644 --- a/test/integrations/destinations/bluecore/trackTestData.ts +++ b/test/integrations/destinations/bluecore/trackTestData.ts @@ -86,7 +86,7 @@ const commonOutputHeaders = { 'Content-Type': 'application/json', }; -const eventEndPoint = 'https://api.bluecore.com/api/track/mobile/v1'; +const eventEndPoint = 'https://api.bluecore.app/api/track/mobile/v1'; export const trackTestData = [ { @@ -140,6 +140,9 @@ export const trackTestData = [ customer: { age: '22', email: 'test@rudderstack.com', + anonymousId: '9c6bd77ea9da3e68', + id: 'user@1', + phone: '9112340375', }, products: [ { @@ -155,9 +158,11 @@ export const trackTestData = [ quantity: 3, }, ], + property1: 'value1', + property2: 'value2', + token: 'dummy_sandbox', }, event: 'TestEven001', - token: 'dummy_sandbox', }, userId: '', }), @@ -216,13 +221,19 @@ export const trackTestData = [ JSON: { properties: { distinct_id: 'test@rudderstack.com', + product_id: '123', + property1: 'value1', + property2: 'value2', + token: 'dummy_sandbox', customer: { age: '22', email: 'test@rudderstack.com', + anonymousId: '9c6bd77ea9da3e68', + id: 'user@1', + phone: '9112340375', }, }, event: 'TestEven001', - token: 'dummy_sandbox', }, userId: '', }), @@ -283,11 +294,17 @@ export const trackTestData = [ distinct_id: 'test@rudderstack.com', customer: { age: '22', + anonymousId: '9c6bd77ea9da3e68', email: 'test@rudderstack.com', + id: 'user@1', + phone: '9112340375', }, + product_id: '123', + property1: 'value1', + property2: 'value2', + token: 'dummy_sandbox', }, event: 'optin', - token: 'dummy_sandbox', }, userId: '', }), @@ -346,13 +363,19 @@ export const trackTestData = [ JSON: { properties: { distinct_id: 'test@rudderstack.com', + product_id: '123', + property1: 'value1', + property2: 'value2', + token: 'dummy_sandbox', customer: { age: '22', + anonymousId: '9c6bd77ea9da3e68', + id: 'user@1', email: 'test@rudderstack.com', + phone: '9112340375', }, }, event: 'unsubscribe', - token: 'dummy_sandbox', }, userId: '', }), @@ -405,9 +428,12 @@ export const trackTestData = [ JSON: { properties: { distinct_id: '54321', + token: 'dummy_sandbox', customer: { age: '22', email: 'abc@gmail.com', + anonymousId: '9c6bd77ea9da3e68', + id: 'user@1', }, products: [ { @@ -423,9 +449,10 @@ export const trackTestData = [ quantity: 3, }, ], + property1: 'value1', + property2: 'value2', }, event: 'TestEven001', - token: 'dummy_sandbox', }, userId: '', }), From 86eaa07cf17de190e6b39c7087c1190faaaf927a Mon Sep 17 00:00:00 2001 From: devops-github-rudderstack <88187154+devops-github-rudderstack@users.noreply.github.com> Date: Thu, 18 Apr 2024 11:26:38 +0530 Subject: [PATCH 40/47] chore(release): pull hotfix-release/v1.62.1 into main (#3292) * fix: revert mixpanel deprecate /track (#3291) * chore(release): 1.62.1 --------- Co-authored-by: Gauravudia <60897972+Gauravudia@users.noreply.github.com> Co-authored-by: GitHub Actions --- CHANGELOG.md | 7 + package-lock.json | 4 +- package.json | 2 +- src/util/prometheus.js | 6 + src/v0/destinations/mp/config.js | 2 + src/v0/destinations/mp/transform.js | 70 ++-- src/v0/destinations/mp/util.js | 8 +- src/v0/destinations/mp/util.test.js | 14 + test/integrations/destinations/mp/common.ts | 2 +- .../destinations/mp/processor/data.ts | 363 ++++++++---------- .../destinations/mp/router/data.ts | 12 +- 11 files changed, 244 insertions(+), 246 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e221a32f8..5aeb88f374 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.62.1](https://github.com/rudderlabs/rudder-transformer/compare/v1.62.0...v1.62.1) (2024-04-18) + + +### Bug Fixes + +* revert mixpanel deprecate /track ([#3291](https://github.com/rudderlabs/rudder-transformer/issues/3291)) ([ec068b4](https://github.com/rudderlabs/rudder-transformer/commit/ec068b49bd4a5652a762c60a8257c883e4709d1a)) + ## [1.62.0](https://github.com/rudderlabs/rudder-transformer/compare/v1.61.1...v1.62.0) (2024-04-15) diff --git a/package-lock.json b/package-lock.json index fdfab6703c..b524ed27ff 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "rudder-transformer", - "version": "1.62.0", + "version": "1.62.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "rudder-transformer", - "version": "1.62.0", + "version": "1.62.1", "license": "ISC", "dependencies": { "@amplitude/ua-parser-js": "0.7.24", diff --git a/package.json b/package.json index 1343f27fbe..57da0144ac 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rudder-transformer", - "version": "1.62.0", + "version": "1.62.1", "description": "", "homepage": "https://github.com/rudderlabs/rudder-transformer#readme", "bugs": { diff --git a/src/util/prometheus.js b/src/util/prometheus.js index a46eae12c9..882dff9e75 100644 --- a/src/util/prometheus.js +++ b/src/util/prometheus.js @@ -587,6 +587,12 @@ class Prometheus { type: 'gauge', labelNames: ['destination_id'], }, + { + name: 'mixpanel_batch_track_pack_size', + help: 'mixpanel_batch_track_pack_size', + type: 'gauge', + labelNames: ['destination_id'], + }, { name: 'mixpanel_batch_import_pack_size', help: 'mixpanel_batch_import_pack_size', diff --git a/src/v0/destinations/mp/config.js b/src/v0/destinations/mp/config.js index 3abdf2eebb..35b40294f5 100644 --- a/src/v0/destinations/mp/config.js +++ b/src/v0/destinations/mp/config.js @@ -49,6 +49,7 @@ const MP_IDENTIFY_EXCLUSION_LIST = [ ]; const GEO_SOURCE_ALLOWED_VALUES = [null, 'reverse_geocoding']; +const TRACK_MAX_BATCH_SIZE = 50; const IMPORT_MAX_BATCH_SIZE = 2000; const ENGAGE_MAX_BATCH_SIZE = 2000; const GROUPS_MAX_BATCH_SIZE = 200; @@ -67,6 +68,7 @@ module.exports = { MP_IDENTIFY_EXCLUSION_LIST, getCreateDeletionTaskEndpoint, DISTINCT_ID_MAX_BATCH_SIZE, + TRACK_MAX_BATCH_SIZE, IMPORT_MAX_BATCH_SIZE, ENGAGE_MAX_BATCH_SIZE, GROUPS_MAX_BATCH_SIZE, diff --git a/src/v0/destinations/mp/transform.js b/src/v0/destinations/mp/transform.js index 195c42fbee..09a7862f9a 100644 --- a/src/v0/destinations/mp/transform.js +++ b/src/v0/destinations/mp/transform.js @@ -24,6 +24,7 @@ const { mappingConfig, BASE_ENDPOINT, BASE_ENDPOINT_EU, + TRACK_MAX_BATCH_SIZE, IMPORT_MAX_BATCH_SIZE, ENGAGE_MAX_BATCH_SIZE, GROUPS_MAX_BATCH_SIZE, @@ -46,19 +47,21 @@ const mPEventPropertiesConfigJson = mappingConfig[ConfigCategory.EVENT_PROPERTIE const setImportCredentials = (destConfig) => { const endpoint = destConfig.dataResidency === 'eu' ? `${BASE_ENDPOINT_EU}/import/` : `${BASE_ENDPOINT}/import/`; + const headers = { 'Content-Type': 'application/json' }; const params = { strict: destConfig.strictMode ? 1 : 0 }; - const { serviceAccountUserName, serviceAccountSecret, projectId, token } = destConfig; - let credentials; - if (token) { - credentials = `${token}:`; + const { apiSecret, serviceAccountUserName, serviceAccountSecret, projectId } = destConfig; + if (apiSecret) { + headers.Authorization = `Basic ${base64Convertor(`${apiSecret}:`)}`; } else if (serviceAccountUserName && serviceAccountSecret && projectId) { - credentials = `${serviceAccountUserName}:${serviceAccountSecret}`; + headers.Authorization = `Basic ${base64Convertor( + `${serviceAccountUserName}:${serviceAccountSecret}`, + )}`; params.projectId = projectId; + } else { + throw new InstrumentationError( + 'Event timestamp is older than 5 days and no API secret or service account credentials (i.e. username, secret and projectId) are provided in destination configuration', + ); } - const headers = { - 'Content-Type': 'application/json', - Authorization: `Basic ${base64Convertor(credentials)}`, - }; return { endpoint, headers, params }; }; @@ -67,26 +70,37 @@ const responseBuilderSimple = (payload, message, eventType, destConfig) => { response.method = defaultPostRequestConfig.requestMethod; response.userId = message.userId || message.anonymousId; response.body.JSON_ARRAY = { batch: JSON.stringify([removeUndefinedValues(payload)]) }; - const { dataResidency } = destConfig; + const { apiSecret, serviceAccountUserName, serviceAccountSecret, projectId, dataResidency } = + destConfig; const duration = getTimeDifference(message.timestamp); switch (eventType) { case EventType.ALIAS: case EventType.TRACK: case EventType.SCREEN: - case EventType.PAGE: { - if (duration.years > 5) { + case EventType.PAGE: + if ( + !apiSecret && + !(serviceAccountUserName && serviceAccountSecret && projectId) && + duration.days <= 5 + ) { + response.endpoint = + dataResidency === 'eu' ? `${BASE_ENDPOINT_EU}/track/` : `${BASE_ENDPOINT}/track/`; + response.headers = {}; + } else if (duration.years > 5) { throw new InstrumentationError('Event timestamp should be within last 5 years'); + } else { + const credentials = setImportCredentials(destConfig); + response.endpoint = credentials.endpoint; + response.headers = credentials.headers; + response.params = { + project_id: credentials.params?.projectId, + strict: credentials.params.strict, + }; + break; } - const credentials = setImportCredentials(destConfig); - response.endpoint = credentials.endpoint; - response.headers = credentials.headers; - response.params = { - project_id: credentials.params?.projectId, - strict: credentials.params.strict, - }; break; - } - case 'merge': { + case 'merge': + // eslint-disable-next-line no-case-declarations const credentials = setImportCredentials(destConfig); response.endpoint = credentials.endpoint; response.headers = credentials.headers; @@ -95,7 +109,7 @@ const responseBuilderSimple = (payload, message, eventType, destConfig) => { strict: credentials.params.strict, }; break; - } + default: response.endpoint = dataResidency === 'eu' ? `${BASE_ENDPOINT_EU}/engage/` : `${BASE_ENDPOINT}/engage/`; @@ -470,6 +484,7 @@ const processRouterDest = async (inputs, reqMetadata) => { const batchSize = { engage: 0, groups: 0, + track: 0, import: 0, }; @@ -501,16 +516,23 @@ const processRouterDest = async (inputs, reqMetadata) => { ); transformedPayloads = lodash.flatMap(transformedPayloads); - const { engageEvents, groupsEvents, importEvents, batchErrorRespList } = + const { engageEvents, groupsEvents, trackEvents, importEvents, batchErrorRespList } = groupEventsByEndpoint(transformedPayloads); const engageRespList = batchEvents(engageEvents, ENGAGE_MAX_BATCH_SIZE, reqMetadata); const groupsRespList = batchEvents(groupsEvents, GROUPS_MAX_BATCH_SIZE, reqMetadata); + const trackRespList = batchEvents(trackEvents, TRACK_MAX_BATCH_SIZE, reqMetadata); const importRespList = batchEvents(importEvents, IMPORT_MAX_BATCH_SIZE, reqMetadata); - const batchSuccessRespList = [...engageRespList, ...groupsRespList, ...importRespList]; + const batchSuccessRespList = [ + ...engageRespList, + ...groupsRespList, + ...trackRespList, + ...importRespList, + ]; batchSize.engage += engageRespList.length; batchSize.groups += groupsRespList.length; + batchSize.track += trackRespList.length; batchSize.import += importRespList.length; return [...batchSuccessRespList, ...batchErrorRespList]; diff --git a/src/v0/destinations/mp/util.js b/src/v0/destinations/mp/util.js index b2807d6e11..d564e805ad 100644 --- a/src/v0/destinations/mp/util.js +++ b/src/v0/destinations/mp/util.js @@ -136,7 +136,7 @@ const createIdentifyResponse = (message, type, destination, responseBuilderSimpl * @returns */ const isImportAuthCredentialsAvailable = (destination) => - destination.Config.token || + destination.Config.apiSecret || (destination.Config.serviceAccountSecret && destination.Config.serviceAccountUserName && destination.Config.projectId); @@ -179,6 +179,7 @@ const groupEventsByEndpoint = (events) => { const eventMap = { engage: [], groups: [], + track: [], import: [], }; const batchErrorRespList = []; @@ -203,6 +204,7 @@ const groupEventsByEndpoint = (events) => { return { engageEvents: eventMap.engage, groupsEvents: eventMap.groups, + trackEvents: eventMap.track, importEvents: eventMap.import, batchErrorRespList, }; @@ -347,6 +349,7 @@ const generatePageOrScreenCustomEventName = (message, userDefinedEventTemplate) * @param {Object} batchSize - The object containing the batch size for different endpoints. * @param {number} batchSize.engage - The batch size for engage endpoint. * @param {number} batchSize.groups - The batch size for group endpoint. + * @param {number} batchSize.track - The batch size for track endpoint. * @param {number} batchSize.import - The batch size for import endpoint. * @param {string} destinationId - The ID of the destination. * @returns {void} @@ -358,6 +361,9 @@ const recordBatchSizeMetrics = (batchSize, destinationId) => { stats.gauge('mixpanel_batch_group_pack_size', batchSize.groups, { destination_id: destinationId, }); + stats.gauge('mixpanel_batch_track_pack_size', batchSize.track, { + destination_id: destinationId, + }); stats.gauge('mixpanel_batch_import_pack_size', batchSize.import, { destination_id: destinationId, }); diff --git a/src/v0/destinations/mp/util.test.js b/src/v0/destinations/mp/util.test.js index 3666081f59..40cdb34649 100644 --- a/src/v0/destinations/mp/util.test.js +++ b/src/v0/destinations/mp/util.test.js @@ -18,6 +18,7 @@ describe('Unit test cases for groupEventsByEndpoint', () => { expect(result).toEqual({ engageEvents: [], groupsEvents: [], + trackEvents: [], importEvents: [], batchErrorRespList: [], }); @@ -121,6 +122,19 @@ describe('Unit test cases for groupEventsByEndpoint', () => { }, }, ], + trackEvents: [ + { + message: { + endpoint: '/track', + body: { + JSON_ARRAY: { + batch: '[{prop:4}]', + }, + }, + userId: 'user1', + }, + }, + ], importEvents: [ { message: { diff --git a/test/integrations/destinations/mp/common.ts b/test/integrations/destinations/mp/common.ts index d40afa0c02..82f0e3202b 100644 --- a/test/integrations/destinations/mp/common.ts +++ b/test/integrations/destinations/mp/common.ts @@ -7,7 +7,7 @@ const defaultMockFns = () => { const sampleDestination: Destination = { Config: { apiKey: 'dummyApiKey', - token: 'test_api_token', + token: 'dummyApiKey', prefixProperties: true, useNativeSDK: false, }, diff --git a/test/integrations/destinations/mp/processor/data.ts b/test/integrations/destinations/mp/processor/data.ts index db5bc840c2..2d70d15384 100644 --- a/test/integrations/destinations/mp/processor/data.ts +++ b/test/integrations/destinations/mp/processor/data.ts @@ -12,7 +12,7 @@ export const data = [ request: { body: [ { - destination: overrideDestination(sampleDestination, { token: 'test_api_token' }), + destination: overrideDestination(sampleDestination, { token: 'dummyApiKey' }), message: { anonymousId: 'e6ab2c5e-2cda-44a9-a962-e2f67df78bca', channel: 'web', @@ -87,17 +87,14 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/import/', - headers: { - Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', - 'Content-Type': 'application/json', - }, - params: { strict: 0 }, + endpoint: 'https://api.mixpanel.com/track/', + headers: {}, + params: {}, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"Loaded a Page","properties":{"ip":"0.0.0.0","campaign_id":"test_name","$user_id":"hjikl","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"dd266c67-9199-4a52-ba32-f46ddde67312","token":"test_api_token","distinct_id":"hjikl","time":1579847342402,"utm_campaign":"test_name","utm_source":"rudder","utm_medium":"test_medium","utm_term":"test_tem","utm_content":"test_content","utm_test":"test","utm_keyword":"test_keyword","name":"Contact Us","$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', + '[{"event":"Loaded a Page","properties":{"ip":"0.0.0.0","campaign_id":"test_name","$user_id":"hjikl","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"dd266c67-9199-4a52-ba32-f46ddde67312","token":"dummyApiKey","distinct_id":"hjikl","time":1579847342402,"utm_campaign":"test_name","utm_source":"rudder","utm_medium":"test_medium","utm_term":"test_tem","utm_content":"test_content","utm_test":"test","utm_keyword":"test_keyword","name":"Contact Us","$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', }, XML: {}, FORM: {}, @@ -194,17 +191,14 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/import/', - headers: { - Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', - 'Content-Type': 'application/json', - }, - params: { strict: 0 }, + endpoint: 'https://api.mixpanel.com/track/', + headers: {}, + params: {}, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"Viewed a Contact Us page","properties":{"ip":"0.0.0.0","$user_id":"hjikl","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"dd266c67-9199-4a52-ba32-f46ddde67312","token":"test_api_token","distinct_id":"hjikl","time":1579847342402,"name":"Contact Us","category":"Contact","$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', + '[{"event":"Viewed a Contact Us page","properties":{"ip":"0.0.0.0","$user_id":"hjikl","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"dd266c67-9199-4a52-ba32-f46ddde67312","token":"dummyApiKey","distinct_id":"hjikl","time":1579847342402,"name":"Contact Us","category":"Contact","$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', }, XML: {}, FORM: {}, @@ -278,17 +272,14 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/import/', - headers: { - Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', - 'Content-Type': 'application/json', - }, - params: { strict: 0 }, + endpoint: 'https://api.mixpanel.com/track/', + headers: {}, + params: {}, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"Loaded a Screen","properties":{"category":"communication","ip":"0.0.0.0","$user_id":"hjikl","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"dd266c67-9199-4a52-ba32-f46ddde67312","token":"test_api_token","distinct_id":"hjikl","time":1579847342402,"name":"Contact Us"}}]', + '[{"event":"Loaded a Screen","properties":{"category":"communication","ip":"0.0.0.0","$user_id":"hjikl","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"dd266c67-9199-4a52-ba32-f46ddde67312","token":"dummyApiKey","distinct_id":"hjikl","time":1579847342402,"name":"Contact Us"}}]', }, XML: {}, FORM: {}, @@ -369,17 +360,14 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/import/', - headers: { - Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', - 'Content-Type': 'application/json', - }, - params: { strict: 0 }, + endpoint: 'https://api.mixpanel.com/track/', + headers: {}, + params: {}, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"Loaded a Screen","properties":{"path":"/tests/html/index2.html","referrer":"","search":"","title":"","url":"http://localhost/tests/html/index2.html","ip":"0.0.0.0","$user_id":"hjiklmk","$screen_dpi":2,"mp_lib":"RudderLabs Android SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"dd266c67-9199-4a52-ba32-f46ddde67312","token":"test_api_token","distinct_id":"hjiklmk","time":1579847342402,"name":"Contact Us","category":"Contact"}}]', + '[{"event":"Loaded a Screen","properties":{"path":"/tests/html/index2.html","referrer":"","search":"","title":"","url":"http://localhost/tests/html/index2.html","ip":"0.0.0.0","$user_id":"hjiklmk","$screen_dpi":2,"mp_lib":"RudderLabs Android SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"dd266c67-9199-4a52-ba32-f46ddde67312","token":"dummyApiKey","distinct_id":"hjiklmk","time":1579847342402,"name":"Contact Us","category":"Contact"}}]', }, XML: {}, FORM: {}, @@ -452,17 +440,14 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/import/', - headers: { - Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', - 'Content-Type': 'application/json', - }, - params: { strict: 0 }, + endpoint: 'https://api.mixpanel.com/track/', + headers: {}, + params: {}, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"Loaded a Screen","properties":{"ip":"0.0.0.0","$user_id":"hjikl","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"dd266c67-9199-4a52-ba32-f46ddde67312","token":"test_api_token","distinct_id":"hjikl","time":1579847342402,"name":"Contact Us"}}]', + '[{"event":"Loaded a Screen","properties":{"ip":"0.0.0.0","$user_id":"hjikl","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"dd266c67-9199-4a52-ba32-f46ddde67312","token":"dummyApiKey","distinct_id":"hjikl","time":1579847342402,"name":"Contact Us"}}]', }, XML: {}, FORM: {}, @@ -565,7 +550,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$created":"2020-01-23T08:54:02.362Z","$email":"mickey@disney.com","$first_name":"Mickey","$last_name":"Mouse","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', + '[{"$set":{"$created":"2020-01-23T08:54:02.362Z","$email":"mickey@disney.com","$first_name":"Mickey","$last_name":"Mouse","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', }, XML: {}, FORM: {}, @@ -679,7 +664,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$append":{"$transactions":{"$time":"2020-01-24T06:29:02.403Z","$amount":45.89}},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca"}]', + '[{"$append":{"$transactions":{"$time":"2020-01-24T06:29:02.403Z","$amount":45.89}},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca"}]', }, XML: {}, FORM: {}, @@ -701,7 +686,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$add":{"counter":1,"item_purchased":"2"},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca"}]', + '[{"$add":{"counter":1,"item_purchased":"2"},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca"}]', }, XML: {}, FORM: {}, @@ -716,17 +701,14 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/import/', - headers: { - Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', - 'Content-Type': 'application/json', - }, - params: { strict: 0 }, + endpoint: 'https://api.mixpanel.com/track/', + headers: {}, + params: {}, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"test revenue MIXPANEL","properties":{"currency":"USD","revenue":45.89,"counter":1,"item_purchased":"2","number_of_logins":"","city":"Disney","country":"USA","email":"mickey@disney.com","firstName":"Mickey","ip":"0.0.0.0","campaign_id":"test_name","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"a6a0ad5a-bd26-4f19-8f75-38484e580fc7","token":"test_api_token","distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","time":1579847342403,"utm_campaign":"test_name","utm_source":"rudder","utm_medium":"test_medium","utm_term":"test_tem","utm_content":"test_content","utm_test":"test","utm_keyword":"test_keyword","$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', + '[{"event":"test revenue MIXPANEL","properties":{"currency":"USD","revenue":45.89,"counter":1,"item_purchased":"2","number_of_logins":"","city":"Disney","country":"USA","email":"mickey@disney.com","firstName":"Mickey","ip":"0.0.0.0","campaign_id":"test_name","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"a6a0ad5a-bd26-4f19-8f75-38484e580fc7","token":"dummyApiKey","distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","time":1579847342403,"utm_campaign":"test_name","utm_source":"rudder","utm_medium":"test_medium","utm_term":"test_tem","utm_content":"test_content","utm_test":"test","utm_keyword":"test_keyword","$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', }, XML: {}, FORM: {}, @@ -814,17 +796,14 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/import/', - headers: { - Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', - 'Content-Type': 'application/json', - }, - params: { strict: 0 }, + endpoint: 'https://api.mixpanel.com/track/', + headers: {}, + params: {}, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"$create_alias","properties":{"distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","alias":"1234abc","token":"test_api_token"}}]', + '[{"event":"$create_alias","properties":{"distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","alias":"1234abc","token":"dummyApiKey"}}]', }, XML: {}, FORM: {}, @@ -954,7 +933,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$append":{"$transactions":{"$time":"2020-01-24T06:29:02.402Z","$amount":25}},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca"}]', + '[{"$append":{"$transactions":{"$time":"2020-01-24T06:29:02.402Z","$amount":25}},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca"}]', }, XML: {}, FORM: {}, @@ -969,17 +948,14 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/import/', - headers: { - Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', - 'Content-Type': 'application/json', - }, - params: { strict: 0 }, + endpoint: 'https://api.mixpanel.com/track/', + headers: {}, + params: {}, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"KM Order Completed","properties":{"affiliation":"Google Store","checkout_id":"fksdjfsdjfisjf9sdfjsd9f","coupon":"hasbros","currency":"USD","discount":2.5,"order_id":"50314b8e9bcf000000000000","products":[{"category":"Games","image_url":"https:///www.example.com/product/path.jpg","name":"Monopoly: 3rd Edition","price":19,"product_id":"507f1f77bcf86cd799439011","quantity":1,"sku":"45790-32","url":"https://www.example.com/product/path"},{"category":"Games","name":"Uno Card Game","price":3,"product_id":"505bd76785ebb509fc183733","quantity":2,"sku":"46493-32"}],"revenue":25,"shipping":3,"subtotal":22.5,"tax":2,"total":27.5,"city":"Disney","country":"USA","email":"mickey@disney.com","firstName":"Mickey","ip":"0.0.0.0","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"aa5f5e44-8756-40ad-ad1e-b0d3b9fa710a","token":"test_api_token","distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","time":1579847342402,"$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', + '[{"event":"KM Order Completed","properties":{"affiliation":"Google Store","checkout_id":"fksdjfsdjfisjf9sdfjsd9f","coupon":"hasbros","currency":"USD","discount":2.5,"order_id":"50314b8e9bcf000000000000","products":[{"category":"Games","image_url":"https:///www.example.com/product/path.jpg","name":"Monopoly: 3rd Edition","price":19,"product_id":"507f1f77bcf86cd799439011","quantity":1,"sku":"45790-32","url":"https://www.example.com/product/path"},{"category":"Games","name":"Uno Card Game","price":3,"product_id":"505bd76785ebb509fc183733","quantity":2,"sku":"46493-32"}],"revenue":25,"shipping":3,"subtotal":22.5,"tax":2,"total":27.5,"city":"Disney","country":"USA","email":"mickey@disney.com","firstName":"Mickey","ip":"0.0.0.0","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"aa5f5e44-8756-40ad-ad1e-b0d3b9fa710a","token":"dummyApiKey","distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","time":1579847342402,"$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', }, XML: {}, FORM: {}, @@ -1113,7 +1089,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$append":{"$transactions":{"$time":"2020-01-24T06:29:02.402Z","$amount":34}},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca"}]', + '[{"$append":{"$transactions":{"$time":"2020-01-24T06:29:02.402Z","$amount":34}},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca"}]', }, XML: {}, FORM: {}, @@ -1128,17 +1104,14 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/import/', - headers: { - Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', - 'Content-Type': 'application/json', - }, - params: { strict: 0 }, + endpoint: 'https://api.mixpanel.com/track/', + headers: {}, + params: {}, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"KM Order Completed","properties":{"affiliation":"Google Store","checkout_id":"fksdjfsdjfisjf9sdfjsd9f","coupon":"hasbros","currency":"USD","discount":2.5,"order_id":"50314b8e9bcf000000000000","revenue":34,"key_1":{"child_key1":"child_value1","child_key2":{"child_key21":"child_value21","child_key22":"child_value22"}},"products":[{"category":"Games","image_url":"https:///www.example.com/product/path.jpg","name":"Monopoly: 3rd Edition","price":19,"product_id":"507f1f77bcf86cd799439011","quantity":1,"sku":"45790-32","url":"https://www.example.com/product/path"},{"category":"Games","name":"Uno Card Game","price":3,"product_id":"505bd76785ebb509fc183733","quantity":2,"sku":"46493-32"}],"shipping":3,"subtotal":22.5,"tax":2,"total":27.5,"city":"Disney","country":"USA","email":"mickey@disney.com","first_name":"Mickey","lastName":"Mouse","name":"Mickey Mouse","ip":"0.0.0.0","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"aa5f5e44-8756-40ad-ad1e-b0d3b9fa710a","token":"test_api_token","distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","time":1579847342402,"$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', + '[{"event":"KM Order Completed","properties":{"affiliation":"Google Store","checkout_id":"fksdjfsdjfisjf9sdfjsd9f","coupon":"hasbros","currency":"USD","discount":2.5,"order_id":"50314b8e9bcf000000000000","revenue":34,"key_1":{"child_key1":"child_value1","child_key2":{"child_key21":"child_value21","child_key22":"child_value22"}},"products":[{"category":"Games","image_url":"https:///www.example.com/product/path.jpg","name":"Monopoly: 3rd Edition","price":19,"product_id":"507f1f77bcf86cd799439011","quantity":1,"sku":"45790-32","url":"https://www.example.com/product/path"},{"category":"Games","name":"Uno Card Game","price":3,"product_id":"505bd76785ebb509fc183733","quantity":2,"sku":"46493-32"}],"shipping":3,"subtotal":22.5,"tax":2,"total":27.5,"city":"Disney","country":"USA","email":"mickey@disney.com","first_name":"Mickey","lastName":"Mouse","name":"Mickey Mouse","ip":"0.0.0.0","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"aa5f5e44-8756-40ad-ad1e-b0d3b9fa710a","token":"dummyApiKey","distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","time":1579847342402,"$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', }, XML: {}, FORM: {}, @@ -1262,17 +1235,14 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/import/', - headers: { - Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', - 'Content-Type': 'application/json', - }, - params: { strict: 0 }, + endpoint: 'https://api.mixpanel.com/track/', + headers: {}, + params: {}, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":" new Order Completed totally","properties":{"affiliation":"Google Store","checkout_id":"fksdjfsdjfisjf9sdfjsd9f","coupon":"hasbros","currency":"USD","discount":2.5,"total":23,"order_id":"50314b8e9bcf000000000000","key_1":{"child_key1":"child_value1","child_key2":{"child_key21":"child_value21","child_key22":"child_value22"}},"products":[{"category":"Games","image_url":"https:///www.example.com/product/path.jpg","name":"Monopoly: 3rd Edition","price":19,"product_id":"507f1f77bcf86cd799439011","quantity":1,"sku":"45790-32","url":"https://www.example.com/product/path"},{"category":"Games","name":"Uno Card Game","price":3,"product_id":"505bd76785ebb509fc183733","quantity":2,"sku":"46493-32"}],"shipping":3,"subtotal":22.5,"tax":2,"city":"Disney","country":"USA","email":"mickey@disney.com","firstName":"Mickey","ip":"0.0.0.0","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"aa5f5e44-8756-40ad-ad1e-b0d3b9fa710a","token":"test_api_token","distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","time":1579847342402,"$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', + '[{"event":" new Order Completed totally","properties":{"affiliation":"Google Store","checkout_id":"fksdjfsdjfisjf9sdfjsd9f","coupon":"hasbros","currency":"USD","discount":2.5,"total":23,"order_id":"50314b8e9bcf000000000000","key_1":{"child_key1":"child_value1","child_key2":{"child_key21":"child_value21","child_key22":"child_value22"}},"products":[{"category":"Games","image_url":"https:///www.example.com/product/path.jpg","name":"Monopoly: 3rd Edition","price":19,"product_id":"507f1f77bcf86cd799439011","quantity":1,"sku":"45790-32","url":"https://www.example.com/product/path"},{"category":"Games","name":"Uno Card Game","price":3,"product_id":"505bd76785ebb509fc183733","quantity":2,"sku":"46493-32"}],"shipping":3,"subtotal":22.5,"tax":2,"city":"Disney","country":"USA","email":"mickey@disney.com","firstName":"Mickey","ip":"0.0.0.0","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"aa5f5e44-8756-40ad-ad1e-b0d3b9fa710a","token":"dummyApiKey","distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","time":1579847342402,"$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', }, XML: {}, FORM: {}, @@ -1396,17 +1366,14 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/import/', - headers: { - Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', - 'Content-Type': 'application/json', - }, - params: { strict: 0 }, + endpoint: 'https://api.mixpanel.com/track/', + headers: {}, + params: {}, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":" Order Completed ","properties":{"affiliation":"Google Store","checkout_id":"fksdjfsdjfisjf9sdfjsd9f","coupon":"hasbros","currency":"USD","discount":2.5,"total":23,"order_id":"50314b8e9bcf000000000000","key_1":{"child_key1":"child_value1","child_key2":{"child_key21":"child_value21","child_key22":"child_value22"}},"products":[{"category":"Games","image_url":"https:///www.example.com/product/path.jpg","name":"Monopoly: 3rd Edition","price":19,"product_id":"507f1f77bcf86cd799439011","quantity":1,"sku":"45790-32","url":"https://www.example.com/product/path"},{"category":"Games","name":"Uno Card Game","price":3,"product_id":"505bd76785ebb509fc183733","quantity":2,"sku":"46493-32"}],"shipping":3,"subtotal":22.5,"tax":2,"Billing Amount":"77","city":"Disney","country":"USA","email":"mickey@disney.com","firstName":"Mickey","ip":"0.0.0.0","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"aa5f5e44-8756-40ad-ad1e-b0d3b9fa710a","token":"test_api_token","distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","time":1579847342402,"$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', + '[{"event":" Order Completed ","properties":{"affiliation":"Google Store","checkout_id":"fksdjfsdjfisjf9sdfjsd9f","coupon":"hasbros","currency":"USD","discount":2.5,"total":23,"order_id":"50314b8e9bcf000000000000","key_1":{"child_key1":"child_value1","child_key2":{"child_key21":"child_value21","child_key22":"child_value22"}},"products":[{"category":"Games","image_url":"https:///www.example.com/product/path.jpg","name":"Monopoly: 3rd Edition","price":19,"product_id":"507f1f77bcf86cd799439011","quantity":1,"sku":"45790-32","url":"https://www.example.com/product/path"},{"category":"Games","name":"Uno Card Game","price":3,"product_id":"505bd76785ebb509fc183733","quantity":2,"sku":"46493-32"}],"shipping":3,"subtotal":22.5,"tax":2,"Billing Amount":"77","city":"Disney","country":"USA","email":"mickey@disney.com","firstName":"Mickey","ip":"0.0.0.0","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"aa5f5e44-8756-40ad-ad1e-b0d3b9fa710a","token":"dummyApiKey","distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","time":1579847342402,"$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', }, XML: {}, FORM: {}, @@ -1574,7 +1541,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$email":"mickey@disney.com","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$firstName":"Mickey","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', + '[{"$set":{"$email":"mickey@disney.com","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$firstName":"Mickey","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', }, XML: {}, FORM: {}, @@ -1661,7 +1628,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$token":"test_api_token","$distinct_id":"hjikl","$set":{"company":["testComp"]},"$ip":"0.0.0.0"}]', + '[{"$token":"dummyApiKey","$distinct_id":"hjikl","$set":{"company":["testComp"]},"$ip":"0.0.0.0"}]', }, XML: {}, FORM: {}, @@ -1683,7 +1650,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$token":"test_api_token","$group_key":"company","$group_id":"testComp","$set":{"company":"testComp"}}]', + '[{"$token":"dummyApiKey","$group_key":"company","$group_id":"testComp","$set":{"company":"testComp"}}]', }, XML: {}, FORM: {}, @@ -1770,7 +1737,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$token":"test_api_token","$distinct_id":"hjikl","$set":{"company":["testComp","testComp1"]},"$ip":"0.0.0.0"}]', + '[{"$token":"dummyApiKey","$distinct_id":"hjikl","$set":{"company":["testComp","testComp1"]},"$ip":"0.0.0.0"}]', }, XML: {}, FORM: {}, @@ -1792,7 +1759,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$token":"test_api_token","$group_key":"company","$group_id":"testComp","$set":{"company":["testComp","testComp1"]}}]', + '[{"$token":"dummyApiKey","$group_key":"company","$group_id":"testComp","$set":{"company":["testComp","testComp1"]}}]', }, XML: {}, FORM: {}, @@ -1814,7 +1781,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$token":"test_api_token","$group_key":"company","$group_id":"testComp1","$set":{"company":["testComp","testComp1"]}}]', + '[{"$token":"dummyApiKey","$group_key":"company","$group_id":"testComp1","$set":{"company":["testComp","testComp1"]}}]', }, XML: {}, FORM: {}, @@ -1902,7 +1869,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$token":"test_api_token","$distinct_id":"hjikl","$set":{"company":["testComp"]},"$ip":"0.0.0.0"}]', + '[{"$token":"dummyApiKey","$distinct_id":"hjikl","$set":{"company":["testComp"]},"$ip":"0.0.0.0"}]', }, XML: {}, FORM: {}, @@ -1924,7 +1891,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$token":"test_api_token","$group_key":"company","$group_id":"testComp","$set":{"company":"testComp"}}]', + '[{"$token":"dummyApiKey","$group_key":"company","$group_id":"testComp","$set":{"company":"testComp"}}]', }, XML: {}, FORM: {}, @@ -2052,7 +2019,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$append":{"$transactions":{"$time":"2020-01-24T06:29:02.402Z","$amount":25}},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca"}]', + '[{"$append":{"$transactions":{"$time":"2020-01-24T06:29:02.402Z","$amount":25}},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca"}]', }, XML: {}, FORM: {}, @@ -2067,17 +2034,14 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api-eu.mixpanel.com/import/', - headers: { - Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', - 'Content-Type': 'application/json', - }, - params: { strict: 0 }, + endpoint: 'https://api-eu.mixpanel.com/track/', + headers: {}, + params: {}, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"KM Order Completed","properties":{"affiliation":"Google Store","checkout_id":"fksdjfsdjfisjf9sdfjsd9f","coupon":"hasbros","currency":"USD","discount":2.5,"order_id":"50314b8e9bcf000000000000","products":[{"category":"Games","image_url":"https:///www.example.com/product/path.jpg","name":"Monopoly: 3rd Edition","price":19,"product_id":"507f1f77bcf86cd799439011","quantity":1,"sku":"45790-32","url":"https://www.example.com/product/path"},{"category":"Games","name":"Uno Card Game","price":3,"product_id":"505bd76785ebb509fc183733","quantity":2,"sku":"46493-32"}],"revenue":25,"shipping":3,"subtotal":22.5,"tax":2,"total":27.5,"city":"Disney","country":"USA","email":"mickey@disney.com","firstname":"Mickey","lastname":"Mouse","ip":"0.0.0.0","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"aa5f5e44-8756-40ad-ad1e-b0d3b9fa710a","token":"test_api_token","distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","time":1579847342402,"$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', + '[{"event":"KM Order Completed","properties":{"affiliation":"Google Store","checkout_id":"fksdjfsdjfisjf9sdfjsd9f","coupon":"hasbros","currency":"USD","discount":2.5,"order_id":"50314b8e9bcf000000000000","products":[{"category":"Games","image_url":"https:///www.example.com/product/path.jpg","name":"Monopoly: 3rd Edition","price":19,"product_id":"507f1f77bcf86cd799439011","quantity":1,"sku":"45790-32","url":"https://www.example.com/product/path"},{"category":"Games","name":"Uno Card Game","price":3,"product_id":"505bd76785ebb509fc183733","quantity":2,"sku":"46493-32"}],"revenue":25,"shipping":3,"subtotal":22.5,"tax":2,"total":27.5,"city":"Disney","country":"USA","email":"mickey@disney.com","firstname":"Mickey","lastname":"Mouse","ip":"0.0.0.0","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"aa5f5e44-8756-40ad-ad1e-b0d3b9fa710a","token":"dummyApiKey","distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","time":1579847342402,"$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', }, XML: {}, FORM: {}, @@ -2165,7 +2129,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$carrier":"Android","$manufacturer":"Google","$model":"Android SDK built for x86","$screen_height":1794,"$screen_width":1080,"$wifi":true,"anonymousId":"5094f5704b9cf2b3","$android_devices":["test_device_token"],"$os":"Android","$android_model":"Android SDK built for x86","$android_os_version":"8.1.0","$android_manufacturer":"Google","$android_app_version":"1.0","$android_app_version_code":"1.0","$android_brand":"Google"},"$token":"test_api_token","$distinct_id":"5094f5704b9cf2b3","$time":1584003903421}]', + '[{"$set":{"$carrier":"Android","$manufacturer":"Google","$model":"Android SDK built for x86","$screen_height":1794,"$screen_width":1080,"$wifi":true,"anonymousId":"5094f5704b9cf2b3","$android_devices":["test_device_token"],"$os":"Android","$android_model":"Android SDK built for x86","$android_os_version":"8.1.0","$android_manufacturer":"Google","$android_app_version":"1.0","$android_app_version_code":"1.0","$android_brand":"Google"},"$token":"dummyApiKey","$distinct_id":"5094f5704b9cf2b3","$time":1584003903421}]', }, XML: {}, FORM: {}, @@ -2252,7 +2216,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$carrier":"Android","$manufacturer":"Google","$model":"Android SDK built for x86","$screen_height":1794,"$screen_width":1080,"$wifi":true,"anonymousId":"5094f5704b9cf2b3","userId":"test_user_id","$ios_devices":["test_device_token"],"$os":"iOS","$ios_device_model":"Android SDK built for x86","$ios_version":"8.1.0","$ios_app_release":"1","$ios_app_version":"1.0"},"$token":"test_api_token","$distinct_id":"test_user_id","$time":1584003903421}]', + '[{"$set":{"$carrier":"Android","$manufacturer":"Google","$model":"Android SDK built for x86","$screen_height":1794,"$screen_width":1080,"$wifi":true,"anonymousId":"5094f5704b9cf2b3","userId":"test_user_id","$ios_devices":["test_device_token"],"$os":"iOS","$ios_device_model":"Android SDK built for x86","$ios_version":"8.1.0","$ios_app_release":"1","$ios_app_version":"1.0"},"$token":"dummyApiKey","$distinct_id":"test_user_id","$time":1584003903421}]', }, XML: {}, FORM: {}, @@ -2269,7 +2233,7 @@ export const data = [ method: 'POST', endpoint: 'https://api-eu.mixpanel.com/import/', headers: { - Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + Authorization: 'Basic c29tZV9hcGlfc2VjcmV0Og==', 'Content-Type': 'application/json', }, params: { strict: 0 }, @@ -2277,7 +2241,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"event":"$merge","properties":{"$distinct_ids":["test_user_id","5094f5704b9cf2b3"],"token":"test_api_token"}}]', + '[{"event":"$merge","properties":{"$distinct_ids":["test_user_id","5094f5704b9cf2b3"],"token":"dummyApiKey"}}]', }, XML: {}, FORM: {}, @@ -2364,17 +2328,14 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/import/', - headers: { - Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', - 'Content-Type': 'application/json', - }, - params: { strict: 0 }, + endpoint: 'https://api.mixpanel.com/track/', + headers: {}, + params: {}, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"Loaded a Page","properties":{"path":"/tests/html/index2.html","referrer":"","search":"","title":"","url":"http://localhost/tests/html/index2.html","category":"communication","ip":"0.0.0.0","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"dd266c67-9199-4a52-ba32-f46ddde67312","token":"test_api_token","distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","time":1579847342402,"name":"Contact Us","$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', + '[{"event":"Loaded a Page","properties":{"path":"/tests/html/index2.html","referrer":"","search":"","title":"","url":"http://localhost/tests/html/index2.html","category":"communication","ip":"0.0.0.0","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"dd266c67-9199-4a52-ba32-f46ddde67312","token":"dummyApiKey","distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","time":1579847342402,"name":"Contact Us","$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', }, XML: {}, FORM: {}, @@ -2462,17 +2423,14 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/import/', - headers: { - Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', - 'Content-Type': 'application/json', - }, - params: { strict: 0 }, + endpoint: 'https://api.mixpanel.com/track/', + headers: {}, + params: {}, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"$create_alias","properties":{"distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","alias":"1234abc","token":"test_api_token"}}]', + '[{"event":"$create_alias","properties":{"distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","alias":"1234abc","token":"dummyApiKey"}}]', }, XML: {}, FORM: {}, @@ -2565,7 +2523,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$carrier":"Android","$manufacturer":"Google","$model":"Android SDK built for x86","$screen_height":1794,"$screen_width":1080,"$wifi":true,"anonymousId":"5094f5704b9cf2b3","userId":"test_user_id","createdat":"2020-01-23T08:54:02.362Z","$ios_devices":["test_device_token"],"$ios_device_model":"Android SDK built for x86","$ios_app_release":"1","$ios_app_version":"1.0"},"$token":"test_api_token","$distinct_id":"test_user_id","$time":1584003903421}]', + '[{"$set":{"$carrier":"Android","$manufacturer":"Google","$model":"Android SDK built for x86","$screen_height":1794,"$screen_width":1080,"$wifi":true,"anonymousId":"5094f5704b9cf2b3","userId":"test_user_id","createdat":"2020-01-23T08:54:02.362Z","$ios_devices":["test_device_token"],"$ios_device_model":"Android SDK built for x86","$ios_app_release":"1","$ios_app_version":"1.0"},"$token":"dummyApiKey","$distinct_id":"test_user_id","$time":1584003903421}]', }, XML: {}, FORM: {}, @@ -2582,7 +2540,7 @@ export const data = [ method: 'POST', endpoint: 'https://api-eu.mixpanel.com/import/', headers: { - Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + Authorization: 'Basic c29tZV9hcGlfc2VjcmV0Og==', 'Content-Type': 'application/json', }, params: { strict: 0 }, @@ -2590,7 +2548,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"event":"$merge","properties":{"$distinct_ids":["test_user_id","5094f5704b9cf2b3"],"token":"test_api_token"}}]', + '[{"event":"$merge","properties":{"$distinct_ids":["test_user_id","5094f5704b9cf2b3"],"token":"dummyApiKey"}}]', }, XML: {}, FORM: {}, @@ -2683,7 +2641,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$email":"mickey@disney.com","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$firstName":"Mickey","$lastName":"Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', + '[{"$set":{"$email":"mickey@disney.com","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$firstName":"Mickey","$lastName":"Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', }, XML: {}, FORM: {}, @@ -2775,7 +2733,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$email":"mickey@disney.com","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$firstName":"Mickey","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', + '[{"$set":{"$email":"mickey@disney.com","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$firstName":"Mickey","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', }, XML: {}, FORM: {}, @@ -2868,7 +2826,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$email":"mickey@disney.com","$name":"Mickey Mouse","$country_code":"USA","$city":"Disney","$region":"US","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$firstName":"Mickey","$lastName":"Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', + '[{"$set":{"$email":"mickey@disney.com","$name":"Mickey Mouse","$country_code":"USA","$city":"Disney","$region":"US","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$firstName":"Mickey","$lastName":"Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', }, XML: {}, FORM: {}, @@ -2966,7 +2924,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$email":"mickey@disney.com","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$firstName":"Mickey","$lastName":"Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', + '[{"$set":{"$email":"mickey@disney.com","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$firstName":"Mickey","$lastName":"Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', }, XML: {}, FORM: {}, @@ -3062,7 +3020,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$email":"mickey@disney.com","$name":"Mouse","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$firstName":"Mickey","$lastName":"Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', + '[{"$set":{"$email":"mickey@disney.com","$name":"Mouse","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$firstName":"Mickey","$lastName":"Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', }, XML: {}, FORM: {}, @@ -3157,7 +3115,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$email":"mickey@disney.com","$first_name":"Mickey","$last_name":"Mouse","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', + '[{"$set":{"$email":"mickey@disney.com","$first_name":"Mickey","$last_name":"Mouse","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', }, XML: {}, FORM: {}, @@ -3251,7 +3209,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$email":"mickey@disney.com","$first_name":"Mickey","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', + '[{"$set":{"$email":"mickey@disney.com","$first_name":"Mickey","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', }, XML: {}, FORM: {}, @@ -3346,7 +3304,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$email":"mickey@disney.com","$first_name":"Mickey","$last_name":"Mouse","$name":"Mickey Mouse","$country_code":"USA","$city":"Disney","$region":"US","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', + '[{"$set":{"$email":"mickey@disney.com","$first_name":"Mickey","$last_name":"Mouse","$name":"Mickey Mouse","$country_code":"USA","$city":"Disney","$region":"US","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', }, XML: {}, FORM: {}, @@ -3447,7 +3405,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$email":"mickey@disney.com","$first_name":"Mickey","$last_name":"Mouse","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', + '[{"$set":{"$email":"mickey@disney.com","$first_name":"Mickey","$last_name":"Mouse","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', }, XML: {}, FORM: {}, @@ -3544,29 +3502,17 @@ export const data = [ status: 200, body: [ { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://api.mixpanel.com/import/', - headers: { - Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', - 'Content-Type': 'application/json', - }, - params: { strict: 0 }, - body: { - JSON: {}, - JSON_ARRAY: { - batch: - '[{"event":"FirstTrackCall12","properties":{"foo":"bar","$deviceId":"nkasdnkasd","anonymousId":"ea776ad0-3136-44fb-9216-5b1578609a2b","userId":"as09sufa09usaf09as0f9uasf","id":"as09sufa09usaf09as0f9uasf","firstName":"Bob","lastName":"Marley","name":"Bob Marley","age":43,"email":"bob@marleymail.com","phone":"+447748544123","birthday":"1987-01-01T20:08:59+0000","createdAt":"2022-01-21T14:10:12+0000","address":"51,B.L.T road, Kolkata-700060","description":"I am great","gender":"male","title":"Founder","username":"bobm","website":"https://bobm.com","randomProperty":"randomValue","$user_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$current_url":"http://127.0.0.1:7307/Testing/App_for_testingTool/","$referrer":"http://127.0.0.1:7307/Testing/","$screen_height":900,"$screen_width":1440,"$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.1.18","$insert_id":"0d5c1a4a-27e4-41da-a246-4d01f44e74bd","token":"test_api_token","distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","time":1632986123523,"$browser":"Chrome","$browser_version":"93.0.4577.82"}}]', - }, - XML: {}, - FORM: {}, - }, - files: {}, - userId: 'e6ab2c5e-2cda-44a9-a962-e2f67df78bca', + error: + 'Event timestamp is older than 5 days and no API secret or service account credentials (i.e. username, secret and projectId) are provided in destination configuration', + statTags: { + destType: 'MP', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', }, - statusCode: 200, + statusCode: 400, }, ], }, @@ -3740,7 +3686,7 @@ export const data = [ method: 'POST', endpoint: 'https://api-eu.mixpanel.com/import/', headers: { - Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + Authorization: 'Basic c29tZV9hcGlfc2VjcmV0Og==', 'Content-Type': 'application/json', }, params: { strict: 0 }, @@ -3748,7 +3694,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"event":"MainActivity","properties":{"name":"MainActivity","automatic":true,"anonymousId":"5094f5704b9cf2b3","userId":"test_user_id","$user_id":"test_user_id","$os":"iOS","$screen_height":1794,"$screen_width":1080,"$screen_dpi":420,"$carrier":"Android","$os_version":"8.1.0","$device":"generic_x86","$manufacturer":"Google","$model":"Android SDK built for x86","mp_device_model":"Android SDK built for x86","$wifi":true,"$bluetooth_enabled":false,"mp_lib":"com.rudderstack.android.sdk.core","$app_build_number":"1","$app_version_string":"1.0","$insert_id":"id2","token":"test_api_token","distinct_id":"test_user_id","time":1520845503421}}]', + '[{"event":"MainActivity","properties":{"name":"MainActivity","automatic":true,"anonymousId":"5094f5704b9cf2b3","userId":"test_user_id","$user_id":"test_user_id","$os":"iOS","$screen_height":1794,"$screen_width":1080,"$screen_dpi":420,"$carrier":"Android","$os_version":"8.1.0","$device":"generic_x86","$manufacturer":"Google","$model":"Android SDK built for x86","mp_device_model":"Android SDK built for x86","$wifi":true,"$bluetooth_enabled":false,"mp_lib":"com.rudderstack.android.sdk.core","$app_build_number":"1","$app_version_string":"1.0","$insert_id":"id2","token":"dummyApiKey","distinct_id":"test_user_id","time":1520845503421}}]', }, XML: {}, FORM: {}, @@ -4019,7 +3965,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$created":"2020-01-23T08:54:02.362Z","$email":"mickey@disney.com","$first_name":"Mickey","$last_name":"Mouse","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402,"$ignore_time":true}]', + '[{"$set":{"$created":"2020-01-23T08:54:02.362Z","$email":"mickey@disney.com","$first_name":"Mickey","$last_name":"Mouse","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402,"$ignore_time":true}]', }, XML: {}, FORM: {}, @@ -4125,7 +4071,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$created":"2020-01-23T08:54:02.362Z","$email":"mickey@disney.com","$first_name":"Mickey","$last_name":"Mouse","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', + '[{"$set":{"$created":"2020-01-23T08:54:02.362Z","$email":"mickey@disney.com","$first_name":"Mickey","$last_name":"Mouse","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyApiKey","$distinct_id":"e6ab2c5e-2cda-44a9-a962-e2f67df78bca","$ip":"0.0.0.0","$time":1579847342402}]', }, XML: {}, FORM: {}, @@ -4330,7 +4276,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$created":"2020-01-23T08:54:02.362Z","$email":"mickey@disney.com","$first_name":"Mickey","$last_name":"Mouse","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"user1234","$ip":"0.0.0.0","$time":1579847342402}]', + '[{"$set":{"$created":"2020-01-23T08:54:02.362Z","$email":"mickey@disney.com","$first_name":"Mickey","$last_name":"Mouse","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyApiKey","$distinct_id":"user1234","$ip":"0.0.0.0","$time":1579847342402}]', }, XML: {}, FORM: {}, @@ -4348,14 +4294,18 @@ export const data = [ endpoint: 'https://api.mixpanel.com/import/', headers: { 'Content-Type': 'application/json', - Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + Authorization: + 'Basic cnVkZGVyLmQyYTNmMS5tcC1zZXJ2aWNlLWFjY291bnQ6amF0cFF4Y2pNaDhlZXRrMXhySDNLalFJYnp5NGlYOGI=', + }, + params: { + project_id: '123456', + strict: 0, }, - params: { strict: 0 }, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"$merge","properties":{"$distinct_ids":["user1234","e6ab2c5e-2cda-44a9-a962-e2f67df78bca"],"token":"test_api_token"}}]', + '[{"event":"$merge","properties":{"$distinct_ids":["user1234","e6ab2c5e-2cda-44a9-a962-e2f67df78bca"],"token":"dummyApiKey"}}]', }, XML: {}, FORM: {}, @@ -4440,7 +4390,7 @@ export const data = [ method: 'POST', endpoint: 'https://api.mixpanel.com/import/', headers: { - Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + Authorization: 'Basic ZHVtbXlBcGlLZXk6', 'Content-Type': 'application/json', }, params: { strict: 0 }, @@ -4448,7 +4398,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"event":"Application Installed","properties":{"build":4,"version":"1.0","anonymousId":"39da706ec83d0e90","$os":"Android","$screen_height":2984,"$screen_width":1440,"$screen_dpi":560,"$carrier":"T-Mobile","$os_version":"12","$device":"emu64a","$manufacturer":"Google","$model":"sdk_gphone64_arm64","mp_device_model":"sdk_gphone64_arm64","$wifi":true,"$bluetooth_enabled":true,"mp_lib":"com.rudderstack.android.sdk.core","$app_build_number":"4","$app_version_string":"1.0","$insert_id":"168cf720-6227-4b56-a98e-c49bdc7279e9","$session_id":"1662363980","token":"test_api_token","distinct_id":"39da706ec83d0e90","time":1662363980290}}]', + '[{"event":"Application Installed","properties":{"build":4,"version":"1.0","anonymousId":"39da706ec83d0e90","$os":"Android","$screen_height":2984,"$screen_width":1440,"$screen_dpi":560,"$carrier":"T-Mobile","$os_version":"12","$device":"emu64a","$manufacturer":"Google","$model":"sdk_gphone64_arm64","mp_device_model":"sdk_gphone64_arm64","$wifi":true,"$bluetooth_enabled":true,"mp_lib":"com.rudderstack.android.sdk.core","$app_build_number":"4","$app_version_string":"1.0","$insert_id":"168cf720-6227-4b56-a98e-c49bdc7279e9","$session_id":"1662363980","token":"dummyApiKey","distinct_id":"39da706ec83d0e90","time":1662363980290}}]', }, XML: {}, FORM: {}, @@ -4530,7 +4480,7 @@ export const data = [ method: 'POST', endpoint: 'https://api.mixpanel.com/import/', headers: { - Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + Authorization: 'Basic ZHVtbXlBcGlLZXk6', 'Content-Type': 'application/json', }, params: { strict: 0 }, @@ -4538,7 +4488,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"event":"Application Opened","properties":{"build":4,"version":"1.0","anonymousId":"39da706ec83d0e90","$os":"Android","$screen_height":2984,"$screen_width":1440,"$screen_dpi":560,"$carrier":"T-Mobile","$os_version":"12","$device":"emu64a","$manufacturer":"Google","$model":"sdk_gphone64_arm64","mp_device_model":"sdk_gphone64_arm64","$wifi":true,"$bluetooth_enabled":true,"mp_lib":"com.rudderstack.android.sdk.core","$app_build_number":"4","$app_version_string":"1.0","$insert_id":"168cf720-6227-4b56-a98e-c49bdc7279e9","$session_id":"1662363980","token":"test_api_token","distinct_id":"39da706ec83d0e90","time":1662363980290}}]', + '[{"event":"Application Opened","properties":{"build":4,"version":"1.0","anonymousId":"39da706ec83d0e90","$os":"Android","$screen_height":2984,"$screen_width":1440,"$screen_dpi":560,"$carrier":"T-Mobile","$os_version":"12","$device":"emu64a","$manufacturer":"Google","$model":"sdk_gphone64_arm64","mp_device_model":"sdk_gphone64_arm64","$wifi":true,"$bluetooth_enabled":true,"mp_lib":"com.rudderstack.android.sdk.core","$app_build_number":"4","$app_version_string":"1.0","$insert_id":"168cf720-6227-4b56-a98e-c49bdc7279e9","$session_id":"1662363980","token":"dummyApiKey","distinct_id":"39da706ec83d0e90","time":1662363980290}}]', }, XML: {}, FORM: {}, @@ -4626,7 +4576,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$token":"test_api_token","$distinct_id":"hjikl","$set":{"groupId":["testGroupId"]},"$ip":"0.0.0.0"}]', + '[{"$token":"dummyApiKey","$distinct_id":"hjikl","$set":{"groupId":["testGroupId"]},"$ip":"0.0.0.0"}]', }, XML: {}, FORM: {}, @@ -4648,7 +4598,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$token":"test_api_token","$group_key":"groupId","$group_id":"testGroupId","$set":{"company":"testComp","groupId":"groupIdInTraits"}}]', + '[{"$token":"dummyApiKey","$group_key":"groupId","$group_id":"testGroupId","$set":{"company":"testComp","groupId":"groupIdInTraits"}}]', }, XML: {}, FORM: {}, @@ -4675,7 +4625,7 @@ export const data = [ description: 'Track: set device id and user id when simplified id merge api is selected', destination: overrideDestination(sampleDestination, { - token: 'test_api_token', + token: 'dummyApiKey', identityMergeApi: 'simplified', }), message: { @@ -4731,17 +4681,14 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/import/', - headers: { - Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', - 'Content-Type': 'application/json', - }, - params: { strict: 0 }, + endpoint: 'https://api.mixpanel.com/track/', + headers: {}, + params: {}, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"Product Viewed","properties":{"name":"T-Shirt","$user_id":"userId01","$os":"iOS","$screen_height":1794,"$screen_width":1080,"$screen_dpi":420,"$carrier":"Android","$os_version":"8.1.0","$device":"generic_x86","$manufacturer":"Google","$model":"Android SDK built for x86","mp_device_model":"Android SDK built for x86","$wifi":true,"$bluetooth_enabled":false,"mp_lib":"com.rudderstack.android.sdk.core","$app_build_number":"1","$app_version_string":"1.0","$insert_id":"id2","token":"test_api_token","distinct_id":"userId01","time":1579847342402,"$device_id":"anonId01"}}]', + '[{"event":"Product Viewed","properties":{"name":"T-Shirt","$user_id":"userId01","$os":"iOS","$screen_height":1794,"$screen_width":1080,"$screen_dpi":420,"$carrier":"Android","$os_version":"8.1.0","$device":"generic_x86","$manufacturer":"Google","$model":"Android SDK built for x86","mp_device_model":"Android SDK built for x86","$wifi":true,"$bluetooth_enabled":false,"mp_lib":"com.rudderstack.android.sdk.core","$app_build_number":"1","$app_version_string":"1.0","$insert_id":"id2","token":"dummyApiKey","distinct_id":"userId01","time":1579847342402,"$device_id":"anonId01"}}]', }, XML: {}, FORM: {}, @@ -4770,7 +4717,7 @@ export const data = [ { description: 'Identify: skip merge event when simplified id merge api is selected', destination: overrideDestination(sampleDestination, { - token: 'test_api_token', + token: 'dummyApiKey', identityMergeApi: 'simplified', }), message: { @@ -4851,7 +4798,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$created":"2020-01-23T08:54:02.362Z","$email":"mickey@disney.com","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$firstName":"Mickey","$lastName":"Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"userId01","$ip":"0.0.0.0","$time":1579847342402}]', + '[{"$set":{"$created":"2020-01-23T08:54:02.362Z","$email":"mickey@disney.com","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$firstName":"Mickey","$lastName":"Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyApiKey","$distinct_id":"userId01","$ip":"0.0.0.0","$time":1579847342402}]', }, XML: {}, FORM: {}, @@ -4879,7 +4826,7 @@ export const data = [ 'Identify: append $device: to deviceId while creating the user when simplified id merge api is selected', destination: overrideDestination(sampleDestination, { apiKey: 'apiKey123', - token: 'test_api_token', + token: 'dummyApiKey', identityMergeApi: 'simplified', }), message: { @@ -4959,7 +4906,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$created":"2020-01-23T08:54:02.362Z","$email":"mickey@disney.com","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$firstName":"Mickey","$lastName":"Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"test_api_token","$distinct_id":"$device:anonId01","$ip":"0.0.0.0","$time":1579847342402}]', + '[{"$set":{"$created":"2020-01-23T08:54:02.362Z","$email":"mickey@disney.com","$country_code":"USA","$city":"Disney","$initial_referrer":"https://docs.rudderstack.com","$initial_referring_domain":"docs.rudderstack.com","$name":"Mickey Mouse","$firstName":"Mickey","$lastName":"Mouse","$browser":"Chrome","$browser_version":"79.0.3945.117"},"$token":"dummyApiKey","$distinct_id":"$device:anonId01","$ip":"0.0.0.0","$time":1579847342402}]', }, XML: {}, FORM: {}, @@ -4986,7 +4933,7 @@ export const data = [ description: 'Unsupported alias call when simplified id merge api is selected', destination: overrideDestination(sampleDestination, { apiKey: 'apiKey123', - token: 'test_api_token', + token: 'dummyApiKey', identityMergeApi: 'simplified', }), message: { @@ -5075,7 +5022,7 @@ export const data = [ 'Track revenue event: set device id and user id when simplified id merge api is selected', destination: overrideDestination(sampleDestination, { apiKey: 'apiKey123', - token: 'test_api_token', + token: 'dummyApiKey', identityMergeApi: 'simplified', }), message: { @@ -5146,7 +5093,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$append":{"$transactions":{"$time":"2020-01-24T06:29:02.403Z","$amount":18.9}},"$token":"test_api_token","$distinct_id":"userId01"}]', + '[{"$append":{"$transactions":{"$time":"2020-01-24T06:29:02.403Z","$amount":18.9}},"$token":"dummyApiKey","$distinct_id":"userId01"}]', }, XML: {}, FORM: {}, @@ -5161,17 +5108,14 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/import/', - headers: { - Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', - 'Content-Type': 'application/json', - }, - params: { strict: 0 }, + endpoint: 'https://api.mixpanel.com/track/', + headers: {}, + params: {}, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"test revenue MIXPANEL","properties":{"currency":"USD","revenue":18.9,"city":"Disney","country":"USA","email":"mickey@disney.com","firstName":"Mickey","ip":"0.0.0.0","$user_id":"userId01","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"a6a0ad5a-bd26-4f19-8f75-38484e580fc7","token":"test_api_token","distinct_id":"userId01","time":1579847342403,"$device_id":"anonId01","$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', + '[{"event":"test revenue MIXPANEL","properties":{"currency":"USD","revenue":18.9,"city":"Disney","country":"USA","email":"mickey@disney.com","firstName":"Mickey","ip":"0.0.0.0","$user_id":"userId01","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"a6a0ad5a-bd26-4f19-8f75-38484e580fc7","token":"dummyApiKey","distinct_id":"userId01","time":1579847342403,"$device_id":"anonId01","$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', }, XML: {}, FORM: {}, @@ -5201,7 +5145,7 @@ export const data = [ description: 'Page with anonymous user when simplified api is selected', destination: overrideDestination(sampleDestination, { apiKey: 'apiKey123', - token: 'test_api_token', + token: 'dummyApiKey', identityMergeApi: 'simplified', }), message: { @@ -5268,17 +5212,14 @@ export const data = [ version: '1', type: 'REST', method: 'POST', - endpoint: 'https://api.mixpanel.com/import/', - headers: { - Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', - 'Content-Type': 'application/json', - }, - params: { strict: 0 }, + endpoint: 'https://api.mixpanel.com/track/', + headers: {}, + params: {}, body: { JSON: {}, JSON_ARRAY: { batch: - '[{"event":"Loaded a Page","properties":{"ip":"0.0.0.0","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"dd266c67-9199-4a52-ba32-f46ddde67312","token":"test_api_token","distinct_id":"$device:anonId01","time":1579847342402,"$device_id":"anonId01","name":"Contact Us","$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', + '[{"event":"Loaded a Page","properties":{"ip":"0.0.0.0","$current_url":"https://docs.rudderstack.com/destinations/mixpanel","$screen_dpi":2,"mp_lib":"RudderLabs JavaScript SDK","$app_build_number":"1.0.0","$app_version_string":"1.0.5","$insert_id":"dd266c67-9199-4a52-ba32-f46ddde67312","token":"dummyApiKey","distinct_id":"$device:anonId01","time":1579847342402,"$device_id":"anonId01","name":"Contact Us","$browser":"Chrome","$browser_version":"79.0.3945.117"}}]', }, XML: {}, FORM: {}, @@ -5308,7 +5249,7 @@ export const data = [ description: 'Group call with anonymous user when simplified api is selected', destination: overrideDestination(sampleDestination, { apiKey: 'apiKey123', - token: 'test_api_token', + token: 'dummyApiKey', identityMergeApi: 'simplified', groupKeySettings: [{ groupKey: 'company' }], }), @@ -5371,7 +5312,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$token":"test_api_token","$distinct_id":"$device:anonId01","$set":{"company":["testComp"]},"$ip":"0.0.0.0"}]', + '[{"$token":"dummyApiKey","$distinct_id":"$device:anonId01","$set":{"company":["testComp"]},"$ip":"0.0.0.0"}]', }, XML: {}, FORM: {}, @@ -5393,7 +5334,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$token":"test_api_token","$group_key":"company","$group_id":"testComp","$set":{"company":"testComp"}}]', + '[{"$token":"dummyApiKey","$group_key":"company","$group_id":"testComp","$set":{"company":"testComp"}}]', }, XML: {}, FORM: {}, @@ -5419,7 +5360,7 @@ export const data = [ { destination: overrideDestination(sampleDestination, { apiKey: 'apiKey123', - token: 'test_api_token', + token: 'dummyApiKey', identityMergeApi: 'simplified', groupKeySettings: [{ groupKey: 'company' }], }), @@ -5538,7 +5479,7 @@ export const data = [ }, destination: overrideDestination(sampleDestination, { apiKey: 'dummyApiKey', - token: 'test_api_token', + token: 'dummyApiKey', apiSecret: 'dummyApiKey', useNewMapping: true, }), @@ -5564,7 +5505,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$append":{"$transactions":{"$time":"2022-09-05T07:46:20.290Z","$amount":12.13}},"$token":"test_api_token","$distinct_id":"39da706ec83d0e90"}]', + '[{"$append":{"$transactions":{"$time":"2022-09-05T07:46:20.290Z","$amount":12.13}},"$token":"dummyApiKey","$distinct_id":"39da706ec83d0e90"}]', }, XML: {}, FORM: {}, @@ -5581,7 +5522,7 @@ export const data = [ method: 'POST', endpoint: 'https://api.mixpanel.com/import/', headers: { - Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + Authorization: 'Basic ZHVtbXlBcGlLZXk6', 'Content-Type': 'application/json', }, params: { strict: 0 }, @@ -5589,7 +5530,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"event":"Application Installed","properties":{"build":4,"version":"1.0","revenue":12.13,"anonymousId":"39da706ec83d0e90","$os":"Android","$screen_height":2984,"$screen_width":1440,"$screen_dpi":560,"$carrier":"T-Mobile","$os_version":"12","$device":"emu64a","$manufacturer":"Google","$model":"sdk_gphone64_arm64","mp_device_model":"sdk_gphone64_arm64","$wifi":true,"$bluetooth_enabled":true,"mp_lib":"com.rudderstack.android.sdk.core","$app_build_number":"4","$app_version_string":"1.0","$insert_id":"168cf720-6227-4b56-a98e-c49bdc7279e9","$session_id":"1662363980","token":"test_api_token","distinct_id":"39da706ec83d0e90","time":1662363980290}}]', + '[{"event":"Application Installed","properties":{"build":4,"version":"1.0","revenue":12.13,"anonymousId":"39da706ec83d0e90","$os":"Android","$screen_height":2984,"$screen_width":1440,"$screen_dpi":560,"$carrier":"T-Mobile","$os_version":"12","$device":"emu64a","$manufacturer":"Google","$model":"sdk_gphone64_arm64","mp_device_model":"sdk_gphone64_arm64","$wifi":true,"$bluetooth_enabled":true,"mp_lib":"com.rudderstack.android.sdk.core","$app_build_number":"4","$app_version_string":"1.0","$insert_id":"168cf720-6227-4b56-a98e-c49bdc7279e9","$session_id":"1662363980","token":"dummyApiKey","distinct_id":"39da706ec83d0e90","time":1662363980290}}]', }, XML: {}, FORM: {}, @@ -5653,7 +5594,7 @@ export const data = [ }, destination: overrideDestination(sampleDestination, { apiKey: 'dummyApiKey', - token: 'test_api_token', + token: 'dummyApiKey', apiSecret: 'dummyApiKey', useNewMapping: true, }), @@ -5679,7 +5620,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$append":{"$transactions":{"$time":"2022-09-05T07:46:20.290Z","$amount":23.45}},"$token":"test_api_token","$distinct_id":"39da706ec83d0e90"}]', + '[{"$append":{"$transactions":{"$time":"2022-09-05T07:46:20.290Z","$amount":23.45}},"$token":"dummyApiKey","$distinct_id":"39da706ec83d0e90"}]', }, XML: {}, FORM: {}, @@ -5696,7 +5637,7 @@ export const data = [ method: 'POST', endpoint: 'https://api.mixpanel.com/import/', headers: { - Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + Authorization: 'Basic ZHVtbXlBcGlLZXk6', 'Content-Type': 'application/json', }, params: { strict: 0 }, @@ -5704,7 +5645,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"event":"Application Installed","properties":{"build":4,"version":"1.0","revenue":23.45,"anonymousId":"39da706ec83d0e90","$os":"Android","$screen_height":2984,"$screen_width":1440,"$screen_dpi":560,"$carrier":"T-Mobile","$os_version":"12","$device":"emu64a","$manufacturer":"Google","$model":"sdk_gphone64_arm64","mp_device_model":"sdk_gphone64_arm64","$wifi":true,"$bluetooth_enabled":true,"mp_lib":"com.rudderstack.android.sdk.core","$app_build_number":"4","$app_version_string":"1.0","$insert_id":"168cf720-6227-4b56-a98e-c49bdc7279e9","$session_id":"1662363980","token":"test_api_token","distinct_id":"39da706ec83d0e90","time":null}}]', + '[{"event":"Application Installed","properties":{"build":4,"version":"1.0","revenue":23.45,"anonymousId":"39da706ec83d0e90","$os":"Android","$screen_height":2984,"$screen_width":1440,"$screen_dpi":560,"$carrier":"T-Mobile","$os_version":"12","$device":"emu64a","$manufacturer":"Google","$model":"sdk_gphone64_arm64","mp_device_model":"sdk_gphone64_arm64","$wifi":true,"$bluetooth_enabled":true,"mp_lib":"com.rudderstack.android.sdk.core","$app_build_number":"4","$app_version_string":"1.0","$insert_id":"168cf720-6227-4b56-a98e-c49bdc7279e9","$session_id":"1662363980","token":"dummyApiKey","distinct_id":"39da706ec83d0e90","time":null}}]', }, XML: {}, FORM: {}, @@ -5731,7 +5672,7 @@ export const data = [ description: 'Track: with strict mode enabled', destination: overrideDestination(sampleDestination, { apiKey: 'dummyApiKey', - token: 'test_api_token', + token: 'dummyApiKey', apiSecret: 'some_api_secret', dataResidency: 'eu', strictMode: true, @@ -5795,7 +5736,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"$set":{"$carrier":"Android","$manufacturer":"Google","$model":"Android SDK built for x86","$screen_height":1794,"$screen_width":1080,"$wifi":true,"anonymousId":"5094f5704b9cf2b3","userId":"test_user_id","$ios_devices":["test_device_token"],"$os":"iOS","$ios_device_model":"Android SDK built for x86","$ios_version":"8.1.0","$ios_app_release":"1","$ios_app_version":"1.0"},"$token":"test_api_token","$distinct_id":"test_user_id","$time":1584003903421}]', + '[{"$set":{"$carrier":"Android","$manufacturer":"Google","$model":"Android SDK built for x86","$screen_height":1794,"$screen_width":1080,"$wifi":true,"anonymousId":"5094f5704b9cf2b3","userId":"test_user_id","$ios_devices":["test_device_token"],"$os":"iOS","$ios_device_model":"Android SDK built for x86","$ios_version":"8.1.0","$ios_app_release":"1","$ios_app_version":"1.0"},"$token":"dummyApiKey","$distinct_id":"test_user_id","$time":1584003903421}]', }, XML: {}, FORM: {}, @@ -5812,7 +5753,7 @@ export const data = [ method: 'POST', endpoint: 'https://api-eu.mixpanel.com/import/', headers: { - Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + Authorization: 'Basic c29tZV9hcGlfc2VjcmV0Og==', 'Content-Type': 'application/json', }, params: { strict: 1 }, @@ -5820,7 +5761,7 @@ export const data = [ JSON: {}, JSON_ARRAY: { batch: - '[{"event":"$merge","properties":{"$distinct_ids":["test_user_id","5094f5704b9cf2b3"],"token":"test_api_token"}}]', + '[{"event":"$merge","properties":{"$distinct_ids":["test_user_id","5094f5704b9cf2b3"],"token":"dummyApiKey"}}]', }, XML: {}, FORM: {}, diff --git a/test/integrations/destinations/mp/router/data.ts b/test/integrations/destinations/mp/router/data.ts index 8716c9daa0..059e222e92 100644 --- a/test/integrations/destinations/mp/router/data.ts +++ b/test/integrations/destinations/mp/router/data.ts @@ -442,7 +442,7 @@ export const data = [ endpoint: 'https://api.mixpanel.com/import/', headers: { 'Content-Type': 'application/json', - Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + Authorization: 'Basic dGVzdF9hcGlfc2VjcmV0Og==', }, params: { strict: 1 }, body: { @@ -509,7 +509,7 @@ export const data = [ endpoint: 'https://api.mixpanel.com/import/', headers: { 'Content-Type': 'application/json', - Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + Authorization: 'Basic dGVzdF9hcGlfc2VjcmV0Og==', }, params: { strict: 1 }, body: { @@ -577,7 +577,7 @@ export const data = [ endpoint: 'https://api.mixpanel.com/import/', headers: { 'Content-Type': 'application/json', - Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + Authorization: 'Basic dGVzdF9hcGlfc2VjcmV0Og==', }, params: { strict: 1 }, body: { @@ -1166,7 +1166,7 @@ export const data = [ endpoint: 'https://api.mixpanel.com/import/', headers: { 'Content-Type': 'application/json', - Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + Authorization: 'Basic dGVzdF9hcGlfc2VjcmV0Og==', }, params: { strict: 1 }, body: { @@ -1232,7 +1232,7 @@ export const data = [ endpoint: 'https://api.mixpanel.com/import/', headers: { 'Content-Type': 'application/json', - Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + Authorization: 'Basic dGVzdF9hcGlfc2VjcmV0Og==', }, params: { strict: 1 }, body: { @@ -1299,7 +1299,7 @@ export const data = [ endpoint: 'https://api.mixpanel.com/import/', headers: { 'Content-Type': 'application/json', - Authorization: 'Basic dGVzdF9hcGlfdG9rZW46', + Authorization: 'Basic dGVzdF9hcGlfc2VjcmV0Og==', }, params: { strict: 1 }, body: { From 63a5c7333ec019c95e9e801f8beac4dd56885c9e Mon Sep 17 00:00:00 2001 From: Jayachand Date: Thu, 18 Apr 2024 15:55:06 +0530 Subject: [PATCH 41/47] chore: support event validation for old and new tracking plan payload formats (#3255) * chore: support event validation for old and new tracking plan payload formats --- src/util/eventValidation.js | 2 +- src/util/trackingPlan.js | 5 + test/__tests__/eventValidation.test.js | 235 +++++++++++++++++++++++++ 3 files changed, 241 insertions(+), 1 deletion(-) diff --git a/src/util/eventValidation.js b/src/util/eventValidation.js index 68d895dcc5..9f3ecd859d 100644 --- a/src/util/eventValidation.js +++ b/src/util/eventValidation.js @@ -126,7 +126,7 @@ async function validate(event) { trackingPlanId, trackingPlanVersion, event.message.type, - event.message.event, + event.message.type === 'track' ? event.message.event : '', workspaceId, ); diff --git a/src/util/trackingPlan.js b/src/util/trackingPlan.js index a77265a5b8..ebfbc6049f 100644 --- a/src/util/trackingPlan.js +++ b/src/util/trackingPlan.js @@ -55,6 +55,11 @@ async function getEventSchema(tpId, tpVersion, eventType, eventName, workspaceId let eventSchema; const tp = await getTrackingPlan(tpId, tpVersion, workspaceId); + if (Object.hasOwn(tp, 'events')) { + const ev = tp.events.find((e) => e.name === eventName && e.eventType === eventType); + return ev?.rules; + } + if (eventType !== 'track') { if (Object.prototype.hasOwnProperty.call(tp.rules, eventType)) { eventSchema = tp.rules[eventType]; diff --git a/test/__tests__/eventValidation.test.js b/test/__tests__/eventValidation.test.js index eb58879eb7..b802b6f886 100644 --- a/test/__tests__/eventValidation.test.js +++ b/test/__tests__/eventValidation.test.js @@ -73,6 +73,97 @@ const trackingPlan = { create_time: "2021-12-14T19:19:13.666Z", update_time: "2021-12-15T13:29:59.272Z" }; + +const newTrackingPlan = { + name: "Demo Tracking Plan", + version: 1, + events: [ + { + id: "ev_22HzyIUtuhfoI80iDfAgf47GHpw", + name: "Product clicked new", + eventType: "track", + description: "Fired when an product is clicked.", + rules: { + type: "object", + $schema: "http://json-schema.org/draft-07/schema#", + required: ["properties"], + properties: { + properties: { + $schema: "http://json-schema.org/draft-07/schema#", + additionalProperties: false, + properties: { + email: { + type: ["string"] + }, + name: { + type: ["string"] + }, + prop_float: { + type: ["number"] + }, + prop_integer: { + type: ["number"] + }, + revenue: { + type: ["number"] + } + }, + type: "object", + required: [ + "email", + "name", + "prop_float", + "prop_integer", + "revenue" + ], + allOf: [ + { + properties: { + prop_integer: { + const: 2 + }, + prop_float: { + const: 2.3 + } + } + } + ] + } + } + } + }, + { + id: "ev_22HzyIUtuhfoI80iDfAgf47GHpx", + name: "", + eventType: "group", + rules: { + type: "object", + $schema: "http://json-schema.org/draft-07/schema#", + required: ["traits"], + properties: { + traits: { + additionalProperties: false, + properties: { + company: { + type: ["string"] + }, + org: { + type: ["string"] + }, + }, + type: "object", + required: [ + "company", + ] + } + } + } + } + ], + workspaceId: "dummy_workspace_id", + createdAt: "2021-12-14T19:19:13.666Z", + updatedAt: "2021-12-15T13:29:59.272Z" +}; const sourceTpConfig = { track: { allowUnplannedEvents: "true", @@ -1364,6 +1455,134 @@ const eventValidationTestCases = [ } ]; +const eventValidationWithNewPlanTestCases = [ + { + testCase: "Group is part of new Tracking Plan + additional property violation", + event: { + metadata: { + trackingPlanId: "dummy_tracking_plan_id_new", + trackingPlanVersion: "dummy_version_new", + workspaceId: "dummy_workspace_id", + mergedTpConfig, + sourceTpConfig + }, + message: { + type: "group", + userId: "user12345", + groupId: "group1", + traits: { + company: "Company", + employees: 123 + }, + context: { + traits: { + trait1: "new-val" + }, + ip: "14.5.67.21", + library: { + name: "http" + } + }, + timestamp: "2020-01-21T00:21:34.208Z" + } + }, + trackingPlan: newTrackingPlan, + output: { + dropEvent: true, + violationType: violationTypes.AdditionalProperties + } + }, + { + testCase: + "Compatibility for Spread sheet plugin + Track is not part of new Tracking Plan and allowUnplannedEvents is set to text TRUE", + event: { + metadata: { + trackingPlanId: "dummy_tracking_plan_id_new", + trackingPlanVersion: "dummy_version_new", + workspaceId: "dummy_workspace_id", + mergedTpConfig: { + allowUnplannedEvents: "TRUE", + ajvOptions: {} + }, + sourceTpConfig: { + track: { + allowUnplannedEvents: "TRUE", + ajvOptions: {} + }, + global: { + allowUnplannedEvents: "FALSE", + ajvOptions: {} + } + } + }, + message: { + type: "track", + userId: "user-demo", + event: "New Product clicked", + properties: { + name: "Rubik's Cube", + revenue: 4.99, + prop_integer: 2, + prop_float: 2.3, + email: "demo@rudderstack.com" + }, + context: { + ip: "14.5.67.21" + }, + timestamp: "2020-02-02T00:23:09.544Z" + } + }, + trackingPlan: newTrackingPlan, + output: { + dropEvent: false, + violationType: "None" + } + }, + { + testCase: + "Track is part of new Tracking Plan + no track config and unplannedProperties is set to drop", + event: { + metadata: { + trackingPlanId: "dummy_tracking_plan_id_new", + trackingPlanVersion: "dummy_version_new", + workspaceId: "dummy_workspace_id", + mergedTpConfig: { + unplannedProperties: "drop", + ajvOptions: {} + }, + sourceTpConfig: { + global: { + unplannedProperties: "drop", + ajvOptions: {} + } + } + }, + message: { + type: "track", + userId: "user-demo", + event: "Product clicked new", + properties: { + name: "Rubik's Cube", + revenue: 4.99, + prop_integer: 2, + prop_float: 2.3, + email: "demo@rudderstack.com", + mobile: "999888777666" + }, + context: { + ip: "14.5.67.21" + }, + timestamp: "2020-02-02T00:23:09.544Z" + } + }, + trackingPlan: newTrackingPlan, + output: { + dropEvent: true, + violationType: violationTypes.AdditionalProperties + } + }, +]; + describe("Supported Event types testing", () => { eventTypesTestCases.forEach(testCase => { it(`should return isSupportedOrNot ${testCase.output} for this input eventType ${testCase.eventType} everytime`, () => { @@ -1389,6 +1608,22 @@ describe("Handle validation", () => { }); }); +describe("Handle validation with new tracking plan payload", () => { + eventValidationWithNewPlanTestCases.forEach(testCase => { + it(`should return dropEvent: ${testCase.output.dropEvent}, violationType: ${testCase.output.violationType}`, async () => { + fetch.mockResolvedValue({ + json: jest.fn().mockResolvedValue(testCase.trackingPlan), + status: 200 + }); + const { dropEvent, violationType } = await handleValidation( + testCase.event + ); + expect(dropEvent).toEqual(testCase.output.dropEvent); + expect(violationType).toEqual(testCase.output.violationType); + }); + }); +}); + describe("HandleValidationErrors", () => { validationErrorsTestCases.forEach(testCase => { it(`should return dropEvent ${testCase.output} for ${testCase.test}`, () => { From e92b052e03182deb41b20b3ec3741306afa50380 Mon Sep 17 00:00:00 2001 From: AASHISH MALIK Date: Thu, 18 Apr 2024 17:18:27 +0530 Subject: [PATCH 42/47] fix: twitter_ads logger (#3295) --- src/v0/destinations/twitter_ads/transform.js | 3 +- .../destinations/twitter_ads/router/data.ts | 204 ++++++++++++++++++ 2 files changed, 205 insertions(+), 2 deletions(-) create mode 100644 test/integrations/destinations/twitter_ads/router/data.ts diff --git a/src/v0/destinations/twitter_ads/transform.js b/src/v0/destinations/twitter_ads/transform.js index 328d8c4a9f..268dca3636 100644 --- a/src/v0/destinations/twitter_ads/transform.js +++ b/src/v0/destinations/twitter_ads/transform.js @@ -156,8 +156,7 @@ function validateRequest(message) { } } -function process(event, requestMetadata, logger) { - logger.debug(`[TWITTER ADS]: Transforming request received with info`); +function process(event) { const { message, metadata, destination } = event; validateRequest(message); diff --git a/test/integrations/destinations/twitter_ads/router/data.ts b/test/integrations/destinations/twitter_ads/router/data.ts new file mode 100644 index 0000000000..ce9aea6595 --- /dev/null +++ b/test/integrations/destinations/twitter_ads/router/data.ts @@ -0,0 +1,204 @@ +const authHeaderConstant = + 'OAuth oauth_consumer_key="qwe", oauth_nonce="V1kMh028kZLLhfeYozuL0B45Pcx6LvuW", oauth_signature="Di4cuoGv4PnCMMEeqfWTcqhvdwc%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1685603652", oauth_token="dummyAccessToken", oauth_version="1.0"'; + +export const data = [ + { + name: 'twitter_ads', + description: 'tests router flow', + feature: 'router', + module: 'destination', + version: 'v0', + input: { + request: { + body: { + input: [ + { + message: { + type: 'track', + event: 'ABC Searched', + channel: 'web', + 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', + properties: { + conversionTime: '2023-06-01T06:03:08.739Z', + tax: 2, + total: 27.5, + coupon: 'hasbros', + revenue: 48, + price: 25, + quantity: 2, + currency: 'USD', + priceCurrency: 'USD', + conversionId: '213123', + numberItems: '2323', + phone: '+919927455678', + twclid: '543', + shipping: 3, + subtotal: 22.5, + affiliation: 'Google Store', + checkout_id: 'fksdjfsdjfisjf9sdfjsd9f', + email: 'abc@ax.com', + contents: [ + { + price: '123.3345', + quantity: '12', + id: '12', + }, + { + price: 200, + quantity: 11, + id: '4', + }, + ], + }, + anonymousId: '50be5c78-6c3f-4b60-be84-97805a316fb1', + integrations: { + All: true, + }, + }, + metadata: { + secret: { + consumerKey: 'qwe', + consumerSecret: 'fdghv', + accessToken: 'dummyAccessToken', + accessTokenSecret: 'testAccessTokenSecret', + }, + }, + destination: { + Config: { + pixelId: 'dummyPixelId', + rudderAccountId: '2EOknn1JNH7WK1MfNku4fGYKkRK', + twitterAdsEventNames: [ + { + rudderEventName: 'ABC Searched', + twitterEventId: 'tw-234234324234', + }, + { + rudderEventName: 'Home Page Viewed', + twitterEventId: 'tw-odt2o-odt2q', + }, + ], + }, + }, + }, + ], + destType: 'twitter_ads', + }, + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: [ + { + batched: false, + batchedRequest: { + body: { + FORM: {}, + JSON: { + conversions: [ + { + contents: [ + { content_id: '12', content_price: 123.3345, num_items: 12 }, + { content_id: '4', content_price: 200, num_items: 11 }, + ], + conversion_id: '213123', + conversion_time: '2023-06-01T06:03:08.739Z', + event_id: 'tw-234234324234', + identifiers: [ + { + hashed_email: + '4c3c8a8cba2f3bb1e9e617301f85d1f68e816a01c7b716f482f2ab9adb8181fb', + }, + { + hashed_phone_number: + 'b308962b96b40cce7981493a372db9478edae79f83c2d8ca6cd15a39566f8c56', + }, + { twclid: '543' }, + ], + number_items: 2, + price_currency: 'USD', + value: '25', + }, + ], + }, + JSON_ARRAY: {}, + XML: {}, + }, + endpoint: 'https://ads-api.twitter.com/12/measurement/conversions/dummyPixelId', + files: {}, + headers: { + Authorization: + 'OAuth oauth_consumer_key="qwe", oauth_nonce="V1kMh028kZLLhfeYozuL0B45Pcx6LvuW", oauth_signature="Di4cuoGv4PnCMMEeqfWTcqhvdwc%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1685603652", oauth_token="dummyAccessToken", oauth_version="1.0"', + 'Content-Type': 'application/json', + }, + method: 'POST', + params: {}, + type: 'REST', + version: '1', + }, + destination: { + Config: { + pixelId: 'dummyPixelId', + rudderAccountId: '2EOknn1JNH7WK1MfNku4fGYKkRK', + twitterAdsEventNames: [ + { rudderEventName: 'ABC Searched', twitterEventId: 'tw-234234324234' }, + { rudderEventName: 'Home Page Viewed', twitterEventId: 'tw-odt2o-odt2q' }, + ], + }, + }, + metadata: [ + { + secret: { + accessToken: 'dummyAccessToken', + accessTokenSecret: 'testAccessTokenSecret', + consumerKey: 'qwe', + consumerSecret: 'fdghv', + }, + }, + ], + statusCode: 200, + }, + ], + }, + }, + }, + }, +].map((tc) => ({ + ...tc, + mockFns: (_) => { + jest.mock('../../../../../src/v0/destinations/twitter_ads/util', () => ({ + getAuthHeaderForRequest: (_a, _b) => { + return { Authorization: authHeaderConstant }; + }, + })); + }, +})); From 68c64db23231252e17aa5a78b716989a7a2d7099 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Thu, 18 Apr 2024 11:51:18 +0000 Subject: [PATCH 43/47] chore(release): 1.62.2 --- 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 5aeb88f374..87ca4738ec 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.62.2](https://github.com/rudderlabs/rudder-transformer/compare/v1.62.1...v1.62.2) (2024-04-18) + + +### Bug Fixes + +* twitter_ads logger ([#3295](https://github.com/rudderlabs/rudder-transformer/issues/3295)) ([e92b052](https://github.com/rudderlabs/rudder-transformer/commit/e92b052e03182deb41b20b3ec3741306afa50380)) + ### [1.62.1](https://github.com/rudderlabs/rudder-transformer/compare/v1.62.0...v1.62.1) (2024-04-18) diff --git a/package-lock.json b/package-lock.json index b524ed27ff..b5b413f936 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "rudder-transformer", - "version": "1.62.1", + "version": "1.62.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "rudder-transformer", - "version": "1.62.1", + "version": "1.62.2", "license": "ISC", "dependencies": { "@amplitude/ua-parser-js": "0.7.24", diff --git a/package.json b/package.json index 57da0144ac..a291bbab90 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rudder-transformer", - "version": "1.62.1", + "version": "1.62.2", "description": "", "homepage": "https://github.com/rudderlabs/rudder-transformer#readme", "bugs": { From 4bf65be47678b7d058d6389b175b836e8692b698 Mon Sep 17 00:00:00 2001 From: Sandeep Digumarty Date: Fri, 19 Apr 2024 10:52:16 +0530 Subject: [PATCH 44/47] chore: upgrade node version to v18.20.1 from v18.19.1 (#3287) --- .nvmrc | 2 +- Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.nvmrc b/.nvmrc index 3c5535cf60..99c98cdd6a 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -18.19.1 +18.20.1 diff --git a/Dockerfile b/Dockerfile index 8cd4005a7b..9fe3c1cdb2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # syntax=docker/dockerfile:1.4 -FROM node:18.19.1-alpine3.18 AS base +FROM node:18.20.1-alpine3.18 AS base ENV HUSKY 0 RUN apk update From bac3cc5670c149454a6063a55a4b901043b0ff02 Mon Sep 17 00:00:00 2001 From: Mihir Bhalala <77438541+mihir-4116@users.noreply.github.com> Date: Mon, 22 Apr 2024 16:40:16 +0530 Subject: [PATCH 45/47] fix(delighted): replace myAxios utility with handleHttpRequest utility (#3237) --- src/v0/destinations/delighted/util.js | 107 +++++++++--------- .../destinations/delighted/network.ts | 14 +++ .../destinations/delighted/processor/data.ts | 89 +++++++++++++++ 3 files changed, 159 insertions(+), 51 deletions(-) diff --git a/src/v0/destinations/delighted/util.js b/src/v0/destinations/delighted/util.js index c690bf5f5c..53f416b48d 100644 --- a/src/v0/destinations/delighted/util.js +++ b/src/v0/destinations/delighted/util.js @@ -1,14 +1,10 @@ -const { - NetworkInstrumentationError, - InstrumentationError, - NetworkError, -} = require('@rudderstack/integrations-lib'); -const myAxios = require('../../../util/myAxios'); +const { InstrumentationError, NetworkError } = require('@rudderstack/integrations-lib'); 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'); +const { handleHttpRequest } = require('../../../adapters/network'); const isValidEmail = (email) => { const re = @@ -41,6 +37,30 @@ const isValidUserIdOrError = (channel, userId) => { }; }; +/** + * Returns final status + * @param {*} status + * @returns + */ +const getErrorStatus = (status) => { + let errStatus; + switch (status) { + case 422: + case 401: + case 406: + case 403: + errStatus = 400; + break; + case 500: + case 503: + errStatus = 500; + break; + default: + errStatus = status; + } + return errStatus; +}; + const userValidity = async (channel, Config, userId) => { const paramsdata = {}; if (channel === 'email') { @@ -50,53 +70,38 @@ const userValidity = async (channel, Config, userId) => { } const basicAuth = Buffer.from(Config.apiKey).toString('base64'); - let response; - try { - response = await myAxios.get( - `${ENDPOINT}`, - { - headers: { - Authorization: `Basic ${basicAuth}`, - 'Content-Type': JSON_MIME_TYPE, - }, - params: paramsdata, + const { processedResponse } = await handleHttpRequest( + 'get', + `${ENDPOINT}`, + { + headers: { + Authorization: `Basic ${basicAuth}`, + 'Content-Type': JSON_MIME_TYPE, }, - { - destType: 'delighted', - feature: 'transformation', - requestMethod: 'GET', - endpointPath: '/people.json', - module: 'router', - }, - ); - if (response && response.data && response.status === 200 && Array.isArray(response.data)) { - return response.data.length > 0; - } - throw new NetworkInstrumentationError('Invalid response'); - } catch (error) { - let errMsg = ''; - let errStatus = 400; - if (error.response && error.response.data) { - errMsg = JSON.stringify(error.response.data); - switch (error.response.status) { - case 422: - case 401: - case 406: - case 403: - errStatus = 400; - break; - case 500: - case 503: - errStatus = 500; - break; - default: - errStatus = 400; - } - } - throw new NetworkError(`Error occurred while checking user : ${errMsg}`, errStatus, { - [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(errStatus), - }); + params: paramsdata, + }, + { + destType: 'delighted', + feature: 'transformation', + requestMethod: 'GET', + endpointPath: '/people.json', + module: 'router', + }, + ); + + if (processedResponse.status === 200 && Array.isArray(processedResponse?.response)) { + return processedResponse.response.length > 0; } + + const errStatus = getErrorStatus(processedResponse.status); + throw new NetworkError( + `Error occurred while checking user: ${JSON.stringify(processedResponse?.response || 'Invalid response')}`, + errStatus, + { + [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(errStatus), + }, + processedResponse, + ); }; const eventValidity = (Config, message) => { const event = getValueFromMessage(message, 'event'); diff --git a/test/integrations/destinations/delighted/network.ts b/test/integrations/destinations/delighted/network.ts index d9896a25e8..1ccc785ea3 100644 --- a/test/integrations/destinations/delighted/network.ts +++ b/test/integrations/destinations/delighted/network.ts @@ -27,4 +27,18 @@ export const networkCallsData = [ status: 200, }, }, + { + httpReq: { + url: 'https://api.delighted.com/v1/people.json', + method: 'GET', + headers: { Authorization: `Basic ZHVtbXlBcGlLZXlmb3JmYWlsdXJl` }, + params: { + email: 'test@rudderlabs.com', + }, + }, + httpRes: { + status: 429, + data: {}, + }, + }, ]; diff --git a/test/integrations/destinations/delighted/processor/data.ts b/test/integrations/destinations/delighted/processor/data.ts index 7a5ad7de9d..f35c2d8ecb 100644 --- a/test/integrations/destinations/delighted/processor/data.ts +++ b/test/integrations/destinations/delighted/processor/data.ts @@ -944,4 +944,93 @@ export const data = [ }, }, }, + { + name: 'delighted', + description: 'Too many request test', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + Config: { + apiKey: 'dummyApiKeyforfailure', + channel: 'email', + delay: 0, + eventNamesSettings: [ + { + event: 'Product Reviewed', + }, + ], + }, + }, + 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', + type: 'track', + userId: 'test@rudderlabs.com', + event: 'Product Reviewed', + properties: { + review_id: '12345', + product_id: '123', + rating: 3, + review_body: 'Average product, expected much more.', + }, + integrations: { + All: true, + }, + sentAt: '2019-10-14T09:03:22.563Z', + }, + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + '{"message":"Error occurred while checking user: {}","destinationResponse":{"response":{},"status":429}}', + statTags: { + destType: 'DELIGHTED', + errorCategory: 'network', + errorType: 'throttled', + feature: 'processor', + implementation: 'native', + module: 'destination', + }, + statusCode: 429, + }, + ], + }, + }, + }, ]; From 650ea9ca9ca6351aadc51bfb5038b8b2507990ec Mon Sep 17 00:00:00 2001 From: Mihir Bhalala <77438541+mihir-4116@users.noreply.github.com> Date: Wed, 24 Apr 2024 16:11:30 +0530 Subject: [PATCH 46/47] feat(iterable): component test refactor (#3250) --- .../iterable/processor/aliasTestData.ts | 97 + .../destinations/iterable/processor/data.ts | 3793 +---------------- .../iterable/processor/identifyTestData.ts | 407 ++ .../iterable/processor/pageScreenTestData.ts | 409 ++ .../iterable/processor/trackTestData.ts | 717 ++++ .../iterable/processor/validationTestData.ts | 258 ++ test/integrations/testUtils.ts | 1 + 7 files changed, 1900 insertions(+), 3782 deletions(-) create mode 100644 test/integrations/destinations/iterable/processor/aliasTestData.ts create mode 100644 test/integrations/destinations/iterable/processor/identifyTestData.ts create mode 100644 test/integrations/destinations/iterable/processor/pageScreenTestData.ts create mode 100644 test/integrations/destinations/iterable/processor/trackTestData.ts create mode 100644 test/integrations/destinations/iterable/processor/validationTestData.ts diff --git a/test/integrations/destinations/iterable/processor/aliasTestData.ts b/test/integrations/destinations/iterable/processor/aliasTestData.ts new file mode 100644 index 0000000000..cac43767bb --- /dev/null +++ b/test/integrations/destinations/iterable/processor/aliasTestData.ts @@ -0,0 +1,97 @@ +import { generateMetadata, transformResultBuilder } from './../../../testUtils'; +import { Destination } from '../../../../../src/types'; +import { ProcessorTestData } from '../../../testTypes'; + +const destination: Destination = { + ID: '123', + Name: 'iterable', + DestinationDefinition: { + ID: '123', + Name: 'iterable', + DisplayName: 'Iterable', + Config: {}, + }, + WorkspaceID: '123', + Transformations: [], + Config: { + apiKey: 'testApiKey', + preferUserId: false, + trackAllPages: true, + trackNamedPages: false, + mapToSingleEvent: false, + trackCategorisedPages: false, + }, + Enabled: true, +}; + +const headers = { + api_key: 'testApiKey', + 'Content-Type': 'application/json', +}; + +const properties = { + path: '/abc', + referrer: '', + search: '', + title: '', + url: '', + category: 'test-category', +}; + +const sentAt = '2020-08-28T16:26:16.473Z'; +const originalTimestamp = '2020-08-28T16:26:06.468Z'; + +export const aliasTestData: ProcessorTestData[] = [ + { + id: 'iterable-alias-test-1', + name: 'iterable', + description: 'Alias call with userId and previousId', + scenario: 'Business', + successCriteria: + 'Response should contain status code 200 and it should contain update email payload', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: { + anonymousId: 'anonId', + userId: 'new@email.com', + previousId: 'old@email.com', + name: 'ApplicationLoaded', + context: {}, + properties, + type: 'alias', + sentAt, + originalTimestamp, + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: '', + headers, + endpoint: 'https://api.iterable.com/api/users/updateEmail', + JSON: { + currentEmail: 'old@email.com', + newEmail: 'new@email.com', + }, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/iterable/processor/data.ts b/test/integrations/destinations/iterable/processor/data.ts index 19b370b513..12e5738641 100644 --- a/test/integrations/destinations/iterable/processor/data.ts +++ b/test/integrations/destinations/iterable/processor/data.ts @@ -1,3784 +1,13 @@ +import { identifyTestData } from './identifyTestData'; +import { trackTestData } from './trackTestData'; +import { pageScreenTestData } from './pageScreenTestData'; +import { aliasTestData } from './aliasTestData'; +import { validationTestData } from './validationTestData'; + export const data = [ - { - name: 'iterable', - description: 'Test 0', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - type: 'page', - sentAt: '2020-08-28T16:26:16.473Z', - context: { - library: { - name: 'analytics-node', - version: '0.0.3', - }, - }, - _metadata: { - nodeVersion: '10.22.0', - }, - messageId: - 'node-6f62b91e789a636929ca38aed01c5f6e-103c720d-81bd-4742-98d6-d45a65aed23e', - properties: { - url: 'https://dominos.com', - title: 'Pizza', - referrer: 'https://google.com', - }, - anonymousId: 'abcdeeeeeeeexxxx102', - originalTimestamp: '2020-08-28T16:26:06.468Z', - }, - destination: { - Config: { - apiKey: '62d12498c37c4fd8a1a546c2d35c2f60', - mapToSingleEvent: false, - trackAllPages: false, - trackCategorisedPages: true, - trackNamedPages: false, - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - error: 'Invalid page call', - statTags: { - destType: 'ITERABLE', - errorCategory: 'dataValidation', - errorType: 'configuration', - feature: 'processor', - implementation: 'native', - module: 'destination', - }, - statusCode: 400, - }, - ], - }, - }, - }, - { - name: 'iterable', - description: 'Test 1', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - type: 'identify', - sentAt: '2020-08-28T16:26:06.466Z', - traits: { - city: 'Bangalore', - name: 'manashi', - email: 'manashi@website.com', - country: 'India', - }, - context: { - traits: { - city: 'Bangalore', - name: 'manashi', - email: 'manashi@website.com', - country: 'India', - preferUserId: false, - }, - library: { - name: 'analytics-node', - version: '0.0.3', - }, - }, - _metadata: { - nodeVersion: '10.22.0', - }, - messageId: - 'node-cc3ef811f686139ee527b806ee0129ef-163a3a88-266f-447e-8cce-34a8f42f8dcd', - anonymousId: 'abcdeeeeeeeexxxx102', - originalTimestamp: '2020-08-28T16:26:06.462Z', - }, - destination: { - Config: { - preferUserId: false, - apiKey: '62d12498c37c4fd8a1a546c2d35c2f60', - mapToSingleEvent: false, - trackAllPages: true, - trackCategorisedPages: false, - trackNamedPages: false, - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - body: { - XML: {}, - JSON_ARRAY: {}, - FORM: {}, - JSON: { - email: 'manashi@website.com', - userId: 'abcdeeeeeeeexxxx102', - dataFields: { - city: 'Bangalore', - name: 'manashi', - email: 'manashi@website.com', - country: 'India', - }, - preferUserId: false, - mergeNestedObjects: true, - }, - }, - type: 'REST', - files: {}, - method: 'POST', - params: {}, - headers: { - api_key: '62d12498c37c4fd8a1a546c2d35c2f60', - 'Content-Type': 'application/json', - }, - version: '1', - endpoint: 'https://api.iterable.com/api/users/update', - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'iterable', - description: 'Test 2', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - type: 'track', - event: 'Email Opened', - sentAt: '2020-08-28T16:26:16.473Z', - context: { - library: { - name: 'analytics-node', - version: '0.0.3', - }, - }, - _metadata: { - nodeVersion: '10.22.0', - }, - messageId: - 'node-570110489d3e99b234b18af9a9eca9d4-6009779e-82d7-469d-aaeb-5ccf162b0453', - properties: { - subject: 'resume validate', - sendtime: '2020-01-01', - sendlocation: 'akashdeep@gmail.com', - }, - anonymousId: 'abcdeeeeeeeexxxx102', - originalTimestamp: '2020-08-28T16:26:06.468Z', - }, - destination: { - Config: { - apiKey: '62d12498c37c4fd8a1a546c2d35c2f60', - mapToSingleEvent: false, - trackAllPages: true, - trackCategorisedPages: false, - trackNamedPages: false, - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - body: { - XML: {}, - JSON_ARRAY: {}, - FORM: {}, - JSON: { - userId: 'abcdeeeeeeeexxxx102', - createdAt: 1598631966468, - eventName: 'Email Opened', - dataFields: { - subject: 'resume validate', - sendtime: '2020-01-01', - sendlocation: 'akashdeep@gmail.com', - }, - }, - }, - type: 'REST', - files: {}, - method: 'POST', - params: {}, - headers: { - api_key: '62d12498c37c4fd8a1a546c2d35c2f60', - 'Content-Type': 'application/json', - }, - version: '1', - endpoint: 'https://api.iterable.com/api/events/track', - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'iterable', - description: 'Test 3', - 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: 'sayan@gmail.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', - ip: '0.0.0.0', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - }, - type: 'page', - messageId: '5e10d13a-bf9a-44bf-b884-43a9e591ea71', - originalTimestamp: '2019-10-14T11:15:18.299Z', - anonymousId: '00000000000000000000000000', - userId: '12345', - properties: { - path: '/abc', - referrer: '', - search: '', - title: '', - url: '', - category: 'test-category', - }, - integrations: { - All: true, - }, - name: 'ApplicationLoaded', - sentAt: '2019-10-14T11:15:53.296Z', - }, - destination: { - Config: { - apiKey: '12345', - mapToSingleEvent: false, - trackAllPages: false, - trackCategorisedPages: true, - trackNamedPages: false, - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://api.iterable.com/api/events/track', - headers: { - 'Content-Type': 'application/json', - api_key: '12345', - }, - params: {}, - body: { - JSON: { - email: 'sayan@gmail.com', - dataFields: { - path: '/abc', - referrer: '', - search: '', - title: '', - url: '', - category: 'test-category', - }, - userId: '12345', - eventName: 'ApplicationLoaded page', - createdAt: 1571051718299, - }, - XML: {}, - JSON_ARRAY: {}, - FORM: {}, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'iterable', - description: 'Test 4', - 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: 'sayan@gmail.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', - ip: '0.0.0.0', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - }, - type: 'page', - messageId: '5e10d13a-bf9a-44bf-b884-43a9e591ea71', - originalTimestamp: '2019-10-14T11:15:18.299Z', - anonymousId: '00000000000000000000000000', - userId: '12345', - properties: { - path: '/abc', - referrer: '', - search: '', - title: '', - url: '', - category: 'test-category', - campaignId: '123456', - templateId: '1213458', - }, - integrations: { - All: true, - }, - name: 'ApplicationLoaded', - sentAt: '2019-10-14T11:15:53.296Z', - }, - destination: { - Config: { - apiKey: '12345', - mapToSingleEvent: true, - trackAllPages: true, - trackCategorisedPages: false, - trackNamedPages: false, - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://api.iterable.com/api/events/track', - headers: { - 'Content-Type': 'application/json', - api_key: '12345', - }, - params: {}, - body: { - JSON: { - email: 'sayan@gmail.com', - dataFields: { - path: '/abc', - referrer: '', - search: '', - title: '', - url: '', - category: 'test-category', - campaignId: '123456', - templateId: '1213458', - }, - userId: '12345', - eventName: 'Loaded a Page', - createdAt: 1571051718299, - campaignId: 123456, - templateId: 1213458, - }, - XML: {}, - JSON_ARRAY: {}, - FORM: {}, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'iterable', - description: 'Test 5', - 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: 'sayan@gmail.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', - ip: '0.0.0.0', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - }, - type: 'page', - messageId: '5e10d13a-bf9a-44bf-b884-43a9e591ea71', - originalTimestamp: '2019-10-14T11:15:18.299Z', - anonymousId: '00000000000000000000000000', - userId: '12345', - properties: { - path: '/abc', - referrer: '', - search: '', - title: '', - url: '', - name: 'test-name', - }, - integrations: { - All: true, - }, - name: 'ApplicationLoaded', - sentAt: '2019-10-14T11:15:53.296Z', - }, - destination: { - Config: { - apiKey: '12345', - mapToSingleEvent: false, - trackAllPages: false, - trackCategorisedPages: false, - trackNamedPages: true, - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://api.iterable.com/api/events/track', - headers: { - 'Content-Type': 'application/json', - api_key: '12345', - }, - params: {}, - body: { - JSON: { - email: 'sayan@gmail.com', - dataFields: { - path: '/abc', - referrer: '', - search: '', - title: '', - url: '', - name: 'test-name', - }, - userId: '12345', - eventName: 'ApplicationLoaded page', - createdAt: 1571051718299, - }, - XML: {}, - JSON_ARRAY: {}, - FORM: {}, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'iterable', - description: 'Test 6', - 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: 'sayan@gmail.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', - ip: '0.0.0.0', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - }, - type: 'page', - messageId: '5e10d13a-bf9a-44bf-b884-43a9e591ea71', - originalTimestamp: '2019-10-14T11:15:18.299Z', - anonymousId: '00000000000000000000000000', - userId: '12345', - properties: { - path: '/abc', - referrer: '', - search: '', - title: '', - url: '', - }, - integrations: { - All: true, - }, - name: 'ApplicationLoaded', - sentAt: '2019-10-14T11:15:53.296Z', - }, - destination: { - Config: { - apiKey: '12345', - mapToSingleEvent: false, - trackAllPages: true, - trackCategorisedPages: false, - trackNamedPages: false, - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://api.iterable.com/api/events/track', - headers: { - 'Content-Type': 'application/json', - api_key: '12345', - }, - params: {}, - body: { - JSON: { - email: 'sayan@gmail.com', - dataFields: { - path: '/abc', - referrer: '', - search: '', - title: '', - url: '', - }, - userId: '12345', - eventName: 'ApplicationLoaded page', - createdAt: 1571051718299, - }, - XML: {}, - JSON_ARRAY: {}, - FORM: {}, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'iterable', - description: 'Test 7', - 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: 'sayan@gmail.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', - ip: '0.0.0.0', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - }, - type: 'screen', - messageId: '5e10d13a-bf9a-44bf-b884-43a9e591ea71', - originalTimestamp: '2019-10-14T11:15:18.299Z', - anonymousId: '00000000000000000000000000', - userId: '12345', - properties: { - path: '/abc', - referrer: '', - search: '', - title: '', - url: '', - category: 'test-category', - }, - integrations: { - All: true, - }, - name: 'ApplicationLoaded', - sentAt: '2019-10-14T11:15:53.296Z', - }, - destination: { - Config: { - apiKey: '12345', - mapToSingleEvent: false, - trackAllPages: false, - trackCategorisedPages: true, - trackNamedPages: false, - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://api.iterable.com/api/events/track', - headers: { - 'Content-Type': 'application/json', - api_key: '12345', - }, - params: {}, - body: { - JSON: { - email: 'sayan@gmail.com', - dataFields: { - path: '/abc', - referrer: '', - search: '', - title: '', - url: '', - category: 'test-category', - }, - userId: '12345', - eventName: 'ApplicationLoaded screen', - createdAt: 1571051718299, - }, - XML: {}, - JSON_ARRAY: {}, - FORM: {}, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'iterable', - description: 'Test 8', - 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: 'sayan@gmail.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', - ip: '0.0.0.0', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - }, - type: 'screen', - messageId: '5e10d13a-bf9a-44bf-b884-43a9e591ea71', - originalTimestamp: '2019-10-14T11:15:18.299Z', - anonymousId: '00000000000000000000000000', - userId: '12345', - properties: { - path: '/abc', - referrer: '', - search: '', - title: '', - url: '', - category: 'test-category', - campaignId: '123456', - templateId: '1213458', - }, - integrations: { - All: true, - }, - name: 'ApplicationLoaded', - sentAt: '2019-10-14T11:15:53.296Z', - }, - destination: { - Config: { - apiKey: '12345', - mapToSingleEvent: true, - trackAllPages: true, - trackCategorisedPages: false, - trackNamedPages: false, - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://api.iterable.com/api/events/track', - headers: { - 'Content-Type': 'application/json', - api_key: '12345', - }, - params: {}, - body: { - JSON: { - email: 'sayan@gmail.com', - dataFields: { - path: '/abc', - referrer: '', - search: '', - title: '', - url: '', - category: 'test-category', - campaignId: '123456', - templateId: '1213458', - }, - userId: '12345', - eventName: 'Loaded a Screen', - createdAt: 1571051718299, - campaignId: 123456, - templateId: 1213458, - }, - XML: {}, - JSON_ARRAY: {}, - FORM: {}, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'iterable', - description: 'Test 9', - 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: 'sayan@gmail.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', - ip: '0.0.0.0', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - }, - type: 'screen', - messageId: '5e10d13a-bf9a-44bf-b884-43a9e591ea71', - originalTimestamp: '2019-10-14T11:15:18.299Z', - anonymousId: '00000000000000000000000000', - userId: '12345', - properties: { - path: '/abc', - referrer: '', - search: '', - title: '', - url: '', - name: 'test-name', - }, - integrations: { - All: true, - }, - name: 'ApplicationLoaded', - sentAt: '2019-10-14T11:15:53.296Z', - }, - destination: { - Config: { - apiKey: '12345', - mapToSingleEvent: false, - trackAllPages: false, - trackCategorisedPages: false, - trackNamedPages: true, - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://api.iterable.com/api/events/track', - headers: { - 'Content-Type': 'application/json', - api_key: '12345', - }, - params: {}, - body: { - JSON: { - email: 'sayan@gmail.com', - dataFields: { - path: '/abc', - referrer: '', - search: '', - title: '', - url: '', - name: 'test-name', - }, - userId: '12345', - eventName: 'ApplicationLoaded screen', - createdAt: 1571051718299, - }, - XML: {}, - JSON_ARRAY: {}, - FORM: {}, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'iterable', - description: 'Test 10', - 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: 'sayan@gmail.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', - ip: '0.0.0.0', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - }, - type: 'screen', - messageId: '5e10d13a-bf9a-44bf-b884-43a9e591ea71', - originalTimestamp: '2019-10-14T11:15:18.299Z', - anonymousId: '00000000000000000000000000', - userId: '12345', - properties: { - path: '/abc', - referrer: '', - search: '', - title: '', - url: '', - }, - integrations: { - All: true, - }, - name: 'ApplicationLoaded', - sentAt: '2019-10-14T11:15:53.296Z', - }, - destination: { - Config: { - apiKey: '12345', - mapToSingleEvent: false, - trackAllPages: true, - trackCategorisedPages: false, - trackNamedPages: false, - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://api.iterable.com/api/events/track', - headers: { - 'Content-Type': 'application/json', - api_key: '12345', - }, - params: {}, - body: { - JSON: { - email: 'sayan@gmail.com', - dataFields: { - path: '/abc', - referrer: '', - search: '', - title: '', - url: '', - }, - userId: '12345', - eventName: 'ApplicationLoaded screen', - createdAt: 1571051718299, - }, - XML: {}, - JSON_ARRAY: {}, - FORM: {}, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'iterable', - description: 'Test 11', - 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: 'ruchira@rudderlabs.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', - ip: '0.0.0.0', - os: { - id: '72e528f869711c3d', - manufacturer: 'Google', - model: 'sdk_gphone_x86', - name: 'generic_x86_arm', - token: 'some_device_token', - type: 'android', - }, - screen: { - density: 2, - }, - }, - type: 'group', - messageId: '84e26acc-56a5-4835-8233-591137fca468', - originalTimestamp: '2019-10-14T09:03:17.562Z', - anonymousId: '00000000000000000000000000', - userId: '123456', - integrations: { - All: true, - }, - sentAt: '2019-10-14T09:03:22.563Z', - }, - destination: { - Config: { - apiKey: '12345', - mapToSingleEvent: false, - trackAllPages: true, - trackCategorisedPages: false, - trackNamedPages: false, - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - error: 'Message type group not supported', - statTags: { - destType: 'ITERABLE', - errorCategory: 'dataValidation', - errorType: 'instrumentation', - feature: 'processor', - implementation: 'native', - module: 'destination', - }, - statusCode: 400, - }, - ], - }, - }, - }, - { - name: 'iterable', - description: 'Test 12', - 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: 'ruchira@rudderlabs.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', - ip: '0.0.0.0', - os: { - id: '72e528f869711c3d', - manufacturer: 'Google', - model: 'sdk_gphone_x86', - name: 'generic_x86_arm', - token: 'some_device_token', - type: 'android', - }, - screen: { - density: 2, - }, - }, - type: 'identify', - messageId: '84e26acc-56a5-4835-8233-591137fca468', - originalTimestamp: '2019-10-14T09:03:17.562Z', - anonymousId: '00000000000000000000000000', - userId: '123456', - integrations: { - All: true, - }, - sentAt: '2019-10-14T09:03:22.563Z', - }, - destination: { - Config: { - mergeNestedObjects: false, - apiKey: '12345', - mapToSingleEvent: false, - trackAllPages: true, - trackCategorisedPages: false, - trackNamedPages: false, - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://api.iterable.com/api/users/update', - headers: { - 'Content-Type': 'application/json', - api_key: '12345', - }, - params: {}, - body: { - JSON: { - email: 'ruchira@rudderlabs.com', - dataFields: { - email: 'ruchira@rudderlabs.com', - }, - userId: '123456', - preferUserId: true, - mergeNestedObjects: false, - }, - XML: {}, - JSON_ARRAY: {}, - FORM: {}, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'iterable', - description: 'Test 13', - 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', - }, - device: { - token: 'sample_push_token', - name: 'sample_device_name', - model: 'sample_device_model', - manufacturer: 'sample_device_manufacturer', - type: 'ios', - }, - traits: { - email: 'ruchira@rudderlabs.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', - ip: '0.0.0.0', - os: { - id: '72e528f869711c3d', - manufacturer: 'Google', - model: 'sdk_gphone_x86', - name: 'generic_x86_arm', - token: 'some_device_token', - type: 'android', - }, - screen: { - density: 2, - }, - }, - type: 'identify', - messageId: '84e26acc-56a5-4835-8233-591137fca468', - originalTimestamp: '2019-10-14T09:03:17.562Z', - anonymousId: '00000000000000000000000000', - userId: '123456', - integrations: { - All: true, - }, - sentAt: '2019-10-14T09:03:22.563Z', - }, - destination: { - Config: { - apiKey: '12345', - mapToSingleEvent: false, - trackAllPages: true, - trackCategorisedPages: false, - trackNamedPages: false, - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://api.iterable.com/api/users/update', - headers: { - 'Content-Type': 'application/json', - api_key: '12345', - }, - params: {}, - body: { - JSON: { - email: 'ruchira@rudderlabs.com', - dataFields: { - email: 'ruchira@rudderlabs.com', - }, - userId: '123456', - preferUserId: true, - mergeNestedObjects: true, - }, - XML: {}, - JSON_ARRAY: {}, - FORM: {}, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'iterable', - description: 'Test 14', - 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', - }, - device: { - token: 'sample_push_token', - name: 'sample_device_name', - model: 'sample_device_model', - manufacturer: 'sample_device_manufacturer', - type: 'android', - }, - traits: { - email: 'ruchira@rudderlabs.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', - ip: '0.0.0.0', - os: { - id: '72e528f869711c3d', - manufacturer: 'Google', - model: 'sdk_gphone_x86', - name: 'generic_x86_arm', - token: 'some_device_token', - type: 'android', - }, - screen: { - density: 2, - }, - }, - type: 'identify', - messageId: '84e26acc-56a5-4835-8233-591137fca468', - originalTimestamp: '2019-10-14T09:03:17.562Z', - anonymousId: '00000000000000000000000000', - userId: '123456', - integrations: { - All: true, - }, - sentAt: '2019-10-14T09:03:22.563Z', - }, - destination: { - Config: { - apiKey: '12345', - mapToSingleEvent: false, - trackAllPages: true, - trackCategorisedPages: false, - trackNamedPages: false, - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://api.iterable.com/api/users/update', - headers: { - 'Content-Type': 'application/json', - api_key: '12345', - }, - params: {}, - body: { - JSON: { - email: 'ruchira@rudderlabs.com', - dataFields: { - email: 'ruchira@rudderlabs.com', - }, - userId: '123456', - preferUserId: true, - mergeNestedObjects: true, - }, - XML: {}, - JSON_ARRAY: {}, - FORM: {}, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'iterable', - description: 'Test 15', - 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: 'sayan@gmail.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', - ip: '0.0.0.0', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - }, - event: 'product added', - type: 'track', - messageId: '5e10d13a-bf9a-44bf-b884-43a9e591ea71', - originalTimestamp: '2019-10-14T11:15:18.299Z', - anonymousId: '00000000000000000000000000', - userId: '12345', - properties: { - campaignId: '1', - templateId: '0', - orderId: 10000, - total: 1000, - products: [ - { - product_id: '507f1f77bcf86cd799439011', - sku: '45790-32', - name: 'Monopoly: 3rd Edition', - price: '19', - position: '1', - category: 'cars', - url: 'https://www.example.com/product/path', - image_url: 'https://www.example.com/product/path.jpg', - quantity: '2', - }, - { - product_id: '507f1f77bcf86cd7994390112', - sku: '45790-322', - name: 'Monopoly: 3rd Edition2', - price: '192', - quantity: 22, - position: '12', - category: 'Cars2', - url: 'https://www.example.com/product/path2', - image_url: 'https://www.example.com/product/path.jpg2', - }, - ], - }, - integrations: { - All: true, - }, - name: 'ApplicationLoaded', - sentAt: '2019-10-14T11:15:53.296Z', - }, - destination: { - Config: { - apiKey: '12345', - mapToSingleEvent: false, - trackAllPages: true, - trackCategorisedPages: false, - trackNamedPages: false, - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://api.iterable.com/api/commerce/updateCart', - headers: { - 'Content-Type': 'application/json', - api_key: '12345', - }, - params: {}, - body: { - JSON: { - user: { - email: 'sayan@gmail.com', - dataFields: { - email: 'sayan@gmail.com', - }, - userId: '12345', - preferUserId: true, - mergeNestedObjects: true, - }, - items: [ - { - id: '507f1f77bcf86cd799439011', - sku: '45790-32', - name: 'Monopoly: 3rd Edition', - categories: ['cars'], - price: 19, - quantity: 2, - imageUrl: 'https://www.example.com/product/path.jpg', - url: 'https://www.example.com/product/path', - }, - { - id: '507f1f77bcf86cd7994390112', - sku: '45790-322', - name: 'Monopoly: 3rd Edition2', - categories: ['Cars2'], - price: 192, - quantity: 22, - imageUrl: 'https://www.example.com/product/path.jpg2', - url: 'https://www.example.com/product/path2', - }, - ], - }, - XML: {}, - JSON_ARRAY: {}, - FORM: {}, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'iterable', - description: 'Test 16', - 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: 'sayan@gmail.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', - ip: '0.0.0.0', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - }, - event: 'order completed', - type: 'track', - messageId: '5e10d13a-bf9a-44bf-b884-43a9e591ea71', - originalTimestamp: '2019-10-14T11:15:18.299Z', - anonymousId: '00000000000000000000000000', - userId: '12345', - properties: { - orderId: 10000, - total: '1000', - campaignId: '123456', - templateId: '1213458', - products: [ - { - product_id: '507f1f77bcf86cd799439011', - sku: '45790-32', - name: 'Monopoly: 3rd Edition', - price: '19', - position: '1', - category: 'Cars', - url: 'https://www.example.com/product/path', - image_url: 'https://www.example.com/product/path.jpg', - quantity: 2, - }, - { - product_id: '507f1f77bcf86cd7994390112', - sku: '45790-322', - name: 'Monopoly: 3rd Edition2', - price: '192', - quantity: '22', - position: '12', - category: 'Cars2', - url: 'https://www.example.com/product/path2', - image_url: 'https://www.example.com/product/path.jpg2', - }, - ], - }, - integrations: { - All: true, - }, - name: 'ApplicationLoaded', - sentAt: '2019-10-14T11:15:53.296Z', - }, - destination: { - Config: { - apiKey: '12345', - mapToSingleEvent: false, - trackAllPages: true, - trackCategorisedPages: false, - trackNamedPages: false, - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://api.iterable.com/api/commerce/trackPurchase', - headers: { - 'Content-Type': 'application/json', - api_key: '12345', - }, - params: {}, - body: { - JSON: { - dataFields: { - orderId: 10000, - total: '1000', - campaignId: '123456', - templateId: '1213458', - products: [ - { - product_id: '507f1f77bcf86cd799439011', - sku: '45790-32', - name: 'Monopoly: 3rd Edition', - price: '19', - position: '1', - category: 'Cars', - url: 'https://www.example.com/product/path', - image_url: 'https://www.example.com/product/path.jpg', - quantity: 2, - }, - { - product_id: '507f1f77bcf86cd7994390112', - sku: '45790-322', - name: 'Monopoly: 3rd Edition2', - price: '192', - quantity: '22', - position: '12', - category: 'Cars2', - url: 'https://www.example.com/product/path2', - image_url: 'https://www.example.com/product/path.jpg2', - }, - ], - }, - id: '10000', - createdAt: 1571051718299, - campaignId: 123456, - templateId: 1213458, - total: 1000, - user: { - email: 'sayan@gmail.com', - dataFields: { - email: 'sayan@gmail.com', - }, - userId: '12345', - preferUserId: true, - mergeNestedObjects: true, - }, - items: [ - { - id: '507f1f77bcf86cd799439011', - sku: '45790-32', - name: 'Monopoly: 3rd Edition', - categories: ['Cars'], - price: 19, - quantity: 2, - imageUrl: 'https://www.example.com/product/path.jpg', - url: 'https://www.example.com/product/path', - }, - { - id: '507f1f77bcf86cd7994390112', - sku: '45790-322', - name: 'Monopoly: 3rd Edition2', - categories: ['Cars2'], - price: 192, - quantity: 22, - imageUrl: 'https://www.example.com/product/path.jpg2', - url: 'https://www.example.com/product/path2', - }, - ], - }, - XML: {}, - JSON_ARRAY: {}, - FORM: {}, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'iterable', - description: 'Test 17', - 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: 'sayan@gmail.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: '2019-10-14T11:15:18.300Z', - anonymousId: '00000000000000000000000000', - userId: '12345', - event: 'test track event GA3', - properties: { - email: 'ruchira@rudderlabs.com', - campaignId: '1', - templateId: '0', - category: 'test-category', - user_actual_role: 'system_admin, system_user', - user_actual_id: 12345, - }, - integrations: { - All: true, - }, - sentAt: '2019-10-14T11:15:53.296Z', - }, - destination: { - Config: { - apiKey: '12345', - mapToSingleEvent: false, - trackAllPages: true, - trackCategorisedPages: false, - trackNamedPages: false, - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://api.iterable.com/api/events/track', - headers: { - 'Content-Type': 'application/json', - api_key: '12345', - }, - params: {}, - body: { - JSON: { - email: 'ruchira@rudderlabs.com', - dataFields: { - campaignId: '1', - templateId: '0', - category: 'test-category', - user_actual_role: 'system_admin, system_user', - user_actual_id: 12345, - email: 'ruchira@rudderlabs.com', - }, - userId: '12345', - eventName: 'test track event GA3', - createdAt: 1571051718300, - campaignId: 1, - templateId: 0, - }, - XML: {}, - JSON_ARRAY: {}, - FORM: {}, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'iterable', - description: 'Test 18', - 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', - }, - 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: { - id: '72e528f869711c3d', - manufacturer: 'Google', - model: 'sdk_gphone_x86', - name: 'generic_x86_arm', - token: 'some_device_token', - type: 'android', - }, - screen: { - density: 2, - }, - }, - traits: { - email: 'ruchira@rudderlabs.com', - }, - type: 'identify', - messageId: '84e26acc-56a5-4835-8233-591137fca468', - originalTimestamp: '2019-10-14T09:03:17.562Z', - anonymousId: '00000000000000000000000000', - userId: '123456', - integrations: { - All: true, - }, - sentAt: '2019-10-14T09:03:22.563Z', - }, - destination: { - Config: { - apiKey: '12345', - mapToSingleEvent: false, - trackAllPages: true, - trackCategorisedPages: false, - trackNamedPages: false, - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://api.iterable.com/api/users/update', - headers: { - 'Content-Type': 'application/json', - api_key: '12345', - }, - params: {}, - body: { - JSON: { - email: 'ruchira@rudderlabs.com', - dataFields: { - email: 'ruchira@rudderlabs.com', - }, - userId: '123456', - preferUserId: true, - mergeNestedObjects: true, - }, - XML: {}, - JSON_ARRAY: {}, - FORM: {}, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'iterable', - description: 'Test 19', - 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', - }, - 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: { - id: '72e528f869711c3d', - manufacturer: 'Google', - model: 'sdk_gphone_x86', - name: 'generic_x86_arm', - token: 'some_device_token', - type: 'android', - }, - screen: { - density: 2, - }, - }, - type: 'identify', - messageId: '84e26acc-56a5-4835-8233-591137fca468', - originalTimestamp: '2019-10-14T09:03:17.562Z', - integrations: { - All: true, - }, - sentAt: '2019-10-14T09:03:22.563Z', - }, - destination: { - Config: { - apiKey: '12345', - mapToSingleEvent: false, - trackAllPages: true, - trackCategorisedPages: false, - trackNamedPages: false, - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - error: 'userId or email is mandatory for this request', - statTags: { - destType: 'ITERABLE', - errorCategory: 'dataValidation', - errorType: 'instrumentation', - feature: 'processor', - implementation: 'native', - module: 'destination', - }, - statusCode: 400, - }, - ], - }, - }, - }, - { - name: 'iterable', - description: 'Test 20', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - type: 'page', - sentAt: '2020-08-28T16:26:16.473Z', - _metadata: { - nodeVersion: '10.22.0', - }, - messageId: - 'node-6f62b91e789a636929ca38aed01c5f6e-103c720d-81bd-4742-98d6-d45a65aed23e', - properties: { - url: 'https://dominos.com', - title: 'Pizza', - referrer: 'https://google.com', - }, - anonymousId: 'abcdeeeeeeeexxxx102', - originalTimestamp: '2020-08-28T16:26:06.468Z', - }, - destination: { - Config: { - apiKey: '62d12498c37c4fd8a1a546c2d35c2f60', - mapToSingleEvent: false, - trackAllPages: false, - trackCategorisedPages: true, - trackNamedPages: false, - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - error: 'Invalid page call', - statTags: { - destType: 'ITERABLE', - errorCategory: 'dataValidation', - errorType: 'configuration', - feature: 'processor', - implementation: 'native', - module: 'destination', - }, - statusCode: 400, - }, - ], - }, - }, - }, - { - name: 'iterable', - description: 'Test 21', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - type: 'track', - event: 'Product Added', - sentAt: '2021-07-09T05:27:17.908Z', - userId: '8751', - channel: 'web', - context: { - os: { - name: '', - version: '', - }, - app: { - name: 'RudderLabs JavaScript SDK', - build: '1.0.0', - version: '1.0.16', - namespace: 'com.rudderlabs.javascript', - }, - page: { - url: 'https://joybird.com/cabinets/vira-console-cabinet/', - path: '/cabinets/vira-console-cabinet/', - title: 'Vira Console Cabinet | Joybird', - search: '', - referrer: '$direct', - referring_domain: '', - }, - locale: 'en-us', - screen: { - density: 2, - }, - traits: { - email: 'jessica@jlpdesign.net', - }, - library: { - name: 'RudderLabs JavaScript SDK', - version: '1.0.16', - }, - campaign: {}, - userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15', - }, - rudderId: '1c42e104-97ec-4f54-a328-2379623583fe', - messageId: 'e58f6624-a1c3-48f4-a6af-610389602304', - timestamp: '2021-07-09T05:27:18.131Z', - properties: { - sku: 'JB24691400-W05', - name: 'Vira Console Cabinet', - price: 797, - cart_id: 'bd9b8dbf4ef8ee01d4206b04fe2ee6ae', - variant: 'Oak', - quantity: 1, - quickship: true, - full_price: 1328, - product_id: 10606, - non_interaction: 1, - }, - receivedAt: '2021-07-09T05:27:18.131Z', - request_ip: '162.224.233.114', - anonymousId: '8a7ff986-62d8-45ca-9a16-8895b3f9d341', - integrations: { - All: true, - }, - originalTimestamp: '2021-07-09T05:27:17.908Z', - }, - destination: { - Config: { - credentials: 'abc', - eventToTopicMap: [ - { - from: 'track', - to: 'projects/big-query-integration-poc/topics/test', - }, - ], - }, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://api.iterable.com/api/commerce/updateCart', - headers: { - 'Content-Type': 'application/json', - }, - params: {}, - body: { - JSON: { - user: { - email: 'jessica@jlpdesign.net', - dataFields: { - email: 'jessica@jlpdesign.net', - }, - userId: '8751', - preferUserId: true, - mergeNestedObjects: true, - }, - items: [ - { - id: 10606, - sku: 'JB24691400-W05', - name: 'Vira Console Cabinet', - price: 797, - quantity: 1, - }, - ], - }, - XML: {}, - JSON_ARRAY: {}, - FORM: {}, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'iterable', - description: 'Test 22', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - channel: 'sources', - context: { - externalId: [ - { - id: 'lynnanderson@smith.net', - identifierType: 'email', - type: 'ITERABLE-users', - }, - ], - mappedToDestination: 'true', - sources: { - batch_id: 'f5f240d0-0acb-46e0-b043-57fb0aabbadd', - job_id: '1zAj94bEy8komdqnYtSoDp0VmGs/Syncher', - job_run_id: 'c5tar6cqgmgmcjvupdhg', - task_id: 'tt_10_rows_check', - task_run_id: 'c5tar6cqgmgmcjvupdi0', - version: 'release.v1.6.8', - }, - }, - messageId: '2f052f7c-f694-4849-a7ed-a432f7ffa0a4', - originalTimestamp: '2021-10-28T14:03:50.503Z', - receivedAt: '2021-10-28T14:03:46.567Z', - recordId: '8', - request_ip: '10.1.94.92', - rudderId: 'c0f6843e-e3d6-4946-9752-fa339fbadef2', - sentAt: '2021-10-28T14:03:50.503Z', - timestamp: '2021-10-28T14:03:46.566Z', - traits: { - administrative_unit: 'Minnesota', - am_pm: 'AM', - boolean: true, - firstname: 'Jacqueline', - pPower: 'AM', - userId: 'Jacqueline', - }, - type: 'identify', - userId: 'lynnanderson@smith.net', - }, - destination: { - ID: '1zia9wKshXt80YksLmUdJnr7IHI', - Name: 'test_iterable', - DestinationDefinition: { - ID: '1iVQvTRMsPPyJzwol0ifH93QTQ6', - Name: 'ITERABLE', - DisplayName: 'Iterable', - Config: { - destConfig: { - defaultConfig: [ - 'apiKey', - 'mapToSingleEvent', - 'trackAllPages', - 'trackCategorisedPages', - 'trackNamedPages', - ], - }, - excludeKeys: [], - includeKeys: [], - saveDestinationResponse: true, - secretKeys: [], - supportedMessageTypes: ['identify', 'page', 'screen', 'track'], - supportedSourceTypes: [ - 'android', - 'ios', - 'web', - 'unity', - 'amp', - 'cloud', - 'warehouse', - 'reactnative', - 'flutter', - 'cordova', - ], - supportsVisualMapper: true, - transformAt: 'processor', - transformAtV1: 'processor', - }, - ResponseRules: null, - }, - Config: { - apiKey: '12345', - mapToSingleEvent: true, - trackAllPages: false, - trackCategorisedPages: true, - trackNamedPages: true, - }, - Enabled: true, - Transformations: [], - IsProcessorEnabled: true, - }, - libraries: [], - request: { - query: {}, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://api.iterable.com/api/users/update', - headers: { - 'Content-Type': 'application/json', - api_key: '12345', - }, - params: {}, - body: { - JSON: { - email: 'lynnanderson@smith.net', - dataFields: { - administrative_unit: 'Minnesota', - am_pm: 'AM', - boolean: true, - firstname: 'Jacqueline', - pPower: 'AM', - userId: 'Jacqueline', - email: 'lynnanderson@smith.net', - }, - userId: 'lynnanderson@smith.net', - preferUserId: true, - mergeNestedObjects: true, - }, - JSON_ARRAY: {}, - XML: {}, - FORM: {}, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'iterable', - description: 'Test 23', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - channel: 'sources', - context: { - externalId: [ - { - id: 'Matthew', - identifierType: 'userId', - type: 'ITERABLE-users', - }, - ], - mappedToDestination: 'true', - sources: { - batch_id: '230d7c79-a2c2-4b2a-90bb-06ba988d3bb4', - job_id: '1zjj9aF5UkmavBi4HtM3kWOGvy0/Syncher', - job_run_id: 'c5tb4gsqgmgmcjvuplhg', - task_id: 'tt_10_rows', - task_run_id: 'c5tb4gsqgmgmcjvupli0', - version: 'release.v1.6.8', - }, - }, - messageId: 'c4c97310-463b-4300-9215-5cfddcb2a769', - originalTimestamp: '2021-10-28T14:23:43.254Z', - receivedAt: '2021-10-28T14:23:38.300Z', - recordId: '3', - request_ip: '10.1.94.92', - rudderId: '7300f5e3-bdb5-489e-ac7e-47876e487de9', - sentAt: '2021-10-28T14:23:43.254Z', - timestamp: '2021-10-28T14:23:38.299Z', - traits: { - price: 'GB', - }, - type: 'identify', - userId: 'Matthew', - }, - destination: { - ID: '1zjjHN4RQ6t4DPj3HVpp0b6XW4A', - Name: 'test_userId_uniq', - DestinationDefinition: { - ID: '1iVQvTRMsPPyJzwol0ifH93QTQ6', - Name: 'ITERABLE', - DisplayName: 'Iterable', - Config: { - destConfig: { - defaultConfig: [ - 'apiKey', - 'mapToSingleEvent', - 'trackAllPages', - 'trackCategorisedPages', - 'trackNamedPages', - ], - }, - excludeKeys: [], - includeKeys: [], - saveDestinationResponse: true, - secretKeys: [], - supportedMessageTypes: ['identify', 'page', 'screen', 'track'], - supportedSourceTypes: [ - 'android', - 'ios', - 'web', - 'unity', - 'amp', - 'cloud', - 'warehouse', - 'reactnative', - 'flutter', - 'cordova', - ], - supportsVisualMapper: true, - transformAt: 'processor', - transformAtV1: 'processor', - }, - ResponseRules: null, - }, - Config: { - apiKey: '12345', - mapToSingleEvent: true, - trackAllPages: false, - trackCategorisedPages: true, - trackNamedPages: true, - }, - Enabled: true, - Transformations: [], - IsProcessorEnabled: true, - }, - libraries: [], - request: { - query: {}, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://api.iterable.com/api/users/update', - headers: { - 'Content-Type': 'application/json', - api_key: '12345', - }, - params: {}, - body: { - JSON: { - dataFields: { - price: 'GB', - userId: 'Matthew', - }, - userId: 'Matthew', - preferUserId: true, - mergeNestedObjects: true, - }, - JSON_ARRAY: {}, - XML: {}, - FORM: {}, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'iterable', - description: 'Test 24', - 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', - }, - device: { - token: 'sample_push_token', - name: 'sample_device_name', - model: 'sample_device_model', - manufacturer: 'sample_device_manufacturer', - type: 'watchos', - }, - traits: { - email: 'ruchira@rudderlabs.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', - ip: '0.0.0.0', - screen: { - density: 2, - }, - }, - type: 'identify', - messageId: '84e26acc-56a5-4835-8233-591137fca468', - originalTimestamp: '2019-10-14T09:03:17.562Z', - anonymousId: '00000000000000000000000000', - userId: '123456', - integrations: { - All: true, - }, - sentAt: '2019-10-14T09:03:22.563Z', - }, - destination: { - Config: { - apiKey: '12345', - mapToSingleEvent: false, - trackAllPages: true, - trackCategorisedPages: false, - trackNamedPages: false, - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://api.iterable.com/api/users/update', - headers: { - 'Content-Type': 'application/json', - api_key: '12345', - }, - params: {}, - body: { - JSON: { - email: 'ruchira@rudderlabs.com', - dataFields: { - email: 'ruchira@rudderlabs.com', - }, - userId: '123456', - preferUserId: true, - mergeNestedObjects: true, - }, - JSON_ARRAY: {}, - XML: {}, - FORM: {}, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'iterable', - description: 'Test 25', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - type: 'alias', - sentAt: '2020-08-28T16:26:16.473Z', - context: { - library: { - name: 'analytics-node', - version: '0.0.3', - }, - }, - _metadata: { - nodeVersion: '10.22.0', - }, - messageId: - 'node-6f62b91e789a636929ca38aed01c5f6e-103c720d-81bd-4742-98d6-d45a65aed23e', - properties: { - url: 'https://dominos.com', - title: 'Pizza', - referrer: 'https://google.com', - }, - userId: 'new@email.com', - previousId: 'old@email.com', - anonymousId: 'abcdeeeeeeeexxxx102', - originalTimestamp: '2020-08-28T16:26:06.468Z', - }, - destination: { - Config: { - apiKey: '62d12498c37c4fd8a1a546c2d35c2f60', - mapToSingleEvent: false, - trackAllPages: false, - trackCategorisedPages: true, - trackNamedPages: false, - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - body: { - XML: {}, - JSON_ARRAY: {}, - FORM: {}, - JSON: { - currentEmail: 'old@email.com', - newEmail: 'new@email.com', - }, - }, - type: 'REST', - files: {}, - method: 'POST', - params: {}, - headers: { - api_key: '62d12498c37c4fd8a1a546c2d35c2f60', - 'Content-Type': 'application/json', - }, - version: '1', - endpoint: 'https://api.iterable.com/api/users/updateEmail', - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'iterable', - description: 'Test 26', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - type: 'alias', - sentAt: '2020-08-28T16:26:16.473Z', - context: { - library: { - name: 'analytics-node', - version: '0.0.3', - }, - }, - _metadata: { - nodeVersion: '10.22.0', - }, - messageId: - 'node-6f62b91e789a636929ca38aed01c5f6e-103c720d-81bd-4742-98d6-d45a65aed23e', - properties: { - url: 'https://dominos.com', - title: 'Pizza', - referrer: 'https://google.com', - }, - userId: 'new@email.com', - anonymousId: 'abcdeeeeeeeexxxx102', - originalTimestamp: '2020-08-28T16:26:06.468Z', - }, - destination: { - Config: { - apiKey: '62d12498c37c4fd8a1a546c2d35c2f60', - mapToSingleEvent: false, - trackAllPages: false, - trackCategorisedPages: true, - trackNamedPages: false, - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - error: 'Missing required value from "previousId"', - statTags: { - destType: 'ITERABLE', - errorCategory: 'dataValidation', - errorType: 'instrumentation', - feature: 'processor', - implementation: 'native', - module: 'destination', - }, - statusCode: 400, - }, - ], - }, - }, - }, - { - name: 'iterable', - description: 'Test 27', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - type: 'alias', - sentAt: '2020-08-28T16:26:16.473Z', - context: { - library: { - name: 'analytics-node', - version: '0.0.3', - }, - }, - _metadata: { - nodeVersion: '10.22.0', - }, - messageId: - 'node-6f62b91e789a636929ca38aed01c5f6e-103c720d-81bd-4742-98d6-d45a65aed23e', - properties: { - url: 'https://dominos.com', - title: 'Pizza', - referrer: 'https://google.com', - }, - previousId: 'old@email.com', - anonymousId: 'abcdeeeeeeeexxxx102', - originalTimestamp: '2020-08-28T16:26:06.468Z', - }, - destination: { - Config: { - apiKey: '62d12498c37c4fd8a1a546c2d35c2f60', - mapToSingleEvent: false, - trackAllPages: false, - trackCategorisedPages: true, - trackNamedPages: false, - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - error: 'Missing required value from "userId"', - statTags: { - destType: 'ITERABLE', - errorCategory: 'dataValidation', - errorType: 'instrumentation', - feature: 'processor', - implementation: 'native', - module: 'destination', - }, - statusCode: 400, - }, - ], - }, - }, - }, - { - name: 'iterable', - description: 'Test 28', - 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: 'john@gmail.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', - ip: '0.0.0.0', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - }, - event: 'product added', - type: 'track', - messageId: '5e10d13a-bf9a-44bf-b884-43a9e591ea71', - originalTimestamp: '2019-10-14T11:15:18.299Z', - anonymousId: '00000000000000000000000000', - userId: '12345', - properties: { - campaignId: '1', - templateId: '0', - orderId: 10000, - total: 1000, - products: [ - { - product_id: '507f1f77bcf86cd799439011', - sku: '45790-32', - name: 'Monopoly: 3rd Edition', - price: '19', - position: '1', - category: ['bikes', 'cars', 'motors'], - url: 'https://www.example.com/product/path', - image_url: 'https://www.example.com/product/path.jpg', - quantity: '2', - }, - { - product_id: '507f1f77bcf86cd7994390112', - sku: '45790-322', - name: 'Monopoly: 3rd Edition2', - price: '192', - quantity: 22, - position: '12', - category: ['Bikes2', 'cars2', 'motors2'], - url: 'https://www.example.com/product/path2', - image_url: 'https://www.example.com/product/path.jpg2', - }, - ], - }, - integrations: { - All: true, - }, - name: 'ApplicationLoaded', - sentAt: '2019-10-14T11:15:53.296Z', - }, - destination: { - Config: { - apiKey: '12345', - mapToSingleEvent: false, - trackAllPages: true, - trackCategorisedPages: false, - trackNamedPages: false, - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://api.iterable.com/api/commerce/updateCart', - headers: { - 'Content-Type': 'application/json', - api_key: '12345', - }, - params: {}, - body: { - JSON: { - user: { - email: 'john@gmail.com', - dataFields: { - email: 'john@gmail.com', - }, - userId: '12345', - preferUserId: true, - mergeNestedObjects: true, - }, - items: [ - { - id: '507f1f77bcf86cd799439011', - sku: '45790-32', - name: 'Monopoly: 3rd Edition', - categories: ['bikes', 'cars', 'motors'], - price: 19, - quantity: 2, - imageUrl: 'https://www.example.com/product/path.jpg', - url: 'https://www.example.com/product/path', - }, - { - id: '507f1f77bcf86cd7994390112', - sku: '45790-322', - name: 'Monopoly: 3rd Edition2', - categories: ['Bikes2', 'cars2', 'motors2'], - price: 192, - quantity: 22, - imageUrl: 'https://www.example.com/product/path.jpg2', - url: 'https://www.example.com/product/path2', - }, - ], - }, - XML: {}, - JSON_ARRAY: {}, - FORM: {}, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'iterable', - description: 'Test 29', - 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: 'sayan@gmail.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', - ip: '0.0.0.0', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - }, - event: 'product added', - type: 'track', - messageId: '5e10d13a-bf9a-44bf-b884-43a9e591ea71', - originalTimestamp: '2019-10-14T11:15:18.299Z', - anonymousId: '00000000000000000000000000', - userId: '12345', - properties: { - campaignId: '1', - templateId: '0', - orderId: 10000, - total: 1000, - products: [ - { - product_id: '507f1f77bcf86cd799439011', - sku: '45790-32', - name: 'Monopoly: 3rd Edition', - price: '19', - position: '1', - category: 'shirts,pants,trousers', - url: 'https://www.example.com/product/path', - image_url: 'https://www.example.com/product/path.jpg', - quantity: '2', - }, - { - product_id: '507f1f77bcf86cd7994390112', - sku: '45790-322', - name: 'Monopoly: 3rd Edition2', - price: '192', - quantity: 22, - position: '12', - category: 'Cars2', - url: 'https://www.example.com/product/path2', - image_url: 'https://www.example.com/product/path.jpg2', - }, - ], - }, - integrations: { - All: true, - }, - name: 'ApplicationLoaded', - sentAt: '2019-10-14T11:15:53.296Z', - }, - destination: { - Config: { - apiKey: '12345', - mapToSingleEvent: false, - trackAllPages: true, - trackCategorisedPages: false, - trackNamedPages: false, - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://api.iterable.com/api/commerce/updateCart', - headers: { - 'Content-Type': 'application/json', - api_key: '12345', - }, - params: {}, - body: { - JSON: { - user: { - email: 'sayan@gmail.com', - dataFields: { - email: 'sayan@gmail.com', - }, - userId: '12345', - preferUserId: true, - mergeNestedObjects: true, - }, - items: [ - { - id: '507f1f77bcf86cd799439011', - sku: '45790-32', - name: 'Monopoly: 3rd Edition', - categories: ['shirts', 'pants', 'trousers'], - price: 19, - quantity: 2, - imageUrl: 'https://www.example.com/product/path.jpg', - url: 'https://www.example.com/product/path', - }, - { - id: '507f1f77bcf86cd7994390112', - sku: '45790-322', - name: 'Monopoly: 3rd Edition2', - categories: ['Cars2'], - price: 192, - quantity: 22, - imageUrl: 'https://www.example.com/product/path.jpg2', - url: 'https://www.example.com/product/path2', - }, - ], - }, - XML: {}, - JSON_ARRAY: {}, - FORM: {}, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'iterable', - description: 'Test 30', - 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: 'sayan@gmail.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', - ip: '0.0.0.0', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - }, - event: 'product added', - type: 'track', - messageId: '5e10d13a-bf9a-44bf-b884-43a9e591ea71', - originalTimestamp: '2019-10-14T11:15:18.299Z', - anonymousId: '00000000000000000000000000', - userId: '12345', - properties: { - campaignId: '1', - templateId: '0', - orderId: 10000, - total: 1000, - product_id: '507f1f77bcf86cd7994390112', - sku: '45790-322', - name: 'Monopoly: 3rd Edition2', - price: '192', - quantity: 22, - position: '12', - category: 'Cars2', - url: 'https://www.example.com/product/path2', - image_url: 'https://www.example.com/product/path.jpg2', - }, - integrations: { - All: true, - }, - name: 'ApplicationLoaded', - sentAt: '2019-10-14T11:15:53.296Z', - }, - destination: { - Config: { - apiKey: '12345', - mapToSingleEvent: false, - trackAllPages: true, - trackCategorisedPages: false, - trackNamedPages: false, - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://api.iterable.com/api/commerce/updateCart', - headers: { - 'Content-Type': 'application/json', - api_key: '12345', - }, - params: {}, - body: { - JSON: { - user: { - email: 'sayan@gmail.com', - dataFields: { - email: 'sayan@gmail.com', - }, - userId: '12345', - preferUserId: true, - mergeNestedObjects: true, - }, - items: [ - { - id: '507f1f77bcf86cd7994390112', - sku: '45790-322', - name: 'Monopoly: 3rd Edition2', - categories: ['Cars2'], - price: 192, - quantity: 22, - imageUrl: 'https://www.example.com/product/path.jpg2', - url: 'https://www.example.com/product/path2', - }, - ], - }, - XML: {}, - JSON_ARRAY: {}, - FORM: {}, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'iterable', - description: 'Test 31', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - destination: { - Config: { - passcode: - 'fbee74a147828e2932c701d19dc1f2dcfa4ac0048be3aa3a88d427090a59dc1c0fa002f1', - accountId: '476550467', - trackAnonymous: true, - enableObjectIdMapping: false, - }, - }, - message: { - channel: 'web', - context: { - app: { - build: '1.0.0', - name: 'RudderLabs JavaScript SDK', - namespace: 'com.rudderlabs.javascript', - version: '1.0.0', - }, - traits: { - email: 'sayan@gmail.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', - ip: '0.0.0.0', - os: { - name: '', - version: '', - }, - screen: { - density: 2, - }, - }, - event: 'order completed', - type: 'track', - messageId: '5e10d13a-bf9a-44bf-b884-43a9e591ea71', - originalTimestamp: '2019-10-14T11:15:18.299Z', - anonymousId: '00000000000000000000000000', - userId: '12345', - properties: { - product_id: 1234, - name: 'Shoes', - price: 45, - quantity: 1, - orderId: 10000, - total: '1000', - campaignId: '123456', - templateId: '1213458', - }, - integrations: { - All: true, - }, - name: 'ApplicationLoaded', - sentAt: '2019-10-14T11:15:53.296Z', - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://api.iterable.com/api/commerce/trackPurchase', - headers: { - 'Content-Type': 'application/json', - }, - params: {}, - body: { - JSON: { - dataFields: { - product_id: 1234, - name: 'Shoes', - price: 45, - quantity: 1, - orderId: 10000, - total: '1000', - campaignId: '123456', - templateId: '1213458', - }, - id: '10000', - createdAt: 1571051718299, - campaignId: 123456, - templateId: 1213458, - total: 1000, - user: { - email: 'sayan@gmail.com', - dataFields: { - email: 'sayan@gmail.com', - }, - userId: '12345', - preferUserId: true, - mergeNestedObjects: true, - }, - items: [ - { - id: 1234, - name: 'Shoes', - price: 45, - quantity: 1, - }, - ], - }, - JSON_ARRAY: {}, - XML: {}, - FORM: {}, - }, - files: {}, - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'iterable', - description: 'Test 32', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - type: 'track', - sentAt: '2020-08-28T16:26:16.473Z', - context: { - library: { - name: 'analytics-node', - version: '0.0.3', - }, - }, - _metadata: { - nodeVersion: '10.22.0', - }, - messageId: - 'node-570110489d3e99b234b18af9a9eca9d4-6009779e-82d7-469d-aaeb-5ccf162b0453', - properties: { - subject: 'resume validate', - sendtime: '2020-01-01', - sendlocation: 'akashdeep@gmail.com', - }, - anonymousId: 'abcdeeeeeeeexxxx102', - originalTimestamp: '2020-08-28T16:26:06.468Z', - }, - destination: { - Config: { - apiKey: '62d12498c37c4fd8a1a546c2d35c2f60', - mapToSingleEvent: false, - trackAllPages: true, - trackCategorisedPages: false, - trackNamedPages: false, - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - body: { - XML: {}, - JSON_ARRAY: {}, - FORM: {}, - JSON: { - userId: 'abcdeeeeeeeexxxx102', - createdAt: 1598631966468, - dataFields: { - subject: 'resume validate', - sendtime: '2020-01-01', - sendlocation: 'akashdeep@gmail.com', - }, - }, - }, - type: 'REST', - files: {}, - method: 'POST', - params: {}, - headers: { - api_key: '62d12498c37c4fd8a1a546c2d35c2f60', - 'Content-Type': 'application/json', - }, - version: '1', - endpoint: 'https://api.iterable.com/api/events/track', - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'iterable', - description: 'Test 33', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - type: 'track', - event: '', - sentAt: '2020-08-28T16:26:16.473Z', - context: { - library: { - name: 'analytics-node', - version: '0.0.3', - }, - }, - _metadata: { - nodeVersion: '10.22.0', - }, - messageId: - 'node-570110489d3e99b234b18af9a9eca9d4-6009779e-82d7-469d-aaeb-5ccf162b0453', - properties: { - subject: 'resume validate', - sendtime: '2020-01-01', - sendlocation: 'akashdeep@gmail.com', - }, - anonymousId: 'abcdeeeeeeeexxxx102', - originalTimestamp: '2020-08-28T16:26:06.468Z', - }, - destination: { - Config: { - apiKey: '62d12498c37c4fd8a1a546c2d35c2f60', - mapToSingleEvent: false, - trackAllPages: true, - trackCategorisedPages: false, - trackNamedPages: false, - }, - Enabled: true, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - body: { - XML: {}, - JSON_ARRAY: {}, - FORM: {}, - JSON: { - userId: 'abcdeeeeeeeexxxx102', - createdAt: 1598631966468, - dataFields: { - subject: 'resume validate', - sendtime: '2020-01-01', - sendlocation: 'akashdeep@gmail.com', - }, - }, - }, - type: 'REST', - files: {}, - method: 'POST', - params: {}, - headers: { - api_key: '62d12498c37c4fd8a1a546c2d35c2f60', - 'Content-Type': 'application/json', - }, - version: '1', - endpoint: 'https://api.iterable.com/api/events/track', - userId: '', - }, - statusCode: 200, - }, - ], - }, - }, - }, + ...identifyTestData, + ...trackTestData, + ...pageScreenTestData, + ...aliasTestData, + ...validationTestData, ]; diff --git a/test/integrations/destinations/iterable/processor/identifyTestData.ts b/test/integrations/destinations/iterable/processor/identifyTestData.ts new file mode 100644 index 0000000000..d05f87a11f --- /dev/null +++ b/test/integrations/destinations/iterable/processor/identifyTestData.ts @@ -0,0 +1,407 @@ +import { + generateMetadata, + transformResultBuilder, + generateIndentifyPayload, +} from './../../../testUtils'; +import { Destination } from '../../../../../src/types'; +import { ProcessorTestData } from '../../../testTypes'; + +const destination: Destination = { + ID: '123', + Name: 'iterable', + DestinationDefinition: { + ID: '123', + Name: 'iterable', + DisplayName: 'Iterable', + Config: {}, + }, + WorkspaceID: '123', + Transformations: [], + Config: { + apiKey: 'testApiKey', + preferUserId: false, + trackAllPages: true, + trackNamedPages: false, + mapToSingleEvent: false, + trackCategorisedPages: false, + }, + Enabled: true, +}; + +const headers = { + api_key: 'testApiKey', + 'Content-Type': 'application/json', +}; + +const user1Traits = { + name: 'manashi', + country: 'India', + city: 'Bangalore', + email: 'manashi@website.com', +}; + +const user2Traits = { + am_pm: 'AM', + pPower: 'AM', + boolean: true, + userId: 'Jacqueline', + firstname: 'Jacqueline', + administrative_unit: 'Minnesota', +}; + +const userId = 'userId'; +const anonymousId = 'anonId'; +const sentAt = '2020-08-28T16:26:16.473Z'; +const originalTimestamp = '2020-08-28T16:26:06.468Z'; + +const updateUserEndpoint = 'https://api.iterable.com/api/users/update'; + +export const identifyTestData: ProcessorTestData[] = [ + { + id: 'iterable-identify-test-1', + name: 'iterable', + description: 'Indentify call to update user in iterable with user traits', + scenario: 'Business', + successCriteria: + 'Response should contain status code 200 and it should contain update user payload with all user traits', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: { + anonymousId, + context: { + traits: user1Traits, + }, + traits: user1Traits, + type: 'identify', + sentAt, + originalTimestamp, + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: '', + headers, + endpoint: updateUserEndpoint, + JSON: { + email: user1Traits.email, + userId: anonymousId, + dataFields: user1Traits, + preferUserId: false, + mergeNestedObjects: true, + }, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'iterable-identify-test-2', + name: 'iterable', + description: 'Indentify call to update user email', + scenario: 'Business', + successCriteria: + 'Response should contain status code 200 and it should contain update user payload with new email sent in payload', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: generateIndentifyPayload({ + userId, + anonymousId, + context: { + traits: { email: 'ruchira@rudderlabs.com' }, + }, + type: 'identify', + sentAt, + originalTimestamp, + }), + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: '', + headers, + endpoint: updateUserEndpoint, + JSON: { + email: 'ruchira@rudderlabs.com', + userId, + dataFields: { + email: 'ruchira@rudderlabs.com', + }, + preferUserId: false, + mergeNestedObjects: true, + }, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'iterable-identify-test-3', + name: 'iterable', + description: 'Indentify call to update user email with preferUserId config set to true', + scenario: 'Business', + successCriteria: + 'Response should contain status code 200 and it should contain update user payload with new email sent in payload', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { ...destination, Config: { ...destination.Config, preferUserId: true } }, + message: generateIndentifyPayload({ + userId, + anonymousId, + context: { + traits: { email: 'ruchira@rudderlabs.com' }, + }, + type: 'identify', + sentAt, + originalTimestamp, + }), + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: '', + headers, + endpoint: updateUserEndpoint, + JSON: { + email: 'ruchira@rudderlabs.com', + userId, + dataFields: { + email: 'ruchira@rudderlabs.com', + }, + preferUserId: true, + mergeNestedObjects: true, + }, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'iterable-identify-test-4', + name: 'iterable', + description: + 'Indentify call to update user email with traits present at root instead of context.traits', + scenario: 'Business', + successCriteria: + 'Response should contain status code 200 and it should contain update user payload with new email sent in payload', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { ...destination, Config: { ...destination.Config, preferUserId: true } }, + message: generateIndentifyPayload({ + userId, + anonymousId, + context: { + traits: {}, + }, + traits: { email: 'ruchira@rudderlabs.com' }, + type: 'identify', + sentAt, + originalTimestamp, + }), + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: '', + headers, + endpoint: updateUserEndpoint, + JSON: { + email: 'ruchira@rudderlabs.com', + userId, + dataFields: { + email: 'ruchira@rudderlabs.com', + }, + preferUserId: true, + mergeNestedObjects: true, + }, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'iterable-identify-test-5', + name: 'iterable', + description: 'Iterable rEtl test to update user', + scenario: 'Business', + successCriteria: + 'Response should contain status code 200 and it should contain update user payload', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { ...destination, Config: { ...destination.Config, preferUserId: true } }, + message: { + userId, + anonymousId, + context: { + externalId: [ + { + id: 'lynnanderson@smith.net', + identifierType: 'email', + type: 'ITERABLE-users', + }, + ], + mappedToDestination: 'true', + }, + traits: user2Traits, + type: 'identify', + sentAt, + originalTimestamp, + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: '', + headers, + endpoint: updateUserEndpoint, + JSON: { + email: 'lynnanderson@smith.net', + userId, + dataFields: { ...user2Traits, email: 'lynnanderson@smith.net' }, + preferUserId: true, + mergeNestedObjects: true, + }, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'iterable-identify-test-6', + name: 'iterable', + description: 'Iterable rEtl test to update user traits', + scenario: 'Business', + successCriteria: + 'Response should contain status code 200 and it should contain update user payload', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: { + userId: 'Matthew', + anonymousId, + context: { + externalId: [ + { + id: 'Matthew', + identifierType: 'userId', + type: 'ITERABLE-users', + }, + ], + mappedToDestination: 'true', + }, + traits: user2Traits, + type: 'identify', + sentAt, + originalTimestamp, + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: '', + headers, + endpoint: updateUserEndpoint, + JSON: { + userId: 'Matthew', + dataFields: { ...user2Traits, userId: 'Matthew' }, + preferUserId: false, + mergeNestedObjects: true, + }, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/iterable/processor/pageScreenTestData.ts b/test/integrations/destinations/iterable/processor/pageScreenTestData.ts new file mode 100644 index 0000000000..074d6b56df --- /dev/null +++ b/test/integrations/destinations/iterable/processor/pageScreenTestData.ts @@ -0,0 +1,409 @@ +import { generateMetadata, transformResultBuilder } from './../../../testUtils'; +import { Destination } from '../../../../../src/types'; +import { ProcessorTestData } from '../../../testTypes'; + +const destination: Destination = { + ID: '123', + Name: 'iterable', + DestinationDefinition: { + ID: '123', + Name: 'iterable', + DisplayName: 'Iterable', + Config: {}, + }, + WorkspaceID: '123', + Transformations: [], + Config: { + apiKey: 'testApiKey', + preferUserId: false, + trackAllPages: true, + trackNamedPages: false, + mapToSingleEvent: false, + trackCategorisedPages: false, + }, + Enabled: true, +}; + +const headers = { + api_key: 'testApiKey', + 'Content-Type': 'application/json', +}; + +const properties = { + path: '/abc', + referrer: '', + search: '', + title: '', + url: '', + category: 'test-category', +}; + +const anonymousId = 'anonId'; +const sentAt = '2020-08-28T16:26:16.473Z'; +const originalTimestamp = '2020-08-28T16:26:06.468Z'; + +const pageEndpoint = 'https://api.iterable.com/api/events/track'; + +export const pageScreenTestData: ProcessorTestData[] = [ + { + id: 'iterable-page-test-1', + name: 'iterable', + description: 'Page call with name and properties', + scenario: 'Business', + successCriteria: + 'Response should contain status code 200 and it should contain page name and all properties', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: { + anonymousId, + name: 'ApplicationLoaded', + context: { + traits: { + email: 'sayan@gmail.com', + }, + }, + properties, + type: 'page', + sentAt, + originalTimestamp, + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: '', + headers, + endpoint: pageEndpoint, + JSON: { + userId: anonymousId, + dataFields: properties, + email: 'sayan@gmail.com', + createdAt: 1598631966468, + eventName: 'ApplicationLoaded page', + }, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'iterable-page-test-2', + name: 'iterable', + description: 'Page call with name and properties and mapToSingleEvent config set to true', + scenario: 'Business', + successCriteria: + 'Response should contain status code 200 and it should contain page name and all properties', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + ...destination, + Config: { ...destination.Config, mapToSingleEvent: true }, + }, + message: { + anonymousId, + name: 'ApplicationLoaded', + context: { + traits: { + email: 'sayan@gmail.com', + }, + }, + properties: { ...properties, campaignId: '123456', templateId: '1213458' }, + type: 'page', + sentAt, + originalTimestamp, + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: '', + headers, + endpoint: pageEndpoint, + JSON: { + campaignId: 123456, + templateId: 1213458, + userId: anonymousId, + email: 'sayan@gmail.com', + createdAt: 1598631966468, + eventName: 'Loaded a Page', + dataFields: { ...properties, campaignId: '123456', templateId: '1213458' }, + }, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'iterable-page-test-3', + name: 'iterable', + description: 'Page call with name and properties and trackNamedPages config set to true', + scenario: 'Business', + successCriteria: + 'Response should contain status code 200 and it should contain page name and all properties', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + ...destination, + Config: { ...destination.Config, trackNamedPages: true, trackAllPages: false }, + }, + message: { + anonymousId, + name: 'ApplicationLoaded', + context: { + traits: { + email: 'sayan@gmail.com', + }, + }, + properties, + type: 'page', + sentAt, + originalTimestamp, + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: '', + headers, + endpoint: pageEndpoint, + JSON: { + userId: anonymousId, + email: 'sayan@gmail.com', + createdAt: 1598631966468, + eventName: 'ApplicationLoaded page', + dataFields: properties, + }, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'iterable-screen-test-1', + name: 'iterable', + description: 'Screen call with name and properties', + scenario: 'Business', + successCriteria: + 'Response should contain status code 200 and it should contain screen name and all properties', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + ...destination, + Config: { ...destination.Config, trackCategorisedPages: true, trackAllPages: false }, + }, + message: { + anonymousId, + name: 'ApplicationLoaded', + context: { + traits: { + email: 'sayan@gmail.com', + }, + }, + properties, + type: 'screen', + sentAt, + originalTimestamp, + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: '', + headers, + endpoint: pageEndpoint, + JSON: { + userId: anonymousId, + dataFields: properties, + email: 'sayan@gmail.com', + createdAt: 1598631966468, + eventName: 'ApplicationLoaded screen', + }, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'iterable-screen-test-2', + name: 'iterable', + description: 'Screen call with name and properties and mapToSingleEvent config set to true', + scenario: 'Business', + successCriteria: + 'Response should contain status code 200 and it should contain screen name and all properties', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + ...destination, + Config: { ...destination.Config, mapToSingleEvent: true }, + }, + message: { + anonymousId, + name: 'ApplicationLoaded', + context: { + traits: { + email: 'sayan@gmail.com', + }, + }, + properties: { ...properties, campaignId: '123456', templateId: '1213458' }, + type: 'screen', + sentAt, + originalTimestamp, + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: '', + headers, + endpoint: pageEndpoint, + JSON: { + campaignId: 123456, + templateId: 1213458, + userId: anonymousId, + email: 'sayan@gmail.com', + createdAt: 1598631966468, + eventName: 'Loaded a Screen', + dataFields: { ...properties, campaignId: '123456', templateId: '1213458' }, + }, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'iterable-screen-test-3', + name: 'iterable', + description: 'Page call with name and properties and trackNamedPages config set to true', + scenario: 'Business', + successCriteria: + 'Response should contain status code 200 and it should contain page name and all properties', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + ...destination, + Config: { ...destination.Config, trackNamedPages: true, trackAllPages: false }, + }, + message: { + anonymousId, + name: 'ApplicationLoaded', + context: { + traits: { + email: 'sayan@gmail.com', + }, + }, + properties, + type: 'screen', + sentAt, + originalTimestamp, + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: '', + headers, + endpoint: pageEndpoint, + JSON: { + userId: anonymousId, + email: 'sayan@gmail.com', + createdAt: 1598631966468, + eventName: 'ApplicationLoaded screen', + dataFields: properties, + }, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/iterable/processor/trackTestData.ts b/test/integrations/destinations/iterable/processor/trackTestData.ts new file mode 100644 index 0000000000..296275ad77 --- /dev/null +++ b/test/integrations/destinations/iterable/processor/trackTestData.ts @@ -0,0 +1,717 @@ +import { + generateMetadata, + generateTrackPayload, + transformResultBuilder, +} from './../../../testUtils'; +import { Destination } from '../../../../../src/types'; +import { ProcessorTestData } from '../../../testTypes'; + +const destination: Destination = { + ID: '123', + Name: 'iterable', + DestinationDefinition: { + ID: '123', + Name: 'iterable', + DisplayName: 'Iterable', + Config: {}, + }, + WorkspaceID: '123', + Transformations: [], + Config: { + apiKey: 'testApiKey', + preferUserId: false, + trackAllPages: true, + trackNamedPages: false, + mapToSingleEvent: false, + trackCategorisedPages: false, + }, + Enabled: true, +}; + +const headers = { + api_key: 'testApiKey', + 'Content-Type': 'application/json', +}; + +const properties = { + subject: 'resume validate', + sendtime: '2020-01-01', + sendlocation: 'akashdeep@gmail.com', +}; + +const customEventProperties = { + campaignId: '1', + templateId: '0', + user_actual_id: 12345, + category: 'test-category', + email: 'ruchira@rudderlabs.com', + user_actual_role: 'system_admin, system_user', +}; + +const productInfo = { + price: 797, + variant: 'Oak', + quantity: 1, + quickship: true, + full_price: 1328, + product_id: 10606, + non_interaction: 1, + sku: 'JB24691400-W05', + name: 'Vira Console Cabinet', + cart_id: 'bd9b8dbf4ef8ee01d4206b04fe2ee6ae', +}; + +const orderCompletedProductInfo = { + price: 45, + quantity: 1, + total: '1000', + name: 'Shoes', + orderId: 10000, + product_id: 1234, + campaignId: '123456', + templateId: '1213458', +}; + +const products = [ + { + product_id: '507f1f77bcf86cd799439011', + sku: '45790-32', + name: 'Monopoly: 3rd Edition', + price: '19', + position: '1', + category: 'cars', + url: 'https://www.example.com/product/path', + image_url: 'https://www.example.com/product/path.jpg', + quantity: '2', + }, + { + product_id: '507f1f77bcf86cd7994390112', + sku: '45790-322', + name: 'Monopoly: 3rd Edition2', + price: '192', + quantity: 22, + position: '12', + category: 'Cars2', + url: 'https://www.example.com/product/path2', + image_url: 'https://www.example.com/product/path.jpg2', + }, +]; + +const items = [ + { + id: '507f1f77bcf86cd799439011', + sku: '45790-32', + name: 'Monopoly: 3rd Edition', + categories: ['cars'], + price: 19, + quantity: 2, + imageUrl: 'https://www.example.com/product/path.jpg', + url: 'https://www.example.com/product/path', + }, + { + id: '507f1f77bcf86cd7994390112', + sku: '45790-322', + name: 'Monopoly: 3rd Edition2', + categories: ['Cars2'], + price: 192, + quantity: 22, + imageUrl: 'https://www.example.com/product/path.jpg2', + url: 'https://www.example.com/product/path2', + }, +]; + +const userId = 'userId'; +const anonymousId = 'anonId'; +const sentAt = '2020-08-28T16:26:16.473Z'; +const originalTimestamp = '2020-08-28T16:26:06.468Z'; + +const endpoint = 'https://api.iterable.com/api/events/track'; +const updateCartEndpoint = 'https://api.iterable.com/api/commerce/updateCart'; +const trackPurchaseEndpoint = 'https://api.iterable.com/api/commerce/trackPurchase'; + +export const trackTestData: ProcessorTestData[] = [ + { + id: 'iterable-track-test-1', + name: 'iterable', + description: 'Track call to add event with user', + scenario: 'Business', + successCriteria: + 'Response should contain status code 200 and it should contain event properties and event name', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: { + anonymousId, + event: 'Email Opened', + type: 'track', + context: {}, + properties, + sentAt, + originalTimestamp, + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: '', + headers, + endpoint, + JSON: { + userId: 'anonId', + createdAt: 1598631966468, + eventName: 'Email Opened', + dataFields: properties, + }, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'iterable-track-test-2', + name: 'iterable', + description: 'Track call for product added event with all properties', + scenario: 'Business', + successCriteria: + 'Response should contain status code 200 and it should contain event name and all properties', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: generateTrackPayload({ + userId, + anonymousId, + event: 'product added', + context: { + traits: { + email: 'sayan@gmail.com', + }, + }, + properties: { + campaignId: '1', + templateId: '0', + orderId: 10000, + total: 1000, + products, + }, + sentAt, + originalTimestamp, + }), + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: '', + headers, + endpoint: updateCartEndpoint, + JSON: { + user: { + email: 'sayan@gmail.com', + dataFields: { + email: 'sayan@gmail.com', + }, + userId, + preferUserId: false, + mergeNestedObjects: true, + }, + items, + }, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'iterable-track-test-3', + name: 'iterable', + description: 'Track call for order completed event with all properties', + scenario: 'Business', + successCriteria: + 'Response should contain status code 200 and it should contain event name and all properties', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: generateTrackPayload({ + userId, + anonymousId, + event: 'order completed', + context: { + traits: { + email: 'sayan@gmail.com', + }, + }, + properties: { + orderId: 10000, + total: '1000', + campaignId: '123456', + templateId: '1213458', + products, + }, + sentAt, + originalTimestamp, + }), + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: '', + headers, + endpoint: trackPurchaseEndpoint, + JSON: { + dataFields: { + orderId: 10000, + total: '1000', + campaignId: '123456', + templateId: '1213458', + products, + }, + id: '10000', + createdAt: 1598631966468, + campaignId: 123456, + templateId: 1213458, + total: 1000, + user: { + email: 'sayan@gmail.com', + dataFields: { + email: 'sayan@gmail.com', + }, + userId, + preferUserId: false, + mergeNestedObjects: true, + }, + items, + }, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'iterable-track-test-4', + name: 'iterable', + description: 'Track call for custom event with all properties', + scenario: 'Business', + successCriteria: + 'Response should contain status code 200 and it should contain custom event name and all properties', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: generateTrackPayload({ + userId, + anonymousId, + event: 'test track event GA3', + context: { + traits: { + email: 'sayan@gmail.com', + }, + }, + properties: customEventProperties, + sentAt, + originalTimestamp, + }), + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: '', + headers, + endpoint, + JSON: { + email: 'ruchira@rudderlabs.com', + dataFields: customEventProperties, + userId, + eventName: 'test track event GA3', + createdAt: 1598631966468, + campaignId: 1, + templateId: 0, + }, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'iterable-track-test-5', + name: 'iterable', + description: 'Track call for product added event with product info as properties', + scenario: 'Business', + successCriteria: + 'Response should contain status code 200 and it should contain event name and all properties', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: generateTrackPayload({ + userId, + anonymousId, + event: 'product added', + context: { + traits: { + email: 'jessica@jlpdesign.net', + }, + }, + properties: productInfo, + sentAt, + originalTimestamp, + }), + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: '', + headers, + endpoint: updateCartEndpoint, + JSON: { + user: { + email: 'jessica@jlpdesign.net', + dataFields: { + email: 'jessica@jlpdesign.net', + }, + userId, + preferUserId: false, + mergeNestedObjects: true, + }, + items: [ + { + id: productInfo.product_id, + sku: productInfo.sku, + name: productInfo.name, + price: productInfo.price, + quantity: productInfo.quantity, + }, + ], + }, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'iterable-track-test-6', + name: 'iterable', + description: 'Track call for product added event with product info as properties', + scenario: 'Business', + successCriteria: + 'Response should contain status code 200 and it should contain event name and all properties', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: generateTrackPayload({ + userId, + anonymousId, + event: 'product added', + context: { + traits: { + email: 'jessica@jlpdesign.net', + }, + }, + properties: { + campaignId: '1', + templateId: '0', + orderId: 10000, + total: 1000, + ...products[1], + }, + sentAt, + originalTimestamp, + }), + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: '', + headers, + endpoint: updateCartEndpoint, + JSON: { + user: { + email: 'jessica@jlpdesign.net', + dataFields: { + email: 'jessica@jlpdesign.net', + }, + userId, + preferUserId: false, + mergeNestedObjects: true, + }, + items: [ + { + price: 192, + url: products[1].url, + sku: products[1].sku, + name: products[1].name, + id: products[1].product_id, + quantity: products[1].quantity, + imageUrl: products[1].image_url, + categories: [products[1].category], + }, + ], + }, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'iterable-track-test-7', + name: 'iterable', + description: 'Track call for order completed event with product info as properties', + scenario: 'Business', + successCriteria: + 'Response should contain status code 200 and it should contain event name and all properties', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: generateTrackPayload({ + userId, + anonymousId, + event: 'order completed', + context: { + traits: { + email: 'jessica@jlpdesign.net', + }, + }, + properties: orderCompletedProductInfo, + sentAt, + originalTimestamp, + }), + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: '', + headers, + endpoint: trackPurchaseEndpoint, + JSON: { + dataFields: orderCompletedProductInfo, + user: { + email: 'jessica@jlpdesign.net', + dataFields: { + email: 'jessica@jlpdesign.net', + }, + userId, + preferUserId: false, + mergeNestedObjects: true, + }, + id: '10000', + total: 1000, + campaignId: 123456, + templateId: 1213458, + createdAt: 1598631966468, + items: [ + { + id: orderCompletedProductInfo.product_id, + name: orderCompletedProductInfo.name, + price: orderCompletedProductInfo.price, + quantity: orderCompletedProductInfo.quantity, + }, + ], + }, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'iterable-track-test-8', + name: 'iterable', + description: 'Track call without event name and userId', + scenario: 'Business', + successCriteria: + 'Response should contain status code 200 and it should contain event properties', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: { + anonymousId, + type: 'track', + context: {}, + properties, + sentAt, + originalTimestamp, + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: '', + headers, + endpoint, + JSON: { + userId: anonymousId, + createdAt: 1598631966468, + dataFields: properties, + }, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'iterable-track-test-8', + name: 'iterable', + description: 'Track call without event name', + scenario: 'Business', + successCriteria: + 'Response should contain status code 200 and it should contain event properties', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: { + userId, + anonymousId, + type: 'track', + context: {}, + properties, + sentAt, + originalTimestamp, + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: '', + headers, + endpoint, + JSON: { + userId, + createdAt: 1598631966468, + dataFields: properties, + }, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/iterable/processor/validationTestData.ts b/test/integrations/destinations/iterable/processor/validationTestData.ts new file mode 100644 index 0000000000..86728a868b --- /dev/null +++ b/test/integrations/destinations/iterable/processor/validationTestData.ts @@ -0,0 +1,258 @@ +import { generateMetadata } from './../../../testUtils'; +import { Destination } from '../../../../../src/types'; +import { ProcessorTestData } from '../../../testTypes'; + +const destination: Destination = { + ID: '123', + Name: 'iterable', + DestinationDefinition: { + ID: '123', + Name: 'iterable', + DisplayName: 'Iterable', + Config: {}, + }, + WorkspaceID: '123', + Transformations: [], + Config: { + apiKey: 'testApiKey', + mapToSingleEvent: false, + trackAllPages: false, + trackCategorisedPages: true, + trackNamedPages: false, + }, + Enabled: true, +}; + +const properties = { + url: 'https://dominos.com', + title: 'Pizza', + referrer: 'https://google.com', +}; + +const sentAt = '2020-08-28T16:26:16.473Z'; +const originalTimestamp = '2020-08-28T16:26:06.468Z'; + +const expectedStatTags = { + destType: 'ITERABLE', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'native', + module: 'destination', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', +}; + +export const validationTestData: ProcessorTestData[] = [ + { + id: 'iterable-validation-test-1', + name: 'iterable', + description: "[Error]: Page call without it's required configuration", + scenario: 'Framework', + successCriteria: + 'Response should contain status code 400 and it should throw configuration error with respective message type', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: { + userId: 'sajal12', + anonymousId: 'abcdeeeeeeeexxxx102', + context: { + traits: { + email: 'abc@example.com', + }, + }, + properties, + type: 'page', + sentAt, + originalTimestamp, + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + statusCode: 400, + error: 'Invalid page call', + statTags: { ...expectedStatTags, errorType: 'configuration' }, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'iterable-validation-test-2', + name: 'iterable', + description: '[Error]: Identify call without userId and email', + scenario: 'Framework', + successCriteria: + 'Response should contain status code 400 and it should throw instrumentation error with respective message type', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: { + context: {}, + type: 'identify', + sentAt, + originalTimestamp, + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + statusCode: 400, + error: 'userId or email is mandatory for this request', + statTags: expectedStatTags, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'iterable-validation-test-3', + name: 'iterable', + description: '[Error]: Message type is not supported', + scenario: 'Framework', + successCriteria: + 'Response should contain status code 400 and it should throw instrumentation error with respective message type', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: { + context: {}, + type: 'group', + sentAt, + originalTimestamp, + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + statusCode: 400, + error: 'Message type group not supported', + statTags: expectedStatTags, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'iterable-validation-test-4', + name: 'iterable', + description: '[Error]: Missing required value for alias call', + scenario: 'Framework', + successCriteria: + 'Response should contain status code 400 and it should throw instrumentation error with respective message type', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: { + context: {}, + type: 'alias', + properties, + sentAt, + originalTimestamp, + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + statusCode: 400, + error: 'Missing required value from "previousId"', + statTags: expectedStatTags, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'iterable-validation-test-5', + name: 'iterable', + description: '[Error]: Missing userId value for alias call', + scenario: 'Framework', + successCriteria: + 'Response should contain status code 400 and it should throw instrumentation error with respective message type', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination, + message: { + context: {}, + type: 'alias', + previousId: 'old@email.com', + anonymousId: 'anonId', + properties, + sentAt, + originalTimestamp, + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + statusCode: 400, + error: 'Missing required value from "userId"', + statTags: expectedStatTags, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/testUtils.ts b/test/integrations/testUtils.ts index c16aeff98c..0a2727f4d0 100644 --- a/test/integrations/testUtils.ts +++ b/test/integrations/testUtils.ts @@ -292,6 +292,7 @@ export const generatePageOrScreenPayload: any = (parametersOverride: any, eventT '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: parametersOverride.event, + name: parametersOverride.name, anonymousId: parametersOverride.anonymousId || 'default-anonymousId', properties: parametersOverride.properties, type: eventType || 'page', From 89a71b757998cb55a63c59151b5e3a118084970b Mon Sep 17 00:00:00 2001 From: Mihir Bhalala <77438541+mihir-4116@users.noreply.github.com> Date: Wed, 24 Apr 2024 16:27:51 +0530 Subject: [PATCH 47/47] chore: component test refactor for intercom destination (#3236) --- .../destinations/intercom/processor/data.ts | 4156 +---------------- .../intercom/processor/groupTestData.ts | 509 ++ .../intercom/processor/identifyTestData.ts | 1025 ++++ .../intercom/processor/trackTestData.ts | 361 ++ .../intercom/processor/validationTestData.ts | 554 +++ 5 files changed, 2458 insertions(+), 4147 deletions(-) create mode 100644 test/integrations/destinations/intercom/processor/groupTestData.ts create mode 100644 test/integrations/destinations/intercom/processor/identifyTestData.ts create mode 100644 test/integrations/destinations/intercom/processor/trackTestData.ts create mode 100644 test/integrations/destinations/intercom/processor/validationTestData.ts diff --git a/test/integrations/destinations/intercom/processor/data.ts b/test/integrations/destinations/intercom/processor/data.ts index 2c562ed4e9..7bc697bc2d 100644 --- a/test/integrations/destinations/intercom/processor/data.ts +++ b/test/integrations/destinations/intercom/processor/data.ts @@ -1,4149 +1,11 @@ +import { identifyTestData } from './identifyTestData'; +import { trackTestData } from './trackTestData'; +import { groupTestData } from './groupTestData'; +import { validationTestData } from './validationTestData'; + export const data = [ - { - name: 'intercom', - description: 'No message type', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - channel: 'web', - context: { - traits: { - age: 23, - email: 'adc@test.com', - firstname: 'Test', - birthday: '2022-05-13T12:51:01.470Z', - }, - userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36', - }, - event: 'Product Searched', - originalTimestamp: '2020-09-22T14:42:44.724Z', - timestamp: '2022-09-22T20:12:44.757+05:30', - userId: 'user@1', - }, - destination: { - DestinationDefinition: { - Config: { - cdkV2Enabled: true, - }, - }, - Config: { - apiKey: 'testApiKey', - apiVersion: 'v2', - apiServer: 'standard', - sendAnonymousId: false, - }, - }, - 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: 'INTERCOM', - module: 'destination', - implementation: 'cdkV2', - feature: 'processor', - }, - }, - ], - }, - }, - }, - { - name: 'intercom', - description: 'Unsupported message type', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - channel: 'web', - context: { - traits: { - age: 23, - email: 'adc@test.com', - firstname: 'Test', - birthday: '2022-05-13T12:51:01.470Z', - }, - userAgent: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36', - }, - event: 'Product Searched', - type: 'page', - originalTimestamp: '2020-09-22T14:42:44.724Z', - timestamp: '2022-09-22T20:12:44.757+05:30', - userId: 'user@1', - }, - destination: { - DestinationDefinition: { - Config: { - cdkV2Enabled: true, - }, - }, - Config: { - apiKey: 'testApiKey', - apiVersion: 'v2', - apiServer: 'standard', - sendAnonymousId: false, - }, - }, - metadata: { - jobId: 2, - }, - }, - ], - method: 'POST', - }, - }, - output: { - response: { - status: 200, - body: [ - { - metadata: { - jobId: 2, - }, - 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: 'INTERCOM', - module: 'destination', - implementation: 'cdkV2', - feature: 'processor', - }, - }, - ], - }, - }, - }, - { - name: 'intercom', - description: 'Missing required 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: { - apiVersion: 'v2', - apiServer: 'standard', - sendAnonymousId: false, - }, - }, - metadata: { - jobId: 3, - }, - }, - ], - method: 'POST', - }, - }, - output: { - response: { - status: 200, - body: [ - { - metadata: { - jobId: 3, - }, - statusCode: 400, - error: - 'Access Token is not present. Aborting: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: Access Token is not present. Aborting', - statTags: { - errorCategory: 'dataValidation', - errorType: 'configuration', - destType: 'INTERCOM', - module: 'destination', - implementation: 'cdkV2', - feature: 'processor', - }, - }, - ], - }, - }, - }, - { - name: 'intercom', - description: 'Create customer with email as lookup field', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - userId: 'user@1', - channel: 'web', - context: { - traits: { - age: 23, - email: 'test@rudderlabs.com', - phone: '+91 9999999999', - firstName: 'Test', - lastName: 'Rudderlabs', - address: 'california usa', - ownerId: '13', - lastSeenAt: '2023-11-10T14:42:44.724Z', - }, - }, - type: 'identify', - originalTimestamp: '2023-11-10T14:42:44.724Z', - timestamp: '2023-11-22T10:12:44.757+05:30', - }, - destination: { - DestinationDefinition: { - Config: { - cdkV2Enabled: true, - }, - }, - Config: { - apiKey: 'testApiKey', - apiVersion: 'v2', - apiServer: 'standard', - sendAnonymousId: false, - }, - }, - metadata: { - jobId: 4, - }, - }, - ], - method: 'POST', - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - body: { - JSON: { - email: 'test@rudderlabs.com', - external_id: 'user@1', - last_seen_at: 1699627364, - name: 'Test Rudderlabs', - owner_id: 13, - phone: '+91 9999999999', - custom_attributes: { - address: 'california usa', - age: 23, - }, - }, - XML: {}, - FORM: {}, - JSON_ARRAY: {}, - }, - endpoint: 'https://api.intercom.io/contacts', - headers: { - Authorization: 'Bearer testApiKey', - 'Content-Type': 'application/json', - Accept: 'application/json', - 'Intercom-Version': '2.10', - }, - userId: '', - version: '1', - type: 'REST', - method: 'POST', - files: {}, - params: {}, - }, - metadata: { jobId: 4 }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'intercom', - description: 'Update customer with email as lookup field', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - userId: 'user@2', - channel: 'web', - context: { - traits: { - age: 32, - email: 'test+2@rudderlabs.com', - phone: '+91 9299999999', - firstName: 'Test', - lastName: 'RudderStack', - ownerId: '14', - }, - }, - type: 'identify', - originalTimestamp: '2023-11-10T14:42:44.724Z', - timestamp: '2023-11-22T10:12:44.757+05:30', - }, - destination: { - DestinationDefinition: { - Config: { - cdkV2Enabled: true, - }, - }, - Config: { - apiKey: 'testApiKey', - apiVersion: 'v2', - apiServer: 'standard', - sendAnonymousId: false, - }, - }, - metadata: { - jobId: 5, - }, - }, - ], - method: 'POST', - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - body: { - JSON: { - email: 'test+2@rudderlabs.com', - external_id: 'user@2', - name: 'Test RudderStack', - owner_id: 14, - phone: '+91 9299999999', - custom_attributes: { - age: 32, - }, - }, - XML: {}, - FORM: {}, - JSON_ARRAY: {}, - }, - endpoint: 'https://api.intercom.io/contacts/7070129940741e45d040', - headers: { - Authorization: 'Bearer testApiKey', - 'Content-Type': 'application/json', - Accept: 'application/json', - 'Intercom-Version': '2.10', - }, - userId: '', - version: '1', - type: 'REST', - method: 'PUT', - files: {}, - params: {}, - }, - metadata: { jobId: 5 }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'intercom', - description: 'Missing required parameters for an identify call', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: 'anon@2', - channel: 'web', - context: { - traits: { - age: 32, - phone: '+91 9299999999', - firstName: 'Test', - lastName: 'RudderStack', - ownerId: '14', - role: 'user', - source: 'rudder-sdk', - }, - }, - integrations: { - INTERCOM: { - lookup: 'phone', - }, - }, - type: 'identify', - originalTimestamp: '2023-11-10T14:42:44.724Z', - timestamp: '2023-11-22T10:12:44.757+05:30', - }, - destination: { - DestinationDefinition: { - Config: { - cdkV2Enabled: true, - }, - }, - Config: { - apiKey: 'testApiKey', - apiVersion: 'v2', - apiServer: 'standard', - sendAnonymousId: false, - }, - }, - metadata: { - jobId: 6, - }, - }, - ], - method: 'POST', - }, - }, - output: { - response: { - status: 200, - body: [ - { - metadata: { - jobId: 6, - }, - statusCode: 400, - error: - 'Either email or userId is required for Identify call: Workflow: procWorkflow, Step: identifyPayloadForLatestVersion, ChildStep: undefined, OriginalError: Either email or userId is required for Identify call', - statTags: { - errorCategory: 'dataValidation', - errorType: 'instrumentation', - destType: 'INTERCOM', - module: 'destination', - implementation: 'cdkV2', - feature: 'processor', - }, - }, - ], - }, - }, - }, - { - name: 'intercom', - description: 'Unauthorized error while searching contact for an identify call', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - userId: 'user@3', - channel: 'web', - context: { - traits: { - phone: '+91 9399999999', - email: 'test+3@rudderlabs.com', - firstName: 'Test', - lastName: 'Rudder', - ownerId: '15', - role: 'admin', - source: 'rudder-android-sdk', - }, - }, - integrations: { - INTERCOM: { - lookup: 'email', - }, - }, - type: 'identify', - originalTimestamp: '2023-11-10T14:42:44.724Z', - timestamp: '2023-11-22T10:12:44.757+05:30', - }, - destination: { - DestinationDefinition: { - Config: { - cdkV2Enabled: true, - }, - }, - Config: { - apiKey: 'invalidApiKey', - apiVersion: 'v2', - apiServer: 'standard', - sendAnonymousId: false, - }, - }, - metadata: { - jobId: 7, - }, - }, - ], - method: 'POST', - }, - }, - output: { - response: { - status: 200, - body: [ - { - metadata: { - jobId: 7, - }, - statusCode: 401, - error: - '{"message":"{\\"message\\":\\"Unable to search contact due to : [{\\\\\\"code\\\\\\":\\\\\\"unauthorized\\\\\\",\\\\\\"message\\\\\\":\\\\\\"Access Token Invalid\\\\\\"}]: Workflow: procWorkflow, Step: searchContact, ChildStep: undefined, OriginalError: Unable to search contact due to : [{\\\\\\"code\\\\\\":\\\\\\"unauthorized\\\\\\",\\\\\\"message\\\\\\":\\\\\\"Access Token Invalid\\\\\\"}]\\",\\"destinationResponse\\":{\\"response\\":{\\"type\\":\\"error.list\\",\\"request_id\\":\\"request_1\\",\\"errors\\":[{\\"code\\":\\"unauthorized\\",\\"message\\":\\"Access Token Invalid\\"}]},\\"status\\":401}}","destinationResponse":{"response":{"type":"error.list","request_id":"request_1","errors":[{"code":"unauthorized","message":"Access Token Invalid"}]},"status":401}}', - statTags: { - errorCategory: 'network', - errorType: 'aborted', - destType: 'INTERCOM', - module: 'destination', - implementation: 'cdkV2', - feature: 'processor', - }, - }, - ], - }, - }, - }, - { - name: 'intercom', - description: 'Track call without event name', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - userId: 'user@3', - channel: 'web', - context: { - traits: { - age: 32, - email: 'test+3@rudderlabs.com', - phone: '+91 9399999999', - firstName: 'Test', - lastName: 'RudderStack', - ownerId: '15', - }, - }, - properties: { - revenue: { - amount: 1232, - currency: 'inr', - test: 123, - }, - price: { - amount: 3000, - currency: 'USD', - }, - }, - type: 'track', - originalTimestamp: '2023-11-10T14:42:44.724Z', - timestamp: '2023-11-22T10:12:44.757+05:30', - }, - destination: { - DestinationDefinition: { - Config: { - cdkV2Enabled: true, - }, - }, - Config: { - apiKey: 'testApiKey', - apiVersion: 'v2', - apiServer: 'standard', - sendAnonymousId: false, - }, - }, - metadata: { - jobId: 8, - }, - }, - ], - method: 'POST', - }, - }, - output: { - response: { - status: 200, - body: [ - { - metadata: { - jobId: 8, - }, - statusCode: 400, - error: - 'Event name is required for track call: Workflow: procWorkflow, Step: trackPayload, ChildStep: undefined, OriginalError: Event name is required for track call', - statTags: { - errorCategory: 'dataValidation', - errorType: 'instrumentation', - destType: 'INTERCOM', - module: 'destination', - implementation: 'cdkV2', - feature: 'processor', - }, - }, - ], - }, - }, - }, - { - name: 'intercom', - description: 'Successful track call', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - userId: 'user@2', - channel: 'web', - context: { - traits: { - age: 32, - email: 'test+2@rudderlabs.com', - phone: '+91 9299999999', - firstName: 'Test', - lastName: 'RudderStack', - ownerId: '14', - }, - }, - properties: { - revenue: { - amount: 1232, - currency: 'inr', - test: 123, - }, - price: { - amount: 3000, - currency: 'USD', - }, - }, - 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: { - apiKey: 'testApiKey', - apiVersion: 'v2', - apiServer: 'standard', - sendAnonymousId: false, - }, - }, - metadata: { - jobId: 9, - }, - }, - ], - method: 'POST', - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - body: { - FORM: {}, - JSON: { - created_at: 1700628164, - email: 'test+2@rudderlabs.com', - event_name: 'Product Viewed', - metadata: { - price: { - amount: 3000, - currency: 'USD', - }, - revenue: { - amount: 1232, - currency: 'inr', - test: 123, - }, - }, - user_id: 'user@2', - }, - JSON_ARRAY: {}, - XML: {}, - }, - endpoint: 'https://api.intercom.io/events', - headers: { - Accept: 'application/json', - Authorization: 'Bearer testApiKey', - 'Content-Type': 'application/json', - 'Intercom-Version': '2.10', - }, - method: 'POST', - type: 'REST', - userId: '', - version: '1', - params: {}, - files: {}, - }, - statusCode: 200, - metadata: { - jobId: 9, - }, - }, - ], - }, - }, - }, - { - name: 'intercom', - description: 'Group call without groupId', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - userId: 'user@4', - channel: 'web', - context: { - traits: { - email: 'test+4@rudderlabs.com', - phone: '+91 9499999999', - firstName: 'John', - lastName: 'Doe', - ownerId: '16', - }, - }, - traits: { - name: 'RudderStack', - size: 500, - website: 'www.rudderstack.com', - industry: 'CDP', - plan: 'enterprise', - }, - type: 'group', - originalTimestamp: '2023-11-10T14:42:44.724Z', - timestamp: '2023-11-22T10:12:44.757+05:30', - }, - destination: { - DestinationDefinition: { - Config: { - cdkV2Enabled: true, - }, - }, - Config: { - apiKey: 'testApiKey', - apiVersion: 'v2', - apiServer: 'standard', - sendAnonymousId: false, - }, - }, - metadata: { - jobId: 10, - }, - }, - ], - method: 'POST', - }, - }, - output: { - response: { - status: 200, - body: [ - { - metadata: { - jobId: 10, - }, - statusCode: 400, - error: - 'groupId is required for group call: Workflow: procWorkflow, Step: groupPayloadForLatestVersion, ChildStep: validateMessageAndPreparePayload, OriginalError: groupId is required for group call', - statTags: { - errorCategory: 'dataValidation', - errorType: 'instrumentation', - destType: 'INTERCOM', - module: 'destination', - implementation: 'cdkV2', - feature: 'processor', - }, - }, - ], - }, - }, - }, - { - name: 'intercom', - description: 'Successful group call to create or update company', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - userId: 'user@4', - groupId: 'rudderlabs', - channel: 'web', - context: { - traits: { - email: 'test+4@rudderlabs.com', - phone: '+91 9499999999', - firstName: 'John', - lastName: 'Doe', - ownerId: '16', - }, - }, - traits: { - name: 'RudderStack', - size: 500, - website: 'www.rudderstack.com', - industry: 'CDP', - plan: 'enterprise', - }, - type: 'group', - originalTimestamp: '2023-11-10T14:42:44.724Z', - timestamp: '2023-11-22T10:12:44.757+05:30', - }, - destination: { - DestinationDefinition: { - Config: { - cdkV2Enabled: true, - }, - }, - Config: { - apiKey: 'testApiKey', - apiVersion: 'v2', - apiServer: 'standard', - sendAnonymousId: false, - }, - }, - metadata: { - jobId: 11, - }, - }, - ], - method: 'POST', - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - body: { - JSON: { - company_id: 'rudderlabs', - industry: 'CDP', - name: 'RudderStack', - plan: 'enterprise', - size: 500, - website: 'www.rudderstack.com', - }, - XML: {}, - FORM: {}, - JSON_ARRAY: {}, - }, - endpoint: 'https://api.intercom.io/companies', - headers: { - Accept: 'application/json', - Authorization: 'Bearer testApiKey', - 'Content-Type': 'application/json', - 'Intercom-Version': '2.10', - }, - method: 'POST', - type: 'REST', - userId: '', - version: '1', - params: {}, - files: {}, - }, - statusCode: 200, - metadata: { - jobId: 11, - }, - }, - ], - }, - }, - }, - { - name: 'intercom', - description: 'Successful group call to add user to company', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - userId: 'user@5', - groupId: 'rudderlabs', - channel: 'web', - context: { - traits: { - email: 'test+5@rudderlabs.com', - phone: '+91 9599999999', - firstName: 'John', - lastName: 'Snow', - ownerId: '17', - }, - }, - traits: { - name: 'RudderStack', - size: 500, - website: 'www.rudderstack.com', - industry: 'CDP', - plan: 'enterprise', - }, - type: 'group', - originalTimestamp: '2023-11-10T14:42:44.724Z', - timestamp: '2023-11-22T10:12:44.757+05:30', - }, - destination: { - DestinationDefinition: { - Config: { - cdkV2Enabled: true, - }, - }, - Config: { - apiKey: 'testApiKey', - apiVersion: 'v2', - apiServer: 'eu', - sendAnonymousId: false, - }, - }, - metadata: { - jobId: 12, - }, - }, - ], - method: 'POST', - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - body: { - JSON: { - id: '657264e9018c0a647s45', - }, - XML: {}, - FORM: {}, - JSON_ARRAY: {}, - }, - endpoint: 'https://api.eu.intercom.io/contacts/70701240741e45d040/companies', - headers: { - Accept: 'application/json', - Authorization: 'Bearer testApiKey', - 'Content-Type': 'application/json', - 'Intercom-Version': '2.10', - }, - method: 'POST', - type: 'REST', - userId: '', - version: '1', - params: {}, - files: {}, - }, - statusCode: 200, - metadata: { - jobId: 12, - }, - }, - ], - }, - }, - }, - { - name: 'intercom', - description: 'Identify rEtl test', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - channel: 'web', - context: { - externalId: [ - { - id: 'user@1', - type: 'INTERCOM-customer', - identifierType: 'user_id', - }, - ], - mappedToDestination: 'true', - }, - traits: { - email: 'test@rudderlabs.com', - phone: '+91 9999999999', - name: 'Test Rudderlabs', - owner_id: 13, - }, - type: 'identify', - originalTimestamp: '2023-11-10T14:42:44.724Z', - timestamp: '2023-11-22T10:12:44.757+05:30', - }, - destination: { - DestinationDefinition: { - Config: { - cdkV2Enabled: true, - }, - }, - Config: { - apiKey: 'testApiKey', - apiVersion: 'v2', - apiServer: 'standard', - sendAnonymousId: false, - }, - }, - metadata: { - jobId: 13, - }, - }, - ], - method: 'POST', - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - body: { - JSON: { - email: 'test@rudderlabs.com', - name: 'Test Rudderlabs', - phone: '+91 9999999999', - owner_id: 13, - user_id: 'user@1', - }, - XML: {}, - FORM: {}, - JSON_ARRAY: {}, - }, - endpoint: 'https://api.intercom.io/contacts', - headers: { - Authorization: 'Bearer testApiKey', - 'Content-Type': 'application/json', - Accept: 'application/json', - 'Intercom-Version': '2.10', - }, - userId: '', - version: '1', - type: 'REST', - method: 'POST', - files: {}, - params: {}, - }, - metadata: { jobId: 13 }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'intercom', - description: 'Track rEtl test', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - userId: 'user@1', - channel: 'web', - context: { - mappedToDestination: 'true', - }, - traits: { - event_name: 'Product Viewed', - user_id: 'user@1', - revenue: { - amount: 1232, - currency: 'inr', - test: 123, - }, - price: { - amount: 3000, - currency: 'USD', - }, - }, - 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: { - apiKey: 'testApiKey', - apiVersion: 'v2', - apiServer: 'standard', - sendAnonymousId: false, - }, - }, - metadata: { - jobId: 14, - }, - }, - ], - method: 'POST', - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - body: { - JSON: { - event_name: 'Product Viewed', - price: { - amount: 3000, - currency: 'USD', - }, - revenue: { - amount: 1232, - currency: 'inr', - test: 123, - }, - user_id: 'user@1', - }, - XML: {}, - FORM: {}, - JSON_ARRAY: {}, - }, - endpoint: 'https://api.intercom.io/events', - headers: { - Authorization: 'Bearer testApiKey', - 'Content-Type': 'application/json', - Accept: 'application/json', - 'Intercom-Version': '2.10', - }, - userId: '', - version: '1', - type: 'REST', - method: 'POST', - files: {}, - params: {}, - }, - metadata: { jobId: 14 }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'intercom', - description: 'Old version - successful identify call', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - channel: 'mobile', - context: { - app: { - build: '1.0', - name: 'Test_Example', - namespace: 'com.example.testapp', - version: '1.0', - }, - device: { - id: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - manufacturer: 'Apple', - model: 'iPhone', - name: 'iPod touch (7th generation)', - type: 'iOS', - }, - library: { - name: 'test-ios-library', - version: '1.0.7', - }, - locale: 'en-US', - network: { - bluetooth: false, - carrier: 'unavailable', - cellular: false, - wifi: true, - }, - os: { - name: 'iOS', - version: '14.0', - }, - screen: { - density: 2, - height: 320, - width: 568, - }, - timezone: 'Asia/Kolkata', - traits: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - name: 'Test Name', - firstName: 'Test', - lastName: 'Name', - createdAt: '2020-09-30T19:11:00.337Z', - userId: 'test_user_id_1', - email: 'test_1@test.com', - phone: '9876543210', - key1: 'value1', - address: { - city: 'Kolkata', - state: 'West Bengal', - }, - originalArray: [ - { - nested_field: 'nested value', - tags: ['tag_1', 'tag_2', 'tag_3'], - }, - { - nested_field: 'nested value', - tags: ['tag_1'], - }, - { - nested_field: 'nested value', - }, - ], - }, - userAgent: 'unknown', - }, - event: 'Test Event 2', - integrations: { - All: true, - }, - messageId: '1601493060-39010c49-e6e4-4626-a75c-0dbf1925c9e8', - originalTimestamp: '2020-09-30T19:11:00.337Z', - receivedAt: '2020-10-01T00:41:11.369+05:30', - request_ip: '2405:201:8005:9856:7911:25e7:5603:5e18', - sentAt: '2020-09-30T19:11:10.382Z', - timestamp: '2020-10-01T00:41:01.324+05:30', - type: 'identify', - }, - destination: { - DestinationDefinition: { - Config: { - cdkV2Enabled: true, - }, - }, - Config: { - apiKey: 'intercomApiKey', - apiVersion: 'v1', - appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', - collectContext: false, - }, - }, - metadata: { - jobId: 15, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://api.intercom.io/users', - headers: { - 'Content-Type': 'application/json', - Authorization: 'Bearer intercomApiKey', - Accept: 'application/json', - 'Intercom-Version': '1.4', - }, - params: {}, - body: { - JSON: { - user_id: 'test_user_id_1', - email: 'test_1@test.com', - phone: '9876543210', - name: 'Test Name', - signed_up_at: 1601493060, - last_seen_user_agent: 'unknown', - custom_attributes: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - key1: 'value1', - 'address.city': 'Kolkata', - 'address.state': 'West Bengal', - 'originalArray[0].nested_field': 'nested value', - 'originalArray[0].tags[0]': 'tag_1', - 'originalArray[0].tags[1]': 'tag_2', - 'originalArray[0].tags[2]': 'tag_3', - 'originalArray[1].nested_field': 'nested value', - 'originalArray[1].tags[0]': 'tag_1', - 'originalArray[2].nested_field': 'nested value', - }, - update_last_request_at: true, - }, - JSON_ARRAY: {}, - XML: {}, - FORM: {}, - }, - files: {}, - userId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - }, - statusCode: 200, - metadata: { - jobId: 15, - }, - }, - ], - }, - }, - }, - { - name: 'intercom', - description: 'Old version - successful identify call', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - channel: 'mobile', - context: { - app: { - build: '1.0', - name: 'Test_Example', - namespace: 'com.example.testapp', - version: '1.0', - }, - device: { - id: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - manufacturer: 'Apple', - model: 'iPhone', - name: 'iPod touch (7th generation)', - type: 'iOS', - }, - library: { - name: 'test-ios-library', - version: '1.0.7', - }, - locale: 'en-US', - network: { - bluetooth: false, - carrier: 'unavailable', - cellular: false, - wifi: true, - }, - os: { - name: 'iOS', - version: '14.0', - }, - screen: { - density: 2, - height: 320, - width: 568, - }, - timezone: 'Asia/Kolkata', - traits: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - firstName: 'Test', - lastName: 'Name', - createdAt: '2020-09-30T19:11:00.337Z', - email: 'test_1@test.com', - phone: '9876543210', - key1: 'value1', - }, - userAgent: 'unknown', - }, - event: 'Test Event 2', - integrations: { - All: true, - }, - messageId: '1601493060-39010c49-e6e4-4626-a75c-0dbf1925c9e8', - originalTimestamp: '2020-09-30T19:11:00.337Z', - receivedAt: '2020-10-01T00:41:11.369+05:30', - request_ip: '2405:201:8005:9856:7911:25e7:5603:5e18', - sentAt: '2020-09-30T19:11:10.382Z', - timestamp: '2020-10-01T00:41:01.324+05:30', - type: 'identify', - }, - destination: { - DestinationDefinition: { - Config: { - cdkV2Enabled: true, - }, - }, - Config: { - apiKey: 'intercomApiKey', - apiVersion: 'v1', - appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', - collectContext: false, - }, - }, - metadata: { - jobId: 16, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://api.intercom.io/users', - headers: { - 'Content-Type': 'application/json', - Authorization: 'Bearer intercomApiKey', - Accept: 'application/json', - 'Intercom-Version': '1.4', - }, - params: {}, - body: { - JSON: { - email: 'test_1@test.com', - phone: '9876543210', - signed_up_at: 1601493060, - last_seen_user_agent: 'unknown', - custom_attributes: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - key1: 'value1', - }, - update_last_request_at: true, - name: 'Test Name', - }, - JSON_ARRAY: {}, - XML: {}, - FORM: {}, - }, - files: {}, - userId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - }, - statusCode: 200, - metadata: { - jobId: 16, - }, - }, - ], - }, - }, - }, - { - name: 'intercom', - description: 'Old version - successful identify call', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - channel: 'mobile', - context: { - app: { - build: '1.0', - name: 'Test_Example', - namespace: 'com.example.testapp', - version: '1.0', - }, - device: { - id: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - manufacturer: 'Apple', - model: 'iPhone', - name: 'iPod touch (7th generation)', - type: 'iOS', - }, - library: { - name: 'test-ios-library', - version: '1.0.7', - }, - locale: 'en-US', - network: { - bluetooth: false, - carrier: 'unavailable', - cellular: false, - wifi: true, - }, - os: { - name: 'iOS', - version: '14.0', - }, - screen: { - density: 2, - height: 320, - width: 568, - }, - timezone: 'Asia/Kolkata', - traits: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - lastName: 'Name', - createdAt: '2020-09-30T19:11:00.337Z', - email: 'test_1@test.com', - phone: '9876543210', - key1: 'value1', - }, - userAgent: 'unknown', - }, - event: 'Test Event 2', - integrations: { - All: true, - }, - messageId: '1601493060-39010c49-e6e4-4626-a75c-0dbf1925c9e8', - originalTimestamp: '2020-09-30T19:11:00.337Z', - receivedAt: '2020-10-01T00:41:11.369+05:30', - request_ip: '2405:201:8005:9856:7911:25e7:5603:5e18', - sentAt: '2020-09-30T19:11:10.382Z', - timestamp: '2020-10-01T00:41:01.324+05:30', - type: 'identify', - }, - destination: { - DestinationDefinition: { - Config: { - cdkV2Enabled: true, - }, - }, - Config: { - apiKey: 'intercomApiKey', - apiVersion: 'v1', - appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', - collectContext: false, - }, - }, - metadata: { - jobId: 17, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://api.intercom.io/users', - headers: { - 'Content-Type': 'application/json', - Authorization: 'Bearer intercomApiKey', - Accept: 'application/json', - 'Intercom-Version': '1.4', - }, - params: {}, - body: { - JSON: { - email: 'test_1@test.com', - phone: '9876543210', - signed_up_at: 1601493060, - last_seen_user_agent: 'unknown', - custom_attributes: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - key1: 'value1', - }, - update_last_request_at: true, - name: 'Name', - }, - JSON_ARRAY: {}, - XML: {}, - FORM: {}, - }, - files: {}, - userId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - }, - statusCode: 200, - metadata: { - jobId: 17, - }, - }, - ], - }, - }, - }, - { - name: 'intercom', - description: 'Old version - successful identify call', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - channel: 'mobile', - context: { - app: { - build: '1.0', - name: 'Test_Example', - namespace: 'com.example.testapp', - version: '1.0', - }, - device: { - id: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - manufacturer: 'Apple', - model: 'iPhone', - name: 'iPod touch (7th generation)', - type: 'iOS', - }, - library: { - name: 'test-ios-library', - version: '1.0.7', - }, - locale: 'en-US', - network: { - bluetooth: false, - carrier: 'unavailable', - cellular: false, - wifi: true, - }, - os: { - name: 'iOS', - version: '14.0', - }, - screen: { - density: 2, - height: 320, - width: 568, - }, - timezone: 'Asia/Kolkata', - traits: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - firstName: 'Name', - createdAt: '2020-09-30T19:11:00.337Z', - email: 'test_1@test.com', - phone: '9876543210', - key1: 'value1', - }, - userAgent: 'unknown', - }, - event: 'Test Event 2', - integrations: { - All: true, - }, - messageId: '1601493060-39010c49-e6e4-4626-a75c-0dbf1925c9e8', - originalTimestamp: '2020-09-30T19:11:00.337Z', - receivedAt: '2020-10-01T00:41:11.369+05:30', - request_ip: '2405:201:8005:9856:7911:25e7:5603:5e18', - sentAt: '2020-09-30T19:11:10.382Z', - timestamp: '2020-10-01T00:41:01.324+05:30', - type: 'identify', - }, - destination: { - DestinationDefinition: { - Config: { - cdkV2Enabled: true, - }, - }, - Config: { - apiKey: 'intercomApiKey', - apiVersion: 'v1', - appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', - collectContext: false, - }, - }, - metadata: { - jobId: 18, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://api.intercom.io/users', - headers: { - 'Content-Type': 'application/json', - Authorization: 'Bearer intercomApiKey', - Accept: 'application/json', - 'Intercom-Version': '1.4', - }, - params: {}, - body: { - JSON: { - email: 'test_1@test.com', - phone: '9876543210', - signed_up_at: 1601493060, - last_seen_user_agent: 'unknown', - custom_attributes: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - key1: 'value1', - }, - update_last_request_at: true, - name: 'Name', - }, - JSON_ARRAY: {}, - XML: {}, - FORM: {}, - }, - files: {}, - userId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - }, - statusCode: 200, - metadata: { - jobId: 18, - }, - }, - ], - }, - }, - }, - { - name: 'intercom', - description: 'Old Version: Identify call without email and userId', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - channel: 'mobile', - context: { - app: { - build: '1.0', - name: 'Test_Example', - namespace: 'com.example.testapp', - version: '1.0', - }, - device: { - id: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - manufacturer: 'Apple', - model: 'iPhone', - name: 'iPod touch (7th generation)', - type: 'iOS', - }, - library: { - name: 'test-ios-library', - version: '1.0.7', - }, - locale: 'en-US', - network: { - bluetooth: false, - carrier: 'unavailable', - cellular: false, - wifi: true, - }, - os: { - name: 'iOS', - version: '14.0', - }, - screen: { - density: 2, - height: 320, - width: 568, - }, - timezone: 'Asia/Kolkata', - traits: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - firstName: 'Name', - createdAt: '2020-09-30T19:11:00.337Z', - phone: '9876543210', - key1: 'value1', - }, - userAgent: 'unknown', - }, - event: 'Test Event 2', - integrations: { - All: true, - }, - messageId: '1601493060-39010c49-e6e4-4626-a75c-0dbf1925c9e8', - originalTimestamp: '2020-09-30T19:11:00.337Z', - receivedAt: '2020-10-01T00:41:11.369+05:30', - request_ip: '2405:201:8005:9856:7911:25e7:5603:5e18', - sentAt: '2020-09-30T19:11:10.382Z', - timestamp: '2020-10-01T00:41:01.324+05:30', - type: 'identify', - }, - destination: { - DestinationDefinition: { - Config: { - cdkV2Enabled: true, - }, - }, - Config: { - apiKey: 'intercomApiKey', - apiVersion: 'v1', - appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', - collectContext: false, - }, - }, - metadata: { - jobId: 19, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - statusCode: 400, - error: - 'Either of `email` or `userId` is required for Identify call: Workflow: procWorkflow, Step: identifyPayloadForOlderVersion, ChildStep: undefined, OriginalError: Either of `email` or `userId` is required for Identify call', - statTags: { - errorCategory: 'dataValidation', - errorType: 'instrumentation', - destType: 'INTERCOM', - module: 'destination', - implementation: 'cdkV2', - feature: 'processor', - }, - metadata: { - jobId: 19, - }, - }, - ], - }, - }, - }, - { - name: 'intercom', - description: 'Old version - successful identify call', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - channel: 'mobile', - context: { - app: { - build: '1.0', - name: 'Test_Example', - namespace: 'com.example.testapp', - version: '1.0', - }, - device: { - id: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - manufacturer: 'Apple', - model: 'iPhone', - name: 'iPod touch (7th generation)', - type: 'iOS', - }, - library: { - name: 'test-ios-library', - version: '1.0.7', - }, - locale: 'en-US', - network: { - bluetooth: false, - carrier: 'unavailable', - cellular: false, - wifi: true, - }, - os: { - name: 'iOS', - version: '14.0', - }, - screen: { - density: 2, - height: 320, - width: 568, - }, - timezone: 'Asia/Kolkata', - traits: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - lastName: 'Name', - createdAt: '2020-09-30T19:11:00.337Z', - email: 'test_1@test.com', - phone: '9876543210', - key1: 'value1', - company: { - name: 'Test Comp', - id: 'company_id', - industry: 'test industry', - key1: 'value1', - key2: { - a: 'a', - }, - key3: [1, 2, 3], - }, - }, - userAgent: 'unknown', - }, - event: 'Test Event 2', - integrations: { - All: true, - }, - messageId: '1601493060-39010c49-e6e4-4626-a75c-0dbf1925c9e8', - originalTimestamp: '2020-09-30T19:11:00.337Z', - receivedAt: '2020-10-01T00:41:11.369+05:30', - request_ip: '2405:201:8005:9856:7911:25e7:5603:5e18', - sentAt: '2020-09-30T19:11:10.382Z', - timestamp: '2020-10-01T00:41:01.324+05:30', - type: 'identify', - }, - destination: { - DestinationDefinition: { - Config: { - cdkV2Enabled: true, - }, - }, - Config: { - apiKey: 'intercomApiKey', - apiVersion: 'v1', - appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', - collectContext: false, - }, - }, - metadata: { - jobId: 20, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://api.intercom.io/users', - headers: { - 'Content-Type': 'application/json', - Authorization: 'Bearer intercomApiKey', - Accept: 'application/json', - 'Intercom-Version': '1.4', - }, - params: {}, - body: { - JSON: { - email: 'test_1@test.com', - phone: '9876543210', - signed_up_at: 1601493060, - last_seen_user_agent: 'unknown', - custom_attributes: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - key1: 'value1', - }, - update_last_request_at: true, - name: 'Name', - companies: [ - { - company_id: 'company_id', - custom_attributes: { - key1: 'value1', - key2: '{"a":"a"}', - key3: '[1,2,3]', - }, - name: 'Test Comp', - industry: 'test industry', - }, - ], - }, - JSON_ARRAY: {}, - XML: {}, - FORM: {}, - }, - files: {}, - userId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - }, - statusCode: 200, - metadata: { - jobId: 20, - }, - }, - ], - }, - }, - }, - { - name: 'intercom', - description: 'Old version - successful identify call', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - channel: 'mobile', - context: { - app: { - build: '1.0', - name: 'Test_Example', - namespace: 'com.example.testapp', - version: '1.0', - }, - device: { - id: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - manufacturer: 'Apple', - model: 'iPhone', - name: 'iPod touch (7th generation)', - type: 'iOS', - }, - library: { - name: 'test-ios-library', - version: '1.0.7', - }, - locale: 'en-US', - network: { - bluetooth: false, - carrier: 'unavailable', - cellular: false, - wifi: true, - }, - os: { - name: 'iOS', - version: '14.0', - }, - screen: { - density: 2, - height: 320, - width: 568, - }, - timezone: 'Asia/Kolkata', - traits: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - lastName: 'Name', - createdAt: '2020-09-30T19:11:00.337Z', - email: 'test_1@test.com', - phone: '9876543210', - key1: 'value1', - company: { - name: 'Test Comp', - industry: 'test industry', - key1: 'value1', - key2: null, - key3: ['value1', 'value2'], - key4: { - foo: 'bar', - }, - }, - }, - userAgent: 'unknown', - }, - event: 'Test Event 2', - integrations: { - All: true, - }, - messageId: '1601493060-39010c49-e6e4-4626-a75c-0dbf1925c9e8', - originalTimestamp: '2020-09-30T19:11:00.337Z', - receivedAt: '2020-10-01T00:41:11.369+05:30', - request_ip: '2405:201:8005:9856:7911:25e7:5603:5e18', - sentAt: '2020-09-30T19:11:10.382Z', - timestamp: '2020-10-01T00:41:01.324+05:30', - type: 'identify', - }, - destination: { - DestinationDefinition: { - Config: { - cdkV2Enabled: true, - }, - }, - Config: { - apiKey: 'intercomApiKey', - apiVersion: 'v1', - appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', - collectContext: false, - updateLastRequestAt: false, - }, - }, - metadata: { - jobId: 21, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://api.intercom.io/users', - headers: { - 'Content-Type': 'application/json', - Authorization: 'Bearer intercomApiKey', - Accept: 'application/json', - 'Intercom-Version': '1.4', - }, - params: {}, - body: { - JSON: { - email: 'test_1@test.com', - phone: '9876543210', - signed_up_at: 1601493060, - last_seen_user_agent: 'unknown', - custom_attributes: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - key1: 'value1', - }, - update_last_request_at: false, - name: 'Name', - companies: [ - { - company_id: 'c0277b5c814453e5135f515f943d085a', - custom_attributes: { - key1: 'value1', - key3: '["value1","value2"]', - key4: '{"foo":"bar"}', - }, - name: 'Test Comp', - industry: 'test industry', - }, - ], - }, - JSON_ARRAY: {}, - XML: {}, - FORM: {}, - }, - files: {}, - userId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - }, - statusCode: 200, - metadata: { - jobId: 21, - }, - }, - ], - }, - }, - }, - { - name: 'intercom', - description: 'Old version - successful identify call', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - channel: 'mobile', - context: { - app: { - build: '1.0', - name: 'Test_Example', - namespace: 'com.example.testapp', - version: '1.0', - }, - device: { - id: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - manufacturer: 'Apple', - model: 'iPhone', - name: 'iPod touch (7th generation)', - type: 'iOS', - }, - library: { - name: 'test-ios-library', - version: '1.0.7', - }, - locale: 'en-US', - network: { - bluetooth: false, - carrier: 'unavailable', - cellular: false, - wifi: true, - }, - os: { - name: 'iOS', - version: '14.0', - }, - screen: { - density: 2, - height: 320, - width: 568, - }, - timezone: 'Asia/Kolkata', - traits: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - lastName: 'Name', - createdAt: '2020-09-30T19:11:00.337Z', - email: 'test_1@test.com', - phone: '9876543210', - key1: 'value1', - company: { - industry: 'test industry', - key1: 'value1', - key2: null, - }, - }, - userAgent: 'unknown', - }, - event: 'Test Event 2', - integrations: { - All: true, - }, - messageId: '1601493060-39010c49-e6e4-4626-a75c-0dbf1925c9e8', - originalTimestamp: '2020-09-30T19:11:00.337Z', - receivedAt: '2020-10-01T00:41:11.369+05:30', - request_ip: '2405:201:8005:9856:7911:25e7:5603:5e18', - sentAt: '2020-09-30T19:11:10.382Z', - timestamp: '2020-10-01T00:41:01.324+05:30', - type: 'identify', - }, - destination: { - DestinationDefinition: { - Config: { - cdkV2Enabled: true, - }, - }, - Config: { - apiKey: 'intercomApiKey', - apiVersion: 'v1', - appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', - collectContext: false, - }, - }, - metadata: { - jobId: 22, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://api.intercom.io/users', - headers: { - 'Content-Type': 'application/json', - Authorization: 'Bearer intercomApiKey', - Accept: 'application/json', - 'Intercom-Version': '1.4', - }, - params: {}, - body: { - JSON: { - email: 'test_1@test.com', - phone: '9876543210', - signed_up_at: 1601493060, - last_seen_user_agent: 'unknown', - custom_attributes: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - key1: 'value1', - }, - update_last_request_at: true, - name: 'Name', - companies: [], - }, - JSON_ARRAY: {}, - XML: {}, - FORM: {}, - }, - files: {}, - userId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - }, - statusCode: 200, - metadata: { - jobId: 22, - }, - }, - ], - }, - }, - }, - { - name: 'intercom', - description: 'Old version - successful track call', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - channel: 'mobile', - context: { - app: { - build: '1.0', - name: 'Test_Example', - namespace: 'com.example.testapp', - version: '1.0', - }, - device: { - id: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - manufacturer: 'Apple', - model: 'iPhone', - name: 'iPod touch (7th generation)', - type: 'iOS', - }, - library: { - name: 'test-ios-library', - version: '1.0.7', - }, - locale: 'en-US', - network: { - bluetooth: false, - carrier: 'unavailable', - cellular: false, - wifi: true, - }, - os: { - name: 'iOS', - version: '14.0', - }, - screen: { - density: 2, - height: 320, - width: 568, - }, - timezone: 'Asia/Kolkata', - traits: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - name: 'Test Name', - firstName: 'Test', - lastName: 'Name', - createdAt: '2020-09-30T19:11:00.337Z', - userId: 'test_user_id_1', - email: 'test_1@test.com', - phone: '9876543210', - key1: 'value1', - }, - userAgent: 'unknown', - }, - properties: { - property1: 1, - property2: 'test', - property3: true, - property4: '2020-10-05T09:09:03.731Z', - property5: { - property1: 1, - property2: 'test', - property3: { - subProp1: { - a: 'a', - b: 'b', - }, - subProp2: ['a', 'b'], - }, - }, - properties6: null, - revenue: { - amount: 1232, - currency: 'inr', - test: 123, - }, - price: { - amount: 3000, - currency: 'USD', - }, - article: { - url: 'https://example.org/ab1de.html', - value: 'the dude abides', - }, - }, - event: 'Test Event 2', - integrations: { - All: true, - }, - messageId: '1601493060-39010c49-e6e4-4626-a75c-0dbf1925c9e8', - originalTimestamp: '2020-09-30T19:11:00.337Z', - receivedAt: '2020-10-01T00:41:11.369+05:30', - request_ip: '2405:201:8005:9856:7911:25e7:5603:5e18', - sentAt: '2020-09-30T19:11:10.382Z', - timestamp: '2020-10-01T00:41:01.324+05:30', - type: 'track', - }, - destination: { - DestinationDefinition: { - Config: { - cdkV2Enabled: true, - }, - }, - Config: { - apiKey: 'intercomApiKey', - apiVersion: 'v1', - appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', - collectContext: false, - }, - }, - metadata: { - jobId: 23, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://api.intercom.io/events', - headers: { - 'Content-Type': 'application/json', - Authorization: 'Bearer intercomApiKey', - Accept: 'application/json', - 'Intercom-Version': '1.4', - }, - params: {}, - body: { - JSON: { - user_id: 'test_user_id_1', - email: 'test_1@test.com', - event_name: 'Test Event 2', - created: 1601493061, - metadata: { - revenue: { - amount: 1232, - currency: 'inr', - test: 123, - }, - price: { - amount: 3000, - currency: 'USD', - }, - article: { - url: 'https://example.org/ab1de.html', - value: 'the dude abides', - }, - property1: 1, - property2: 'test', - property3: true, - property4: '2020-10-05T09:09:03.731Z', - 'property5.property1': 1, - 'property5.property2': 'test', - 'property5.property3.subProp1.a': 'a', - 'property5.property3.subProp1.b': 'b', - 'property5.property3.subProp2[0]': 'a', - 'property5.property3.subProp2[1]': 'b', - properties6: null, - }, - }, - JSON_ARRAY: {}, - XML: {}, - FORM: {}, - }, - files: {}, - userId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - }, - statusCode: 200, - metadata: { - jobId: 23, - }, - }, - ], - }, - }, - }, - { - name: 'intercom', - description: 'Old version - successful track call', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - channel: 'mobile', - context: { - app: { - build: '1.0', - name: 'Test_Example', - namespace: 'com.example.testapp', - version: '1.0', - }, - device: { - id: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - manufacturer: 'Apple', - model: 'iPhone', - name: 'iPod touch (7th generation)', - type: 'iOS', - }, - library: { - name: 'test-ios-library', - version: '1.0.7', - }, - locale: 'en-US', - network: { - bluetooth: false, - carrier: 'unavailable', - cellular: false, - wifi: true, - }, - os: { - name: 'iOS', - version: '14.0', - }, - screen: { - density: 2, - height: 320, - width: 568, - }, - timezone: 'Asia/Kolkata', - traits: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - name: 'Test Name', - firstName: 'Test', - lastName: 'Name', - createdAt: '2020-09-30T19:11:00.337Z', - email: 'test_1@test.com', - phone: '9876543210', - key1: 'value1', - }, - userAgent: 'unknown', - }, - event: 'Test Event 2', - integrations: { - All: true, - }, - messageId: '1601493060-39010c49-e6e4-4626-a75c-0dbf1925c9e8', - originalTimestamp: '2020-09-30T19:11:00.337Z', - receivedAt: '2020-10-01T00:41:11.369+05:30', - request_ip: '2405:201:8005:9856:7911:25e7:5603:5e18', - sentAt: '2020-09-30T19:11:10.382Z', - timestamp: '2020-10-01T00:41:01.324+05:30', - type: 'track', - }, - destination: { - DestinationDefinition: { - Config: { - cdkV2Enabled: true, - }, - }, - Config: { - apiKey: 'intercomApiKey', - apiVersion: 'v1', - appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', - collectContext: false, - }, - }, - metadata: { - jobId: 24, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://api.intercom.io/events', - headers: { - 'Content-Type': 'application/json', - Authorization: 'Bearer intercomApiKey', - Accept: 'application/json', - 'Intercom-Version': '1.4', - }, - params: {}, - body: { - JSON: { - email: 'test_1@test.com', - event_name: 'Test Event 2', - created: 1601493061, - }, - JSON_ARRAY: {}, - XML: {}, - FORM: {}, - }, - files: {}, - userId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - }, - statusCode: 200, - metadata: { - jobId: 24, - }, - }, - ], - }, - }, - }, - { - name: 'intercom', - description: 'Old version : Track call without email or userId', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - channel: 'mobile', - context: { - app: { - build: '1.0', - name: 'Test_Example', - namespace: 'com.example.testapp', - version: '1.0', - }, - device: { - id: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - manufacturer: 'Apple', - model: 'iPhone', - name: 'iPod touch (7th generation)', - type: 'iOS', - }, - library: { - name: 'test-ios-library', - version: '1.0.7', - }, - locale: 'en-US', - network: { - bluetooth: false, - carrier: 'unavailable', - cellular: false, - wifi: true, - }, - os: { - name: 'iOS', - version: '14.0', - }, - screen: { - density: 2, - height: 320, - width: 568, - }, - timezone: 'Asia/Kolkata', - traits: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - name: 'Test Name', - firstName: 'Test', - lastName: 'Name', - createdAt: '2020-09-30T19:11:00.337Z', - phone: '9876543210', - key1: 'value1', - }, - userAgent: 'unknown', - }, - event: 'Test Event 2', - integrations: { - All: true, - }, - messageId: '1601493060-39010c49-e6e4-4626-a75c-0dbf1925c9e8', - originalTimestamp: '2020-09-30T19:11:00.337Z', - receivedAt: '2020-10-01T00:41:11.369+05:30', - request_ip: '2405:201:8005:9856:7911:25e7:5603:5e18', - sentAt: '2020-09-30T19:11:10.382Z', - timestamp: '2020-10-01T00:41:01.324+05:30', - type: 'track', - }, - destination: { - DestinationDefinition: { - Config: { - cdkV2Enabled: true, - }, - }, - Config: { - apiKey: 'intercomApiKey', - apiVersion: 'v1', - appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', - collectContext: false, - }, - }, - metadata: { - jobId: 25, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - statusCode: 400, - error: - 'Either email or userId is required for Track call: Workflow: procWorkflow, Step: trackPayload, ChildStep: undefined, OriginalError: Either email or userId is required for Track call', - statTags: { - errorCategory: 'dataValidation', - errorType: 'instrumentation', - destType: 'INTERCOM', - module: 'destination', - implementation: 'cdkV2', - feature: 'processor', - }, - metadata: { - jobId: 25, - }, - }, - ], - }, - }, - }, - { - name: 'intercom', - description: 'Old version : successful identify call', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - channel: 'mobile', - context: { - app: { - build: '1.0', - name: 'Test_Example', - namespace: 'com.example.testapp', - version: '1.0', - }, - externalId: [ - { - id: '10156', - type: 'INTERCOM-customer', - identifierType: 'user_id', - }, - ], - mappedToDestination: 'true', - device: { - id: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - manufacturer: 'Apple', - model: 'iPhone', - name: 'iPod touch (7th generation)', - type: 'iOS', - }, - library: { - name: 'test-ios-library', - version: '1.0.7', - }, - locale: 'en-US', - network: { - bluetooth: false, - carrier: 'unavailable', - cellular: false, - wifi: true, - }, - os: { - name: 'iOS', - version: '14.0', - }, - screen: { - density: 2, - height: 320, - width: 568, - }, - timezone: 'Asia/Kolkata', - traits: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - name: 'Test Name', - firstName: 'Test', - lastName: 'Name', - createdAt: '2020-09-30T19:11:00.337Z', - phone: '9876543210', - key1: 'value1', - }, - userAgent: 'unknown', - }, - event: 'Test Event 2', - integrations: { - All: true, - }, - messageId: '1601493060-39010c49-e6e4-4626-a75c-0dbf1925c9e8', - originalTimestamp: '2020-09-30T19:11:00.337Z', - receivedAt: '2020-10-01T00:41:11.369+05:30', - request_ip: '2405:201:8005:9856:7911:25e7:5603:5e18', - sentAt: '2020-09-30T19:11:10.382Z', - timestamp: '2020-10-01T00:41:01.324+05:30', - type: 'identify', - }, - destination: { - DestinationDefinition: { - Config: { - cdkV2Enabled: true, - }, - }, - Config: { - apiKey: 'intercomApiKey', - apiVersion: 'v1', - appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', - collectContext: false, - }, - }, - metadata: { - jobId: 26, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://api.intercom.io/users', - headers: { - 'Content-Type': 'application/json', - Authorization: 'Bearer intercomApiKey', - Accept: 'application/json', - 'Intercom-Version': '1.4', - }, - params: {}, - body: { - JSON: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - name: 'Test Name', - firstName: 'Test', - lastName: 'Name', - createdAt: '2020-09-30T19:11:00.337Z', - phone: '9876543210', - key1: 'value1', - update_last_request_at: true, - user_id: '10156', - }, - JSON_ARRAY: {}, - XML: {}, - FORM: {}, - }, - files: {}, - userId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - }, - statusCode: 200, - metadata: { - jobId: 26, - }, - }, - ], - }, - }, - }, - { - name: 'intercom', - description: 'Old version : successful identify call', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - channel: 'mobile', - context: { - app: { - build: '1.0', - name: 'Test_Example', - namespace: 'com.example.testapp', - version: '1.0', - }, - device: { - id: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - manufacturer: 'Apple', - model: 'iPhone', - name: 'iPod touch (7th generation)', - type: 'iOS', - }, - library: { - name: 'test-ios-library', - version: '1.0.7', - }, - locale: 'en-US', - network: { - bluetooth: false, - carrier: 'unavailable', - cellular: false, - wifi: true, - }, - os: { - name: 'iOS', - version: '14.0', - }, - screen: { - density: 2, - height: 320, - width: 568, - }, - timezone: 'Asia/Kolkata', - traits: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - name: 'Test Name', - firstName: 'Test', - lastName: 'Name', - createdAt: '2020-09-30T19:11:00.337Z', - phone: '9876543210', - key1: 'value1', - }, - userAgent: 'unknown', - }, - event: 'Test Event 2', - integrations: { - All: true, - }, - messageId: '1601493060-39010c49-e6e4-4626-a75c-0dbf1925c9e8', - originalTimestamp: '2020-09-30T19:11:00.337Z', - receivedAt: '2020-10-01T00:41:11.369+05:30', - request_ip: '2405:201:8005:9856:7911:25e7:5603:5e18', - sentAt: '2020-09-30T19:11:10.382Z', - timestamp: '2020-10-01T00:41:01.324+05:30', - type: 'identify', - }, - destination: { - DestinationDefinition: { - Config: { - cdkV2Enabled: true, - }, - }, - Config: { - apiKey: 'intercomApiKey', - apiVersion: 'v1', - appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', - collectContext: false, - sendAnonymousId: true, - }, - }, - metadata: { - jobId: 27, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://api.intercom.io/users', - headers: { - 'Content-Type': 'application/json', - Authorization: 'Bearer intercomApiKey', - Accept: 'application/json', - 'Intercom-Version': '1.4', - }, - params: {}, - body: { - JSON: { - phone: '9876543210', - name: 'Test Name', - signed_up_at: 1601493060, - last_seen_user_agent: 'unknown', - custom_attributes: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - key1: 'value1', - }, - user_id: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - update_last_request_at: true, - }, - JSON_ARRAY: {}, - XML: {}, - FORM: {}, - }, - files: {}, - userId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - }, - statusCode: 200, - metadata: { - jobId: 27, - }, - }, - ], - }, - }, - }, - { - name: 'intercom', - description: 'Old version : Identify call without email or userId', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - channel: 'mobile', - context: { - app: { - build: '1.0', - name: 'Test_Example', - namespace: 'com.example.testapp', - version: '1.0', - }, - device: { - id: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - manufacturer: 'Apple', - model: 'iPhone', - name: 'iPod touch (7th generation)', - type: 'iOS', - }, - library: { - name: 'test-ios-library', - version: '1.0.7', - }, - locale: 'en-US', - network: { - bluetooth: false, - carrier: 'unavailable', - cellular: false, - wifi: true, - }, - os: { - name: 'iOS', - version: '14.0', - }, - screen: { - density: 2, - height: 320, - width: 568, - }, - timezone: 'Asia/Kolkata', - traits: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - name: 'Test Name', - firstName: 'Test', - lastName: 'Name', - createdAt: '2020-09-30T19:11:00.337Z', - phone: '9876543210', - key1: 'value1', - }, - userAgent: 'unknown', - }, - event: 'Test Event 2', - integrations: { - All: true, - }, - messageId: '1601493060-39010c49-e6e4-4626-a75c-0dbf1925c9e8', - originalTimestamp: '2020-09-30T19:11:00.337Z', - receivedAt: '2020-10-01T00:41:11.369+05:30', - request_ip: '2405:201:8005:9856:7911:25e7:5603:5e18', - sentAt: '2020-09-30T19:11:10.382Z', - timestamp: '2020-10-01T00:41:01.324+05:30', - type: 'identify', - }, - destination: { - DestinationDefinition: { - Config: { - cdkV2Enabled: true, - }, - }, - Config: { - apiKey: 'intercomApiKey', - apiVersion: 'v1', - appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', - collectContext: false, - sendAnonymousId: false, - }, - }, - metadata: { - jobId: 28, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - statusCode: 400, - error: - 'Either of `email` or `userId` is required for Identify call: Workflow: procWorkflow, Step: identifyPayloadForOlderVersion, ChildStep: undefined, OriginalError: Either of `email` or `userId` is required for Identify call', - statTags: { - errorCategory: 'dataValidation', - errorType: 'instrumentation', - destType: 'INTERCOM', - module: 'destination', - implementation: 'cdkV2', - feature: 'processor', - }, - metadata: { - jobId: 28, - }, - }, - ], - }, - }, - }, - { - name: 'intercom', - description: 'Old version : successful group call', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - groupId: 'test_company_id_wdasda', - traits: { - employees: 450, - plan: 'basic', - userId: 'sdfrsdfsdfsf', - email: 'test@test.com', - name: 'rudderUpdate', - size: '50', - industry: 'IT', - monthlySpend: '2131231', - remoteCreatedAt: '1683017572', - key1: 'val1', - }, - anonymousId: 'sdfrsdfsdfsf', - integrations: { - All: true, - }, - type: 'group', - userId: 'sdfrsdfsdfsf', - }, - destination: { - DestinationDefinition: { - Config: { - cdkV2Enabled: true, - }, - }, - Config: { - apiKey: 'abcd=', - appId: 'asdasdasd', - apiVersion: 'v1', - collectContext: false, - }, - }, - metadata: { - jobId: 29, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://api.intercom.io/companies', - headers: { - 'Content-Type': 'application/json', - Authorization: 'Bearer abcd=', - Accept: 'application/json', - 'Intercom-Version': '1.4', - }, - params: {}, - body: { - JSON: { - company_id: 'test_company_id_wdasda', - name: 'rudderUpdate', - plan: 'basic', - size: 50, - industry: 'IT', - monthly_spend: 2131231, - remote_created_at: 1683017572, - custom_attributes: { - employees: 450, - email: 'test@test.com', - key1: 'val1', - }, - }, - JSON_ARRAY: {}, - XML: {}, - FORM: {}, - }, - files: {}, - userId: 'sdfrsdfsdfsf', - }, - statusCode: 200, - metadata: { - jobId: 29, - }, - }, - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://api.intercom.io/users', - headers: { - 'Content-Type': 'application/json', - Authorization: 'Bearer abcd=', - Accept: 'application/json', - 'Intercom-Version': '1.4', - }, - params: {}, - body: { - JSON: { - user_id: 'sdfrsdfsdfsf', - companies: [ - { - company_id: 'test_company_id_wdasda', - name: 'rudderUpdate', - }, - ], - }, - JSON_ARRAY: {}, - XML: {}, - FORM: {}, - }, - files: {}, - userId: 'sdfrsdfsdfsf', - }, - statusCode: 200, - metadata: { - jobId: 29, - }, - }, - ], - }, - }, - }, - { - name: 'intercom', - description: 'Old version : successful group call', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - groupId: 'test_company_id', - traits: { - plan: 'basic', - name: 'rudderUpdate', - size: 50, - industry: 'IT', - monthlySpend: '2131231', - email: 'comanyemail@abc.com', - }, - anonymousId: '12312312', - context: { - app: { - build: '1.0', - name: 'Test_Example', - namespace: 'com.example.testapp', - version: '1.0', - }, - device: { - id: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - manufacturer: 'Apple', - model: 'iPhone', - name: 'iPod touch (7th generation)', - type: 'iOS', - }, - library: { - name: 'test-ios-library', - version: '1.0.7', - }, - locale: 'en-US', - network: { - bluetooth: false, - carrier: 'unavailable', - cellular: false, - wifi: true, - }, - os: { - name: 'iOS', - version: '14.0', - }, - screen: { - density: 2, - height: 320, - width: 568, - }, - timezone: 'Asia/Kolkata', - userAgent: 'unknown', - }, - integrations: { - All: true, - }, - messageId: '1601493060-39010c49-e6e4-4626-a75c-0dbf1925c9e8', - type: 'group', - }, - destination: { - DestinationDefinition: { - Config: { - cdkV2Enabled: true, - }, - }, - Config: { - apiKey: 'abcd=', - apiVersion: 'v1', - appId: 'asdasdasd', - collectContext: false, - }, - }, - metadata: { - jobId: 30, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://api.intercom.io/companies', - headers: { - 'Content-Type': 'application/json', - Authorization: 'Bearer abcd=', - Accept: 'application/json', - 'Intercom-Version': '1.4', - }, - params: {}, - body: { - JSON: { - company_id: 'test_company_id', - name: 'rudderUpdate', - plan: 'basic', - size: 50, - industry: 'IT', - monthly_spend: 2131231, - custom_attributes: { - email: 'comanyemail@abc.com', - }, - }, - JSON_ARRAY: {}, - XML: {}, - FORM: {}, - }, - files: {}, - userId: '12312312', - }, - statusCode: 200, - metadata: { - jobId: 30, - }, - }, - ], - }, - }, - }, - { - name: 'intercom', - description: 'Old version : successful group call', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - groupId: 'test_company_id_wdasda', - context: { - traits: { - email: 'testUser@test.com', - }, - }, - traits: { - employees: 450, - plan: 'basic', - email: 'test@test.com', - name: 'rudderUpdate', - size: '50', - industry: 'IT', - website: 'url', - monthlySpend: '2131231', - remoteCreatedAt: '1683017572', - key1: 'val1', - }, - anonymousId: 'sdfrsdfsdfsf', - integrations: { - All: true, - }, - type: 'group', - userId: 'sdfrsdfsdfsf', - }, - destination: { - DestinationDefinition: { - Config: { - cdkV2Enabled: true, - }, - }, - Config: { - apiKey: 'abcd=', - apiVersion: 'v1', - appId: 'asdasdasd', - collectContext: false, - }, - }, - metadata: { - jobId: 31, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://api.intercom.io/companies', - headers: { - 'Content-Type': 'application/json', - Authorization: 'Bearer abcd=', - Accept: 'application/json', - 'Intercom-Version': '1.4', - }, - params: {}, - body: { - JSON: { - company_id: 'test_company_id_wdasda', - name: 'rudderUpdate', - plan: 'basic', - size: 50, - website: 'url', - industry: 'IT', - monthly_spend: 2131231, - remote_created_at: 1683017572, - custom_attributes: { - employees: 450, - email: 'test@test.com', - key1: 'val1', - }, - }, - JSON_ARRAY: {}, - XML: {}, - FORM: {}, - }, - files: {}, - userId: 'sdfrsdfsdfsf', - }, - statusCode: 200, - metadata: { - jobId: 31, - }, - }, - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://api.intercom.io/users', - headers: { - 'Content-Type': 'application/json', - Authorization: 'Bearer abcd=', - Accept: 'application/json', - 'Intercom-Version': '1.4', - }, - params: {}, - body: { - JSON: { - user_id: 'sdfrsdfsdfsf', - email: 'testUser@test.com', - companies: [ - { - company_id: 'test_company_id_wdasda', - name: 'rudderUpdate', - }, - ], - }, - JSON_ARRAY: {}, - XML: {}, - FORM: {}, - }, - files: {}, - userId: 'sdfrsdfsdfsf', - }, - statusCode: 200, - metadata: { - jobId: 31, - }, - }, - ], - }, - }, - }, - { - name: 'intercom', - description: 'Old version : successful group call', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - groupId: 'test_company_id_wdasda', - context: { - traits: { - email: 'testUser@test.com', - }, - }, - traits: { - employees: 450, - plan: 'basic', - email: 'test@test.com', - name: 'rudderUpdate', - size: '50', - industry: 'IT', - website: 'url', - monthlySpend: '2131231', - remoteCreatedAt: '1683017572', - key1: 'val1', - key2: { - a: 'a', - b: 'b', - }, - key3: [1, 2, 3], - key4: null, - }, - anonymousId: 'anonId', - integrations: { - All: true, - }, - type: 'group', - }, - destination: { - DestinationDefinition: { - Config: { - cdkV2Enabled: true, - }, - }, - Config: { - apiKey: 'abcd=', - appId: 'asdasdasd', - apiVersion: 'v1', - collectContext: false, - sendAnonymousId: true, - }, - }, - metadata: { - jobId: 32, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://api.intercom.io/companies', - headers: { - 'Content-Type': 'application/json', - Authorization: 'Bearer abcd=', - Accept: 'application/json', - 'Intercom-Version': '1.4', - }, - params: {}, - body: { - JSON: { - company_id: 'test_company_id_wdasda', - name: 'rudderUpdate', - plan: 'basic', - size: 50, - website: 'url', - industry: 'IT', - monthly_spend: 2131231, - remote_created_at: 1683017572, - custom_attributes: { - employees: 450, - email: 'test@test.com', - key1: 'val1', - 'key2.a': 'a', - 'key2.b': 'b', - 'key3[0]': 1, - 'key3[1]': 2, - 'key3[2]': 3, - key4: null, - }, - }, - JSON_ARRAY: {}, - XML: {}, - FORM: {}, - }, - files: {}, - userId: 'anonId', - }, - statusCode: 200, - metadata: { - jobId: 32, - }, - }, - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://api.intercom.io/users', - headers: { - 'Content-Type': 'application/json', - Authorization: 'Bearer abcd=', - Accept: 'application/json', - 'Intercom-Version': '1.4', - }, - params: {}, - body: { - JSON: { - user_id: 'anonId', - email: 'testUser@test.com', - companies: [ - { - company_id: 'test_company_id_wdasda', - name: 'rudderUpdate', - }, - ], - }, - JSON_ARRAY: {}, - XML: {}, - FORM: {}, - }, - files: {}, - userId: 'anonId', - }, - statusCode: 200, - metadata: { - jobId: 32, - }, - }, - ], - }, - }, - }, - { - name: 'intercom', - description: 'Test 0', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - channel: 'mobile', - context: { - app: { - build: '1.0', - name: 'Test_Example', - namespace: 'com.example.testapp', - version: '1.0', - }, - device: { - id: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - manufacturer: 'Apple', - model: 'iPhone', - name: 'iPod touch (7th generation)', - type: 'iOS', - }, - library: { - name: 'test-ios-library', - version: '1.0.7', - }, - locale: 'en-US', - network: { - bluetooth: false, - carrier: 'unavailable', - cellular: false, - wifi: true, - }, - os: { - name: 'iOS', - version: '14.0', - }, - screen: { - density: 2, - height: 320, - width: 568, - }, - timezone: 'Asia/Kolkata', - traits: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - name: 'Test Name', - firstName: 'Test', - lastName: 'Name', - createdAt: '2020-09-30T19:11:00.337Z', - userId: 'test_user_id_1', - email: 'test_1@test.com', - phone: '9876543210', - key1: 'value1', - address: { - city: 'Kolkata', - state: 'West Bengal', - }, - originalArray: [ - { - nested_field: 'nested value', - tags: ['tag_1', 'tag_2', 'tag_3'], - }, - { - nested_field: 'nested value', - tags: ['tag_1'], - }, - { - nested_field: 'nested value', - }, - ], - }, - userAgent: 'unknown', - }, - event: 'Test Event 2', - integrations: { - All: true, - }, - messageId: '1601493060-39010c49-e6e4-4626-a75c-0dbf1925c9e8', - originalTimestamp: '2020-09-30T19:11:00.337Z', - receivedAt: '2020-10-01T00:41:11.369+05:30', - request_ip: '2405:201:8005:9856:7911:25e7:5603:5e18', - sentAt: '2020-09-30T19:11:10.382Z', - timestamp: '2020-10-01T00:41:01.324+05:30', - type: 'identify', - }, - destination: { - Config: { - apiKey: 'intercomApiKey', - appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', - collectContext: false, - }, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://api.intercom.io/users', - headers: { - 'Content-Type': 'application/json', - Authorization: 'Bearer intercomApiKey', - Accept: 'application/json', - 'Intercom-Version': '1.4', - }, - params: {}, - body: { - JSON: { - user_id: 'test_user_id_1', - email: 'test_1@test.com', - phone: '9876543210', - name: 'Test Name', - signed_up_at: 1601493060, - last_seen_user_agent: 'unknown', - custom_attributes: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - key1: 'value1', - 'address.city': 'Kolkata', - 'address.state': 'West Bengal', - 'originalArray[0].nested_field': 'nested value', - 'originalArray[0].tags[0]': 'tag_1', - 'originalArray[0].tags[1]': 'tag_2', - 'originalArray[0].tags[2]': 'tag_3', - 'originalArray[1].nested_field': 'nested value', - 'originalArray[1].tags[0]': 'tag_1', - 'originalArray[2].nested_field': 'nested value', - }, - update_last_request_at: true, - }, - JSON_ARRAY: {}, - XML: {}, - FORM: {}, - }, - files: {}, - userId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'intercom', - description: 'Test 1', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - channel: 'mobile', - context: { - app: { - build: '1.0', - name: 'Test_Example', - namespace: 'com.example.testapp', - version: '1.0', - }, - device: { - id: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - manufacturer: 'Apple', - model: 'iPhone', - name: 'iPod touch (7th generation)', - type: 'iOS', - }, - library: { - name: 'test-ios-library', - version: '1.0.7', - }, - locale: 'en-US', - network: { - bluetooth: false, - carrier: 'unavailable', - cellular: false, - wifi: true, - }, - os: { - name: 'iOS', - version: '14.0', - }, - screen: { - density: 2, - height: 320, - width: 568, - }, - timezone: 'Asia/Kolkata', - traits: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - firstName: 'Test', - lastName: 'Name', - createdAt: '2020-09-30T19:11:00.337Z', - email: 'test_1@test.com', - phone: '9876543210', - key1: 'value1', - }, - userAgent: 'unknown', - }, - event: 'Test Event 2', - integrations: { - All: true, - }, - messageId: '1601493060-39010c49-e6e4-4626-a75c-0dbf1925c9e8', - originalTimestamp: '2020-09-30T19:11:00.337Z', - receivedAt: '2020-10-01T00:41:11.369+05:30', - request_ip: '2405:201:8005:9856:7911:25e7:5603:5e18', - sentAt: '2020-09-30T19:11:10.382Z', - timestamp: '2020-10-01T00:41:01.324+05:30', - type: 'identify', - }, - destination: { - Config: { - apiKey: 'intercomApiKey', - appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', - collectContext: false, - }, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://api.intercom.io/users', - headers: { - 'Content-Type': 'application/json', - Authorization: 'Bearer intercomApiKey', - Accept: 'application/json', - 'Intercom-Version': '1.4', - }, - params: {}, - body: { - JSON: { - email: 'test_1@test.com', - phone: '9876543210', - signed_up_at: 1601493060, - last_seen_user_agent: 'unknown', - custom_attributes: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - key1: 'value1', - }, - update_last_request_at: true, - name: 'Test Name', - }, - JSON_ARRAY: {}, - XML: {}, - FORM: {}, - }, - files: {}, - userId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - }, - statusCode: 200, - }, - ], - }, - }, - }, - { - name: 'intercom', - description: 'Test 2', - feature: 'processor', - module: 'destination', - version: 'v0', - input: { - request: { - body: [ - { - message: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - channel: 'mobile', - context: { - app: { - build: '1.0', - name: 'Test_Example', - namespace: 'com.example.testapp', - version: '1.0', - }, - device: { - id: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - manufacturer: 'Apple', - model: 'iPhone', - name: 'iPod touch (7th generation)', - type: 'iOS', - }, - library: { - name: 'test-ios-library', - version: '1.0.7', - }, - locale: 'en-US', - network: { - bluetooth: false, - carrier: 'unavailable', - cellular: false, - wifi: true, - }, - os: { - name: 'iOS', - version: '14.0', - }, - screen: { - density: 2, - height: 320, - width: 568, - }, - timezone: 'Asia/Kolkata', - traits: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - lastName: 'Name', - createdAt: '2020-09-30T19:11:00.337Z', - email: 'test_1@test.com', - phone: '9876543210', - key1: 'value1', - }, - userAgent: 'unknown', - }, - event: 'Test Event 2', - integrations: { - All: true, - }, - messageId: '1601493060-39010c49-e6e4-4626-a75c-0dbf1925c9e8', - originalTimestamp: '2020-09-30T19:11:00.337Z', - receivedAt: '2020-10-01T00:41:11.369+05:30', - request_ip: '2405:201:8005:9856:7911:25e7:5603:5e18', - sentAt: '2020-09-30T19:11:10.382Z', - timestamp: '2020-10-01T00:41:01.324+05:30', - type: 'identify', - }, - destination: { - Config: { - apiKey: 'intercomApiKey', - appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', - collectContext: false, - }, - }, - }, - ], - }, - }, - output: { - response: { - status: 200, - body: [ - { - output: { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://api.intercom.io/users', - headers: { - 'Content-Type': 'application/json', - Authorization: 'Bearer intercomApiKey', - Accept: 'application/json', - 'Intercom-Version': '1.4', - }, - params: {}, - body: { - JSON: { - email: 'test_1@test.com', - phone: '9876543210', - signed_up_at: 1601493060, - last_seen_user_agent: 'unknown', - custom_attributes: { - anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - key1: 'value1', - }, - update_last_request_at: true, - name: 'Name', - }, - JSON_ARRAY: {}, - XML: {}, - FORM: {}, - }, - files: {}, - userId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', - }, - statusCode: 200, - }, - ], - }, - }, - }, + ...identifyTestData, + ...trackTestData, + ...groupTestData, + ...validationTestData, ]; diff --git a/test/integrations/destinations/intercom/processor/groupTestData.ts b/test/integrations/destinations/intercom/processor/groupTestData.ts new file mode 100644 index 0000000000..cb81df7bd2 --- /dev/null +++ b/test/integrations/destinations/intercom/processor/groupTestData.ts @@ -0,0 +1,509 @@ +import { Destination } from '../../../../../src/types'; +import { + generateMetadata, + transformResultBuilder, + generateSimplifiedGroupPayload, +} from '../../../testUtils'; + +const v1Config = { + apiKey: 'abcd=', + appId: 'asdasdasd', + apiVersion: 'v1', + collectContext: false, +}; + +const v2Config = { + apiKey: 'testApiKey', + apiVersion: 'v2', + apiServer: 'standard', + sendAnonymousId: false, +}; + +const v1Headers = { + 'Content-Type': 'application/json', + Authorization: 'Bearer abcd=', + Accept: 'application/json', + 'Intercom-Version': '1.4', +}; + +const v2Headers = { + Accept: 'application/json', + Authorization: 'Bearer testApiKey', + 'Content-Type': 'application/json', + 'Intercom-Version': '2.10', +}; + +const destination: Destination = { + ID: '123', + Name: 'intercom', + DestinationDefinition: { + ID: '123', + Name: 'intercom', + DisplayName: 'Intercom', + Config: { + cdkV2Enabled: true, + }, + }, + Config: {}, + Enabled: true, + WorkspaceID: '123', + Transformations: [], +}; + +const v1Destination = { ...destination, Config: v1Config }; +const v2Destination = { ...destination, Config: v2Config }; + +const userTraits = { + ownerId: '17', + firstName: 'John', + lastName: 'Snow', + phone: '+91 9599999999', + email: 'test+5@rudderlabs.com', +}; + +const group1Traits = { + size: 500, + industry: 'CDP', + plan: 'enterprise', + name: 'RudderStack', + website: 'www.rudderstack.com', +}; + +const group2Traits = { + size: '50', + key1: 'val1', + plan: 'basic', + industry: 'IT', + employees: 450, + monthlySpend: '2131231', + userId: 'sdfrsdfsdfsf', + email: 'test@test.com', + name: 'rudderUpdate', + remoteCreatedAt: '1683017572', +}; + +const timestamp = '2023-11-22T10:12:44.757+05:30'; +const originalTimestamp = '2023-11-10T14:42:44.724Z'; + +const endpoint = 'https://api.intercom.io/companies'; + +export const groupTestData = [ + { + id: 'intercom-group-test-1', + name: 'intercom', + description: 'V2 version : Successful group call to create or update company', + scenario: 'Business', + successCriteria: + 'Response status code should be 200 and response should contain create or update company payload', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: v2Destination, + message: generateSimplifiedGroupPayload({ + userId: 'user@4', + groupId: 'rudderlabs', + context: { + traits: { email: 'test+4@rudderlabs.com' }, + }, + traits: group1Traits, + timestamp, + originalTimestamp, + }), + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: '', + endpoint, + headers: v2Headers, + JSON: { company_id: 'rudderlabs', ...group1Traits }, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'intercom-group-test-2', + name: 'intercom', + description: 'V2 version : Successful group call to add user to company', + scenario: 'Business', + successCriteria: + 'Response status code should be 200 and response should contain add user to company payload', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { ...v2Destination, Config: { ...v2Destination.Config, apiServer: 'eu' } }, + message: generateSimplifiedGroupPayload({ + userId: 'user@5', + groupId: 'rudderlabs', + context: { + traits: userTraits, + }, + traits: group1Traits, + timestamp, + originalTimestamp, + }), + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: '', + endpoint: 'https://api.eu.intercom.io/contacts/70701240741e45d040/companies', + headers: v2Headers, + JSON: { id: '657264e9018c0a647s45' }, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'intercom-group-test-3', + name: 'intercom', + description: + 'V1 version : successful group call to create company and add user to company based on userId', + scenario: 'Business', + successCriteria: + 'Response status code should be 200 and response should contain create company and add user to company payload', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: v1Destination, + message: generateSimplifiedGroupPayload({ + userId: 'sdfrsdfsdfsf', + anonymousId: 'sdfrsdfsdfsf', + groupId: 'test_company_id_wdasda', + context: { + traits: {}, + }, + traits: group2Traits, + timestamp, + originalTimestamp, + }), + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: 'sdfrsdfsdfsf', + endpoint, + headers: v1Headers, + JSON: { + company_id: 'test_company_id_wdasda', + custom_attributes: { + email: 'test@test.com', + employees: 450, + key1: 'val1', + }, + industry: 'IT', + monthly_spend: 2131231, + name: 'rudderUpdate', + plan: 'basic', + remote_created_at: 1683017572, + size: 50, + }, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + { + output: transformResultBuilder({ + userId: 'sdfrsdfsdfsf', + endpoint: 'https://api.intercom.io/users', + headers: v1Headers, + JSON: { + companies: [ + { + name: 'rudderUpdate', + company_id: 'test_company_id_wdasda', + }, + ], + user_id: 'sdfrsdfsdfsf', + }, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'intercom-group-test-4', + name: 'intercom', + description: + 'V1 version : successful group call to create company and add user to company based on userId', + scenario: 'Business', + successCriteria: + 'Response status code should be 200 and response should contain create company and add user to company payload', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: v1Destination, + message: generateSimplifiedGroupPayload({ + userId: 'sdfrsdfsdfsf', + anonymousId: 'sdfrsdfsdfsf', + groupId: 'test_company_id_wdasda', + context: { + traits: { + email: 'testUser@test.com', + }, + }, + traits: { ...group2Traits, website: 'url' }, + timestamp, + originalTimestamp, + }), + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: 'sdfrsdfsdfsf', + endpoint, + headers: v1Headers, + JSON: { + company_id: 'test_company_id_wdasda', + custom_attributes: { + email: 'test@test.com', + employees: 450, + key1: 'val1', + }, + industry: 'IT', + monthly_spend: 2131231, + name: 'rudderUpdate', + plan: 'basic', + remote_created_at: 1683017572, + size: 50, + website: 'url', + }, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + { + output: transformResultBuilder({ + userId: 'sdfrsdfsdfsf', + endpoint: 'https://api.intercom.io/users', + headers: v1Headers, + JSON: { + companies: [ + { + name: 'rudderUpdate', + company_id: 'test_company_id_wdasda', + }, + ], + email: 'testUser@test.com', + user_id: 'sdfrsdfsdfsf', + }, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'intercom-group-test-5', + name: 'intercom', + description: + 'V1 version : successful group call without userId (anonId will be considered as userId)', + scenario: 'Business', + successCriteria: + 'Response status code should be 200 and response should contain create company and add user to company payload', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { ...v1Destination, Config: v1Destination.Config, sendAnonymousId: true }, + message: { + anonymousId: 'anonId', + groupId: 'test_company_id_wdasda', + context: { + traits: { + email: 'testUser@test.com', + }, + }, + traits: { + ...group2Traits, + website: 'url', + key1: 'val1', + key2: { + a: 'a', + b: 'b', + }, + key3: [1, 2, 3], + key4: null, + }, + type: 'group', + timestamp, + originalTimestamp, + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: 'anonId', + endpoint, + headers: v1Headers, + JSON: { + company_id: 'test_company_id_wdasda', + custom_attributes: { + email: 'test@test.com', + employees: 450, + key1: 'val1', + 'key2.a': 'a', + 'key2.b': 'b', + 'key3[0]': 1, + 'key3[1]': 2, + 'key3[2]': 3, + key4: null, + }, + industry: 'IT', + monthly_spend: 2131231, + name: 'rudderUpdate', + plan: 'basic', + remote_created_at: 1683017572, + size: 50, + website: 'url', + }, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + { + output: transformResultBuilder({ + userId: 'anonId', + endpoint: 'https://api.intercom.io/users', + headers: v1Headers, + JSON: { + companies: [ + { + name: 'rudderUpdate', + company_id: 'test_company_id_wdasda', + }, + ], + email: 'testUser@test.com', + }, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'intercom-group-test-6', + name: 'intercom', + description: 'V1 version : successful group call with email as custom attribute', + scenario: 'Business', + successCriteria: + 'Response status code should be 200 and response should contain create company payload with email as custom attribute', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: v1Destination, + message: { + anonymousId: '12312312', + groupId: 'test_company_id', + context: { + traits: {}, + }, + traits: { ...group1Traits, monthlySpend: '2131231', email: 'comanyemail@abc.com' }, + type: 'group', + timestamp, + originalTimestamp, + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: '12312312', + endpoint, + headers: v1Headers, + JSON: { + ...group1Traits, + custom_attributes: { + email: 'comanyemail@abc.com', + }, + monthly_spend: 2131231, + company_id: 'test_company_id', + }, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/intercom/processor/identifyTestData.ts b/test/integrations/destinations/intercom/processor/identifyTestData.ts new file mode 100644 index 0000000000..d88b7cf7f5 --- /dev/null +++ b/test/integrations/destinations/intercom/processor/identifyTestData.ts @@ -0,0 +1,1025 @@ +import { Destination } from '../../../../../src/types'; +import { + generateMetadata, + transformResultBuilder, + generateSimplifiedIdentifyPayload, +} from '../../../testUtils'; + +const v1Config = { + apiKey: 'intercomApiKey', + apiVersion: 'v1', + appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', + collectContext: false, +}; + +const v2Config = { + apiKey: 'testApiKey', + apiVersion: 'v2', + apiServer: 'standard', + sendAnonymousId: false, +}; + +const v2Headers = { + Accept: 'application/json', + Authorization: 'Bearer testApiKey', + 'Content-Type': 'application/json', + 'Intercom-Version': '2.10', +}; + +const v1Headers = { + 'Content-Type': 'application/json', + Authorization: 'Bearer intercomApiKey', + Accept: 'application/json', + 'Intercom-Version': '1.4', +}; + +const destination: Destination = { + ID: '123', + Name: 'intercom', + DestinationDefinition: { + ID: '123', + Name: 'intercom', + DisplayName: 'Intercom', + Config: { + cdkV2Enabled: true, + }, + }, + Config: {}, + Enabled: true, + WorkspaceID: '123', + Transformations: [], +}; + +const v1Destination = { ...destination, Config: v1Config }; +const v2Destination = { ...destination, Config: v2Config }; + +const user1Traits = { + age: 23, + ownerId: '13', + firstName: 'Test', + lastName: 'Rudderlabs', + phone: '+91 9999999999', + address: 'california usa', + email: 'test@rudderlabs.com', + lastSeenAt: '2023-11-10T14:42:44.724Z', +}; + +const user2Traits = { + age: 32, + ownerId: '14', + firstName: 'Test', + lastName: 'RudderStack', + phone: '+91 9299999999', + email: 'test+2@rudderlabs.com', +}; + +const user3Traits = { + owner_id: 13, + name: 'Test Rudderlabs', + phone: '+91 9999999999', + email: 'test@rudderlabs.com', +}; + +const user4Traits = { + key1: 'value1', + name: 'Test Name', + firstName: 'Test', + lastName: 'Name', + phone: '9876543210', + userId: 'test_user_id_1', + email: 'test_1@test.com', + createdAt: '2020-09-30T19:11:00.337Z', + anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + address: { + city: 'Kolkata', + state: 'West Bengal', + }, + originalArray: [ + { + nested_field: 'nested value', + tags: ['tag_1', 'tag_2', 'tag_3'], + }, + { + nested_field: 'nested value', + tags: ['tag_1'], + }, + { + nested_field: 'nested value', + }, + ], +}; + +const user5Traits = { + firstName: 'Test', + lastName: 'Name', + key1: 'value1', + phone: '9876543210', + email: 'test_1@test.com', + createdAt: '2020-09-30T19:11:00.337Z', + anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', +}; + +const user6Traits = { + lastName: 'Name', + key1: 'value1', + phone: '9876543210', + email: 'test_1@test.com', + createdAt: '2020-09-30T19:11:00.337Z', + anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + company: { + key1: 'value1', + name: 'Test Comp', + id: 'company_id', + industry: 'test industry', + key2: { + a: 'a', + }, + key3: [1, 2, 3], + }, +}; + +const expectedUser1Traits = { + owner_id: 13, + external_id: 'user@1', + last_seen_at: 1699627364, + name: 'Test Rudderlabs', + phone: '+91 9999999999', + email: 'test@rudderlabs.com', + custom_attributes: { + age: 23, + address: 'california usa', + }, +}; + +const expectedUser2Traits = { + owner_id: 14, + external_id: 'user@2', + name: 'Test RudderStack', + phone: '+91 9299999999', + email: 'test+2@rudderlabs.com', + custom_attributes: { + age: 32, + }, +}; + +const expectedUser3Traits = { + owner_id: 13, + user_id: 'user@1', + name: 'Test Rudderlabs', + phone: '+91 9999999999', + email: 'test@rudderlabs.com', +}; + +const expectedUser4Traits = { + name: 'Test Name', + phone: '9876543210', + email: 'test_1@test.com', + signed_up_at: 1601493060, + user_id: 'test_user_id_1', + last_seen_user_agent: 'unknown', + custom_attributes: { + key1: 'value1', + 'address.city': 'Kolkata', + 'address.state': 'West Bengal', + 'originalArray[0].nested_field': 'nested value', + 'originalArray[0].tags[0]': 'tag_1', + 'originalArray[0].tags[1]': 'tag_2', + 'originalArray[0].tags[2]': 'tag_3', + 'originalArray[1].nested_field': 'nested value', + 'originalArray[1].tags[0]': 'tag_1', + 'originalArray[2].nested_field': 'nested value', + anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + }, + update_last_request_at: true, +}; + +const expectedUser5Traits = { + name: 'Test Name', + phone: '9876543210', + email: 'test_1@test.com', + signed_up_at: 1601493060, + update_last_request_at: true, + last_seen_user_agent: 'unknown', + custom_attributes: { + key1: 'value1', + anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + }, +}; + +const expectedUser6Traits = { + name: 'Name', + phone: '9876543210', + email: 'test_1@test.com', + signed_up_at: 1601493060, + last_seen_user_agent: 'unknown', + update_last_request_at: true, + custom_attributes: { + key1: 'value1', + anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + }, + companies: [ + { + name: 'Test Comp', + industry: 'test industry', + company_id: 'company_id', + custom_attributes: { + key1: 'value1', + key2: '{"a":"a"}', + key3: '[1,2,3]', + }, + }, + ], +}; + +const timestamp = '2023-11-22T10:12:44.757+05:30'; +const originalTimestamp = '2023-11-10T14:42:44.724Z'; + +const v2Endpoint = 'https://api.intercom.io/contacts'; +const v1Endpoint = 'https://api.intercom.io/users'; + +export const identifyTestData = [ + { + id: 'intercom-identify-test-1', + name: 'intercom', + description: 'V2 version : Create customer with email as lookup field', + scenario: 'Business', + successCriteria: + 'Response status code should be 200 and response should contain create user payload with all traits', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: v2Destination, + message: generateSimplifiedIdentifyPayload({ + userId: 'user@1', + context: { + traits: user1Traits, + }, + timestamp, + originalTimestamp, + }), + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: '', + endpoint: v2Endpoint, + headers: v2Headers, + JSON: expectedUser1Traits, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'intercom-identify-test-2', + name: 'intercom', + description: 'V2 version : Update customer with email as lookup field', + scenario: 'Business', + successCriteria: + 'Response status code should be 200 and response should contain update user payload with all traits', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: v2Destination, + message: generateSimplifiedIdentifyPayload({ + userId: 'user@2', + context: { + traits: user2Traits, + }, + timestamp, + originalTimestamp, + }), + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: '', + endpoint: `${v2Endpoint}/7070129940741e45d040`, + headers: v2Headers, + method: 'PUT', + JSON: expectedUser2Traits, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'intercom-identify-test-3', + name: 'intercom', + description: 'V2 version : Identify rEtl test', + scenario: 'Business', + successCriteria: + 'Response status code should be 200 and response should contain create user payload with all traits', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: v2Destination, + message: { + context: { + externalId: [ + { + id: 'user@1', + type: 'INTERCOM-customer', + identifierType: 'user_id', + }, + ], + mappedToDestination: 'true', + }, + traits: user3Traits, + type: 'identify', + timestamp, + originalTimestamp, + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: '', + endpoint: v2Endpoint, + headers: v2Headers, + method: 'POST', + JSON: expectedUser3Traits, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'intercom-identify-test-4', + name: 'intercom', + description: 'V1 version : successful identify call to create user', + scenario: 'Business', + successCriteria: + 'Response status code should be 200 and response should contain create user payload with all traits', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: v1Destination, + message: { + anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + context: { + traits: user4Traits, + userAgent: 'unknown', + }, + type: 'identify', + timestamp, + originalTimestamp, + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + endpoint: v1Endpoint, + headers: v1Headers, + method: 'POST', + JSON: expectedUser4Traits, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'intercom-identify-test-5', + name: 'intercom', + description: 'V1 version : successful identify call to create user', + scenario: 'Business', + successCriteria: + 'Response status code should be 200 and response should contain create user payload with all traits', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: v1Destination, + message: { + anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + context: { + traits: user5Traits, + userAgent: 'unknown', + }, + type: 'identify', + timestamp, + originalTimestamp, + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + endpoint: v1Endpoint, + headers: v1Headers, + method: 'POST', + JSON: expectedUser5Traits, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'intercom-identify-test-6', + name: 'intercom', + description: 'V1 version : successful identify call to update user', + scenario: 'Business', + successCriteria: + 'Response status code should be 200 and response should contain update user payload with all traits', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: v1Destination, + message: { + anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + context: { + traits: { ...user5Traits, firstName: undefined }, + userAgent: 'unknown', + }, + type: 'identify', + timestamp, + originalTimestamp, + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + endpoint: v1Endpoint, + headers: v1Headers, + method: 'POST', + JSON: { ...expectedUser5Traits, name: 'Name' }, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'intercom-identify-test-7', + name: 'intercom', + description: 'V1 version : successful identify call to update user', + scenario: 'Business', + successCriteria: + 'Response status code should be 200 and response should contain update user payload with all traits', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: v1Destination, + message: { + anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + context: { + traits: { ...user5Traits, lastName: undefined }, + userAgent: 'unknown', + }, + type: 'identify', + timestamp, + originalTimestamp, + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + endpoint: v1Endpoint, + headers: v1Headers, + method: 'POST', + JSON: { ...expectedUser5Traits, name: 'Test' }, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'intercom-identify-test-8', + name: 'intercom', + description: 'V1 version : successful identify call to create user', + scenario: 'Business', + successCriteria: + 'Response status code should be 200 and response should contain create user payload with all traits', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: v1Destination, + message: { + anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + context: { + traits: user6Traits, + userAgent: 'unknown', + }, + type: 'identify', + timestamp, + originalTimestamp, + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + endpoint: v1Endpoint, + headers: v1Headers, + method: 'POST', + JSON: expectedUser6Traits, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'intercom-identify-test-9', + name: 'intercom', + description: 'V1 version : successful identify call to create user', + scenario: 'Business', + successCriteria: + 'Response status code should be 200 and response should contain create user payload with all traits', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: v1Destination, + message: { + anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + context: { + traits: { + ...user6Traits, + company: { + name: 'Test Comp', + industry: 'test industry', + key1: 'value1', + key2: null, + key3: ['value1', 'value2'], + key4: { + foo: 'bar', + }, + }, + }, + userAgent: 'unknown', + }, + type: 'identify', + timestamp, + originalTimestamp, + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + endpoint: v1Endpoint, + headers: v1Headers, + method: 'POST', + JSON: { + ...expectedUser6Traits, + companies: [ + { + ...expectedUser6Traits.companies[0], + custom_attributes: { + key1: 'value1', + key3: '["value1","value2"]', + key4: '{"foo":"bar"}', + }, + company_id: 'c0277b5c814453e5135f515f943d085a', + }, + ], + }, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'intercom-identify-test-10', + name: 'intercom', + description: 'V1 version : successful identify call to update user', + scenario: 'Business', + successCriteria: + 'Response status code should be 200 and response should contain update user payload with all traits', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: v1Destination, + message: { + anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + context: { + traits: { + ...user5Traits, + firstName: undefined, + company: { + industry: 'test industry', + key1: 'value1', + key2: null, + }, + }, + userAgent: 'unknown', + }, + type: 'identify', + timestamp, + originalTimestamp, + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + endpoint: v1Endpoint, + headers: v1Headers, + method: 'POST', + JSON: { ...expectedUser5Traits, companies: [], name: 'Name' }, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'intercom-identify-test-11', + name: 'intercom', + description: + 'No Version : Successful identify call to create user without giving apiVersion in configuration', + scenario: 'Business', + successCriteria: + 'Response should take v1 apiVersion by default and response status code should be 200 and response should contain create user payload with all traits', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { ...v1Destination, apiVersion: undefined }, + message: { + anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + context: { + traits: user4Traits, + userAgent: 'unknown', + }, + type: 'identify', + timestamp, + originalTimestamp, + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + endpoint: v1Endpoint, + headers: v1Headers, + method: 'POST', + JSON: expectedUser4Traits, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'intercom-identify-test-12', + name: 'intercom', + description: + 'No Version : Successful identify call to create user without giving apiVersion in configuration', + scenario: 'Business', + successCriteria: + 'Response should take v1 apiVersion by default and response status code should be 200 and response should contain create user payload with all traits', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { ...v1Destination, apiVersion: undefined }, + message: { + anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + context: { + traits: user5Traits, + userAgent: 'unknown', + }, + type: 'identify', + timestamp, + originalTimestamp, + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + endpoint: v1Endpoint, + headers: v1Headers, + method: 'POST', + JSON: expectedUser5Traits, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'intercom-identify-test-13', + name: 'intercom', + description: + 'No Version : Successful identify call to update user without giving apiVersion in configuration', + scenario: 'Business', + successCriteria: + 'Response should take v1 apiVersion by default and response status code should be 200 and response should contain update user payload with all traits', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { ...v1Destination, apiVersion: undefined }, + message: { + anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + context: { + traits: { ...user5Traits, firstName: undefined }, + userAgent: 'unknown', + }, + type: 'identify', + timestamp, + originalTimestamp, + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + endpoint: v1Endpoint, + headers: v1Headers, + method: 'POST', + JSON: { ...expectedUser5Traits, name: 'Name' }, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'intercom-identify-test-14', + name: 'intercom', + description: + 'V1 version : Successful identify call to update user with sendAnonymousId configuration set to true', + scenario: 'Business', + successCriteria: + 'Response status code should be 200 and response should contain update user payload with all traits and userId should be equal to anonymousId', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: v1Destination, + message: { + anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + context: { + traits: user5Traits, + userAgent: 'unknown', + }, + type: 'identify', + timestamp, + originalTimestamp, + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + endpoint: v1Endpoint, + headers: v1Headers, + method: 'POST', + JSON: expectedUser5Traits, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'intercom-identify-test-15', + name: 'intercom', + description: 'V1 version : Identify rEtl test', + scenario: 'Business', + successCriteria: + 'Response status code should be 200 and response should contain create user payload with all traits', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: v1Destination, + message: { + context: { + externalId: [ + { + id: '10156', + type: 'INTERCOM-customer', + identifierType: 'user_id', + }, + ], + mappedToDestination: 'true', + traits: user5Traits, + }, + type: 'identify', + timestamp, + originalTimestamp, + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: '', + endpoint: v1Endpoint, + headers: v1Headers, + method: 'POST', + JSON: { + ...user5Traits, + user_id: '10156', + name: 'Test Name', + update_last_request_at: true, + }, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/intercom/processor/trackTestData.ts b/test/integrations/destinations/intercom/processor/trackTestData.ts new file mode 100644 index 0000000000..15bed25d68 --- /dev/null +++ b/test/integrations/destinations/intercom/processor/trackTestData.ts @@ -0,0 +1,361 @@ +import { Destination } from '../../../../../src/types'; +import { + generateMetadata, + transformResultBuilder, + generateSimplifiedTrackPayload, +} from '../../../testUtils'; + +const v1Config = { + apiKey: 'intercomApiKey', + apiVersion: 'v1', + appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', + collectContext: false, +}; + +const v2Config = { + apiKey: 'testApiKey', + apiVersion: 'v2', + apiServer: 'standard', + sendAnonymousId: false, +}; + +const v1Headers = { + 'Content-Type': 'application/json', + Authorization: 'Bearer intercomApiKey', + Accept: 'application/json', + 'Intercom-Version': '1.4', +}; + +const v2Headers = { + Accept: 'application/json', + Authorization: 'Bearer testApiKey', + 'Content-Type': 'application/json', + 'Intercom-Version': '2.10', +}; + +const destination: Destination = { + ID: '123', + Name: 'intercom', + DestinationDefinition: { + ID: '123', + Name: 'intercom', + DisplayName: 'Intercom', + Config: { + cdkV2Enabled: true, + }, + }, + Config: {}, + Enabled: true, + WorkspaceID: '123', + Transformations: [], +}; + +const v1Destination = { ...destination, Config: v1Config }; +const v2Destination = { ...destination, Config: v2Config }; + +const userTraits = { + age: 23, + ownerId: '13', + firstName: 'Test', + lastName: 'Rudderlabs', + phone: '+91 9999999999', + address: 'california usa', + email: 'test@rudderlabs.com', + lastSeenAt: '2023-11-10T14:42:44.724Z', +}; + +const properties = { + revenue: { + amount: 1232, + currency: 'inr', + test: 123, + }, + price: { + amount: 3000, + currency: 'USD', + }, +}; + +const nestedProperties = { + property1: 1, + property2: 'test', + property3: true, + property4: '2020-10-05T09:09:03.731Z', + property5: { + property1: 1, + property2: 'test', + property3: { + subProp1: { + a: 'a', + b: 'b', + }, + subProp2: ['a', 'b'], + }, + }, + properties6: null, + revenue: { + amount: 1232, + currency: 'inr', + test: 123, + }, + price: { + amount: 3000, + currency: 'USD', + }, + article: { + url: 'https://example.org/ab1de.html', + value: 'the dude abides', + }, +}; + +const expectedNestedProperties = { + revenue: { + amount: 1232, + currency: 'inr', + test: 123, + }, + price: { + amount: 3000, + currency: 'USD', + }, + article: { + url: 'https://example.org/ab1de.html', + value: 'the dude abides', + }, + property1: 1, + property2: 'test', + property3: true, + property4: '2020-10-05T09:09:03.731Z', + 'property5.property1': 1, + 'property5.property2': 'test', + 'property5.property3.subProp1.a': 'a', + 'property5.property3.subProp1.b': 'b', + 'property5.property3.subProp2[0]': 'a', + 'property5.property3.subProp2[1]': 'b', + properties6: null, +}; + +const expectedOutput = { + user_id: 'user@2', + created: 1699627364, + event_name: 'Test Event 2', + email: 'test@rudderlabs.com', +}; + +const timestamp = '2023-11-22T10:12:44.757+05:30'; +const originalTimestamp = '2023-11-10T14:42:44.724Z'; + +const endpoint = 'https://api.intercom.io/events'; + +export const trackTestData = [ + { + id: 'intercom-track-test-1', + name: 'intercom', + description: 'V2 version : Successful track call', + scenario: 'Business', + successCriteria: + "Response status code should be 200 and response should contain event name and it's properties", + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: v2Destination, + message: generateSimplifiedTrackPayload({ + userId: 'user@2', + event: 'Product Viewed', + context: { + traits: userTraits, + }, + properties, + timestamp, + originalTimestamp, + }), + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: '', + endpoint, + headers: v2Headers, + JSON: { + user_id: 'user@2', + metadata: properties, + created_at: 1699627364, + event_name: 'Product Viewed', + email: 'test@rudderlabs.com', + }, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'intercom-track-test-2', + name: 'intercom', + description: 'V2 version : Track rEtl test', + scenario: 'Business', + successCriteria: + "Response status code should be 200 and response should contain event name and it's properties", + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: v2Destination, + message: { + userId: 'user@2', + event: 'Product Viewed', + context: { + mappedToDestination: 'true', + }, + traits: { + ...properties, + user_id: 'user@1', + event_name: 'Product Viewed', + }, + type: 'track', + timestamp, + originalTimestamp, + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: '', + endpoint, + headers: v2Headers, + JSON: { + ...properties, + user_id: 'user@1', + event_name: 'Product Viewed', + }, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'intercom-track-test-3', + name: 'intercom', + description: 'V1 version : successful track call with nested properties', + scenario: 'Business', + successCriteria: + "Response status code should be 200 and response should contain event name and it's properties", + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: v1Destination, + message: generateSimplifiedTrackPayload({ + userId: 'user@2', + event: 'Test Event 2', + context: { + traits: userTraits, + }, + properties: nestedProperties, + timestamp, + originalTimestamp, + }), + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: 'default-anonymousId', + endpoint, + headers: v1Headers, + JSON: { + ...expectedOutput, + metadata: { + ...expectedNestedProperties, + }, + }, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'intercom-track-test-4', + name: 'intercom', + description: 'V1 version : successful track call without properties', + scenario: 'Business', + successCriteria: 'Response status code should be 200 and response should contain event name', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: v1Destination, + message: generateSimplifiedTrackPayload({ + userId: 'user@2', + event: 'Test Event 2', + context: { + traits: userTraits, + }, + timestamp, + originalTimestamp, + }), + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + endpoint, + headers: v1Headers, + JSON: expectedOutput, + userId: 'default-anonymousId', + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, +]; diff --git a/test/integrations/destinations/intercom/processor/validationTestData.ts b/test/integrations/destinations/intercom/processor/validationTestData.ts new file mode 100644 index 0000000000..45fe3c1b9e --- /dev/null +++ b/test/integrations/destinations/intercom/processor/validationTestData.ts @@ -0,0 +1,554 @@ +import { Destination } from '../../../../../src/types'; +import { ProcessorTestData } from '../../../testTypes'; +import { generateMetadata } from '../../../testUtils'; + +const v1Config = { + apiKey: 'intercomApiKey', + apiVersion: 'v1', + appId: '9e9cdea1-78fa-4829-a9b2-5d7f7e96d1a0', + collectContext: false, +}; + +const v2Config = { + apiKey: 'testApiKey', + apiVersion: 'v2', + apiServer: 'standard', + sendAnonymousId: false, +}; + +const destination: Destination = { + ID: '123', + Name: 'intercom', + DestinationDefinition: { + ID: '123', + Name: 'intercom', + DisplayName: 'Intercom', + Config: { + cdkV2Enabled: true, + }, + }, + Config: { + apiKey: 'testApiKey', + apiVersion: 'v2', + apiServer: 'standard', + sendAnonymousId: false, + }, + Enabled: true, + WorkspaceID: '123', + Transformations: [], +}; + +const v1Destination = { ...destination, Config: v1Config }; +const v2Destination = { ...destination, Config: v2Config }; + +const userTraits = { + age: 23, + ownerId: '14', + role: 'user', + source: 'rudder-sdk', + firstname: 'Test', + lastName: 'RudderStack', + phone: '+91 9299999999', + birthday: '2022-05-13T12:51:01.470Z', +}; + +const properties = { + revenue: { + amount: 1232, + currency: 'inr', + test: 123, + }, + price: { + amount: 3000, + currency: 'USD', + }, +}; + +const groupTraits = { + name: 'RudderStack', + size: 500, + website: 'www.rudderstack.com', + industry: 'CDP', + plan: 'enterprise', +}; + +const expectedStatTags = { + destType: 'INTERCOM', + errorCategory: 'dataValidation', + errorType: 'instrumentation', + feature: 'processor', + implementation: 'cdkV2', + module: 'destination', + destinationId: 'default-destinationId', + workspaceId: 'default-workspaceId', +}; + +export const validationTestData: ProcessorTestData[] = [ + { + id: 'intercom-validation-test-1', + name: 'intercom', + description: '[Error - V2 version]: Check for no message type', + scenario: 'Framework', + successCriteria: 'Response status code should be 400 with respective error message', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: v2Destination, + message: { + event: 'Product Searched', + context: { + traits: userTraits, + }, + timestamp: '2020-01-21T00:21:34.208Z', + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + 'message Type is not present. Aborting: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: message Type is not present. Aborting', + statTags: expectedStatTags, + statusCode: 400, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'intercom-validation-test-2', + name: 'intercom', + description: '[Error - V2 version]: Check for unsupported message type', + scenario: 'Framework', + successCriteria: + 'Response should contain error message and status code should be 400, as we are sending a message type which is not supported by intercom destination and the error message should be Event type alias is not supported', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: v2Destination, + message: { + userId: 'user@45', + type: 'page', + context: { + traits: userTraits, + }, + timestamp: '2020-01-21T00:21:34.208Z', + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + 'message type page is not supported: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: message type page is not supported', + statTags: expectedStatTags, + statusCode: 400, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'intercom-validation-test-3', + name: 'intercom', + description: '[Error - V2 version]: Missing required config', + scenario: 'Framework', + successCriteria: + 'Response status code should be 400 and it should throw configuration error with respective error message', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + ...v2Destination, + Config: { ...v2Destination.Config, apiKey: null }, + }, + message: { + userId: 'user@1', + type: 'identify', + context: { + traits: userTraits, + }, + timestamp: '2020-01-21T00:21:34.208Z', + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + 'Access Token is not present. Aborting: Workflow: procWorkflow, Step: validateInput, ChildStep: undefined, OriginalError: Access Token is not present. Aborting', + statTags: { ...expectedStatTags, errorType: 'configuration' }, + statusCode: 400, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'intercom-validation-test-4', + name: 'intercom', + description: '[Error - V2 version]: Missing required parameters for an identify call', + scenario: 'Framework', + successCriteria: + 'Response status code should be 400 and it should throw instrumentation error with respective error message', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: v2Destination, + message: { + anonymousId: 'anon@2', + type: 'identify', + context: { + traits: userTraits, + }, + integrations: { + INTERCOM: { + lookup: 'phone', + }, + }, + timestamp: '2020-01-21T00:21:34.208Z', + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + 'Either email or userId is required for Identify call: Workflow: procWorkflow, Step: identifyPayloadForLatestVersion, ChildStep: undefined, OriginalError: Either email or userId is required for Identify call', + statTags: expectedStatTags, + statusCode: 400, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'intercom-validation-test-5', + name: 'intercom', + description: '[Error - V2 version]: Missing required parameters for an identify call', + scenario: 'Framework', + successCriteria: + 'Response status code should be 400 and it should throw instrumentation error with respective error message', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: v2Destination, + message: { + anonymousId: 'anon@2', + type: 'identify', + context: { + traits: userTraits, + }, + integrations: { + INTERCOM: { + lookup: 'phone', + }, + }, + timestamp: '2020-01-21T00:21:34.208Z', + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + 'Either email or userId is required for Identify call: Workflow: procWorkflow, Step: identifyPayloadForLatestVersion, ChildStep: undefined, OriginalError: Either email or userId is required for Identify call', + statTags: expectedStatTags, + statusCode: 400, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'intercom-validation-test-6', + name: 'intercom', + description: + '[Error - V2 version]: Unauthorized error while searching contact for an identify call', + scenario: 'Framework', + successCriteria: + 'Response status code should be 400 and it should throw network error with respective error message', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: { + ...v2Destination, + Config: { ...v2Destination.Config, apiKey: 'invalidApiKey' }, + }, + message: { + userId: 'user@3', + type: 'identify', + context: { + traits: { + phone: '+91 9399999999', + email: 'test+3@rudderlabs.com', + firstName: 'Test', + lastName: 'Rudder', + ownerId: '15', + role: 'admin', + source: 'rudder-android-sdk', + }, + }, + integrations: { + INTERCOM: { + lookup: 'email', + }, + }, + timestamp: '2020-01-21T00:21:34.208Z', + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + '{"message":"{\\"message\\":\\"Unable to search contact due to : [{\\\\\\"code\\\\\\":\\\\\\"unauthorized\\\\\\",\\\\\\"message\\\\\\":\\\\\\"Access Token Invalid\\\\\\"}]: Workflow: procWorkflow, Step: searchContact, ChildStep: undefined, OriginalError: Unable to search contact due to : [{\\\\\\"code\\\\\\":\\\\\\"unauthorized\\\\\\",\\\\\\"message\\\\\\":\\\\\\"Access Token Invalid\\\\\\"}]\\",\\"destinationResponse\\":{\\"response\\":{\\"type\\":\\"error.list\\",\\"request_id\\":\\"request_1\\",\\"errors\\":[{\\"code\\":\\"unauthorized\\",\\"message\\":\\"Access Token Invalid\\"}]},\\"status\\":401}}","destinationResponse":{"response":{"type":"error.list","request_id":"request_1","errors":[{"code":"unauthorized","message":"Access Token Invalid"}]},"status":401}}', + statTags: { ...expectedStatTags, errorCategory: 'network', errorType: 'aborted' }, + statusCode: 401, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'intercom-validation-test-7', + name: 'intercom', + description: '[Error - V2 version]: Track call without event name', + scenario: 'Framework', + successCriteria: + 'Response status code should be 400 and it should throw instrumentation error with respective error message', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: v2Destination, + message: { + userId: 'user@3', + type: 'track', + context: { + traits: userTraits, + }, + properties, + timestamp: '2023-11-22T10:12:44.757+05:30', + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + 'Event name is required for track call: Workflow: procWorkflow, Step: trackPayload, ChildStep: undefined, OriginalError: Event name is required for track call', + statTags: expectedStatTags, + statusCode: 400, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'intercom-validation-test-8', + name: 'intercom', + description: '[Error - V2 version]: Group call without groupId', + scenario: 'Framework', + successCriteria: + 'Response status code should be 400 and it should throw instrumentation error with respective error message', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: v2Destination, + message: { + userId: 'user@4', + type: 'group', + context: { + traits: { + email: 'test+4@rudderlabs.com', + phone: '+91 9499999999', + firstName: 'John', + lastName: 'Doe', + ownerId: '16', + }, + }, + traits: groupTraits, + timestamp: '2023-11-22T10:12:44.757+05:30', + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + 'groupId is required for group call: Workflow: procWorkflow, Step: groupPayloadForLatestVersion, ChildStep: validateMessageAndPreparePayload, OriginalError: groupId is required for group call', + statTags: expectedStatTags, + statusCode: 400, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'intercom-validation-test-9', + name: 'intercom', + description: '[Error - V1 version]: Identify call without email and userId', + scenario: 'Framework', + successCriteria: + 'Response status code should be 400 and it should throw instrumentation error with respective error message', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: v1Destination, + message: { + type: 'identify', + anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + context: { + traits: userTraits, + }, + timestamp: '2023-11-22T10:12:44.757+05:30', + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + 'Either of `email` or `userId` is required for Identify call: Workflow: procWorkflow, Step: identifyPayloadForOlderVersion, ChildStep: undefined, OriginalError: Either of `email` or `userId` is required for Identify call', + statTags: expectedStatTags, + statusCode: 400, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, + { + id: 'intercom-validation-test-10', + name: 'intercom', + description: '[Error - V1 version]: Track call without email or userId', + scenario: 'Framework', + successCriteria: + 'Response status code should be 400 and it should throw instrumentation error with respective error message', + feature: 'processor', + module: 'destination', + version: 'v0', + input: { + request: { + body: [ + { + destination: v1Destination, + message: { + type: 'track', + anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + context: { + traits: userTraits, + }, + event: 'Test Event 2', + timestamp: '2023-11-22T10:12:44.757+05:30', + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + error: + 'Either email or userId is required for Track call: Workflow: procWorkflow, Step: trackPayload, ChildStep: undefined, OriginalError: Either email or userId is required for Track call', + statTags: expectedStatTags, + statusCode: 400, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, +];