Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(zendesk): remove endpoint global variable #1746

Merged
merged 17 commits into from
Jan 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions src/v0/destinations/zendesk/config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
const { getMappingConfig } = require("../../util");

const getBaseEndpoint = domain => {
return `https://${domain}.zendesk.com/api/v2/`;
};
const NAME = "zendesk";
const ConfigCategory = {
IDENTIFY: {
name: "ZDIdentifyConfig",
Expand Down Expand Up @@ -44,16 +48,13 @@ const ZENDESK_MARKET_PLACE_NAME = "RudderStack";
const ZENDESK_MARKET_PLACE_ORG_ID = "3339";
const ZENDESK_MARKET_PLACE_APP_ID = "263241";

const getBaseEndpoint = domain => {
return `https://${domain}.zendesk.com/api/v2/`;
};

module.exports = {
getBaseEndpoint,
ConfigCategory,
mappingConfig,
defaultFields,
ZENDESK_MARKET_PLACE_NAME,
ZENDESK_MARKET_PLACE_ORG_ID,
ZENDESK_MARKET_PLACE_APP_ID
ZENDESK_MARKET_PLACE_APP_ID,
NAME
};
139 changes: 86 additions & 53 deletions src/v0/destinations/zendesk/transform.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const {
ZENDESK_MARKET_PLACE_NAME,
ZENDESK_MARKET_PLACE_ORG_ID,
ZENDESK_MARKET_PLACE_APP_ID,
NAME,
getBaseEndpoint
} = require("./config");
const {
Expand All @@ -27,8 +28,11 @@ const logger = require("../../../logger");
const { httpGET } = require("../../../adapters/network");
const {
NetworkInstrumentationError,
InstrumentationError
InstrumentationError,
NetworkError
} = require("../../util/errorTypes");
const { getDynamicErrorType } = require("../../../adapters/utils/networkUtils");
const tags = require("../../util/tags");

function responseBuilder(message, headers, payload, endpoint) {
const response = defaultRequestConfig();
Expand Down Expand Up @@ -121,9 +125,12 @@ const payloadBuilderforUpdatingEmail = async (
}
}
}
logger.debug("Failed in fetching Identity details");
logger.debug(`${NAME}:: Failed in fetching Identity details`);
} catch (error) {
logger.debug("Error :", error.response ? error.response.data : error);
logger.debug(
`${NAME}:: Error :`,
error.response ? error.response.data : error
);
}
return {};
};
Expand All @@ -146,11 +153,11 @@ async function createUserFields(url, config, newFields, fieldJson) {
try {
const response = await axios.post(url, fieldData, config);
if (response.status !== 201) {
logger.debug("Failed to create User Field : ", field);
logger.debug(`${NAME}:: Failed to create User Field : `, field);
}
} catch (error) {
if (error.response && error.response.status !== 422) {
logger.debug("Cannot create User field ", field, error);
logger.debug(`${NAME}:: Cannot create User field `, field, error);
}
}
});
Expand Down Expand Up @@ -187,7 +194,10 @@ async function checkAndCreateUserFields(
}
}
} catch (error) {
logger.debug("Error :", error.response ? error.response.data : error);
logger.debug(
`${NAME}:: Error :`,
error.response ? error.response.data : error
);
}
}

