mirror of
https://dev.azure.com/globalhealthx/EMR/_git/helix-engage-server
synced 2026-04-11 18:08:16 +00:00
99 lines
2.9 KiB
TypeScript
99 lines
2.9 KiB
TypeScript
import { Injectable, Logger, OnModuleInit } from '@nestjs/common';
|
|
import { ConfigService } from '@nestjs/config';
|
|
import { PlatformGraphqlService } from '../platform/platform-graphql.service';
|
|
import { OzonetelAgentService } from '../ozonetel/ozonetel-agent.service';
|
|
|
|
type ActiveCall = {
|
|
ucid: string;
|
|
agentId: string;
|
|
callerNumber: string;
|
|
callType: string;
|
|
startTime: string;
|
|
status: 'active' | 'on-hold';
|
|
};
|
|
|
|
@Injectable()
|
|
export class SupervisorService implements OnModuleInit {
|
|
private readonly logger = new Logger(SupervisorService.name);
|
|
private readonly activeCalls = new Map<string, ActiveCall>();
|
|
|
|
constructor(
|
|
private platform: PlatformGraphqlService,
|
|
private ozonetel: OzonetelAgentService,
|
|
private config: ConfigService,
|
|
) {}
|
|
|
|
async onModuleInit() {
|
|
this.logger.log('Supervisor service initialized');
|
|
}
|
|
|
|
handleCallEvent(event: any) {
|
|
const action = event.action;
|
|
const ucid = event.ucid ?? event.monitorUCID;
|
|
const agentId = event.agent_id ?? event.agentID;
|
|
const callerNumber = event.caller_id ?? event.callerID;
|
|
const callType = event.call_type ?? event.Type;
|
|
const eventTime =
|
|
event.event_time ?? event.eventTime ?? new Date().toISOString();
|
|
|
|
if (!ucid) return;
|
|
|
|
if (action === 'Answered' || action === 'Calling') {
|
|
this.activeCalls.set(ucid, {
|
|
ucid,
|
|
agentId,
|
|
callerNumber,
|
|
callType,
|
|
startTime: eventTime,
|
|
status: 'active',
|
|
});
|
|
this.logger.log(`Active call: ${agentId} ↔ ${callerNumber} (${ucid})`);
|
|
} else if (action === 'Disconnect') {
|
|
this.activeCalls.delete(ucid);
|
|
this.logger.log(`Call ended: ${ucid}`);
|
|
}
|
|
}
|
|
|
|
handleAgentEvent(event: any) {
|
|
this.logger.log(
|
|
`Agent event: ${event.agentId ?? event.agent_id} → ${event.action}`,
|
|
);
|
|
}
|
|
|
|
getActiveCalls(): ActiveCall[] {
|
|
return Array.from(this.activeCalls.values());
|
|
}
|
|
|
|
async getTeamPerformance(date: string): Promise<any> {
|
|
// Get all agents from platform
|
|
const agentData = await this.platform.query<any>(
|
|
`{ agents(first: 20) { edges { node {
|
|
id name ozonetelagentid npsscore
|
|
maxidleminutes minnpsthreshold minconversionpercent
|
|
} } } }`,
|
|
);
|
|
const agents = agentData?.agents?.edges?.map((e: any) => e.node) ?? [];
|
|
|
|
// Fetch Ozonetel time summary per agent
|
|
const summaries = await Promise.all(
|
|
agents.map(async (agent: any) => {
|
|
if (!agent.ozonetelagentid) return { ...agent, timeBreakdown: null };
|
|
try {
|
|
const summary = await this.ozonetel.getAgentSummary(
|
|
agent.ozonetelagentid,
|
|
date,
|
|
);
|
|
return { ...agent, timeBreakdown: summary };
|
|
} catch (err) {
|
|
this.logger.warn(
|
|
`Failed to get summary for ${agent.ozonetelagentid}: ${err}`,
|
|
);
|
|
return { ...agent, timeBreakdown: null };
|
|
}
|
|
}),
|
|
);
|
|
|
|
return { date, agents: summaries };
|
|
}
|
|
}
|