rest:dial support timeLimit (#1024)

* rest:dial support timeLimit

* wip

* wip

* clear maxCallDuration timer
This commit is contained in:
Hoan Luu Huu
2025-01-08 00:21:09 +07:00
committed by Quan HL
parent 380cd7f792
commit db3f7937e9
5 changed files with 98 additions and 9 deletions

View File

@@ -1172,6 +1172,11 @@ class CallSession extends Emitter {
this.wakeupResolver({reason: 'session ended'}); this.wakeupResolver({reason: 'session ended'});
this.wakeupResolver = null; this.wakeupResolver = null;
} }
if (this._maxCallDurationTimer) {
clearTimeout(this._maxCallDurationTimer);
this._maxCallDurationTimer = null;
}
} }
/** /**
@@ -2680,6 +2685,27 @@ Duration=${duration} `
this.verbHookSpan = null; this.verbHookSpan = null;
} }
} }
}
async startMaxCallDurationTimer(timeLimit) {
if (!this._maxCallDurationTimer && timeLimit > 0) {
this.timeLimit = timeLimit;
this._maxCallDurationTimer = setTimeout(this._onMaxCallDuration.bind(this), timeLimit * 1000);
this.logger.debug(`CallSession:startMaxCallDurationTimer - started max call duration timer for ${timeLimit}s`);
}
}
/**
* _onMaxCallDuration - called when the call has reached the maximum duration
*/
_onMaxCallDuration() {
this.logger.info(`callSession:_onMaxCallDuration tearing down call as it has reached ${this.timeLimit}s`);
if (!this.dlg) {
this.logger.debug('CallSession:_onMaxCallDuration - no dialog, call already gone');
return;
}
this._jambonzHangup('Max Call Duration');
this._maxCallDurationTimer = null;
} }
module.exports = CallSession; module.exports = CallSession;

View File

