diff --git a/lib/tasks/dialogflow/index.js b/lib/tasks/dialogflow/index.js index 723b8df8..3f644bdf 100644 --- a/lib/tasks/dialogflow/index.js +++ b/lib/tasks/dialogflow/index.js @@ -87,6 +87,8 @@ class Dialogflow extends Task { get isCX() { return this.model === 'cx'; } + get isES() { return !this.isCX; } + async exec(cs, {ep}) { await super.exec(cs); @@ -439,9 +441,10 @@ class Dialogflow extends Task { // kill filler audio await ep.api('uuid_break', ep.uuid); - // start a new intent, (we want to continue to listen during the audio playback) + // if ES start a new intent (for CX we do not set single_utterance on), + // (we want to continue to listen during the audio playback) // _unless_ we are transferring or ending the session - if (/*this.greetingPlayed &&*/ !this.hangupAfterPlayDone) { + if (this.isES && !this.hangupAfterPlayDone) { ep.api(this.cmd, `${ep.uuid} ${this.project} ${this.lang}`); } @@ -467,12 +470,7 @@ class Dialogflow extends Task { return; } } - /* - if (!this.inbound && !this.greetingPlayed) { - this.logger.info('finished greeting on outbound call, starting new intent'); - this.ep.api(this.cmd, `${ep.uuid} ${this.project} ${this.lang}`); - } - */ + this.greetingPlayed = true; if (this.hangupAfterPlayDone) { diff --git a/lib/tasks/dialogflow/intent.js b/lib/tasks/dialogflow/intent.js index d09936bd..871b80f9 100644 --- a/lib/tasks/dialogflow/intent.js +++ b/lib/tasks/dialogflow/intent.js @@ -4,19 +4,31 @@ class Intent { this.evt = evt; this.logger.debug({evt}, 'intent'); - this.dtmfRequest = checkIntentForDtmfEntry(logger, evt); + this.qr = this.isCX ? evt.detect_intent_response.query_result : evt.query_result; + this.dtmfRequest = this._checkIntentForDtmfEntry(logger, evt); + } + + get response_id() { + return this.isCX ? this.evt.detect_intent_response.response_id : this.evt.response_id; } get isEmpty() { - return this.evt.response_id.length === 0; + return !(this.response_id?.length > 0); } get fulfillmentText() { - return this.evt.query_result.fulfillment_text; + return this.qr.fulfillment_text; } get saysEndInteraction() { - return this.evt.query_result.intent.end_interaction ; + if (this.isCX) { + const end_interaction = this.qr.response_messages + .find((m) => typeof m === 'object' && 'end_interaction' in m)?.end_interaction; + + //TODO: need to do more checking on the actual contents + return end_interaction && Object.keys(end_interaction).length > 0; + } + else return this.qr.intent.end_interaction ; } get saysCollectDtmf() { @@ -28,7 +40,22 @@ class Intent { } get name() { - if (!this.isEmpty) return this.evt.query_result.intent.display_name; + if (!this.isEmpty) { + if (this.isCX) { + return this.qr.match?.intent?.display_name; + } + else { + return this.qr.intent.display_name; + } + } + } + + get isCX() { + return typeof this.evt.detect_intent_response === 'object'; + } + + get isES() { + return !this.isCX; } toJSON() { @@ -38,11 +65,7 @@ class Intent { }; } -} - -module.exports = Intent; - -/** + /** * Parse a returned intent for DTMF entry information * i.e. * allow-dtmf-x-y-z @@ -55,35 +78,39 @@ module.exports = Intent; * allow-dtmf-1-4-# : collect 1-4 digits, terminating if '#' is entered * @param {*} intent - dialogflow intent */ -const checkIntentForDtmfEntry = (logger, intent) => { - const qr = intent.query_result; - if (!qr || !qr.fulfillment_messages || !qr.output_contexts) { - logger.info({f: qr.fulfillment_messages, o: qr.output_contexts}, 'no dtmfs'); - return; - } + _checkIntentForDtmfEntry(logger, intent) { + const qr = this.isCX ? intent.detect_intent_response.query_result : intent.query_result; - // check for custom payloads with a gather verb - const custom = qr.fulfillment_messages.find((f) => f.payload && f.payload.verb === 'gather'); - if (custom && custom.payload && custom.payload.verb === 'gather') { - logger.info({custom}, 'found dtmf custom payload'); - return { - max: custom.payload.numDigits, - term: custom.payload.finishOnKey, - template: custom.payload.responseTemplate - }; - } + if (!qr || !qr.fulfillment_messages || !qr.output_contexts) { + logger.info({f: qr.fulfillment_messages, o: qr.output_contexts}, 'no dtmfs'); + return; + } - // check for an output context with a specific naming convention - const context = qr.output_contexts.find((oc) => oc.name.includes('/contexts/allow-dtmf-')); - if (context) { - const arr = /allow-dtmf-(\d+)(?:-(\d+))?(?:-(.*))?/.exec(context.name); - if (arr) { - logger.info({custom}, 'found dtmf output context'); + // check for custom payloads with a gather verb + const custom = qr.fulfillment_messages.find((f) => f.payload && f.payload.verb === 'gather'); + if (custom && custom.payload && custom.payload.verb === 'gather') { + logger.info({custom}, 'found dtmf custom payload'); return { - min: parseInt(arr[1]), - max: arr.length > 2 ? parseInt(arr[2]) : null, - term: arr.length > 3 ? arr[3] : null + max: custom.payload.numDigits, + term: custom.payload.finishOnKey, + template: custom.payload.responseTemplate }; } + + // check for an output context with a specific naming convention + const context = qr.output_contexts.find((oc) => oc.name.includes('/contexts/allow-dtmf-')); + if (context) { + const arr = /allow-dtmf-(\d+)(?:-(\d+))?(?:-(.*))?/.exec(context.name); + if (arr) { + logger.info({custom}, 'found dtmf output context'); + return { + min: parseInt(arr[1]), + max: arr.length > 2 ? parseInt(arr[2]) : null, + term: arr.length > 3 ? arr[3] : null + }; + } + } } -}; +} + +module.exports = Intent;