diff --git a/src/services/destination/cdkV2Integration.ts b/src/services/destination/cdkV2Integration.ts index a91bc5674b..0789a98c1e 100644 --- a/src/services/destination/cdkV2Integration.ts +++ b/src/services/destination/cdkV2Integration.ts @@ -1,7 +1,6 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ /* eslint-disable class-methods-use-this */ import { TransformationError } from '@rudderstack/integrations-lib'; -import groupBy from 'lodash/groupBy'; import { processCdkV2Workflow } from '../../cdk/v2/handler'; import { DestinationService } from '../../interfaces/DestinationService'; import { @@ -20,6 +19,7 @@ import { } from '../../types/index'; import stats from '../../util/stats'; import { CatchErr } from '../../util/types'; +import { groupRouterTransformEvents } from '../../v0/util'; import tags from '../../v0/util/tags'; import { DestinationPostTransformationService } from './postTransformation'; @@ -112,46 +112,38 @@ export class CDKV2DestinationService implements DestinationService { _version: string, requestMetadata: NonNullable, ): Promise { - const allDestEvents: object = groupBy( - events, - (ev: RouterTransformationRequestData) => ev.destination?.ID, - ); + const groupedEvents: RouterTransformationRequestData[][] = groupRouterTransformEvents(events); const response: RouterTransformationResponse[][] = await Promise.all( - Object.values(allDestEvents).map( - async (destInputArray: RouterTransformationRequestData[]) => { - const metaTo = this.getTags( - destinationType, - destInputArray[0].metadata.destinationId, - destInputArray[0].metadata.workspaceId, - tags.FEATURES.ROUTER, - ); - metaTo.metadata = destInputArray[0].metadata; - try { - const doRouterTransformationResponse: RouterTransformationResponse[] = - await processCdkV2Workflow( - destinationType, - destInputArray, - tags.FEATURES.ROUTER, - requestMetadata, - ); - return DestinationPostTransformationService.handleRouterTransformSuccessEvents( - doRouterTransformationResponse, - undefined, - metaTo, - tags.IMPLEMENTATIONS.CDK_V2, - destinationType.toUpperCase(), + groupedEvents.map(async (destInputArray: RouterTransformationRequestData[]) => { + const metaTo = this.getTags( + destinationType, + destInputArray[0].metadata.destinationId, + destInputArray[0].metadata.workspaceId, + tags.FEATURES.ROUTER, + ); + metaTo.metadata = destInputArray[0].metadata; + try { + const doRouterTransformationResponse: RouterTransformationResponse[] = + await processCdkV2Workflow( + destinationType, + destInputArray, + tags.FEATURES.ROUTER, + requestMetadata, ); - } catch (error: CatchErr) { - metaTo.metadatas = destInputArray.map((input) => input.metadata); - const erroredResp = - DestinationPostTransformationService.handleRouterTransformFailureEvents( - error, - metaTo, - ); - return [erroredResp]; - } - }, - ), + return DestinationPostTransformationService.handleRouterTransformSuccessEvents( + doRouterTransformationResponse, + undefined, + metaTo, + tags.IMPLEMENTATIONS.CDK_V2, + destinationType.toUpperCase(), + ); + } catch (error: CatchErr) { + metaTo.metadatas = destInputArray.map((input) => input.metadata); + const erroredResp = + DestinationPostTransformationService.handleRouterTransformFailureEvents(error, metaTo); + return [erroredResp]; + } + }), ); return response.flat(); } diff --git a/src/services/destination/nativeIntegration.ts b/src/services/destination/nativeIntegration.ts index 38a27ea71d..38ec934ff7 100644 --- a/src/services/destination/nativeIntegration.ts +++ b/src/services/destination/nativeIntegration.ts @@ -26,6 +26,7 @@ import { import stats from '../../util/stats'; import tags from '../../v0/util/tags'; import { DestinationPostTransformationService } from './postTransformation'; +import { groupRouterTransformEvents } from '../../v0/util'; export class NativeIntegrationDestinationService implements DestinationService { public init() {} @@ -99,11 +100,7 @@ export class NativeIntegrationDestinationService implements DestinationService { requestMetadata: NonNullable, ): Promise { const destHandler = FetchHandler.getDestHandler(destinationType, version); - const allDestEvents: NonNullable = groupBy( - events, - (ev: RouterTransformationRequestData) => ev.destination?.ID, - ); - const groupedEvents: RouterTransformationRequestData[][] = Object.values(allDestEvents); + const groupedEvents: RouterTransformationRequestData[][] = groupRouterTransformEvents(events); const response: RouterTransformationResponse[][] = await Promise.all( groupedEvents.map(async (destInputArray: RouterTransformationRequestData[]) => { const metaTO = this.getTags( diff --git a/src/types/index.ts b/src/types/index.ts index 7aa6bd8ebf..13c54214fd 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -160,6 +160,7 @@ type RouterTransformationRequestData = { message: object; metadata: Metadata; destination: Destination; + connection?: Record; }; type RouterTransformationRequest = { diff --git a/src/v0/destinations/fb_custom_audience/config.js b/src/v0/destinations/fb_custom_audience/config.js index 39ca2d04c4..809ba0b7d6 100644 --- a/src/v0/destinations/fb_custom_audience/config.js +++ b/src/v0/destinations/fb_custom_audience/config.js @@ -4,6 +4,8 @@ function getEndPoint(audienceId) { return `${BASE_URL}/${audienceId}/users`; } +const VDM_V2_SCHEMA_VERSION = '1.1'; + const schemaFields = [ 'EXTERN_ID', 'EMAIL', @@ -105,4 +107,5 @@ module.exports = { typeFields, subTypeFields, maxPayloadSize, + VDM_V2_SCHEMA_VERSION, }; diff --git a/src/v0/destinations/fb_custom_audience/recordTransform.js b/src/v0/destinations/fb_custom_audience/recordTransform.js index 62d4bd568b..9b4e72f961 100644 --- a/src/v0/destinations/fb_custom_audience/recordTransform.js +++ b/src/v0/destinations/fb_custom_audience/recordTransform.js @@ -2,7 +2,7 @@ const lodash = require('lodash'); const get = require('get-value'); const { InstrumentationError, ConfigurationError } = require('@rudderstack/integrations-lib'); -const { schemaFields } = require('./config'); +const { schemaFields, VDM_V2_SCHEMA_VERSION } = require('./config'); const { MappedToDestinationKey } = require('../../../constants'); const stats = require('../../../util/stats'); const { @@ -17,6 +17,7 @@ const { ensureApplicableFormat, getUpdatedDataElement, getSchemaForEventMappedToDest, + getSchemaForEventMappedToDestForVDMv2, batchingWithPayloadSize, responseBuilderSimple, getDataSource, @@ -100,18 +101,18 @@ const processRecordEventArray = ( }; async function processRecordInputs(groupedRecordInputs) { - const { destination } = groupedRecordInputs[0]; + const { destination, connection } = groupedRecordInputs[0]; const { message } = groupedRecordInputs[0]; - const { - isHashRequired, - accessToken, - disableFormat, - type, - subType, - isRaw, - maxUserCount, - audienceId, - } = destination.Config; + const { accessToken, disableFormat, type, subType, isRaw, maxUserCount } = destination.Config; + let audienceId; + let isHashRequired; + if (connection?.config?.destination?.schemaVersion === VDM_V2_SCHEMA_VERSION) { + audienceId = connection?.config?.destination?.audienceId; + isHashRequired = connection?.config?.destination?.isHashRequired; + } else { + audienceId = destination.Config?.audienceId; + isHashRequired = destination.Config?.isHashRequired; + } const prepareParams = { access_token: accessToken, }; @@ -125,7 +126,7 @@ async function processRecordInputs(groupedRecordInputs) { // audience id validation let operationAudienceId = audienceId; const mappedToDestination = get(message, MappedToDestinationKey); - if (mappedToDestination) { + if (mappedToDestination && !operationAudienceId) { const { objectType } = getDestinationExternalIDInfoForRetl(message, 'FB_CUSTOM_AUDIENCE'); operationAudienceId = objectType; } @@ -136,7 +137,11 @@ async function processRecordInputs(groupedRecordInputs) { // user schema validation let { userSchema } = destination.Config; if (mappedToDestination) { - userSchema = getSchemaForEventMappedToDest(message); + if (connection?.config?.destination?.schemaVersion === VDM_V2_SCHEMA_VERSION) { + userSchema = getSchemaForEventMappedToDestForVDMv2(message); + } else { + userSchema = getSchemaForEventMappedToDest(message); + } } if (!Array.isArray(userSchema)) { userSchema = [userSchema]; diff --git a/src/v0/destinations/fb_custom_audience/transform.js b/src/v0/destinations/fb_custom_audience/transform.js index c5c340c043..f920ebe398 100644 --- a/src/v0/destinations/fb_custom_audience/transform.js +++ b/src/v0/destinations/fb_custom_audience/transform.js @@ -12,16 +12,16 @@ const { const { prepareDataField, getSchemaForEventMappedToDest, + getSchemaForEventMappedToDestForVDMv2, batchingWithPayloadSize, generateAppSecretProof, responseBuilderSimple, getDataSource, } = require('./util'); -const { schemaFields, USER_ADD, USER_DELETE } = require('./config'); +const { schemaFields, USER_ADD, USER_DELETE, VDM_V2_SCHEMA_VERSION } = require('./config'); const { MappedToDestinationKey } = require('../../../constants'); const { processRecordInputs } = require('./recordTransform'); -const logger = require('../../../logger'); function checkForUnsupportedEventTypes(dictionary, keyList) { const unsupportedEventTypes = []; @@ -154,11 +154,21 @@ const prepareToSendEvents = ( }); return toSendEvents; }; -const processEvent = (message, destination) => { +const processEvent = (event) => { + const { message, destination, connection } = event; const respList = []; let toSendEvents = []; let { userSchema } = destination.Config; - const { isHashRequired, audienceId, maxUserCount } = destination.Config; + const { maxUserCount } = destination.Config; + let audienceId; + let isHashRequired; + if (connection?.config?.destination?.schemaVersion === VDM_V2_SCHEMA_VERSION) { + audienceId = connection?.config?.destination?.audienceId; + isHashRequired = connection?.config?.destination?.isHashRequired; + } else { + audienceId = destination.Config?.audienceId; + isHashRequired = destination.Config?.isHashRequired; + } if (!message.type) { throw new InstrumentationError('Message Type is not present. Aborting message.'); } @@ -182,7 +192,11 @@ const processEvent = (message, destination) => { // If mapped to destination, use the mapped fields instead of destination userschema if (mappedToDestination) { - userSchema = getSchemaForEventMappedToDest(message); + if (connection?.config?.destination?.schemaVersion === VDM_V2_SCHEMA_VERSION) { + userSchema = getSchemaForEventMappedToDestForVDMv2(message); + } else { + userSchema = getSchemaForEventMappedToDest(message); + } } // When one single schema field is added in the webapp, it does not appear to be an array @@ -236,7 +250,7 @@ const processEvent = (message, destination) => { return respList; }; -const process = (event) => processEvent(event.message, event.destination); +const process = (event) => processEvent(event); const processRouterDest = async (inputs, reqMetadata) => { const respList = []; @@ -247,7 +261,6 @@ const processRouterDest = async (inputs, reqMetadata) => { const eventTypes = ['record', 'audiencelist']; const unsupportedEventList = checkForUnsupportedEventTypes(groupedInputs, eventTypes); if (unsupportedEventList.length > 0) { - logger.info(`unsupported events found ${unsupportedEventList}`); throw new ConfigurationError('unsupported events present in the event'); } diff --git a/src/v0/destinations/fb_custom_audience/util.js b/src/v0/destinations/fb_custom_audience/util.js index 401b601869..84dcdf52dc 100644 --- a/src/v0/destinations/fb_custom_audience/util.js +++ b/src/v0/destinations/fb_custom_audience/util.js @@ -61,6 +61,18 @@ const getSchemaForEventMappedToDest = (message) => { return userSchema; }; +const getSchemaForEventMappedToDestForVDMv2 = (message) => { + const mappedSchema = message?.identifierMappings; + if (!mappedSchema) { + throw new InstrumentationError( + 'event.identifierMappings is required property for events mapped to destination ', + ); + } + let userSchema = Object.keys(mappedSchema); + userSchema = userSchema.map((field) => field.trim()); + return userSchema; +}; + // function responsible to ensure the user inputs are passed according to the allowed format const ensureApplicableFormat = (userProperty, userInformation) => { let updatedProperty; @@ -261,6 +273,7 @@ const responseBuilderSimple = (payload, audienceId) => { module.exports = { prepareDataField, getSchemaForEventMappedToDest, + getSchemaForEventMappedToDestForVDMv2, batchingWithPayloadSize, ensureApplicableFormat, getUpdatedDataElement, diff --git a/src/v0/util/index.js b/src/v0/util/index.js index c3b9570bc4..cf1ff60e99 100644 --- a/src/v0/util/index.js +++ b/src/v0/util/index.js @@ -2281,8 +2281,14 @@ const validateEventAndLowerCaseConversion = (event, isMandatory, convertToLowerC return convertToLowerCase ? event.toString().toLowerCase() : event.toString(); }; -const applyCustomMappings = (message, mappings) => - JsonTemplateEngine.createAsSync(mappings, { defaultPathType: PathType.JSON }).evaluate(message); +/** + * This function applies custom mappings to the event. + * @param {*} event The event to be transformed. + * @param {*} mappings The custom mappings to be applied. + * @returns {object} The transformed event. + */ +const applyCustomMappings = (event, mappings) => + JsonTemplateEngine.createAsSync(mappings, { defaultPathType: PathType.JSON }).evaluate(event); const applyJSONStringTemplate = (message, template) => JsonTemplateEngine.createAsSync(template.replace(/{{/g, '${').replace(/}}/g, '}'), { @@ -2290,6 +2296,22 @@ const applyJSONStringTemplate = (message, template) => }).evaluate(message); /** + * This groups the events by destination ID and source ID. + * Note: sourceID is only used for rETL events. + * @param {*} events The events to be grouped. + * @returns {array} The array of grouped events. + */ +const groupRouterTransformEvents = (events) => + Object.values( + lodash.groupBy(events, (ev) => [ + ev.metadata?.destinationId || ev.destination?.ID, + ev.metadata?.sourceCategory === 'warehouse' + ? ev.metadata?.sourceId || ev.connection?.sourceId + : 'default', + ]), + ); + +/* * Gets url path omitting the hostname & protocol * * **Note**: @@ -2364,6 +2386,7 @@ module.exports = { getValueFromMessage, getValueFromPropertiesOrTraits, getValuesAsArrayFromConfig, + groupRouterTransformEvents, handleSourceKeysOperation, hashToSha256, isAppleFamily, diff --git a/src/v0/util/index.test.js b/src/v0/util/index.test.js index 1b99e5ebb7..2c5cda5db8 100644 --- a/src/v0/util/index.test.js +++ b/src/v0/util/index.test.js @@ -1,4 +1,4 @@ -const { TAG_NAMES, InstrumentationError } = require('@rudderstack/integrations-lib'); +const { InstrumentationError } = require('@rudderstack/integrations-lib'); const utilities = require('.'); const { getFuncTestData } = require('../../../test/testHelper'); const { FilteredEventsError } = require('./errorTypes'); @@ -8,6 +8,7 @@ const { generateExclusionList, combineBatchRequestsWithSameJobIds, validateEventAndLowerCaseConversion, + groupRouterTransformEvents, isAxiosError, } = require('./index'); const exp = require('constants'); @@ -693,6 +694,250 @@ describe('extractCustomFields', () => { }); }); +describe('groupRouterTransformEvents', () => { + // groups events correctly by destination ID + it('should group events correctly by destination ID and source ID', () => { + const events = [ + { + message: { + eventID: 'evt001', + eventName: 'OrderReceived', + }, + metadata: { + sourceId: 'SRC001', + destinationId: 'DEST001', + sourceCategory: 'warehouse', + }, + }, + { + message: { + eventID: 'evt002', + eventName: 'InventoryUpdate', + }, + metadata: { + sourceId: 'SRC002', + destinationId: 'DEST002', + sourceCategory: 'cloud', + }, + }, + { + message: { + eventID: 'evt003', + eventName: 'UserLogin', + }, + metadata: { + sourceId: 'SRC003', + destinationId: 'DEST003', + sourceCategory: 'webhook', + }, + }, + { + message: { + eventID: 'evt004', + eventName: 'PaymentProcessed', + }, + metadata: { + sourceId: 'SRC001', + destinationId: 'DEST002', + sourceCategory: 'warehouse', + }, + }, + { + message: { + eventID: 'evt005', + eventName: 'ShipmentDispatched', + }, + metadata: { + sourceId: 'SRC002', + destinationId: 'DEST003', + sourceCategory: 'cloud', + }, + }, + { + message: { + eventID: 'evt006', + eventName: 'ProductReturn', + }, + metadata: { + sourceId: 'SRC003', + destinationId: 'DEST001', + sourceCategory: 'webhook', + }, + }, + { + message: { + eventID: 'evt007', + eventName: 'StockAlert', + }, + metadata: { + sourceId: 'SRC001', + destinationId: 'DEST003', + sourceCategory: 'warehouse', + }, + }, + { + message: { + eventID: 'evt008', + eventName: 'UserRegistration', + }, + metadata: { + sourceId: 'SRC002', + destinationId: 'DEST001', + sourceCategory: 'cloud', + }, + }, + { + message: { + eventID: 'evt009', + eventName: 'ReviewSubmitted', + }, + metadata: { + sourceId: 'SRC003', + destinationId: 'DEST002', + sourceCategory: 'webhook', + }, + }, + { + message: { + eventID: 'evt010', + eventName: 'DiscountApplied', + }, + metadata: { + sourceId: 'SRC001', + destinationId: 'DEST001', + sourceCategory: 'warehouse', + }, + }, + ]; + + const groupedEvents = groupRouterTransformEvents(events); + expect(groupedEvents).toEqual([ + [ + { + message: { + eventID: 'evt001', + eventName: 'OrderReceived', + }, + metadata: { + sourceId: 'SRC001', + destinationId: 'DEST001', + sourceCategory: 'warehouse', + }, + }, + { + message: { + eventID: 'evt010', + eventName: 'DiscountApplied', + }, + metadata: { + sourceId: 'SRC001', + destinationId: 'DEST001', + sourceCategory: 'warehouse', + }, + }, + ], + [ + { + message: { + eventID: 'evt002', + eventName: 'InventoryUpdate', + }, + metadata: { + sourceId: 'SRC002', + destinationId: 'DEST002', + sourceCategory: 'cloud', + }, + }, + { + message: { + eventID: 'evt009', + eventName: 'ReviewSubmitted', + }, + metadata: { + sourceId: 'SRC003', + destinationId: 'DEST002', + sourceCategory: 'webhook', + }, + }, + ], + [ + { + message: { + eventID: 'evt003', + eventName: 'UserLogin', + }, + metadata: { + sourceId: 'SRC003', + destinationId: 'DEST003', + sourceCategory: 'webhook', + }, + }, + { + message: { + eventID: 'evt005', + eventName: 'ShipmentDispatched', + }, + metadata: { + sourceId: 'SRC002', + destinationId: 'DEST003', + sourceCategory: 'cloud', + }, + }, + ], + [ + { + message: { + eventID: 'evt004', + eventName: 'PaymentProcessed', + }, + metadata: { + sourceId: 'SRC001', + destinationId: 'DEST002', + sourceCategory: 'warehouse', + }, + }, + ], + [ + { + message: { + eventID: 'evt006', + eventName: 'ProductReturn', + }, + metadata: { + sourceId: 'SRC003', + destinationId: 'DEST001', + sourceCategory: 'webhook', + }, + }, + { + message: { + eventID: 'evt008', + eventName: 'UserRegistration', + }, + metadata: { + sourceId: 'SRC002', + destinationId: 'DEST001', + sourceCategory: 'cloud', + }, + }, + ], + [ + { + message: { + eventID: 'evt007', + eventName: 'StockAlert', + }, + metadata: { + sourceId: 'SRC001', + destinationId: 'DEST003', + sourceCategory: 'warehouse', + }, + }, + ], + ]); + }); +}); + describe('applyJSONStringTemplate', () => { it('should apply JSON string template to the payload', () => { const payload = { diff --git a/test/integrations/destinations/fb_custom_audience/processor/data.ts b/test/integrations/destinations/fb_custom_audience/processor/data.ts index 75fa321aca..7fff17fe06 100644 --- a/test/integrations/destinations/fb_custom_audience/processor/data.ts +++ b/test/integrations/destinations/fb_custom_audience/processor/data.ts @@ -16,6 +16,13 @@ export const data = [ request: { body: [ { + connection: { + config: { + destination: { + audienceId: 'aud1', + }, + }, + }, message: { userId: 'user 1', anonymousId: 'anon-id-new', @@ -128,6 +135,13 @@ export const data = [ request: { body: [ { + connection: { + Config: { + destination: { + audienceId: 'aud1', + }, + }, + }, message: { userId: 'user 1', anonymousId: 'anon-id-new', @@ -241,6 +255,13 @@ export const data = [ request: { body: [ { + connection: { + Config: { + destination: { + audienceId: 'aud1', + }, + }, + }, message: { userId: 'user 1', anonymousId: 'anon-id-new', @@ -354,6 +375,13 @@ export const data = [ request: { body: [ { + connection: { + Config: { + destination: { + audienceId: '', + }, + }, + }, message: { userId: 'user 1', anonymousId: 'anon-id-new', @@ -467,6 +495,13 @@ export const data = [ request: { body: [ { + connection: { + config: { + destination: { + audienceId: 'aud1', + }, + }, + }, message: { userId: 'user 1', anonymousId: 'anon-id-new', @@ -678,6 +713,13 @@ export const data = [ request: { body: [ { + connection: { + config: { + destination: { + audienceId: 'aud1', + }, + }, + }, message: { userId: 'user 1', anonymousId: 'anon-id-new', @@ -889,6 +931,13 @@ export const data = [ request: { body: [ { + connection: { + config: { + destination: { + audienceId: 'aud1', + }, + }, + }, message: { userId: 'user 1', anonymousId: 'anon-id-new', @@ -1038,6 +1087,13 @@ export const data = [ request: { body: [ { + connection: { + config: { + destination: { + audienceId: 'aud1', + }, + }, + }, message: { userId: 'user 1', anonymousId: 'anon-id-new', @@ -1251,6 +1307,13 @@ export const data = [ request: { body: [ { + connection: { + config: { + destination: { + audienceId: 'aud1', + }, + }, + }, message: { userId: 'user 1', anonymousId: 'anon-id-new', @@ -1506,6 +1569,13 @@ export const data = [ request: { body: [ { + connection: { + config: { + destination: { + audienceId: 'aud1', + }, + }, + }, message: { userId: 'user 1', anonymousId: 'anon-id-new', @@ -1717,6 +1787,13 @@ export const data = [ request: { body: [ { + connection: { + config: { + destination: { + audienceId: 'aud1', + }, + }, + }, message: { userId: 'user 1', anonymousId: 'anon-id-new', @@ -1928,6 +2005,13 @@ export const data = [ request: { body: [ { + connection: { + config: { + destination: { + audienceId: 'aud1', + }, + }, + }, message: { userId: 'user 1', anonymousId: 'anon-id-new', @@ -2071,6 +2155,13 @@ export const data = [ request: { body: [ { + connection: { + config: { + destination: { + audienceId: 'aud1', + }, + }, + }, message: { userId: 'user 1', anonymousId: 'anon-id-new', @@ -2199,6 +2290,13 @@ export const data = [ request: { body: [ { + connection: { + config: { + destination: { + audienceId: 'aud1', + }, + }, + }, message: { userId: 'user 1', anonymousId: 'anon-id-new', @@ -2341,6 +2439,13 @@ export const data = [ request: { body: [ { + connection: { + config: { + destination: { + audienceId: 'aud1', + }, + }, + }, message: { userId: 'user 1', anonymousId: 'anon-id-new', @@ -54479,6 +54584,13 @@ export const data = [ request: { body: [ { + connection: { + config: { + destination: { + audienceId: 'aud1', + }, + }, + }, message: { userId: 'user 1', anonymousId: 'anon-id-new', diff --git a/test/integrations/destinations/fb_custom_audience/router/audienceList.ts b/test/integrations/destinations/fb_custom_audience/router/audienceList.ts index c386fbf782..b636a59618 100644 --- a/test/integrations/destinations/fb_custom_audience/router/audienceList.ts +++ b/test/integrations/destinations/fb_custom_audience/router/audienceList.ts @@ -39,7 +39,10 @@ export const rETLAudienceRouterRequest: RouterTransformationRequest = { messageId: '4d906837-031d-4d34-b97a-62fdf51b4d3a', event: 'Add_Audience', context: { - destinationFields: 'EMAIL, FN', + fields: { + EMAIL: 'subscribed@eewrfrd.com', + FN: 'dfgdfg', + }, externalId: [{ type: 'FB_CUSTOM_AUDIENCE-23848494844100489', identifierType: 'EMAIL' }], mappedToDestination: 'true', sources: { diff --git a/test/integrations/destinations/fb_custom_audience/router/batchingRecord.ts b/test/integrations/destinations/fb_custom_audience/router/batchingRecord.ts index 0ceff5260e..e716e36d12 100644 --- a/test/integrations/destinations/fb_custom_audience/router/batchingRecord.ts +++ b/test/integrations/destinations/fb_custom_audience/router/batchingRecord.ts @@ -32,6 +32,13 @@ const destination: Destination = { export const rETLBatchingRouterRequest: RouterTransformationRequest = { input: [ { + connection: { + config: { + destination: { + isHashRequired: true, + }, + }, + }, destination: destination, message: { action: 'insert', @@ -62,6 +69,13 @@ export const rETLBatchingRouterRequest: RouterTransformationRequest = { metadata: generateMetadata(1), }, { + connection: { + config: { + destination: { + isHashRequired: true, + }, + }, + }, destination: destination, message: { action: 'insert', @@ -92,6 +106,13 @@ export const rETLBatchingRouterRequest: RouterTransformationRequest = { metadata: generateMetadata(2), }, { + connection: { + config: { + destination: { + isHashRequired: true, + }, + }, + }, destination: destination, message: { action: 'insert', diff --git a/test/integrations/destinations/fb_custom_audience/router/data.ts b/test/integrations/destinations/fb_custom_audience/router/data.ts index ab9bfee973..d0ba3f7b60 100644 --- a/test/integrations/destinations/fb_custom_audience/router/data.ts +++ b/test/integrations/destinations/fb_custom_audience/router/data.ts @@ -345,195 +345,6 @@ export const data = [ }, }, }, - { - name: 'fb_custom_audience', - description: 'rETL tests', - scenario: 'business', - successCriteria: 'it should transform audience event correctly', - feature: 'router', - module: 'destination', - version: 'v0', - input: { - request: { - body: rETLAudienceRouterRequest, - }, - }, - output: { - response: { - status: 200, - body: { - output: [ - { - batchedRequest: [ - { - version: '1', - type: 'REST', - method: 'POST', - endpoint: 'https://graph.facebook.com/v20.0/23848494844100489/users', - headers: {}, - params: { - access_token: 'ABC', - payload: { - schema: ['EMAIL', 'FN'], - data: [ - [ - '7625cab24612c37df6d2f724721bb38a25095d0295e29b807238ee188b8aca43', - 'e328a0d90d4b5132b2655cf7079b160040d2c1a83d70d4cad9cf1f69310635b3', - ], - [ - 'b2b4abadd72190af54305c0d3abf1977fec4935016bb13ff28040d5712318dfd', - 'f8147eb72c9bb356c362fdb0796b54971ebc983cb60b3cc3ff29582ce2052bad', - ], - [ - 'c4b007d1c3c9a5d31bd4082237a913e8e0db1767225c2a5ef33be2716df005fa', - 'd8bb13b95eaed7f9b6a8af276aa6122e8015e0c466c1a84e49ff7c69ad6ac911', - ], - [ - '94639be1bd9f17c05820164e9d71ef78558f117a9e8bfab43cf8015e08aa0b27', - 'b1661f97721dede0f876dcbf603289ee339f641b9c310deba53c76940f472698', - ], - [ - '39b456cfb4bb07f9e6bb18698aa173171ca49c731fccc4790e9ecea808d24ae6', - '6c882abd6d0aff713cdd6a4a31ee28c9140612fb2627a611f6f9f539bac44f81', - ], - [ - '769f73387add781a481ca08300008a08fb2f1816aaed196137efc2e05976d711', - '2222cb73346f7a01a1d4d3db28b58fd41045782bb66152b92aade379192544c5', - ], - [ - '48ddb93f0b30c475423fe177832912c5bcdce3cc72872f8051627967ef278e08', - 'abc12f8d666517c35280bf220f5390b1f0ef4bdbbc794ac59c95bba0381bf91b', - ], - [ - 'da2d431121cd10578fd81f8f80344b06db59ea2d05a7b5d27536c8789ddae8f0', - 'abc12f8d666517c35280bf220f5390b1f0ef4bdbbc794ac59c95bba0381bf91b', - ], - [ - 'b100c2ec0718fe6b4805b623aeec6710719d042ceea55f5c8135b010ec1c7b36', - '62a2fed3d6e08c44835fce71f02210b1ddabfb066e39edf1e6c261988f824dd3', - ], - [ - '0c1d1b0ba547a742013366d6fbc8f71dd77f566d94e41ed9f828a74b96928161', - '62a2fed3d6e08c44835fce71f02210b1ddabfb066e39edf1e6c261988f824dd3', - ], - ], - }, - }, - body: { - JSON: {}, - JSON_ARRAY: {}, - XML: {}, - FORM: {}, - }, - files: {}, - }, - ], - metadata: [ - { - attemptNum: 1, - destinationId: 'default-destinationId', - dontBatch: false, - jobId: 3, - secret: { - accessToken: 'default-accessToken', - }, - sourceId: 'default-sourceId', - userId: 'default-userId', - workspaceId: 'default-workspaceId', - }, - ], - batched: false, - statusCode: 200, - destination: { - Config: { - accessToken: 'ABC', - disableFormat: false, - isHashRequired: true, - isRaw: false, - maxUserCount: '50', - oneTrustCookieCategories: [], - skipVerify: false, - subType: 'NA', - type: 'NA', - userSchema: ['EMAIL'], - }, - ID: '1mMy5cqbtfuaKZv1IhVQKnBdVwe', - Name: 'FB_CUSTOM_AUDIENCE', - Enabled: true, - WorkspaceID: '1TSN08muJTZwH8iCDmnnRt1pmLd', - DestinationDefinition: { - ID: '1aIXqM806xAVm92nx07YwKbRrO9', - Name: 'FB_CUSTOM_AUDIENCE', - DisplayName: 'FB_CUSTOM_AUDIENCE', - Config: {}, - }, - Transformations: [], - IsConnectionEnabled: true, - IsProcessorEnabled: true, - }, - }, - { - metadata: [ - { - attemptNum: 1, - destinationId: 'default-destinationId', - dontBatch: false, - jobId: 4, - secret: { - accessToken: 'default-accessToken', - }, - sourceId: 'default-sourceId', - userId: 'default-userId', - workspaceId: 'default-workspaceId', - }, - ], - batched: false, - statusCode: 400, - error: - 'context.destinationFields is required property for events mapped to destination ', - statTags: { - errorCategory: 'dataValidation', - errorType: 'instrumentation', - destType: 'FB_CUSTOM_AUDIENCE', - destinationId: 'default-destinationId', - module: 'destination', - implementation: 'native', - feature: 'router', - workspaceId: 'default-workspaceId', - }, - destination: { - Config: { - accessToken: 'ABC', - disableFormat: false, - isHashRequired: true, - isRaw: false, - maxUserCount: '50', - oneTrustCookieCategories: [], - skipVerify: false, - subType: 'NA', - type: 'NA', - userSchema: ['EMAIL'], - }, - ID: '1mMy5cqbtfuaKZv1IhVQKnBdVwe', - Name: 'FB_CUSTOM_AUDIENCE', - Enabled: true, - WorkspaceID: '1TSN08muJTZwH8iCDmnnRt1pmLd', - DestinationDefinition: { - ID: '1aIXqM806xAVm92nx07YwKbRrO9', - Name: 'FB_CUSTOM_AUDIENCE', - DisplayName: 'FB_CUSTOM_AUDIENCE', - Config: {}, - }, - Transformations: [], - IsConnectionEnabled: true, - IsProcessorEnabled: true, - }, - }, - ], - }, - }, - }, - }, { name: 'fb_custom_audience', description: 'rETL record tests', diff --git a/test/integrations/destinations/fb_custom_audience/router/eventStream.ts b/test/integrations/destinations/fb_custom_audience/router/eventStream.ts index b4dcebf48b..269283ef61 100644 --- a/test/integrations/destinations/fb_custom_audience/router/eventStream.ts +++ b/test/integrations/destinations/fb_custom_audience/router/eventStream.ts @@ -42,6 +42,13 @@ const destination: Destination = { export const eventStreamRouterRequest: RouterTransformationRequest = { input: [ { + connection: { + config: { + destination: { + audienceId: 'aud1', + }, + }, + }, message: { userId: 'user 1', anonymousId: 'anon-id-new', @@ -88,6 +95,13 @@ export const eventStreamRouterRequest: RouterTransformationRequest = { destination: destination, }, { + connection: { + config: { + destination: { + audienceId: 'aud1', + }, + }, + }, message: { userId: 'user 1', anonymousId: 'anon-id-new', diff --git a/test/integrations/destinations/fb_custom_audience/router/record.ts b/test/integrations/destinations/fb_custom_audience/router/record.ts index 534c1c40c2..f6dcf37a74 100644 --- a/test/integrations/destinations/fb_custom_audience/router/record.ts +++ b/test/integrations/destinations/fb_custom_audience/router/record.ts @@ -32,6 +32,13 @@ const destination: Destination = { export const rETLRecordRouterRequest: RouterTransformationRequest = { input: [ { + connection: { + config: { + destination: { + isHashRequired: true, + }, + }, + }, destination: destination, message: { action: 'insert', @@ -62,6 +69,13 @@ export const rETLRecordRouterRequest: RouterTransformationRequest = { metadata: generateMetadata(3), }, { + connection: { + config: { + destination: { + isHashRequired: true, + }, + }, + }, destination: destination, message: { action: 'update', @@ -92,6 +106,13 @@ export const rETLRecordRouterRequest: RouterTransformationRequest = { metadata: generateMetadata(4), }, { + connection: { + config: { + destination: { + isHashRequired: true, + }, + }, + }, destination: destination, message: { action: 'delete', @@ -122,6 +143,13 @@ export const rETLRecordRouterRequest: RouterTransformationRequest = { metadata: generateMetadata(1), }, { + connection: { + config: { + destination: { + isHashRequired: true, + }, + }, + }, destination: destination, message: { action: 'delete', @@ -152,6 +180,13 @@ export const rETLRecordRouterRequest: RouterTransformationRequest = { metadata: generateMetadata(2), }, { + connection: { + config: { + destination: { + isHashRequired: true, + }, + }, + }, destination: destination, message: { action: 'update', @@ -182,6 +217,13 @@ export const rETLRecordRouterRequest: RouterTransformationRequest = { metadata: generateMetadata(5), }, { + connection: { + config: { + destination: { + isHashRequired: true, + }, + }, + }, destination: destination, message: { action: 'update', @@ -212,6 +254,13 @@ export const rETLRecordRouterRequest: RouterTransformationRequest = { metadata: generateMetadata(6), }, { + connection: { + config: { + destination: { + isHashRequired: true, + }, + }, + }, destination: destination, message: { action: 'lol',