@@ -12,6 +12,7 @@ class TaskRestDial extends Task {
this.from = this.data.from; this.from = this.data.from;
this.callerName = this.data.callerName; this.callerName = this.data.callerName;
this.timeLimit = this.data.timeLimit;
this.fromHost = this.data.fromHost; this.fromHost = this.data.fromHost;
this.to = this.data.to; this.to = this.data.to;
this.call_hook = this.data.call_hook; this.call_hook = this.data.call_hook;
@@ -66,6 +67,9 @@ class TaskRestDial extends Task {
const cs = this.callSession; const cs = this.callSession;
cs.setDialog(dlg); cs.setDialog(dlg);
cs.referHook = this.referHook; cs.referHook = this.referHook;
if (this.timeLimit) {
cs.startMaxCallDurationTimer(this.timeLimit);
}
this.logger.debug('TaskRestDial:_onConnect - call connected'); this.logger.debug('TaskRestDial:_onConnect - call connected');
if (this.sipRequestWithinDialogHook) this._initSipRequestWithinDialogHandler(cs, dlg); if (this.sipRequestWithinDialogHook) this._initSipRequestWithinDialogHandler(cs, dlg);
try { try {

14
package-lock.json generated
View File

@@ -18,7 +18,7 @@
"@jambonz/speech-utils": "^0.1.20", "@jambonz/speech-utils": "^0.1.20",
"@jambonz/stats-collector": "^0.1.10", "@jambonz/stats-collector": "^0.1.10",
"@jambonz/time-series": "^0.2.9", "@jambonz/time-series": "^0.2.9",
"@jambonz/verb-specifications": "^0.0.83", "@jambonz/verb-specifications": "^0.0.91",
"@opentelemetry/api": "^1.8.0", "@opentelemetry/api": "^1.8.0",
"@opentelemetry/exporter-jaeger": "^1.23.0", "@opentelemetry/exporter-jaeger": "^1.23.0",
"@opentelemetry/exporter-trace-otlp-http": "^0.50.0", "@opentelemetry/exporter-trace-otlp-http": "^0.50.0",
@@ -1577,9 +1577,9 @@
} }
}, },
"node_modules/@jambonz/verb-specifications": { "node_modules/@jambonz/verb-specifications": {
"version": "0.0.83", "version": "0.0.91",
"resolved": "https://registry.npmjs.org/@jambonz/verb-specifications/-/verb-specifications-0.0.83.tgz", "resolved": "https://registry.npmjs.org/@jambonz/verb-specifications/-/verb-specifications-0.0.91.tgz",
"integrity": "sha512-3m1o3gnWw1yEwNfkZ6IIyUhdUqsQ3aWBNoWJHswe4udvVbEIxPHi+8jKGTJVF2vxddzwfOWp7RmMCV9RmKWzkw==", "integrity": "sha512-C9UIKytogOdUp5sGqfEetl82/8lDQ8zgEU5diQKpU4dZeA3M8qItqjJGSXexNh4PK9ECUYNorsPoRGNxGcr2IA==",
"dependencies": { "dependencies": {
"debug": "^4.3.4", "debug": "^4.3.4",
"pino": "^8.8.0" "pino": "^8.8.0"
@@ -10674,9 +10674,9 @@
} }
}, },
"@jambonz/verb-specifications": { "@jambonz/verb-specifications": {
"version": "0.0.83", "version": "0.0.91",
"resolved": "https://registry.npmjs.org/@jambonz/verb-specifications/-/verb-specifications-0.0.83.tgz", "resolved": "https://registry.npmjs.org/@jambonz/verb-specifications/-/verb-specifications-0.0.91.tgz",
"integrity": "sha512-3m1o3gnWw1yEwNfkZ6IIyUhdUqsQ3aWBNoWJHswe4udvVbEIxPHi+8jKGTJVF2vxddzwfOWp7RmMCV9RmKWzkw==", "integrity": "sha512-C9UIKytogOdUp5sGqfEetl82/8lDQ8zgEU5diQKpU4dZeA3M8qItqjJGSXexNh4PK9ECUYNorsPoRGNxGcr2IA==",
"requires": { "requires": {
"debug": "^4.3.4", "debug": "^4.3.4",
"pino": "^8.8.0" "pino": "^8.8.0"

View File

@@ -33,8 +33,8 @@
"@jambonz/realtimedb-helpers": "^0.8.8", "@jambonz/realtimedb-helpers": "^0.8.8",
"@jambonz/speech-utils": "^0.1.20", "@jambonz/speech-utils": "^0.1.20",
"@jambonz/stats-collector": "^0.1.10", "@jambonz/stats-collector": "^0.1.10",
"@jambonz/time-series": "^0.2.9", "@jambonz/time-series": "^0.2.13",
"@jambonz/verb-specifications": "^0.0.83", "@jambonz/verb-specifications": "^0.0.91",
"@opentelemetry/api": "^1.8.0", "@opentelemetry/api": "^1.8.0",
"@opentelemetry/exporter-jaeger": "^1.23.0", "@opentelemetry/exporter-jaeger": "^1.23.0",
"@opentelemetry/exporter-trace-otlp-http": "^0.50.0", "@opentelemetry/exporter-trace-otlp-http": "^0.50.0",

View File

@@ -222,3 +222,62 @@ test('test create-call app_json', async(t) => {
t.error(err); t.error(err);
} }
}); });
test('test create-call timeLimit', async(t) => {
clearModule.all();
const {srf, disconnect} = require('../app');
try {
await connect(srf);
// GIVEN
let from = 'create-call-app-json';
let account_sid = 'bb845d4b-83a9-4cde-a6e9-50f3743bab3f';
// Give UAS app time to come up
const p = sippUac('uas.xml', '172.38.0.10', from);
await waitFor(1000);
const startTime = Date.now();
const app_json = `[
{
"verb": "pause",
"length": 7
}
]`;
const post = bent('http://127.0.0.1:3000/', 'POST', 'json', 201);
post('v1/createCall', {
'account_sid':account_sid,
"call_hook": {
"url": "http://127.0.0.1:3100/",
"method": "POST",
"username": "username",
"password": "password"
},
app_json,
"from": from,
"to": {
"type": "phone",
"number": "15583084809"
},
"timeLimit": 1,
"speech_recognizer_vendor": "google",
"speech_recognizer_language": "en"
});
//THEN
await p;
const endTime = Date.now();
t.ok(endTime - startTime < 2000, 'create-call: timeLimit is respected');
disconnect();
} catch (err) {
console.log(`error received: ${err}`);
disconnect();
t.error(err);
}
});