Expand Down Expand Up @@ -237,7 +247,7 @@ function getIdentifyPayload(message, category, destinationConfig, type) {
const getUserIdByExternalId = async (message, headers, baseEndpoint) => {
const externalId = getFieldValueFromMessage(message, "userIdOnly");
if (!externalId) {
logger.debug("externalId is required for getting zenuserId");
logger.debug(`${NAME}:: externalId is required for getting zenuserId`);
return undefined;
}
const url = `${baseEndpoint}users/search.json?query=${externalId}`;
Expand All @@ -250,10 +260,10 @@ const getUserIdByExternalId = async (message, headers, baseEndpoint) => {
const zendeskUserId = get(resp, "response.data.users.0.id");
return zendeskUserId;
}
logger.debug("Failed in fetching User details");
logger.debug(`${NAME}:: Failed in fetching User details`);
} catch (error) {
logger.debug(
`Cannot get userId for externalId : ${externalId}`,
`${NAME}:: Cannot get userId for externalId : ${externalId}`,
error.response
);
return undefined;
Expand All @@ -267,7 +277,7 @@ async function getUserId(message, headers, baseEndpoint, type) {
: getFieldValueFromMessage(message, "traits");
const userEmail = traits?.email || traits?.primaryEmail;
if (!userEmail) {
logger.debug("Email ID is required for getting zenuserId");
logger.debug(`${NAME}:: Email ID is required for getting zenuserId`);
return undefined;
}
const url = `${baseEndpoint}users/search.json?query=${userEmail}`;
Expand All @@ -276,11 +286,11 @@ async function getUserId(message, headers, baseEndpoint, type) {
try {
const resp = await axios.get(url, config);
if (!resp || !resp.data || resp.data.count === 0) {
logger.debug("User not found");
logger.debug(`${NAME}:: User not found`);
return undefined;
}

const zendeskUserId = resp.data.users[0].id;
const zendeskUserId = resp?.data?.users?.[0]?.id;
return zendeskUserId;
} catch (error) {
// logger.debug(
Expand All @@ -294,13 +304,16 @@ async function getUserId(message, headers, baseEndpoint, type) {
async function isUserAlreadyAssociated(userId, orgId, headers, baseEndpoint) {
const url = `${baseEndpoint}/users/${userId}/organization_memberships.json`;
const config = { headers };
const response = await axios.get(url, config);
if (
response.data &&
response.data.organization_memberships.length > 0 &&
response.data.organization_memberships[0].organization_id === orgId
) {
return true;
try {
const response = await axios.get(url, config);
if (
response?.data?.organization_memberships?.[0]?.organization_id === orgId
) {
return true;
}
} catch (error) {
logger.debug(`${NAME}:: Error :`);
logger.debug(error?.response?.data || error);
}
return false;
}
Expand Down Expand Up @@ -332,12 +345,12 @@ async function createUser(
const resp = await axios.post(url, payload, config);

if (!resp.data || !resp.data.user || !resp.data.user.id) {
logger.debug(`Couldn't create User: ${name}`);
logger.debug(`${NAME}:: Couldn't create User: ${name}`);
throw new NetworkInstrumentationError("user not found");
}

const userID = resp.data.user.id;
const userEmail = resp.data.user.email;
const userID = resp?.data?.user?.id;
const userEmail = resp?.data?.user.email;
return { zendeskUserId: userID, email: userEmail };
} catch (error) {
logger.debug(error);
Expand Down Expand Up @@ -431,14 +444,18 @@ async function createOrganization(
const resp = await axios.post(url, payload, config);

if (!resp.data || !resp.data.organization) {
logger.debug(`Couldn't create Organization: ${message.traits.name}`);
logger.debug(
`${NAME}:: Couldn't create Organization: ${message.traits.name}`
);
return undefined;
}

const orgId = resp.data.organization.id;
const orgId = resp?.data?.organization?.id;
return orgId;
} catch (error) {
logger.debug(`Couldn't create Organization: ${message.traits.name}`);
logger.debug(
`${NAME}:: Couldn't create Organization: ${message.traits.name}`
);
return undefined;
}
}
Expand Down Expand Up @@ -512,15 +529,11 @@ async function processIdentify(
try {
const config = { headers };
const response = await axios.get(membershipUrl, config);
if (
response.data &&
response.data.organization_memberships &&
response.data.organization_memberships.length > 0
) {
if (response?.data?.organization_memberships?.length > 0) {
if (
orgId === response.data.organization_memberships[0].organization_id
orgId === response.data.organization_memberships[0]?.organization_id
) {
const membershipId = response.data.organization_memberships[0].id;
const membershipId = response.data.organization_memberships[0]?.id;
const deleteResponse = defaultRequestConfig();

deleteResponse.endpoint = `${baseEndpoint}users/${userId}/organization_memberships/${membershipId}.json`;
Expand All @@ -536,7 +549,7 @@ async function processIdentify(
}
}
} catch (error) {
logger.debug(error);
logger.debug(`${NAME}:: ${error}`);
}
}
}
Expand All @@ -557,26 +570,40 @@ async function processTrack(message, destinationConfig, headers, baseEndpoint) {
}
let zendeskUserID;

let url = `${baseEndpoint}users/search.json?query=${userEmail}`;
const url = `${baseEndpoint}users/search.json?query=${userEmail}`;
const config = { headers };
const userResponse = await axios.get(url, config);
if (!get(userResponse, "data.users.0.id") || userResponse.data.count === 0) {
const { zendeskUserId, email } = await createUser(
message,
headers,
destinationConfig,
baseEndpoint
);
if (!zendeskUserId) {
throw new NetworkInstrumentationError("User not found");
}
if (!email) {
throw new NetworkInstrumentationError("User email not found", 400);
try {
const userResponse = await axios.get(url, config);
if (
!get(userResponse, "data.users.0.id") ||
userResponse.data.count === 0
) {
const { zendeskUserId, email } = await createUser(
message,
headers,
destinationConfig,
baseEndpoint
);
if (!zendeskUserId) {
throw new NetworkInstrumentationError("User not found");
}
if (!email) {
throw new NetworkInstrumentationError("User email not found", 400);
}
zendeskUserID = zendeskUserId;
userEmail = email;
}
zendeskUserID = zendeskUserId;
userEmail = email;
zendeskUserID = zendeskUserID || userResponse?.data?.users?.[0]?.id;
} catch (error) {
throw new NetworkError(
sanpj2292 marked this conversation as resolved.
Show resolved Hide resolved
`Failed to fetch user with email: ${userEmail} due to ${error.message}`,
error.status,
{
[tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(error.status)
},
error?.response?.data || error?.response || error
);
}
zendeskUserID = zendeskUserID || userResponse.data.users[0].id;

const eventObject = {};
eventObject.description = message.event;
Expand All @@ -590,9 +617,14 @@ async function processTrack(message, destinationConfig, headers, baseEndpoint) {
profileObject.identifiers = [{ type: "email", value: userEmail }];

const eventPayload = { event: eventObject, profile: profileObject };
url = `${baseEndpoint}users/${zendeskUserID}/events`;
const eventEndpoint = `${baseEndpoint}users/${zendeskUserID}/events`;

const response = responseBuilder(message, headers, eventPayload, url);
const response = responseBuilder(
message,
headers,
eventPayload,
eventEndpoint
);
return response;
}

Expand All @@ -606,7 +638,8 @@ async function processGroup(message, destinationConfig, headers, baseEndpoint) {
message,
category,
headers,
destinationConfig
destinationConfig,
baseEndpoint
);
url = baseEndpoint + category.createEndpoint;
} else {
Expand Down
59 changes: 59 additions & 0 deletions test/__mocks__/data/zendesk/response.json
Original file line number Diff line number Diff line change
Expand Up @@ -286,5 +286,64 @@
"next_page": null,
"previous_page": null,
"count": 1
},
"https://rudderlabtest1.zendesk.com/api/v2/users/search.json?query=testemail1@email": {
"users": [],
"next_page": null,
"previous_page": null,
"count": 0
},
"https://rudderlabtest2.zendesk.com/api/v2/users/search.json?query=testemail2@email": {
"users": [],
"next_page": null,
"previous_page": null,
"count": 0
},
"https://rudderlabtest1.zendesk.com/api/v2/users/create_or_update.json": {
"user": {
"id": 900113780483,
"url": "https://rudderlabtest1.zendesk.com/api/v2/users/900113780483.json",
"name": "John Wick",
"email": "testemail1@email",
"created_at": "2020-03-17T10:21:15Z",
"updated_at": "2020-03-23T15:56:56Z",
"time_zone": "Eastern Time (US & Canada)",
"iana_time_zone": "America/New_York",
"phone": null,
"shared_phone_number": null,
"photo": null,
"locale_id": 1,
"locale": "en-US",
"organization_id": 900001329943,
"role": "end-user",
"verified": true,
"external_id": "exId-123",
"tags": [],
"alias": null,
"active": true,
"shared": false,
"shared_agent": false,
"last_login_at": null,
"two_factor_auth_enabled": false,
"signature": null,
"details": null,
"notes": null,
"role_type": null,
"custom_role_id": null,
"moderator": false,
"ticket_restriction": "requested",
"only_private_comments": false,
"restricted_agent": true,
"suspended": false,
"chat_only": false,
"default_group_id": null,
"report_csv": false,
"user_fields": {
"birthday": null
}
}
},
"https://rudderlabtest2.zendesk.com/api/v2/users/create_or_update.json": {
"user": {}
}
}
Loading