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

fix: allow null values to be passed in Braze for standard properties #2111

Merged
merged 11 commits into from
May 5, 2023
14 changes: 7 additions & 7 deletions src/controllers/bulkUpload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,20 @@ import { client as errNotificationClient } from '../util/errorNotifier';
import logger from '../logger';
// TODO: To be refactored and redisgned

const getDestFileUploadHandler = (version, dest) => require(`../${version}/destinations/${dest}/fileUpload`);
const getDestFileUploadHandler = (version, dest) =>
require(`../${version}/destinations/${dest}/fileUpload`);
const getPollStatusHandler = (version, dest) => require(`../${version}/destinations/${dest}/poll`);
const getJobStatusHandler = (version, dest) => require(`../${version}/destinations/${dest}/fetchJobStatus`);
const getJobStatusHandler = (version, dest) =>
require(`../${version}/destinations/${dest}/fetchJobStatus`);

const getCommonMetadata = (ctx) =>
const getCommonMetadata = (ctx) =>
// TODO: Parse information such as
// cluster, namespace, etc information
// from the request
({
({
namespace: 'Unknown',
cluster: 'Unknown',
})
;

});
export const fileUpload = async (ctx) => {
logger.debug(
'Native(Bulk-Upload): Request to transformer:: /fileUpload route',
Expand Down
9 changes: 4 additions & 5 deletions src/middlewares/routeActivation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,10 @@ export default class RouteActivationMiddleware {
private static executeActivationRule(ctx: Context, next: Next, shouldActivate: boolean) {
if (shouldActivate) {
return next();
}
ctx.status = 404;
ctx.body = 'RouteActivationMiddleware route is disabled';
return ctx;

}
ctx.status = 404;
ctx.body = 'RouteActivationMiddleware route is disabled';
return ctx;
}

private static shouldActivateRoute(integration: string, filterList: string | undefined) {
Expand Down
9 changes: 7 additions & 2 deletions src/services/destination/cdkV2Integration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,13 @@ export default class CDKV2DestinationService implements IntegrationDestinationSe
const respList: ProcessorTransformationResponse[][] = await Promise.all(
events.map(async (event) => {
try {
const transformedPayloads: ProcessorTransformationOutput | ProcessorTransformationOutput[] =
await processCdkV2Workflow(destinationType, event, tags.FEATURES.PROCESSOR);
const transformedPayloads:
| ProcessorTransformationOutput
| ProcessorTransformationOutput[] = await processCdkV2Workflow(
destinationType,
event,
tags.FEATURES.PROCESSOR,
);
// We are not passing destination handler for CDK flows
return DestinationPostTransformationService.handleProcessorTransformSucessEvents(
event,
Expand Down
5 changes: 3 additions & 2 deletions src/services/destination/nativeIntegration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,9 @@ export default class NativeIntegrationDestinationService implements IntegrationD
const respList: ProcessorTransformationResponse[][] = await Promise.all(
events.map(async (event) => {
try {
const transformedPayloads: ProcessorTransformationOutput | ProcessorTransformationOutput[] =
await destHandler.process(event);
const transformedPayloads:
| ProcessorTransformationOutput
| ProcessorTransformationOutput[] = await destHandler.process(event);
return DestinationPostTransformationService.handleProcessorTransformSucessEvents(
event,
transformedPayloads,
Expand Down
8 changes: 4 additions & 4 deletions src/services/source/postTransformation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ export default class PostTransformationSourceService {
// We will not return array for events not meant for gateway
if (Object.prototype.hasOwnProperty.call(events, 'outputToSource')) {
return events as SourceTransformationResponse;
} if (Array.isArray(events)) {
}
if (Array.isArray(events)) {
return { output: { batch: events } } as SourceTransformationResponse;
}
return { output: { batch: [events] } } as SourceTransformationResponse;

}
return { output: { batch: [events] } } as SourceTransformationResponse;
}
}
13 changes: 8 additions & 5 deletions src/services/userTransform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,14 @@ export default class UserTransformService {
status = error.statusCode;
}
transformedEvents.push(
...eventsToProcess.map((e) => ({
statusCode: status,
metadata: e.metadata,
error: errorString,
} as ProcessorTransformationResponse)),
...eventsToProcess.map(
(e) =>
({
statusCode: status,
metadata: e.metadata,
error: errorString,
} as ProcessorTransformationResponse),
),
);
stats.counter('user_transform_errors', eventsToProcess.length, {
transformationVersionId,
Expand Down
3 changes: 2 additions & 1 deletion src/util/dynamicConfigParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ export class DynamicConfigParser {
events: ProcessorTransformationRequest[] | RouterTransformationRequestData[],
) {
const eventRespArr = events.map(
(e: ProcessorTransformationRequest | RouterTransformationRequestData) => this.getDynamicConfig(e),
(e: ProcessorTransformationRequest | RouterTransformationRequestData) =>
this.getDynamicConfig(e),
);
return eventRespArr;
}
Expand Down
36 changes: 18 additions & 18 deletions src/v0/destinations/braze/transform.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,17 @@ const { JSON_MIME_TYPE } = require('../../util/constant');

function formatGender(gender) {
// few possible cases of woman
if (['woman', 'female', 'w', 'f'].includes(gender.toLowerCase())) {
if (['woman', 'female', 'w', 'f'].includes(gender?.toLowerCase())) {
return 'F';
}

// few possible cases of man
if (['man', 'male', 'm'].includes(gender.toLowerCase())) {
if (['man', 'male', 'm'].includes(gender?.toLowerCase())) {
return 'M';
}

// few possible cases of other
if (['other', 'o'].includes(gender.toLowerCase())) {
if (['other', 'o'].includes(gender?.toLowerCase())) {
return 'O';
}

Expand Down Expand Up @@ -148,21 +148,6 @@ function getUserAttributesObject(message, mappingJson, destination) {
return traits;
}

// iterate over the destKeys and set the value if present
Object.keys(mappingJson).forEach((destKey) => {
let value = get(traits, mappingJson[destKey]);
if (value) {
// handle gender special case
if (destKey === 'gender') {
value = formatGender(value);
}
if (destKey === 'email') {
value = value.toLowerCase();
}
data[destKey] = value;
}
});

// reserved keys : already mapped through mappingJson
const reservedKeys = [
krishna2020 marked this conversation as resolved.
Show resolved Hide resolved
'address',
Expand All @@ -175,7 +160,22 @@ function getUserAttributesObject(message, mappingJson, destination) {
'phone',
];

// iterate over the destKeys and set the value if present
if (traits) {
krishna2020 marked this conversation as resolved.
Show resolved Hide resolved
Object.keys(mappingJson).forEach((destKey) => {
let value = get(traits, mappingJson[destKey]);
if (value || (value === null && reservedKeys.includes(destKey))) {
shrouti1507 marked this conversation as resolved.
Show resolved Hide resolved
// handle gender special case
if (destKey === 'gender') {
value = formatGender(value);
}
if (destKey === 'email') {
value = value.toLowerCase();
}
data[destKey] = value;
}
});

// iterate over rest of the traits properties
Object.keys(traits).forEach((traitKey) => {
// if traitKey is not reserved add the value to final output
Expand Down
6 changes: 0 additions & 6 deletions src/v0/destinations/braze/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,6 @@ const BrazeDedupUtility = {
const externalIdentifiers = ids.filter((id) => id.external_id);
const aliasIdentifiers = ids.filter((id) => id.alias_name !== undefined);

const startTime = Date.now();
const { processedResponse: lookUpResponse } = await handleHttpRequest(
'post',
`${getEndpointFromConfig(destination)}/users/export/ids`,
Expand All @@ -146,11 +145,6 @@ const BrazeDedupUtility = {
timeout: 10 * 1000,
},
);
const endTime = Date.now();
// TODO: Remove this log
console.log(
`Time taken to fetch user store: ${endTime - startTime} ms for ${ids.length} users`,
);
stats.counter('braze_lookup_failure_count', 1, { http_status: lookUpResponse.status });
const { users } = lookUpResponse.response;

Expand Down
134 changes: 134 additions & 0 deletions test/__tests__/data/braze_input.json
Original file line number Diff line number Diff line change
Expand Up @@ -1164,5 +1164,139 @@
"type": "track",
"userId": "finalUserTestCA"
}
},
{
"destination": {
"Config": {
"restApiKey": "9432f11f70f8ce386f5110c8c924b3ec4f825256",
"prefixProperties": true,
"useNativeSDK": false,
"dataCenter": "us-01"
},
"DestinationDefinition": {
"DisplayName": "Braze",
"ID": "1WhbSZ6uA3H5ChVifHpfL2H6sie",
"Name": "BRAZE"
},
"Enabled": true,
"ID": "1WhcOCGgj9asZu850HvugU2C3Aq",
"Name": "Braze",
"Transformations": []
},
"message": {
"channel": "web",
"context": {
"traits": {
"address": {
"city": "Mathura",
"country": "India"
},
"email": "anuj.kumar@gmail.com",
"phone": "9988123321",
"firstName": "anuj",
"lastName": "kumar",
"gender": "male",
"birthday": "01/01/1971",
"avatar": "https://i.kym-cdn.com/entries/icons/mobile/000/034/772/anuj-1.jpg",
"bio": "Tech and tension go together",
"language": "en-IN",
"job": "Director",
"company": "Plinth India"
},
"app": {
"build": "1.0.0",
"name": "RudderLabs JavaScript SDK",
"namespace": "com.rudderlabs.javascript",
"version": "1.0.5"
},
"ip": "0.0.0.0",
"library": {
"name": "RudderLabs JavaScript SDK",
"version": "1.0.5"
},
"locale": "en-GB",
"os": {
"name": "",
"version": ""
},
"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.117 Safari/537.36"
},
"integrations": {
"All": true
},
"request_ip": "[::1]:53709",
"type": "identify",
"userId": "ank101"
}
},
{
"destination": {
"Config": {
"restApiKey": "9432f11f70f8ce386f5110c8c924b3ec4f825256",
"prefixProperties": true,
"useNativeSDK": false,
"dataCenter": "us-01"
},
"DestinationDefinition": {
"DisplayName": "Braze",
"ID": "1WhbSZ6uA3H5ChVifHpfL2H6sie",
"Name": "BRAZE"
},
"Enabled": true,
"ID": "1WhcOCGgj9asZu850HvugU2C3Aq",
"Name": "Braze",
"Transformations": []
},
"message": {
"channel": "web",
"context": {
"traits": {
"address": {
"city": "Mathura",
"country": "India"
},
"email": "anuj.kumar@gmail.com",
"phone": "9988123321",
"firstName": "anuj",
"lastName": "kumar",
"gender": null,
"birthday": "01/01/1971",
"avatar": "https://i.kym-cdn.com/entries/icons/mobile/000/034/772/anuj-1.jpg",
"bio": "Tech and tension go together",
"language": "en-IN",
"job": "Director",
"company": null
},
"app": {
"build": "1.0.0",
"name": "RudderLabs JavaScript SDK",
"namespace": "com.rudderlabs.javascript",
"version": "1.0.5"
},
"ip": "0.0.0.0",
"library": {
"name": "RudderLabs JavaScript SDK",
"version": "1.0.5"
},
"locale": "en-GB",
"os": {
"name": "",
"version": ""
},
"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.117 Safari/537.36"
},
"integrations": {
"All": true
},
"request_ip": "[::1]:53709",
"type": "identify",
"userId": "ank101"
}
}
]
Loading