Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: onboard klaviyo bulk upload destination #3348

Merged
merged 13 commits into from
Jun 18, 2024
Merged
86 changes: 55 additions & 31 deletions src/cdk/v2/destinations/klaviyo_bulk_upload/utils.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/* eslint-disable no-param-reassign */
const { removeUndefinedValues } = require('../../../../v0/util');

const locationAttributes = [
'address1',
'address2',
Expand All @@ -10,20 +13,39 @@
'ip',
];

function removeLocationAttributes(traits) {
const finalObject = {};
return Object.keys(traits).reduce((result, key) => {
if (!locationAttributes.includes(key)) {
finalObject[key] = traits[key];
}
return finalObject;
}, {});
const standardTraits = [
'email',
'phone_number',
'external_id',
'anonymous_id',
'_kx',
'first_name',
'last_name',
'organization',
'title',
'image',
];

function setStandardAndCustomTraits(traits) {
const standardAttributes = {};
const customAttributes = {};
return Object.keys(traits).reduce(
(result, key) => {
if (!locationAttributes.includes(key) && standardTraits.includes(key)) {
result.standardAttributes[key] = traits[key];
} else if (!locationAttributes.includes(key)) {
result.customAttributes[key] = traits[key];
}
return result;
},
{ standardAttributes, customAttributes },
);
}

function generateLocationObject({
traits: { address1, address2, city, country, latitude, longitude, region, zip, ip },
}) {
return {
const locationObject = {
address1,
address2,
city,
Expand All @@ -34,36 +56,38 @@
zip,
ip,
};

return removeUndefinedValues(locationObject);
}

function transformSingleMessage(data, metadata) {
yashasvibajpai marked this conversation as resolved.
Show resolved Hide resolved
const { context, traits } = data;
const location = generateLocationObject(data);
const { jobId } = metadata;
const traitsWithoutLocation = removeLocationAttributes(traits);
let transformedSinglePayload = {};
const { standardAttributes, customAttributes } = setStandardAndCustomTraits(traits);
const transformedSinglePayload = {
type: 'profile',
attributes: {
...standardAttributes,
location,
properties: customAttributes,
anonymous_id: context.externalId[0].id,
koladilip marked this conversation as resolved.
Show resolved Hide resolved
jobIdentifier: `${context.externalId[0].id}:${jobId}`,
},
};
if (context.externalId[0].identifierType === 'id') {
transformedSinglePayload = {
type: 'profile',
id: context.externalId[0].id || traits.id,
attributes: {
...traitsWithoutLocation,
location,
jobIdentifier: `${context.externalId[0].id}:${jobId}`,
},
};
} else {
transformedSinglePayload = {
type: 'profile',
attributes: {
...traitsWithoutLocation,
location,
anonymous_id: context.externalId[0].id,
jobIdentifier: `${context.externalId[0].id}:${jobId}`,
},
};
transformedSinglePayload.id = context.externalId[0].id || traits.id;
transformedSinglePayload.attributes.anonymous_id = context.externalId[0].id;

Check warning on line 80 in src/cdk/v2/destinations/klaviyo_bulk_upload/utils.js

View check run for this annotation

Codecov / codecov/patch

src/cdk/v2/destinations/klaviyo_bulk_upload/utils.js#L80

Added line #L80 was not covered by tests
} else if (context.externalId[0].identifierType === 'email') {
transformedSinglePayload.attributes.email = context.externalId[0].id;

Check warning on line 82 in src/cdk/v2/destinations/klaviyo_bulk_upload/utils.js

View check run for this annotation

Codecov / codecov/patch

src/cdk/v2/destinations/klaviyo_bulk_upload/utils.js#L82

Added line #L82 was not covered by tests
}
if (Object.keys(transformedSinglePayload.attributes.location).length === 0) {
delete transformedSinglePayload.attributes.location;

Check warning on line 85 in src/cdk/v2/destinations/klaviyo_bulk_upload/utils.js

View check run for this annotation

Codecov / codecov/patch

src/cdk/v2/destinations/klaviyo_bulk_upload/utils.js#L85

Added line #L85 was not covered by tests
}
if (Object.keys(transformedSinglePayload.attributes.properties).length === 0) {
delete transformedSinglePayload.attributes.properties;
}
return transformedSinglePayload;
return removeUndefinedValues(transformedSinglePayload);
}

function wrapCombinePayloads(transformedInputs, destinationObj) {
yashasvibajpai marked this conversation as resolved.
Show resolved Hide resolved
Expand Down
119 changes: 119 additions & 0 deletions test/integrations/destinations/klaviyo_bulk_upload/processor/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -368,4 +368,123 @@ export const data = [
},
},
},
{
name: 'klaviyo_bulk_upload',
description: 'Successful identify event with custom properties',
feature: 'processor',
module: 'destination',
version: 'v0',
input: {
request: {
body: [
{
message: {
channel: 'sources',
context: {
externalId: [
{
id: 'user1',
identifierType: 'userId',
type: 'KLAVIYO_BULK_UPLOAD-userProfiles',
},
],
mappedToDestination: 'true',
sources: {
job_id: '2gif2bMzsX1Nt0rbV1vcbAE3cxC',
job_run_id: 'cp5p5ilq47pqg38v2nfg',
task_run_id: 'cp5p5ilq47pqg38v2ng0',
version: '2051/merge',
},
},
traits: {
email: '[email protected]',
first_name: 'Testqwe0022',
last_name: 'user',
phone_number: '+919902330123',
ip: '213.5.6.41',
last_visit_date: '2020-10-01T00:00:00Z',
lastVisitService: ['Brazilian'],
},
type: 'identify',
userId: '1',
},
destination: {
DestinationDefinition: {
Config: {
cdkV2Enabled: true,
},
},
Config: {
privateApiKey: 'pk_dummy_123',
},
},
metadata: {
destinationId: 'destId',
workspaceId: 'wspId',
jobId: 1,
},
},
],
},
},
output: {
response: {
status: 200,
body: [
{
output: {
version: '1',
type: 'REST',
method: 'POST',
endpoint: '',
headers: {},
params: {},
body: {
JSON: {
data: {
type: 'profile-bulk-import-job',
attributes: {
profiles: {
data: [
{
type: 'profile',
attributes: {
email: '[email protected]',
first_name: 'Testqwe0022',
last_name: 'user',
phone_number: '+919902330123',
location: {
ip: '213.5.6.41',
},
anonymous_id: 'user1',
jobIdentifier: 'user1:1',
properties: {
lastVisitService: ['Brazilian'],
last_visit_date: '2020-10-01T00:00:00Z',
},
},
},
],
},
},
},
},
JSON_ARRAY: {},
XML: {},
FORM: {},
},
files: {},
userId: '',
},
statusCode: 200,
metadata: {
destinationId: 'destId',
workspaceId: 'wspId',
jobId: 1,
},
},
],
},
},
},
];
Loading