Skip to content

Commit

Permalink
Merge branch 'develop' into feat.awin-filter-unknown-event
Browse files Browse the repository at this point in the history
  • Loading branch information
manish339k authored May 23, 2024
2 parents eadfae7 + f74c4a0 commit 83bd3e7
Show file tree
Hide file tree
Showing 43 changed files with 1,688 additions and 295 deletions.
39 changes: 39 additions & 0 deletions src/cdk/v2/destinations/koddi/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
const { getMappingConfig } = require('../../../../v0/util');

/**
* ref :- https://developers.koddi.com/reference/winning-ads
* impressions - https://developers.koddi.com/reference/impressions-1
* clicks - https://developers.koddi.com/reference/clicks-1
* conversions - https://developers.koddi.com/reference/conversions-1
*/
const EVENT_TYPES = {
IMPRESSIONS: 'impressions',
CLICKS: 'clicks',
CONVERSIONS: 'conversions',
};

const CONFIG_CATEGORIES = {
IMPRESSIONS: {
type: 'track',
name: 'ImpressionsConfig',
},
CLICKS: {
type: 'track',
name: 'ClicksConfig',
},
CONVERSIONS: {
type: 'track',
name: 'ConversionsConfig',
},
};

const MAPPING_CONFIG = getMappingConfig(CONFIG_CATEGORIES, __dirname);

module.exports = {
EVENT_TYPES,
CONFIG_CATEGORIES,
MAPPING_CONFIG,
IMPRESSIONS_CONFIG: MAPPING_CONFIG[CONFIG_CATEGORIES.IMPRESSIONS.name],
CLICKS_CONFIG: MAPPING_CONFIG[CONFIG_CATEGORIES.CLICKS.name],
CONVERSIONS_CONFIG: MAPPING_CONFIG[CONFIG_CATEGORIES.CONVERSIONS.name],
};
35 changes: 35 additions & 0 deletions src/cdk/v2/destinations/koddi/data/ClicksConfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
[
{
"sourceKeys": "properties.tracking_data",
"required": true,
"destKey": "trackingData"
},
{
"sourceKeys": "properties.rank",
"required": true,
"destKey": "rank"
},
{
"sourceKeys": "properties.beacon_issued",
"required": true,
"destKey": "beaconIssued"
},
{
"sourceKeys": "userId",
"sourceFromGenericMap": true,
"required": true,
"destKey": "userGuid"
},
{
"sourceKeys": "properties.test_version_override",
"destKey": "testVersionOverride"
},
{
"sourceKeys": "properties.destination_url",
"destKey": "destinationUrl"
},
{
"sourceKeys": "properties.overrides",
"destKey": "overrides"
}
]
53 changes: 53 additions & 0 deletions src/cdk/v2/destinations/koddi/data/ConversionsConfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
[
{
"sourceKeys": "context.page.referring_domain",
"destKey": "domain"
},
{
"sourceKeys": "context.locale",
"required": true,
"destKey": "culture"
},
{
"sourceKeys": "properties.currency",
"required": true,
"destKey": "currency"
},
{
"sourceKeys": ["context.ip", "request_ip"],
"destKey": "user_ip"
},
{
"sourceKeys": "context.userAgent",
"destKey": "user_agent"
},
{
"sourceKeys": "userId",
"sourceFromGenericMap": true,
"required": true,
"destKey": "user_guid"
},
{
"sourceKeys": "context.device.type",
"destKey": "device_type"
},
{
"sourceKeys": ["properties.order_id", "properties.transaction_id"],
"required": true,
"destKey": "transaction_id"
},
{
"sourceKeys": "properties.conversion_source",
"destKey": "conversion_source"
},
{
"sourceKeys": "timestamp",
"sourceFromGenericMap": true,
"destKey": "unixtime"
},
{
"sourceKeys": "properties.bidders",
"required": true,
"destKey": "bidders"
}
]
22 changes: 22 additions & 0 deletions src/cdk/v2/destinations/koddi/data/ImpressionsConfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[
{
"sourceKeys": "properties.tracking_data",
"required": true,
"destKey": "trackingData"
},
{
"sourceKeys": "properties.rank",
"required": true,
"destKey": "rank"
},
{
"sourceKeys": "properties.beacon_issued",
"required": true,
"destKey": "beaconIssued"
},
{
"sourceKeys": "timestamp",
"sourceFromGenericMap": true,
"destKey": "ts"
}
]
33 changes: 33 additions & 0 deletions src/cdk/v2/destinations/koddi/procWorkflow.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
bindings:
- name: EventType
path: ../../../../constants
- path: ../../bindings/jsontemplate
- name: removeUndefinedAndNullValues
path: ../../../../v0/util
- path: ./utils
- path: ./config

