From 9ebc00d27a7dfe90f497958bfe7f518131f4320b Mon Sep 17 00:00:00 2001 From: ItsSudip Date: Fri, 14 Jun 2024 17:33:24 +0530 Subject: [PATCH 1/3] chore: move gainsight_px from myaxios to httpget,put and post --- src/v0/destinations/gainsight_px/util.js | 167 ++++++++--------------- 1 file changed, 57 insertions(+), 110 deletions(-) diff --git a/src/v0/destinations/gainsight_px/util.js b/src/v0/destinations/gainsight_px/util.js index 83d23566dd..edb6e5b63d 100644 --- a/src/v0/destinations/gainsight_px/util.js +++ b/src/v0/destinations/gainsight_px/util.js @@ -1,9 +1,9 @@ const { NetworkError } = require('@rudderstack/integrations-lib'); -const myAxios = require('../../../util/myAxios'); const { ENDPOINTS } = require('./config'); const tags = require('../../util/tags'); const { getDynamicErrorType } = require('../../../adapters/utils/networkUtils'); const { JSON_MIME_TYPE } = require('../../util/constant'); +const { httpGET, httpPOST, httpPUT } = require('../../../adapters/network'); const handleErrorResponse = (error, customErrMessage, expectedErrStatus, defaultStatus = 400) => { let destResp; @@ -39,131 +39,78 @@ const handleErrorResponse = (error, customErrMessage, expectedErrStatus, default */ const objectExists = async (id, Config, objectType) => { let url = `${ENDPOINTS.USERS_ENDPOINT}/${id}`; - let err = 'invalid response while searching user'; if (objectType === 'account') { url = `${ENDPOINTS.ACCOUNTS_ENDPOINT}/${id}`; - err = 'invalid response while searching account'; } - - let response; - try { - response = await myAxios.get( - url, - { - headers: { - 'X-APTRINSIC-API-KEY': Config.apiKey, - 'Content-Type': JSON_MIME_TYPE, - }, - }, - { - destType: 'gainsight_px', - feature: 'transformation', - requestMethod: 'GET', - endpointPath: '/accounts/accountId', - module: 'router', - }, - ); - if (response && response.status === 200) { - return { success: true, err: null }; - } - const defStatus = 400; - const status = response ? response.status || defStatus : defStatus; - throw new NetworkError( - err, - status, - { - [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(status), + const res = await httpGET( + url, + { + headers: { + 'X-APTRINSIC-API-KEY': Config.apiKey, + 'Content-Type': JSON_MIME_TYPE, }, - response, - ); - } catch (error) { - return handleErrorResponse(error, `error while fetching ${objectType}`, 404); + }, + { + destType: 'gainsight_px', + feature: 'transformation', + requestMethod: 'GET', + endpointPath: '/accounts/accountId', + module: 'router', + }, + ); + if (res.success && res.response && res.response.status === 200) { + return { success: true, err: null }; } + return handleErrorResponse(res.response, `error while fetching ${objectType}`, 404); }; const createAccount = async (payload, Config) => { - let response; - try { - response = await myAxios.post( - ENDPOINTS.ACCOUNTS_ENDPOINT, - payload, - { - headers: { - 'X-APTRINSIC-API-KEY': Config.apiKey, - 'Content-Type': JSON_MIME_TYPE, - }, - }, - { - destType: 'gainsight_px', - feature: 'transformation', - requestMethod: 'POST', - endpointPath: '/accounts', - module: 'router', - }, - ); - if (response && response.status === 201) { - return { success: true, err: null }; - } - - const defStatus = 400; - const status = response ? response.status || defStatus : defStatus; - throw new NetworkError( - 'invalid response while creating account', - status, - { - [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(status), + const res = await httpPOST( + ENDPOINTS.ACCOUNTS_ENDPOINT, + payload, + { + headers: { + 'X-APTRINSIC-API-KEY': Config.apiKey, + 'Content-Type': JSON_MIME_TYPE, }, - response, - ); - } catch (error) { - return handleErrorResponse(error, 'error while creating account', 400); + }, + { + destType: 'gainsight_px', + feature: 'transformation', + requestMethod: 'POST', + endpointPath: '/accounts', + module: 'router', + }, + ); + if (res.success && res.response.status === 201) { + return { success: true, err: null }; } + return handleErrorResponse(res.response, 'error while creating account', 400); }; const updateAccount = async (accountId, payload, Config) => { - let response; - try { - response = await myAxios.put( - `${ENDPOINTS.ACCOUNTS_ENDPOINT}/${accountId}`, - payload, - { - headers: { - 'X-APTRINSIC-API-KEY': Config.apiKey, - 'Content-Type': JSON_MIME_TYPE, - }, - }, - { - destType: 'gainsight_px', - feature: 'transformation', - requestMethod: 'PUT', - endpointPath: '/accounts/accountId', - module: 'router', - }, - ); - if (response && response.status === 204) { - return { success: true, err: null }; - } - const defStatus = 400; - const status = response ? response.status || defStatus : defStatus; - throw new NetworkError( - 'invalid response while updating account', - status, - { - [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(status), + const res = await httpPUT( + `${ENDPOINTS.ACCOUNTS_ENDPOINT}/${accountId}`, + payload, + { + headers: { + 'X-APTRINSIC-API-KEY': Config.apiKey, + 'Content-Type': JSON_MIME_TYPE, }, - response, - ); - } catch (error) { - // it will only occur if the user does not exist - if ( - error.response?.status === 404 && - error.response?.data?.externalapierror?.status === 'NOT_FOUND' - ) { - return { success: false, err: null }; - } - return handleErrorResponse(error, 'error while updating account', 400); + }, + { + destType: 'gainsight_px', + feature: 'transformation', + requestMethod: 'PUT', + endpointPath: '/accounts/accountId', + module: 'router', + }, + ); + if (res.success && res.response.status === 204) { + return { success: true, err: null }; } + return handleErrorResponse(res.response, 'error while updating account', 400); }; /** From 270c76ee144cf7e9c48ac217c09bf54a101a8a09 Mon Sep 17 00:00:00 2001 From: ItsSudip Date: Thu, 20 Jun 2024 09:33:06 +0530 Subject: [PATCH 2/3] chore: address comment --- src/v0/destinations/gainsight_px/transform.js | 28 +++++++++---------- src/v0/destinations/gainsight_px/util.js | 20 ++++++++----- 2 files changed, 27 insertions(+), 21 deletions(-) diff --git a/src/v0/destinations/gainsight_px/transform.js b/src/v0/destinations/gainsight_px/transform.js index a63be08c80..0911b76b6c 100644 --- a/src/v0/destinations/gainsight_px/transform.js +++ b/src/v0/destinations/gainsight_px/transform.js @@ -39,7 +39,7 @@ const { JSON_MIME_TYPE } = require('../../util/constant'); /** * Create/Update a User with user attributes */ -const identifyResponseBuilder = async (message, { Config }) => { +const identifyResponseBuilder = async (message, { Config }, metadata) => { const userId = getFieldValueFromMessage(message, 'userId'); if (!userId) { throw new InstrumentationError('userId or anonymousId is required for identify'); @@ -51,7 +51,7 @@ const identifyResponseBuilder = async (message, { Config }) => { 'Content-Type': JSON_MIME_TYPE, }; - const { success: isUserPresent } = await objectExists(userId, Config, 'user'); + const { success: isUserPresent } = await objectExists(userId, Config, 'user', metadata); let payload = constructPayload(message, identifyMapping); const name = getValueFromMessage(message, ['traits.name', 'context.traits.name']); @@ -110,7 +110,7 @@ const identifyResponseBuilder = async (message, { Config }) => { * Pros: Will make atleast 2 API call and at most 3 API calls * Cons: There might be some unwanted accounts */ -const newGroupResponseBuilder = async (message, { Config }) => { +const newGroupResponseBuilder = async (message, { Config }, metadata) => { const userId = getFieldValueFromMessage(message, 'userId'); if (!userId) { throw new InstrumentationError('userId or anonymousId is required for group'); @@ -140,12 +140,12 @@ const newGroupResponseBuilder = async (message, { Config }) => { payload = removeUndefinedAndNullValues(payload); // update account - const { success: updateSuccess, err } = await updateAccount(groupId, payload, Config); + const { success: updateSuccess, err } = await updateAccount(groupId, payload, Config, metadata); // will not throw error if it is due to unavailable accounts if (!updateSuccess && err === null) { // create account payload.id = groupId; - const { success: createSuccess, error } = await createAccount(payload, Config); + const { success: createSuccess, error } = await createAccount(payload, Config, metadata); if (!createSuccess) { throw new ConfigurationError(`failed to create account for group: ${error}`); } @@ -172,13 +172,13 @@ const newGroupResponseBuilder = async (message, { Config }) => { /** * Associates a User with an Account. */ -const groupResponseBuilder = async (message, { Config }) => { +const groupResponseBuilder = async (message, { Config }, metadata) => { const userId = getFieldValueFromMessage(message, 'userId'); if (!userId) { throw new InstrumentationError('userId or anonymousId is required for group'); } - const { success: isPresent, err: e } = await objectExists(userId, Config, 'user'); + const { success: isPresent, err: e } = await objectExists(userId, Config, 'user', metadata); if (!isPresent) { throw new InstrumentationError(`aborting group call: ${e}`); } @@ -188,7 +188,7 @@ const groupResponseBuilder = async (message, { Config }) => { throw new InstrumentationError('groupId is required for group'); } - const { success: accountIsPresent } = await objectExists(groupId, Config, 'account'); + const { success: accountIsPresent } = await objectExists(groupId, Config, 'account', metadata); let payload = constructPayload(message, groupMapping); let customAttributes = {}; @@ -210,14 +210,14 @@ const groupResponseBuilder = async (message, { Config }) => { if (accountIsPresent) { // update account - const { success: updateSuccess, err } = await updateAccount(groupId, payload, Config); + const { success: updateSuccess, err } = await updateAccount(groupId, payload, Config, metadata); if (!updateSuccess) { throw new ConfigurationError(`failed to update account for group: ${err}`); } } else { // create account payload.id = groupId; - const { success: createSuccess, err } = await createAccount(payload, Config); + const { success: createSuccess, err } = await createAccount(payload, Config, metadata); if (!createSuccess) { throw new ConfigurationError(`failed to create account for group: ${err}`); } @@ -279,7 +279,7 @@ const trackResponseBuilder = (message, { Config }) => { * Processing Single event */ const process = async (event) => { - const { message, destination } = event; + const { message, destination, metadata } = event; if (!message.type) { throw new InstrumentationError('Message Type is not present. Aborting message.'); } @@ -301,16 +301,16 @@ const process = async (event) => { let response; switch (messageType) { case EventType.IDENTIFY: - response = await identifyResponseBuilder(message, destination); + response = await identifyResponseBuilder(message, destination, metadata); break; case EventType.TRACK: response = trackResponseBuilder(message, destination); break; case EventType.GROUP: if (limitAPIForGroup) { - response = await newGroupResponseBuilder(message, destination); + response = await newGroupResponseBuilder(message, destination, metadata); } else { - response = await groupResponseBuilder(message, destination); + response = await groupResponseBuilder(message, destination, metadata); } break; default: diff --git a/src/v0/destinations/gainsight_px/util.js b/src/v0/destinations/gainsight_px/util.js index edb6e5b63d..9921d46c07 100644 --- a/src/v0/destinations/gainsight_px/util.js +++ b/src/v0/destinations/gainsight_px/util.js @@ -3,7 +3,7 @@ const { ENDPOINTS } = require('./config'); const tags = require('../../util/tags'); const { getDynamicErrorType } = require('../../../adapters/utils/networkUtils'); const { JSON_MIME_TYPE } = require('../../util/constant'); -const { httpGET, httpPOST, httpPUT } = require('../../../adapters/network'); +const { handleHttpRequest } = require('../../../adapters/network'); const handleErrorResponse = (error, customErrMessage, expectedErrStatus, defaultStatus = 400) => { let destResp; @@ -37,13 +37,14 @@ const handleErrorResponse = (error, customErrMessage, expectedErrStatus, default * @param {*} objectType * @returns */ -const objectExists = async (id, Config, objectType) => { +const objectExists = async (id, Config, objectType, metadata) => { let url = `${ENDPOINTS.USERS_ENDPOINT}/${id}`; if (objectType === 'account') { url = `${ENDPOINTS.ACCOUNTS_ENDPOINT}/${id}`; } - const res = await httpGET( + const res = await handleHttpRequest( + 'get', url, { headers: { @@ -52,6 +53,7 @@ const objectExists = async (id, Config, objectType) => { }, }, { + metadata, destType: 'gainsight_px', feature: 'transformation', requestMethod: 'GET', @@ -65,8 +67,9 @@ const objectExists = async (id, Config, objectType) => { return handleErrorResponse(res.response, `error while fetching ${objectType}`, 404); }; -const createAccount = async (payload, Config) => { - const res = await httpPOST( +const createAccount = async (payload, Config, metadata) => { + const res = await handleHttpRequest( + 'post', ENDPOINTS.ACCOUNTS_ENDPOINT, payload, { @@ -76,6 +79,7 @@ const createAccount = async (payload, Config) => { }, }, { + metadata, destType: 'gainsight_px', feature: 'transformation', requestMethod: 'POST', @@ -89,8 +93,9 @@ const createAccount = async (payload, Config) => { return handleErrorResponse(res.response, 'error while creating account', 400); }; -const updateAccount = async (accountId, payload, Config) => { - const res = await httpPUT( +const updateAccount = async (accountId, payload, Config, metadata) => { + const res = await handleHttpRequest( + 'put', `${ENDPOINTS.ACCOUNTS_ENDPOINT}/${accountId}`, payload, { @@ -100,6 +105,7 @@ const updateAccount = async (accountId, payload, Config) => { }, }, { + metadata, destType: 'gainsight_px', feature: 'transformation', requestMethod: 'PUT', From 13c378e4313b767ce2d6bc6bb2c2a8e60a4f14bd Mon Sep 17 00:00:00 2001 From: ItsSudip Date: Thu, 20 Jun 2024 09:36:52 +0530 Subject: [PATCH 3/3] chore: update util.js with new handleHttpRequest response --- src/v0/destinations/gainsight_px/util.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/v0/destinations/gainsight_px/util.js b/src/v0/destinations/gainsight_px/util.js index 9921d46c07..7300189297 100644 --- a/src/v0/destinations/gainsight_px/util.js +++ b/src/v0/destinations/gainsight_px/util.js @@ -43,7 +43,7 @@ const objectExists = async (id, Config, objectType, metadata) => { if (objectType === 'account') { url = `${ENDPOINTS.ACCOUNTS_ENDPOINT}/${id}`; } - const res = await handleHttpRequest( + const { httpResponse: res } = await handleHttpRequest( 'get', url, { @@ -68,7 +68,7 @@ const objectExists = async (id, Config, objectType, metadata) => { }; const createAccount = async (payload, Config, metadata) => { - const res = await handleHttpRequest( + const { httpResponse: res } = await handleHttpRequest( 'post', ENDPOINTS.ACCOUNTS_ENDPOINT, payload, @@ -94,7 +94,7 @@ const createAccount = async (payload, Config, metadata) => { }; const updateAccount = async (accountId, payload, Config, metadata) => { - const res = await handleHttpRequest( + const { httpResponse: res } = await handleHttpRequest( 'put', `${ENDPOINTS.ACCOUNTS_ENDPOINT}/${accountId}`, payload,