Skip to content

Commit

Permalink
feat: onboard destination movable ink
Browse files Browse the repository at this point in the history
  • Loading branch information
Gauravudia committed Mar 5, 2024
1 parent 433e067 commit ca8d695
Show file tree
Hide file tree
Showing 9 changed files with 787 additions and 1 deletion.
65 changes: 65 additions & 0 deletions src/cdk/v2/destinations/movable_ink/procWorkflow.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
bindings:
- name: EventType
path: ../../../../constants
- path: ../../bindings/jsontemplate
- name: defaultRequestConfig
path: ../../../../v0/util
- name: toUnixTimestampInMS
path: ../../../../v0/util
- name: base64Convertor
path: ../../../../v0/util
- path: ./utils

steps:
- name: messageType
template: |
.message.type.toLowerCase();
- name: validateInput
template: |
let messageType = $.outputs.messageType;
$.assert(messageType, "message Type is not present. Aborting");
$.assert(messageType in {{$.EventType.([.IDENTIFY,.TRACK])}}, "message type " + messageType + " is not supported");
$.assertConfig(.destination.Config.endpoint, "Movable Ink Endpoint is not present. Aborting");
$.assertConfig(.destination.Config.accessKey, "Access key is not present . Aborting");
$.assertConfig(.destination.Config.accessSecret, "Access Secret is not present. Aborting");
$.assert(.message.timestamp ?? .message.originalTimestamp, "Timestamp is not present. Aborting");
const userId = .message.().(
{{{{$.getGenericPaths("userIdOnly")}}}};
);
const email = .message.().(
{{{{$.getGenericPaths("email")}}}};
);
$.assert(userId ?? email ?? .message.anonymousId, "Either one of userId or email or anonymousId is required. Aborting");
- name: preparePayload
template: |
const userId = .message.().(
{{{{$.getGenericPaths("userIdOnly")}}}};
);
const email = .message.().(
{{{{$.getGenericPaths("email")}}}};
);
const timestampInUnix = $.toUnixTimestampInMS(.message.().(
{{{{$.getGenericPaths("timestamp")}}}};
));
$.context.payload = {
...(.message),
userId: userId ?? email,
timestamp: timestampInUnix,
anonymousId: .message.anonymousId
}
- name: buildResponse
template: |
const response = $.defaultRequestConfig();
response.body.JSON = $.context.payload;
response.endpoint = .destination.Config.endpoint;
response.method = "POST";
response.headers = {
"Content-Type": "application/json",
"Authorization": "Basic " + $.base64Convertor(.destination.Config.accessKey + ":" + .destination.Config.accessSecret)
}
response;
33 changes: 33 additions & 0 deletions src/cdk/v2/destinations/movable_ink/rtWorkflow.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
bindings:
- name: handleRtTfSingleEventError
path: ../../../../v0/util/index
- path: ./utils
exportAll: true

steps:
- name: validateInput
template: |
$.assert(Array.isArray(^) && ^.length > 0, "Invalid event array")
- name: transform
externalWorkflow:
path: ./procWorkflow.yaml
loopOverInput: true

