mirror of
https://github.com/jambonz/jambonz-feature-server.git
synced 2025-12-20 16:50:39 +00:00
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:
@@ -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}`);
|
||||
|
||||
@@ -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');
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user