diff --git a/src/cdk/v2/destinations/webhook_v2/utils.js b/src/cdk/v2/destinations/webhook_v2/utils.js index 8e04b59ec0..329c5fc053 100644 --- a/src/cdk/v2/destinations/webhook_v2/utils.js +++ b/src/cdk/v2/destinations/webhook_v2/utils.js @@ -3,7 +3,12 @@ const { groupBy } = require('lodash'); const { createHash } = require('crypto'); const { ConfigurationError } = require('@rudderstack/integrations-lib'); const { BatchUtils } = require('@rudderstack/workflow-engine'); -const { base64Convertor, applyCustomMappings, isEmptyObject } = require('../../../../v0/util'); +const { + base64Convertor, + applyCustomMappings, + isEmptyObject, + applyJSONStringTemplate, +} = require('../../../../v0/util'); const getAuthHeaders = (config) => { let headers; @@ -36,8 +41,13 @@ const getCustomMappings = (message, mapping) => { } }; -// TODO: write a func to evaluate json path template -const addPathParams = (message, webhookUrl) => webhookUrl; +const addPathParams = (message, webhookUrl) => { + try { + return applyJSONStringTemplate(message, `\`${webhookUrl}\``); + } catch (e) { + throw new ConfigurationError(`[Webhook]:: Error in url template: ${e.message}`); + } +}; const excludeMappedFields = (payload, mapping) => { const rawPayload = { ...payload }; diff --git a/test/integrations/destinations/webhook_v2/common.ts b/test/integrations/destinations/webhook_v2/common.ts index c31a7aabad..dafc5853d5 100644 --- a/test/integrations/destinations/webhook_v2/common.ts +++ b/test/integrations/destinations/webhook_v2/common.ts @@ -41,7 +41,7 @@ const destinations: Destination[] = [ }, { Config: { - webhookUrl: 'http://abc.com/contact/$traits.userId', + webhookUrl: 'http://abc.com/contacts', auth: 'basicAuth', username: 'test-user', password: '', @@ -92,7 +92,7 @@ const destinations: Destination[] = [ }, { Config: { - webhookUrl: 'http://abc.com/contacts/$.traits.userId/', + webhookUrl: 'http://abc.com/contacts/{{$.traits.email}}/', auth: 'apiKeyAuth', apiKeyName: 'x-api-key', apiKeyValue: 'test-api-key', @@ -114,7 +114,7 @@ const destinations: Destination[] = [ }, { Config: { - webhookUrl: 'http://abc.com/contacts/$.traits.userId/', + webhookUrl: 'http://abc.com/contacts/{{$.traits.email}}/', auth: 'apiKeyAuth', apiKeyName: 'x-api-key', apiKeyValue: 'test-api-key', @@ -247,6 +247,37 @@ const destinations: Destination[] = [ Transformations: [], WorkspaceID: 'test-workspace-id', }, + { + Config: { + webhookUrl: 'http://abc.com/contacts/{{$.traits.phone}}', + auth: 'noAuth', + method: 'POST', + format: 'JSON', + isBatchingEnabled: true, + maxBatchSize: 4, + headers: [ + { + to: "$.'content-type'", + from: "'application/json'", + }, + { + to: '$.key', + from: '.traits.key', + }, + ], + }, + DestinationDefinition: { + DisplayName: displayName, + ID: '123', + Name: destTypeInUpperCase, + Config: { cdkV2Enabled: true }, + }, + Enabled: true, + ID: '123', + Name: destTypeInUpperCase, + Transformations: [], + WorkspaceID: 'test-workspace-id', + }, ]; const traits = { diff --git a/test/integrations/destinations/webhook_v2/processor/configuration.ts b/test/integrations/destinations/webhook_v2/processor/configuration.ts index 7a1c105ed0..702c20a6fb 100644 --- a/test/integrations/destinations/webhook_v2/processor/configuration.ts +++ b/test/integrations/destinations/webhook_v2/processor/configuration.ts @@ -87,7 +87,7 @@ export const configuration: ProcessorTestData[] = [ output: transformResultBuilder({ method: 'DELETE', userId: '', - endpoint: 'http://abc.com/contacts/$.traits.userId/', + endpoint: 'http://abc.com/contacts/john.doe@example.com/', headers: { 'x-api-key': 'test-api-key', }, diff --git a/test/integrations/destinations/webhook_v2/router/data.ts b/test/integrations/destinations/webhook_v2/router/data.ts index 44c9f0e6fe..34f16f211f 100644 --- a/test/integrations/destinations/webhook_v2/router/data.ts +++ b/test/integrations/destinations/webhook_v2/router/data.ts @@ -120,7 +120,48 @@ const routerRequest3 = { destType, }; -// TODO: add failure testcases +const routerRequest4 = { + input: [ + { + message: { + type: 'identify', + userId: 'userId1', + traits: { ...traits, key: 'value1' }, + }, + metadata: generateMetadata(1), + destination: destinations[6], + }, + { + message: { + type: 'identify', + userId: 'userId1', + traits: { ...traits, key: 'value1' }, + }, + metadata: generateMetadata(2), + destination: destinations[6], + }, + { + message: { + type: 'identify', + userId: 'userId1', + traits, + }, + metadata: generateMetadata(3), + destination: destinations[6], + }, + { + message: { + type: 'identify', + userId: 'userId1', + traits: { ...traits, phone: '2234567890' }, + }, + metadata: generateMetadata(4), + destination: destinations[6], + }, + ], + destType, +}; + export const data = [ { id: 'webhook_v2-router-test-1', @@ -147,7 +188,7 @@ export const data = [ version: '1', type: 'REST', method: 'GET', - endpoint: 'http://abc.com/contacts/$.traits.userId/', + endpoint: 'http://abc.com/contacts/john.doe@example.com/', headers: { 'x-api-key': 'test-api-key', }, @@ -196,7 +237,7 @@ export const data = [ version: '1', type: 'REST', method: 'GET', - endpoint: 'http://abc.com/contact/$traits.userId', + endpoint: 'http://abc.com/contacts', headers: { Authorization: 'Basic dGVzdC11c2VyOg==', 'content-type': 'application/json', @@ -228,7 +269,7 @@ export const data = [ version: '1', type: 'REST', method: 'GET', - endpoint: 'http://abc.com/contact/$traits.userId', + endpoint: 'http://abc.com/contacts', headers: { Authorization: 'Basic dGVzdC11c2VyOg==', 'content-type': 'application/json', @@ -260,7 +301,7 @@ export const data = [ version: '1', type: 'REST', method: 'GET', - endpoint: 'http://abc.com/contact/$traits.userId', + endpoint: 'http://abc.com/contacts', headers: { Authorization: 'Basic dGVzdC11c2VyOg==', 'content-type': 'application/json', @@ -347,4 +388,99 @@ export const data = [ }, }, }, + { + id: 'webhook_v2-router-test-4', + name: destType, + description: 'Batch multiple requests based on webhook url and headers', + scenario: 'Framework', + successCriteria: 'All events should be transformed successfully and status code should be 200', + feature: 'router', + module: 'destination', + version: 'v0', + input: { + request: { + body: routerRequest4, + method: 'POST', + }, + }, + output: { + response: { + status: 200, + body: { + output: [ + { + batchedRequest: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'http://abc.com/contacts/1234567890', + headers: { + 'content-type': 'application/json', + key: 'value1', + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: { batch: '[]' }, + XML: {}, + FORM: {}, + }, + files: {}, + }, + metadata: [generateMetadata(1), generateMetadata(2)], + batched: true, + statusCode: 200, + destination: destinations[6], + }, + { + batchedRequest: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'http://abc.com/contacts/1234567890', + headers: { + 'content-type': 'application/json', + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: { batch: '[]' }, + XML: {}, + FORM: {}, + }, + files: {}, + }, + metadata: [generateMetadata(3)], + batched: true, + statusCode: 200, + destination: destinations[6], + }, + { + batchedRequest: { + version: '1', + type: 'REST', + method: 'POST', + endpoint: 'http://abc.com/contacts/2234567890', + headers: { + 'content-type': 'application/json', + }, + params: {}, + body: { + JSON: {}, + JSON_ARRAY: { batch: '[]' }, + XML: {}, + FORM: {}, + }, + files: {}, + }, + metadata: [generateMetadata(4)], + batched: true, + statusCode: 200, + destination: destinations[6], + }, + ], + }, + }, + }, + }, ];