mirror of
https://github.com/jambonz/jambonz-feature-server.git
synced 2026-02-14 18:30:59 +00:00
merge features from hosted branch (#32)
major merge of features from the hosted branch that was created temporarily during the initial launch of jambonz.org
This commit is contained in:
@@ -51,9 +51,23 @@ class TaskGather extends Task {
|
||||
|
||||
async exec(cs, ep) {
|
||||
await super.exec(cs);
|
||||
const {updateSpeechCredentialLastUsed} = require('../utils/db-utils')(this.logger, cs.srf);
|
||||
|
||||
this.ep = ep;
|
||||
if ('default' === this.vendor || !this.vendor) this.vendor = cs.speechRecognizerVendor;
|
||||
if ('default' === this.language || !this.language) this.language = cs.speechRecognizerLanguage;
|
||||
this.sttCredentials = cs.getSpeechCredentials(this.vendor, 'stt');
|
||||
if (!this.sttCredentials) {
|
||||
const {writeAlerts, AlertType} = cs.srf.locals;
|
||||
this.logger.info(`TaskGather:exec - ERROR stt using ${this.vendor} requested but not creds supplied`);
|
||||
writeAlerts({
|
||||
account_sid: cs.accountSid,
|
||||
alert_type: AlertType.STT_NOT_PROVISIONED,
|
||||
vendor: this.vendor
|
||||
}).catch((err) => this.logger.info({err}, 'Error generating alert for no stt'));
|
||||
|
||||
throw new Error(`no speech-to-text service credentials for ${this.vendor} have been configured`);
|
||||
}
|
||||
|
||||
try {
|
||||
if (this.sayTask) {
|
||||
@@ -71,8 +85,10 @@ class TaskGather extends Task {
|
||||
else this._startTimer();
|
||||
|
||||
if (this.input.includes('speech')) {
|
||||
await this._initSpeech(ep);
|
||||
await this._initSpeech(cs, ep);
|
||||
this._startTranscribing(ep);
|
||||
updateSpeechCredentialLastUsed(this.sttCredentials.speech_credential_sid)
|
||||
.catch(() => {/*already logged error */});
|
||||
}
|
||||
|
||||
if (this.input.includes('digits')) {
|
||||
@@ -105,10 +121,11 @@ class TaskGather extends Task {
|
||||
this._killAudio();
|
||||
}
|
||||
|
||||
async _initSpeech(ep) {
|
||||
async _initSpeech(cs, ep) {
|
||||
const opts = {};
|
||||
|
||||
if ('google' === this.vendor) {
|
||||
if (this.sttCredentials) opts.GOOGLE_APPLICATION_CREDENTIALS = JSON.stringify(this.sttCredentials.credentials);
|
||||
Object.assign(opts, {
|
||||
GOOGLE_SPEECH_USE_ENHANCED: true,
|
||||
GOOGLE_SPEECH_SINGLE_UTTERANCE: true,
|
||||
@@ -121,6 +138,8 @@ class TaskGather extends Task {
|
||||
if (this.profanityFilter === true) {
|
||||
Object.assign(opts, {'GOOGLE_SPEECH_PROFANITY_FILTER': true});
|
||||
}
|
||||
ep.addCustomEventListener(GoogleTranscriptionEvents.Transcription, this._onTranscription.bind(this, cs, ep));
|
||||
ep.addCustomEventListener(GoogleTranscriptionEvents.EndOfUtterance, this._onEndOfUtterance.bind(this, cs, ep));
|
||||
}
|
||||
else {
|
||||
if (this.vocabularyName) opts.AWS_VOCABULARY_NAME = this.vocabularyName;
|
||||
@@ -129,18 +148,16 @@ class TaskGather extends Task {
|
||||
opts.AWS_VOCABULARY_FILTER_METHOD = this.filterMethod || 'mask';
|
||||
}
|
||||
Object.assign(opts, {
|
||||
AWS_ACCESS_KEY_ID: process.env.AWS_ACCESS_KEY_ID,
|
||||
AWS_SECRET_ACCESS_KEY: process.env.AWS_SECRET_ACCESS_KEY,
|
||||
AWS_REGION: process.env.AWS_REGION
|
||||
AWS_ACCESS_KEY_ID: this.sttCredentials.accessKeyId,
|
||||
AWS_SECRET_ACCESS_KEY: this.sttCredentials.secretAccessKey,
|
||||
AWS_REGION: this.sttCredentials.region
|
||||
});
|
||||
ep.addCustomEventListener(AwsTranscriptionEvents.Transcription, this._onTranscription.bind(this, cs, ep));
|
||||
}
|
||||
this.logger.debug(`setting freeswitch vars ${JSON.stringify(opts)}`);
|
||||
this.logger.debug({vars: opts}, 'setting freeswitch vars');
|
||||
await ep.set(opts)
|
||||
.catch((err) => this.logger.info(err, 'Error setting channel variables'));
|
||||
|
||||
ep.addCustomEventListener(GoogleTranscriptionEvents.Transcription, this._onTranscription.bind(this, ep));
|
||||
ep.addCustomEventListener(AwsTranscriptionEvents.Transcription, this._onTranscription.bind(this, ep));
|
||||
ep.addCustomEventListener(GoogleTranscriptionEvents.EndOfUtterance, this._onEndOfUtterance.bind(this, ep));
|
||||
}
|
||||
|
||||
_startTranscribing(ep) {
|
||||
@@ -148,7 +165,16 @@ class TaskGather extends Task {
|
||||
vendor: this.vendor,
|
||||
locale: this.language,
|
||||
interim: this.partialResultCallback ? true : false,
|
||||
}).catch((err) => this.logger.error(err, 'TaskGather:_startTranscribing error'));
|
||||
}).catch((err) => {
|
||||
const {writeAlerts, AlertType} = this.cs.srf.locals;
|
||||
this.logger.error(err, 'TaskGather:_startTranscribing error');
|
||||
writeAlerts({
|
||||
account_sid: this.cs.accountSid,
|
||||
alert_type: AlertType.STT_FAILURE,
|
||||
vendor: this.vendor,
|
||||
detail: err.message
|
||||
});
|
||||
}).catch((err) => this.logger.info({err}, 'Error generating alert for tts failure'));
|
||||
}
|
||||
|
||||
_startTimer() {
|
||||
@@ -175,19 +201,23 @@ class TaskGather extends Task {
|
||||
}
|
||||
}
|
||||
|
||||
_onTranscription(ep, evt) {
|
||||
_onTranscription(cs, ep, evt) {
|
||||
if ('aws' === this.vendor && Array.isArray(evt) && evt.length > 0) evt = evt[0];
|
||||
this.logger.debug(evt, 'TaskGather:_onTranscription');
|
||||
const final = evt.is_final;
|
||||
if (final) this._resolve('speech', evt);
|
||||
if (final) {
|
||||
this._resolve('speech', evt);
|
||||
}
|
||||
else if (this.partialResultHook) {
|
||||
this.cs.requestor.request(this.partialResultHook, Object.assign({speech: evt}, this.cs.callInfo))
|
||||
.catch((err) => this.logger.info(err, 'GatherTask:_onTranscription error'));
|
||||
}
|
||||
}
|
||||
_onEndOfUtterance(ep, evt) {
|
||||
this.logger.info(evt, 'TaskGather:_onEndOfUtterance');
|
||||
this._startTranscribing(ep);
|
||||
_onEndOfUtterance(cs, ep) {
|
||||
this.logger.info('TaskGather:_onEndOfUtterance');
|
||||
if (!this.resolved && !this.killed) {
|
||||
this._startTranscribing(ep);
|
||||
}
|
||||
}
|
||||
|
||||
async _resolve(reason, evt) {
|
||||
@@ -202,13 +232,10 @@ class TaskGather extends Task {
|
||||
|
||||
this._clearTimer();
|
||||
if (reason.startsWith('dtmf')) {
|
||||
await this.performAction({reason: 'dtmfDetected', digits: this.digitBuffer});
|
||||
await this.performAction({digits: this.digitBuffer});
|
||||
}
|
||||
else if (reason.startsWith('speech')) {
|
||||
await this.performAction({reason: 'speechDetected', speech: evt});
|
||||
}
|
||||
else if (reason.startsWith('timeout')) {
|
||||
await this.performAction({reason: 'inputTimeout'});
|
||||
await this.performAction({speech: evt});
|
||||
}
|
||||
this.notifyTaskDone();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user