steps:
- name: messageType
template: |
.message.type.toLowerCase();
- name: eventType
template: |
.message.integrations.koddi.eventType.toLowerCase();
- name: validateInput
template: |
let messageType = $.outputs.messageType;
let eventType = $.outputs.eventType;
$.assert(messageType, "message Type is not present. Aborting message.");
$.assert(messageType in {{$.EventType.([.TRACK])}}, "message type " + messageType + " is not supported");
$.assert(eventType in {{$.EVENT_TYPES.([.IMPRESSIONS, .CLICKS, .CONVERSIONS])}}, "event type " + eventType + " is not supported");
$.assertConfig(.destination.Config.apiBaseUrl, "API Base URL is not present. Aborting");
$.assertConfig(.destination.Config.clientName, "Client Name is not present. Aborting");
- name: preparePayload
template: |
const payload = $.constructFullPayload($.outputs.eventType, .message, .destination.Config);
$.context.payload = $.removeUndefinedAndNullValues(payload);
- name: buildResponse
template: |
const response = $.constructResponse($.outputs.eventType, .destination.Config, $.context.payload);
response
31 changes: 31 additions & 0 deletions src/cdk/v2/destinations/koddi/rtWorkflow.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
bindings:
- name: handleRtTfSingleEventError
path: ../../../../v0/util/index

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]
116 changes: 116 additions & 0 deletions src/cdk/v2/destinations/koddi/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
const { InstrumentationError } = require('@rudderstack/integrations-lib');
const { EVENT_TYPES, IMPRESSIONS_CONFIG, CLICKS_CONFIG, CONVERSIONS_CONFIG } = require('./config');
const {
constructPayload,
defaultRequestConfig,
toUnixTimestamp,
stripTrailingSlash,
} = require('../../../../v0/util');

const validateBidders = (bidders) => {
if (!Array.isArray(bidders)) {
throw new InstrumentationError('properties.bidders should be an array of objects. Aborting.');
}
if (bidders.length === 0) {
throw new InstrumentationError(
'properties.bidders should contains at least one bidder. Aborting.',
);
}
bidders.forEach((bidder) => {
if (!(bidder.bidder || bidder.alternate_bidder)) {
throw new InstrumentationError('bidder or alternate_bidder is not present. Aborting.');
}
if (!bidder.count) {
throw new InstrumentationError('count is not present. Aborting.');
}
if (!bidder.base_price) {
throw new InstrumentationError('base_price is not present. Aborting.');
}
});
};

/**
* This function constructs payloads based upon mappingConfig for all calls.
* @param {*} eventType
* @param {*} message
* @param {*} Config
* @returns
*/
const constructFullPayload = (eventType, message, Config) => {
let payload;
switch (eventType) {
case EVENT_TYPES.IMPRESSIONS:
payload = constructPayload(message, IMPRESSIONS_CONFIG);
payload.clientName = Config.clientName;
break;
case EVENT_TYPES.CLICKS:
payload = constructPayload(message, CLICKS_CONFIG);
payload.clientName = Config.clientName;
if (!Config.testVersionOverride) {
payload.testVersionOverride = null;
}
if (!Config.overrides) {
payload.overrides = null;
}
break;
case EVENT_TYPES.CONVERSIONS:
payload = constructPayload(message, CONVERSIONS_CONFIG);
payload.client_name = Config.clientName;
payload.unixtime = toUnixTimestamp(payload.unixtime);
validateBidders(payload.bidders);
break;
default:
throw new InstrumentationError(`event type ${eventType} is not supported.`);
}
return payload;
};

const getEndpoint = (eventType, Config) => {
let endpoint = stripTrailingSlash(Config.apiBaseUrl);
switch (eventType) {
case EVENT_TYPES.IMPRESSIONS:
endpoint += '?action=impression';
break;
case EVENT_TYPES.CLICKS:
endpoint += '?action=click';
break;
case EVENT_TYPES.CONVERSIONS:
endpoint += '/conversion';
break;
default:
throw new InstrumentationError(`event type ${eventType} is not supported.`);
}
return endpoint;
};

/**
* This function constructs response based upon event.
* @param {*} eventType
* @param {*} Config
* @param {*} payload
* @returns
*/
const constructResponse = (eventType, Config, payload) => {
if (!Object.values(EVENT_TYPES).includes(eventType)) {
throw new InstrumentationError(`event type ${eventType} is not supported.`);
}
const response = defaultRequestConfig();
response.endpoint = getEndpoint(eventType, Config);
response.headers = {
accept: 'application/json',
};
if (eventType === EVENT_TYPES.CONVERSIONS) {
response.body.JSON = payload;
response.method = 'POST';
response.headers = {
...response.headers,
'content-type': 'application/json',
};
} else {
response.params = payload;
response.method = 'GET';
}
return response;
};

module.exports = { getEndpoint, validateBidders, constructFullPayload, constructResponse };
Loading

0 comments on commit 83bd3e7

Please sign in to comment.