Skip to content

Commit

Permalink
Merge branch 'develop' into chore.adjust-shopify-upgrade-to-v2
Browse files Browse the repository at this point in the history
  • Loading branch information
vinayteki95 authored Dec 9, 2024
2 parents d01f411 + ebcf84e commit 82e322d
Show file tree
Hide file tree
Showing 36 changed files with 2,685 additions and 203 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/dt-test-and-report-code-coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
- name: Checkout
uses: actions/[email protected]
with:
fetch-depth: 1
fetch-depth: 0

- name: Setup Node
uses: actions/[email protected]
Expand Down
18 changes: 18 additions & 0 deletions src/util/prometheus.js
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,24 @@ class Prometheus {
type: 'counter',
labelNames: ['destination_id'],
},
{
name: 'braze_batch_subscription_size',
help: 'braze_batch_subscription_size',
type: 'gauge',
labelNames: ['destination_id'],
},
{
name: 'braze_batch_subscription_combined_size',
help: 'braze_batch_subscription_combined_size',
type: 'gauge',
labelNames: ['destination_id'],
},
{
name: 'mailjet_packing_size',
help: 'mailjet_packing_size',
type: 'gauge',
labelNames: ['group'],
},
{
name: 'hs_batch_size',
help: 'hs_batch_size',
Expand Down
151 changes: 140 additions & 11 deletions src/v0/destinations/braze/braze.util.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const {
getPurchaseObjs,
setAliasObject,
handleReservedProperties,
combineSubscriptionGroups,
} = require('./util');
const { processBatch } = require('./util');
const {
Expand Down Expand Up @@ -958,7 +959,9 @@ describe('processBatch', () => {
attributes: [{ id: i, name: 'test', xyz: 'abc' }],
events: [{ id: i, event: 'test', xyz: 'abc' }],
purchases: [{ id: i, purchase: 'test', xyz: 'abc' }],
subscription_groups: [{ id: i, group: 'test', xyz: 'abc' }],
subscription_groups: [
{ subscription_group_id: i, group: 'test', subscription_state: 'abc' },
],
merge_updates: [{ id: i, alias: 'test', xyz: 'abc' }],
},
},
Expand All @@ -972,7 +975,7 @@ describe('processBatch', () => {

// Assert that the response is as expected
expect(result.length).toBe(1); // One successful batched request and one failure response
expect(result[0].batchedRequest.length).toBe(6); // Two batched requests
expect(result[0].batchedRequest.length).toBe(8); // Two batched requests
expect(result[0].batchedRequest[0].body.JSON.partner).toBe('RudderStack'); // Verify partner name
expect(result[0].batchedRequest[0].body.JSON.attributes.length).toBe(75); // First batch contains 75 attributes
expect(result[0].batchedRequest[0].body.JSON.events.length).toBe(75); // First batch contains 75 events
Expand All @@ -981,10 +984,12 @@ describe('processBatch', () => {
expect(result[0].batchedRequest[1].body.JSON.attributes.length).toBe(25); // Second batch contains remaining 25 attributes
expect(result[0].batchedRequest[1].body.JSON.events.length).toBe(25); // Second batch contains remaining 25 events
expect(result[0].batchedRequest[1].body.JSON.purchases.length).toBe(25); // Second batch contains remaining 25 purchases
expect(result[0].batchedRequest[2].body.JSON.subscription_groups.length).toBe(50); // First batch contains 50 subscription group
expect(result[0].batchedRequest[3].body.JSON.subscription_groups.length).toBe(50);
expect(result[0].batchedRequest[4].body.JSON.merge_updates.length).toBe(50); // First batch contains 50 merge_updates
expect(result[0].batchedRequest[5].body.JSON.merge_updates.length).toBe(50); // First batch contains 25 merge_updates
expect(result[0].batchedRequest[2].body.JSON.subscription_groups.length).toBe(25); // First batch contains 25 subscription group
expect(result[0].batchedRequest[3].body.JSON.subscription_groups.length).toBe(25); // Second batch contains 25 subscription group
expect(result[0].batchedRequest[4].body.JSON.subscription_groups.length).toBe(25); // Third batch contains 25 subscription group
expect(result[0].batchedRequest[5].body.JSON.subscription_groups.length).toBe(25); // Fourth batch contains 25 subscription group
expect(result[0].batchedRequest[6].body.JSON.merge_updates.length).toBe(50); // First batch contains 50 merge_updates
expect(result[0].batchedRequest[7].body.JSON.merge_updates.length).toBe(50); // First batch contains 25 merge_updates
});

test('processBatch handles more than 75 attributes, events, and purchases with non uniform distribution', () => {
Expand Down Expand Up @@ -1055,7 +1060,9 @@ describe('processBatch', () => {
batchedRequest: {
body: {
JSON: {
subscription_groups: [{ id: i, group: 'test', xyz: 'abc' }],
subscription_groups: [
{ subscription_group_id: i, group: 'test', subscription_state: 'abc' },
],
},
},
},
Expand Down Expand Up @@ -1093,7 +1100,7 @@ describe('processBatch', () => {
// Assert that the response is as expected
expect(result.length).toBe(1); // One successful batched request and one failure response
expect(result[0].metadata.length).toBe(490); // Check the total length is same as input jobs (120 + 160 + 100 + 70 +40)
expect(result[0].batchedRequest.length).toBe(6); // Two batched requests
expect(result[0].batchedRequest.length).toBe(7); // Two batched requests
expect(result[0].batchedRequest[0].body.JSON.partner).toBe('RudderStack'); // Verify partner name
expect(result[0].batchedRequest[0].body.JSON.attributes.length).toBe(75); // First batch contains 75 attributes
expect(result[0].batchedRequest[0].body.JSON.events.length).toBe(75); // First batch contains 75 events
Expand All @@ -1103,9 +1110,10 @@ describe('processBatch', () => {
expect(result[0].batchedRequest[1].body.JSON.events.length).toBe(45); // Second batch contains remaining 45 events
expect(result[0].batchedRequest[1].body.JSON.purchases.length).toBe(75); // Second batch contains remaining 75 purchases
expect(result[0].batchedRequest[2].body.JSON.purchases.length).toBe(10); // Third batch contains remaining 10 purchases
expect(result[0].batchedRequest[3].body.JSON.subscription_groups.length).toBe(50); // First batch contains 50 subscription group
expect(result[0].batchedRequest[4].body.JSON.subscription_groups.length).toBe(20); // Second batch contains 20 subscription group
expect(result[0].batchedRequest[5].body.JSON.merge_updates.length).toBe(40); // First batch contains 40 merge_updates
expect(result[0].batchedRequest[3].body.JSON.subscription_groups.length).toBe(25); // First batch contains 25 subscription group
expect(result[0].batchedRequest[4].body.JSON.subscription_groups.length).toBe(25); // Second batch contains 25 subscription group
expect(result[0].batchedRequest[5].body.JSON.subscription_groups.length).toBe(20); // Third batch contains 20 subscription group
expect(result[0].batchedRequest[6].body.JSON.merge_updates.length).toBe(40); // First batch contains 50 merge_updates
});

test('check success and failure scenarios both for processBatch', () => {
Expand Down Expand Up @@ -1751,3 +1759,124 @@ describe('handleReservedProperties', () => {
});
});
});

describe('combineSubscriptionGroups', () => {
it('should merge external_ids, emails, and phones for the same subscription_group_id and subscription_state', () => {
const input = [
{
subscription_group_id: 'group1',
subscription_state: 'Subscribed',
external_ids: ['id1', 'id2'],
emails: ['[email protected]', '[email protected]'],
phones: ['+1234567890', '+0987654321'],
},
{
subscription_group_id: 'group1',
subscription_state: 'Subscribed',
external_ids: ['id2', 'id3'],
emails: ['[email protected]', '[email protected]'],
phones: ['+1234567890', '+1122334455'],
},
];

const expectedOutput = [
{
subscription_group_id: 'group1',
subscription_state: 'Subscribed',
external_ids: ['id1', 'id2', 'id3'],
emails: ['[email protected]', '[email protected]', '[email protected]'],
phones: ['+1234567890', '+0987654321', '+1122334455'],
},
];

const result = combineSubscriptionGroups(input);
expect(result).toEqual(expectedOutput);
});

it('should handle groups with missing external_ids, emails, or phones', () => {
const input = [
{
subscription_group_id: 'group1',
subscription_state: 'Subscribed',
external_ids: ['id1'],
},
{
subscription_group_id: 'group1',
subscription_state: 'Subscribed',
emails: ['[email protected]'],
},
{
subscription_group_id: 'group1',
subscription_state: 'Subscribed',
phones: ['+1234567890'],
},
];

const expectedOutput = [
{
subscription_group_id: 'group1',
subscription_state: 'Subscribed',
external_ids: ['id1'],
emails: ['[email protected]'],
phones: ['+1234567890'],
},
];

const result = combineSubscriptionGroups(input);
expect(result).toEqual(expectedOutput);
});

it('should handle multiple unique subscription groups', () => {
const input = [
{
subscription_group_id: 'group1',
subscription_state: 'Subscribed',
external_ids: ['id1'],
},
{
subscription_group_id: 'group2',
subscription_state: 'Unsubscribed',
external_ids: ['id2'],
emails: ['[email protected]'],
},
];

const expectedOutput = [
{
subscription_group_id: 'group1',
subscription_state: 'Subscribed',
external_ids: ['id1'],
},
{
subscription_group_id: 'group2',
subscription_state: 'Unsubscribed',
external_ids: ['id2'],
emails: ['[email protected]'],
},
];

const result = combineSubscriptionGroups(input);
expect(result).toEqual(expectedOutput);
});

it('should not include undefined fields in the output', () => {
const input = [
{
subscription_group_id: 'group1',
subscription_state: 'Subscribed',
external_ids: ['id1'],
},
];

const expectedOutput = [
{
subscription_group_id: 'group1',
subscription_state: 'Subscribed',
external_ids: ['id1'],
},
];

const result = combineSubscriptionGroups(input);
expect(result).toEqual(expectedOutput);
});
});
2 changes: 1 addition & 1 deletion src/v0/destinations/braze/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const IDENTIFY_BRAZE_MAX_REQ_COUNT = 50;
// https://www.braze.com/docs/api/endpoints/user_data/post_user_delete/

const ALIAS_BRAZE_MAX_REQ_COUNT = 50;
const SUBSCRIPTION_BRAZE_MAX_REQ_COUNT = 50;
const SUBSCRIPTION_BRAZE_MAX_REQ_COUNT = 25;

const DEL_MAX_BATCH_SIZE = 50;
const DESTINATION = 'braze';
Expand Down
2 changes: 1 addition & 1 deletion src/v0/destinations/braze/transform.js
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ function processGroup(message, destination) {
);
}
subscriptionGroup.subscription_state = message.traits.subscriptionState;
subscriptionGroup.external_id = [message.userId];
subscriptionGroup.external_ids = [message.userId];
const phone = getFieldValueFromMessage(message, 'phone');
const email = getFieldValueFromMessage(message, 'email');
if (phone) {
Expand Down
54 changes: 53 additions & 1 deletion src/v0/destinations/braze/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,42 @@ const getEndpointFromConfig = (destination) => {
return endpoint;
};

// Merges external_ids, emails, and phones for entries with the same subscription_group_id and subscription_state
const combineSubscriptionGroups = (subscriptionGroups) => {
const uniqueGroups = {};

subscriptionGroups.forEach((group) => {
const key = `${group.subscription_group_id}-${group.subscription_state}`;
if (!uniqueGroups[key]) {
uniqueGroups[key] = {
...group,
external_ids: [...(group.external_ids || [])],
emails: [...(group.emails || [])],
phones: [...(group.phones || [])],
};
} else {
uniqueGroups[key].external_ids.push(...(group.external_ids || []));
uniqueGroups[key].emails.push(...(group.emails || []));
uniqueGroups[key].phones.push(...(group.phones || []));
}
});

return Object.values(uniqueGroups).map((group) => {
const result = {
subscription_group_id: group.subscription_group_id,
subscription_state: group.subscription_state,
external_ids: [...new Set(group.external_ids)],
};
if (group.emails?.length) {
result.emails = [...new Set(group.emails)];
}
if (group.phones?.length) {
result.phones = [...new Set(group.phones)];
}
return result;
});
};

const CustomAttributeOperationUtil = {
customAttributeUpdateOperation(key, data, traits, mergeObjectsUpdateOperation) {
data[key] = {};
Expand Down Expand Up @@ -381,8 +417,22 @@ function prepareGroupAndAliasBatch(arrayChunks, responseArray, destination, type
} else if (type === 'subscription') {
response.endpoint = getSubscriptionGroupEndPoint(getEndpointFromConfig(destination));
const subscription_groups = chunk;
// maketool transformed event
logger.info(`braze subscription chunk ${JSON.stringify(subscription_groups)}`);

stats.gauge('braze_batch_subscription_size', subscription_groups.length, {
destination_id: destination.ID,
});

// Deduplicate the subscription groups before constructing the response body
const deduplicatedSubscriptionGroups = combineSubscriptionGroups(subscription_groups);

stats.gauge('braze_batch_subscription_combined_size', deduplicatedSubscriptionGroups.length, {
destination_id: destination.ID,
});

response.body.JSON = removeUndefinedAndNullValues({
subscription_groups,
subscription_groups: deduplicatedSubscriptionGroups,
});
}
responseArray.push({
Expand Down Expand Up @@ -490,6 +540,7 @@ const processBatch = (transformedEvents) => {
prepareGroupAndAliasBatch(mergeUsersArrayChunks, responseArray, destination, 'merge');

if (successMetadata.length > 0) {
console.log(`Response 1 batchRequest ${JSON.stringify(responseArray)}`);
finalResponse.push({
batchedRequest: responseArray,
metadata: successMetadata,
Expand Down Expand Up @@ -756,4 +807,5 @@ module.exports = {
collectStatsForAliasFailure,
collectStatsForAliasMissConfigurations,
handleReservedProperties,
combineSubscriptionGroups,
};
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const {
getClickConversionPayloadAndEndpoint,
getConsentsDataFromIntegrationObj,
getCallConversionPayload,
updateConversion,
} = require('./utils');
const helper = require('./helper');

Expand Down Expand Up @@ -48,6 +49,9 @@ const getConversions = (message, metadata, { Config }, event, conversionType) =>
filteredCustomerId,
eventLevelConsentsData,
);
convertedPayload.payload.conversions[0] = updateConversion(
convertedPayload.payload.conversions[0],
);
payload = convertedPayload.payload;
endpoint = convertedPayload.endpoint;
} else if (conversionType === 'store') {
Expand Down
Loading

0 comments on commit 82e322d

Please sign in to comment.