Skip to content

Commit

Permalink
feat: add support of custom page/screen event name in mixpanel (#3098)
Browse files Browse the repository at this point in the history
* feat: add support of custom page/screen event name in mixpanel

* refactor: use handlebars

* test: add testcase for multiple handlebars

* refactor: replace handlebar with regex

* refactor: update error message

* refactor: generatePageOrScreenCustomEventName

* fix: skip event trimming
  • Loading branch information
Gauravudia committed Mar 1, 2024
1 parent aea417c commit 0eb2393
Show file tree
Hide file tree
Showing 4 changed files with 452 additions and 350 deletions.
26 changes: 23 additions & 3 deletions src/v0/destinations/mp/transform.js
Expand Up @@ -36,6 +36,7 @@ const {
groupEventsByEndpoint,
batchEvents,
trimTraits,
generatePageOrScreenCustomEventName,
} = require('./util');
const { CommonUtils } = require('../../../util/common');

Expand Down Expand Up @@ -297,17 +298,25 @@ const processIdentifyEvents = async (message, type, destination) => {
};

const processPageOrScreenEvents = (message, type, destination) => {
const {
token,
identityMergeApi,
useUserDefinedPageEventName,
userDefinedPageEventTemplate,
useUserDefinedScreenEventName,
userDefinedScreenEventTemplate,
} = destination.Config;
const mappedProperties = constructPayload(message, mPEventPropertiesConfigJson);
let properties = {
...get(message, 'context.traits'),
...message.properties,
...mappedProperties,
token: destination.Config.token,
token,
distinct_id: message.userId || message.anonymousId,
time: toUnixTimestampInMS(message.timestamp || message.originalTimestamp),
...buildUtmParams(message.context?.campaign),
};
if (destination.Config?.identityMergeApi === 'simplified') {
if (identityMergeApi === 'simplified') {
properties = {
...properties,
distinct_id: message.userId || `$device:${message.anonymousId}`,
Expand All @@ -326,7 +335,18 @@ const processPageOrScreenEvents = (message, type, destination) => {
properties.$browser = browser.name;
properties.$browser_version = browser.version;
}
const eventName = type === 'page' ? 'Loaded a Page' : 'Loaded a Screen';

let eventName;
if (type === 'page') {
eventName = useUserDefinedPageEventName
? generatePageOrScreenCustomEventName(message, userDefinedPageEventTemplate)
: 'Loaded a Page';
} else {
eventName = useUserDefinedScreenEventName
? generatePageOrScreenCustomEventName(message, userDefinedScreenEventTemplate)
: 'Loaded a Screen';
}

const payload = {
event: eventName,
properties,
Expand Down
44 changes: 43 additions & 1 deletion src/v0/destinations/mp/util.js
@@ -1,7 +1,7 @@
const lodash = require('lodash');
const set = require('set-value');
const get = require('get-value');
const { InstrumentationError } = require('@rudderstack/integrations-lib');
const { InstrumentationError, ConfigurationError } = require('@rudderstack/integrations-lib');
const {
isDefined,
constructPayload,
Expand All @@ -16,6 +16,7 @@ const {
IsGzipSupported,
isObject,
isDefinedAndNotNullAndNotEmpty,
isDefinedAndNotNull,
} = require('../../util');
const {
ConfigCategory,
Expand Down Expand Up @@ -301,6 +302,46 @@ function trimTraits(traits, contextTraits, setOnceProperties) {
};
}

/**
* Generates a custom event name for a page or screen.
*
* @param {Object} message - The message object
* @param {string} userDefinedEventTemplate - The user-defined event template to be used for generating the event name.
* @throws {ConfigurationError} If the event template is missing.
* @returns {string} The generated custom event name.
* @example
* const userDefinedEventTemplate = "Viewed {{ category }} {{ name }} Page";
* const message = {name: 'Home', properties: {category: 'Index'}};
* output: "Viewed Index Home Page"
*/
const generatePageOrScreenCustomEventName = (message, userDefinedEventTemplate) => {
if (!userDefinedEventTemplate) {
throw new ConfigurationError(
'Event name template is not configured. Please provide a valid value for the `Page/Screen Event Name Template` in the destination dashboard.',
);
}

let eventName = userDefinedEventTemplate;

if (isDefinedAndNotNull(message.properties?.category)) {
// Replace {{ category }} with actual values
eventName = eventName.replace(/{{\s*category\s*}}/g, message.properties.category);
} else {
// find {{ category }} surrounded by whitespace characters and replace it with a single whitespace character
eventName = eventName.replace(/\s{{\s*category\s*}}\s/g, ' ');
}

if (isDefinedAndNotNull(message.name)) {
// Replace {{ name }} with actual values
eventName = eventName.replace(/{{\s*name\s*}}/g, message.name);
} else {
// find {{ name }} surrounded by whitespace characters and replace it with a single whitespace character
eventName = eventName.replace(/\s{{\s*name\s*}}\s/g, ' ');
}

return eventName;
};

module.exports = {
createIdentifyResponse,
isImportAuthCredentialsAvailable,
Expand All @@ -309,4 +350,5 @@ module.exports = {
generateBatchedPayloadForArray,
batchEvents,
trimTraits,
generatePageOrScreenCustomEventName,
};

0 comments on commit 0eb2393

Please sign in to comment.