Skip to content

Commit

Permalink
Merge branch 'develop' into feat.linkedin_audience
Browse files Browse the repository at this point in the history
  • Loading branch information
ItsSudip authored Nov 13, 2024
2 parents b1244b6 + 640a11e commit 97bd84d
Show file tree
Hide file tree
Showing 40 changed files with 1,539 additions and 307 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/dt-test-and-report-code-coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ jobs:
- name: SonarCloud Scan
if: always()
uses: SonarSource/sonarcloud-github-action@v3.0.0
uses: SonarSource/sonarcloud-github-action@v3.1.0
env:
GITHUB_TOKEN: ${{ secrets.PAT }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
Expand Down
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@

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.83.2](https://github.com/rudderlabs/rudder-transformer/compare/v1.83.1...v1.83.2) (2024-11-05)


### Bug Fixes

* update gaec destination with config validation ([#3847](https://github.com/rudderlabs/rudder-transformer/issues/3847)) ([e5c5b0a](https://github.com/rudderlabs/rudder-transformer/commit/e5c5b0a28070ff5ca89a274c3998b96780139149))

### [1.83.1](https://github.com/rudderlabs/rudder-transformer/compare/v1.83.0...v1.83.1) (2024-11-01)

## [1.83.0](https://github.com/rudderlabs/rudder-transformer/compare/v1.82.2...v1.83.0) (2024-10-25)


Expand Down
25 changes: 14 additions & 11 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "rudder-transformer",
"version": "1.83.0",
"version": "1.83.2",
"description": "",
"homepage": "https://github.com/rudderlabs/rudder-transformer#readme",
"bugs": {
Expand Down Expand Up @@ -64,7 +64,7 @@
"@koa/router": "^12.0.0",
"@ndhoule/extend": "^2.0.0",
"@pyroscope/nodejs": "^0.2.9",
"@rudderstack/integrations-lib": "^0.2.10",
"@rudderstack/integrations-lib": "^0.2.12",
"@rudderstack/json-template-engine": "^0.18.0",
"@rudderstack/workflow-engine": "^0.8.13",
"@shopify/jest-koa-mocks": "^5.1.1",
Expand Down Expand Up @@ -95,7 +95,7 @@
"koa": "^2.15.3",
"koa-bodyparser": "^4.4.0",
"koa2-swagger-ui": "^5.7.0",
"libphonenumber-js": "^1.11.1",
"libphonenumber-js": "^1.11.12",
"lodash": "^4.17.21",
"match-json": "^1.3.5",
"md5": "^2.3.0",
Expand Down Expand Up @@ -152,7 +152,7 @@
"eslint-plugin-unicorn": "^46.0.1",
"glob": "^10.3.3",
"http-terminator": "^3.2.0",
"husky": "^9.1.1",
"husky": "^9.1.6",
"jest": "^29.5.0",
"jest-sonar": "^0.2.16",
"jest-when": "^3.5.2",
Expand Down
6 changes: 2 additions & 4 deletions src/cdk/v2/destinations/linkedin_ads/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ function checkIfPricePresent(properties) {
}

const calculateConversionObject = (message) => {
const { properties, event } = message;
const { properties } = message;

const calculateAmount = () => {
if (properties?.products && properties.products.length > 0) {
Expand All @@ -107,9 +107,7 @@ const calculateConversionObject = (message) => {
};
return conversionObject;
}
throw new InstrumentationError(
`[LinkedIn Conversion API]: Cannot map price for event ${event}. Aborting`,
);
return null;
};

const deduceConversionRules = (trackEventName, destConfig) => {
Expand Down
9 changes: 5 additions & 4 deletions src/cdk/v2/destinations/linkedin_ads/utils.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,13 @@ describe('formatEmail', () => {
});

describe('calculateConversionObject', () => {
// Returns a conversion object with currency code 'USD' and amount 0 when message properties are empty
it('should throw instrumentation error when message properties are empty', () => {
// Returns empty object when message properties are empty
it('should return empty object when message properties are empty', () => {
const message = { properties: {} };
expect(() => {
fetchUserIds(calculateConversionObject(message));
}).toThrow(InstrumentationError);
const conversionObject = calculateConversionObject(message);
expect(conversionObject).toEqual({});
});
});

// Returns a conversion object with currency code 'USD' and amount 0 when message properties price is defined but quantity is 0
Expand Down
6 changes: 1 addition & 5 deletions src/cdk/v2/destinations/pinterest_tag/procWorkflow.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -167,11 +167,7 @@ steps:
"content_ids": (props.product_id ?? props.sku ?? props.id)[],
"contents": {
"quantity": Number(props.quantity) || 1,
"item_price": String(props.price),
"item_name": String(props.name),
"id": props.product_id ?? props.sku,
"item_category": props.category,
"item_brand": props.brand
"item_price": String(props.price)
}[]
};
- name: combineAllEcomFields
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,11 @@ const responseBuilder = async (metadata, message, { Config }, payload) => {
if (isNumber(customerId)) {
customerId = customerId.toString();
}
if (isNumber(loginCustomerId)) {
loginCustomerId = loginCustomerId.toString();
}
if (!isString(customerId) || !isString(loginCustomerId)) {
throw new InstrumentationError('customerId and loginCustomerId should be a string or number');
if (!isString(customerId)) {
throw new InstrumentationError('customerId should be a string or number');
}
const filteredCustomerId = removeHyphens(customerId);

response.endpoint = `${BASE_ENDPOINT}/${filteredCustomerId}:uploadConversionAdjustments`;
response.body.JSON = payload;
const accessToken = getAccessToken(metadata, 'access_token');
Expand All @@ -72,11 +70,19 @@ const responseBuilder = async (metadata, message, { Config }, payload) => {
'developer-token': getValueFromMessage(metadata, 'secret.developer_token'),
};
response.params = { event, customerId: filteredCustomerId };
if (subAccount)
if (loginCustomerId) {
const filteredLoginCustomerId = removeHyphens(loginCustomerId);
response.headers['login-customer-id'] = filteredLoginCustomerId;
} else throw new ConfigurationError(`LoginCustomerId is required as subAccount is true.`);
if (subAccount) {
if (!loginCustomerId) {
throw new ConfigurationError(`loginCustomerId is required as subAccount is true.`);
}
if (isNumber(loginCustomerId)) {
loginCustomerId = loginCustomerId.toString();
}
if (loginCustomerId && !isString(loginCustomerId)) {
throw new InstrumentationError('loginCustomerId should be a string or number');
}
const filteredLoginCustomerId = removeHyphens(loginCustomerId);
response.headers['login-customer-id'] = filteredLoginCustomerId;
}

if (loginCustomerId) {
const filteredLoginCustomerId = removeHyphens(loginCustomerId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const CONFIG_CATEGORIES = {
AUDIENCE_LIST: { type: 'audienceList', name: 'offlineDataJobs' },
ADDRESSINFO: { type: 'addressInfo', name: 'addressInfo' },
};
const ADDRESS_INFO_ATTRIBUTES = ['firstName', 'lastName', 'country', 'postalCode'];
const attributeMapping = {
email: 'hashedEmail',
phone: 'hashedPhoneNumber',
Expand All @@ -31,6 +32,7 @@ module.exports = {
hashAttributes,
offlineDataJobsMapping: MAPPING_CONFIG[CONFIG_CATEGORIES.AUDIENCE_LIST.name],
addressInfoMapping: MAPPING_CONFIG[CONFIG_CATEGORIES.ADDRESSINFO.name],
ADDRESS_INFO_ATTRIBUTES,
consentConfigMap,
destType: 'google_adwords_remarketing_lists',
};
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ const {
isEventSentByVDMV2Flow,
} = require('../../util');
const { populateConsentFromConfig } = require('../../util/googleUtils');
const { populateIdentifiers, responseBuilder, getOperationAudienceId } = require('./util');
const {
populateIdentifiersForRecordEvent,
responseBuilder,
getOperationAudienceId,
} = require('./util');
const { getErrorResponse, createFinalResponse } = require('../../util/recordUtils');
const { offlineDataJobsMapping, consentConfigMap } = require('./config');

Expand All @@ -23,6 +27,7 @@ const processRecordEventArray = (
developerToken,
audienceId,
typeOfList,
userSchema,
isHashRequired,
operationType,
) => {
Expand All @@ -36,10 +41,10 @@ const processRecordEventArray = (
metadata.push(record.metadata);
});

const userIdentifiersList = populateIdentifiers(
const userIdentifiersList = populateIdentifiersForRecordEvent(
fieldsArray,
destination,
typeOfList,
userSchema,
isHashRequired,
);

Expand Down Expand Up @@ -91,7 +96,7 @@ function preparepayload(events, config) {
const { destination, message, metadata } = events[0];
const accessToken = getAccessToken(metadata, 'access_token');
const developerToken = getValueFromMessage(metadata, 'secret.developer_token');
const { audienceId, typeOfList, isHashRequired } = config;
const { audienceId, typeOfList, isHashRequired, userSchema } = config;

const groupedRecordsByAction = lodash.groupBy(events, (record) =>
record.message.action?.toLowerCase(),
Expand All @@ -110,6 +115,7 @@ function preparepayload(events, config) {
developerToken,
audienceId,
typeOfList,
userSchema,
isHashRequired,
'remove',
);
Expand All @@ -124,6 +130,7 @@ function preparepayload(events, config) {
developerToken,
audienceId,
typeOfList,
userSchema,
isHashRequired,
'add',
);
Expand All @@ -138,6 +145,7 @@ function preparepayload(events, config) {
developerToken,
audienceId,
typeOfList,
userSchema,
isHashRequired,
'add',
);
Expand All @@ -161,19 +169,26 @@ function preparepayload(events, config) {

function processRecordInputsV0(groupedRecordInputs) {
const { destination, message } = groupedRecordInputs[0];
const { audienceId, typeOfList, isHashRequired } = destination.Config;
const { audienceId, typeOfList, isHashRequired, userSchema } = destination.Config;

return preparepayload(groupedRecordInputs, {
audienceId: getOperationAudienceId(audienceId, message),
typeOfList,
userSchema,
isHashRequired,
});
}

function processRecordInputsV1(groupedRecordInputs) {
const { connection } = groupedRecordInputs[0];
const { connection, message } = groupedRecordInputs[0];
const { audienceId, typeOfList, isHashRequired } = connection.config.destination;

const identifiers = message?.identifiers;
let userSchema;
if (identifiers) {
userSchema = Object.keys(identifiers);
}

const events = groupedRecordInputs.map((record) => ({
...record,
message: {
Expand All @@ -185,6 +200,7 @@ function processRecordInputsV1(groupedRecordInputs) {
return preparepayload(events, {
audienceId,
typeOfList,
userSchema,
isHashRequired,
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,16 @@ function extraKeysPresent(dictionary, keyList) {
const createPayload = (message, destination) => {
const { listData } = message.properties;
const properties = ['add', 'remove'];
const { typeOfList, isHashRequired } = destination.Config;
const { typeOfList, userSchema, isHashRequired } = destination.Config;

let outputPayloads = {};
const typeOfOperation = Object.keys(listData);
typeOfOperation.forEach((key) => {
if (properties.includes(key)) {
const userIdentifiersList = populateIdentifiers(
listData[key],
destination,
typeOfList,
userSchema,
isHashRequired,
);
if (userIdentifiersList.length === 0) {
Expand Down
Loading

0 comments on commit 97bd84d

Please sign in to comment.