mirror of
https://github.com/jambonz/jambonz-feature-server.git
synced 2025-12-22 01:27:55 +00:00
add bargein support to gather
This commit is contained in:
@@ -17,7 +17,7 @@ class TaskGather extends Task {
|
|||||||
|
|
||||||
[
|
[
|
||||||
'finishOnKey', 'hints', 'input', 'numDigits',
|
'finishOnKey', 'hints', 'input', 'numDigits',
|
||||||
'partialResultHook',
|
'partialResultHook', 'bargein',
|
||||||
'speechTimeout', 'timeout', 'say', 'play'
|
'speechTimeout', 'timeout', 'say', 'play'
|
||||||
].forEach((k) => this[k] = this.data[k]);
|
].forEach((k) => this[k] = this.data[k]);
|
||||||
|
|
||||||
@@ -34,6 +34,9 @@ class TaskGather extends Task {
|
|||||||
const {enable, voiceMs = 0, mode = -1} = recognizer.vad || {};
|
const {enable, voiceMs = 0, mode = -1} = recognizer.vad || {};
|
||||||
this.vad = {enable, voiceMs, mode};
|
this.vad = {enable, voiceMs, mode};
|
||||||
|
|
||||||
|
this.listenDuringPrompt = this.data.listenDuringPrompt === false ? false : true;
|
||||||
|
this.minBargeinWordCount = this.data.minBargeinWordCount || 1;
|
||||||
|
|
||||||
/* aws options */
|
/* aws options */
|
||||||
this.vocabularyName = recognizer.vocabularyName;
|
this.vocabularyName = recognizer.vocabularyName;
|
||||||
this.vocabularyFilterName = recognizer.vocabularyFilterName;
|
this.vocabularyFilterName = recognizer.vocabularyFilterName;
|
||||||
@@ -84,22 +87,36 @@ class TaskGather extends Task {
|
|||||||
throw new Error(`no speech-to-text service credentials for ${this.vendor} have been configured`);
|
throw new Error(`no speech-to-text service credentials for ${this.vendor} have been configured`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const startListening = (cs, ep) => {
|
||||||
|
this._startTimer();
|
||||||
|
if (this.input.includes('speech') && !this.listenDuringPrompt) {
|
||||||
|
this._initSpeech(cs, ep)
|
||||||
|
.then(() => {
|
||||||
|
this._startTranscribing(ep);
|
||||||
|
return updateSpeechCredentialLastUsed(this.sttCredentials.speech_credential_sid);
|
||||||
|
})
|
||||||
|
.catch(() => {});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (this.sayTask) {
|
if (this.sayTask) {
|
||||||
this.sayTask.exec(cs, ep); // kicked off, _not_ waiting for it to complete
|
this.sayTask.exec(cs, ep); // kicked off, _not_ waiting for it to complete
|
||||||
this.sayTask.on('playDone', (err) => {
|
this.sayTask.on('playDone', (err) => {
|
||||||
if (!this.killed) this._startTimer();
|
if (err) return this.logger.error({err}, 'Gather:exec Error playing tts');
|
||||||
|
this.logger.debug('Gather: say task completed');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if (this.playTask) {
|
else if (this.playTask) {
|
||||||
this.playTask.exec(cs, ep); // kicked off, _not_ waiting for it to complete
|
this.playTask.exec(cs, ep); // kicked off, _not_ waiting for it to complete
|
||||||
this.playTask.on('playDone', (err) => {
|
this.playTask.on('playDone', (err) => {
|
||||||
if (!this.killed) this._startTimer();
|
if (err) return this.logger.error({err}, 'Gather:exec Error playing url');
|
||||||
|
if (!this.killed) startListening(cs, ep);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else this._startTimer();
|
else this._startTimer();
|
||||||
|
|
||||||
if (this.input.includes('speech')) {
|
if (this.input.includes('speech') && this.listenDuringPrompt) {
|
||||||
await this._initSpeech(cs, ep);
|
await this._initSpeech(cs, ep);
|
||||||
this._startTranscribing(ep);
|
this._startTranscribing(ep);
|
||||||
updateSpeechCredentialLastUsed(this.sttCredentials.speech_credential_sid)
|
updateSpeechCredentialLastUsed(this.sttCredentials.speech_credential_sid)
|
||||||
@@ -207,7 +224,7 @@ class TaskGather extends Task {
|
|||||||
ep.startTranscription({
|
ep.startTranscription({
|
||||||
vendor: this.vendor,
|
vendor: this.vendor,
|
||||||
locale: this.language,
|
locale: this.language,
|
||||||
interim: this.partialResultCallback ? true : false,
|
interim: this.partialResultCallback || this.bargein,
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
const {writeAlerts, AlertType} = this.cs.srf.locals;
|
const {writeAlerts, AlertType} = this.cs.srf.locals;
|
||||||
this.logger.error(err, 'TaskGather:_startTranscribing error');
|
this.logger.error(err, 'TaskGather:_startTranscribing error');
|
||||||
@@ -263,11 +280,23 @@ class TaskGather extends Task {
|
|||||||
}
|
}
|
||||||
this.logger.debug(evt, 'TaskGather:_onTranscription');
|
this.logger.debug(evt, 'TaskGather:_onTranscription');
|
||||||
if (evt.is_final) this._resolve('speech', evt);
|
if (evt.is_final) this._resolve('speech', evt);
|
||||||
else if (this.partialResultHook) {
|
else {
|
||||||
this.cs.requestor.request('verb:hook', this.partialResultHook, Object.assign({speech: evt}, this.cs.callInfo))
|
if (this.bargein && evt.alternatives[0].transcript.split(' ').length >= this.minBargeinWordCount) {
|
||||||
|
this.logger.debug('Gather:_onTranscription - killing audio due to bargein');
|
||||||
|
this._killAudio(cs);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (this.bargein && evt.alternatives[0].transcript.split(' ').length >= this.minBargeinWordCount) {
|
||||||
|
this.logger.debug('Gather:_onTranscription - killing audio due to bargein');
|
||||||
|
this._killAudio(cs);
|
||||||
|
}
|
||||||
|
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'));
|
.catch((err) => this.logger.info(err, 'GatherTask:_onTranscription error'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
_onEndOfUtterance(cs, ep) {
|
_onEndOfUtterance(cs, ep) {
|
||||||
this.logger.info('TaskGather:_onEndOfUtterance');
|
this.logger.info('TaskGather:_onEndOfUtterance');
|
||||||
if (!this.resolved && !this.killed) {
|
if (!this.resolved && !this.killed) {
|
||||||
|
|||||||
@@ -80,7 +80,11 @@ class TaskSay extends Task {
|
|||||||
const {memberId, confName, confUuid} = cs;
|
const {memberId, confName, confUuid} = cs;
|
||||||
await this.playToConfMember(this.ep, memberId, confName, confUuid, filepath[segment]);
|
await this.playToConfMember(this.ep, memberId, confName, confUuid, filepath[segment]);
|
||||||
}
|
}
|
||||||
else await ep.play(filepath[segment]);
|
else {
|
||||||
|
this.logger.debug(`Say:exec sending command to play file ${filepath[segment]}`);
|
||||||
|
await ep.play(filepath[segment]);
|
||||||
|
this.logger.debug(`Say:exec completed play file ${filepath[segment]}`);
|
||||||
|
}
|
||||||
} while (!this.killed && ++segment < filepath.length);
|
} while (!this.killed && ++segment < filepath.length);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
@@ -100,6 +100,9 @@
|
|||||||
"numDigits": "number",
|
"numDigits": "number",
|
||||||
"partialResultHook": "object|string",
|
"partialResultHook": "object|string",
|
||||||
"speechTimeout": "number",
|
"speechTimeout": "number",
|
||||||
|
"listenDuringPrompt": "boolean",
|
||||||
|
"bargein": "boolean",
|
||||||
|
"minBargeinWordCount": "number",
|
||||||
"timeout": "number",
|
"timeout": "number",
|
||||||
"recognizer": "#recognizer",
|
"recognizer": "#recognizer",
|
||||||
"play": "#play",
|
"play": "#play",
|
||||||
|
|||||||
Reference in New Issue
Block a user