Skip to content

Commit

Permalink
chore: resolve conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
utsabc committed Jun 24, 2024
2 parents 8e6c00b + 11ce96b commit 38be6cf
Show file tree
Hide file tree
Showing 29 changed files with 2,295 additions and 805 deletions.
15 changes: 5 additions & 10 deletions package-lock.json

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

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@
"@pyroscope/nodejs": "^0.2.9",
"@rudderstack/integrations-lib": "^0.2.11",
"@rudderstack/integrations-store": "^1.0.0",
"@rudderstack/json-template-engine": "^0.13.8",
"@rudderstack/workflow-engine": "^0.8.6",
"@rudderstack/json-template-engine": "^0.14.1",
"@rudderstack/workflow-engine": "^0.8.8",
"@shopify/jest-koa-mocks": "^5.1.1",
"ajv": "^8.12.0",
"ajv-draft-04": "^1.0.0",
Expand Down
2 changes: 2 additions & 0 deletions src/cdk/v2/destinations/intercom/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const BASE_AU_ENDPOINT = 'https://api.au.intercom.io';

const SEARCH_CONTACT_ENDPOINT = 'contacts/search';
const CREATE_OR_UPDATE_COMPANY_ENDPOINT = 'companies';
const TAGS_ENDPOINT = 'tags';

