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

feat: onboard source ortto #2693

Merged
merged 8 commits into from
Oct 13, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 95 additions & 0 deletions src/v0/sources/ortto/event_mapping.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
{
"act::s": "Sent email",
"act::c": "Clicked email",
"act::o": "Opened email",
"act::r": "Received email",
"act::b": "Bounced email",
"act::sk": "Skipped email",
"act::rt": "Redacted email",
"act::f": "Forwarded email",
"act::i": "Invalid email",
"act::v": "Viewed email online",
"act::d": "Deferred email",

"act::ss": "Incident Triggered",
"act::ds": "Incident Unacknowledged",
"act::cs": "Service Created",
"act::is": "Service Deleted",
"act::bs": "Service Updated",
"act::des": "Service Updated",
"act::rs": "Service Updated",
"act::rtss": "Service Updated",
"act::ras": "Service Updated",
"act::cos": "Service Updated",
"act::rtns": "Service Updated",
"act::sf": "Submitted form",
"act::oos-a": "Opted out from SMS audience",
"act::ois-a": "Opted in to SMS audience",
"act::oos-all": "Opted out from all SMS",
"act::ros-all": "Opted in to all SMS",
"act::ss-ab": "SMS subscription abuse",
"act::scr": "SMS consent requested",
"act::scf": "SMS consent failed",

"act::sph": "Sent push",
"act::dph": "Delivered push",
"act::cph": "Clicked push",
"act::iph": "Invalid push",
"act::oiip-all": "Opted in to all iOS push",
"act::ooip-all": "Opted out of all iOS push",
"act::oiip-a": "Opted in to iOS push audience",
"act::oips-a": "Opted out of iOS push audience",
"act::oigp-all": "Opted in to all Android push",
"act::oogp-all": "Opted out of all Android push",
"act::oigp-a": "Opted out of Android push audience",
"act::oogs-a": "Opted in to Android push audience",
"act::oiwp-all": "Opted in to all web push",
"act::oowp-all": "Opted out of all web push",
"act::oiwp-a": "Opted in to web push audience",
"act::oows-a": "Opted out of to web push audience",
"act::iws-ab": "Web push subscription abuse",

"act::ws": "Website session",
"act::us": "User session",

"act::enter-audience": "Entered audience",
"act::leave-audience": "Left audience",
"act::ta": "Tag added",
"act::tr": "Tag removed",
"act::u-a": "Unsubscribe from audience",
"act::s-a": "Subscribe to audience",
"act::u-all": "Un subscribe from all email",
"act::s-all": "Resubscribe globally",
"act::s-ab": "Subscription abuse",

"act::ep": "Entered playbook",
"act::lp": "Left playbook",
"act::spa": "Successful playbook action",
"act::fpa": "Failed playbook action",

"act::ej": "Entered journey",
"act::lj": "Left journey",
"act::sja": "Successful journey action",
"act::fja": "Failed journey action",

"act::cw": "Clicked widget",
"act::sw": "Shown widget",
"act::dw": "Dismissed widget",
"act::rw": "Reacted to widget",
"act::swf": "Submitted widget form",
"act::rws": "Responded to widget survey",
"act::wwv": "Watched widget video",
"act::sww": "Spun widget wheel",

"act::cop": "Conversation opened",
"act::cro": "Conversation re-opened",
"act::cas": "Conversation assigned",
"act::clc": "Conversation closed",
"act::csn": "Conversation snoozed",
"act::crt": "Conversation rated",
"act::cms": "Conversation marked as spam",
"act::cvs": "Conversation voice call started",
"act::cve": "Conversation voice call ended",
"act::ctg": "Conversation tagged",
"act::cut": "Conversation un-tagged"
}
14 changes: 14 additions & 0 deletions src/v0/sources/ortto/mapping.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[
{
"sourceKeys": "contact.email",
"destKeys": "context.traits.email"
},
{
"sourceKeys": "id",
"destKeys": "messageId"
},
{
"sourceKeys": "time",
"destKeys": "originalTimestamp"
}
]
74 changes: 74 additions & 0 deletions src/v0/sources/ortto/transform.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
const path = require('path');
const fs = require('fs');
const { flattenJson, removeUndefinedAndNullValues, generateUUID } = require('../../util');
const Message = require('../message');
const eventMapping = require('./event_mapping.json');
const { JSON_MIME_TYPE } = require('../../util/constant');