- name: successfulEvents
template: |
$.outputs.transform#idx.output.({
"batchedRequest": .,
"batched": false,
"destination": ^[idx].destination,
"metadata": ^[idx].metadata[],
"statusCode": 200
})[]
- name: failedEvents
template: |
$.outputs.transform#idx.error.(
$.handleRtTfSingleEventError(^[idx], .originalError ?? ., {})
)[]
- name: finalPayload
template: |
[...$.outputs.successfulEvents, ...$.outputs.failedEvents]
3 changes: 2 additions & 1 deletion src/features.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@
"REDDIT": true,
"THE_TRADE_DESK": true,
"INTERCOM": true,
"NINETAILED": true
"NINETAILED": true,
"MOVABLE_INK": true
},
"regulations": [
"BRAZE",
Expand Down
121 changes: 121 additions & 0 deletions test/integrations/destinations/movable_ink/common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import { Destination } from '../../../../src/types';

const destType = 'movable_ink';
const destTypeInUpperCase = 'MOVABLE_INK';
const displayName = 'Movable Ink';
const channel = 'web';
const destination: Destination = {
Config: {
endpoint: 'https://collector.movableink-dmz.com/behavioral/abc123',
accessKey: 'test-access-key',
accessSecret: 'test_access_secret',
},
DestinationDefinition: {
DisplayName: displayName,
ID: '123',
Name: destTypeInUpperCase,
Config: { cdkV2Enabled: true },
},
Enabled: true,
ID: '123',
Name: destTypeInUpperCase,
Transformations: [],
WorkspaceID: 'test-workspace-id',
};

const processorInstrumentationErrorStatTags = {
destType: destTypeInUpperCase,
errorCategory: 'dataValidation',
errorType: 'instrumentation',
feature: 'processor',
implementation: 'cdkV2',
module: 'destination',
destinationId: 'default-destinationId',
workspaceId: 'default-workspaceId',
};

const RouterInstrumentationErrorStatTags = {
...processorInstrumentationErrorStatTags,
feature: 'router',
};

const traits = {
email: '[email protected]',
firstName: 'John',
lastName: 'Doe',
phone: '1234567890',
};

const headers = {
'Content-Type': 'application/json',
Authorization: 'Basic dGVzdC1hY2Nlc3Mta2V5OnRlc3RfYWNjZXNzX3NlY3JldA==',
};

const commonProperties = {
product_id: '622c6f5d5cf86a4c77358033',
sku: '8472-998-0112',
categories: [
{ url: 'https://example1', id: '1' },
{ url: 'https://example2', id: '2' },
],
name: 'Cones of Dunshire',
brand: 'Wyatt Games',
variant: 'expansion pack',
price: 49.99,
quantity: 5,
coupon: 'PREORDER15',
position: 1,
url: 'https://www.website.com/product/path',
image_url: 'https://www.website.com/product/path.webp',
};

const trackTestProperties = {
'Product Added': commonProperties,
'Product Viewed': commonProperties,
'Order Completed': {
checkout_id: '70324a1f0eaf000000000000',
order_id: '40684e8f0eaf000000000000',
affiliation: 'Vandelay Games',
total: 52,
subtotal: 45,
revenue: 50,
shipping: 4,
tax: 3,
discount: 5,
coupon: 'NEWCUST5',
currency: 'USD',
products: [
{
product_id: '622c6f5d5cf86a4c77358033',
sku: '8472-998-0112',
name: 'Cones of Dunshire',
price: 40,
position: 1,
category: 'Games',
url: 'https://www.website.com/product/path',
image_url: 'https://www.website.com/product/path.jpg',
},
{
product_id: '577c6f5d5cf86a4c7735ba03',
sku: '3309-483-2201',
name: 'Five Crowns',
price: 5,
position: 2,
category: 'Games',
},
],
},
'Products Searched': { query: 'HDMI cable', url: 'https://www.website.com/product/path' },
'Custom event': { ...commonProperties, key1: 'value1', key2: true },
};

export {
destType,
channel,
destination,
processorInstrumentationErrorStatTags,
RouterInstrumentationErrorStatTags,
traits,
headers,
trackTestProperties,
};
4 changes: 4 additions & 0 deletions test/integrations/destinations/movable_ink/processor/data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { validation } from './validation';
import { identify } from './identify';
import { track } from './track';
export const data = [...identify, ...track, ...validation];
64 changes: 64 additions & 0 deletions test/integrations/destinations/movable_ink/processor/identify.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { ProcessorTestData } from '../../../testTypes';
import { generateMetadata, transformResultBuilder } from '../../../testUtils';
import { destType, channel, destination, traits, headers } from '../common';

export const identify: ProcessorTestData[] = [
{
id: 'MovableInk-identify-test-1',
name: destType,
description: 'Identify call with traits and anonymousId',
scenario: 'Framework+Business',
successCriteria:
'Response should contain the input payload with few additional mappings configured in transformer and status code should be 200',
feature: 'processor',
module: 'destination',
version: 'v0',
input: {
request: {
body: [
{
destination,
message: {
type: 'identify',
anonymousId: 'anonId123',
traits,
integrations: {
All: true,
},
originalTimestamp: '2024-03-04T15:32:56.409Z',
},
metadata: generateMetadata(1),
},
],
},
},
output: {
response: {
status: 200,
body: [
{
output: transformResultBuilder({
method: 'POST',
userId: '',
endpoint: destination.Config.endpoint,
headers,
JSON: {
type: 'identify',
userId: traits.email,
anonymousId: 'anonId123',
traits,
integrations: {
All: true,
},
originalTimestamp: '2024-03-04T15:32:56.409Z',
timestamp: 1709566376409,
},
}),
statusCode: 200,
metadata: generateMetadata(1),
},
],
},
},
},
];
Loading

0 comments on commit ca8d695

Please sign in to comment.