diff --git a/src/v0/destinations/mailchimp/transform.js b/src/v0/destinations/mailchimp/transform.js index 87f547c124..1f708b4f64 100644 --- a/src/v0/destinations/mailchimp/transform.js +++ b/src/v0/destinations/mailchimp/transform.js @@ -78,7 +78,7 @@ const trackResponseBuilder = (message, { Config }) => { return responseBuilderSimple(processedPayload, endpoint, Config, audienceId); }; -const identifyResponseBuilder = async (message, { Config }) => { +const identifyResponseBuilder = async (message, { Config }, metadata) => { const { datacenterId } = Config; const email = getFieldValueFromMessage(message, 'email'); if (!email) { @@ -86,13 +86,13 @@ const identifyResponseBuilder = async (message, { Config }) => { } const audienceId = getAudienceId(message, Config); const endpoint = mailChimpSubscriptionEndpoint(datacenterId, audienceId, email); - const processedPayload = await processPayload(message, Config, audienceId); + const processedPayload = await processPayload(message, Config, audienceId, metadata); return responseBuilderSimple(processedPayload, endpoint, Config, audienceId); }; const process = async (event) => { let response; - const { message, destination } = event; + const { message, destination, metadata } = event; const messageType = message.type.toLowerCase(); const destConfig = destination.Config; @@ -114,7 +114,7 @@ const process = async (event) => { switch (messageType) { case EventType.IDENTIFY: - response = await identifyResponseBuilder(message, destination); + response = await identifyResponseBuilder(message, destination, metadata); break; case EventType.TRACK: response = trackResponseBuilder(message, destination); diff --git a/src/v0/destinations/mailchimp/utils.js b/src/v0/destinations/mailchimp/utils.js index f678742f2d..58f6a29445 100644 --- a/src/v0/destinations/mailchimp/utils.js +++ b/src/v0/destinations/mailchimp/utils.js @@ -1,7 +1,6 @@ const get = require('get-value'); const md5 = require('md5'); const { InstrumentationError, NetworkError } = require('@rudderstack/integrations-lib'); -const myAxios = require('../../../util/myAxios'); const { MappedToDestinationKey } = require('../../../constants'); const { isDefinedAndNotNull, @@ -20,6 +19,7 @@ const { MERGE_CONFIG, MERGE_ADDRESS, SUBSCRIPTION_STATUS, VALID_STATUSES } = req const { getDynamicErrorType } = require('../../../adapters/utils/networkUtils'); const tags = require('../../util/tags'); const { JSON_MIME_TYPE } = require('../../util/constant'); +const { handleHttpRequest } = require('../../../adapters/network'); const ADDRESS_MANDATORY_FIELDS = ['addr1', 'city', 'state', 'zip']; @@ -145,7 +145,7 @@ const filterTagValue = (tag) => { * @param {*} email * @returns */ -const checkIfMailExists = async (apiKey, datacenterId, audienceId, email) => { +const checkIfMailExists = async (apiKey, datacenterId, audienceId, email, metadata) => { if (!email) { return false; } @@ -155,28 +155,31 @@ const checkIfMailExists = async (apiKey, datacenterId, audienceId, email) => { }; const url = `${mailChimpSubscriptionEndpoint(datacenterId, audienceId, email)}`; const basicAuth = Buffer.from(`apiKey:${apiKey}`).toString('base64'); - try { - const response = await myAxios.get( - url, - { - headers: { - Authorization: `Basic ${basicAuth}`, - }, - }, - { - destType: 'mailchimp', - feature: 'transformation', - endpointPath: '/lists/audienceId/members/email', - requestMethod: 'GET', - module: 'router', + + const { processedResponse, httpResponse } = await handleHttpRequest( + 'get', + url, + { + headers: { + Authorization: `Basic ${basicAuth}`, }, - ); - if (response?.data?.contact_id) { - userStatus.exists = true; - userStatus.subscriptionStatus = response.data.status; - } - } catch (error) { - logger.info(`[Mailchimp] :: Email does not exists, Error: ${error.message}`); + }, + { + metadata, + destType: 'mailchimp', + feature: 'transformation', + endpointPath: '/lists/audienceId/members/email', + requestMethod: 'GET', + module: 'router', + }, + ); + if (!httpResponse.success) { + logger.info(`[Mailchimp] :: Email does not exists, Error: ${httpResponse.response?.message}`); + return userStatus; + } + if (processedResponse.response.contact_id) { + userStatus.exists = true; + userStatus.subscriptionStatus = processedResponse.response.status; } return userStatus; }; @@ -188,33 +191,35 @@ const checkIfMailExists = async (apiKey, datacenterId, audienceId, email) => { * @param {*} audienceId * @returns */ -const checkIfDoubleOptIn = async (apiKey, datacenterId, audienceId) => { - let response; +const checkIfDoubleOptIn = async (apiKey, datacenterId, audienceId, metadata) => { const url = `${getMailChimpBaseEndpoint(datacenterId, audienceId)}`; const basicAuth = Buffer.from(`apiKey:${apiKey}`).toString('base64'); - try { - response = await myAxios.get( - url, - { - headers: { - Authorization: `Basic ${basicAuth}`, - }, - }, - { - destType: 'mailchimp', - feature: 'transformation', - endpointPath: '/lists/audienceId', - requestMethod: 'GET', - module: 'router', + const { httpResponse, processedResponse } = await handleHttpRequest( + 'get', + url, + { + headers: { + Authorization: `Basic ${basicAuth}`, }, - ); - } catch (error) { + }, + { + metadata, + destType: 'mailchimp', + feature: 'transformation', + endpointPath: '/lists/audienceId', + requestMethod: 'GET', + module: 'router', + }, + ); + if (!httpResponse.success) { + const error = httpResponse.response?.response; const status = error.status || 400; throw new NetworkError('User does not have access to the requested operation', status, { [tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(status), }); } - return !!response.data.double_optin; + + return !!processedResponse.response?.double_optin; }; /** @@ -313,7 +318,7 @@ const overrideSubscriptionStatus = (message, primaryPayload, userStatus) => { * @param {*} audienceId * @returns */ -const processPayload = async (message, Config, audienceId) => { +const processPayload = async (message, Config, audienceId, metadata) => { let primaryPayload; let email; const { apiKey, datacenterId, enableMergeFields } = Config; @@ -351,10 +356,10 @@ const processPayload = async (message, Config, audienceId) => { merge_fields: mergeAdditionalTraitsFields(traits, mergedFieldPayload), }; } - const userStatus = await checkIfMailExists(apiKey, datacenterId, audienceId, email); + const userStatus = await checkIfMailExists(apiKey, datacenterId, audienceId, email, metadata); if (!userStatus.exists) { - const isDoubleOptin = await checkIfDoubleOptIn(apiKey, datacenterId, audienceId); + const isDoubleOptin = await checkIfDoubleOptIn(apiKey, datacenterId, audienceId, metadata); primaryPayload.status = isDoubleOptin ? SUBSCRIPTION_STATUS.pending : SUBSCRIPTION_STATUS.subscribed; diff --git a/test/integrations/destinations/mailchimp/network.ts b/test/integrations/destinations/mailchimp/network.ts index b036bf566c..a29712ce9a 100644 --- a/test/integrations/destinations/mailchimp/network.ts +++ b/test/integrations/destinations/mailchimp/network.ts @@ -77,4 +77,42 @@ export const networkCallsData = [ status: 200, }, }, + { + httpReq: { + url: 'https://usXX.api.mailchimp.com/3.0/lists/aud111/members/5587981bdf09024971ff9ddfb2590a6d', + method: 'GET', + headers: { + Authorization: 'Basic YXBpS2V5OmFwaUtleS1kdW1teUFwaUtleQ==', + }, + }, + httpRes: { + data: { + type: 'https://mailchimp.com/developer/marketing/docs/errors/', + title: 'API Key Invalid', + status: 401, + detail: "Your API key may be invalid, or you've attempted to access the wrong datacenter.", + instance: 'd2e09e5b-7c28-8585-68db-8feaf57ee0f7', + }, + status: 401, + }, + }, + { + httpReq: { + url: 'https://usXX.api.mailchimp.com/3.0/lists/aud111', + method: 'GET', + headers: { + Authorization: 'Basic YXBpS2V5OmFwaUtleS1kdW1teUFwaUtleQ==', + }, + }, + httpRes: { + data: { + type: 'https://mailchimp.com/developer/marketing/docs/errors/', + title: 'API Key Invalid', + status: 401, + detail: "Your API key may be invalid, or you've attempted to access the wrong datacenter.", + instance: 'd2e09e5b-7c28-8585-68db-8feaf57ee0f7', + }, + status: 401, + }, + }, ]; diff --git a/test/integrations/destinations/mailchimp/processor/data.ts b/test/integrations/destinations/mailchimp/processor/data.ts index a0ee5de3d3..bf3cb6ad06 100644 --- a/test/integrations/destinations/mailchimp/processor/data.ts +++ b/test/integrations/destinations/mailchimp/processor/data.ts @@ -345,7 +345,7 @@ export const data = [ implementation: 'native', module: 'destination', }, - statusCode: 400, + statusCode: 401, }, ], },