mirror of
https://dev.azure.com/globalhealthx/EMR/_git/helix-engage-server
synced 2026-04-11 18:08:16 +00:00
lint and format
This commit is contained in:
@@ -4,463 +4,530 @@ import axios from 'axios';
|
||||
|
||||
@Injectable()
|
||||
export class OzonetelAgentService {
|
||||
private readonly logger = new Logger(OzonetelAgentService.name);
|
||||
private readonly apiDomain: string;
|
||||
private readonly apiKey: string;
|
||||
private readonly accountId: string;
|
||||
private cachedToken: string | null = null;
|
||||
private tokenExpiry: number = 0;
|
||||
private readonly logger = new Logger(OzonetelAgentService.name);
|
||||
private readonly apiDomain: string;
|
||||
private readonly apiKey: string;
|
||||
private readonly accountId: string;
|
||||
private cachedToken: string | null = null;
|
||||
private tokenExpiry: number = 0;
|
||||
|
||||
constructor(private config: ConfigService) {
|
||||
this.apiDomain = config.get<string>('exotel.subdomain') ?? 'in1-ccaas-api.ozonetel.com';
|
||||
this.apiKey = config.get<string>('exotel.apiKey') ?? '';
|
||||
this.accountId = config.get<string>('exotel.accountSid') ?? '';
|
||||
constructor(private config: ConfigService) {
|
||||
this.apiDomain =
|
||||
config.get<string>('exotel.subdomain') ?? 'in1-ccaas-api.ozonetel.com';
|
||||
this.apiKey = config.get<string>('exotel.apiKey') ?? '';
|
||||
this.accountId = config.get<string>('exotel.accountSid') ?? '';
|
||||
}
|
||||
|
||||
private async getToken(): Promise<string> {
|
||||
if (this.cachedToken && Date.now() < this.tokenExpiry) {
|
||||
return this.cachedToken;
|
||||
}
|
||||
|
||||
private async getToken(): Promise<string> {
|
||||
if (this.cachedToken && Date.now() < this.tokenExpiry) {
|
||||
return this.cachedToken;
|
||||
}
|
||||
const url = `https://${this.apiDomain}/ca_apis/CAToken/generateToken`;
|
||||
this.logger.log('Generating CloudAgent API token');
|
||||
|
||||
const url = `https://${this.apiDomain}/ca_apis/CAToken/generateToken`;
|
||||
this.logger.log('Generating CloudAgent API token');
|
||||
const response = await axios.post(
|
||||
url,
|
||||
{ userName: this.accountId },
|
||||
{
|
||||
headers: { apiKey: this.apiKey, 'Content-Type': 'application/json' },
|
||||
},
|
||||
);
|
||||
|
||||
const response = await axios.post(url, { userName: this.accountId }, {
|
||||
headers: { apiKey: this.apiKey, 'Content-Type': 'application/json' },
|
||||
});
|
||||
|
||||
const data = response.data;
|
||||
if (data.token) {
|
||||
this.cachedToken = data.token;
|
||||
this.tokenExpiry = Date.now() + 55 * 60 * 1000;
|
||||
this.logger.log('CloudAgent token generated successfully');
|
||||
return data.token;
|
||||
}
|
||||
|
||||
throw new Error(data.message ?? 'Token generation failed');
|
||||
const data = response.data;
|
||||
if (data.token) {
|
||||
this.cachedToken = data.token;
|
||||
this.tokenExpiry = Date.now() + 55 * 60 * 1000;
|
||||
this.logger.log('CloudAgent token generated successfully');
|
||||
return data.token;
|
||||
}
|
||||
|
||||
async loginAgent(params: {
|
||||
agentId: string;
|
||||
password: string;
|
||||
phoneNumber: string;
|
||||
mode?: string;
|
||||
}): Promise<{ status: string; message: string }> {
|
||||
const url = `https://${this.apiDomain}/CAServices/AgentAuthenticationV2/index.php`;
|
||||
throw new Error(data.message ?? 'Token generation failed');
|
||||
}
|
||||
|
||||
this.logger.log(`Logging in agent ${params.agentId} with phone ${params.phoneNumber}`);
|
||||
async loginAgent(params: {
|
||||
agentId: string;
|
||||
password: string;
|
||||
phoneNumber: string;
|
||||
mode?: string;
|
||||
}): Promise<{ status: string; message: string }> {
|
||||
const url = `https://${this.apiDomain}/CAServices/AgentAuthenticationV2/index.php`;
|
||||
|
||||
try {
|
||||
const response = await axios.post(
|
||||
url,
|
||||
new URLSearchParams({
|
||||
userName: this.accountId,
|
||||
apiKey: this.apiKey,
|
||||
phoneNumber: params.phoneNumber,
|
||||
action: 'login',
|
||||
mode: params.mode ?? 'blended',
|
||||
state: 'Ready',
|
||||
}).toString(),
|
||||
{
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
},
|
||||
auth: {
|
||||
username: params.agentId,
|
||||
password: params.password,
|
||||
},
|
||||
},
|
||||
);
|
||||
this.logger.log(
|
||||
`Logging in agent ${params.agentId} with phone ${params.phoneNumber}`,
|
||||
);
|
||||
|
||||
const data = response.data;
|
||||
try {
|
||||
const response = await axios.post(
|
||||
url,
|
||||
new URLSearchParams({
|
||||
userName: this.accountId,
|
||||
apiKey: this.apiKey,
|
||||
phoneNumber: params.phoneNumber,
|
||||
action: 'login',
|
||||
mode: params.mode ?? 'blended',
|
||||
state: 'Ready',
|
||||
}).toString(),
|
||||
{
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
},
|
||||
auth: {
|
||||
username: params.agentId,
|
||||
password: params.password,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
// "already logged in" is not a real error — treat as success
|
||||
if (data.status === 'error' && data.message?.includes('already logged in')) {
|
||||
this.logger.log(`Agent ${params.agentId} already logged in — treating as success`);
|
||||
return { status: 'success', message: data.message };
|
||||
}
|
||||
const data = response.data;
|
||||
|
||||
this.logger.log(`Agent login response: ${JSON.stringify(data)}`);
|
||||
return data;
|
||||
} catch (error: any) {
|
||||
this.logger.error(`Agent login failed: ${error.message}`);
|
||||
throw error;
|
||||
}
|
||||
// "already logged in" is not a real error — treat as success
|
||||
if (
|
||||
data.status === 'error' &&
|
||||
data.message?.includes('already logged in')
|
||||
) {
|
||||
this.logger.log(
|
||||
`Agent ${params.agentId} already logged in — treating as success`,
|
||||
);
|
||||
return { status: 'success', message: data.message };
|
||||
}
|
||||
|
||||
this.logger.log(`Agent login response: ${JSON.stringify(data)}`);
|
||||
return data;
|
||||
} catch (error: any) {
|
||||
this.logger.error(`Agent login failed: ${error.message}`);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async manualDial(params: {
|
||||
agentId: string;
|
||||
campaignName: string;
|
||||
customerNumber: string;
|
||||
}): Promise<{ status: string; ucid?: string; message?: string }> {
|
||||
const url = `https://${this.apiDomain}/ca_apis/AgentManualDial`;
|
||||
async manualDial(params: {
|
||||
agentId: string;
|
||||
campaignName: string;
|
||||
customerNumber: string;
|
||||
}): Promise<{ status: string; ucid?: string; message?: string }> {
|
||||
const url = `https://${this.apiDomain}/ca_apis/AgentManualDial`;
|
||||
|
||||
this.logger.log(`Manual dial: agent=${params.agentId} campaign=${params.campaignName} number=${params.customerNumber}`);
|
||||
this.logger.log(
|
||||
`Manual dial: agent=${params.agentId} campaign=${params.campaignName} number=${params.customerNumber}`,
|
||||
);
|
||||
|
||||
try {
|
||||
const token = await this.getToken();
|
||||
const response = await axios.post(url, {
|
||||
userName: this.accountId,
|
||||
agentID: params.agentId,
|
||||
campaignName: params.campaignName,
|
||||
customerNumber: params.customerNumber,
|
||||
UCID: 'true',
|
||||
}, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
try {
|
||||
const token = await this.getToken();
|
||||
const response = await axios.post(
|
||||
url,
|
||||
{
|
||||
userName: this.accountId,
|
||||
agentID: params.agentId,
|
||||
campaignName: params.campaignName,
|
||||
customerNumber: params.customerNumber,
|
||||
UCID: 'true',
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
this.logger.log(`Manual dial response: ${JSON.stringify(response.data)}`);
|
||||
return response.data;
|
||||
} catch (error: any) {
|
||||
const responseData = error?.response?.data ? JSON.stringify(error.response.data) : '';
|
||||
this.logger.error(`Manual dial failed: ${error.message} ${responseData}`);
|
||||
throw error;
|
||||
}
|
||||
this.logger.log(`Manual dial response: ${JSON.stringify(response.data)}`);
|
||||
return response.data;
|
||||
} catch (error: any) {
|
||||
const responseData = error?.response?.data
|
||||
? JSON.stringify(error.response.data)
|
||||
: '';
|
||||
this.logger.error(`Manual dial failed: ${error.message} ${responseData}`);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async changeAgentState(params: {
|
||||
agentId: string;
|
||||
state: 'Ready' | 'Pause';
|
||||
pauseReason?: string;
|
||||
}): Promise<{ status: string; message: string }> {
|
||||
const url = `https://${this.apiDomain}/ca_apis/changeAgentState`;
|
||||
async changeAgentState(params: {
|
||||
agentId: string;
|
||||
state: 'Ready' | 'Pause';
|
||||
pauseReason?: string;
|
||||
}): Promise<{ status: string; message: string }> {
|
||||
const url = `https://${this.apiDomain}/ca_apis/changeAgentState`;
|
||||
|
||||
this.logger.log(`Changing agent ${params.agentId} state to ${params.state}`);
|
||||
this.logger.log(
|
||||
`Changing agent ${params.agentId} state to ${params.state}`,
|
||||
);
|
||||
|
||||
try {
|
||||
const body: Record<string, string> = {
|
||||
userName: this.accountId,
|
||||
agentId: params.agentId,
|
||||
state: params.state,
|
||||
};
|
||||
if (params.pauseReason) {
|
||||
body.pauseReason = params.pauseReason;
|
||||
}
|
||||
try {
|
||||
const body: Record<string, string> = {
|
||||
userName: this.accountId,
|
||||
agentId: params.agentId,
|
||||
state: params.state,
|
||||
};
|
||||
if (params.pauseReason) {
|
||||
body.pauseReason = params.pauseReason;
|
||||
}
|
||||
|
||||
const token = await this.getToken();
|
||||
const response = await axios.post(url, body, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
const token = await this.getToken();
|
||||
const response = await axios.post(url, body, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
|
||||
this.logger.log(`Change agent state response: ${JSON.stringify(response.data)}`);
|
||||
return response.data;
|
||||
} catch (error: any) {
|
||||
const responseData = error?.response?.data ? JSON.stringify(error.response.data) : '';
|
||||
this.logger.error(`Change agent state failed: ${error.message} ${responseData}`);
|
||||
throw error;
|
||||
}
|
||||
this.logger.log(
|
||||
`Change agent state response: ${JSON.stringify(response.data)}`,
|
||||
);
|
||||
return response.data;
|
||||
} catch (error: any) {
|
||||
const responseData = error?.response?.data
|
||||
? JSON.stringify(error.response.data)
|
||||
: '';
|
||||
this.logger.error(
|
||||
`Change agent state failed: ${error.message} ${responseData}`,
|
||||
);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async setDisposition(params: {
|
||||
agentId: string;
|
||||
ucid: string;
|
||||
disposition: string;
|
||||
}): Promise<{ status: string; message?: string; details?: string }> {
|
||||
const url = `https://${this.apiDomain}/ca_apis/DispositionAPIV2`;
|
||||
const did = process.env.OZONETEL_DID ?? '918041763265';
|
||||
async setDisposition(params: {
|
||||
agentId: string;
|
||||
ucid: string;
|
||||
disposition: string;
|
||||
}): Promise<{ status: string; message?: string; details?: string }> {
|
||||
const url = `https://${this.apiDomain}/ca_apis/DispositionAPIV2`;
|
||||
const did = process.env.OZONETEL_DID ?? '918041763265';
|
||||
|
||||
this.logger.log(`Set disposition: agent=${params.agentId} ucid=${params.ucid} disposition=${params.disposition}`);
|
||||
this.logger.log(
|
||||
`Set disposition: agent=${params.agentId} ucid=${params.ucid} disposition=${params.disposition}`,
|
||||
);
|
||||
|
||||
try {
|
||||
const token = await this.getToken();
|
||||
const response = await axios.post(url, {
|
||||
userName: this.accountId,
|
||||
agentID: params.agentId,
|
||||
did,
|
||||
ucid: params.ucid,
|
||||
action: 'Set',
|
||||
disposition: params.disposition,
|
||||
autoRelease: 'true',
|
||||
}, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
try {
|
||||
const token = await this.getToken();
|
||||
const response = await axios.post(
|
||||
url,
|
||||
{
|
||||
userName: this.accountId,
|
||||
agentID: params.agentId,
|
||||
did,
|
||||
ucid: params.ucid,
|
||||
action: 'Set',
|
||||
disposition: params.disposition,
|
||||
autoRelease: 'true',
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
this.logger.log(`Set disposition response: ${JSON.stringify(response.data)}`);
|
||||
return response.data;
|
||||
} catch (error: any) {
|
||||
const responseData = error?.response?.data ? JSON.stringify(error.response.data) : '';
|
||||
this.logger.error(`Set disposition failed: ${error.message} ${responseData}`);
|
||||
throw error;
|
||||
}
|
||||
this.logger.log(
|
||||
`Set disposition response: ${JSON.stringify(response.data)}`,
|
||||
);
|
||||
return response.data;
|
||||
} catch (error: any) {
|
||||
const responseData = error?.response?.data
|
||||
? JSON.stringify(error.response.data)
|
||||
: '';
|
||||
this.logger.error(
|
||||
`Set disposition failed: ${error.message} ${responseData}`,
|
||||
);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async callControl(params: {
|
||||
action: 'CONFERENCE' | 'HOLD' | 'UNHOLD' | 'MUTE' | 'UNMUTE' | 'KICK_CALL';
|
||||
ucid: string;
|
||||
conferenceNumber?: string;
|
||||
}): Promise<{ status: string; message: string; ucid?: string }> {
|
||||
const url = `https://${this.apiDomain}/ca_apis/CallControl_V4`;
|
||||
const did = process.env.OZONETEL_DID ?? '918041763265';
|
||||
const agentPhoneName = process.env.OZONETEL_SIP_ID ?? '523590';
|
||||
async callControl(params: {
|
||||
action: 'CONFERENCE' | 'HOLD' | 'UNHOLD' | 'MUTE' | 'UNMUTE' | 'KICK_CALL';
|
||||
ucid: string;
|
||||
conferenceNumber?: string;
|
||||
}): Promise<{ status: string; message: string; ucid?: string }> {
|
||||
const url = `https://${this.apiDomain}/ca_apis/CallControl_V4`;
|
||||
const did = process.env.OZONETEL_DID ?? '918041763265';
|
||||
const agentPhoneName = process.env.OZONETEL_SIP_ID ?? '523590';
|
||||
|
||||
this.logger.log(`Call control: action=${params.action} ucid=${params.ucid} conference=${params.conferenceNumber ?? 'none'}`);
|
||||
this.logger.log(
|
||||
`Call control: action=${params.action} ucid=${params.ucid} conference=${params.conferenceNumber ?? 'none'}`,
|
||||
);
|
||||
|
||||
try {
|
||||
const token = await this.getToken();
|
||||
const body: Record<string, string> = {
|
||||
userName: this.accountId,
|
||||
action: params.action,
|
||||
ucid: params.ucid,
|
||||
did,
|
||||
agentPhoneName,
|
||||
};
|
||||
if (params.conferenceNumber) {
|
||||
body.conferenceNumber = params.conferenceNumber;
|
||||
}
|
||||
try {
|
||||
const token = await this.getToken();
|
||||
const body: Record<string, string> = {
|
||||
userName: this.accountId,
|
||||
action: params.action,
|
||||
ucid: params.ucid,
|
||||
did,
|
||||
agentPhoneName,
|
||||
};
|
||||
if (params.conferenceNumber) {
|
||||
body.conferenceNumber = params.conferenceNumber;
|
||||
}
|
||||
|
||||
const response = await axios.post(url, body, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
const response = await axios.post(url, body, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
|
||||
this.logger.log(`Call control response: ${JSON.stringify(response.data)}`);
|
||||
return response.data;
|
||||
} catch (error: any) {
|
||||
const responseData = error?.response?.data ? JSON.stringify(error.response.data) : '';
|
||||
this.logger.error(`Call control failed: ${error.message} ${responseData}`);
|
||||
throw error;
|
||||
}
|
||||
this.logger.log(
|
||||
`Call control response: ${JSON.stringify(response.data)}`,
|
||||
);
|
||||
return response.data;
|
||||
} catch (error: any) {
|
||||
const responseData = error?.response?.data
|
||||
? JSON.stringify(error.response.data)
|
||||
: '';
|
||||
this.logger.error(
|
||||
`Call control failed: ${error.message} ${responseData}`,
|
||||
);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async pauseRecording(params: {
|
||||
ucid: string;
|
||||
action: 'pause' | 'unPause';
|
||||
}): Promise<{ status: string; message: string }> {
|
||||
const url = `https://${this.apiDomain}/CAServices/Call/Record.php`;
|
||||
async pauseRecording(params: {
|
||||
ucid: string;
|
||||
action: 'pause' | 'unPause';
|
||||
}): Promise<{ status: string; message: string }> {
|
||||
const url = `https://${this.apiDomain}/CAServices/Call/Record.php`;
|
||||
|
||||
this.logger.log(`Recording ${params.action}: ucid=${params.ucid}`);
|
||||
this.logger.log(`Recording ${params.action}: ucid=${params.ucid}`);
|
||||
|
||||
try {
|
||||
const response = await axios.get(url, {
|
||||
params: {
|
||||
userName: this.accountId,
|
||||
apiKey: this.apiKey,
|
||||
action: params.action,
|
||||
ucid: params.ucid,
|
||||
},
|
||||
});
|
||||
try {
|
||||
const response = await axios.get(url, {
|
||||
params: {
|
||||
userName: this.accountId,
|
||||
apiKey: this.apiKey,
|
||||
action: params.action,
|
||||
ucid: params.ucid,
|
||||
},
|
||||
});
|
||||
|
||||
this.logger.log(`Recording control response: ${JSON.stringify(response.data)}`);
|
||||
return response.data;
|
||||
} catch (error: any) {
|
||||
const responseData = error?.response?.data ? JSON.stringify(error.response.data) : '';
|
||||
this.logger.error(`Recording control failed: ${error.message} ${responseData}`);
|
||||
throw error;
|
||||
}
|
||||
this.logger.log(
|
||||
`Recording control response: ${JSON.stringify(response.data)}`,
|
||||
);
|
||||
return response.data;
|
||||
} catch (error: any) {
|
||||
const responseData = error?.response?.data
|
||||
? JSON.stringify(error.response.data)
|
||||
: '';
|
||||
this.logger.error(
|
||||
`Recording control failed: ${error.message} ${responseData}`,
|
||||
);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async getAbandonCalls(params?: {
|
||||
fromTime?: string;
|
||||
toTime?: string;
|
||||
campaignName?: string;
|
||||
}): Promise<Array<{
|
||||
monitorUCID: string;
|
||||
type: string;
|
||||
status: string;
|
||||
campaign: string;
|
||||
callerID: string;
|
||||
did: string;
|
||||
agentID: string;
|
||||
agent: string;
|
||||
hangupBy: string;
|
||||
callTime: string;
|
||||
}>> {
|
||||
const url = `https://${this.apiDomain}/ca_apis/abandonCalls`;
|
||||
async getAbandonCalls(params?: {
|
||||
fromTime?: string;
|
||||
toTime?: string;
|
||||
campaignName?: string;
|
||||
}): Promise<
|
||||
Array<{
|
||||
monitorUCID: string;
|
||||
type: string;
|
||||
status: string;
|
||||
campaign: string;
|
||||
callerID: string;
|
||||
did: string;
|
||||
agentID: string;
|
||||
agent: string;
|
||||
hangupBy: string;
|
||||
callTime: string;
|
||||
}>
|
||||
> {
|
||||
const url = `https://${this.apiDomain}/ca_apis/abandonCalls`;
|
||||
|
||||
this.logger.log('Fetching abandon calls');
|
||||
this.logger.log('Fetching abandon calls');
|
||||
|
||||
try {
|
||||
const token = await this.getToken();
|
||||
const body: Record<string, string> = { userName: this.accountId };
|
||||
if (params?.fromTime) body.fromTime = params.fromTime;
|
||||
if (params?.toTime) body.toTime = params.toTime;
|
||||
if (params?.campaignName) body.campaignName = params.campaignName;
|
||||
try {
|
||||
const token = await this.getToken();
|
||||
const body: Record<string, string> = { userName: this.accountId };
|
||||
if (params?.fromTime) body.fromTime = params.fromTime;
|
||||
if (params?.toTime) body.toTime = params.toTime;
|
||||
if (params?.campaignName) body.campaignName = params.campaignName;
|
||||
|
||||
const response = await axios({
|
||||
method: 'GET',
|
||||
url,
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
data: JSON.stringify(body),
|
||||
});
|
||||
const response = await axios({
|
||||
method: 'GET',
|
||||
url,
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
data: JSON.stringify(body),
|
||||
});
|
||||
|
||||
const data = response.data;
|
||||
this.logger.log(`Abandon calls response: ${JSON.stringify(data).substring(0, 200)}`);
|
||||
if (data.status === 'success' && Array.isArray(data.message)) {
|
||||
return data.message;
|
||||
}
|
||||
return [];
|
||||
} catch (error: any) {
|
||||
this.logger.error(`Abandon calls failed: ${error.message}`);
|
||||
return [];
|
||||
}
|
||||
const data = response.data;
|
||||
this.logger.log(
|
||||
`Abandon calls response: ${JSON.stringify(data).substring(0, 200)}`,
|
||||
);
|
||||
if (data.status === 'success' && Array.isArray(data.message)) {
|
||||
return data.message;
|
||||
}
|
||||
return [];
|
||||
} catch (error: any) {
|
||||
this.logger.error(`Abandon calls failed: ${error.message}`);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
async fetchCDR(params: {
|
||||
date: string; // YYYY-MM-DD
|
||||
campaignName?: string;
|
||||
status?: string;
|
||||
callType?: string;
|
||||
}): Promise<Array<Record<string, any>>> {
|
||||
const url = `https://${this.apiDomain}/ca_reports/fetchCDRDetails`;
|
||||
async fetchCDR(params: {
|
||||
date: string; // YYYY-MM-DD
|
||||
campaignName?: string;
|
||||
status?: string;
|
||||
callType?: string;
|
||||
}): Promise<Array<Record<string, any>>> {
|
||||
const url = `https://${this.apiDomain}/ca_reports/fetchCDRDetails`;
|
||||
|
||||
this.logger.log(`Fetch CDR: date=${params.date}`);
|
||||
this.logger.log(`Fetch CDR: date=${params.date}`);
|
||||
|
||||
try {
|
||||
const token = await this.getToken();
|
||||
const body: Record<string, string> = {
|
||||
userName: this.accountId,
|
||||
fromDate: `${params.date} 00:00:00`,
|
||||
toDate: `${params.date} 23:59:59`,
|
||||
};
|
||||
if (params.campaignName) body.campaignName = params.campaignName;
|
||||
if (params.status) body.status = params.status;
|
||||
if (params.callType) body.callType = params.callType;
|
||||
try {
|
||||
const token = await this.getToken();
|
||||
const body: Record<string, string> = {
|
||||
userName: this.accountId,
|
||||
fromDate: `${params.date} 00:00:00`,
|
||||
toDate: `${params.date} 23:59:59`,
|
||||
};
|
||||
if (params.campaignName) body.campaignName = params.campaignName;
|
||||
if (params.status) body.status = params.status;
|
||||
if (params.callType) body.callType = params.callType;
|
||||
|
||||
const response = await axios({
|
||||
method: 'GET',
|
||||
url,
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
data: JSON.stringify(body),
|
||||
});
|
||||
const response = await axios({
|
||||
method: 'GET',
|
||||
url,
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
data: JSON.stringify(body),
|
||||
});
|
||||
|
||||
const data = response.data;
|
||||
if (data.status === 'success' && Array.isArray(data.details)) {
|
||||
return data.details;
|
||||
}
|
||||
return [];
|
||||
} catch (error: any) {
|
||||
const responseData = error?.response?.data ? JSON.stringify(error.response.data) : '';
|
||||
this.logger.error(`Fetch CDR failed: ${error.message} ${responseData}`);
|
||||
return [];
|
||||
}
|
||||
const data = response.data;
|
||||
if (data.status === 'success' && Array.isArray(data.details)) {
|
||||
return data.details;
|
||||
}
|
||||
return [];
|
||||
} catch (error: any) {
|
||||
const responseData = error?.response?.data
|
||||
? JSON.stringify(error.response.data)
|
||||
: '';
|
||||
this.logger.error(`Fetch CDR failed: ${error.message} ${responseData}`);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
async getAgentSummary(agentId: string, date: string): Promise<{
|
||||
totalLoginDuration: string;
|
||||
totalBusyTime: string;
|
||||
totalIdleTime: string;
|
||||
totalPauseTime: string;
|
||||
totalWrapupTime: string;
|
||||
totalDialTime: string;
|
||||
} | null> {
|
||||
const url = `https://${this.apiDomain}/ca_reports/summaryReport`;
|
||||
async getAgentSummary(
|
||||
agentId: string,
|
||||
date: string,
|
||||
): Promise<{
|
||||
totalLoginDuration: string;
|
||||
totalBusyTime: string;
|
||||
totalIdleTime: string;
|
||||
totalPauseTime: string;
|
||||
totalWrapupTime: string;
|
||||
totalDialTime: string;
|
||||
} | null> {
|
||||
const url = `https://${this.apiDomain}/ca_reports/summaryReport`;
|
||||
|
||||
try {
|
||||
const token = await this.getToken();
|
||||
const response = await axios({
|
||||
method: 'GET',
|
||||
url,
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
data: JSON.stringify({
|
||||
userName: this.accountId,
|
||||
agentId,
|
||||
fromDate: `${date} 00:00:00`,
|
||||
toDate: `${date} 23:59:59`,
|
||||
}),
|
||||
});
|
||||
try {
|
||||
const token = await this.getToken();
|
||||
const response = await axios({
|
||||
method: 'GET',
|
||||
url,
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
data: JSON.stringify({
|
||||
userName: this.accountId,
|
||||
agentId,
|
||||
fromDate: `${date} 00:00:00`,
|
||||
toDate: `${date} 23:59:59`,
|
||||
}),
|
||||
});
|
||||
|
||||
const data = response.data;
|
||||
if (data.status === 'success' && data.message) {
|
||||
const record = Array.isArray(data.message) ? data.message[0] : data.message;
|
||||
return {
|
||||
totalLoginDuration: record.TotalLoginDuration ?? '00:00:00',
|
||||
totalBusyTime: record.TotalBusyTime ?? '00:00:00',
|
||||
totalIdleTime: record.TotalIdleTime ?? '00:00:00',
|
||||
totalPauseTime: record.TotalPauseTime ?? '00:00:00',
|
||||
totalWrapupTime: record.TotalWrapupTime ?? '00:00:00',
|
||||
totalDialTime: record.TotalDialTime ?? '00:00:00',
|
||||
};
|
||||
}
|
||||
return null;
|
||||
} catch (error: any) {
|
||||
this.logger.error(`Agent summary failed: ${error.message}`);
|
||||
return null;
|
||||
}
|
||||
const data = response.data;
|
||||
if (data.status === 'success' && data.message) {
|
||||
const record = Array.isArray(data.message)
|
||||
? data.message[0]
|
||||
: data.message;
|
||||
return {
|
||||
totalLoginDuration: record.TotalLoginDuration ?? '00:00:00',
|
||||
totalBusyTime: record.TotalBusyTime ?? '00:00:00',
|
||||
totalIdleTime: record.TotalIdleTime ?? '00:00:00',
|
||||
totalPauseTime: record.TotalPauseTime ?? '00:00:00',
|
||||
totalWrapupTime: record.TotalWrapupTime ?? '00:00:00',
|
||||
totalDialTime: record.TotalDialTime ?? '00:00:00',
|
||||
};
|
||||
}
|
||||
return null;
|
||||
} catch (error: any) {
|
||||
this.logger.error(`Agent summary failed: ${error.message}`);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async getAHT(agentId: string): Promise<string> {
|
||||
const url = `https://${this.apiDomain}/ca_apis/aht`;
|
||||
async getAHT(agentId: string): Promise<string> {
|
||||
const url = `https://${this.apiDomain}/ca_apis/aht`;
|
||||
|
||||
try {
|
||||
const token = await this.getToken();
|
||||
const response = await axios({
|
||||
method: 'GET',
|
||||
url,
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
data: JSON.stringify({
|
||||
userName: this.accountId,
|
||||
agentId,
|
||||
}),
|
||||
});
|
||||
try {
|
||||
const token = await this.getToken();
|
||||
const response = await axios({
|
||||
method: 'GET',
|
||||
url,
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
data: JSON.stringify({
|
||||
userName: this.accountId,
|
||||
agentId,
|
||||
}),
|
||||
});
|
||||
|
||||
const data = response.data;
|
||||
if (data.status === 'success') {
|
||||
return data.AHT ?? '00:00:00';
|
||||
}
|
||||
return '00:00:00';
|
||||
} catch (error: any) {
|
||||
this.logger.error(`AHT failed: ${error.message}`);
|
||||
return '00:00:00';
|
||||
}
|
||||
const data = response.data;
|
||||
if (data.status === 'success') {
|
||||
return data.AHT ?? '00:00:00';
|
||||
}
|
||||
return '00:00:00';
|
||||
} catch (error: any) {
|
||||
this.logger.error(`AHT failed: ${error.message}`);
|
||||
return '00:00:00';
|
||||
}
|
||||
}
|
||||
|
||||
async logoutAgent(params: {
|
||||
agentId: string;
|
||||
password: string;
|
||||
}): Promise<{ status: string; message: string }> {
|
||||
const url = `https://${this.apiDomain}/CAServices/AgentAuthenticationV2/index.php`;
|
||||
async logoutAgent(params: {
|
||||
agentId: string;
|
||||
password: string;
|
||||
}): Promise<{ status: string; message: string }> {
|
||||
const url = `https://${this.apiDomain}/CAServices/AgentAuthenticationV2/index.php`;
|
||||
|
||||
this.logger.log(`Logging out agent ${params.agentId}`);
|
||||
this.logger.log(`Logging out agent ${params.agentId}`);
|
||||
|
||||
try {
|
||||
const response = await axios.post(
|
||||
url,
|
||||
new URLSearchParams({
|
||||
userName: this.accountId,
|
||||
apiKey: this.apiKey,
|
||||
action: 'logout',
|
||||
mode: 'blended',
|
||||
state: 'Ready',
|
||||
}).toString(),
|
||||
{
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
},
|
||||
auth: {
|
||||
username: params.agentId,
|
||||
password: params.password,
|
||||
},
|
||||
},
|
||||
);
|
||||
try {
|
||||
const response = await axios.post(
|
||||
url,
|
||||
new URLSearchParams({
|
||||
userName: this.accountId,
|
||||
apiKey: this.apiKey,
|
||||
action: 'logout',
|
||||
mode: 'blended',
|
||||
state: 'Ready',
|
||||
}).toString(),
|
||||
{
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
},
|
||||
auth: {
|
||||
username: params.agentId,
|
||||
password: params.password,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
this.logger.log(`Agent logout response: ${JSON.stringify(response.data)}`);
|
||||
return response.data;
|
||||
} catch (error: any) {
|
||||
this.logger.error(`Agent logout failed: ${error.message}`);
|
||||
throw error;
|
||||
}
|
||||
this.logger.log(
|
||||
`Agent logout response: ${JSON.stringify(response.data)}`,
|
||||
);
|
||||
return response.data;
|
||||
} catch (error: any) {
|
||||
this.logger.error(`Agent logout failed: ${error.message}`);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user