diff --git a/.npmrc b/.npmrc new file mode 100644 index 00000000..d263b35b --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +registry=https://registry.yarnpkg.com \ No newline at end of file diff --git a/lib/tasks/cognigy/index.js b/lib/tasks/cognigy/index.js index ef5e6cb0..b016a6a3 100644 --- a/lib/tasks/cognigy/index.js +++ b/lib/tasks/cognigy/index.js @@ -3,6 +3,7 @@ const {TaskName, TaskPreconditions} = require('../../utils/constants'); const makeTask = require('../make_task'); const { SocketClient } = require('@cognigy/socket-client'); const SpeechConfig = require('./speech-config'); +const queue = require('queue'); const parseGallery = (obj = {}) => { const {_default} = obj; @@ -48,6 +49,9 @@ class Cognigy extends Task { this.prompts = []; this.retry = {}; this.timeoutCount = 0; + // create a task queue so we can execute our taskss subsequently + // also executing tasks whenever they come in + this.taskQueue = queue({concurrency: 1, autostart: true}); } get name() { return TaskName.Cognigy; } @@ -56,6 +60,27 @@ class Cognigy extends Task { return this.reportedFinalAction || this.isReplacingApplication; } + async _enqueueTask(task) { + let resolver; + let rejector; + const taskPromise = new Promise(async(resolve, reject) => { + resolver = resolve; + rejector = reject; + }); + this.taskQueue.push(async(cb) => { + try { + const result = await task.bind(this)(); + resolver(result); + cb(result); + } catch (err) { + rejector(err); + cb(err); + } + }); + this.taskQueue.lastPromise = taskPromise; + return taskPromise; + } + async exec(cs, ep) { await super.exec(cs); @@ -119,12 +144,16 @@ class Cognigy extends Task { super.kill(cs); this.logger.debug('Cognigy:kill'); + this.removeAllListeners(); this.transcribeTask && this.transcribeTask.kill(); this.client.removeAllListeners(); if (this.client && this.client.connected) this.client.disconnect(); + // end the task queue AFTER we have removed all listeneres since now we cannot get new stuff inside the queue + this.taskQueue.end(); + if (!this.hasReportedFinalAction) { this.reportedFinalAction = true; this.performAction({cognigyResult: 'caller hungup'}) @@ -176,6 +205,17 @@ class Cognigy extends Task { return refer; } + /* if we need to interrupt the currently-running say task(s), call this */ + _killSayTasks(ep) { + // this will also remove all other upcoming tasks after the say task + // maybe we need a flow to kill only one say tasks and keep others executitng need to discuss this further + // this.taskQueue.end(); + if (ep && ep.connected) { + ep.api('uuid_break', this.ep.uuid) + .catch((err) => this.logger.info({err}, 'Cognigy:_killSayTasks - error killing audio for current say task')); + } + } + async _onBotError(cs, ep, evt) { this.logger.info({evt}, 'Cognigy:_onBotError'); this.performAction({cognigyResult: 'botError', message: evt.message }); @@ -184,16 +224,10 @@ class Cognigy extends Task { } async _onBotFinalPing(cs, ep) { - this.logger.info({}, 'TEST FROM ALEX'); this.logger.info({prompts: this.prompts}, 'Cognigy:_onBotFinalPing'); - if (this.prompts.length) { - const text = this.prompts.join('.'); - if (text && !this.killed) { - this.gatherTask = this._makeGatherTask({textPrompt: text}); - this.gatherTask.exec(cs, ep, this) - .catch((err) => this.logger.info({err}, 'Cognigy gather task returned error')); - } - } + this.gatherTask = this._makeGatherTask({textPrompt: ""}); + this.gatherTask.exec(cs, ep, this) + .catch((err) => this.logger.info({err}, 'Cognigy gather task returned error')); this.prompts = []; } @@ -215,22 +249,36 @@ class Cognigy extends Task { }); } + const text = parseBotText(evt); + if (evt.data) this.config.update(evt.data); + if (text) { + await this._enqueueTask(async() => { + await this._makeSayTask(text); + }); + } + + if (evt && evt.data && evt.data.type) { try { switch (evt.data.type) { case 'hangup': - await this._makeHangupTask(evt.data.reason); - this.performAction({cognigyResult: 'hangup Succeeded'}); - this.reportedFinalAction = true; - this.notifyTaskDone(); - this.kill(cs); + await this._enqueueTask(async() => { + await this._makeHangupTask(evt.data.reason); + this.performAction({cognigyResult: 'hangup Succeeded'}); + this.reportedFinalAction = true; + this.notifyTaskDone(); + this.kill(cs); + }); + return; case 'refer': - await this._makeReferTask(evt.data.number); - this.performAction({cognigyResult: 'refer succeeded'}); - this.reportedFinalAction = true; - this.notifyTaskDone(); - this.kill(cs); + await this._enqueueTask(async() => { + await this._makeReferTask(evt.data.number); + this.performAction({cognigyResult: 'refer succeeded'}); + this.reportedFinalAction = true; + this.notifyTaskDone(); + this.kill(cs); + }); return; default: break; @@ -241,12 +289,7 @@ class Cognigy extends Task { this.reportedFinalAction = true; this.notifyTaskDone(); } - - } - const text = parseBotText(evt); - if (evt.data) this.config.update(evt.data); - if (text) this.prompts.push(text); } async _onTranscription(cs, ep, evt) { diff --git a/package-lock.json b/package-lock.json index 20433a8f..119b4979 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,6 +28,7 @@ "moment": "^2.29.1", "parse-url": "^5.0.7", "pino": "^6.13.2", + "queue": "^6.0.2", "to-snake-case": "^1.0.0", "uuid": "^8.3.2", "verify-aws-sns-signature": "^0.0.6", @@ -4192,6 +4193,15 @@ "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" }, + "node_modules/queue": { + "version": "6.0.2", + "resolved": "https://cognigy.pkgs.visualstudio.com/_packaging/cognigy-feed/npm/registry/queue/-/queue-6.0.2.tgz", + "integrity": "sha1-uRUlKD4jFcdVPS76GNg+dkMv7WU=", + "license": "MIT", + "dependencies": { + "inherits": "~2.0.3" + } + }, "node_modules/quick-format-unescaped": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.3.tgz", @@ -8743,6 +8753,14 @@ "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" }, + "queue": { + "version": "6.0.2", + "resolved": "https://cognigy.pkgs.visualstudio.com/_packaging/cognigy-feed/npm/registry/queue/-/queue-6.0.2.tgz", + "integrity": "sha1-uRUlKD4jFcdVPS76GNg+dkMv7WU=", + "requires": { + "inherits": "~2.0.3" + } + }, "quick-format-unescaped": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.3.tgz", diff --git a/package.json b/package.json index aabb469a..93593a4b 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "moment": "^2.29.1", "parse-url": "^5.0.7", "pino": "^6.13.2", + "queue": "^6.0.2", "to-snake-case": "^1.0.0", "uuid": "^8.3.2", "verify-aws-sns-signature": "^0.0.6",