Files
jambonz-feature-server/lib/tasks/rest_dial.js
Dave Horton a950f9f738 Feature/trace propagation (#96)
* add b3 header for trace propagation on initial webhook

* logging

* add tracing context to all webhooks

* Add span parameter to Task.getTracingPropagation. Pass proper span to getTracingPropagation calls in Task methods to propagate the proper spanId (#91)

* some tracing cleanup

* bugfix: azure stt results need to be ordered by confidence level before processing (#92)

* fix assertion

* bugfix: vad was not enabled on config verb, restart STT on empty transcript in gather

* gather: dont send webhook if call is gone

* rest outdial: handle 302 redirect so we can later cancel request if needed (#95)

* gather: restart if we get an empty transcript (looking at you, Azure)

Co-authored-by: javibookline <98887695+javibookline@users.noreply.github.com>
2022-04-01 14:48:27 -04:00

90 lines
2.3 KiB
JavaScript

const Task = require('./task');
const {TaskName} = require('../utils/constants');
const makeTask = require('./make_task');
const normalizeJambones = require('../utils/normalize-jambones');
/**
* Manages an outdial made via REST API
*/
class TaskRestDial extends Task {
constructor(logger, opts) {
super(logger, opts);
this.from = this.data.from;
this.to = this.data.to;
this.call_hook = this.data.call_hook;
this.timeout = this.data.timeout || 60;
this.on('connect', this._onConnect.bind(this));
this.on('callStatus', this._onCallStatus.bind(this));
}
get name() { return TaskName.RestDial; }
/**
* INVITE has just been sent at this point
*/
async exec(cs) {
await super.exec(cs);
this.req = cs.req;
this._setCallTimer();
await this.awaitTaskDone();
}
kill(cs) {
super.kill(cs);
this._clearCallTimer();
if (this.req) {
this.req.cancel();
this.req = null;
}
this.notifyTaskDone();
}
async _onConnect(dlg) {
this.req = null;
const cs = this.callSession;
cs.setDialog(dlg);
try {
const b3 = this.getTracingPropagation();
const httpHeaders = b3 && {b3};
const tasks = await cs.requestor.request('verb:hook', this.call_hook, cs.callInfo, httpHeaders);
if (tasks && Array.isArray(tasks)) {
this.logger.debug({tasks: tasks}, `TaskRestDial: replacing application with ${tasks.length} tasks`);
cs.replaceApplication(normalizeJambones(this.logger, tasks).map((tdata) => makeTask(this.logger, tdata)));
}
} catch (err) {
this.logger.error(err, 'TaskRestDial:_onConnect error retrieving or parsing application, ending call');
this.notifyTaskDone();
}
}
_onCallStatus(status) {
this.logger.debug(`CallStatus: ${status}`);
if (status >= 200) {
this.req = null;
this._clearCallTimer();
if (status !== 200) this.notifyTaskDone();
}
}
_setCallTimer() {
this.timer = setTimeout(this._onCallTimeout.bind(this), this.timeout * 1000);
}
_clearCallTimer() {
if (this.timer) clearTimeout(this.timer);
this.timer = null;
}
_onCallTimeout() {
this.logger.debug('TaskRestDial: timeout expired without answer, killing task');
this.timer = null;
this.kill();
}
}
module.exports = TaskRestDial;