From 6c5afd1d5e50cf3b47171a4d806bf28e3e8390f9 Mon Sep 17 00:00:00 2001 From: ItsSudip Date: Mon, 23 Sep 2024 19:33:19 +0530 Subject: [PATCH] fix: support different lookup fields and custom_attributes for rETL events --- .../destinations/intercom/procWorkflow.yaml | 10 +-- src/cdk/v2/destinations/intercom/utils.js | 25 ++++-- .../destinations/intercom/network.ts | 37 +++++++++ .../intercom/processor/identifyTestData.ts | 78 +++++++++++++++++++ 4 files changed, 137 insertions(+), 13 deletions(-) diff --git a/src/cdk/v2/destinations/intercom/procWorkflow.yaml b/src/cdk/v2/destinations/intercom/procWorkflow.yaml index 0f2ac18fbc..48360adf65 100644 --- a/src/cdk/v2/destinations/intercom/procWorkflow.yaml +++ b/src/cdk/v2/destinations/intercom/procWorkflow.yaml @@ -77,8 +77,8 @@ steps: template: | const payload = .message.context.mappedToDestination ? $.outputs.rEtlPayload : $.outputs.identifyTransformationForLatestVersion; payload.name = $.getName(.message); - payload.custom_attributes = .message.context.traits || {}; - payload.custom_attributes = $.filterCustomAttributes(payload, "user", .destination); + payload.custom_attributes = !.message.context.mappedToDestination ? .message.context.traits || {} : .message.traits.custom_attributes || {}; + payload.custom_attributes = $.filterCustomAttributes(payload, "user", .destination, .message); payload.external_id = !payload.external_id && .destination.Config.sendAnonymousId && .message.anonymousId ? .message.anonymousId : payload.external_id; $.context.payload = payload; $.assert($.context.payload.external_id || $.context.payload.email, "Either email or userId is required for Identify call"); @@ -114,7 +114,7 @@ steps: update_last_request_at: typeof .destination.Config.updateLastRequestAt === 'boolean' ? .destination.Config.updateLastRequestAt : true } payload.companies = $.getCompaniesList(payload); - payload.custom_attributes = !.message.context.mappedToDestination ? $.filterCustomAttributes(payload, "user", .destination); + payload.custom_attributes = !.message.context.mappedToDestination ? $.filterCustomAttributes(payload, "user", .destination,.message); payload.user_id = !payload.user_id && .destination.Config.sendAnonymousId && .message.anonymousId ? .message.anonymousId : payload.user_id; $.context.payload = payload; $.assert($.context.payload.user_id || $.context.payload.email, "Either of `email` or `userId` is required for Identify call"); @@ -175,7 +175,7 @@ steps: $.assert(.message.groupId, "groupId is required for group call"); const payload = .message.context.mappedToDestination ? $.outputs.rEtlPayload : $.outputs.groupTransformation; payload.custom_attributes = .message.traits || {}; - payload.custom_attributes = $.filterCustomAttributes(payload, "company", .destination); + payload.custom_attributes = $.filterCustomAttributes(payload, "company", .destination,.message); $.context.payload = payload; - name: whenSearchContactFound condition: $.isDefinedAndNotNull($.outputs.searchContact) @@ -214,7 +214,7 @@ steps: ...payload, custom_attributes : $.getFieldValueFromMessage(.message, "traits") || {} } - payload.custom_attributes = $.filterCustomAttributes(payload, "company", .destination); + payload.custom_attributes = $.filterCustomAttributes(payload, "company", .destination, .message); response.body.JSON = $.removeUndefinedAndNullValues(payload); response.endpoint = $.getBaseEndpoint(.destination) + "/" + "companies"; response.headers = $.getHeaders(.destination, $.outputs.apiVersion); diff --git a/src/cdk/v2/destinations/intercom/utils.js b/src/cdk/v2/destinations/intercom/utils.js index dc483e040b..9f73ce527c 100644 --- a/src/cdk/v2/destinations/intercom/utils.js +++ b/src/cdk/v2/destinations/intercom/utils.js @@ -233,20 +233,26 @@ const attachUserAndCompany = (message, Config) => { * @param {*} type * @returns */ -const filterCustomAttributes = (payload, type, destination) => { +const filterCustomAttributes = (payload, type, destination, message) => { let ReservedAttributesList; let { apiVersion } = destination.Config; apiVersion = isDefinedAndNotNull(apiVersion) ? apiVersion : 'v2'; + // we are discarding the lookup field from custom attributes + const lookupField = getLookUpField(message); if (type === 'user') { - ReservedAttributesList = - apiVersion === 'v1' + ReservedAttributesList = [ + ...(apiVersion === 'v1' ? ReservedAttributes.v1UserAttributes - : ReservedAttributes.v2UserAttributes; + : ReservedAttributes.v2UserAttributes), + lookupField, + ]; } else { - ReservedAttributesList = - apiVersion === 'v1' + ReservedAttributesList = [ + ...(apiVersion === 'v1' ? ReservedAttributes.v1CompanyAttributes - : ReservedAttributes.v2CompanyAttributes; + : ReservedAttributes.v2CompanyAttributes), + lookupField !== 'email' && lookupField, + ]; } let customAttributes = { ...get(payload, 'custom_attributes') }; if (customAttributes) { @@ -270,7 +276,10 @@ const filterCustomAttributes = (payload, type, destination) => { */ const searchContact = async (message, destination, metadata) => { const lookupField = getLookUpField(message); - const lookupFieldValue = getFieldValueFromMessage(message, lookupField); + let lookupFieldValue = getFieldValueFromMessage(message, lookupField); + if (!lookupFieldValue) { + lookupFieldValue = get(message, `context.traits.${lookupField}`); + } const data = JSON.stringify({ query: { operator: 'AND', diff --git a/test/integrations/destinations/intercom/network.ts b/test/integrations/destinations/intercom/network.ts index 2f90beac40..0a86ce3c89 100644 --- a/test/integrations/destinations/intercom/network.ts +++ b/test/integrations/destinations/intercom/network.ts @@ -1041,5 +1041,42 @@ const deliveryCallsData = [ }, }, }, + { + httpReq: { + method: 'post', + url: 'https://api.intercom.io/contacts/search', + data: { + query: { + operator: 'AND', + value: [{ field: 'external_id', operator: '=', value: '10156' }], + }, + }, + headers: { ...commonHeaders, 'Intercom-Version': '2.10', 'User-Agent': 'RudderStack' }, + }, + httpRes: { + status: 200, + statusText: 'ok', + data: { + type: 'list', + total_count: 1, + pages: { + type: 'pages', + page: 1, + per_page: 50, + total_pages: 1, + }, + data: [ + { + type: 'contact', + id: '7070129940741e45d040', + workspace_id: 'rudderWorkspace', + external_id: 'user@2', + role: 'user', + email: 'test+2@rudderlabs.com', + }, + ], + }, + }, + }, ]; export const networkCallsData = [...deleteNwData, ...deliveryCallsData]; diff --git a/test/integrations/destinations/intercom/processor/identifyTestData.ts b/test/integrations/destinations/intercom/processor/identifyTestData.ts index 49f3a400d1..f078536b30 100644 --- a/test/integrations/destinations/intercom/processor/identifyTestData.ts +++ b/test/integrations/destinations/intercom/processor/identifyTestData.ts @@ -80,6 +80,10 @@ const user3Traits = { name: 'Test Rudderlabs', phone: '+91 9999999999', email: 'test@rudderlabs.com', + custom_attributes: { + ca1: 'value1', + ca2: 'value2', + }, }; const user4Traits = { @@ -170,6 +174,10 @@ const expectedUser3Traits = { name: 'Test Rudderlabs', phone: '+91 9999999999', email: 'test@rudderlabs.com', + custom_attributes: { + ca1: 'value1', + ca2: 'value2', + }, }; const expectedUser4Traits = { @@ -233,6 +241,17 @@ const expectedUser6Traits = { ], }; +const expectedUser7Traits = { + custom_attributes: { + anonymousId: '58b21c2d-f8d5-4410-a2d0-b268a26b7e33', + key1: 'value1', + }, + email: 'test_1@test.com', + name: 'Test Name', + phone: '9876543210', + signed_up_at: 1601493060, +}; + const timestamp = '2023-11-22T10:12:44.757+05:30'; const originalTimestamp = '2023-11-10T14:42:44.724Z'; @@ -1024,4 +1043,63 @@ export const identifyTestData = [ }, }, }, + { + id: 'intercom-identify-test-16', + name: 'intercom', + description: 'V1 version : Identify test with different lookup field than email', + 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: { + context: { + externalId: [ + { + id: '10156', + type: 'INTERCOM-customer', + identifierType: 'user_id', + }, + ], + traits: { ...user5Traits, external_id: '10156' }, + }, + type: 'identify', + timestamp, + originalTimestamp, + integrations: { + INTERCOM: { + lookup: 'external_id', + }, + }, + }, + metadata: generateMetadata(1), + }, + ], + }, + }, + output: { + response: { + status: 200, + body: [ + { + output: transformResultBuilder({ + userId: '', + endpoint: `${v2Endpoint}/7070129940741e45d040`, + headers: v2Headers, + method: 'PUT', + JSON: expectedUser7Traits, + }), + statusCode: 200, + metadata: generateMetadata(1), + }, + ], + }, + }, + }, ];