Skip to content

Commit

Permalink
chore: purchase event implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
aanshi07 committed Dec 9, 2024
1 parent 35b10f8 commit 11a7fc7
Show file tree
Hide file tree
Showing 5 changed files with 233 additions and 81 deletions.
7 changes: 4 additions & 3 deletions src/v0/destinations/topsort/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ const { getMappingConfig } = require('../../util');

const BASE_URL = 'https://api.topsort.com/v2/events';

const ConfigCategories = {
const ConfigCategory = {
TRACK: {
type: 'track',
name: 'TopsortTrackConfig',
},
PLACEMENT: { name: 'TopsortPlacementConfig' },
ITEM: { name: 'TopsortItemConfig' },
PURCHASE_ITEM: { name: 'TopSortPurchaseProductConfig' },
};

const ECOMM_EVENTS_WITH_PRODUCT_ARRAY = [
Expand All @@ -20,11 +21,11 @@ const ECOMM_EVENTS_WITH_PRODUCT_ARRAY = [
'Order Cancelled',
];

const mappingConfig = getMappingConfig(ConfigCategories, __dirname);
const mappingConfig = getMappingConfig(ConfigCategory, __dirname);

module.exports = {
mappingConfig,
ConfigCategories,
ConfigCategory,
BASE_URL,
ECOMM_EVENTS_WITH_PRODUCT_ARRAY,
};
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[
{
"destKey": "productId",
"sourceKeys": ["productId", "properties.productId"]
"sourceKeys": ["product_id", "properties.product_id"]
},
{
"destKey": "unitPrice",
Expand Down
4 changes: 2 additions & 2 deletions src/v0/destinations/topsort/data/TopsortTrackConfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
"required": true
},
{
"destKey": "anonymousId",
"sourceKeys": "opaqueUserId",
"destKey": "opaqueUserId",
"sourceKeys": "anonymousId",
"required": true
},
{
Expand Down
86 changes: 31 additions & 55 deletions src/v0/destinations/topsort/transform.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,58 +3,22 @@ const {
ConfigurationError,
getHashFromArray,
} = require('@rudderstack/integrations-lib');
const { ConfigCategory, mappingConfig, ECOMM_EVENTS_WITH_PRODUCT_ARRAY } = require('./config');
const { mappingConfig, ECOMM_EVENTS_WITH_PRODUCT_ARRAY, ConfigCategory } = require('./config');
const { constructPayload, simpleProcessRouterDest } = require('../../util');
const {
constructItemPayloads,
createEventData,
isProductArrayValid,
getMappedEventName,
addFinalPayload,
processImpressionsAndClicksUtility,
processPurchaseEventUtility,
} = require('./utils');

// Function to process events with a product array
const processProductArray = ({
products,
basePayload,
placementPayload,
topsortEvent,
finalPayloads,
}) => {
const itemPayloads = constructItemPayloads(products, mappingConfig[ConfigCategory.ITEM.name]);
itemPayloads.forEach((itemPayload) => {
const eventData = createEventData(basePayload, placementPayload, itemPayload, topsortEvent);
addFinalPayload(eventData, finalPayloads);
});
};

// Function to process events with a single product or no product data
const processSingleProduct = ({
basePayload,
placementPayload,
message,
topsortEvent,
finalPayloads,
messageId,
}) => {
const itemPayload = constructPayload(message, mappingConfig[ConfigCategory.ITEM.name]);
const eventData = createEventData(basePayload, placementPayload, itemPayload, topsortEvent);

// Ensure messageId is used instead of generating a UUID for single product events
eventData.data.id = messageId;

// Add final payload with appropriate ID and other headers
addFinalPayload(eventData, finalPayloads);
};

const responseBuilder = (message, { Config }) => {
const { topsortEvents } = Config;
const { event, properties } = message;
const { products, messageId } = properties;
const { products } = properties;

// Parse Topsort event mappings
const parsedTopsortEventMappings = getHashFromArray(topsortEvents);
const mappedEventName = getMappedEventName(parsedTopsortEventMappings, event);
const mappedEventName = getMappedEventName(getHashFromArray(topsortEvents), event);

if (!mappedEventName) {
throw new InstrumentationError("Event not mapped in 'topsortEvents'. Dropping the event.");

Check warning on line 24 in src/v0/destinations/topsort/transform.js

View check run for this annotation

Codecov / codecov/patch

src/v0/destinations/topsort/transform.js#L24

Added line #L24 was not covered by tests
Expand All @@ -64,32 +28,44 @@ const responseBuilder = (message, { Config }) => {

// Construct base and placement payloads
const basePayload = constructPayload(message, mappingConfig[ConfigCategory.TRACK.name]);
const placementPayload = constructPayload(message, mappingConfig[ConfigCategory.PLACEMENT.name]);

// Check if the event involves a product array (using ECOMM_EVENTS_WITH_PRODUCT_ARRAY)
const isProductArrayAvailable =
ECOMM_EVENTS_WITH_PRODUCT_ARRAY.includes(event) && isProductArrayValid(event, properties);

const finalPayloads = [];
const finalPayloads = {
impressions: [],
clicks: [],
purchases: [],
};

const commonArgs = {
basePayload,
placementPayload,
topsortEventName,
finalPayloads,
products,
message,
isProductArrayAvailable:
ECOMM_EVENTS_WITH_PRODUCT_ARRAY.includes(event) && isProductArrayValid(event, properties),
};

if (isProductArrayAvailable) {
processProductArray({
// Process events based on type and construct payload within each logic block
if (topsortEventName === 'impressions' || topsortEventName === 'clicks') {
const placementPayload = constructPayload(

Check warning on line 50 in src/v0/destinations/topsort/transform.js

View check run for this annotation

Codecov / codecov/patch

src/v0/destinations/topsort/transform.js#L50

Added line #L50 was not covered by tests
message,
mappingConfig[ConfigCategory.PLACEMENT.name],
);
processImpressionsAndClicksUtility.processImpressionsAndClicks({

Check warning on line 54 in src/v0/destinations/topsort/transform.js

View check run for this annotation

Codecov / codecov/patch

src/v0/destinations/topsort/transform.js#L54

Added line #L54 was not covered by tests
...commonArgs,
products, // Directly use destructured products
placementPayload, // Only pass placementPayload for impressions and clicks
});
} else {
processSingleProduct({
...commonArgs,
} else if (topsortEventName === 'purchases') {
const purchasePayload = constructPayload(

Check warning on line 59 in src/v0/destinations/topsort/transform.js

View check run for this annotation

Codecov / codecov/patch

src/v0/destinations/topsort/transform.js#L59

Added line #L59 was not covered by tests
message,
messageId, // Add 'messageId' for single product event
mappingConfig[ConfigCategory.PURCHASE_ITEM.name],
);
processPurchaseEventUtility.processPurchaseEvent({

Check warning on line 63 in src/v0/destinations/topsort/transform.js

View check run for this annotation

Codecov / codecov/patch

src/v0/destinations/topsort/transform.js#L63

Added line #L63 was not covered by tests
...commonArgs,
purchasePayload, // Only pass purchasePayload for purchase events
});
} else {
throw new InstrumentationError(`Unknown event type: ${topsortEventName}`);
}

return finalPayloads;

Check warning on line 71 in src/v0/destinations/topsort/transform.js

View check run for this annotation

Codecov / codecov/patch

src/v0/destinations/topsort/transform.js#L71

Added line #L71 was not covered by tests
Expand Down
Loading

0 comments on commit 11a7fc7

Please sign in to comment.