mirror of
https://github.com/jambonz/jambonz-feature-server.git
synced 2025-12-22 01:27:55 +00:00
first implementation of nextTurn and gather task cognigy
This commit is contained in:
@@ -176,8 +176,8 @@ class Cognigy extends Task {
|
|||||||
this.notifyTaskDone();
|
this.notifyTaskDone();
|
||||||
}
|
}
|
||||||
|
|
||||||
_makeGatherTask({textPrompt, urlPrompt} = {}) {
|
_makeGatherTask({textPrompt, urlPrompt, turnConfig} = {}) {
|
||||||
const config = this.config.makeGatherTaskConfig({textPrompt, urlPrompt});
|
const config = this.config.makeGatherTaskConfig({textPrompt, urlPrompt, turnConfig});
|
||||||
const {retry, ...rest} = config;
|
const {retry, ...rest} = config;
|
||||||
this.retry = retry;
|
this.retry = retry;
|
||||||
const gather = makeTask(this.logger, {gather: rest}, this);
|
const gather = makeTask(this.logger, {gather: rest}, this);
|
||||||
@@ -199,19 +199,22 @@ class Cognigy extends Task {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_makeReferTask(referTo) {
|
_makeReferTask(referTo) {
|
||||||
const refer = makeTask(this.logger, {'sip:refer': {
|
return makeTask(this.logger, {'sip:refer': {
|
||||||
referTo
|
referTo
|
||||||
}});
|
}}
|
||||||
return refer;
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
_makeHangupTask(reason) {
|
_makeHangupTask(reason) {
|
||||||
const hangup = makeTask(this.logger, {hangup: {
|
return makeTask(this.logger, {hangup: {
|
||||||
headers: {
|
headers: {
|
||||||
'X-Reason': reason
|
'X-Reason': reason
|
||||||
}
|
}
|
||||||
}});
|
}});
|
||||||
return hangup;
|
}
|
||||||
|
|
||||||
|
_makePlayTask(url, loop) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if we need to interrupt the currently-running say task(s), call this */
|
/* 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) {
|
async _onBotFinalPing(cs, ep) {
|
||||||
this.logger.info({prompts: this.prompts}, 'Cognigy:_onBotFinalPing');
|
this.logger.info({prompts: this.prompts}, 'Cognigy:_onBotFinalPing');
|
||||||
try {
|
try {
|
||||||
await this.taskQueue.lastPromise;
|
if (!this.gatherTaskExists) {
|
||||||
this.gatherTask = this._makeGatherTask();
|
await this.taskQueue.lastPromise;
|
||||||
this.gatherTask.exec(cs, ep, this)
|
this.gatherTask = this._makeGatherTask();
|
||||||
.catch((err) => this.logger.info({err}, 'Cognigy gather task returned error'));
|
this.gatherTask.exec(cs, ep, this)
|
||||||
this.prompts = [];
|
.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) {
|
} catch (err) {
|
||||||
this.logger.error({err}, 'Could not execute bot final ping!');
|
this.logger.error({err}, 'Could not execute bot final ping!');
|
||||||
}
|
}
|
||||||
@@ -264,8 +272,10 @@ class Cognigy extends Task {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const text = parseBotText(evt);
|
const text = parseBotText(evt);
|
||||||
if (evt.data) this.config.update(evt.data);
|
if (evt.data && evt.data.config && evt.data.config.session) this.config.update(evt.data.config.session);
|
||||||
if (text) {
|
|
||||||
|
// 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._enqueueTask(async() => {
|
||||||
this.logger.info({text}, 'received text');
|
this.logger.info({text}, 'received text');
|
||||||
const sayTask = this._makeSayTask(text);
|
const sayTask = this._makeSayTask(text);
|
||||||
@@ -293,6 +303,22 @@ class Cognigy extends Task {
|
|||||||
cs.replaceApplication([this._makeReferTask(evt.data.referTo)]);
|
cs.replaceApplication([this._makeReferTask(evt.data.referTo)]);
|
||||||
});
|
});
|
||||||
return;
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
const Emitter = require('events');
|
const Emitter = require('events');
|
||||||
|
const lodash = require('lodash');
|
||||||
const hasKeys = (obj) => typeof obj === 'object' && Object.keys(obj) > 0;
|
const hasKeys = (obj) => typeof obj === 'object' && Object.keys(obj) > 0;
|
||||||
|
|
||||||
const stripNulls = (obj) => {
|
const stripNulls = (obj) => {
|
||||||
@@ -13,19 +13,33 @@ class SpeechConfig extends Emitter {
|
|||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
this.ep = ep;
|
this.ep = ep;
|
||||||
this.sessionConfig = opts.session || {};
|
this.sessionConfig = opts.session || {};
|
||||||
this.turnConfig = opts.nextTurn || {};
|
|
||||||
this.update(opts);
|
this.update(opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
update(opts = {}) {
|
update(opts = {}) {
|
||||||
const {session, nextTurn = {}} = opts;
|
// TODO validation of session params?
|
||||||
if (session) this.sessionConfig = {...this.sessionConfig, ...session};
|
const {session } = opts;
|
||||||
this.turnConfig = nextTurn;
|
if (session) {
|
||||||
this.logger.debug({opts, sessionLevel: this.sessionConfig, turnLevel: this.turnConfig}, 'SpeechConfig updated');
|
this.sessionConfig = lodash.merge(
|
||||||
|
{},
|
||||||
|
this.sessionConfig,
|
||||||
|
session
|
||||||
|
);
|
||||||
|
}
|
||||||
|
//this.turnConfig = nextTurn;
|
||||||
|
this.logger.debug({opts, sessionLevel: this.sessionConfig}, 'SpeechConfig updated');
|
||||||
}
|
}
|
||||||
|
|
||||||
makeGatherTaskConfig({textPrompt, urlPrompt} = {}) {
|
makeGatherTaskConfig({textPrompt, urlPrompt, turnConfig} = {}) {
|
||||||
const opts = JSON.parse(JSON.stringify(this.sessionConfig || {}));
|
// 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 nextTurnKeys = Object.keys(this.turnConfig || {});
|
||||||
const newKeys = nextTurnKeys.filter((k) => !(k in opts));
|
const newKeys = nextTurnKeys.filter((k) => !(k in opts));
|
||||||
const bothKeys = 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 newKeys) opts[key] = this.turnConfig[key];
|
||||||
for (const key of bothKeys) opts[key] = {...opts[key], ...this.turnConfig[key]};
|
for (const key of bothKeys) opts[key] = {...opts[key], ...this.turnConfig[key]};
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
this.logger.debug({
|
this.logger.debug({
|
||||||
opts,
|
opts,
|
||||||
sessionConfig: this.sessionConfig,
|
sessionConfig: this.sessionConfig,
|
||||||
turnConfig: this.turnConfig,
|
turnConfig
|
||||||
}, 'Congigy SpeechConfig:_makeGatherTask current options');
|
}, 'Congigy SpeechConfig:_makeGatherTask current options');
|
||||||
|
|
||||||
/* input type: speech and/or dtmf entry */
|
/* 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) {
|
if (urlPrompt) {
|
||||||
playConfig = {
|
playConfig = {
|
||||||
url: urlPrompt
|
url: urlPrompt
|
||||||
@@ -89,9 +106,6 @@ class SpeechConfig extends Emitter {
|
|||||||
|
|
||||||
const final = stripNulls(config);
|
const final = stripNulls(config);
|
||||||
|
|
||||||
/* turn config can now be emptied for next turn of conversation */
|
|
||||||
this.turnConfig = {};
|
|
||||||
|
|
||||||
const finalConfig = final;
|
const finalConfig = final;
|
||||||
if (sayConfig) {
|
if (sayConfig) {
|
||||||
finalConfig.say = sayConfig;
|
finalConfig.say = sayConfig;
|
||||||
|
|||||||
1
package-lock.json
generated
1
package-lock.json
generated
@@ -25,6 +25,7 @@
|
|||||||
"drachtio-srf": "^4.4.55",
|
"drachtio-srf": "^4.4.55",
|
||||||
"express": "^4.17.1",
|
"express": "^4.17.1",
|
||||||
"ip": "^1.1.5",
|
"ip": "^1.1.5",
|
||||||
|
"lodash": "^4.17.21",
|
||||||
"moment": "^2.29.1",
|
"moment": "^2.29.1",
|
||||||
"parse-url": "^5.0.7",
|
"parse-url": "^5.0.7",
|
||||||
"pino": "^6.13.2",
|
"pino": "^6.13.2",
|
||||||
|
|||||||
@@ -43,6 +43,7 @@
|
|||||||
"drachtio-srf": "^4.4.55",
|
"drachtio-srf": "^4.4.55",
|
||||||
"express": "^4.17.1",
|
"express": "^4.17.1",
|
||||||
"ip": "^1.1.5",
|
"ip": "^1.1.5",
|
||||||
|
"lodash": "^4.17.21",
|
||||||
"moment": "^2.29.1",
|
"moment": "^2.29.1",
|
||||||
"parse-url": "^5.0.7",
|
"parse-url": "^5.0.7",
|
||||||
"pino": "^6.13.2",
|
"pino": "^6.13.2",
|
||||||
|
|||||||
Reference in New Issue
Block a user