diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
new file mode 100644
index 0000000000..5b716b7e9f
--- /dev/null
+++ b/.github/pull_request_template.md
@@ -0,0 +1,57 @@
+## What are the changes introduced in this PR?
+
+Write a brief explainer on your code changes.
+
+## Please explain the objectives of your changes below
+
+Put down any required details on the broader aspect of your changes. If there are any dependent changes, **mandatorily** mention them here
+
+### Type of change
+
+If the pull request is a **bug-fix**, **enhancement** or a **refactor**, please fill in the details on the changes made.
+
+- Existing capabilities/behavior
+
+- New capabilities/behavior
+
+If the pull request is a **new feature**,
+
+### Any technical or performance related pointers to consider with the change?
+
+N/A
+
+### Any new dependencies introduced with this change?
+
+N/A
+
+### Any new generic utility introduced or modified. Please explain the changes.
+
+N/A
+
+### If the PR has changes in more than 10 files, please mention why the changes were not split into multiple PRs.
+
+N/A
+
+### If multiple linear tasks are associated with the PR changes, please elaborate on the reason:
+
+N/A
+
+
+
+### Developer checklist
+
+- [ ] **No breaking changes are being introduced.**
+
+- [ ] Are all related docs linked with the PR?
+
+- [ ] Are all changes manually tested?
+
+- [ ] Does this change require any documentation changes?
+
+- [ ] Are relevant unit and component test-cases added?
+
+### Reviewer checklist
+
+- [ ] Is the type of change in the PR title appropriate as per the changes?
+
+- [ ] Verified that there are no credentials or confidential data exposed with the changes.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8f990fe3b9..b769b51a6d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,48 @@
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
+### [1.51.1](https://github.com/rudderlabs/rudder-transformer/compare/v1.51.0...v1.51.1) (2023-12-06)
+
+
+### Bug Fixes
+
+* marketo backward compatibility ([#2880](https://github.com/rudderlabs/rudder-transformer/issues/2880)) ([af6aebb](https://github.com/rudderlabs/rudder-transformer/commit/af6aebba9a9891fadc91fe2dc4ae4db4b1e269c9))
+* marketo new field introduction backward compatibility ([cd6c3b0](https://github.com/rudderlabs/rudder-transformer/commit/cd6c3b0672a0b17078627f28f6613a2ef1898ee7))
+* remove ErrorResponse type from postTransfomration delivery ([b13f0a6](https://github.com/rudderlabs/rudder-transformer/commit/b13f0a6340177a56417692ad7dcf3829d4990826))
+
+## [1.51.0](https://github.com/rudderlabs/rudder-transformer/compare/v1.50.1...v1.51.0) (2023-12-06)
+
+
+### Features
+
+* cm360 router batching ([#2836](https://github.com/rudderlabs/rudder-transformer/issues/2836)) ([4b260e4](https://github.com/rudderlabs/rudder-transformer/commit/4b260e4ec6d25875903830004b3e4975b3402b2d))
+* cm360 transformerproxy V1 flag ([#2848](https://github.com/rudderlabs/rudder-transformer/issues/2848)) ([27f0797](https://github.com/rudderlabs/rudder-transformer/commit/27f0797c6dcd626a713c11a48c6e85a69e0a4963))
+* **INT-305:** onboard gladly destination ([#2786](https://github.com/rudderlabs/rudder-transformer/issues/2786)) ([ff80b88](https://github.com/rudderlabs/rudder-transformer/commit/ff80b885fe0507c137b3c9eacffcef331010da0c))
+* marketo: migrate config fields and fix test cases ([#2789](https://github.com/rudderlabs/rudder-transformer/issues/2789)) ([7910dba](https://github.com/rudderlabs/rudder-transformer/commit/7910dba2318f92cec3be1b7c7aa6b00428ecae94))
+* mixpanel set once feature onboard ([#2820](https://github.com/rudderlabs/rudder-transformer/issues/2820)) ([9eda50e](https://github.com/rudderlabs/rudder-transformer/commit/9eda50e850c5a1ccb46f1b54c3d176edb915eb27))
+* onboard webhook to component tests ([#2837](https://github.com/rudderlabs/rudder-transformer/issues/2837)) ([284d141](https://github.com/rudderlabs/rudder-transformer/commit/284d1411514c26dda2403a4a18967e5f40e255ea))
+* update facebook destinations API version to v18.0 ([#2828](https://github.com/rudderlabs/rudder-transformer/issues/2828)) ([3127a1c](https://github.com/rudderlabs/rudder-transformer/commit/3127a1ca8dc1b887f9158a1d839c5504f40c4678))
+
+
+### Bug Fixes
+
+* add support for custom properties for braze purchase events ([#2856](https://github.com/rudderlabs/rudder-transformer/issues/2856)) ([be6ef26](https://github.com/rudderlabs/rudder-transformer/commit/be6ef2605f04e9182534b9633eeec1091cf7a431))
+* bugsnag issue in moengage identify event ([#2845](https://github.com/rudderlabs/rudder-transformer/issues/2845)) ([0e7adc6](https://github.com/rudderlabs/rudder-transformer/commit/0e7adc66ff88d9510e48a5651460b4e02cc57c78))
+* encode &, < and > to html counterparts in adobe analytics ([#2854](https://github.com/rudderlabs/rudder-transformer/issues/2854)) ([571dbf5](https://github.com/rudderlabs/rudder-transformer/commit/571dbf5bd65e7d0e261562ff3da3b393f27f27b6))
+* error handling in active_campaign ([#2843](https://github.com/rudderlabs/rudder-transformer/issues/2843)) ([a015460](https://github.com/rudderlabs/rudder-transformer/commit/a015460f0a6d2d5320f633abc151febf22561b6b))
+* make supportTransformerProxyV1 false ([#2861](https://github.com/rudderlabs/rudder-transformer/issues/2861)) ([80cf69d](https://github.com/rudderlabs/rudder-transformer/commit/80cf69dc40bb4dc7c0a6d516814f36d962018745))
+* remove errorCategory for braze dedup error ([#2850](https://github.com/rudderlabs/rudder-transformer/issues/2850)) ([91d4cd1](https://github.com/rudderlabs/rudder-transformer/commit/91d4cd16f9839b0be5a663ca5010bdd72cff9bdc))
+* sfmc bug fix for track event validations ([#2852](https://github.com/rudderlabs/rudder-transformer/issues/2852)) ([cd9a046](https://github.com/rudderlabs/rudder-transformer/commit/cd9a046f66eab8363373cb9a0fa1afeef3137d78))
+* unhandled error code in facebook_custom_audience ([#2853](https://github.com/rudderlabs/rudder-transformer/issues/2853)) ([8c02b8c](https://github.com/rudderlabs/rudder-transformer/commit/8c02b8ccb2101147ac84b4555e7fd07235ebf9fc))
+* updated transformerProxyV1 name ([#2859](https://github.com/rudderlabs/rudder-transformer/issues/2859)) ([1a8d825](https://github.com/rudderlabs/rudder-transformer/commit/1a8d825ccbb87d34d8ae5ff2cb02f4be9700eee6))
+
+### [1.50.1](https://github.com/rudderlabs/rudder-transformer/compare/v1.50.0...v1.50.1) (2023-12-05)
+
+
+### Bug Fixes
+
+* salesforce transformer proxy response handling issue for authorization flow ([#2873](https://github.com/rudderlabs/rudder-transformer/issues/2873)) ([4cec65e](https://github.com/rudderlabs/rudder-transformer/commit/4cec65e4103e99021f5108fcc7c557b952f1c5eb))
+
## [1.50.0](https://github.com/rudderlabs/rudder-transformer/compare/v1.49.1...v1.50.0) (2023-11-13)
diff --git a/package-lock.json b/package-lock.json
index 4f83954e5b..27655f81ef 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "rudder-transformer",
- "version": "1.50.0",
+ "version": "1.51.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "rudder-transformer",
- "version": "1.50.0",
+ "version": "1.51.1",
"license": "ISC",
"dependencies": {
"@amplitude/ua-parser-js": "^0.7.24",
diff --git a/package.json b/package.json
index 8a8b6177bd..a36ac26e9c 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "rudder-transformer",
- "version": "1.50.0",
+ "version": "1.51.1",
"description": "",
"homepage": "https://github.com/rudderlabs/rudder-transformer#readme",
"bugs": {
diff --git a/src/cdk/v2/destinations/tiktok_audience/rtWorkflow.yaml b/src/cdk/v2/destinations/tiktok_audience/rtWorkflow.yaml
index 3db4c405ad..a7fa855938 100644
--- a/src/cdk/v2/destinations/tiktok_audience/rtWorkflow.yaml
+++ b/src/cdk/v2/destinations/tiktok_audience/rtWorkflow.yaml
@@ -13,7 +13,6 @@ steps:
loopOverInput: true
- name: successfulEvents
- debug: true
template: |
$.outputs.transform#idx{"output" in .}.({
"batchedRequest": .output,
diff --git a/src/services/destination/postTransformation.ts b/src/services/destination/postTransformation.ts
index 1e99961045..0b91eb7cc1 100644
--- a/src/services/destination/postTransformation.ts
+++ b/src/services/destination/postTransformation.ts
@@ -16,15 +16,6 @@ import { ErrorReportingService } from '../errorReporting';
import tags from '../../v0/util/tags';
import stats from '../../util/stats';
-type ErrorResponse = {
- status?: number;
- message?: string;
- destinationResponse?: object;
- statTags?: object;
- authErrorCategory?: string | undefined;
- response?: object | undefined;
-};
-
export class DestinationPostTransformationService {
public static handleProcessorTransformSucessEvents(
event: ProcessorTransformationRequest,
@@ -148,7 +139,7 @@ export class DestinationPostTransformationService {
}
public static handleDeliveryFailureEvents(
- error: ErrorResponse,
+ error: NonNullable,
metaTo: MetaTransferObject,
): DeliveryResponse {
const errObj = generateErrorObject(error, metaTo.errorDetails, false);
@@ -161,12 +152,6 @@ export class DestinationPostTransformationService {
authErrorCategory: errObj.authErrorCategory,
}),
} as DeliveryResponse;
-
- // for transformer-proxy to maintain contract
- const { response } = error;
- if (response) {
- resp.response = response;
- }
ErrorReportingService.reportError(error, metaTo.errorContext, resp);
return resp;
}
diff --git a/src/util/prometheus.js b/src/util/prometheus.js
index 116f77d214..ec8ad61789 100644
--- a/src/util/prometheus.js
+++ b/src/util/prometheus.js
@@ -487,6 +487,12 @@ class Prometheus {
type: 'counter',
labelNames: ['type', 'writeKey', 'source'],
},
+ {
+ name: 'shopify_anon_id_resolve',
+ help: 'shopify_anon_id_resolve',
+ type: 'counter',
+ labelNames: ['method', 'writeKey', 'shopifyTopic'],
+ },
{
name: 'shopify_redis_calls',
help: 'shopify_redis_calls',
diff --git a/src/v0/destinations/braze/braze.util.test.js b/src/v0/destinations/braze/braze.util.test.js
index eb5a46fe34..9859e16152 100644
--- a/src/v0/destinations/braze/braze.util.test.js
+++ b/src/v0/destinations/braze/braze.util.test.js
@@ -1219,4 +1219,145 @@ describe('getPurchaseObjs', () => {
);
}
});
+
+ test('products having extra properties', () => {
+ const output = getPurchaseObjs(
+ {
+ properties: {
+ products: [
+ { product_id: '123', price: 10.99, quantity: 2, random_extra_property_a: 'abc' },
+ { product_id: '456', price: 5.49, quantity: 1, random_extra_property_b: 'efg' },
+ {
+ product_id: '789',
+ price: 15.49,
+ quantity: 1,
+ random_extra_property_a: 'abc',
+ random_extra_property_b: 'efg',
+ random_extra_property_c: 'hij',
+ },
+ ],
+ currency: 'USD',
+ },
+ timestamp: '2023-08-04T12:34:56Z',
+ anonymousId: 'abc',
+ },
+ {
+ sendPurchaseEventWithExtraProperties: true,
+ },
+ );
+ expect(output).toEqual([
+ {
+ product_id: '123',
+ price: 10.99,
+ currency: 'USD',
+ quantity: 2,
+ time: '2023-08-04T12:34:56Z',
+ properties: {
+ random_extra_property_a: 'abc',
+ },
+ _update_existing_only: false,
+ user_alias: {
+ alias_name: 'abc',
+ alias_label: 'rudder_id',
+ },
+ },
+ {
+ product_id: '456',
+ price: 5.49,
+ currency: 'USD',
+ quantity: 1,
+ time: '2023-08-04T12:34:56Z',
+ properties: {
+ random_extra_property_b: 'efg',
+ },
+ _update_existing_only: false,
+ user_alias: {
+ alias_name: 'abc',
+ alias_label: 'rudder_id',
+ },
+ },
+ {
+ product_id: '789',
+ price: 15.49,
+ currency: 'USD',
+ quantity: 1,
+ time: '2023-08-04T12:34:56Z',
+ properties: {
+ random_extra_property_a: 'abc',
+ random_extra_property_b: 'efg',
+ random_extra_property_c: 'hij',
+ },
+ _update_existing_only: false,
+ user_alias: {
+ alias_name: 'abc',
+ alias_label: 'rudder_id',
+ },
+ },
+ ]);
+ });
+
+ test('products having extra properties with sendPurchaseEventWithExtraProperties as false', () => {
+ const output = getPurchaseObjs(
+ {
+ properties: {
+ products: [
+ { product_id: '123', price: 10.99, quantity: 2, random_extra_property_a: 'abc' },
+ { product_id: '456', price: 5.49, quantity: 1, random_extra_property_b: 'efg' },
+ {
+ product_id: '789',
+ price: 15.49,
+ quantity: 1,
+ random_extra_property_a: 'abc',
+ random_extra_property_b: 'efg',
+ random_extra_property_c: 'hij',
+ },
+ ],
+ currency: 'USD',
+ },
+ timestamp: '2023-08-04T12:34:56Z',
+ anonymousId: 'abc',
+ },
+ {
+ sendPurchaseEventWithExtraProperties: false,
+ },
+ );
+ expect(output).toEqual([
+ {
+ product_id: '123',
+ price: 10.99,
+ currency: 'USD',
+ quantity: 2,
+ time: '2023-08-04T12:34:56Z',
+ _update_existing_only: false,
+ user_alias: {
+ alias_name: 'abc',
+ alias_label: 'rudder_id',
+ },
+ },
+ {
+ product_id: '456',
+ price: 5.49,
+ currency: 'USD',
+ quantity: 1,
+ time: '2023-08-04T12:34:56Z',
+ _update_existing_only: false,
+ user_alias: {
+ alias_name: 'abc',
+ alias_label: 'rudder_id',
+ },
+ },
+ {
+ product_id: '789',
+ price: 15.49,
+ currency: 'USD',
+ quantity: 1,
+ time: '2023-08-04T12:34:56Z',
+ _update_existing_only: false,
+ user_alias: {
+ alias_name: 'abc',
+ alias_label: 'rudder_id',
+ },
+ },
+ ]);
+ });
});
diff --git a/src/v0/destinations/braze/config.js b/src/v0/destinations/braze/config.js
index 2e24f43f61..2bbade2754 100644
--- a/src/v0/destinations/braze/config.js
+++ b/src/v0/destinations/braze/config.js
@@ -56,6 +56,7 @@ const BRAZE_NON_BILLABLE_ATTRIBUTES = [
'subscription_groups',
];
+const BRAZE_PURCHASE_STANDARD_PROPERTIES = ['product_id', 'sku', 'price', 'quantity', 'currency'];
module.exports = {
ConfigCategory,
mappingConfig,
@@ -64,6 +65,7 @@ module.exports = {
getSubscriptionGroupEndPoint,
getAliasMergeEndPoint,
BRAZE_PARTNER_NAME,
+ BRAZE_PURCHASE_STANDARD_PROPERTIES,
TRACK_BRAZE_MAX_REQ_COUNT,
IDENTIFY_BRAZE_MAX_REQ_COUNT,
DESTINATION,
@@ -71,5 +73,5 @@ module.exports = {
DEL_MAX_BATCH_SIZE,
BRAZE_NON_BILLABLE_ATTRIBUTES,
ALIAS_BRAZE_MAX_REQ_COUNT,
- SUBSCRIPTION_BRAZE_MAX_REQ_COUNT
+ SUBSCRIPTION_BRAZE_MAX_REQ_COUNT,
};
diff --git a/src/v0/destinations/braze/transform.js b/src/v0/destinations/braze/transform.js
index b939e1f414..38a5947ded 100644
--- a/src/v0/destinations/braze/transform.js
+++ b/src/v0/destinations/braze/transform.js
@@ -315,7 +315,7 @@ function processTrackEvent(messageType, message, destination, mappingJson, proce
typeof eventName === 'string' &&
eventName.toLowerCase() === 'order completed'
) {
- const purchaseObjs = getPurchaseObjs(message);
+ const purchaseObjs = getPurchaseObjs(message, destination.Config);
// del used properties
delete properties.products;
diff --git a/src/v0/destinations/braze/util.js b/src/v0/destinations/braze/util.js
index 9b5d57d6bc..3b0855b338 100644
--- a/src/v0/destinations/braze/util.js
+++ b/src/v0/destinations/braze/util.js
@@ -21,6 +21,7 @@ const {
SUBSCRIPTION_BRAZE_MAX_REQ_COUNT,
ALIAS_BRAZE_MAX_REQ_COUNT,
TRACK_BRAZE_MAX_REQ_COUNT,
+ BRAZE_PURCHASE_STANDARD_PROPERTIES,
} = require('./config');
const { JSON_MIME_TYPE, HTTP_STATUS_CODES } = require('../../util/constant');
const { isObject } = require('../../util');
@@ -539,7 +540,7 @@ function addMandatoryPurchaseProperties(productId, price, currencyCode, quantity
};
}
-function getPurchaseObjs(message) {
+function getPurchaseObjs(message, config) {
// ref:https://www.braze.com/docs/api/objects_filters/purchase_object/
const validateForPurchaseEvent = (message) => {
const { properties } = message;
@@ -634,6 +635,10 @@ function getPurchaseObjs(message) {
parseInt(quantity, 10),
timestamp,
);
+ const extraProperties = _.omit(product, BRAZE_PURCHASE_STANDARD_PROPERTIES);
+ if (Object.keys(extraProperties).length > 0 && config.sendPurchaseEventWithExtraProperties) {
+ purchaseObj = { ...purchaseObj, properties: extraProperties };
+ }
purchaseObj = setExternalIdOrAliasObject(purchaseObj, message);
purchaseObjs.push(purchaseObj);
});
diff --git a/src/v0/destinations/marketo/config.js b/src/v0/destinations/marketo/config.js
index 16449ebbad..604be41dc0 100644
--- a/src/v0/destinations/marketo/config.js
+++ b/src/v0/destinations/marketo/config.js
@@ -14,24 +14,18 @@ const DESTINATION = 'marketo';
const formatConfig = (destination) => ({
ID: destination.ID,
...destination.Config,
- customActivityEventMap: getHashFromArray(
- destination.Config.rudderEventsMapping,
- 'event',
- 'marketoActivityId',
- false,
- ),
+ customActivityEventMap: destination.Config?.rudderEventsMapping
+ ? getHashFromArray(destination.Config.rudderEventsMapping, 'event', 'marketoActivityId', false)
+ : getHashFromArray(destination.Config.customActivityEventMap, 'from', 'to', false),
customActivityPropertyMap: getHashFromArray(
destination.Config.customActivityPropertyMap,
'from',
'to',
false,
),
- customActivityPrimaryKeyMap: getHashFromArray(
- destination.Config.rudderEventsMapping,
- 'event',
- 'marketoPrimarykey',
- false,
- ),
+ customActivityPrimaryKeyMap: destination.Config?.rudderEventsMapping
+ ? getHashFromArray(destination.Config.rudderEventsMapping, 'event', 'marketoPrimarykey', false)
+ : getHashFromArray(destination.Config.customActivityPrimaryKeyMap, 'from', 'to', false),
leadTraitMapping: getHashFromArray(destination.Config.leadTraitMapping, 'from', 'to', false),
responseRules: destination.DestinationDefinition
? destination.DestinationDefinition.ResponseRules
diff --git a/src/v0/destinations/salesforce/networkHandler.js b/src/v0/destinations/salesforce/networkHandler.js
index 622d2ae731..dc67aff1b7 100644
--- a/src/v0/destinations/salesforce/networkHandler.js
+++ b/src/v0/destinations/salesforce/networkHandler.js
@@ -1,5 +1,6 @@
const { proxyRequest, prepareProxyRequest } = require('../../../adapters/network');
const { processAxiosResponse } = require('../../../adapters/utils/networkUtils');
+const { LEGACY } = require('./config');
const { salesforceResponseHandler } = require('./utils');
const responseHandler = (destinationResponse, destType) => {
@@ -9,6 +10,7 @@ const responseHandler = (destinationResponse, destType) => {
destinationResponse,
'during Salesforce Response Handling',
destinationResponse?.rudderJobMetadata?.destInfo?.authKey,
+ LEGACY
);
// else successfully return status as 200, message and original destination response
diff --git a/src/v0/destinations/salesforce/utils.js b/src/v0/destinations/salesforce/utils.js
index c725ec3b20..96735ecc17 100644
--- a/src/v0/destinations/salesforce/utils.js
+++ b/src/v0/destinations/salesforce/utils.js
@@ -33,16 +33,21 @@ const salesforceResponseHandler = (destResponse, sourceMessage, authKey, authori
const matchErrorCode = (errorCode) =>
response && Array.isArray(response) && response.some((resp) => resp?.errorCode === errorCode);
if (status === 401 && authKey && matchErrorCode('INVALID_SESSION_ID')) {
- if (authorizationFlow === LEGACY) {
- // checking for invalid/expired token errors and evicting cache in that case
- // rudderJobMetadata contains some destination info which is being used to evict the cache
- ACCESS_TOKEN_CACHE.del(authKey);
+ if (authorizationFlow === OAUTH) {
+ throw new RetryableError(
+ `${DESTINATION} Request Failed - due to "INVALID_SESSION_ID", (Retryable) ${sourceMessage}`,
+ 500,
+ destResponse,
+ getAuthErrCategoryFromStCode(status),
+ );
}
+ // checking for invalid/expired token errors and evicting cache in that case
+ // rudderJobMetadata contains some destination info which is being used to evict the cache
+ ACCESS_TOKEN_CACHE.del(authKey);
throw new RetryableError(
`${DESTINATION} Request Failed - due to "INVALID_SESSION_ID", (Retryable) ${sourceMessage}`,
500,
destResponse,
- authorizationFlow === LEGACY ? '' : getAuthErrCategoryFromStCode(status),
);
} else if (status === 403 && matchErrorCode('REQUEST_LIMIT_EXCEEDED')) {
// If the error code is REQUEST_LIMIT_EXCEEDED, you’ve exceeded API request limits in your org.
diff --git a/src/v0/destinations/salesforce_oauth/networkHandler.js b/src/v0/destinations/salesforce_oauth/networkHandler.js
new file mode 100644
index 0000000000..2042830cb1
--- /dev/null
+++ b/src/v0/destinations/salesforce_oauth/networkHandler.js
@@ -0,0 +1,33 @@
+const { proxyRequest, prepareProxyRequest } = require('../../../adapters/network');
+const { processAxiosResponse } = require('../../../adapters/utils/networkUtils');
+const { OAUTH } = require('../salesforce/config');
+const { salesforceResponseHandler } = require('../salesforce/utils');
+
+const responseHandler = (destinationResponse, destType) => {
+ const message = `Request for destination: ${destType} Processed Successfully`;
+
+ salesforceResponseHandler(
+ destinationResponse,
+ 'during Salesforce Response Handling',
+ destinationResponse?.rudderJobMetadata?.destInfo?.authKey,
+ OAUTH
+ );
+
+ // else successfully return status as 200, message and original destination response
+ return {
+ status: 200,
+ message,
+ destinationResponse,
+ };
+};
+
+function networkHandler() {
+ this.responseHandler = responseHandler;
+ this.proxy = proxyRequest;
+ this.prepareProxy = prepareProxyRequest;
+ this.processAxiosResponse = processAxiosResponse;
+}
+
+module.exports = {
+ networkHandler,
+};
diff --git a/src/v0/sources/shopify/transform.js b/src/v0/sources/shopify/transform.js
index fd763eeb46..013580d7a3 100644
--- a/src/v0/sources/shopify/transform.js
+++ b/src/v0/sources/shopify/transform.js
@@ -175,7 +175,7 @@ const processEvent = async (inputEvent, metricMetadata) => {
if (message.type !== EventType.IDENTIFY) {
const { anonymousId, sessionId } = await getAnonymousIdAndSessionId(
message,
- metricMetadata,
+ { shopifyTopic, ...metricMetadata },
redisData,
);
if (isDefinedAndNotNull(anonymousId)) {
diff --git a/src/v0/sources/shopify/util.js b/src/v0/sources/shopify/util.js
index 61501bdab6..6f31ade4a7 100644
--- a/src/v0/sources/shopify/util.js
+++ b/src/v0/sources/shopify/util.js
@@ -164,6 +164,10 @@ const getAnonymousIdAndSessionId = async (message, metricMetadata, redisData = n
}
// falling back to cartToken mapping or its hash in case no rudderAnonymousId or rudderSessionId is found
if (isDefinedAndNotNull(anonymousId) && isDefinedAndNotNull(sessionId)) {
+ stats.increment('shopify_anon_id_resolve', {
+ method: 'note_attributes',
+ ...metricMetadata,
+ });
return { anonymousId, sessionId };
}
const cartToken = getCartToken(message);
@@ -189,6 +193,13 @@ const getAnonymousIdAndSessionId = async (message, metricMetadata, redisData = n
Hash the id and use it as anonymousId (limiting 256 -> 36 chars) and sessionId is not sent as its not required field
*/
anonymousId = v5(cartToken, v5.URL);
+ } else {
+ // This metric let us know how many events based on event name used redis for anonId resolution
+ // and for how many
+ stats.increment('shopify_anon_id_resolve', {
+ method: 'database',
+ ...metricMetadata,
+ });
}
return { anonymousId, sessionId };
};
diff --git a/test/__tests__/data/braze_input.json b/test/__tests__/data/braze_input.json
index e799cf2e82..8c3294e42b 100644
--- a/test/__tests__/data/braze_input.json
+++ b/test/__tests__/data/braze_input.json
@@ -1814,5 +1814,101 @@
"type": "track",
"userId": "mickeyMouse"
}
+ },
+ {
+ "destination": {
+ "Config": {
+ "restApiKey": "dummyApiKey",
+ "prefixProperties": true,
+ "useNativeSDK": false,
+ "sendPurchaseEventWithExtraProperties": true
+ },
+ "DestinationDefinition": {
+ "DisplayName": "Braze",
+ "ID": "1WhbSZ6uA3H5ChVifHpfL2H6sie",
+ "Name": "BRAZE"
+ },
+ "Enabled": true,
+ "ID": "1WhcOCGgj9asZu850HvugU2C3Aq",
+ "Name": "Braze",
+ "Transformations": []
+ },
+ "message": {
+ "anonymousId": "e6ab2c5e-2cda-44a9-a962-e2f67df78bca",
+ "channel": "web",
+ "context": {
+ "app": {
+ "build": "1.0.0",
+ "name": "RudderLabs JavaScript SDK",
+ "namespace": "com.rudderlabs.javascript",
+ "version": "1.0.5"
+ },
+ "ip": "0.0.0.0",
+ "library": {
+ "name": "RudderLabs JavaScript SDK",
+ "version": "1.0.5"
+ },
+ "locale": "en-GB",
+ "os": {
+ "name": "",
+ "version": ""
+ },
+ "screen": {
+ "density": 2
+ },
+ "traits": {
+ "city": "Disney",
+ "country": "USA",
+ "email": "mickey@disney.com",
+ "firstname": "Mickey"
+ },
+ "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36"
+ },
+ "event": "Order Completed",
+ "integrations": {
+ "All": true
+ },
+ "messageId": "aa5f5e44-8756-40ad-ad1e-b0d3b9fa710a",
+ "originalTimestamp": "2020-01-24T06:29:02.367Z",
+ "properties": {
+ "affiliation": "Google Store",
+ "checkout_id": "fksdjfsdjfisjf9sdfjsd9f",
+ "coupon": "hasbros",
+ "currency": "USD",
+ "discount": 2.5,
+ "order_id": "50314b8e9bcf000000000000",
+ "products": [
+ {
+ "category": "Games",
+ "image_url": "https:///www.example.com/product/path.jpg",
+ "name": "Monopoly: 3rd Edition",
+ "price": 0,
+ "product_id": "507f1f77bcf86cd799439023",
+ "quantity": 1,
+ "sku": "45790-32",
+ "url": "https://www.example.com/product/path"
+ },
+ {
+ "category": "Games",
+ "name": "Uno Card Game",
+ "price": 0,
+ "product_id": "505bd76785ebb509fc183724",
+ "quantity": 2,
+ "sku": "46493-32"
+ }
+ ],
+ "revenue": 25,
+ "shipping": 3,
+ "subtotal": 22.5,
+ "tax": 2,
+ "total": 27.5
+ },
+ "receivedAt": "2020-01-24T11:59:02.403+05:30",
+ "request_ip": "[::1]:53712",
+ "sentAt": "2020-01-24T06:29:02.368Z",
+ "timestamp": "2020-01-24T11:59:02.402+05:30",
+ "type": "track",
+ "userId": ""
+ }
}
]
diff --git a/test/__tests__/data/braze_output.json b/test/__tests__/data/braze_output.json
index 10c42b1064..0575326237 100644
--- a/test/__tests__/data/braze_output.json
+++ b/test/__tests__/data/braze_output.json
@@ -963,5 +963,76 @@
},
"files": {},
"userId": "mickeyMouse"
+ },
+ {
+ "body": {
+ "FORM": {},
+ "JSON": {
+ "attributes": [
+ {
+ "_update_existing_only": false,
+ "city": "Disney",
+ "country": "USA",
+ "email": "mickey@disney.com",
+ "firstname": "Mickey",
+ "user_alias": {
+ "alias_label": "rudder_id",
+ "alias_name": "e6ab2c5e-2cda-44a9-a962-e2f67df78bca"
+ }
+ }
+ ],
+ "partner": "RudderStack",
+ "purchases": [
+ {
+ "_update_existing_only": false,
+ "currency": "USD",
+ "price": 0,
+ "product_id": "507f1f77bcf86cd799439023",
+ "properties": {
+ "category": "Games",
+ "image_url": "https:///www.example.com/product/path.jpg",
+ "name": "Monopoly: 3rd Edition",
+ "url": "https://www.example.com/product/path"
+ },
+ "quantity": 1,
+ "time": "2020-01-24T11:59:02.402+05:30",
+ "user_alias": {
+ "alias_label": "rudder_id",
+ "alias_name": "e6ab2c5e-2cda-44a9-a962-e2f67df78bca"
+ }
+ },
+ {
+ "_update_existing_only": false,
+ "currency": "USD",
+ "price": 0,
+ "product_id": "505bd76785ebb509fc183724",
+ "properties": {
+ "category": "Games",
+ "name": "Uno Card Game"
+ },
+ "quantity": 2,
+ "time": "2020-01-24T11:59:02.402+05:30",
+ "user_alias": {
+ "alias_label": "rudder_id",
+ "alias_name": "e6ab2c5e-2cda-44a9-a962-e2f67df78bca"
+ }
+ }
+ ]
+ },
+ "JSON_ARRAY": {},
+ "XML": {}
+ },
+ "endpoint": "https://rest.fra-01.braze.eu/users/track",
+ "files": {},
+ "headers": {
+ "Accept": "application/json",
+ "Authorization": "Bearer dummyApiKey",
+ "Content-Type": "application/json"
+ },
+ "method": "POST",
+ "params": {},
+ "type": "REST",
+ "userId": "e6ab2c5e-2cda-44a9-a962-e2f67df78bca",
+ "version": "1"
}
]
diff --git a/test/__tests__/data/marketo_input.json b/test/__tests__/data/marketo_input.json
index 6a891fdea0..10fff935fc 100644
--- a/test/__tests__/data/marketo_input.json
+++ b/test/__tests__/data/marketo_input.json
@@ -170,11 +170,16 @@
}
],
"createIfNotExist": true,
- "rudderEventsMapping": [
+ "customActivityPrimaryKeyMap": [
{
- "event": "Product Clicked",
- "marketoPrimarykey": "name",
- "marketoActivityId": "100001"
+ "from": "Product Clicked",
+ "to": "name"
+ }
+ ],
+ "customActivityEventMap": [
+ {
+ "from": "Product Clicked",
+ "to": "100001"
}
]
}
diff --git a/test/integrations/destinations/salesforce/dataDelivery/data.ts b/test/integrations/destinations/salesforce/dataDelivery/data.ts
index c53ce58f9e..2f1e04815b 100644
--- a/test/integrations/destinations/salesforce/dataDelivery/data.ts
+++ b/test/integrations/destinations/salesforce/dataDelivery/data.ts
@@ -119,7 +119,6 @@ export const data = [
body: {
output: {
status: 500,
- authErrorCategory: 'REFRESH_TOKEN',
message:
'Salesforce Request Failed - due to "INVALID_SESSION_ID", (Retryable) during Salesforce Response Handling',
destinationResponse: {