rasa: add support for eventhook which provides user and bot messages in realtime and supports redirecting to a new app

This commit is contained in:
Dave Horton
2021-09-02 10:27:59 -04:00
committed by Dave Horton
parent 19f3cbaa43
commit d15fdcf663
3 changed files with 72 additions and 8 deletions

View File

@@ -45,7 +45,7 @@ module.exports = function(srf, logger) {
// TODO: alert
return res.send(503, {headers: {'X-Reason': 'Account exists but is inactive'}});
}
logger.debug({accountInfo: req.locals.accountInfo}, `retrieved account info for ${account_sid}`);
logger.debug({accountInfo: req.locals?.accountInfo?.account}, `retrieved account info for ${account_sid}`);
next();
} catch (err) {
logger.info({err}, `Error retrieving account details for account ${account_sid}`);

View File

@@ -16,6 +16,10 @@ class Rasa extends Task {
get name() { return TaskName.Rasa; }
get hasReportedFinalAction() {
return this.reportedFinalAction || this.isReplacingApplication;
}
async exec(cs, ep) {
await super.exec(cs);
@@ -39,12 +43,15 @@ class Rasa extends Task {
async kill(cs) {
super.kill(cs);
if (this.ep.connected) {
this.logger.debug('Rasa:kill');
if (!this.hasReportedFinalAction) {
this.reportedFinalAction = true;
this.performAction({rasaResult: 'caller hungup'})
.catch((err) => this.logger.error({err}, 'rasa - error w/ action webook'));
.catch((err) => this.logger.info({err}, 'rasa - error w/ action webook'));
}
if (this.ep.connected) {
await this.ep.api('uuid_break', this.ep.uuid).catch((err) => this.logger.info(err, 'Error killing audio'));
}
this.removeAllListeners();
@@ -70,14 +77,31 @@ class Rasa extends Task {
say: sayOpts
};
}
this.logger.debug({opts}, 'constructing a nested gather object');
//this.logger.debug({opts}, 'constructing a nested gather object');
const gather = makeTask(this.logger, {gather: opts}, this);
return gather;
}
async _onTranscription(cs, ep, evt) {
this.logger.debug({evt}, `Rasa: got transcription for callSid ${cs.callSid}`);
//this.logger.debug({evt}, `Rasa: got transcription for callSid ${cs.callSid}`);
const utterance = evt.alternatives[0].transcript;
if (this.eventHook) {
this.performHook(cs, this.eventHook, {event: 'userMessage', message: utterance})
.then((redirected) => {
if (redirected) {
this.logger.info('Rasa_onTranscription: event handler for user message redirected us to new webhook');
this.reportedFinalAction = true;
this.performAction({rasaResult: 'redirect'}, false);
if (this.gatherTask) this.gatherTask.kill(cs);
}
return;
})
.catch(({err}) => {
this.logger.info({err}, 'Rasa_onTranscription: error sending event hook');
});
}
try {
const payload = {
sender: cs.callSid,
@@ -90,17 +114,38 @@ class Rasa extends Task {
response.reduce((prev, current) => `${prev} ${current.text}`, '') :
null;
if (botUtterance) {
this.logger.debug({botUtterance}, 'playing out bot utterance');
this.logger.debug({botUtterance}, 'Rasa:_onTranscription: got user utterance');
this.gatherTask = this._makeGatherTask(botUtterance);
this.gatherTask.exec(cs, ep, this)
.catch((err) => this.logger.info({err}, 'Rasa gather task returned error'));
if (this.eventHook) {
this.performHook(cs, this.eventHook, {event: 'botMessage', message: botUtterance})
.then((redirected) => {
if (redirected) {
this.logger.info('Rasa_onTranscription: event handler for bot message redirected us to new webhook');
this.reportedFinalAction = true;
this.performAction({rasaResult: 'redirect'}, false);
if (this.gatherTask) this.gatherTask.kill(cs);
}
return;
})
.catch(({err}) => {
this.logger.info({err}, 'Rasa_onTranscription: error sending event hook');
});
}
}
} catch (err) {
this.logger.error({err}, 'Error sending');
this.logger.error({err}, 'Rasa_onTranscription: Error sending user utterance to Rasa - ending task');
this.performAction({rasaResult: 'webhookError'});
this.reportedFinalAction = true;
this.notifyTaskDone();
}
}
_onTimeout(cs, ep, evt) {
this.logger.debug({evt}, 'Rasa: got timeout');
if (!this.hasReportedFinalAction) this.performAction({rasaResult: 'timeout'});
this.reportedFinalAction = true;
this.notifyTaskDone();
}

View File

@@ -99,6 +99,25 @@ class Task extends Emitter {
}
}
async performHook(cs, hook, results) {
const json = await cs.requestor.request(hook, results);
if (json && Array.isArray(json)) {
const makeTask = require('./make_task');
const tasks = normalizeJambones(this.logger, json).map((tdata) => makeTask(this.logger, tdata));
if (tasks && tasks.length > 0) {
this.redirect(cs, tasks);
return true;
}
}
return false;
}
redirect(cs, tasks) {
this.logger.info({tasks: tasks}, `${this.name} replacing application with ${tasks.length} tasks`);
this.isReplacingApplication = true;
cs.replaceApplication(tasks);
}
async transferCallToFeatureServer(cs, sipAddress, opts) {
const uuid = uuidv4();
const {addKey} = cs.srf.locals.dbHelpers;