Skip to content

Commit

Permalink
fix: allow null values to be passed in Braze for standard properties (#…
Browse files Browse the repository at this point in the history
…2111)

* allow null vslues to be passed for standard properties

* fix: implementation and testcases

* fix: home city value reference

* chore: turn off error rule for dot notation syntax

* refactor: restore object string notation

* chore: run integration tests before commit

* fix: redundant pass, console.log

* fix: remove redundant mapping

---------

Co-authored-by: saikumarrs <saibattinoju@rudderstack.com>
  • Loading branch information
yashasvibajpai and saikumarrs committed May 5, 2023
1 parent c4b0a69 commit 10d037a
Show file tree
Hide file tree
Showing 11 changed files with 265 additions and 50 deletions.
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 = [
'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) {
Object.keys(mappingJson).forEach((destKey) => {
let value = get(traits, mappingJson[destKey]);
if (value || (value === null && reservedKeys.includes(destKey))) {
// 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

0 comments on commit 10d037a

Please sign in to comment.