mirror of
https://github.com/jambonz/jambonz-feature-server.git
synced 2025-12-20 16:50:39 +00:00
Feature/incoming refer (#76)
* Dial: handle incoming REFER on either leg by calling referHook, if configured * lint * modify payload of referHook * support target.trunk on rest createCall api * bugfix: gather partial result hook was not working * lint * handling of incoming REFER
This commit is contained in:
@@ -14,6 +14,7 @@ const sessionTracker = require('../session/session-tracker');
|
||||
const DtmfCollector = require('../utils/dtmf-collector');
|
||||
const dbUtils = require('../utils/db-utils');
|
||||
const debug = require('debug')('jambonz:feature-server');
|
||||
const {parseUri} = require('drachtio-srf');
|
||||
|
||||
function parseDtmfOptions(logger, dtmfCapture) {
|
||||
let parentDtmfCollector, childDtmfCollector;
|
||||
@@ -91,6 +92,7 @@ class TaskDial extends Task {
|
||||
this.timeLimit = this.data.timeLimit;
|
||||
this.confirmHook = this.data.confirmHook;
|
||||
this.confirmMethod = this.data.confirmMethod;
|
||||
this.referHook = this.data.referHook;
|
||||
this.dtmfHook = this.data.dtmfHook;
|
||||
this.proxy = this.data.proxy;
|
||||
|
||||
@@ -245,6 +247,40 @@ class TaskDial extends Task {
|
||||
}
|
||||
}
|
||||
|
||||
async handleRefer(cs, req, res, callInfo = cs.callInfo) {
|
||||
if (this.referHook) {
|
||||
try {
|
||||
const isChild = !!callInfo.parentCallSid;
|
||||
const referring_call_sid = isChild ? callInfo.callSid : cs.callSid;
|
||||
const referred_call_sid = isChild ? callInfo.parentCallSid : this.sd.callSid;
|
||||
|
||||
const to = parseUri(req.getParsedHeader('Refer-To').uri);
|
||||
const by = parseUri(req.getParsedHeader('Referred-By').uri);
|
||||
this.logger.info({to}, 'refer to parsed');
|
||||
await cs.requestor.request('verb:hook', this.referHook, {
|
||||
...callInfo,
|
||||
refer_details: {
|
||||
sip_refer_to: req.get('Refer-To'),
|
||||
sip_referred_by: req.get('Referred-By'),
|
||||
sip_user_agent: req.get('User-Agent'),
|
||||
refer_to_user: to.user,
|
||||
referred_by_user: by.user,
|
||||
referring_call_sid,
|
||||
referred_call_sid
|
||||
}
|
||||
});
|
||||
res.send(202);
|
||||
this.logger.info('DialTask:handleRefer - sent 202 Accepted');
|
||||
} catch (err) {
|
||||
res.send(err.statusCode || 501);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.logger.info('DialTask:handleRefer - got REFER but no referHook, responding 501');
|
||||
res.send(501);
|
||||
}
|
||||
}
|
||||
|
||||
_removeHandlers(sd) {
|
||||
sd.removeAllListeners('accept');
|
||||
sd.removeAllListeners('decline');
|
||||
@@ -389,6 +425,7 @@ class TaskDial extends Task {
|
||||
this.dials.set(sd.callSid, sd);
|
||||
|
||||
sd
|
||||
.on('refer', (callInfo, req, res) => this.handleRefer(cs, req, res, callInfo))
|
||||
.on('callCreateFail', () => {
|
||||
clearTimeout(this.timerRing);
|
||||
this.dials.delete(sd.callSid);
|
||||
@@ -457,6 +494,9 @@ class TaskDial extends Task {
|
||||
} catch (err) {
|
||||
this.logger.error(err, 'Error in dial einvite from B leg');
|
||||
}
|
||||
})
|
||||
.on('refer', (callInfo, req, res) => {
|
||||
|
||||
})
|
||||
.once('adulting', () => {
|
||||
/* child call just adulted and got its own session */
|
||||
|
||||
@@ -26,7 +26,7 @@ class TaskGather extends Task {
|
||||
if (this.dtmfBargein !== false && this.input.includes('digits')) this.dtmfBargein = true;
|
||||
|
||||
this.timeout = (this.timeout || 15) * 1000;
|
||||
this.interim = this.partialResultCallback;
|
||||
this.interim = this.partialResultHook || this.bargein;
|
||||
if (this.data.recognizer) {
|
||||
const recognizer = this.data.recognizer;
|
||||
this.vendor = recognizer.vendor;
|
||||
@@ -209,7 +209,7 @@ class TaskGather extends Task {
|
||||
if (this.hints && this.hints.length > 1) {
|
||||
opts.GOOGLE_SPEECH_HINTS = this.hints.map((h) => h.trim()).join(',');
|
||||
}
|
||||
if (this.altLanguages && this.altLanguages.length > 1) {
|
||||
if (this.altLanguages && this.altLanguages.length > 0) {
|
||||
opts.GOOGLE_SPEECH_ALTERNATIVE_LANGUAGE_CODES = this.altLanguages.join(',');
|
||||
}
|
||||
if (this.profanityFilter === true) {
|
||||
@@ -259,7 +259,7 @@ class TaskGather extends Task {
|
||||
ep.startTranscription({
|
||||
vendor: this.vendor,
|
||||
locale: this.language,
|
||||
interim: this.partialResultCallback || this.bargein,
|
||||
interim: this.interim,
|
||||
}).catch((err) => {
|
||||
const {writeAlerts, AlertType} = this.cs.srf.locals;
|
||||
this.logger.error(err, 'TaskGather:_startTranscribing error');
|
||||
|
||||
@@ -19,7 +19,11 @@ class TaskSipDecline extends Task {
|
||||
res.send(this.data.status, this.data.reason, {
|
||||
headers: this.headers
|
||||
});
|
||||
cs.emit('callStatusChange', {callStatus: CallStatus.Failed, sipStatus: this.data.status});
|
||||
cs.emit('callStatusChange', {
|
||||
callStatus: CallStatus.Failed,
|
||||
sipStatus: this.data.status,
|
||||
sipReason: this.data.reason
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -140,6 +140,7 @@
|
||||
"answerOnBridge": "boolean",
|
||||
"callerId": "string",
|
||||
"confirmHook": "object|string",
|
||||
"referHook": "object|string",
|
||||
"dialMusic": "string",
|
||||
"dtmfCapture": "object",
|
||||
"dtmfHook": "object|string",
|
||||
|
||||
Reference in New Issue
Block a user