test: try 0-prefix SIP extension in Kookoo dial — still fails

Kookoo <dial> only routes to PSTN numbers, not SIP extensions.
Tested: 523590, 0523590 — both result in not_answered.
The bridge from Kookoo to browser SIP requires either:
- Ozonetel enabling /ca_apis/ auth (CloudAgent API)
- Or a way to route Kookoo calls to internal SIP extensions

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-20 07:01:39 +05:30
parent d0cb68d8d7
commit 68c03b0af4

View File

@@ -5,9 +5,11 @@ import { ConfigService } from '@nestjs/config';
export class KookooIvrController { export class KookooIvrController {
private readonly logger = new Logger(KookooIvrController.name); private readonly logger = new Logger(KookooIvrController.name);
private readonly sipId: string; private readonly sipId: string;
private readonly callerId: string;
constructor(private config: ConfigService) { constructor(private config: ConfigService) {
this.sipId = process.env.OZONETEL_SIP_ID ?? '523590'; this.sipId = process.env.OZONETEL_SIP_ID ?? '523590';
this.callerId = process.env.OZONETEL_DID ?? '918041763265';
} }
@Get('ivr') @Get('ivr')
@@ -16,30 +18,32 @@ export class KookooIvrController {
const event = query.event ?? ''; const event = query.event ?? '';
const sid = query.sid ?? ''; const sid = query.sid ?? '';
const cid = query.cid ?? ''; const cid = query.cid ?? '';
const data = query.data ?? '';
const status = query.status ?? ''; const status = query.status ?? '';
this.logger.log(`Kookoo IVR: event=${event} sid=${sid} cid=${cid} status=${status}`); this.logger.log(`Kookoo IVR: event=${event} sid=${sid} cid=${cid} status=${status}`);
// New outbound call — customer answered, connect to agent's SIP // New outbound call — customer answered, put them in a conference room
// The room ID is based on the call SID so we can join from the browser
if (event === 'NewCall') { if (event === 'NewCall') {
this.logger.log(`Connecting customer ${cid} to agent SIP ${this.sipId}`); // Try dialing the SIP extension with 0 prefix (internal routing)
const ext = query.ext ?? `0${this.sipId}`;
this.logger.log(`Customer ${cid} answered — dialing agent at ${ext}`);
return `<?xml version="1.0" encoding="UTF-8"?> return `<?xml version="1.0" encoding="UTF-8"?>
<response> <response>
<dial record="true" timeout="30" moh="ring">${this.sipId}</dial> <dial record="true" timeout="30" moh="ring">${ext}</dial>
</response>`; </response>`;
} }
// Dial event — call to agent finished // Conference event — user left with #
if (event === 'Dial') { if (event === 'conference' || event === 'Conference') {
this.logger.log(`Dial completed: status=${status} data=${data}`); this.logger.log(`Conference event: status=${status}`);
return `<?xml version="1.0" encoding="UTF-8"?> return `<?xml version="1.0" encoding="UTF-8"?>
<response> <response>
<hangup/> <hangup/>
</response>`; </response>`;
} }
// Hangup or any other event // Dial or Disconnect
this.logger.log(`Call ended: event=${event}`); this.logger.log(`Call ended: event=${event}`);
return `<?xml version="1.0" encoding="UTF-8"?> return `<?xml version="1.0" encoding="UTF-8"?>
<response> <response>