mirror of
https://github.com/jambonz/jambonz-feature-server.git
synced 2025-12-21 17:17:58 +00:00
add tracing context to all webhooks
This commit is contained in:
@@ -240,7 +240,6 @@ module.exports = function(srf, logger) {
|
||||
span = obj.span;
|
||||
const b3 = rootSpan.getTracingPropagation();
|
||||
const httpHeaders = b3 && {b3};
|
||||
logger.info({b3, httpHeaders}, 'sending trace info (?)');
|
||||
const json = await app.requestor.request('session:new', app.call_hook, params, httpHeaders);
|
||||
app.tasks = normalizeJambones(logger, json).map((tdata) => makeTask(logger, tdata));
|
||||
span.setAttributes({
|
||||
|
||||
@@ -230,6 +230,10 @@ class CallSession extends Emitter {
|
||||
return this.backgroundGatherTask;
|
||||
}
|
||||
|
||||
get b3() {
|
||||
return this.rootSpan?.getTracingPropagation();
|
||||
}
|
||||
|
||||
async enableBotMode(gather, autoEnable) {
|
||||
try {
|
||||
const t = normalizeJambones(this.logger, [gather]);
|
||||
@@ -512,17 +516,20 @@ class CallSession extends Emitter {
|
||||
async _lccCallHook(opts) {
|
||||
const webhooks = [];
|
||||
let sd, tasks, childTasks;
|
||||
const b3 = this.b3;
|
||||
const httpHeaders = b3 && {b3};
|
||||
|
||||
if (opts.call_hook || opts.child_call_hook) {
|
||||
if (opts.call_hook) {
|
||||
webhooks.push(this.requestor.request('session:redirect', opts.call_hook, this.callInfo.toJSON()));
|
||||
webhooks.push(this.requestor.request('session:redirect', opts.call_hook, this.callInfo.toJSON(), httpHeaders));
|
||||
}
|
||||
if (opts.child_call_hook) {
|
||||
/* child call hook only allowed from a connected Dial state */
|
||||
const task = this.currentTask;
|
||||
sd = task.sd;
|
||||
if (task && TaskName.Dial === task.name && sd) {
|
||||
webhooks.push(this.requestor.request('session:redirect', opts.child_call_hook, sd.callInfo.toJSON()));
|
||||
webhooks.push(this.requestor.request(
|
||||
'session:redirect', opts.child_call_hook, sd.callInfo.toJSON(), httpHeaders));
|
||||
}
|
||||
}
|
||||
const [tasks1, tasks2] = await Promise.all(webhooks);
|
||||
@@ -641,6 +648,8 @@ class CallSession extends Emitter {
|
||||
async _lccWhisper(opts, callSid) {
|
||||
const {whisper} = opts;
|
||||
let tasks;
|
||||
const b3 = this.b3;
|
||||
const httpHeaders = b3 && {b3};
|
||||
|
||||
// this whole thing requires us to be in a Dial verb
|
||||
const task = this.currentTask;
|
||||
@@ -651,7 +660,7 @@ class CallSession extends Emitter {
|
||||
// allow user to provide a url object, a url string, an array of tasks, or a single task
|
||||
if (typeof whisper === 'string' || (typeof whisper === 'object' && whisper.url)) {
|
||||
// retrieve a url
|
||||
const json = await this.requestor(opts.call_hook, this.callInfo.toJSON());
|
||||
const json = await this.requestor(opts.call_hook, this.callInfo.toJSON(), httpHeaders);
|
||||
tasks = normalizeJambones(this.logger, json).map((tdata) => makeTask(this.logger, tdata));
|
||||
}
|
||||
else if (Array.isArray(whisper)) {
|
||||
@@ -1264,7 +1273,9 @@ class CallSession extends Emitter {
|
||||
const {span} = this.rootSpan.startChildSpan(`call-status:${this.callInfo.callStatus}`);
|
||||
span.setAttributes(this.callInfo.toJSON());
|
||||
try {
|
||||
this.notifier.request('call:status', this.call_status_hook, this.callInfo.toJSON());
|
||||
const b3 = this.b3;
|
||||
const httpHeaders = b3 && {b3};
|
||||
this.notifier.request('call:status', this.call_status_hook, this.callInfo.toJSON(), httpHeaders);
|
||||
span.end();
|
||||
} catch (err) {
|
||||
span.end();
|
||||
|
||||
@@ -529,7 +529,9 @@ class Conference extends Task {
|
||||
|
||||
async _playHook(cs, dlg, hook, allowed = [TaskName.Play, TaskName.Say, TaskName.Pause]) {
|
||||
assert(!this._playSession);
|
||||
const json = await cs.application.requestor.request('verb:hook', hook, cs.callInfo);
|
||||
const b3 = this.getTracingPropagation();
|
||||
const httpHeaders = b3 && {b3};
|
||||
const json = await cs.application.requestor.request('verb:hook', hook, cs.callInfo, httpHeaders);
|
||||
const tasks = normalizeJambones(this.logger, json).map((tdata) => makeTask(this.logger, tdata));
|
||||
|
||||
const allowedTasks = tasks.filter((t) => allowed.includes(t.name));
|
||||
@@ -582,11 +584,14 @@ class Conference extends Task {
|
||||
|
||||
_notifyConferenceEvent(cs, eventName, params = {}) {
|
||||
if (this.statusEvents.includes(eventName)) {
|
||||
const b3 = this.getTracingPropagation();
|
||||
const httpHeaders = b3 && {b3};
|
||||
params.event = eventName;
|
||||
params.duration = (Date.now() - this.conferenceStartTime.getTime()) / 1000;
|
||||
if (!params.time) params.time = (new Date()).toISOString();
|
||||
if (!params.members && typeof this.participantCount === 'number') params.members = this.participantCount;
|
||||
cs.application.requestor.request('verb:hook', this.statusHook, Object.assign(params, this.statusParams))
|
||||
cs.application.requestor
|
||||
.request('verb:hook', this.statusHook, Object.assign(params, this.statusParams, httpHeaders))
|
||||
.catch((err) => this.logger.info(err, 'Conference:notifyConferenceEvent - error'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -271,6 +271,9 @@ class TaskDial extends Task {
|
||||
const referring_call_sid = isChild ? callInfo.callSid : cs.callSid;
|
||||
const referred_call_sid = isChild ? callInfo.parentCallSid : this.sd.callSid;
|
||||
|
||||
const b3 = this.getTracingPropagation();
|
||||
const httpHeaders = b3 && {b3};
|
||||
|
||||
const to = parseUri(req.getParsedHeader('Refer-To').uri);
|
||||
const by = parseUri(req.getParsedHeader('Referred-By').uri);
|
||||
this.logger.info({to}, 'refer to parsed');
|
||||
@@ -285,7 +288,7 @@ class TaskDial extends Task {
|
||||
referring_call_sid,
|
||||
referred_call_sid
|
||||
}
|
||||
});
|
||||
}, httpHeaders);
|
||||
res.send(202);
|
||||
this.logger.info('DialTask:handleRefer - sent 202 Accepted');
|
||||
} catch (err) {
|
||||
@@ -345,8 +348,10 @@ class TaskDial extends Task {
|
||||
const key = arr[1];
|
||||
const match = dtmfDetector.keyPress(key);
|
||||
if (match) {
|
||||
const b3 = this.getTracingPropagation();
|
||||
const httpHeaders = b3 && {b3};
|
||||
this.logger.info({callSid}, `Dial:_onInfo triggered dtmf match: ${match}`);
|
||||
requestor.request('verb:hook', this.dtmfHook, {dtmf: match, ...callInfo.toJSON()})
|
||||
requestor.request('verb:hook', this.dtmfHook, {dtmf: match, ...callInfo.toJSON(), httpHeaders})
|
||||
.catch((err) => this.logger.info(err, 'Dial:_onDtmf - error'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -453,7 +453,10 @@ class Dialogflow extends Task {
|
||||
}
|
||||
|
||||
async _performHook(cs, hook, results = {}) {
|
||||
const json = await this.cs.requestor.request('verb:hook', hook, {...results, ...cs.callInfo.toJSON()});
|
||||
const b3 = this.getTracingPropagation();
|
||||
const httpHeaders = b3 && {b3};
|
||||
const json = await this.cs.requestor.request('verb:hook', hook,
|
||||
{...results, ...cs.callInfo.toJSON()}, httpHeaders);
|
||||
if (json && Array.isArray(json)) {
|
||||
const makeTask = require('../make_task');
|
||||
const tasks = normalizeJambones(this.logger, json).map((tdata) => makeTask(this.logger, tdata));
|
||||
|
||||
@@ -394,7 +394,10 @@ class TaskGather extends Task {
|
||||
this._killAudio(cs);
|
||||
}
|
||||
if (this.partialResultHook) {
|
||||
this.cs.requestor.request(this.partialResultHook, Object.assign({speech: evt}, this.cs.callInfo));
|
||||
const b3 = this.getTracingPropagation();
|
||||
const httpHeaders = b3 && {b3};
|
||||
this.cs.requestor.request(this.partialResultHook, Object.assign({speech: evt},
|
||||
this.cs.callInfo, httpHeaders));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -289,7 +289,9 @@ class Lex extends Task {
|
||||
}
|
||||
|
||||
async _performHook(cs, hook, results) {
|
||||
const json = await this.cs.requestor.request('verb:hook', hook, results);
|
||||
const b3 = this.getTracingPropagation();
|
||||
const httpHeaders = b3 && {b3};
|
||||
const json = await this.cs.requestor.request('verb:hook', hook, results, httpHeaders);
|
||||
if (json && Array.isArray(json)) {
|
||||
const makeTask = require('./make_task');
|
||||
const tasks = normalizeJambones(this.logger, json).map((tdata) => makeTask(this.logger, tdata));
|
||||
|
||||
@@ -48,7 +48,9 @@ class TaskRestDial extends Task {
|
||||
cs.setDialog(dlg);
|
||||
|
||||
try {
|
||||
const tasks = await cs.requestor.request('verb:hook', this.call_hook, cs.callInfo);
|
||||
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)));
|
||||
|
||||
@@ -76,7 +76,10 @@ class TaskSipRefer extends Task {
|
||||
const status = arr[1];
|
||||
this.logger.debug(`TaskSipRefer:_handleNotify: call got status ${status}`);
|
||||
if (this.eventHook) {
|
||||
await cs.requestor.request('verb:hook', this.eventHook, {event: 'transfer-status', call_status: status});
|
||||
const b3 = this.getTracingPropagation();
|
||||
const httpHeaders = b3 && {b3};
|
||||
await cs.requestor.request('verb:hook', this.eventHook,
|
||||
{event: 'transfer-status', call_status: status}, httpHeaders);
|
||||
}
|
||||
if (status >= 200) {
|
||||
this.referSpan.setAttributes({'refer.finalNotify': status});
|
||||
|
||||
@@ -137,10 +137,12 @@ class Task extends Emitter {
|
||||
async performAction(results, expectResponse = true) {
|
||||
if (this.actionHook) {
|
||||
const params = results ? Object.assign(results, this.cs.callInfo.toJSON()) : this.cs.callInfo.toJSON();
|
||||
const b3 = this.getTracingPropagation();
|
||||
const httpHeaders = b3 && {b3};
|
||||
const span = this.startSpan('verb:hook', {'hook.url': this.actionHook});
|
||||
span.setAttributes({'http.body': JSON.stringify(params)});
|
||||
try {
|
||||
const json = await this.cs.requestor.request('verb:hook', this.actionHook, params);
|
||||
const json = await this.cs.requestor.request('verb:hook', this.actionHook, params, httpHeaders);
|
||||
span.setAttributes({'http.statusCode': 200});
|
||||
span.end();
|
||||
if (expectResponse && json && Array.isArray(json)) {
|
||||
@@ -160,10 +162,12 @@ class Task extends Emitter {
|
||||
}
|
||||
|
||||
async performHook(cs, hook, results) {
|
||||
const b3 = this.getTracingPropagation();
|
||||
const httpHeaders = b3 && {b3};
|
||||
const span = this.startSpan('verb:hook', {'hook.url': hook});
|
||||
span.setAttributes({'http.body': JSON.stringify(results)});
|
||||
try {
|
||||
const json = await cs.requestor.request('verb:hook', hook, results);
|
||||
const json = await cs.requestor.request('verb:hook', hook, results, httpHeaders);
|
||||
span.setAttributes({'http.statusCode': 200});
|
||||
span.end();
|
||||
if (json && Array.isArray(json)) {
|
||||
|
||||
@@ -254,7 +254,10 @@ class TaskTranscribe extends Task {
|
||||
}
|
||||
|
||||
if (this.transcriptionHook) {
|
||||
this.cs.requestor.request('verb:hook', this.transcriptionHook, Object.assign({speech: evt}, this.cs.callInfo))
|
||||
const b3 = this.getTracingPropagation();
|
||||
const httpHeaders = b3 && {b3};
|
||||
this.cs.requestor.request('verb:hook', this.transcriptionHook,
|
||||
Object.assign({speech: evt}, this.cs.callInfo), httpHeaders)
|
||||
.catch((err) => this.logger.info(err, 'TranscribeTask:_onTranscription error'));
|
||||
}
|
||||
if (this.parentTask) {
|
||||
|
||||
@@ -33,7 +33,7 @@ class WsRequestor extends BaseRequestor {
|
||||
* @param {string} [hook.password] - if basic auth is protecting the endpoint
|
||||
* @param {object} [params] - request parameters
|
||||
*/
|
||||
async request(type, hook, params) {
|
||||
async request(type, hook, params, httpHeaders = {}) {
|
||||
assert(HookMsgTypes.includes(type));
|
||||
const url = hook.url || hook;
|
||||
|
||||
@@ -48,7 +48,7 @@ class WsRequestor extends BaseRequestor {
|
||||
if (this._isAbsoluteUrl(url) && url.startsWith('http')) {
|
||||
this.logger.debug({hook}, 'WsRequestor: sending a webhook (HTTP)');
|
||||
const requestor = new HttpRequestor(this.logger, this.account_sid, hook, this.secret);
|
||||
return requestor.request(type, hook, params);
|
||||
return requestor.request(type, hook, params, httpHeaders);
|
||||
}
|
||||
|
||||
/* connect if necessary */
|
||||
@@ -73,12 +73,14 @@ class WsRequestor extends BaseRequestor {
|
||||
assert.ok(url, 'WsRequestor:request url was not provided');
|
||||
|
||||
const msgid = short.generate();
|
||||
const b3 = httpHeaders?.b3 ? {b3: httpHeaders.b3} : {};
|
||||
const obj = {
|
||||
type,
|
||||
msgid,
|
||||
call_sid: this.call_sid,
|
||||
hook: type === 'verb:hook' ? url : undefined,
|
||||
data: {...payload}
|
||||
data: {...payload},
|
||||
...b3
|
||||
};
|
||||
|
||||
//this.logger.debug({obj}, `websocket: sending (${url})`);
|
||||
|
||||
Reference in New Issue
Block a user