const Task = require('./task'); const {TaskName, TaskPreconditions} = require('../utils/constants'); class TaskConfig extends Task { constructor(logger, opts) { super(logger, opts); [ 'synthesizer', 'recognizer', 'bargeIn', 'record' ].forEach((k) => this[k] = this.data[k] || {}); if (this.bargeIn.enable) { this.gatherOpts = { verb: 'gather', timeout: 0, bargein: true, input: ['speech'] }; [ 'finishOnKey', 'input', 'numDigits', 'minDigits', 'maxDigits', 'interDigitTimeout', 'bargein', 'dtmfBargein', 'minBargeinWordCount', 'actionHook' ].forEach((k) => { if (this.bargeIn[k]) this.gatherOpts[k] = this.bargeIn[k]; }); } if (this.bargeIn.sticky) this.autoEnable = true; this.preconditions = (this.bargeIn.enable || this.record?.action) ? TaskPreconditions.Endpoint : TaskPreconditions.None; } get name() { return TaskName.Config; } get hasSynthesizer() { return Object.keys(this.synthesizer).length; } get hasRecognizer() { return Object.keys(this.recognizer).length; } get summary() { const phrase = []; if (this.bargeIn.enable) phrase.push('enable barge-in'); if (this.hasSynthesizer) { const {vendor:v, language:l, voice} = this.synthesizer; const s = `{${v},${l},${voice}}`; phrase.push(`set synthesizer${s}`); } if (this.hasRecognizer) { const {vendor:v, language:l} = this.recognizer; const s = `{${v},${l}}`; phrase.push(`set recognizer${s}`); } if (this.data.amd) phrase.push('enable amd'); return `${this.name}{${phrase.join(',')}`; } async exec(cs) { await super.exec(cs); if (this.data.amd) { this.startAmd = cs.startAmd; this.stopAmd = cs.stopAmd; this.on('amd', this._onAmdEvent.bind(this, cs)); } if (this.hasSynthesizer) { cs.speechSynthesisVendor = this.synthesizer.vendor !== 'default' ? this.synthesizer.vendor : cs.speechSynthesisVendor; cs.speechSynthesisLanguage = this.synthesizer.language !== 'default' ? this.synthesizer.language : cs.speechSynthesisLanguage; cs.speechSynthesisVoice = this.synthesizer.voice !== 'default' ? this.synthesizer.voice : cs.speechSynthesisVoice; this.logger.info({synthesizer: this.synthesizer}, 'Config: updated synthesizer'); } if (this.hasRecognizer) { cs.speechRecognizerVendor = this.recognizer.vendor !== 'default' ? this.recognizer.vendor : cs.speechRecognizerVendor; cs.speechRecognizerLanguage = this.recognizer.language !== 'default' ? this.recognizer.language : cs.speechRecognizerLanguage; cs.isContinuousAsr = typeof this.recognizer.asrTimeout === 'number' ? true : false; if (cs.isContinuousAsr) { cs.asrTimeout = this.recognizer.asrTimeout; cs.asrDtmfTerminationDigit = this.recognizer.asrDtmfTerminationDigit; } if (Array.isArray(this.recognizer.hints)) { const obj = {hints: this.recognizer.hints}; if (typeof this.recognizer.hintsBoost === 'number') { obj.hintsBoost = this.recognizer.hintsBoost; } cs.globalSttHints = obj; } this.logger.info({ recognizer: this.recognizer, isContinuousAsr: cs.isContinuousAsr }, 'Config: updated recognizer'); } if ('enable' in this.bargeIn) { if (this.bargeIn.enable === true && this.gatherOpts) { this.gatherOpts.recognizer = this.hasRecognizer ? this.recognizer : { vendor: cs.speechRecognizerVendor, language: cs.speechRecognizerLanguage }; this.logger.info({opts: this.gatherOpts}, 'Config: enabling bargeIn'); cs.enableBotMode(this.gatherOpts, this.autoEnable); } else if (this.bargeIn.enable === false) { this.logger.info('Config: disabling bargeIn'); cs.disableBotMode(); } } if (this.record.action) { try { await cs.notifyRecordOptions(this.record); } catch (err) { this.logger.info({err}, 'Config: error starting recording'); } } } async kill(cs) { super.kill(cs); } _onAmdEvent(cs, evt) { this.logger.info({evt}, 'Config:_onAmdEvent'); const {actionHook} = this.data.amd; this.performHook(cs, actionHook, evt); } } module.exports = TaskConfig;