const ReservedAttributes = {
v1UserAttributes: [
Expand Down Expand Up @@ -78,4 +79,5 @@ module.exports = {
SEARCH_CONTACT_ENDPOINT,
ReservedCompanyProperties,
CREATE_OR_UPDATE_COMPANY_ENDPOINT,
TAGS_ENDPOINT,
};
25 changes: 25 additions & 0 deletions src/cdk/v2/destinations/intercom/procWorkflow.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ bindings:
- name: addExternalIdToTraits
path: ../../../../v0/util
- path: ../../bindings/jsontemplate
- name: HTTP_STATUS_CODES
path: ../../../../v0/util/constant

steps:
- name: checkIfProcessed
Expand Down Expand Up @@ -182,10 +184,17 @@ steps:
id: companyId,
};
$.context.endpoint = $.getBaseEndpoint(.destination) + "/" + "contacts" + "/" + contactId + "/" + "companies";
const payload = $.context.payload;
const endpoint = $.context.endpoint;
await $.attachContactToCompany(payload, endpoint, .destination);
await $.addOrUpdateTagsToCompany(.message, .destination, companyId);
else:
name: whenSearchContactNotFound
template: |
const companyId = await $.createOrUpdateCompany($.context.payload, .destination);
$.assert(companyId, "Unable to create or update company");
$.context.endpoint = $.getBaseEndpoint(.destination) + "/" + "companies";
await $.addOrUpdateTagsToCompany(.message, .destination, companyId);
- name: prepareFinalPayload
template: |
$.context.requestMethod = 'POST';
Expand All @@ -208,9 +217,25 @@ steps:
response.method = "POST";
response.userId = .message.anonymousId;
$.context.response.push(response);
payload = response.body.JSON;
const companyId = await $.createOrUpdateCompany(payload, .destination);
$.assert(companyId, "Unable to create or update company");
const attachUserAndCompanyResponse = $.attachUserAndCompany(.message, .destination.Config);
attachUserAndCompanyResponse ? attachUserAndCompanyResponse.userId = .message.anonymousId;
attachUserAndCompanyResponse ? $.context.response.push(attachUserAndCompanyResponse);
payload = attachUserAndCompanyResponse.body.JSON;
let endpoint = attachUserAndCompanyResponse.endpoint;
attachUserAndCompanyResponse ? await $.attachContactToCompany(payload, endpoint, .destination);
await $.addOrUpdateTagsToCompany(.message, .destination, companyId);
- name: statusCode
condition: $.outputs.messageType === {{$.EventType.GROUP}}
template: |
$.HTTP_STATUS_CODES.SUPPRESS_EVENTS
else:
name: successStatusCode
template: |
$.HTTP_STATUS_CODES.OK
- name: buildResponseForProcessTransformation
description: Build response for multiple transformed event
Expand Down
2 changes: 1 addition & 1 deletion src/cdk/v2/destinations/intercom/rtWorkflow.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ steps:
"batched": false,
"destination": ^[idx].destination,
"metadata": ^[idx].metadata[],
"statusCode": 200
"statusCode": .outputs.statusCode
})[]
- name: failedEvents
template: |
Expand Down
138 changes: 136 additions & 2 deletions src/cdk/v2/destinations/intercom/utils.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
const md5 = require('md5');
const get = require('get-value');
const { NetworkError } = require('@rudderstack/integrations-lib');
const {
NetworkError,
ConfigurationError,
InstrumentationError,
} = require('@rudderstack/integrations-lib');
const tags = require('../../../../v0/util/tags');
const { httpPOST } = require('../../../../adapters/network');
const {
Expand All @@ -27,8 +31,42 @@ const {
SEARCH_CONTACT_ENDPOINT,
ReservedCompanyProperties,
CREATE_OR_UPDATE_COMPANY_ENDPOINT,
TAGS_ENDPOINT,
} = require('./config');

/**
* method to handle error during api call
* ref docs: https://developers.intercom.com/docs/references/rest-api/errors/error-codes/
* https://developers.intercom.com/docs/references/rest-api/errors/error-objects/
* https://developers.intercom.com/docs/references/rest-api/errors/http-responses/
* e.g.
* 400 - code: parameter_not_found (or parameter_invalid), message: company not specified
* 401 - code: unauthorized, message: Access Token Invalid
* 404 - code: company_not_found, message: Company Not Found
* @param {*} message
* @param {*} processedResponse
*/
const intercomErrorHandler = (message, processedResponse) => {
const errorMessages = JSON.stringify(processedResponse.response);
if (processedResponse.status === 400) {
throw new InstrumentationError(`${message} : ${errorMessages}`);
}
if (processedResponse.status === 401) {
throw new ConfigurationError(`${message} : ${errorMessages}`);
}
if (processedResponse.status === 404) {
throw new InstrumentationError(`${message} : ${errorMessages}`);
}
throw new NetworkError(
`${message} : ${errorMessages}`,
processedResponse.status,
{
[tags]: getDynamicErrorType(processedResponse.status),
},
processedResponse,
);
};

/**
* Returns destination request headers
* @param {*} destination
Expand Down Expand Up @@ -285,7 +323,8 @@ const searchContact = async (message, destination) => {
* @returns
*/
const createOrUpdateCompany = async (payload, destination) => {
const headers = getHeaders(destination);
const { apiVersion } = destination.Config;
const headers = getHeaders(destination, apiVersion);
const finalPayload = JSON.stringify(removeUndefinedAndNullValues(payload));
const baseEndPoint = getBaseEndpoint(destination);
const endpoint = `${baseEndPoint}/${CREATE_OR_UPDATE_COMPANY_ENDPOINT}`;
Expand Down Expand Up @@ -369,6 +408,99 @@ const addMetadataToPayload = (payload) => {
return finalPayload;
};

/**
* Api call to attach user to the company
* Ref doc v1: https://developers.intercom.com/docs/references/1.4/rest-api/users/companies-and-users/
* Ref doc v2: https://developers.intercom.com/docs/references/2.10/rest-api/api.intercom.io/Contacts/attachContactToACompany/
* @param {*} payload
* @param {*} endpoint
* @param {*} destination
*/
const attachContactToCompany = async (payload, endpoint, destination) => {
let { apiVersion } = destination.Config;
apiVersion = isDefinedAndNotNull(apiVersion) ? apiVersion : 'v2';
let endpointPath = '/contact/{id}/companies';
if (apiVersion === 'v1') {
endpointPath = '/users';
}
const commonStatTags = {
destType: 'intercom',
feature: 'transformation',
requestMethod: 'POST',
module: 'router',
};
const headers = getHeaders(destination, apiVersion);
const finalPayload = JSON.stringify(removeUndefinedAndNullValues(payload));
const response = await httpPOST(
endpoint,
finalPayload,
{
headers,
},
{
...commonStatTags,
endpointPath,
},
);

const processedResponse = processAxiosResponse(response);
if (!isHttpStatusSuccess(processedResponse.status)) {
intercomErrorHandler('Unable to attach Contact or User to Company due to', processedResponse);
}
};

/**
* Api calls to add or update tags to the company
* Ref doc v1: https://developers.intercom.com/docs/references/1.4/rest-api/tags/tag-or-untag-users-companies-leads-contacts/
* Ref doc v2: https://developers.intercom.com/docs/references/2.10/rest-api/api.intercom.io/Tags/createTag/
* @param message
* @param destination
* @param id
* @returns
*/
const addOrUpdateTagsToCompany = async (message, destination, id) => {
const companyTags = message?.context?.traits?.tags;
if (!companyTags) return;
const { apiVersion } = destination.Config;
const headers = getHeaders(destination, apiVersion);
const baseEndPoint = getBaseEndpoint(destination);
const endpoint = `${baseEndPoint}/${TAGS_ENDPOINT}`;
const statTags = {
destType: 'intercom',
feature: 'transformation',
endpointPath: '/tags',
requestMethod: 'POST',
module: 'router',
};
await Promise.all(
companyTags.map(async (tag) => {
const finalPayload = {
name: tag,
companies: [
{
id,
},
],
};
const response = await httpPOST(
endpoint,
finalPayload,
{
headers,
},
statTags,
);
const processedResponse = processAxiosResponse(response);
if (!isHttpStatusSuccess(processedResponse.status)) {
intercomErrorHandler(
'Unable to Add or Update the Tag to Company due to',
processedResponse,
);
}
}),
);
};

module.exports = {
getName,
getHeaders,
Expand All @@ -382,4 +514,6 @@ module.exports = {
filterCustomAttributes,
checkIfEmailOrUserIdPresent,
separateReservedAndRestMetadata,
attachContactToCompany,
addOrUpdateTagsToCompany,
};
Loading

0 comments on commit 38be6cf

Please sign in to comment.