poserver
Version:
Server for JD Bot
223 lines (186 loc) • 7.92 kB
JavaScript
/**
* Created by tomdaley on 11/18/16.
*/
var builder = require('botbuilder');
var params = require("../../../poserver-configuration.json");
var prompts = require('../const/prompts');
var _created = false;
module.exports =
{
create: function (bot)
{
if (_created) return;
_created = true;
//Create the BUILTIN library if we don't already have it.
if (!bot.lib.libraries.hasOwnProperty("BUILTIN"))
bot.library(new builder.Library('BUILTIN'));
var navigationRecognizer = new builder.LuisRecognizer(params.LUIS_SERVICE_NAVIGATION);
var choiceDialog = new builder.IntentDialog({recognizers: [navigationRecognizer]});
var backWaterfall = [
function (session, args)
{
session.endDialogWithResult({navigation: "back"});
}
];
//RegEx processed before LUIS recognizer is called. Some really obvious/common regex patterns will reduce the number
//of LUIS API calls. Will make the app run faster and cheaper.
choiceDialog.matches(/^(back|go back|prev|up)/i, backWaterfall);
choiceDialog.matches('navigation.intent.goback', backWaterfall);
var helpWaterfall = [
function (session, args, next)
{
if (session.dialogData.config.hasOwnProperty('helpDialog'))
{
session.beginDialog(session.dialogData.config.helpDialog);
}
else if (session.dialogData.hasOwnProperty('helpMessage'))
{
session.send(session.dialogData.config.helpMessage);
next();
}
else
{
session.send(prompts.sayICantHelpYou);
next();
}
},
function (session)
{
Util.confirm(session, session.dialogData.config.prompt);
}
];
choiceDialog.matches(/^(help|\?)/i, helpWaterfall);
choiceDialog.matches('navigation.intent.help', helpWaterfall);
choiceDialog.matches('navigation.intent.explain',
[
function (session, args, next)
{
if (session.dialogData.config.hasOwnProperty('explainDialog'))
{
session.beginDialog(session.dialogData.config.explainDialog);
}
else if (session.dialogData.config.hasOwnProperty('explainMessage'))
{
session.send(session.dialogData.config.explainMessage);
next();
}
else
{
session.send(prompts.sayIDontKnowWhy);
next();
}
},
function (session)
{
Util.confirm(session, session.dialogData.config.prompt);
}
]);
var restartWaterfall = [
function (session, args)
{
session.endDialogWithResult({navigation: "restart"});
}
];
choiceDialog.matches(/^(restart|start over)/i, restartWaterfall);
choiceDialog.matches('navigation.intent.restart', restartWaterfall);
var quitWaterfall = [
function (session, args)
{
session.endDialogWithResult({navigation: "quit"});
}
];
choiceDialog.matches(/^(quit|abort)/i, quitWaterfall);
choiceDialog.matches('navigation.intent.quit', quitWaterfall);
choiceDialog.onDefault(function (session, results)
{
var match = builder.EntityRecognizer.findBestMatch(session.dialogData.config.choices, session.message.text);
if (match.score > 0.6)
{
session.endDialogWithResult({response: match});
}
else
{
offerChoice(session, session.dialogData.config);
}
});
choiceDialog.onBegin(function (session, config)
{
session.dialogData.config = config || {};
offerChoice(session, config);
});
bot.lib.libraries.BUILTIN.dialog('/choice', choiceDialog);
},
/**
* Presents the user with a list of choices in the form of buttons.
* @param session
* @param prompt
* @param choices
* @param config
*/
choice: function (session, prompt, choices, config)
{
if (!prompt) throw new Error("ChoiceDialog.choice(): prompt argument is required.");
if (typeof prompt != "string" && !Array.isArray(prompt)) throw new Error("ChoiceDialog.choice(): prompt arg must be string or array of strings.");
if (!choices) throw new Error("ChoiceDialog.choice(): choices argument is required.");
if (typeof choices != "string" && !Array.isArray(choices)) throw new Error("ChoiceDialog.choice(): choices arg must be string (weird) or array of strings.");
if (!Array.isArray(choices)) choices = [choices];
config = config || {};
config.prompt = prompt;
config.choices = choices;
config.showHelp = (config.helpDialog || config.helpMessage);
session.beginDialog('BUILTIN:/choice', config);
}
};
/**
* A better version of builder.Prompts.choice() in that it creates a better-looking output on skype.
*
* @param session
* @param {object} config - Dialog configuration
* @property {string|string[]} config.prompt - Prompt string or array of strings
* @property {string[]} config.choices - List of choices user can accept
* @property {string|string[]} config.title - [OPTIONAL] Title string or array of strings
* @property {subtitle|string[]} config.subtitle - [OPTIONAL] subtitle string or array of strings
* @property {string|string[]} config.imageUrl - [OPTIONAL] image URL or array of URL strings
* @property {boolean} config.showHelp - Determines whether a help button is shown.
*/
function offerChoice(session, config)
{
showHelp = config.showHelp;
var card = new builder.HeroCard(session);
var xchoices = [];
var choices = config.choices;
for (var c in choices) xchoices.push(builder.CardAction.postBack(session, choices[c], choices[c]));
//If the calling dialog can provide help, then add a HELP button to the mix.
if (showHelp)
{
var helpAction = builder.CardAction.postBack(session, "?", prompts.help);
if (!fs.existsSync(helpIconPath))
{
console.info("ConfirmDialog.configm(): %s not found.", helpIconPath);
}
else
{
var helpPath = fs.realpathSync(helpIconPath).replace(/\\/g, "/");
if (helpPath.slice(0, 0) != "/") helpPath = "/" + helpPath; //when running under Windows
helpAction.image(encodeURI("file:///" + helpPath));
console.log(encodeURI("file:///" + helpPath));
}
xchoices.push(helpAction);
}
card.buttons(xchoices);
card.text = (Array.isArray(config.prompt)) ? config.prompt[Math.floor(Math.random() * config.prompt.length)] : config.prompt;
if (config.hasOwnProperty("title"))
{
card.title = (Array.isArray(config.title)) ? config.title[Math.floor(Math.random() * config.title.length)] : config.title;
}
if (config.hasOwnProperty("subtitle"))
{
card.subtitle = (Array.isArray(config.subtitle)) ? config.subtitle[Math.floor(Math.random() * config.subtitle.length)] : config.subtitle;
}
if (config.hasOwnProperty("imageUrl"))
{
card.images = (Array.isArray(imageUrl)) ? config.imageUrl : [config.imageUrl];
}
var msg = new builder.Message(session).addAttachment(card);
session.send(msg);
}