Skip to content

Commit

Permalink
feat(iterable): user deletion support (#2621)
Browse files Browse the repository at this point in the history
* feat(iterable): user deletion support

* feat(iterable): user deletion improvements

* chore: added comments
  • Loading branch information
mihir-4116 authored Sep 26, 2023
1 parent 6fcac7a commit c0ab19a
Show file tree
Hide file tree
Showing 4 changed files with 343 additions and 0 deletions.
80 changes: 80 additions & 0 deletions src/v0/destinations/iterable/deleteUsers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
const { httpDELETE } = require('../../../adapters/network');
const { processAxiosResponse } = require('../../../adapters/utils/networkUtils');
const { isHttpStatusSuccess } = require('../../util');
const { getDynamicErrorType } = require('../../../adapters/utils/networkUtils');
const { NetworkError, ConfigurationError } = require('../../util/errorTypes');
const { executeCommonValidations } = require('../../util/regulation-api');
const tags = require('../../util/tags');
const { JSON_MIME_TYPE } = require('../../util/constant');

// Ref-> https://developers.intercom.com/intercom-api-reference/v1.3/reference/permanently-delete-a-user
const userDeletionHandler = async (userAttributes, config) => {
if (!config) {
throw new ConfigurationError('Config for deletion not present');
}
const { apiKey } = config;
if (!apiKey) {
throw new ConfigurationError('api key for deletion not present');
}
const validUserIds = [];
userAttributes.forEach((userAttribute) => {
// Dropping the user if userId is not present
if (userAttribute.userId) {
validUserIds.push(userAttribute.userId);
}
});
const failedUserDeletions = [];
await Promise.all(
validUserIds.map(async (uId) => {
const url = `https://api.iterable.com/api/users/byUserId/${uId}`;
const requestOptions = {
headers: {
'Content-Type': JSON_MIME_TYPE,
api_key: apiKey,
},
};
const resp = await httpDELETE(url, requestOptions, {
destType: 'iterable',
feature: 'deleteUsers',
});
const handledDelResponse = processAxiosResponse(resp);
if (!isHttpStatusSuccess(handledDelResponse.status) && handledDelResponse.status !== 404) {
if (handledDelResponse.status !== 400) {
// Generic errors such as invalid api key
throw new NetworkError(
`User deletion request failed : ${handledDelResponse.response.msg}`,
handledDelResponse.status,
{
[tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(handledDelResponse.status),
},
handledDelResponse,
);
} else {
// Specific errors such as user is not found
failedUserDeletions.push({ userId: uId, Reason: handledDelResponse.response.msg });
}
}
}),
);

if (failedUserDeletions.length > 0) {
throw new NetworkError(
`User deletion request failed for userIds : ${JSON.stringify(failedUserDeletions)}`,
400,
{
[tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(400),
},
failedUserDeletions,
);
}

return { statusCode: 200, status: 'successful' };
};
const processDeleteUsers = async (event) => {
const { userAttributes, config } = event;
executeCommonValidations(userAttributes);
const resp = await userDeletionHandler(userAttributes, config);
return resp;
};

module.exports = { processDeleteUsers };
93 changes: 93 additions & 0 deletions test/deleteUsers/data/iterable/handler_input.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
[
{
"request": {
"body": [
{
"destType": "ITERABLE",
"userAttributes": [
{
"userId": "rudder1"
}
]
}
]
}
},
{
"request": {
"body": [
{
"destType": "ITERABLE",
"userAttributes": [
{
"userId": "rudder2"
}
],
"config": {
"apiToken": "dummyApiKey"
}
}
]
}
},
{
"request": {
"body": [
{
"destType": "ITERABLE",
"userAttributes": [
{
"userId": "rudder1"
},
{
"userId": "rudder2"
}
],
"config": {
"apiKey": "dummyApiKey"
}
}
]
}
},
{
"request": {
"body": [
{
"destType": "ITERABLE",
"userAttributes": [
{
"userId": "rudder3"
},
{
"userId": "rudder4"
}
],
"config": {
"apiKey": "invalidKey"
}
}
]
}
},
{
"request": {
"body": [
{
"destType": "ITERABLE",
"userAttributes": [
{
"userId": "rudder5"
},
{
"userId": "rudder6"
}
],
"config": {
"apiKey": "dummyApiKey"
}
}
]
}
}
]
32 changes: 32 additions & 0 deletions test/deleteUsers/data/iterable/handler_output.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
[
[
{
"statusCode": 400,
"error": "Config for deletion not present"
}
],
[
{
"statusCode": 400,
"error": "api key for deletion not present"
}
],
[
{
"statusCode": 400,
"error": "User deletion request failed for userIds : [{\"userId\":\"rudder2\",\"Reason\":\"User does not exist. Email: UserId: rudder2\"}]"
}
],
[
{
"error": "User deletion request failed : Invalid API key",
"statusCode": 401
}
],
[
{
"statusCode": 200,
"status": "successful"
}
]
]
138 changes: 138 additions & 0 deletions test/deleteUsers/data/iterable/nw_client_data.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
[
[
{
"type": "delete",
"reqParams": [
"https://api.iterable.com/api/users/byUserId/rudder1",
{},
{
"Accept": "application/json",
"api_key": "dummyApiKey"
}
],
"response": {
"response": {
"data": {
"msg": "All users associated with rudder1 were successfully deleted",
"code": "Success",
"params": null
},
"status": 200
}
}
},
{
"type": "delete",
"reqParams": [
"https://api.iterable.com/api/users/byUserId/rudder2",
{},
{
"Accept": "application/json",
"api_key": "dummyApiKey"
}
],
"response": {
"response": {
"data": {
"msg": "User does not exist. Email: UserId: rudder2",
"code": "BadParams",
"params": null
},
"status": 400
}
}
}
],
[
{
"type": "delete",
"reqParams": [
"https://api.iterable.com/api/users/byUserId/rudder3",
{},
{
"Accept": "application/json",
"api_key": "invalidKey"
}
],
"response": {
"response": {
"data": {
"msg": "Invalid API key",
"code": "Success",
"params": {
"endpoint": "/api/users/byUserId/rudder3"
}
},
"status": 401
}
}
},
{
"type": "delete",
"reqParams": [
"https://api.iterable.com/api/users/byUserId/rudder4",
{},
{
"Accept": "application/json",
"api_key": "invalidKey"
}
],
"response": {
"response": {
"data": {
"msg": "Invalid API key",
"code": "Success",
"params": {
"endpoint": "/api/users/byUserId/rudder3"
}
},
"status": 401
}
}
}
],
[
{
"type": "delete",
"reqParams": [
"https://api.iterable.com/api/users/byUserId/rudder5",
{},
{
"Accept": "application/json",
"api_key": "dummyApiKey"
}
],
"response": {
"response": {
"data": {
"msg": "All users associated with rudder5 were successfully deleted",
"code": "Success",
"params": null
},
"status": 200
}
}
},
{
"type": "delete",
"reqParams": [
"https://api.iterable.com/api/users/byUserId/rudder6",
{},
{
"Accept": "application/json",
"api_key": "dummyApiKey"
}
],
"response": {
"response": {
"data": {
"msg": "All users associated with rudder6 were successfully deleted",
"code": "Success",
"params": null
},
"status": 200
}
}
}
]
]

0 comments on commit c0ab19a

Please sign in to comment.