// import mapping json using JSON.parse to preserve object key order
const mapping = JSON.parse(fs.readFileSync(path.resolve(__dirname, './mapping.json'), 'utf-8'));

function settingProperties(event, message) {
const messageReplica = message;

// flattening the event and assigning it to properties
messageReplica.properties = removeUndefinedAndNullValues(flattenJson(event));

// fields that are already mapped
const excludeFields = ['contact.email', 'contact.contact_id', 'id', 'time', 'activity.field_id'];

// deleting already mapped fields
excludeFields.forEach((field) => {
delete messageReplica.properties[field];
});

return message;
}

function process(event) {
let message = new Message(`ortto`);

// Here, we are checking for the test event to discard them
if (event.activity?.field_id === 'act::test_webhook') {
return {

Check warning on line 33 in src/v0/sources/ortto/transform.js

View check run for this annotation

Codecov / codecov/patch

src/v0/sources/ortto/transform.js#L33

Added line #L33 was not covered by tests
outputToSource: {
body: Buffer.from(JSON.stringify(event)).toString('base64'),
contentType: JSON_MIME_TYPE,
},
statusCode: 200,
};
}

// we are setting event type as track always
message.setEventType('track');

// setting anonymousId
message.anonymousId = generateUUID();
ujjwal-ab marked this conversation as resolved.
Show resolved Hide resolved

message.setPropertiesV2(event, mapping);

// Updating timestamp to acceptable timestamp format ["2023-10-10T06:24:19.103820974Z" -> "2023-10-10T06:24:19.103820974Z"]
ujjwal-ab marked this conversation as resolved.
Show resolved Hide resolved
if (message.originalTimestamp) {
const date = `${Math.floor(new Date(message.originalTimestamp).getTime() / 1000)}`;
message.originalTimestamp = new Date(date * 1000).toISOString();
}

// setting event Name
message.setEventName(eventMapping[event.activity.field_id]);
ItsSudip marked this conversation as resolved.
Show resolved Hide resolved

// setting up ortto contact.contact_id to externalId
if (event.user?.id) {
message.context.externalId = [

Check warning on line 61 in src/v0/sources/ortto/transform.js

View check run for this annotation

Codecov / codecov/patch

src/v0/sources/ortto/transform.js#L61

Added line #L61 was not covered by tests
{
type: 'orttoContactId',
id: event.contact.contact_id,
},
];
}

message = settingProperties(event, message);

return message;
}

module.exports = { process };
79 changes: 79 additions & 0 deletions test/integrations/sources/ortto/data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import utils from '../../../../src/v0/util';

const defaultMockFns = () => {
jest.spyOn(utils, 'generateUUID').mockReturnValue('97fcd7b2-cc24-47d7-b776-057b7b199513');
};

export const data = [
{
name: 'ortto',
description: 'Simple track call',
module: 'source',
version: 'v0',
input: {
request: {
body: [
{
activity: {
id: "00651b946bfef7e80478efee",
field_id: "act::s-all",
created: "2023-10-03T04:11:23Z",
attr: {
"str::is": "API",
"str::s-ctx": "Subscribed via API"
}
},
contact: {
contact_id: "00651b946baa9be6b2edad00",
email: "[email protected]"
},
id: "00651b946cef87c7af64f4f3",
time: "2023-10-03T04:11:24.25726779Z",
webhook_id: "651b8aec8002153e16319fd3"
},
],
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
},
pathSuffix: '',
},
output: {
response: {
status: 200,
body: [
{
output: {
batch: [
{
context: {
library: { name: 'unknown', version: 'unknown' },
integration: { name: 'ortto' },
traits: { email: '[email protected]' },
},
event: 'Resubscribe globally',
integrations: { ortto: false },
type: 'track',
anonymousId: '97fcd7b2-cc24-47d7-b776-057b7b199513',
messageId: '00651b946cef87c7af64f4f3',
originalTimestamp: '2023-10-03T04:11:24.000Z',
properties: {
'activity.id': '00651b946bfef7e80478efee',
'activity.created': '2023-10-03T04:11:23Z',
'activity.attr.str::is': 'API',
'activity.attr.str::s-ctx': 'Subscribed via API',
webhook_id: '651b8aec8002153e16319fd3',
},
},
],
},
},
],
},
},
mockFns: () => {
defaultMockFns();
},
}
]
Loading