Skip to content

Commit

Permalink
fix: revert mixpanel deprecate /track (#3291)
Browse files Browse the repository at this point in the history
  • Loading branch information
Gauravudia authored Apr 18, 2024
1 parent 9546b9e commit ec068b4
Show file tree
Hide file tree
Showing 8 changed files with 234 additions and 243 deletions.
6 changes: 6 additions & 0 deletions src/util/prometheus.js
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,12 @@ class Prometheus {
type: 'gauge',
labelNames: ['destination_id'],
},
{
name: 'mixpanel_batch_track_pack_size',
help: 'mixpanel_batch_track_pack_size',
type: 'gauge',
labelNames: ['destination_id'],
},
{
name: 'mixpanel_batch_import_pack_size',
help: 'mixpanel_batch_import_pack_size',
Expand Down
2 changes: 2 additions & 0 deletions src/v0/destinations/mp/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ const MP_IDENTIFY_EXCLUSION_LIST = [
];

const GEO_SOURCE_ALLOWED_VALUES = [null, 'reverse_geocoding'];
const TRACK_MAX_BATCH_SIZE = 50;
const IMPORT_MAX_BATCH_SIZE = 2000;
const ENGAGE_MAX_BATCH_SIZE = 2000;
const GROUPS_MAX_BATCH_SIZE = 200;
Expand All @@ -67,6 +68,7 @@ module.exports = {
MP_IDENTIFY_EXCLUSION_LIST,
getCreateDeletionTaskEndpoint,
DISTINCT_ID_MAX_BATCH_SIZE,
TRACK_MAX_BATCH_SIZE,
IMPORT_MAX_BATCH_SIZE,
ENGAGE_MAX_BATCH_SIZE,
GROUPS_MAX_BATCH_SIZE,
Expand Down
70 changes: 46 additions & 24 deletions src/v0/destinations/mp/transform.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const {
mappingConfig,
BASE_ENDPOINT,
BASE_ENDPOINT_EU,
TRACK_MAX_BATCH_SIZE,
IMPORT_MAX_BATCH_SIZE,
ENGAGE_MAX_BATCH_SIZE,
GROUPS_MAX_BATCH_SIZE,
Expand All @@ -46,19 +47,21 @@ const mPEventPropertiesConfigJson = mappingConfig[ConfigCategory.EVENT_PROPERTIE
const setImportCredentials = (destConfig) => {
const endpoint =
destConfig.dataResidency === 'eu' ? `${BASE_ENDPOINT_EU}/import/` : `${BASE_ENDPOINT}/import/`;
const headers = { 'Content-Type': 'application/json' };
const params = { strict: destConfig.strictMode ? 1 : 0 };
const { serviceAccountUserName, serviceAccountSecret, projectId, token } = destConfig;
let credentials;
if (token) {
credentials = `${token}:`;
const { apiSecret, serviceAccountUserName, serviceAccountSecret, projectId } = destConfig;
if (apiSecret) {
headers.Authorization = `Basic ${base64Convertor(`${apiSecret}:`)}`;
} else if (serviceAccountUserName && serviceAccountSecret && projectId) {
credentials = `${serviceAccountUserName}:${serviceAccountSecret}`;
headers.Authorization = `Basic ${base64Convertor(
`${serviceAccountUserName}:${serviceAccountSecret}`,
)}`;
params.projectId = projectId;
} else {
throw new InstrumentationError(
'Event timestamp is older than 5 days and no API secret or service account credentials (i.e. username, secret and projectId) are provided in destination configuration',
);
}
const headers = {
'Content-Type': 'application/json',
Authorization: `Basic ${base64Convertor(credentials)}`,
};
return { endpoint, headers, params };
};

Expand All @@ -67,26 +70,37 @@ const responseBuilderSimple = (payload, message, eventType, destConfig) => {
response.method = defaultPostRequestConfig.requestMethod;
response.userId = message.userId || message.anonymousId;
response.body.JSON_ARRAY = { batch: JSON.stringify([removeUndefinedValues(payload)]) };
const { dataResidency } = destConfig;
const { apiSecret, serviceAccountUserName, serviceAccountSecret, projectId, dataResidency } =
destConfig;
const duration = getTimeDifference(message.timestamp);
switch (eventType) {
case EventType.ALIAS:
case EventType.TRACK:
case EventType.SCREEN:
case EventType.PAGE: {
if (duration.years > 5) {
case EventType.PAGE:
if (
!apiSecret &&
!(serviceAccountUserName && serviceAccountSecret && projectId) &&
duration.days <= 5
) {
response.endpoint =
dataResidency === 'eu' ? `${BASE_ENDPOINT_EU}/track/` : `${BASE_ENDPOINT}/track/`;
response.headers = {};
} else if (duration.years > 5) {
throw new InstrumentationError('Event timestamp should be within last 5 years');
} else {
const credentials = setImportCredentials(destConfig);
response.endpoint = credentials.endpoint;
response.headers = credentials.headers;
response.params = {
project_id: credentials.params?.projectId,
strict: credentials.params.strict,
};
break;
}
const credentials = setImportCredentials(destConfig);
response.endpoint = credentials.endpoint;
response.headers = credentials.headers;
response.params = {
project_id: credentials.params?.projectId,
strict: credentials.params.strict,
};
break;
}
case 'merge': {
case 'merge':
// eslint-disable-next-line no-case-declarations
const credentials = setImportCredentials(destConfig);
response.endpoint = credentials.endpoint;
response.headers = credentials.headers;
Expand All @@ -95,7 +109,7 @@ const responseBuilderSimple = (payload, message, eventType, destConfig) => {
strict: credentials.params.strict,
};
break;
}

default:
response.endpoint =
dataResidency === 'eu' ? `${BASE_ENDPOINT_EU}/engage/` : `${BASE_ENDPOINT}/engage/`;
Expand Down Expand Up @@ -470,6 +484,7 @@ const processRouterDest = async (inputs, reqMetadata) => {
const batchSize = {
engage: 0,
groups: 0,
track: 0,
import: 0,
};

Expand Down Expand Up @@ -501,16 +516,23 @@ const processRouterDest = async (inputs, reqMetadata) => {
);

transformedPayloads = lodash.flatMap(transformedPayloads);
const { engageEvents, groupsEvents, importEvents, batchErrorRespList } =
const { engageEvents, groupsEvents, trackEvents, importEvents, batchErrorRespList } =
groupEventsByEndpoint(transformedPayloads);

const engageRespList = batchEvents(engageEvents, ENGAGE_MAX_BATCH_SIZE, reqMetadata);
const groupsRespList = batchEvents(groupsEvents, GROUPS_MAX_BATCH_SIZE, reqMetadata);
const trackRespList = batchEvents(trackEvents, TRACK_MAX_BATCH_SIZE, reqMetadata);
const importRespList = batchEvents(importEvents, IMPORT_MAX_BATCH_SIZE, reqMetadata);
const batchSuccessRespList = [...engageRespList, ...groupsRespList, ...importRespList];
const batchSuccessRespList = [
...engageRespList,
...groupsRespList,
...trackRespList,
...importRespList,
];

batchSize.engage += engageRespList.length;
batchSize.groups += groupsRespList.length;
batchSize.track += trackRespList.length;
batchSize.import += importRespList.length;

return [...batchSuccessRespList, ...batchErrorRespList];
Expand Down
8 changes: 7 additions & 1 deletion src/v0/destinations/mp/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ const createIdentifyResponse = (message, type, destination, responseBuilderSimpl
* @returns
*/
const isImportAuthCredentialsAvailable = (destination) =>
destination.Config.token ||
destination.Config.apiSecret ||
(destination.Config.serviceAccountSecret &&
destination.Config.serviceAccountUserName &&
destination.Config.projectId);
Expand Down Expand Up @@ -179,6 +179,7 @@ const groupEventsByEndpoint = (events) => {
const eventMap = {
engage: [],
groups: [],
track: [],
import: [],
};
const batchErrorRespList = [];
Expand All @@ -203,6 +204,7 @@ const groupEventsByEndpoint = (events) => {
return {
engageEvents: eventMap.engage,
groupsEvents: eventMap.groups,
trackEvents: eventMap.track,
importEvents: eventMap.import,
batchErrorRespList,
};
Expand Down Expand Up @@ -347,6 +349,7 @@ const generatePageOrScreenCustomEventName = (message, userDefinedEventTemplate)
* @param {Object} batchSize - The object containing the batch size for different endpoints.
* @param {number} batchSize.engage - The batch size for engage endpoint.
* @param {number} batchSize.groups - The batch size for group endpoint.
* @param {number} batchSize.track - The batch size for track endpoint.
* @param {number} batchSize.import - The batch size for import endpoint.
* @param {string} destinationId - The ID of the destination.
* @returns {void}
Expand All @@ -358,6 +361,9 @@ const recordBatchSizeMetrics = (batchSize, destinationId) => {
stats.gauge('mixpanel_batch_group_pack_size', batchSize.groups, {
destination_id: destinationId,
});
stats.gauge('mixpanel_batch_track_pack_size', batchSize.track, {
destination_id: destinationId,
});
stats.gauge('mixpanel_batch_import_pack_size', batchSize.import, {
destination_id: destinationId,
});
Expand Down
14 changes: 14 additions & 0 deletions src/v0/destinations/mp/util.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ describe('Unit test cases for groupEventsByEndpoint', () => {
expect(result).toEqual({
engageEvents: [],
groupsEvents: [],
trackEvents: [],
importEvents: [],
batchErrorRespList: [],
});
Expand Down Expand Up @@ -121,6 +122,19 @@ describe('Unit test cases for groupEventsByEndpoint', () => {
},
},
],
trackEvents: [
{
message: {
endpoint: '/track',
body: {
JSON_ARRAY: {
batch: '[{prop:4}]',
},
},
userId: 'user1',
},
},
],
importEvents: [
{
message: {
Expand Down
2 changes: 1 addition & 1 deletion test/integrations/destinations/mp/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const defaultMockFns = () => {
const sampleDestination: Destination = {
Config: {
apiKey: 'dummyApiKey',
token: 'test_api_token',
token: 'dummyApiKey',
prefixProperties: true,
useNativeSDK: false,
},
Expand Down
Loading

0 comments on commit ec068b4

Please sign in to comment.