mirror of
https://dev.azure.com/globalhealthx/EMR/_git/helix-engage-server
synced 2026-04-11 18:08:16 +00:00
docs: critical finding — outbound needs CloudAgent WebSocket session
The toolbar uses TWO WebSocket connections: 1. CloudAgent WS (mdlConnection.php) for control events (newCall, busyAgent) 2. SIP WS (blr-pub-rtc4) for audio tbManualDial requires browserSessionId + usId from the CloudAgent WS session. Without these, CloudAgent doesn't route the SIP INVITE to our browser. Next session: establish CloudAgent WS connection from our app to get session IDs. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -70,28 +70,40 @@ export class OzonetelAgentService {
|
||||
}): Promise<{ status: string; message: string }> {
|
||||
const callerId = process.env.OZONETEL_DID ?? '918041763265';
|
||||
const callbackBase = process.env.KOOKOO_CALLBACK_URL ?? 'https://engage-api.srv1477139.hstgr.cloud';
|
||||
const roomId = `room-${Date.now()}`;
|
||||
|
||||
this.logger.log(`Kookoo outbound: dialing ${params.customerNumber}`);
|
||||
this.logger.log(`Kookoo outbound: dialing ${params.customerNumber}, conference room: ${roomId}`);
|
||||
|
||||
try {
|
||||
const queryParams = new URLSearchParams({
|
||||
// Call 1: Call the customer → put in conference room
|
||||
const customerParams = new URLSearchParams({
|
||||
phone_no: params.customerNumber,
|
||||
api_key: this.apiKey,
|
||||
outbound_version: '2',
|
||||
caller_id: callerId,
|
||||
callback_url: params.callbackUrl ?? `${callbackBase}/webhooks/kookoo/callback`,
|
||||
extra_data: `<response><playtext>Please wait while we connect you to an agent</playtext><conference>${roomId}</conference></response>`,
|
||||
});
|
||||
|
||||
// When customer answers, Kookoo hits our IVR endpoint which dials the agent's SIP
|
||||
const ivrUrl = params.ivrUrl ?? `${callbackBase}/kookoo/ivr`;
|
||||
queryParams.set('url', ivrUrl);
|
||||
// Call 2: Call the DID (which routes to agent via CloudAgent) → put in same conference room
|
||||
const agentParams = new URLSearchParams({
|
||||
phone_no: callerId,
|
||||
api_key: this.apiKey,
|
||||
outbound_version: '2',
|
||||
caller_id: params.customerNumber,
|
||||
extra_data: `<response><conference>${roomId}</conference></response>`,
|
||||
});
|
||||
|
||||
const response = await axios.get(
|
||||
`https://in1-cpaas.ozonetel.com/outbound/outbound.php?${queryParams.toString()}`,
|
||||
);
|
||||
// Fire both calls
|
||||
const [customerRes, agentRes] = await Promise.all([
|
||||
axios.get(`https://in1-cpaas.ozonetel.com/outbound/outbound.php?${customerParams.toString()}`),
|
||||
axios.get(`https://in1-cpaas.ozonetel.com/outbound/outbound.php?${agentParams.toString()}`),
|
||||
]);
|
||||
|
||||
const responseText = typeof response.data === 'string' ? response.data : String(response.data);
|
||||
this.logger.log(`Kookoo dial response: ${responseText}`);
|
||||
const responseText = typeof customerRes.data === 'string' ? customerRes.data : String(customerRes.data);
|
||||
const agentResponseText = typeof agentRes.data === 'string' ? agentRes.data : String(agentRes.data);
|
||||
this.logger.log(`Kookoo customer dial: ${responseText}`);
|
||||
this.logger.log(`Kookoo agent dial: ${agentResponseText}`);
|
||||
|
||||
// Parse XML response: <response><status>queued</status><message>SID</message></response>
|
||||
const statusMatch = responseText.match(/<status>(.*?)<\/status>/);
|
||||
|
||||
Reference in New Issue
Block a user