- C#
- Python
- NodeJS
Phone Exchange C# Rest Code Snippet
using System.Web;
namespace phone_exchange_2_dot_net.REST
{
/// <summary>
/// Provides functionality to call the ServiceObjects Phone Exchange (PE2) REST API's GetExchangeInfo endpoint,
/// retrieving phone exchange information (e.g., carrier, line type, ported status) for a given phone number
/// with fallback to a backup endpoint for reliability in live mode.
/// </summary>
public static class GetExchangeInfoClient
{
// Base URL constants: production, backup, and trial
private const string LiveBaseUrl = "https://sws.serviceobjects.com/pe2/web.svc/json/";
private const string BackupBaseUrl = "https://swsbackup.serviceobjects.com/pe2/web.svc/json/";
private const string TrialBaseUrl = "https://trial.serviceobjects.com/pe2/web.svc/json/";
/// <summary>
/// Synchronously calls the GetExchangeInfo REST endpoint to retrieve phone exchange information,
/// attempting the primary endpoint first and falling back to the backup if the response is invalid
/// (Error.TypeCode == "3") in live mode.
/// </summary>
/// <param name="input">The input parameters including phone number, country code, and license key.</param>
/// <returns>Deserialized <see cref="PE2Response"/> containing phone exchange data or an error.</returns>
public static PE2Response Invoke(GetExchangeInfoInput input)
{
// Use query string parameters so missing/optional fields don't break the URL
string url = BuildUrl(input, input.IsLive ? LiveBaseUrl : TrialBaseUrl);
PE2Response response = Helper.HttpGet<PE2Response>(url, input.TimeoutSeconds);
// Fallback on error in live mode
if (input.IsLive && !IsValid(response))
{
string fallbackUrl = BuildUrl(input, BackupBaseUrl);
PE2Response fallbackResponse = Helper.HttpGet<PE2Response>(fallbackUrl, input.TimeoutSeconds);
return fallbackResponse;
}
return response;
}
/// <summary>
/// Asynchronously calls the GetExchangeInfo REST endpoint to retrieve phone exchange information,
/// attempting the primary endpoint first and falling back to the backup if the response is invalid
/// (Error.TypeCode == "3") in live mode.
/// </summary>
/// <param name="input">The input parameters including phone number, country code, and license key.</param>
/// <returns>Deserialized <see cref="PE2Response"/> containing phone exchange data or an error.</returns>
public static async Task<PE2Response> InvokeAsync(GetExchangeInfoInput input)
{
// Use query string parameters so missing/optional fields don't break the URL
string url = BuildUrl(input, input.IsLive ? LiveBaseUrl : TrialBaseUrl);
PE2Response response = await Helper.HttpGetAsync<PE2Response>(url, input.TimeoutSeconds).ConfigureAwait(false);
// Fallback on error in live mode
if (input.IsLive && !IsValid(response))
{
string fallbackUrl = BuildUrl(input, BackupBaseUrl);
PE2Response fallbackResponse = await Helper.HttpGetAsync<PE2Response>(fallbackUrl, input.TimeoutSeconds).ConfigureAwait(false);
return fallbackResponse;
}
return response;
}
// Build the full request URL, including URL-encoded query string
public static string BuildUrl(GetExchangeInfoInput input, string baseUrl)
{
// Construct query string with URL-encoded parameters
string qs = $"GetExchangeInfo?" +
$"PhoneNumber={Helper.UrlEncode(input.PhoneNumber)}" +
$"&LicenseKey={Helper.UrlEncode(input.LicenseKey)}";
return baseUrl + qs;
}
private static bool IsValid(PE2Response response) => response?.Error == null || response.Error.TypeCode != "3";
/// <summary>
/// Input parameters for the GetExchangeInfo API call. Represents a phone number to retrieve exchange information.
/// </summary>
/// <param name="PhoneNumber">The phone number to validate (e.g., "1234567890").</param>
/// <param name="CountryCode">1-3 digit country calling code (e.g., "1"). Optional.</param>
/// <param name="Country">ISO2, ISO3, or country name (e.g., "US"). Optional.</param>
/// <param name="IPAddress">IPv4 address. Optional.</param>
/// <param name="CallerCountry">ISO2 or ISO3 code representing the caller's country. Optional.</param>
/// <param name="Extras">Comma-separated list of possible options. Optional.</param>
/// <param name="LicenseKey">The license key to authenticate the API request.</param>
/// <param name="IsLive">Indicates whether to use the live service (true) or trial service (false).</param>
/// <param name="TimeoutSeconds">Timeout duration for the API call, in seconds.</param>
public record GetExchangeInfoInput(
string PhoneNumber = "",
string CountryCode = "",
string Country = "",
string IPAddress = "",
string CallerCountry = "",
string Extras = "",
string LicenseKey = "",
string Token = "",
bool IsLive = true,
int TimeoutSeconds = 15
);
}
}
using System.Runtime.Serialization;
using System.Linq;
namespace phone_exchange_2_dot_net.REST
{
/// <summary>
/// Response from PE2 GetExchangeInfo and GetInternationalExchangeInfo APIs, containing phone exchange information.
/// </summary>
[DataContract]
public class PE2Response
{
public ExchangeInfo[] ExchangeInfoResults { get; set; }
public InternationalExchangeInfo InternationalExchangeInfo { get; set; }
public Error Error { get; set; }
public override string ToString()
{
string exchangeInfoStr = ExchangeInfoResults != null
? string.Join("\n", ExchangeInfoResults.Select(r => r.ToString()))
: "null";
string internationalInfoStr = InternationalExchangeInfo != null
? InternationalExchangeInfo.ToString()
: "";
return $"PE2Response:\n" +
$"ExchangeInfoResults:\n{exchangeInfoStr}\n" +
$"InternationalExchangeInfo:\n{internationalInfoStr}\n" +
$"Error: {(Error != null ? Error.ToString() : "null")}";
}
}
/// <summary>
/// Phone exchange information for a validated phone number (USA/Canada).
/// </summary>
[DataContract]
public class ExchangeInfo
{
public string PhoneNumber { get; set; }
public string Name { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Country { get; set; }
public string LineType { get; set; }
public string TimeZone { get; set; }
public string Latitude { get; set; }
public string Longitude { get; set; }
public string SMSAddress { get; set; }
public string MMSAddress { get; set; }
public PortedInfo PortedInfo { get; set; }
public string NoteCodes { get; set; }
public string NoteDescriptions { get; set; }
public override string ToString()
{
string portedInfoStr = PortedInfo != null
? PortedInfo.ToString()
: "";
return $"ExchangeInfo:\n" +
$"PhoneNumber: {PhoneNumber}\n" +
$"Name: {Name}\n" +
$"City: {City}\n" +
$"State: {State}\n" +
$"Country: {Country}\n" +
$"LineType: {LineType}\n" +
$"TimeZone: {TimeZone}\n" +
$"Latitude: {Latitude}\n" +
$"Longitude: {Longitude}\n" +
$"SMSAddress: {SMSAddress}\n" +
$"MMSAddress: {MMSAddress}\n" +
$"PortedInfo: {portedInfoStr}\n" +
$"NoteCodes: {NoteCodes}\n" +
$"NoteDescriptions: {NoteDescriptions}";
}
}
/// <summary>
/// Ported information for a phone number.
/// </summary>
[DataContract]
public class PortedInfo
{
public string OriginalName { get; set; }
public string OriginalLineType { get; set; }
public string PortedDate { get; set; }
public string LATA { get; set; }
public override string ToString()
{
return $"OriginalName: {OriginalName}, OriginalLineType: {OriginalLineType}, PortedDate: {PortedDate}, LATA: {LATA}";
}
}
/// <summary>
/// International phone exchange information for a validated phone number.
/// </summary>
[DataContract]
public class InternationalExchangeInfo
{
public string PhoneNumberIn { get; set; }
public string CountryCode { get; set; }
public string FormatNational { get; set; }
public string Extension { get; set; }
public string Locality { get; set; }
public string LocalityMatchLevel { get; set; }
public string TimeZone { get; set; }
public string Latitude { get; set; }
public string Longitude { get; set; }
public string Country { get; set; }
public string CountryISO2 { get; set; }
public string CountryISO3 { get; set; }
public string FormatInternational { get; set; }
public string FormatE164 { get; set; }
public string Carrier { get; set; }
public string LineType { get; set; }
public string SMSAddress { get; set; }
public string MMSAddress { get; set; }
public bool IsValid { get; set; }
public bool IsValidForRegion { get; set; }
public string NoteCodes { get; set; }
public string NoteDescriptions { get; set; }
public override string ToString()
{
return $"InternationalExchangeInfo:\n" +
$"PhoneNumberIn: {PhoneNumberIn}\n" +
$"CountryCode: {CountryCode}\n" +
$"FormatNational: {FormatNational}\n" +
$"Extension: {Extension}\n" +
$"Locality: {Locality}\n" +
$"LocalityMatchLevel: {LocalityMatchLevel}\n" +
$"TimeZone: {TimeZone}\n" +
$"Latitude: {Latitude}\n" +
$"Longitude: {Longitude}\n" +
$"Country: {Country}\n" +
$"CountryISO2: {CountryISO2}\n" +
$"CountryISO3: {CountryISO3}\n" +
$"FormatInternational: {FormatInternational}\n" +
$"FormatE164: {FormatE164}\n" +
$"Carrier: {Carrier}\n" +
$"LineType: {LineType}\n" +
$"SMSAddress: {SMSAddress}\n" +
$"MMSAddress: {MMSAddress}\n" +
$"IsValid: {IsValid}\n" +
$"IsValidForRegion: {IsValidForRegion}\n" +
$"NoteCodes: {NoteCodes}\n" +
$"NoteDescriptions: {NoteDescriptions}";
}
}
/// <summary>
/// Error object for PE2 API responses.
/// </summary>
[DataContract]
public class Error
{
public string Type { get; set; }
public string Desc { get; set; }
public string TypeCode { get; set; }
public string DescCode { get; set; }
public override string ToString()
{
return $"Desc: {Desc}, TypeCode: {TypeCode}, DescCode: {DescCode}, Type: {Type}";
}
}
}
using System.Net.Http;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Web;
namespace phone_exchange_2_dot_net.REST
{
public static class Helper
{
public static async Task<T> HttpGetAsync<T>(string url, int timeoutSeconds)
{
HttpClient HttpClient = new HttpClient();
HttpClient.Timeout = TimeSpan.FromSeconds(timeoutSeconds);
using var httpResponse = await HttpClient.GetAsync(url).ConfigureAwait(false);
httpResponse.EnsureSuccessStatusCode();
var stream = await httpResponse.Content.ReadAsStreamAsync().ConfigureAwait(false);
return JsonSerializer.Deserialize<T>(stream)!;
}
public static T HttpGet<T>(string url, int timeoutSeconds)
{
using var httpClient = new HttpClient
{
Timeout = TimeSpan.FromSeconds(timeoutSeconds)
};
using var request = new HttpRequestMessage(HttpMethod.Get, url);
using HttpResponseMessage response = httpClient
.SendAsync(request)
.GetAwaiter()
.GetResult();
response.EnsureSuccessStatusCode();
using Stream responseStream = response.Content
.ReadAsStreamAsync()
.GetAwaiter()
.GetResult();
var options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
};
object? obj = JsonSerializer.Deserialize(responseStream, typeof(T), options);
T result = (T)obj!;
return result;
}
public static string UrlEncode(string value) => HttpUtility.UrlEncode(value ?? string.Empty);
}
}
Phone Exchange Python Rest Code Snippet
from pe2_response import PE2Response, ExchangeInfo, InternationalExchangeInfo, PortedInfo, Error
import requests
# Endpoint URLs for ServiceObjects Phone Exchange (PE2) API
primary_url = "https://sws.serviceobjects.com/pe2/web.svc/json/GetExchangeInfo?"
backup_url = "https://swsbackup.serviceobjects.com/pe2/web.svc/json/GetExchangeInfo?"
trial_url = "https://trial.serviceobjects.com/pe2/web.svc/json/GetExchangeInfo?"
def get_exchange_info(
phone_number: str,
license_key: str = None,
is_live: bool = True
) -> PE2Response:
"""
Call ServiceObjects Phone Exchange (PE2) API's GetExchangeInfo endpoint
to retrieve phone exchange information for a given US/Canada phone number.
Parameters:
phone_number: The phone number to validate (e.g., "8051234567").
license_key: Your ServiceObjects license key.
is_live: Use live or trial servers.
Returns:
PE2Response: Parsed JSON response with phone exchange results or error details.
Raises:
RuntimeError: If the API returns an error payload.
requests.RequestException: On network/HTTP failures (trial mode).
"""
params = {
"PhoneNumber": phone_number,
"LicenseKey": license_key,
}
# Select the base URL: production vs trial
url = primary_url if is_live else trial_url
try:
# Attempt primary (or trial) endpoint
response = requests.get(url, params=params, timeout=10)
response.raise_for_status()
data = response.json()
# If API returned an error in JSON payload, trigger fallback
error = data.get('Error')
if not (error is None or error.get('TypeCode') != "3"):
if is_live:
# Try backup URL
response = requests.get(backup_url, params=params, timeout=10)
response.raise_for_status()
data = response.json()
# If still error, propagate exception
if 'Error' in data:
raise RuntimeError(f"Phone Exchange service error: {data['Error']}")
else:
# Trial mode error is terminal
raise RuntimeError(f"Phone Exchange trial error: {data['Error']}")
# Convert JSON response to PE2Response for structured access
error = Error(**data.get("Error", {})) if data.get("Error") else None
exchange_info_results = []
if "ExchangeInfoResults" in data:
for ei in data.get("ExchangeInfoResults", []):
if isinstance(ei, dict):
ported_info_list = []
if "PortedInfo" in ei and ei.get("PortedInfo"):
for pi in ei.get("PortedInfo", []):
if isinstance(pi, dict):
ported_info_list.append(PortedInfo(
OriginalName=pi.get("OriginalName"),
OriginalLineType=pi.get("OriginalLineType"),
PortedDate=pi.get("PortedDate"),
LATA=pi.get("LATA")
))
exchange_info_results.append(ExchangeInfo(
PhoneNumber=ei.get("PhoneNumber"),
Name=ei.get("Name"),
City=ei.get("City"),
State=ei.get("State"),
Country=ei.get("Country"),
LineType=ei.get("LineType"),
TimeZone=ei.get("TimeZone"),
Latitude=ei.get("Latitude"),
Longitude=ei.get("Longitude"),
SMSAddress=ei.get("SMSAddress"),
MMSAddress=ei.get("MMSAddress"),
PortedInfo=ported_info_list,
NoteCodes=ei.get("NoteCodes", []),
NoteDescriptions=ei.get("NoteDescriptions", [])
))
return PE2Response(
ExchangeInfoResults=exchange_info_results,
Error=error
)
except requests.RequestException as req_exc:
# Network or HTTP-level error occurred
if is_live:
try:
# Fallback to backup URL
response = requests.get(backup_url, params=params, timeout=10)
response.raise_for_status()
data = response.json()
if "Error" in data:
raise RuntimeError(f"Phone Exchange backup error: {data['Error']}") from req_exc
error = Error(**data.get("Error", {})) if data.get("Error") else None
exchange_info_results = []
if "ExchangeInfoResults" in data:
for ei in data.get("ExchangeInfoResults", []):
if isinstance(ei, dict):
ported_info_list = []
if "PortedInfo" in ei and ei.get("PortedInfo"):
for pi in ei.get("PortedInfo", []):
if isinstance(pi, dict):
ported_info_list.append(PortedInfo(
OriginalName=pi.get("OriginalName"),
OriginalLineType=pi.get("OriginalLineType"),
PortedDate=pi.get("PortedDate"),
LATA=pi.get("LATA")
))
exchange_info_results.append(ExchangeInfo(
PhoneNumber=ei.get("PhoneNumber"),
Name=ei.get("Name"),
City=ei.get("City"),
State=ei.get("State"),
Country=ei.get("Country"),
LineType=ei.get("LineType"),
TimeZone=ei.get("TimeZone"),
Latitude=ei.get("Latitude"),
Longitude=ei.get("Longitude"),
SMSAddress=ei.get("SMSAddress"),
MMSAddress=ei.get("MMSAddress"),
PortedInfo=ported_info_list,
NoteCodes=ei.get("NoteCodes", []),
NoteDescriptions=ei.get("NoteDescriptions", [])
))
return PE2Response(
ExchangeInfoResults=exchange_info_results,
Error=error
)
except Exception as backup_exc:
raise RuntimeError("Phone Exchange service unreachable on both endpoints") from backup_exc
else:
raise RuntimeError(f"Phone Exchange trial error: {str(req_exc)}") from req_exc
from asyncio.windows_events import NULL
from dataclasses import dataclass
from typing import Optional, List, Type
@dataclass
class Error:
Desc: Optional[str] = None
TypeCode: Optional[str] = None
DescCode: Optional[str] = None
Type: Optional[str] = None
def __str__(self) -> str:
return f"Error: Desc={self.Desc}, TypeCode={self.TypeCode}, DescCode={self.DescCode}, Type={self.Type}"
@dataclass
class PortedInfo:
OriginalName: Optional[str] = None
OriginalLineType: Optional[str] = None
PortedDate: Optional[str] = None
LATA: Optional[str] = None
def __str__(self) -> str:
return (f"PortedInfo: OriginalName={self.OriginalName}, OriginalLineType={self.OriginalLineType}, "
f"PortedDate={self.PortedDate}, LATA={self.LATA}")
@dataclass
class ExchangeInfo:
PhoneNumber: Optional[str] = None
Name: Optional[str] = None
City: Optional[str] = None
State: Optional[str] = None
Country: Optional[str] = None
LineType: Optional[str] = None
TimeZone: Optional[str] = None
Latitude: Optional[str] = None
Longitude: Optional[str] = None
SMSAddress: Optional[str] = None
MMSAddress: Optional[str] = None
PortedInfo: Optional['PortedInfo'] = None
NoteCodes: Optional[str] = None
NoteDescriptions: Optional[str] = None
def __post_init__(self):
if self.NoteCodes is None:
self.NoteCodes = ""
if self.NoteDescriptions is None:
self.NoteDescriptions = ""
def __str__(self) -> str:
return (f"ExchangeInfo: PhoneNumber={self.PhoneNumber}, Name={self.Name}, City={self.City}, "
f"State={self.State}, Country={self.Country}, LineType={self.LineType}, "
f"TimeZone={self.TimeZone}, Latitude={self.Latitude}, Longitude={self.Longitude}, "
f"SMSAddress={self.SMSAddress}, MMSAddress={self.MMSAddress}, "
f"PortedInfo={self.PortedInfo}, NoteCodes=[{self.NoteCodes}], "
f"NoteDescriptions={self.NoteDescriptions}")
@dataclass
class InternationalExchangeInfo:
PhoneNumberIn: Optional[str] = None
CountryCode: Optional[str] = None
FormatNational: Optional[str] = None
Extension: Optional[str] = None
Locality: Optional[str] = None
LocalityMatchLevel: Optional[str] = None
TimeZone: Optional[str] = None
Latitude: Optional[str] = None
Longitude: Optional[str] = None
Country: Optional[str] = None
CountryISO2: Optional[str] = None
CountryISO3: Optional[str] = None
FormatInternational: Optional[str] = None
FormatE164: Optional[str] = None
Carrier: Optional[str] = None
LineType: Optional[str] = None
SMSAddress: Optional[str] = None
MMSAddress: Optional[str] = None
IsValid: bool = False
IsValidForRegion: bool = False
NoteCodes: Optional[str] = None
NoteDescriptions: Optional[str] = None
def __post_init__(self):
if self.NoteCodes is None:
self.NoteCodes = ""
if self.NoteDescriptions is None:
self.NoteDescriptions = ""
def __str__(self) -> str:
return (f"InternationalExchangeInfo: PhoneNumberIn={self.PhoneNumberIn}, CountryCode={self.CountryCode}, "
f"FormatNational={self.FormatNational}, Extension={self.Extension}, Locality={self.Locality}, "
f"LocalityMatchLevel={self.LocalityMatchLevel}, TimeZone={self.TimeZone}, "
f"Latitude={self.Latitude}, Longitude={self.Longitude}, Country={self.Country}, "
f"CountryISO2={self.CountryISO2}, CountryISO3={self.CountryISO3}, "
f"FormatInternational={self.FormatInternational}, FormatE164={self.FormatE164}, "
f"Carrier={self.Carrier}, LineType={self.LineType}, SMSAddress={self.SMSAddress}, "
f"MMSAddress={self.MMSAddress}, IsValid={self.IsValid}, IsValidForRegion={self.IsValidForRegion}, "
f"NoteCodes={self.NoteCodes}, NoteDescriptions={self.NoteDescriptions}")
@dataclass
class PE2Response:
ExchangeInfoResults: Optional[List['ExchangeInfo']] = None
InternationalExchangeInfo: Optional['InternationalExchangeInfo'] = None
Error: Optional['Error'] = None
def __post_init__(self):
if self.ExchangeInfoResults is None:
self.ExchangeInfoResults = []
def __str__(self) -> str:
exchange_info_str = '\n'.join(str(r) for r in self.ExchangeInfoResults) if self.ExchangeInfoResults else 'None'
error_str = str(self.Error) if self.Error else 'None'
return (f"PE2Response: ExchangeInfoResults=[\n{exchange_info_str}\n], "
f"InternationalExchangeInfo=\n{self.InternationalExchangeInfo}\n, Error={error_str}")
Phone Exchange NodeJS Rest Code Snippet
import axios from 'axios';
import querystring from 'querystring';
import {PE2Response} from './pe2_response.js';
/**
* @constant
* @type {string}
* @description The base URL for the live ServiceObjects Phone Exchange (PE2) API service.
*/
const LiveBaseUrl = 'https://sws.serviceobjects.com/pe2/web.svc/json/';
/**
* @constant
* @type {string}
* @description The base URL for the backup ServiceObjects Phone Exchange (PE2) API service.
*/
const BackupBaseUrl = 'https://swsbackup.serviceobjects.com/pe2/web.svc/json/';
/**
* @constant
* @type {string}
* @description The base URL for the trial ServiceObjects Phone Exchange (PE2) API service.
*/
const TrialBaseUrl = 'https://trial.serviceobjects.com/pe2/web.svc/json/';
/**
* <summary>
* Checks if a response from the API is valid by verifying that it either has no Error object
* or the Error.TypeCode is not equal to '3'.
* </summary>
* <param name="response" type="Object">The API response object to validate.</param>
* <returns type="boolean">True if the response is valid, false otherwise.</returns>
*/
const isValid = (response) => !response?.Error || response.Error.TypeCode !== '3';
/**
* <summary>
* Constructs a full URL for the GetExchangeInfo API endpoint by combining the base URL
* with query parameters derived from the input parameters.
* </summary>
* <param name="params" type="Object">An object containing all the input parameters.</param>
* <param name="baseUrl" type="string">The base URL for the API service (live, backup, or trial).</param>
* <returns type="string">The constructed URL with query parameters.</returns>
*/
const buildUrl = (params, baseUrl) =>
`${baseUrl}GetExchangeInfo?${querystring.stringify(params)}`;
/**
* <summary>
* Performs an HTTP GET request to the specified URL with a given timeout.
* </summary>
* <param name="url" type="string">The URL to send the GET request to.</param>
* <param name="timeoutSeconds" type="number">The timeout duration in seconds for the request.</param>
* <returns type="Promise<PE2Response>">A promise that resolves to a PE2Response object containing the API response data.</returns>
* <exception cref="Error">Thrown if the HTTP request fails, with a message detailing the error.</exception>
*/
const httpGet = async (url, timeoutSeconds) => {
try {
const response = await axios.get(url, { timeout: timeoutSeconds * 1000 });
return new PE2Response(response.data);
} catch (error) {
throw new Error(`HTTP request failed: ${error.message}`);
}
};
/**
* <summary>
* Provides functionality to call the ServiceObjects Phone Exchange (PE2) API's GetExchangeInfo endpoint,
* retrieving phone exchange information (e.g., carrier, line type, ported status) for a given US/Canada phone number
* with fallback to a backup endpoint for reliability in live mode.
* </summary>
*/
const GetExchangeInfoClient = {
/**
* <summary>
* Asynchronously invokes the GetExchangeInfo API endpoint, attempting the primary endpoint
* first and falling back to the backup if the response is invalid (Error.TypeCode == '3') in live mode.
* </summary>
* @param {string} PhoneNumber - The phone number to validate (e.g., "1234567890").
* @param {string} LicenseKey - Your license key to use the service.
* @param {boolean} isLive - Value to determine whether to use the live or trial servers.
* @param {number} timeoutSeconds - Timeout, in seconds, for the call to the service.
* @returns {Promise<PE2Response>} - A promise that resolves to a PE2Response object.
*/
async invokeAsync(PhoneNumber, LicenseKey, isLive = true, timeoutSeconds = 15) {
const params = {
PhoneNumber,
LicenseKey
};
const url = buildUrl(params, isLive ? LiveBaseUrl : TrialBaseUrl);
let response = await httpGet(url, timeoutSeconds);
if (isLive && !isValid(response)) {
const fallbackUrl = buildUrl(params, BackupBaseUrl);
const fallbackResponse = await httpGet(fallbackUrl, timeoutSeconds);
return fallbackResponse;
}
return response;
},
/**
* <summary>
* Synchronously invokes the GetExchangeInfo API endpoint by wrapping the async call
* and awaiting its result immediately.
* </summary>
* @param {string} PhoneNumber - The phone number to validate (e.g., "1234567890").
* @param {string} LicenseKey - Your license key to use the service.
* @param {boolean} isLive - Value to determine whether to use the live or trial servers.
* @param {number} timeoutSeconds - Timeout, in seconds, for the call to the service.
* @returns {PE2Response} - A PE2Response object with phone exchange details or an error.
*/
invoke(PhoneNumber, LicenseKey, isLive = true, timeoutSeconds = 15) {
return (async () => await this.invokeAsync(
PhoneNumber, LicenseKey, isLive, timeoutSeconds
))();
}
};
export { GetExchangeInfoClient, PE2Response };
export class ExchangeInfo {
constructor(data = {}) {
this.PhoneNumber = data.PhoneNumber;
this.Name = data.Name;
this.City = data.City;
this.State = data.State;
this.Country = data.Country;
this.LineType = data.LineType;
this.TimeZone = data.TimeZone;
this.Latitude = data.Latitude;
this.Longitude = data.Longitude;
this.SMSAddress = data.SMSAddress;
this.MMSAddress = data.MMSAddress;
this.PortedInfo = data.PortedInfo;
this.NoteCodes = data.NoteCodes;
this.NoteDescriptions = data.NoteDescriptions;
}
toString() {
return `ExchangeInfo: PhoneNumber = ${this.PhoneNumber}, Name = ${this.Name}, City = ${this.City}, State = ${this.State}, Country = ${this.Country}, LineType = ${this.LineType}, TimeZone = ${this.TimeZone}, Latitude = ${this.Latitude}, Longitude = ${this.Longitude}, SMSAddress = ${this.SMSAddress}, MMSAddress = ${this.MMSAddress}, PortedInfo = ${this.PortedInfo}, NoteCodes = ${this.NoteCodes}, NoteDescriptions = ${this.NoteDescriptions}`;
}
}
/**
* Ported information for a phone number.
*/
export class PortedInfo {
constructor(data = {}) {
this.OriginalName = data.OriginalName;
this.OriginalLineType = data.OriginalLineType;
this.PortedDate = data.PortedDate;
this.LATA = data.LATA;
}
toString() {
return `PortedInfo: OriginalName = ${this.OriginalName}, OriginalLineType = ${this.OriginalLineType}, PortedDate = ${this.PortedDate}, LATA = ${this.LATA}`;
}
}
/**
* International phone exchange information for a validated phone number.
*/
export class InternationalExchangeInfo {
constructor(data = {}) {
this.PhoneNumberIn = data.NumberIn;
this.CountryCode = data.CountryCode;
this.FormatNational = data.FormatNational;
this.Extension = data.Extension;
this.Locality = data.Locality;
this.LocalityMatchLevel = data.LocalityMatchLevel;
this.TimeZone = data.TimeZone;
this.Latitude = data.Latitude;
this.Longitude = data.Longitude;
this.Country = data.Country;
this.CountryISO2 = data.CountryISO2;
this.CountryISO3 = data.CountryISO3;
this.FormatInternational = data.FormatInternational;
this.FormatE164 = data.FormatE164;
this.Carrier = data.Carrier;
this.LineType = data.LineType;
this.SMSAddress = data.SMSAddress;
this.MMSAddress = data.MMSAddress;
this.IsValid = data.IsValid !== undefined ? data.IsValid : null;
this.IsValidForRegion = data.IsValidForRegion !== undefined ? data.IsValidForRegion : null;
this.NoteCodes = data.NoteCodes;
this.NoteDescriptions = data.NoteDescriptions;
}
toString() {
return `InternationalExchangeInfo: PhoneNumberIn = ${this.PhoneNumberIn}, CountryCode = ${this.CountryCode}, FormatNational = ${this.FormatNational}, Extension = ${this.Extension}, Locality = ${this.Locality}, LocalityMatchLevel = ${this.LocalityMatchLevel}, TimeZone = ${this.TimeZone}, Latitude = ${this.Latitude}, Longitude = ${this.Longitude}, Country = ${this.Country}, CountryISO2 = ${this.CountryISO2}, CountryISO3 = ${this.CountryISO3}, FormatInternational = ${this.FormatInternational}, FormatE164 = ${this.FormatE164}, Carrier = ${this.Carrier}, LineType = ${this.LineType}, SMSAddress = ${this.SMSAddress}, MMSAddress = ${this.MMSAddress}, IsValid = ${this.IsValid}, IsValidForRegion = ${this.IsValidForRegion}, NoteCodes = ${this.NoteCodes}, NoteDescriptions = ${this.NoteDescriptions}`;
}
}
/**
* Error object for PE2 API responses.
*/
export class Error {
constructor(data = {}) {
this.Desc = data.Desc;
this.TypeCode = data.TypeCode;
this.DescCode = data.DescCode;
this.Type = data.Type;
}
toString() {
return `Error: Desc = ${this.Desc}, TypeCode = ${this.TypeCode}, DescCode = ${this.DescCode}, Type= ${this.Type}}`;
}
}
/**
* Response from PE2 GetExchangeInfo and GetInternationalExchangeInfo APIs, containing phone exchange information.
*/
export class PE2Response {
constructor(data = {}) {
this.ExchangeInfo = Array.isArray(data.ExchangeInfoResults)
? data.ExchangeInfoResults.map(info => new ExchangeInfo(info))
: [];
this.ExchangeInfoResults = (data.ExchangeInfoResults || []).map(info => new ExchangeInfo(info));
this.InternationalExchangeInfo = data.InternationalExchangeInfo ? new InternationalExchangeInfo(data.InternationalExchangeInfo) : null;
this.Error = data.Error ? new Error(data.Error) : null;
}
toString() {
const exchangeInfoString = this.ExchangeInfoResults.length
? this.ExchangeInfoResults.map(info => info.toString()).join('; ')
: 'null';
const internationalInfoString = this.InternationalExchangeInfo.length
? this.InternationalExchangeInfo.map(info => info.toString()).join('; ')
: 'null';
return `PE2Response: ExchangeInfoResults = [${exchangeInfoString}], InternationalExchangeInfo = [${internationalInfoString}], Error = ${this.Error ? this.Error.toString() : 'null'}`;
}
}
export default PE2Response;