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 }> {
|
}): Promise<{ status: string; message: string }> {
|
||||||
const callerId = process.env.OZONETEL_DID ?? '918041763265';
|
const callerId = process.env.OZONETEL_DID ?? '918041763265';
|
||||||
const callbackBase = process.env.KOOKOO_CALLBACK_URL ?? 'https://engage-api.srv1477139.hstgr.cloud';
|
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 {
|
try {
|
||||||
const queryParams = new URLSearchParams({
|
// Call 1: Call the customer → put in conference room
|
||||||
|
const customerParams = new URLSearchParams({
|
||||||
phone_no: params.customerNumber,
|
phone_no: params.customerNumber,
|
||||||
api_key: this.apiKey,
|
api_key: this.apiKey,
|
||||||
outbound_version: '2',
|
outbound_version: '2',
|
||||||
caller_id: callerId,
|
caller_id: callerId,
|
||||||
callback_url: params.callbackUrl ?? `${callbackBase}/webhooks/kookoo/callback`,
|
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
|
// Call 2: Call the DID (which routes to agent via CloudAgent) → put in same conference room
|
||||||
const ivrUrl = params.ivrUrl ?? `${callbackBase}/kookoo/ivr`;
|
const agentParams = new URLSearchParams({
|
||||||
queryParams.set('url', ivrUrl);
|
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(
|
// Fire both calls
|
||||||
`https://in1-cpaas.ozonetel.com/outbound/outbound.php?${queryParams.toString()}`,
|
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);
|
const responseText = typeof customerRes.data === 'string' ? customerRes.data : String(customerRes.data);
|
||||||
this.logger.log(`Kookoo dial response: ${responseText}`);
|
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>
|
// Parse XML response: <response><status>queued</status><message>SID</message></response>
|
||||||
const statusMatch = responseText.match(/<status>(.*?)<\/status>/);
|
const statusMatch = responseText.match(/<status>(.*?)<\/status>/);
|
||||||
|
|||||||
Reference in New Issue
Block a user