mirror of
https://github.com/jambonz/sbc-inbound.git
synced 2025-12-19 04:37:43 +00:00
start/stop/pause/resume recording success when one of siprec server success. (#131)
* start/stop/pause/resume recording success when one of siprec server success. * wip * wip * update customer header for pause and resume * allow timeout for siprec action * wip * wip * wip * update siprec client utils
This commit is contained in:
@@ -67,6 +67,7 @@ class CallSession extends Emitter {
|
|||||||
this.account_sid = req.locals.account_sid;
|
this.account_sid = req.locals.account_sid;
|
||||||
this.service_provider_sid = req.locals.service_provider_sid;
|
this.service_provider_sid = req.locals.service_provider_sid;
|
||||||
this.srsClients = [];
|
this.srsClients = [];
|
||||||
|
this.recordingNoAnswerTimeout = (process.env.JAMBONES_RECORDING_NO_ANSWER_TIMEOUT || 2) * 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
get isFromMSTeams() {
|
get isFromMSTeams() {
|
||||||
@@ -335,6 +336,22 @@ class CallSession extends Emitter {
|
|||||||
dlg.on('modify', this._onReinvite.bind(this, dlg));
|
dlg.on('modify', this._onReinvite.bind(this, dlg));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_startRecordingNoAnswerTimer(res) {
|
||||||
|
this._clearRecordingNoAnswerTimer();
|
||||||
|
this.recordingNoAnswerTimer = setTimeout(() => {
|
||||||
|
this.logger.info('No response from SipRec server, return error to feature server');
|
||||||
|
this.isRecordingNoAnswerResponded = true;
|
||||||
|
res.send(400);
|
||||||
|
}, this.recordingNoAnswerTimeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
_clearRecordingNoAnswerTimer() {
|
||||||
|
if (this.recordingNoAnswerTimer) {
|
||||||
|
clearTimeout(this.recordingNoAnswerTimer);
|
||||||
|
this.recordingNoAnswerTimer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_stopRecording() {
|
_stopRecording() {
|
||||||
if (this.srsClients.length) {
|
if (this.srsClients.length) {
|
||||||
this.srsClients.forEach((c) => c.stop());
|
this.srsClients.forEach((c) => c.stop());
|
||||||
@@ -706,12 +723,12 @@ Duration=${payload.duration} `
|
|||||||
}
|
}
|
||||||
else if (reason.includes('CallRecording')) {
|
else if (reason.includes('CallRecording')) {
|
||||||
let succeeded = false;
|
let succeeded = false;
|
||||||
|
const headers = contentType === 'application/json' && req.body ? JSON.parse(req.body) : {};
|
||||||
if (reason === 'startCallRecording') {
|
if (reason === 'startCallRecording') {
|
||||||
const from = this.req.getParsedHeader('From');
|
const from = this.req.getParsedHeader('From');
|
||||||
const to = this.req.getParsedHeader('To');
|
const to = this.req.getParsedHeader('To');
|
||||||
const aorFrom = from.uri;
|
const aorFrom = from.uri;
|
||||||
const aorTo = to.uri;
|
const aorTo = to.uri;
|
||||||
const headers = contentType === 'application/json' && req.body ? JSON.parse(req.body) : {};
|
|
||||||
this.logger.info({to, from}, 'startCallRecording request for a call');
|
this.logger.info({to, from}, 'startCallRecording request for a call');
|
||||||
|
|
||||||
const srsUrl = req.get('X-Srs-Url');
|
const srsUrl = req.get('X-Srs-Url');
|
||||||
@@ -755,11 +772,14 @@ Duration=${payload.duration} `
|
|||||||
headers
|
headers
|
||||||
}));
|
}));
|
||||||
try {
|
try {
|
||||||
succeeded = (await Promise.all(
|
this._startRecordingNoAnswerTimer(res);
|
||||||
this.srsClients.map((c) => c.start())
|
await Promise.any(this.srsClients.map((c) => c.start()));
|
||||||
)).every((r) => r);
|
// Only take who success accept request.
|
||||||
|
this.srsClients = this.srsClients.filter((c) => c.activated);
|
||||||
|
succeeded = true;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.logger.error({err}, 'Error starting SipRec call recording');
|
this.logger.error({err}, 'Error starting SipRec call recording');
|
||||||
|
succeeded = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (reason === 'stopCallRecording') {
|
else if (reason === 'stopCallRecording') {
|
||||||
@@ -769,11 +789,12 @@ Duration=${payload.duration} `
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
succeeded = (await Promise.all(
|
this._startRecordingNoAnswerTimer(res);
|
||||||
this.srsClients.map((c) => c.stop())
|
await Promise.any(this.srsClients.map((c) => c.stop()));
|
||||||
)).every((r) => r);
|
succeeded = true;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.logger.error({err}, 'Error stopping SipRec call recording');
|
this.logger.error({err}, 'Error stopping SipRec call recording');
|
||||||
|
succeeded = false;
|
||||||
}
|
}
|
||||||
this.srsClients = [];
|
this.srsClients = [];
|
||||||
}
|
}
|
||||||
@@ -783,9 +804,14 @@ Duration=${payload.duration} `
|
|||||||
res.send(400);
|
res.send(400);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
succeeded = (await Promise.all(
|
try {
|
||||||
this.srsClients.map((c) => c.pause())
|
this._startRecordingNoAnswerTimer(res);
|
||||||
)).every((r) => r);
|
await Promise.any(this.srsClients.map((c) => c.pause({headers})));
|
||||||
|
succeeded = true;
|
||||||
|
} catch (err) {
|
||||||
|
this.logger.error({err}, 'Error pausing SipRec call recording');
|
||||||
|
succeeded = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (reason === 'resumeCallRecording') {
|
else if (reason === 'resumeCallRecording') {
|
||||||
if (!this.srsClients.length || !this.srsClients.every((c) => c.paused)) {
|
if (!this.srsClients.length || !this.srsClients.every((c) => c.paused)) {
|
||||||
@@ -793,11 +819,19 @@ Duration=${payload.duration} `
|
|||||||
this.logger.info('discarding invalid resumeCallRecording request');
|
this.logger.info('discarding invalid resumeCallRecording request');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
succeeded = (await Promise.all(
|
try {
|
||||||
this.srsClients.map((c) => c.resume())
|
this._startRecordingNoAnswerTimer(res);
|
||||||
)).every((r) => r);
|
await Promise.any(this.srsClients.map((c) => c.resume({headers})));
|
||||||
|
succeeded = true;
|
||||||
|
} catch (err) {
|
||||||
|
this.logger.error({err}, 'Error resuming SipRec call recording');
|
||||||
|
succeeded = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!this.isRecordingNoAnswerResponded) {
|
||||||
|
this._clearRecordingNoAnswerTimer();
|
||||||
|
res.send(succeeded ? 200 : 503);
|
||||||
}
|
}
|
||||||
res.send(succeeded ? 200 : 503);
|
|
||||||
} else if (reason.includes('Dtmf')) {
|
} else if (reason.includes('Dtmf')) {
|
||||||
const arr = /Signal=\s*([0-9#*])/.exec(req.body);
|
const arr = /Signal=\s*([0-9#*])/.exec(req.body);
|
||||||
if (!arr) {
|
if (!arr) {
|
||||||
|
|||||||
14
package-lock.json
generated
14
package-lock.json
generated
@@ -16,7 +16,7 @@
|
|||||||
"@jambonz/http-health-check": "^0.0.1",
|
"@jambonz/http-health-check": "^0.0.1",
|
||||||
"@jambonz/realtimedb-helpers": "^0.8.7",
|
"@jambonz/realtimedb-helpers": "^0.8.7",
|
||||||
"@jambonz/rtpengine-utils": "^0.4.4",
|
"@jambonz/rtpengine-utils": "^0.4.4",
|
||||||
"@jambonz/siprec-client-utils": "^0.2.6",
|
"@jambonz/siprec-client-utils": "^0.2.7",
|
||||||
"@jambonz/stats-collector": "^0.1.9",
|
"@jambonz/stats-collector": "^0.1.9",
|
||||||
"@jambonz/time-series": "^0.2.5",
|
"@jambonz/time-series": "^0.2.5",
|
||||||
"bent": "^7.3.12",
|
"bent": "^7.3.12",
|
||||||
@@ -1850,9 +1850,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@jambonz/siprec-client-utils": {
|
"node_modules/@jambonz/siprec-client-utils": {
|
||||||
"version": "0.2.6",
|
"version": "0.2.7",
|
||||||
"resolved": "https://registry.npmjs.org/@jambonz/siprec-client-utils/-/siprec-client-utils-0.2.6.tgz",
|
"resolved": "https://registry.npmjs.org/@jambonz/siprec-client-utils/-/siprec-client-utils-0.2.7.tgz",
|
||||||
"integrity": "sha512-z2x6nghLaCfOBPcr36f+1vxsV557X3z5JW1L1RxZg8YPWkTboNIHyHxtEcAua7V9g6EB4G1qv2KDwA+iE5n5Ww==",
|
"integrity": "sha512-VztOToBfXnOphg/y6kO+lBYqoDH7X5Ci0daXT5zQ8v5NnaZw+UwxGeFPX3knIR3r5pmzUld0f2giFOuD4ZOF8w==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"sdp-transform": "^2.14.1",
|
"sdp-transform": "^2.14.1",
|
||||||
"uuid": "^8.3.2"
|
"uuid": "^8.3.2"
|
||||||
@@ -7548,9 +7548,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@jambonz/siprec-client-utils": {
|
"@jambonz/siprec-client-utils": {
|
||||||
"version": "0.2.6",
|
"version": "0.2.7",
|
||||||
"resolved": "https://registry.npmjs.org/@jambonz/siprec-client-utils/-/siprec-client-utils-0.2.6.tgz",
|
"resolved": "https://registry.npmjs.org/@jambonz/siprec-client-utils/-/siprec-client-utils-0.2.7.tgz",
|
||||||
"integrity": "sha512-z2x6nghLaCfOBPcr36f+1vxsV557X3z5JW1L1RxZg8YPWkTboNIHyHxtEcAua7V9g6EB4G1qv2KDwA+iE5n5Ww==",
|
"integrity": "sha512-VztOToBfXnOphg/y6kO+lBYqoDH7X5Ci0daXT5zQ8v5NnaZw+UwxGeFPX3knIR3r5pmzUld0f2giFOuD4ZOF8w==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"sdp-transform": "^2.14.1",
|
"sdp-transform": "^2.14.1",
|
||||||
"uuid": "^8.3.2"
|
"uuid": "^8.3.2"
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
"@jambonz/http-health-check": "^0.0.1",
|
"@jambonz/http-health-check": "^0.0.1",
|
||||||
"@jambonz/realtimedb-helpers": "^0.8.7",
|
"@jambonz/realtimedb-helpers": "^0.8.7",
|
||||||
"@jambonz/rtpengine-utils": "^0.4.4",
|
"@jambonz/rtpengine-utils": "^0.4.4",
|
||||||
"@jambonz/siprec-client-utils": "^0.2.6",
|
"@jambonz/siprec-client-utils": "^0.2.7",
|
||||||
"@jambonz/stats-collector": "^0.1.9",
|
"@jambonz/stats-collector": "^0.1.9",
|
||||||
"@jambonz/time-series": "^0.2.5",
|
"@jambonz/time-series": "^0.2.5",
|
||||||
"@jambonz/digest-utils": "^0.0.3",
|
"@jambonz/digest-utils": "^0.0.3",
|
||||||
|
|||||||
Reference in New Issue
Block a user