Compare commits

..

8 Commits

Author SHA1 Message Date
Dave Horton
43af27e802 update time-series 2022-10-10 09:19:05 +01:00
Dave Horton
b25f92e17a Feature/azure custom stt (#171)
* gather/transcribe: support for azure custom speech models (endpoint id)

* allow azure stt custom speech endpoint id to be passed as property in recognizer

* fix to add custom stt endpoint to session speech credentials object
2022-10-07 09:46:25 +01:00
Dave Horton
90cb5e1348 bugfix: typo in bugname was causing transcripts to be ignored 2022-10-04 12:59:58 +01:00
Dave Horton
cf821569b3 minor logging changes 2022-10-02 22:36:27 +01:00
Dave Horton
218f2d6c67 bugfix: unnecessary call to stopTranscription in gather verb when only collecting digits 2022-09-30 10:27:33 +01:00
Joan
c2c8f00978 added call_termination_by on app call status (#168)
Co-authored-by: Joan Salvatella <joan@bookline.io>
2022-09-23 09:13:55 +02:00
Dave Horton
32714d73f3 update to synthAudio with bugfix for writing TTS rtt stats for microsoft 2022-09-21 15:22:19 +02:00
Dave Horton
8da85ebd5a include custom header X-Application-Sid to make it available to cdrs 2022-09-20 13:54:54 +02:00
13 changed files with 68 additions and 37 deletions

View File

@@ -11,6 +11,7 @@ class CallInfo {
let srf; let srf;
this.direction = opts.direction; this.direction = opts.direction;
this.traceId = opts.traceId; this.traceId = opts.traceId;
this.callTerminationBy = undefined;
if (opts.req) { if (opts.req) {
const u = opts.req.getParsedHeader('from'); const u = opts.req.getParsedHeader('from');
const uri = parseUri(u.uri); const uri = parseUri(u.uri);
@@ -119,7 +120,7 @@ class CallInfo {
applicationSid: this.applicationSid, applicationSid: this.applicationSid,
fsSipAddress: this.localSipAddress fsSipAddress: this.localSipAddress
}; };
['parentCallSid', 'originatingSipIp', 'originatingSipTrunkName'].forEach((prop) => { ['parentCallSid', 'originatingSipIp', 'originatingSipTrunkName', 'callTerminationBy'].forEach((prop) => {
if (this[prop]) obj[prop] = this[prop]; if (this[prop]) obj[prop] = this[prop];
}); });
if (typeof this.duration === 'number') obj.duration = this.duration; if (typeof this.duration === 'number') obj.duration = this.duration;

View File

@@ -549,7 +549,9 @@ class CallSession extends Emitter {
return { return {
speech_credential_sid: credential.speech_credential_sid, speech_credential_sid: credential.speech_credential_sid,
api_key: credential.api_key, api_key: credential.api_key,
region: credential.region region: credential.region,
use_custom_stt: credential.use_custom_stt,
custom_stt_endpoint: credential.custom_stt_endpoint
}; };
} }
else if ('wellsaid' === vendor) { else if ('wellsaid' === vendor) {
@@ -638,6 +640,7 @@ class CallSession extends Emitter {
this._onTasksDone(); this._onTasksDone();
this._clearResources(); this._clearResources();
if (!this.isConfirmCallSession && !this.isSmsCallSession) sessionTracker.remove(this.callSid); if (!this.isConfirmCallSession && !this.isSmsCallSession) sessionTracker.remove(this.callSid);
} }
@@ -1188,6 +1191,7 @@ class CallSession extends Emitter {
} catch (err) { } catch (err) {
if (err === CALLER_CANCELLED_ERR_MSG) { if (err === CALLER_CANCELLED_ERR_MSG) {
this.logger.error(err, 'caller canceled quickly before we could respond, ending call'); this.logger.error(err, 'caller canceled quickly before we could respond, ending call');
this.callInfo.callTerminationBy = 'caller';
this._notifyCallStatusChange({ this._notifyCallStatusChange({
callStatus: CallStatus.NoAnswer, callStatus: CallStatus.NoAnswer,
sipStatus: 487, sipStatus: 487,
@@ -1302,7 +1306,8 @@ class CallSession extends Emitter {
this.dlg = await this.srf.createUAS(this.req, this.res, { this.dlg = await this.srf.createUAS(this.req, this.res, {
headers: { headers: {
'X-Trace-ID': this.req.locals.traceId, 'X-Trace-ID': this.req.locals.traceId,
'X-Call-Sid': this.req.locals.callSid 'X-Call-Sid': this.req.locals.callSid,
...(this.applicationSid && {'X-Application-Sid': this.applicationSid})
}, },
localSdp: this.ep.local.sdp localSdp: this.ep.local.sdp
}); });
@@ -1494,8 +1499,9 @@ class CallSession extends Emitter {
dlg.connected = false; dlg.connected = false;
dlg.destroy = origDestroy; dlg.destroy = origDestroy;
const duration = moment().diff(this.dlg.connectTime, 'seconds'); const duration = moment().diff(this.dlg.connectTime, 'seconds');
this.callInfo.callTerminationBy = 'jambonz';
this.emit('callStatusChange', {callStatus: CallStatus.Completed, duration}); this.emit('callStatusChange', {callStatus: CallStatus.Completed, duration});
this.logger.debug('CallSession: call terminated by jambones'); this.logger.debug('CallSession: call terminated by jambonz');
this.rootSpan.setAttributes({'call.termination': 'hangup by jambonz'}); this.rootSpan.setAttributes({'call.termination': 'hangup by jambonz'});
origDestroy().catch((err) => this.logger.info({err}, 'CallSession - error destroying dialog')); origDestroy().catch((err) => this.logger.info({err}, 'CallSession - error destroying dialog'));
if (this.wakeupResolver) { if (this.wakeupResolver) {

View File

@@ -34,6 +34,7 @@ class InboundCallSession extends CallSession {
_onCancel() { _onCancel() {
this.rootSpan.setAttributes({'call.termination': 'caller abandoned'}); this.rootSpan.setAttributes({'call.termination': 'caller abandoned'});
this.callInfo.callTerminationBy = 'caller';
this._notifyCallStatusChange({ this._notifyCallStatusChange({
callStatus: CallStatus.NoAnswer, callStatus: CallStatus.NoAnswer,
sipStatus: 487, sipStatus: 487,
@@ -69,6 +70,7 @@ class InboundCallSession extends CallSession {
assert(this.dlg.connectTime); assert(this.dlg.connectTime);
const duration = moment().diff(this.dlg.connectTime, 'seconds'); const duration = moment().diff(this.dlg.connectTime, 'seconds');
this.rootSpan.setAttributes({'call.termination': 'hangup by caller'}); this.rootSpan.setAttributes({'call.termination': 'hangup by caller'});
this.callInfo.callTerminationBy = 'caller';
this.emit('callStatusChange', { this.emit('callStatusChange', {
callStatus: CallStatus.Completed, callStatus: CallStatus.Completed,
duration duration

View File

@@ -44,6 +44,7 @@ class RestCallSession extends CallSession {
* This is invoked when the called party hangs up, in order to calculate the call duration. * This is invoked when the called party hangs up, in order to calculate the call duration.
*/ */
_callerHungup() { _callerHungup() {
this.callInfo.callTerminationBy = 'caller';
const duration = moment().diff(this.dlg.connectTime, 'seconds'); const duration = moment().diff(this.dlg.connectTime, 'seconds');
this.emit('callStatusChange', {callStatus: CallStatus.Completed, duration}); this.emit('callStatusChange', {callStatus: CallStatus.Completed, duration});
this.logger.debug('RestCallSession: called party hung up'); this.logger.debug('RestCallSession: called party hung up');

View File

@@ -36,7 +36,8 @@ class SipRecCallSession extends InboundCallSession {
headers: { headers: {
'Content-Type': 'application/sdp', 'Content-Type': 'application/sdp',
'X-Trace-ID': this.req.locals.traceId, 'X-Trace-ID': this.req.locals.traceId,
'X-Call-Sid': this.req.locals.callSid 'X-Call-Sid': this.req.locals.callSid,
...(this.applicationSid && {'X-Application-Sid': this.applicationSid})
}, },
localSdp: combinedSdp localSdp: combinedSdp
}); });

View File

@@ -82,6 +82,7 @@ class TaskGather extends Task {
this.requestSnr = recognizer.requestSnr || false; this.requestSnr = recognizer.requestSnr || false;
this.initialSpeechTimeoutMs = recognizer.initialSpeechTimeoutMs || 0; this.initialSpeechTimeoutMs = recognizer.initialSpeechTimeoutMs || 0;
this.azureServiceEndpoint = recognizer.azureServiceEndpoint; this.azureServiceEndpoint = recognizer.azureServiceEndpoint;
this.azureSttEndpointId = recognizer.azureSttEndpointId;
} }
else { else {
this.hints = []; this.hints = [];
@@ -301,7 +302,7 @@ class TaskGather extends Task {
} }
if ('google' === this.vendor) { if ('google' === this.vendor) {
this.bugname = 'google_trancribe'; this.bugname = 'google_transcribe';
if (this.sttCredentials) opts.GOOGLE_APPLICATION_CREDENTIALS = JSON.stringify(this.sttCredentials.credentials); if (this.sttCredentials) opts.GOOGLE_APPLICATION_CREDENTIALS = JSON.stringify(this.sttCredentials.credentials);
[ [
['enhancedModel', 'GOOGLE_SPEECH_USE_ENHANCED'], ['enhancedModel', 'GOOGLE_SPEECH_USE_ENHANCED'],
@@ -339,7 +340,7 @@ class TaskGather extends Task {
ep.addCustomEventListener(GoogleTranscriptionEvents.VadDetected, this._onVadDetected.bind(this, cs, ep)); ep.addCustomEventListener(GoogleTranscriptionEvents.VadDetected, this._onVadDetected.bind(this, cs, ep));
} }
else if (['aws', 'polly'].includes(this.vendor)) { else if (['aws', 'polly'].includes(this.vendor)) {
this.bugname = 'aws_trancribe'; this.bugname = 'aws_transcribe';
if (this.vocabularyName) opts.AWS_VOCABULARY_NAME = this.vocabularyName; if (this.vocabularyName) opts.AWS_VOCABULARY_NAME = this.vocabularyName;
if (this.vocabularyFilterName) { if (this.vocabularyFilterName) {
opts.AWS_VOCABULARY_NAME = this.vocabularyFilterName; opts.AWS_VOCABULARY_NAME = this.vocabularyFilterName;
@@ -358,10 +359,18 @@ class TaskGather extends Task {
else if ('microsoft' === this.vendor) { else if ('microsoft' === this.vendor) {
this.bugname = 'azure_transcribe'; this.bugname = 'azure_transcribe';
if (this.sttCredentials) { if (this.sttCredentials) {
const {api_key, region, use_custom_stt, custom_stt_endpoint} = this.sttCredentials;
Object.assign(opts, { Object.assign(opts, {
'AZURE_SUBSCRIPTION_KEY': this.sttCredentials.api_key, 'AZURE_SUBSCRIPTION_KEY': api_key,
'AZURE_REGION': this.sttCredentials.region 'AZURE_REGION': region
}); });
if (this.azureSttEndpointId) {
Object.assign(opts, {'AZURE_SERVICE_ENDPOINT_ID': this.azureSttEndpointId});
}
else if (use_custom_stt && custom_stt_endpoint) {
Object.assign(opts, {'AZURE_SERVICE_ENDPOINT_ID': custom_stt_endpoint});
}
} }
if (this.hints && this.hints.length > 0) { if (this.hints && this.hints.length > 0) {
opts.AZURE_SPEECH_HINTS = this.hints.map((h) => h.trim()).join(','); opts.AZURE_SPEECH_HINTS = this.hints.map((h) => h.trim()).join(',');
@@ -641,7 +650,7 @@ class TaskGather extends Task {
} }
this.span.setAttributes({'stt.resolve': reason, 'stt.result': JSON.stringify(evt)}); this.span.setAttributes({'stt.resolve': reason, 'stt.result': JSON.stringify(evt)});
if (this.ep && this.ep.connected) { if (this.needsStt && this.ep && this.ep.connected) {
this.ep.stopTranscription({vendor: this.vendor}) this.ep.stopTranscription({vendor: this.vendor})
.catch((err) => this.logger.error({err}, 'Error stopping transcription')); .catch((err) => this.logger.error({err}, 'Error stopping transcription'));
} }

View File

@@ -497,6 +497,7 @@
"requestSnr": "boolean", "requestSnr": "boolean",
"initialSpeechTimeoutMs": "number", "initialSpeechTimeoutMs": "number",
"azureServiceEndpoint": "string", "azureServiceEndpoint": "string",
"azureSttEndpointId": "string",
"asrDtmfTerminationDigit": "string", "asrDtmfTerminationDigit": "string",
"asrTimeout": "number" "asrTimeout": "number"
}, },

View File

@@ -54,6 +54,7 @@ class TaskTranscribe extends Task {
this.requestSnr = recognizer.requestSnr || false; this.requestSnr = recognizer.requestSnr || false;
this.initialSpeechTimeoutMs = recognizer.initialSpeechTimeoutMs || 0; this.initialSpeechTimeoutMs = recognizer.initialSpeechTimeoutMs || 0;
this.azureServiceEndpoint = recognizer.azureServiceEndpoint; this.azureServiceEndpoint = recognizer.azureServiceEndpoint;
this.azureSttEndpointId = recognizer.azureSttEndpointId;
} }
get name() { return TaskName.Transcribe; } get name() { return TaskName.Transcribe; }
@@ -161,7 +162,7 @@ class TaskTranscribe extends Task {
ep.addCustomEventListener(AzureTranscriptionEvents.NoSpeechDetected, this._onNoAudio.bind(this, cs, ep, channel)); ep.addCustomEventListener(AzureTranscriptionEvents.NoSpeechDetected, this._onNoAudio.bind(this, cs, ep, channel));
if (this.vendor === 'google') { if (this.vendor === 'google') {
this.bugname = 'google_trancribe'; this.bugname = 'google_transcribe';
if (this.sttCredentials) opts.GOOGLE_APPLICATION_CREDENTIALS = JSON.stringify(this.sttCredentials.credentials); if (this.sttCredentials) opts.GOOGLE_APPLICATION_CREDENTIALS = JSON.stringify(this.sttCredentials.credentials);
[ [
['enhancedModel', 'GOOGLE_SPEECH_USE_ENHANCED'], ['enhancedModel', 'GOOGLE_SPEECH_USE_ENHANCED'],
@@ -199,7 +200,7 @@ class TaskTranscribe extends Task {
.catch((err) => this.logger.info(err, 'TaskTranscribe:_startTranscribing with google')); .catch((err) => this.logger.info(err, 'TaskTranscribe:_startTranscribing with google'));
} }
else if (this.vendor === 'aws') { else if (this.vendor === 'aws') {
this.bugname = 'aws_trancribe'; this.bugname = 'aws_transcribe';
[ [
['diarization', 'AWS_SHOW_SPEAKER_LABEL'], ['diarization', 'AWS_SHOW_SPEAKER_LABEL'],
['identifyChannels', 'AWS_ENABLE_CHANNEL_IDENTIFICATION'] ['identifyChannels', 'AWS_ENABLE_CHANNEL_IDENTIFICATION']
@@ -231,11 +232,18 @@ class TaskTranscribe extends Task {
.catch((err) => this.logger.info(err, 'TaskTranscribe:_startTranscribing with aws')); .catch((err) => this.logger.info(err, 'TaskTranscribe:_startTranscribing with aws'));
} }
else if (this.vendor === 'microsoft') { else if (this.vendor === 'microsoft') {
this.bugname = 'azure_trancribe'; this.bugname = 'azure_transcribe';
const {api_key, region, use_custom_stt, custom_stt_endpoint} = this.sttCredentials;
Object.assign(opts, { Object.assign(opts, {
'AZURE_SUBSCRIPTION_KEY': this.sttCredentials.api_key, 'AZURE_SUBSCRIPTION_KEY': api_key,
'AZURE_REGION': this.sttCredentials.region 'AZURE_REGION': region
}); });
if (this.azureSttEndpointId) {
Object.assign(opts, {'AZURE_SERVICE_ENDPOINT_ID': this.azureSttEndpointId});
}
else if (use_custom_stt && custom_stt_endpoint) {
Object.assign(opts, {'AZURE_SERVICE_ENDPOINT_ID': custom_stt_endpoint});
}
if (this.hints && this.hints.length > 0) { if (this.hints && this.hints.length > 0) {
opts.AZURE_SPEECH_HINTS = this.hints.map((h) => h.trim()).join(','); opts.AZURE_SPEECH_HINTS = this.hints.map((h) => h.trim()).join(',');
} }

View File

@@ -36,6 +36,8 @@ const speechMapper = (cred) => {
const o = JSON.parse(decrypt(credential)); const o = JSON.parse(decrypt(credential));
obj.api_key = o.api_key; obj.api_key = o.api_key;
obj.region = o.region; obj.region = o.region;
obj.use_custom_stt = o.use_custom_stt;
obj.custom_stt_endpoint = o.custom_stt_endpoint;
} }
else if ('wellsaid' === obj.vendor) { else if ('wellsaid' === obj.vendor) {
const o = JSON.parse(decrypt(credential)); const o = JSON.parse(decrypt(credential));

View File

@@ -67,7 +67,8 @@ class SingleDialer extends Emitter {
...opts.headers, ...opts.headers,
...(this.target.headers || {}), ...(this.target.headers || {}),
'X-Jambonz-Routing': this.target.type, 'X-Jambonz-Routing': this.target.type,
'X-Call-Sid': this.callSid 'X-Call-Sid': this.callSid,
...(this.applicationSid && {'X-Application-Sid': this.applicationSid})
}; };
if (srf.locals.fsUUID) { if (srf.locals.fsUUID) {
opts.headers = { opts.headers = {

View File

@@ -138,7 +138,7 @@ class WsRequestor extends BaseRequestor {
success: (response) => { success: (response) => {
clearTimeout(timer); clearTimeout(timer);
const rtt = this._roundTrip(startAt); const rtt = this._roundTrip(startAt);
this.logger.info({response}, `WsRequestor:request ${url} succeeded in ${rtt}ms`); this.logger.debug({response}, `WsRequestor:request ${url} succeeded in ${rtt}ms`);
this.stats.histogram('app.hook.ws_response_time', rtt, ['hook_type:app']); this.stats.histogram('app.hook.ws_response_time', rtt, ['hook_type:app']);
resolve(response); resolve(response);
}, },
@@ -286,7 +286,7 @@ class WsRequestor extends BaseRequestor {
const obj = JSON.parse(content); const obj = JSON.parse(content);
const {type, msgid, command, call_sid = this.call_sid, queueCommand = false, data} = obj; const {type, msgid, command, call_sid = this.call_sid, queueCommand = false, data} = obj;
this.logger.debug({obj}, 'WsRequestor:request websocket: received'); //this.logger.debug({obj}, 'WsRequestor:request websocket: received');
assert.ok(type, 'type property not supplied'); assert.ok(type, 'type property not supplied');
switch (type) { switch (type) {
@@ -323,7 +323,7 @@ class WsRequestor extends BaseRequestor {
_recvCommand(msgid, command, call_sid, queueCommand, data) { _recvCommand(msgid, command, call_sid, queueCommand, data) {
// TODO: validate command // TODO: validate command
this.logger.info({msgid, command, call_sid, queueCommand, data}, 'received command'); this.logger.debug({msgid, command, call_sid, queueCommand, data}, 'received command');
this.emit('command', {msgid, command, call_sid, queueCommand, data}); this.emit('command', {msgid, command, call_sid, queueCommand, data});
} }
} }

28
package-lock.json generated
View File

@@ -11,9 +11,9 @@
"dependencies": { "dependencies": {
"@jambonz/db-helpers": "^0.6.18", "@jambonz/db-helpers": "^0.6.18",
"@jambonz/http-health-check": "^0.0.1", "@jambonz/http-health-check": "^0.0.1",
"@jambonz/realtimedb-helpers": "^0.4.30", "@jambonz/realtimedb-helpers": "^0.4.32",
"@jambonz/stats-collector": "^0.1.6", "@jambonz/stats-collector": "^0.1.6",
"@jambonz/time-series": "^0.2.1", "@jambonz/time-series": "^0.2.5",
"@opentelemetry/api": "^1.1.0", "@opentelemetry/api": "^1.1.0",
"@opentelemetry/exporter-jaeger": "^1.3.1", "@opentelemetry/exporter-jaeger": "^1.3.1",
"@opentelemetry/exporter-trace-otlp-http": "^0.27.0", "@opentelemetry/exporter-trace-otlp-http": "^0.27.0",
@@ -543,9 +543,9 @@
} }
}, },
"node_modules/@jambonz/realtimedb-helpers": { "node_modules/@jambonz/realtimedb-helpers": {
"version": "0.4.30", "version": "0.4.32",
"resolved": "https://registry.npmjs.org/@jambonz/realtimedb-helpers/-/realtimedb-helpers-0.4.30.tgz", "resolved": "https://registry.npmjs.org/@jambonz/realtimedb-helpers/-/realtimedb-helpers-0.4.32.tgz",
"integrity": "sha512-bF1crcyz/sYDCnOX0odbI1KLZUo6TADc548MHX5/O2+gY6Yi6u9GdEaf2u5q5fgmpoJ+Qrf3fuiENxzro+Pq8g==", "integrity": "sha512-m08rqFEg6I43JVwjiyt0ahvljxJ3YvL3xsKHMoSJw48hdy/8V4w9ovYnUNaZGhaerhJVw36fCfTk4YNlByTnVw==",
"dependencies": { "dependencies": {
"@google-cloud/text-to-speech": "^3.4.0", "@google-cloud/text-to-speech": "^3.4.0",
"@jambonz/promisify-redis": "^0.0.6", "@jambonz/promisify-redis": "^0.0.6",
@@ -566,9 +566,9 @@
} }
}, },
"node_modules/@jambonz/time-series": { "node_modules/@jambonz/time-series": {
"version": "0.2.1", "version": "0.2.5",
"resolved": "https://registry.npmjs.org/@jambonz/time-series/-/time-series-0.2.1.tgz", "resolved": "https://registry.npmjs.org/@jambonz/time-series/-/time-series-0.2.5.tgz",
"integrity": "sha512-uAoeZ3ibS7kEOGdT+vaY8BB8hOV4q38eEaF+d5OvLQaHCrPonNiwB8tWhhXDwtYdDompfqVRUy/plNA9fyS7Vw==", "integrity": "sha512-WrVenxY4ZgW0YYNIXdAz3ZKao8IQy612RVDAnYq7oWvHHqzgLmLrbIvTXKhycd27iYvwFAPCcUDk1EMuUoPLPA==",
"dependencies": { "dependencies": {
"debug": "^4.3.1", "debug": "^4.3.1",
"influx": "^5.9.3" "influx": "^5.9.3"
@@ -6669,9 +6669,9 @@
} }
}, },
"@jambonz/realtimedb-helpers": { "@jambonz/realtimedb-helpers": {
"version": "0.4.30", "version": "0.4.32",
"resolved": "https://registry.npmjs.org/@jambonz/realtimedb-helpers/-/realtimedb-helpers-0.4.30.tgz", "resolved": "https://registry.npmjs.org/@jambonz/realtimedb-helpers/-/realtimedb-helpers-0.4.32.tgz",
"integrity": "sha512-bF1crcyz/sYDCnOX0odbI1KLZUo6TADc548MHX5/O2+gY6Yi6u9GdEaf2u5q5fgmpoJ+Qrf3fuiENxzro+Pq8g==", "integrity": "sha512-m08rqFEg6I43JVwjiyt0ahvljxJ3YvL3xsKHMoSJw48hdy/8V4w9ovYnUNaZGhaerhJVw36fCfTk4YNlByTnVw==",
"requires": { "requires": {
"@google-cloud/text-to-speech": "^3.4.0", "@google-cloud/text-to-speech": "^3.4.0",
"@jambonz/promisify-redis": "^0.0.6", "@jambonz/promisify-redis": "^0.0.6",
@@ -6692,9 +6692,9 @@
} }
}, },
"@jambonz/time-series": { "@jambonz/time-series": {
"version": "0.2.1", "version": "0.2.5",
"resolved": "https://registry.npmjs.org/@jambonz/time-series/-/time-series-0.2.1.tgz", "resolved": "https://registry.npmjs.org/@jambonz/time-series/-/time-series-0.2.5.tgz",
"integrity": "sha512-uAoeZ3ibS7kEOGdT+vaY8BB8hOV4q38eEaF+d5OvLQaHCrPonNiwB8tWhhXDwtYdDompfqVRUy/plNA9fyS7Vw==", "integrity": "sha512-WrVenxY4ZgW0YYNIXdAz3ZKao8IQy612RVDAnYq7oWvHHqzgLmLrbIvTXKhycd27iYvwFAPCcUDk1EMuUoPLPA==",
"requires": { "requires": {
"debug": "^4.3.1", "debug": "^4.3.1",
"influx": "^5.9.3" "influx": "^5.9.3"

View File

@@ -16,8 +16,7 @@
"type": "git", "type": "git",
"url": "https://github.com/jambonz/jambonz-feature-server.git" "url": "https://github.com/jambonz/jambonz-feature-server.git"
}, },
"bugs": { "bugs": {},
},
"scripts": { "scripts": {
"start": "node app", "start": "node app",
"test": "NODE_ENV=test JAMBONES_HOSTING=1 HTTP_POOL=1 DRACHTIO_HOST=127.0.0.1 DRACHTIO_PORT=9060 DRACHTIO_SECRET=cymru JAMBONES_MYSQL_HOST=127.0.0.1 JAMBONES_MYSQL_PORT=3360 JAMBONES_MYSQL_USER=jambones_test JAMBONES_MYSQL_PASSWORD=jambones_test JAMBONES_MYSQL_DATABASE=jambones_test JAMBONES_REDIS_HOST=127.0.0.1 JAMBONES_REDIS_PORT=16379 JAMBONES_LOGLEVEL=error ENABLE_METRICS=0 HTTP_PORT=3000 JAMBONES_SBCS=172.38.0.10 JAMBONES_FREESWITCH=127.0.0.1:8022:ClueCon:docker-host JAMBONES_TIME_SERIES_HOST=127.0.0.1 JAMBONES_NETWORK_CIDR=172.38.0.0/16 node test/ ", "test": "NODE_ENV=test JAMBONES_HOSTING=1 HTTP_POOL=1 DRACHTIO_HOST=127.0.0.1 DRACHTIO_PORT=9060 DRACHTIO_SECRET=cymru JAMBONES_MYSQL_HOST=127.0.0.1 JAMBONES_MYSQL_PORT=3360 JAMBONES_MYSQL_USER=jambones_test JAMBONES_MYSQL_PASSWORD=jambones_test JAMBONES_MYSQL_DATABASE=jambones_test JAMBONES_REDIS_HOST=127.0.0.1 JAMBONES_REDIS_PORT=16379 JAMBONES_LOGLEVEL=error ENABLE_METRICS=0 HTTP_PORT=3000 JAMBONES_SBCS=172.38.0.10 JAMBONES_FREESWITCH=127.0.0.1:8022:ClueCon:docker-host JAMBONES_TIME_SERIES_HOST=127.0.0.1 JAMBONES_NETWORK_CIDR=172.38.0.0/16 node test/ ",
@@ -27,9 +26,9 @@
"dependencies": { "dependencies": {
"@jambonz/db-helpers": "^0.6.18", "@jambonz/db-helpers": "^0.6.18",
"@jambonz/http-health-check": "^0.0.1", "@jambonz/http-health-check": "^0.0.1",
"@jambonz/realtimedb-helpers": "^0.4.30", "@jambonz/realtimedb-helpers": "^0.4.32",
"@jambonz/stats-collector": "^0.1.6", "@jambonz/stats-collector": "^0.1.6",
"@jambonz/time-series": "^0.2.1", "@jambonz/time-series": "^0.2.5",
"@opentelemetry/api": "^1.1.0", "@opentelemetry/api": "^1.1.0",
"@opentelemetry/exporter-jaeger": "^1.3.1", "@opentelemetry/exporter-jaeger": "^1.3.1",
"@opentelemetry/exporter-trace-otlp-http": "^0.27.0", "@opentelemetry/exporter-trace-otlp-http": "^0.27.0",