From 83c015c839d759ab0538df5896e48f6a7202ffeb Mon Sep 17 00:00:00 2001 From: akirilyuk Date: Wed, 2 Feb 2022 14:59:04 +0100 Subject: [PATCH] first implementation of nextTurn and gather task cognigy --- lib/tasks/cognigy/index.js | 54 ++++++++++++++++++++++-------- lib/tasks/cognigy/speech-config.js | 38 ++++++++++++++------- package-lock.json | 1 + package.json | 1 + 4 files changed, 68 insertions(+), 26 deletions(-) diff --git a/lib/tasks/cognigy/index.js b/lib/tasks/cognigy/index.js index a6050192..cc18d497 100644 --- a/lib/tasks/cognigy/index.js +++ b/lib/tasks/cognigy/index.js @@ -176,8 +176,8 @@ class Cognigy extends Task { this.notifyTaskDone(); } - _makeGatherTask({textPrompt, urlPrompt} = {}) { - const config = this.config.makeGatherTaskConfig({textPrompt, urlPrompt}); + _makeGatherTask({textPrompt, urlPrompt, turnConfig} = {}) { + const config = this.config.makeGatherTaskConfig({textPrompt, urlPrompt, turnConfig}); const {retry, ...rest} = config; this.retry = retry; const gather = makeTask(this.logger, {gather: rest}, this); @@ -199,19 +199,22 @@ class Cognigy extends Task { } _makeReferTask(referTo) { - const refer = makeTask(this.logger, {'sip:refer': { + return makeTask(this.logger, {'sip:refer': { referTo - }}); - return refer; + }} + ); } _makeHangupTask(reason) { - const hangup = makeTask(this.logger, {hangup: { + return makeTask(this.logger, {hangup: { headers: { 'X-Reason': reason } }}); - return hangup; + } + + _makePlayTask(url, loop) { + } /* if we need to interrupt the currently-running say task(s), call this */ @@ -235,11 +238,16 @@ class Cognigy extends Task { async _onBotFinalPing(cs, ep) { this.logger.info({prompts: this.prompts}, 'Cognigy:_onBotFinalPing'); try { - await this.taskQueue.lastPromise; - this.gatherTask = this._makeGatherTask(); - this.gatherTask.exec(cs, ep, this) - .catch((err) => this.logger.info({err}, 'Cognigy gather task returned error')); - this.prompts = []; + if (!this.gatherTaskExists) { + await this.taskQueue.lastPromise; + this.gatherTask = this._makeGatherTask(); + this.gatherTask.exec(cs, ep, this) + .catch((err) => this.logger.info({err}, 'Cognigy gather task returned error')); + this.prompts = []; + } else { + this.logger.info({}, 'no need to create a gather task, it already exists!'); + } + } catch (err) { this.logger.error({err}, 'Could not execute bot final ping!'); } @@ -264,8 +272,10 @@ class Cognigy extends Task { } const text = parseBotText(evt); - if (evt.data) this.config.update(evt.data); - if (text) { + if (evt.data && evt.data.config && evt.data.config.session) this.config.update(evt.data.config.session); + + // only add say task if its a normal cognigy node and not a "gather task" + if (text && (!evt.data || !evt.data.type || !evt.data.type !== 'gather')) { this._enqueueTask(async() => { this.logger.info({text}, 'received text'); const sayTask = this._makeSayTask(text); @@ -293,6 +303,22 @@ class Cognigy extends Task { cs.replaceApplication([this._makeReferTask(evt.data.referTo)]); }); return; + case 'gather': + this.gatherTaskExists = true; + this._enqueueTask(async() => { + this.gatherTask = this._makeGatherTask({ + textPrompt: evt.data.text, + urlPrompt: evt.data.url, + nextTurnConfig: evt.data.config && evt.data.config.nextTurn + }); + try { + this.gatherTask.exec(cs, ep, this); + } catch (err) { + this.logger.info({err}, 'Cognigy gather task returned error'); + } + this.gatherTaskExists = false; + }); + return; default: break; } diff --git a/lib/tasks/cognigy/speech-config.js b/lib/tasks/cognigy/speech-config.js index ff9fb2bd..a1c95e7a 100644 --- a/lib/tasks/cognigy/speech-config.js +++ b/lib/tasks/cognigy/speech-config.js @@ -1,5 +1,5 @@ const Emitter = require('events'); - +const lodash = require('lodash'); const hasKeys = (obj) => typeof obj === 'object' && Object.keys(obj) > 0; const stripNulls = (obj) => { @@ -13,19 +13,33 @@ class SpeechConfig extends Emitter { this.logger = logger; this.ep = ep; this.sessionConfig = opts.session || {}; - this.turnConfig = opts.nextTurn || {}; this.update(opts); } update(opts = {}) { - const {session, nextTurn = {}} = opts; - if (session) this.sessionConfig = {...this.sessionConfig, ...session}; - this.turnConfig = nextTurn; - this.logger.debug({opts, sessionLevel: this.sessionConfig, turnLevel: this.turnConfig}, 'SpeechConfig updated'); + // TODO validation of session params? + const {session } = opts; + if (session) { + this.sessionConfig = lodash.merge( + {}, + this.sessionConfig, + session + ); + } + //this.turnConfig = nextTurn; + this.logger.debug({opts, sessionLevel: this.sessionConfig}, 'SpeechConfig updated'); } - makeGatherTaskConfig({textPrompt, urlPrompt} = {}) { - const opts = JSON.parse(JSON.stringify(this.sessionConfig || {})); + makeGatherTaskConfig({textPrompt, urlPrompt, turnConfig} = {}) { + // we merge from top to bottom deeply so we wil have + // defaults from session config and then will override them via turn config + const opts = lodash.merge( + {}, + this.sessionConfig || {}, // this should not be undefined ever + turnConfig + ); + + /* const nextTurnKeys = Object.keys(this.turnConfig || {}); const newKeys = nextTurnKeys.filter((k) => !(k in opts)); const bothKeys = nextTurnKeys.filter((k) => k in opts); @@ -33,10 +47,12 @@ class SpeechConfig extends Emitter { for (const key of newKeys) opts[key] = this.turnConfig[key]; for (const key of bothKeys) opts[key] = {...opts[key], ...this.turnConfig[key]}; + */ + this.logger.debug({ opts, sessionConfig: this.sessionConfig, - turnConfig: this.turnConfig, + turnConfig }, 'Congigy SpeechConfig:_makeGatherTask current options'); /* input type: speech and/or dtmf entry */ @@ -62,6 +78,7 @@ class SpeechConfig extends Emitter { }; } + // todo what is the logic here if we put both? play over say or say over play? if (urlPrompt) { playConfig = { url: urlPrompt @@ -89,9 +106,6 @@ class SpeechConfig extends Emitter { const final = stripNulls(config); - /* turn config can now be emptied for next turn of conversation */ - this.turnConfig = {}; - const finalConfig = final; if (sayConfig) { finalConfig.say = sayConfig; diff --git a/package-lock.json b/package-lock.json index 119b4979..2b574c36 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,6 +25,7 @@ "drachtio-srf": "^4.4.55", "express": "^4.17.1", "ip": "^1.1.5", + "lodash": "^4.17.21", "moment": "^2.29.1", "parse-url": "^5.0.7", "pino": "^6.13.2", diff --git a/package.json b/package.json index 93593a4b..03087496 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,7 @@ "drachtio-srf": "^4.4.55", "express": "^4.17.1", "ip": "^1.1.5", + "lodash": "^4.17.21", "moment": "^2.29.1", "parse-url": "^5.0.7", "pino": "^6.13.2",