-
Notifications
You must be signed in to change notification settings - Fork 113
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'develop' into resolve-vulnerabilities
- Loading branch information
Showing
60 changed files
with
5,919 additions
and
176 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import { getMappingConfig } from '../../../../v0/util'; | ||
|
||
export const CUSTOMER_COMMAND = 'customers'; | ||
export const CUSTOMER_EVENT_COMMAND = 'customers/events'; | ||
export const MAX_BATCH_SIZE = 50; | ||
|
||
// ref:- https://documentation.bloomreach.com/engagement/reference/batch-commands-2 | ||
export const getBatchEndpoint = (apiBaseUrl: string, projectToken: string): string => | ||
`${apiBaseUrl}/track/v2/projects/${projectToken}/batch`; | ||
|
||
const CONFIG_CATEGORIES = { | ||
CUSTOMER_PROPERTIES_CONFIG: { name: 'BloomreachCustomerPropertiesConfig' }, | ||
}; | ||
const MAPPING_CONFIG = getMappingConfig(CONFIG_CATEGORIES, __dirname); | ||
export const EXCLUSION_FIELDS: string[] = [ | ||
'email', | ||
'firstName', | ||
'firstname', | ||
'first_name', | ||
'lastName', | ||
'lastname', | ||
'last_name', | ||
'name', | ||
'phone', | ||
'city', | ||
'birthday', | ||
'country', | ||
]; | ||
export const CUSTOMER_PROPERTIES_CONFIG = | ||
MAPPING_CONFIG[CONFIG_CATEGORIES.CUSTOMER_PROPERTIES_CONFIG.name]; |
36 changes: 36 additions & 0 deletions
36
src/cdk/v2/destinations/bloomreach/data/BloomreachCustomerPropertiesConfig.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
[ | ||
{ | ||
"destKey": "first_name", | ||
"sourceKeys": "firstName", | ||
"sourceFromGenericMap": true | ||
}, | ||
{ | ||
"destKey": "last_name", | ||
"sourceKeys": "lastName", | ||
"sourceFromGenericMap": true | ||
}, | ||
{ | ||
"destKey": "email", | ||
"sourceKeys": "emailOnly", | ||
"sourceFromGenericMap": true | ||
}, | ||
{ | ||
"destKey": "phone", | ||
"sourceKeys": "phone", | ||
"sourceFromGenericMap": true | ||
}, | ||
{ | ||
"destKey": "city", | ||
"sourceKeys": "city", | ||
"sourceFromGenericMap": true | ||
}, | ||
{ | ||
"destKey": "country", | ||
"sourceKeys": ["traits.address.country", "context.traits.address.country"] | ||
}, | ||
{ | ||
"destKey": "birthday", | ||
"sourceKeys": "birthday", | ||
"sourceFromGenericMap": true | ||
} | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
bindings: | ||
- name: EventType | ||
path: ../../../../constants | ||
- path: ../../bindings/jsontemplate | ||
- name: defaultRequestConfig | ||
path: ../../../../v0/util | ||
- name: toUnixTimestamp | ||
path: ../../../../v0/util | ||
- name: base64Convertor | ||
path: ../../../../v0/util | ||
- name: removeUndefinedAndNullValues | ||
path: ../../../../v0/util | ||
- name: generateExclusionList | ||
path: ../../../../v0/util | ||
- name: extractCustomFields | ||
path: ../../../../v0/util | ||
- name: constructPayload | ||
path: ../../../../v0/util | ||
- path: ./utils | ||
- path: ./config | ||
|
||
steps: | ||
- name: messageType | ||
template: | | ||
$.context.messageType = .message.type.toLowerCase(); | ||
- name: validateInput | ||
template: | | ||
let messageType = $.context.messageType; | ||
$.assert(messageType, "message Type is not present. Aborting"); | ||
$.assert(messageType in {{$.EventType.([.IDENTIFY,.TRACK,.PAGE,.SCREEN])}}, "message type " + messageType + " is not supported"); | ||
$.assertConfig(.destination.Config.apiBaseUrl, "API Base URL is not present. Aborting"); | ||
$.assertConfig(.destination.Config.apiKey, "API Key is not present . Aborting"); | ||
$.assertConfig(.destination.Config.apiSecret, "API Secret is not present. Aborting"); | ||
$.assertConfig(.destination.Config.projectToken, "Project Token is not present. Aborting"); | ||
$.assertConfig(.destination.Config.hardID, "Hard ID is not present. Aborting"); | ||
$.assertConfig(.destination.Config.softID, "Soft ID is not present. Aborting"); | ||
$.assert(.message.timestamp ?? .message.originalTimestamp, "Timestamp is not present. Aborting"); | ||
const userId = .message.().( | ||
{{{{$.getGenericPaths("userIdOnly")}}}}; | ||
); | ||
$.assert(userId ?? .message.anonymousId, "Either one of userId or anonymousId is required. Aborting"); | ||
- name: prepareIdentifyPayload | ||
condition: $.context.messageType === {{$.EventType.IDENTIFY}} | ||
template: | | ||
const customerIDs = $.prepareCustomerIDs(.message, .destination); | ||
const customerProperties = $.constructPayload(.message, $.CUSTOMER_PROPERTIES_CONFIG); | ||
const extraCustomerProperties = $.extractCustomFields(.message, {}, ['traits', 'context.traits'], $.EXCLUSION_FIELDS); | ||
const properties = { | ||
...customerProperties, | ||
...extraCustomerProperties | ||
} | ||
const data = .message.().({ | ||
"customer_ids": customerIDs, | ||
"update_timestamp": $.toUnixTimestamp({{{{$.getGenericPaths("timestamp")}}}}), | ||
properties | ||
}); | ||
$.context.payload = $.removeUndefinedAndNullValues({name: $.CUSTOMER_COMMAND, data}) | ||
- name: prepareEventName | ||
steps: | ||
- name: pageEventName | ||
condition: $.context.messageType === {{$.EventType.PAGE}} | ||
template: | | ||
const category = .message.category ?? .message.properties.category; | ||
const name = .message.name || .message.properties.name; | ||
const eventNameArray = ["Viewed"]; | ||
category ? eventNameArray.push(category); | ||
name ? eventNameArray.push(name); | ||
eventNameArray.push("Page"); | ||
$.context.event = eventNameArray.join(" "); | ||
- name: screenEventName | ||
condition: $.context.messageType === {{$.EventType.SCREEN}} | ||
template: | | ||
const category = .message.category ?? .message.properties.category; | ||
const name = .message.name || .message.properties.name; | ||
const eventNameArray = ["Viewed"]; | ||
category ? eventNameArray.push(category); | ||
name ? eventNameArray.push(name); | ||
eventNameArray.push("Screen"); | ||
$.context.event = eventNameArray.join(" "); | ||
- name: trackEventName | ||
condition: $.context.messageType === {{$.EventType.TRACK}} | ||
template: | | ||
$.assert(.message.event, "Event name is required. Aborting"); | ||
$.context.event = .message.event | ||
- name: prepareTrackPageScreenPayload | ||
condition: $.context.messageType !== {{$.EventType.IDENTIFY}} | ||
template: | | ||
const customerIDs = $.prepareCustomerIDs(.message, .destination); | ||
const data = .message.().({ | ||
"customer_ids": customerIDs, | ||
"timestamp": $.toUnixTimestamp({{{{$.getGenericPaths("timestamp")}}}}), | ||
"properties": .properties, | ||
"event_type": $.context.event, | ||
}); | ||
$.context.payload = $.removeUndefinedAndNullValues({name: $.CUSTOMER_EVENT_COMMAND, data}) | ||
- name: buildResponse | ||
description: In batchMode we return payload directly | ||
condition: $.batchMode | ||
template: | | ||
$.context.payload | ||
else: | ||
name: buildResponseForProcessTransformation | ||
template: | | ||
const response = $.defaultRequestConfig(); | ||
response.body.JSON = $.context.payload; | ||
response.endpoint = $.getBatchEndpoint(.destination.Config.apiBaseUrl, .destination.Config.projectToken); | ||
response.method = "POST"; | ||
response.headers = { | ||
"Content-Type": "application/json", | ||
"Authorization": "Basic " + $.base64Convertor(.destination.Config.apiKey + ":" + .destination.Config.apiSecret) | ||
} | ||
response; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
bindings: | ||
- name: handleRtTfSingleEventError | ||
path: ../../../../v0/util/index | ||
- path: ./utils | ||
exportAll: true | ||
- name: base64Convertor | ||
path: ../../../../v0/util | ||
- name: toUnixTimestamp | ||
path: ../../../../v0/util | ||
- name: BatchUtils | ||
path: '@rudderstack/workflow-engine' | ||
- path: ./config | ||
|
||
steps: | ||
- name: validateInput | ||
template: | | ||
$.assert(Array.isArray(^) && ^.length > 0, "Invalid event array") | ||
- name: transform | ||
externalWorkflow: | ||
path: ./procWorkflow.yaml | ||
bindings: | ||
- name: batchMode | ||
value: true | ||
loopOverInput: true | ||
|
||
- name: successfulEvents | ||
template: | | ||
$.outputs.transform#idx.output.({ | ||
"batchedRequest": ., | ||
"batched": false, | ||
"destination": ^[idx].destination, | ||
"metadata": ^[idx].metadata, | ||
"statusCode": 200 | ||
})[] | ||
- name: failedEvents | ||
template: | | ||
$.outputs.transform#idx.error.( | ||
$.handleRtTfSingleEventError(^[idx], .originalError ?? ., {}) | ||
)[] | ||
- name: batchSuccessfulEvents | ||
description: Batches the successfulEvents | ||
template: | | ||
let batches = $.BatchUtils.chunkArrayBySizeAndLength( | ||
$.outputs.successfulEvents, {maxItems: $.MAX_BATCH_SIZE}).items; | ||
batches@batch.({ | ||
"batchedRequest": { | ||
"body": { | ||
"JSON": {"commands": ~r batch.batchedRequest[]}, | ||
"JSON_ARRAY": {}, | ||
"XML": {}, | ||
"FORM": {} | ||
}, | ||
"version": "1", | ||
"type": "REST", | ||
"method": "POST", | ||
"endpoint": batch[0].destination.Config.().($.getBatchEndpoint(.apiBaseUrl, .projectToken)), | ||
"headers": batch[0].destination.Config.().({ | ||
"Content-Type": "application/json", | ||
"Authorization": "Basic " + $.base64Convertor(.apiKey + ":" + .apiSecret) | ||
}), | ||
"params": {}, | ||
"files": {} | ||
}, | ||
"metadata": ~r batch.metadata[], | ||
"batched": true, | ||
"statusCode": 200, | ||
"destination": batch[0].destination | ||
})[]; | ||
- name: finalPayload | ||
template: | | ||
[...$.outputs.batchSuccessfulEvents, ...$.outputs.failedEvents] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { isObject, isEmptyObject, getIntegrationsObj } from '../../../../v0/util'; | ||
import { RudderMessage, Destination } from '../../../../types'; | ||
|
||
const getCustomerIDsFromIntegrationObject = (message: RudderMessage): any => { | ||
const integrationObj = getIntegrationsObj(message, 'bloomreach' as any) || {}; | ||
const { hardID, softID } = integrationObj; | ||
const customerIDs = {}; | ||
|
||
if (isObject(hardID) && !isEmptyObject(hardID)) { | ||
Object.keys(hardID).forEach((id) => { | ||
customerIDs[id] = hardID[id]; | ||
}); | ||
} | ||
|
||
if (isObject(softID) && !isEmptyObject(softID)) { | ||
Object.keys(softID).forEach((id) => { | ||
customerIDs[id] = softID[id]; | ||
}); | ||
} | ||
|
||
return customerIDs; | ||
}; | ||
|
||
export const prepareCustomerIDs = (message: RudderMessage, destination: Destination): any => { | ||
const customerIDs = { | ||
[destination.Config.hardID]: message.userId, | ||
[destination.Config.softID]: message.anonymousId, | ||
...getCustomerIDsFromIntegrationObject(message), | ||
}; | ||
return customerIDs; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
const { getMappingConfig } = require('../../../../v0/util'); | ||
|
||
// ref : https://learn.microsoft.com/en-us/linkedin/marketing/integrations/ads-reporting/conversions-api?view=li-lms-2024-02&tabs=http#adding-multiple-conversion-events-in-a-batch | ||
const BATCH_ENDPOINT = 'https://api.linkedin.com/rest/conversionEvents'; | ||
const API_HEADER_METHOD = 'BATCH_CREATE'; | ||
const API_VERSION = '202402'; // yyyymm format | ||
const API_PROTOCOL_VERSION = '2.0.0'; | ||
|
||
const CONFIG_CATEGORIES = { | ||
USER_INFO: { | ||
name: 'linkedinUserInfoConfig', | ||
type: 'user', | ||
}, | ||
}; | ||
|
||
const MAPPING_CONFIG = getMappingConfig(CONFIG_CATEGORIES, __dirname); | ||
|
||
module.exports = { | ||
MAX_BATCH_SIZE: 5000, | ||
BATCH_ENDPOINT, | ||
API_HEADER_METHOD, | ||
API_VERSION, | ||
API_PROTOCOL_VERSION, | ||
CONFIG_CATEGORIES, | ||
MAPPING_CONFIG, | ||
}; |
31 changes: 31 additions & 0 deletions
31
src/cdk/v2/destinations/linkedin_ads/data/linkedinUserInfoConfig.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
[ | ||
{ | ||
"destKey": "firstName", | ||
"sourceKeys": "firstName", | ||
"required": false, | ||
"sourceFromGenericMap": true | ||
}, | ||
{ | ||
"destKey": "lastName", | ||
"sourceKeys": "lastName", | ||
"required": false, | ||
"sourceFromGenericMap": true | ||
}, | ||
{ | ||
"destKey": "title", | ||
"sourceKeys": "title", | ||
"required": false, | ||
"sourceFromGenericMap": true | ||
}, | ||
{ | ||
"destKey": "companyName", | ||
"sourceKeys": "context.traits.companyName", | ||
"required": false | ||
}, | ||
{ | ||
"destKey": "countryCode", | ||
"sourceKeys": "countryCode", | ||
"sourceFromGenericMap": true, | ||
"required": false | ||
} | ||
] |
Oops, something went wrong.