|
|
|
|
@@ -0,0 +1,431 @@
|
|
|
|
|
const utterance = req.body.utterance;
|
|
|
|
|
const sessionId = req.body.sessionId;
|
|
|
|
|
console.log({
|
|
|
|
|
loop: "1.6",
|
|
|
|
|
utterance,
|
|
|
|
|
sessionId
|
|
|
|
|
});
|
|
|
|
|
const getNested = (obj, ...args) => {
|
|
|
|
|
return args.reduce((obj, level) => {
|
|
|
|
|
return obj && obj[level];
|
|
|
|
|
}, obj);
|
|
|
|
|
};
|
|
|
|
|
if (req.body.body && req.body.query) {
|
|
|
|
|
const tmpBody = JSON.parse(JSON.stringify(req.body.body));
|
|
|
|
|
const tmpQuery = JSON.parse(JSON.stringify(req.body.query));
|
|
|
|
|
req.query = tmpQuery;
|
|
|
|
|
req.body = tmpBody;
|
|
|
|
|
}
|
|
|
|
|
if (req.body.sessionJSON) {
|
|
|
|
|
try {
|
|
|
|
|
req.body.sessionJSON = JSON.parse(req.body.sessionJSON);
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.log(e.message);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
const verbose = voiceSettings_6647ad7b84df93835bbb4346.verbose || false;
|
|
|
|
|
const useDomain = req.body.useDomain;
|
|
|
|
|
const route = req.params && req.params[0] && req.params[0].split('/').slice(-1)[0];
|
|
|
|
|
const requestId = uuidv4();
|
|
|
|
|
const safetyNet = voiceSettings_6647ad7b84df93835bbb4346.responses.safetynet;
|
|
|
|
|
const waitHoldTimeout = voiceSettings_6647ad7b84df93835bbb4346.waitHoldTimeout;
|
|
|
|
|
let promptText = voiceSettings_6647ad7b84df93835bbb4346.responses.welcome;
|
|
|
|
|
let disconnect;
|
|
|
|
|
let waveform;
|
|
|
|
|
let gcsUri;
|
|
|
|
|
let fileName;
|
|
|
|
|
let recognizedData;
|
|
|
|
|
if (req.body.waveform) {
|
|
|
|
|
try {
|
|
|
|
|
waveform = url.parse(req.body.waveform, true).query.googleUri;
|
|
|
|
|
fileName = url.parse(waveform, true);
|
|
|
|
|
if (fileName && fileName.pathName) gcsUri = `gs:/${fileName.pathname}`;
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.log(e.message);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
const isCA = () => {
|
|
|
|
|
return voiceSettings_6647ad7b84df93835bbb4346?.integrations?.CAInterface?.enabled || false;
|
|
|
|
|
};
|
|
|
|
|
const getCA = () => {
|
|
|
|
|
if (isCA()) {
|
|
|
|
|
let ca = "CAInterface";
|
|
|
|
|
if (voiceSettings_6647ad7b84df93835bbb4346.integrations.CAInterface.suffix) {
|
|
|
|
|
ca += voiceSettings_6647ad7b84df93835bbb4346.integrations.CAInterface.suffix;
|
|
|
|
|
}
|
|
|
|
|
ca += "()";
|
|
|
|
|
return eval(ca);
|
|
|
|
|
}
|
|
|
|
|
return undefined;
|
|
|
|
|
};
|
|
|
|
|
const getInteractionId = async (ani, dnis, xSpVerintId) => {
|
|
|
|
|
const suffix = voiceSettings_6647ad7b84df93835bbb4346.suffix && `_${voiceSettings_6647ad7b84df93835bbb4346.suffix}` || "";
|
|
|
|
|
const callback = `${voiceSettings_6647ad7b84df93835bbb4346.ivr.hostname}/ProxyScript/run/${req.params.workspaceId}/${req.params.branch}/vxml_transfer${suffix}?sessionId=${sessionId}`;
|
|
|
|
|
let tisId;
|
|
|
|
|
const CA = getCA();
|
|
|
|
|
if (CA) {
|
|
|
|
|
try {
|
|
|
|
|
const OIDC = await CA.getOIDC();
|
|
|
|
|
if (OIDC.access_token) {
|
|
|
|
|
tisId = await CA.createTelephonyInteraction(OIDC, ani, dnis, xSpVerintId, callback);
|
|
|
|
|
} else {
|
|
|
|
|
console.log("getInteractionId failed: Bad OIDC credentials");
|
|
|
|
|
console.log(OIDC);
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.log(`getInteractionId failed. error: ${error.message}`);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return tisId;
|
|
|
|
|
};
|
|
|
|
|
const blockWaitLiveOperator = async (smStr, sessionMap, CA) => {
|
|
|
|
|
const start = Date.now();
|
|
|
|
|
let rd;
|
|
|
|
|
const loopWait = 100;
|
|
|
|
|
const total = voiceSettings_6647ad7b84df93835bbb4346.waitHoldQueueStatus * 1000 / loopWait;
|
|
|
|
|
for (let i = 0; i < total; i++) {
|
|
|
|
|
const sessionMap = await redis.hGetAll(smStr);
|
|
|
|
|
if (sessionMap.transferCall) {
|
|
|
|
|
console.log("Loop: transfer call");
|
|
|
|
|
rd = {
|
|
|
|
|
answers: [voiceSettings_6647ad7b84df93835bbb4346.responses.transferCall],
|
|
|
|
|
endCall: true
|
|
|
|
|
};
|
|
|
|
|
return rd;
|
|
|
|
|
}
|
|
|
|
|
await new Promise(r => setTimeout(r, loopWait));
|
|
|
|
|
}
|
|
|
|
|
if (CA) {
|
|
|
|
|
try {
|
|
|
|
|
const OIDC = await CA.getOIDC();
|
|
|
|
|
// fallthrough, provide a queue status update
|
|
|
|
|
const predictions = await CA.getWaitTime(OIDC, sessionMap.interactionId);
|
|
|
|
|
rd = await run_app_event(sessionMap, smStr, "VXML Queue Status Event", "vxmlqueuestatus", voiceSettings_6647ad7b84df93835bbb4346.responses.pleaseContinueToHold, {
|
|
|
|
|
predictions
|
|
|
|
|
});
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.log("/predictions failed" + error.message);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!rd) {
|
|
|
|
|
rd = {
|
|
|
|
|
answers: [voiceSettings_6647ad7b84df93835bbb4346.responses.pleaseContinueToHold]
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
console.log({
|
|
|
|
|
blockWaitElapsed: Date.now() - start
|
|
|
|
|
});
|
|
|
|
|
return rd;
|
|
|
|
|
};
|
|
|
|
|
const sequenceApiCalls = async (smStr, interactionId, apiCalls) => {
|
|
|
|
|
const CA = getCA();
|
|
|
|
|
if (CA) {
|
|
|
|
|
await redis.hSet(smStr, {
|
|
|
|
|
waitForApi: "true"
|
|
|
|
|
});
|
|
|
|
|
const OIDC = await CA.getOIDC();
|
|
|
|
|
for (let api of apiCalls) {
|
|
|
|
|
try {
|
|
|
|
|
if (api.api == "patchCallInfo") {
|
|
|
|
|
await CA.patchCallInfo(OIDC, interactionId, api.params);
|
|
|
|
|
} else if (api.api = "connectWithLiveOperator") {
|
|
|
|
|
const isVirtualHold = api.params.isVirtualHold;
|
|
|
|
|
const callReason = api.params.callReason;
|
|
|
|
|
if (isVirtualHold || callReason) {
|
|
|
|
|
await CA.patchCallInfo(OIDC, interactionId, {
|
|
|
|
|
isVirtualHold,
|
|
|
|
|
callReason
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
await CA.connectWithLiveOperator(OIDC, interactionId);
|
|
|
|
|
redis.hSet(smStr, {
|
|
|
|
|
waitForLiveOperator: "true",
|
|
|
|
|
lastQueueStatus: JSON.stringify(Date.now())
|
|
|
|
|
});
|
|
|
|
|
redis.hDel(smStr, "pendingAPIs");
|
|
|
|
|
} else {
|
|
|
|
|
console.log({
|
|
|
|
|
badapi: api
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
} catch (err) {
|
|
|
|
|
console.log(`Error: ${api.api} failed. ${err.message}`);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
redis.hDel(smStr, "waitForApi");
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
const run_app_event = async (sessionMap, smStr, intent, input, defaultAnswer, metadata = {}) => {
|
|
|
|
|
const configuration = {
|
|
|
|
|
directIntentHit: intent
|
|
|
|
|
};
|
|
|
|
|
return await run_model_and_report(sessionMap, smStr, input, defaultAnswer, configuration, metadata);
|
|
|
|
|
};
|
|
|
|
|
const run_model_and_report = async (sessionMap, smStr, input, defaultAnswer, configuration, metadata = {}) => {
|
|
|
|
|
let privateData = voiceSettings_6647ad7b84df93835bbb4346.ivr.privateData || false;
|
|
|
|
|
let interactionId = sessionMap.interactionId;
|
|
|
|
|
let {
|
|
|
|
|
data: recognizedData
|
|
|
|
|
} = await axios.post(`${voiceSettings_6647ad7b84df93835bbb4346.nlu.apiBaseURL}/Model/run/${req.params.workspaceId}/${req.params.branch}/${voiceSettings_6647ad7b84df93835bbb4346.nlu.modelName}`, {
|
|
|
|
|
input,
|
|
|
|
|
configuration,
|
|
|
|
|
conversationId: sessionMap.conversationId,
|
|
|
|
|
settings: voiceSettings_6647ad7b84df93835bbb4346.nlu.settings,
|
|
|
|
|
channel: "voice",
|
|
|
|
|
// for old multi-channel widgets
|
|
|
|
|
metadata: {
|
|
|
|
|
channel: 'voice',
|
|
|
|
|
gcsUriAudio: waveform,
|
|
|
|
|
ani: sessionMap.ani,
|
|
|
|
|
dnis: sessionMap.dnis,
|
|
|
|
|
callid: sessionMap.callid,
|
|
|
|
|
xSpVerintId: sessionMap.xSpVerintId,
|
|
|
|
|
interactionId,
|
|
|
|
|
sessionId,
|
|
|
|
|
syntheticAudio: true,
|
|
|
|
|
utteranceFileName: `${fileName?.pathname?.replace('/asr-archive/', '') || ""}`,
|
|
|
|
|
...metadata
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
privateData = recognizedData.ivrSettings?.privateData || privateData;
|
|
|
|
|
if (!privateData && recognizedData.conversationId && sessionMap.conversationId === undefined) {
|
|
|
|
|
db.analytics.addConversation({
|
|
|
|
|
id: recognizedData.conversationId
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
if (recognizedData.conversationId) {
|
|
|
|
|
await redis.hSet(smStr, {
|
|
|
|
|
conversationId: recognizedData.conversationId
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
if (defaultAnswer && recognizedData.answers.length === 0) {
|
|
|
|
|
recognizedData.answers = [defaultAnswer];
|
|
|
|
|
} else if (recognizedData.classificationResults.length === 0 && recognizedData.answers.length === 0) {
|
|
|
|
|
recognizedData.answers = [voiceSettings_6647ad7b84df93835bbb4346.responses.unrecognized];
|
|
|
|
|
} else if (recognizedData.answers.length === 0) {
|
|
|
|
|
recognizedData.answers = [voiceSettings_6647ad7b84df93835bbb4346.responses.unanswered];
|
|
|
|
|
}
|
|
|
|
|
if (!recognizedData.ivrSettings) {
|
|
|
|
|
recognizedData.ivrSettings = {};
|
|
|
|
|
}
|
|
|
|
|
let timeout;
|
|
|
|
|
// look for the wait-hold event from the flow
|
|
|
|
|
|
|
|
|
|
if (recognizedData.vxmlCAApis) {
|
|
|
|
|
timeout = waitHoldTimeout;
|
|
|
|
|
// async
|
|
|
|
|
if (recognizedData.vxmlCAApis.find(api => api.api == "connectWithLiveOperator")) {
|
|
|
|
|
// defer api until after the current prompt finishes. next loop
|
|
|
|
|
console.log("Deferring VC Apis");
|
|
|
|
|
await redis.hSet(smStr, {
|
|
|
|
|
waitForLiveOperator: "true",
|
|
|
|
|
pendingAPIs: JSON.stringify(recognizedData.vxmlCAApis)
|
|
|
|
|
});
|
|
|
|
|
sessionMap.waitForLiveOperator = true;
|
|
|
|
|
} else {
|
|
|
|
|
sequenceApiCalls(smStr, interactionId, recognizedData.vxmlCAApis);
|
|
|
|
|
}
|
|
|
|
|
} else if (sessionMap.waitForLiveOperator) {
|
|
|
|
|
timeout = waitHoldTimeout;
|
|
|
|
|
}
|
|
|
|
|
if (timeout && !recognizedData.ivrSettings.timeout) {
|
|
|
|
|
recognizedData.ivrSettings.timeout = timeout;
|
|
|
|
|
}
|
|
|
|
|
// add dialogName hueristically
|
|
|
|
|
if (!recognizedData.ivrSettings.dialogName) {
|
|
|
|
|
let dialogName = "";
|
|
|
|
|
if (recognizedData.classificationResults.length) {
|
|
|
|
|
dialogName = recognizedData.classificationResults[0].label.split(/\s+/).join('_');
|
|
|
|
|
}
|
|
|
|
|
if (recognizedData.answers.length) {
|
|
|
|
|
let words = recognizedData.answers[0].split(/\s+/).map(word => {
|
|
|
|
|
return word.replace(/[^a-z0-9]/gi, '');
|
|
|
|
|
}).filter(word => word.length > 0);
|
|
|
|
|
for (let i = 0; i < Math.min(6, words.length); i++) {
|
|
|
|
|
dialogName += "_" + words[i];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (dialogName.length) {
|
|
|
|
|
recognizedData.ivrSettings.dialogName = dialogName;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!privateData && input !== "vxmlqueuestatus") {
|
|
|
|
|
db.analytics.addTransaction(recognizedData);
|
|
|
|
|
}
|
|
|
|
|
return recognizedData;
|
|
|
|
|
};
|
|
|
|
|
// DEMO DISTRIBUTOR CODE
|
|
|
|
|
console.log("req.body.interpretation");
|
|
|
|
|
console.log(req.body.interpretation);
|
|
|
|
|
const selectedWorkspaceOption = req.body.interpretation;
|
|
|
|
|
console.log("Selected Option:");
|
|
|
|
|
console.log(selectedWorkspaceOption);
|
|
|
|
|
|
|
|
|
|
let vxmlResponse;
|
|
|
|
|
|
|
|
|
|
const generateVXML = async () => {
|
|
|
|
|
try {
|
|
|
|
|
// Common properties used in all cases, unless specified in the case block
|
|
|
|
|
const commonProperties = {
|
|
|
|
|
hostname: "https://router.ivastudio.verint.live",
|
|
|
|
|
branch: "current",
|
|
|
|
|
requestId,
|
|
|
|
|
promptText,
|
|
|
|
|
disconnect,
|
|
|
|
|
recognizedData,
|
|
|
|
|
...voiceSettings_6647ad7b84df93835bbb4346.ivr,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
switch (selectedWorkspaceOption) {
|
|
|
|
|
case "1":
|
|
|
|
|
// Peter's Workspace
|
|
|
|
|
vxmlResponse = vxmlgen_gvf_6647ad7b84df93835bbb4346().frontDoor({
|
|
|
|
|
workspaceId: "67bca862210071627d32ef12",
|
|
|
|
|
suffix: "6647ad7b84df93835bbb4346",
|
|
|
|
|
...commonProperties,
|
|
|
|
|
});
|
|
|
|
|
break;
|
|
|
|
|
case "2":
|
|
|
|
|
// David's Workspace
|
|
|
|
|
vxmlResponse = vxmlgen_gvf_6647ad7b84df93835bbb4346().frontDoor({
|
|
|
|
|
workspaceId: "67c9ddd765e40fd3d60ef441",
|
|
|
|
|
suffix: "6647ad7b84df93835bbb4346",
|
|
|
|
|
...commonProperties,
|
|
|
|
|
});
|
|
|
|
|
break;
|
|
|
|
|
case "3":
|
|
|
|
|
// Ramzi's Workspace
|
|
|
|
|
vxmlResponse = vxmlgen_gvf_6647ad7b84df93835bbb4346().frontDoor({
|
|
|
|
|
workspaceId: "67c758bf8e90ca81122106a5",
|
|
|
|
|
suffix: "6647ad7b84df93835bbb4346",
|
|
|
|
|
...commonProperties,
|
|
|
|
|
});
|
|
|
|
|
break;
|
|
|
|
|
case "4":
|
|
|
|
|
// Amber's Workspace
|
|
|
|
|
vxmlResponse = vxmlgen_gvf_6647ad7b84df93835bbb4346().frontDoor({
|
|
|
|
|
workspaceId: "67c9dde765e40fd3d60ef446",
|
|
|
|
|
suffix: "6647ad7b84df93835bbb4346",
|
|
|
|
|
...commonProperties,
|
|
|
|
|
});
|
|
|
|
|
break;
|
|
|
|
|
case "5":
|
|
|
|
|
// Ring Central Workspace
|
|
|
|
|
vxmlResponse = vxmlgen_gvf_6647ad7b84df93835bbb4346().frontDoor({
|
|
|
|
|
workspaceId: "68098e35ad4260eaf807cff2",
|
|
|
|
|
suffix: "6647ad7b84df93835bbb4346",
|
|
|
|
|
...commonProperties,
|
|
|
|
|
});
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
vxmlResponse = vxmlgen_gvf_6647ad7b84df93835bbb4346().loop({
|
|
|
|
|
hostname: voiceSettings_6647ad7b84df93835bbb4346.ivr.hostname,
|
|
|
|
|
workspaceId: req.params.workspaceId,
|
|
|
|
|
suffix: voiceSettings_6647ad7b84df93835bbb4346.suffix,
|
|
|
|
|
branch: req.params.branch,
|
|
|
|
|
sessionId,
|
|
|
|
|
...commonProperties,
|
|
|
|
|
});
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// END OF DEMO DISTRIBUTOR CODE
|
|
|
|
|
res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0');
|
|
|
|
|
res.setHeader('etag', nanoid());
|
|
|
|
|
res.type('text/xml');
|
|
|
|
|
if (verbose) {
|
|
|
|
|
console.log('============================');
|
|
|
|
|
console.log(vxmlResponse);
|
|
|
|
|
console.log('++++++++++++++++++++++++++++');
|
|
|
|
|
}
|
|
|
|
|
res.send(vxmlResponse);
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.log(e.message);
|
|
|
|
|
if (e.toJSON) console.log(e.toJSON());
|
|
|
|
|
res.status(500);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
if (sessionId) {
|
|
|
|
|
const smStr = `session-map-${sessionId}`;
|
|
|
|
|
(async () => {
|
|
|
|
|
if (req.body.sessionJSON && req.body.sessionJSON) {
|
|
|
|
|
const ani = getNested(req.body, 'sessionJSON', 'telephone', 'ani').split('@')[0];
|
|
|
|
|
const dnis = getNested(req.body, 'sessionJSON', 'connection', 'protocol', 'sip', 'requesturi').split('@')[0];
|
|
|
|
|
const callid = getNested(req.body, 'sessionJSON', 'connection', 'protocol', 'sip', 'headers', 'call-id').split('_')[0];
|
|
|
|
|
let xSpVerintId = getNested(req.body, 'sessionJSON', 'connection', 'protocol', 'sip', 'headers', 'x-sp-verintid') || callid;
|
|
|
|
|
if (utterance == undefined) {
|
|
|
|
|
getInteractionId(ani, dnis, callid).then(interactionId => {
|
|
|
|
|
if (interactionId) {
|
|
|
|
|
redis.hSet(smStr, {
|
|
|
|
|
interactionId
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
await redis.hSet(smStr, {
|
|
|
|
|
ani,
|
|
|
|
|
dnis,
|
|
|
|
|
callid,
|
|
|
|
|
xSpVerintId
|
|
|
|
|
});
|
|
|
|
|
await redis.expire(smStr, 60 * 60 * 24);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
const sessionMap = await redis.hGetAll(smStr);
|
|
|
|
|
Object.keys(sessionMap).forEach((key, i) => {
|
|
|
|
|
try {
|
|
|
|
|
sessionMap[key] = JSON.parse(sessionMap[key]);
|
|
|
|
|
} catch (e) {}
|
|
|
|
|
});
|
|
|
|
|
console.log(sessionMap);
|
|
|
|
|
if (sessionMap.waitForApi) {
|
|
|
|
|
promptText = undefined;
|
|
|
|
|
recognizedData = {
|
|
|
|
|
answers: [""],
|
|
|
|
|
ivrSettings: {
|
|
|
|
|
timeout: waitHoldTimeout
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
} else if (sessionMap.endCall) {
|
|
|
|
|
promptText = undefined;
|
|
|
|
|
recognizedData = {
|
|
|
|
|
answers: [""],
|
|
|
|
|
endCall: true
|
|
|
|
|
};
|
|
|
|
|
} else if (sessionMap.transferCall) {
|
|
|
|
|
recognizedData = await run_app_event(sessionMap, smStr, 'VXML Transfer Call Event', 'vxmltransfercall', voiceSettings_6647ad7b84df93835bbb4346.responses.transferCall);
|
|
|
|
|
recognizedData.endCall = true;
|
|
|
|
|
} else if (sessionMap.waitForLiveOperator) {
|
|
|
|
|
if (sessionMap.pendingAPIs) {
|
|
|
|
|
// async. success will delete sessionMap.pendingApis
|
|
|
|
|
sequenceApiCalls(smStr, sessionMap.interactionId, sessionMap.pendingAPIs);
|
|
|
|
|
}
|
|
|
|
|
recognizedData = await blockWaitLiveOperator(smStr, sessionMap, getCA());
|
|
|
|
|
} else if (route === 'noinput') {
|
|
|
|
|
recognizedData = await run_app_event(sessionMap, smStr, 'VXML Noinput Event', 'vxmlnoinput', voiceSettings_6647ad7b84df93835bbb4346.responses.noinput);
|
|
|
|
|
} else if (route === 'nomatch') {
|
|
|
|
|
recognizedData = await run_app_event(sessionMap, smStr, 'VXML Unrecognized Event', 'vxmlunrecognized', voiceSettings_6647ad7b84df93835bbb4346.responses.unrecognized);
|
|
|
|
|
} else if (route === 'maxspeechtimeout') {
|
|
|
|
|
recognizedData = await run_app_event(sessionMap, smStr, 'VXML Max Speech Timeout', 'vxmlmaxspeechtimeout', voiceSettings_6647ad7b84df93835bbb4346.responses.speechtimeout);
|
|
|
|
|
} else if (utterance) {
|
|
|
|
|
recognizedData = await run_model_and_report(sessionMap, smStr, utterance);
|
|
|
|
|
} else {
|
|
|
|
|
recognizedData = await run_app_event(sessionMap, smStr, 'VXML Welcome Event', 'vxmlwelcome', voiceSettings_6647ad7b84df93835bbb4346.responses.welcome);
|
|
|
|
|
}
|
|
|
|
|
if (recognizedData && recognizedData.transferCall) {
|
|
|
|
|
recognizedData.endCall = true;
|
|
|
|
|
await redis.hSet(smStr, {
|
|
|
|
|
transferCall: "true",
|
|
|
|
|
transferTo: recognizedData.transferTo || voiceSettings_6647ad7b84df93835bbb4346.transfer.destination
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
promptText = recognizedData && recognizedData.answers && recognizedData.answers.join(' ') || promptText;
|
|
|
|
|
disconnect = recognizedData && recognizedData.endCall || false;
|
|
|
|
|
generateVXML(sessionMap);
|
|
|
|
|
})().catch(e => {
|
|
|
|
|
console.log(e.message);
|
|
|
|
|
promptText = safetyNet;
|
|
|
|
|
generateVXML();
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
generateVXML();
|
|
|
|
|
}
|