@twilio/flex-plugins-library-utils
Version:
Flex Plugins Library Utils
207 lines (183 loc) • 7.93 kB
text/typescript
import { Twilio } from 'twilio';
import { retryHandler } from '../../common/retryHandler';
import { PluginsUtilsMetaData } from '../../types';
import { Parameters, ApiReturnType } from '../../types';
import { IncomingPhoneNumberInstance } from 'twilio/lib/rest/api/v2010/account/incomingPhoneNumber';
import { OutgoingCallerIdInstance } from 'twilio/lib/rest/api/v2010/account/outgoingCallerId';
import { isNumber } from 'lodash';
import { PluginUtils } from '../../common/BaseClasses/PluginUtils';
import { HttpErrorCode } from '../../constants/statusCodes';
import { PluginUtilsErrorManager } from '../../common/PluginUtilsErrorManager';
import { PhoneNumberInstance } from 'twilio/lib/rest/lookups/v2/phoneNumber';
import { CountryInstance } from 'twilio/lib/rest/voice/v1/dialingPermissions/country';
import { HighriskSpecialPrefixInstance } from 'twilio/lib/rest/voice/v1/dialingPermissions/country/highriskSpecialPrefix';
import { RETRY_STRATEGY } from 'src/constants/api';
export default class PhoneNumbersUtils extends PluginUtils {
private config: PluginsUtilsMetaData;
/**
* Utility class for Twilio PhoneNumber resources
* @param {Twilio} client Twilio client
* @param {TaskRouterMetaData} config.maxBackoff Twilio service backoff max timeout
* @param {TaskRouterMetaData} config.minBackoff Twilio service backoff min timeout
* @param {TaskRouterMetaData} config.retryLimit Service retry limit
* @param {TaskRouterMetaData} config.accountSid Twilio account sid
* @param {TaskRouterMetaData} config.authToken Twilio auth token
* */
constructor(client: Twilio, config: PluginsUtilsMetaData) {
super(client);
this.config = {
...config,
maxBackoff: config.maxBackoff || RETRY_STRATEGY.MAX_BACKOFF,
minBackoff: config.minBackoff || RETRY_STRATEGY.MIN_BACKOFF,
retryLimit: config.retryLimit || RETRY_STRATEGY.RETRY_LIMIT,
};
}
/**
* @returns {Array<PhoneNumber>} An array of phone numbers for the account
* @description the following method is used to robustly retrieve
* the phone numbers for the account
*/
public async listPhoneNumbers(
parameters: Parameters,
): Promise<ApiReturnType & { phoneNumbers?: Array<IncomingPhoneNumberInstance> }> {
try {
const phoneNumbers = await this.client.incomingPhoneNumbers.list({
...(parameters.limit && { limit: parameters.limit }),
});
return { success: true, phoneNumbers, status: HttpErrorCode.OK };
} catch (error) {
return retryHandler(
this.config,
error,
{ ...parameters, attempts: !parameters.attempts ? 0 : parameters.attempts },
this.listPhoneNumbers,
);
}
}
/**
* @returns {Array<PhoneNumber>} An array of outbound caller ids for the account
* @description the following method is used to robustly retrieve
* the outbound caller ids for the account
*/
public async listOutgoingCallerIds(
parameters: Parameters,
): Promise<ApiReturnType & { callerIds?: Array<OutgoingCallerIdInstance> }> {
try {
const callerIds = await this.client.outgoingCallerIds.list({
...(parameters.limit && { limit: parameters.limit }),
});
return { success: true, callerIds, status: HttpErrorCode.OK };
} catch (error) {
return retryHandler(
this.config,
error,
{ ...parameters, attempts: !parameters.attempts ? 0 : parameters.attempts },
this.listOutgoingCallerIds,
);
}
}
/**
* @param {string} parameters.phoneNumber the phone number to validate
* @returns {object} https://www.twilio.com/docs/lookup/v2-api#making-a-request
* @description the following method is used to validate a phone number
*/
public async validatePhoneNumber(
parameters: Parameters & { phoneNumber: string },
): Promise<ApiReturnType & { phoneNumber?: PhoneNumberInstance }> {
const parameterChecks = {
phoneNumber: 'string',
};
try {
const inputError = PluginUtilsErrorManager.checkInvalidParameters<Parameters>(parameters, parameterChecks);
if (inputError) {
throw new PluginUtilsErrorManager(inputError, HttpErrorCode.BadRequest);
}
const phoneNumber = await this.client.lookups.v2.phoneNumbers(parameters.phoneNumber).fetch();
return { success: true, phoneNumber, status: HttpErrorCode.OK };
} catch (error) {
if (error.code === HttpErrorCode.BadRequest) {
return {
success: false,
status: HttpErrorCode.BadRequest,
message: error.message,
};
}
return retryHandler(
this.config,
error,
{ ...parameters, attempts: !parameters.attempts ? 0 : parameters.attempts },
this.validatePhoneNumber,
);
}
}
/**
* @param {number} parameters.attempts the number of retry attempts performed
* @param {string} parameters.callingCountryCode the calling country code to get permissions for
* @returns {object} https://www.twilio.com/docs/voice/api/dialingpermissions-country-resource
* @description the following method is used to get dialing permissions for a given country code
*/
public async getDialingPermissions(
parameters: Parameters & { callingCountryCode: string },
): Promise<ApiReturnType & { dialingPermissions?: CountryInstance }> {
const parameterChecks = {
callingCountryCode: 'string',
};
try {
const inputError = PluginUtilsErrorManager.checkInvalidParameters<Parameters>(parameters, parameterChecks);
if (inputError) {
throw new PluginUtilsErrorManager(inputError, HttpErrorCode.BadRequest);
}
const dialingPermissions = await this.client.voice.v1.dialingPermissions.countries.list({
countryCode: parameters.callingCountryCode,
});
if (!dialingPermissions.length) {
throw new PluginUtilsErrorManager(
'Unable to determine dialing permissions for this number.',
HttpErrorCode.BadRequest,
);
}
return { success: true, dialingPermissions: dialingPermissions[0], status: HttpErrorCode.OK };
} catch (error) {
if (error.code === HttpErrorCode.BadRequest) {
return {
success: false,
status: HttpErrorCode.BadRequest,
message: error.message,
};
}
return retryHandler(this.config, error, parameters, this.getDialingPermissions);
}
}
/**
* @param {number} parameters.attempts the number of retry attempts performed
* @param {string} parameters.isoCode the country ISO code to list high-risk special prefixes for
* @returns {object} https://www.twilio.com/docs/voice/api/dialingpermissions-highriskspecialprefix-resource
* @description the following method is used to list high-risk special prefixes for a given country code
*/
public async listHighRiskSpecialPrefixes(
parameters: Parameters & { isoCode: string },
): Promise<ApiReturnType & { highRiskSpecialPrefixes?: HighriskSpecialPrefixInstance[] }> {
const parameterChecks = {
isoCode: 'string',
};
try {
const inputError = PluginUtilsErrorManager.checkInvalidParameters<Parameters>(parameters, parameterChecks);
if (inputError) {
throw new PluginUtilsErrorManager(inputError, HttpErrorCode.BadRequest);
}
const highRiskSpecialPrefixes = await this.client.voice.v1.dialingPermissions
.countries(parameters.isoCode)
.highriskSpecialPrefixes.list();
return { success: true, highRiskSpecialPrefixes, status: HttpErrorCode.OK };
} catch (error) {
if (error.code === HttpErrorCode.BadRequest) {
return {
success: false,
status: HttpErrorCode.BadRequest,
message: error.message,
};
}
return retryHandler(this.config, error, parameters, this.listHighRiskSpecialPrefixes);
}
}
}