UNPKG

poserver

Version:
337 lines (281 loc) 10.9 kB
/** * Created by tomdaley on 9/4/16. */ "use strict"; var myPackage = require('./package.json'); var Util = require('./JdBotUtil'); var mongoUtil = require('./classes/mongoUtils'); /********************************************* * Classes use in session.userData *********************************************/ var ParsedAddress = require('./classes/clsParsedAddress'); var ParsedName = require('./classes/clsParsedName'); var Person = require('./classes/clsPerson'); var Types = require('./classes/types'); Types.registerType("ParsedAddress", ParsedAddress); Types.registerType("ParsedName", ParsedName); Types.registerType("Person", Person); var restify = require('restify'); var builder = require('botbuilder'); /********************************************* * Runtime Environment *********************************************/ var params = require("../../poserver-configuration.json"); /********************************************* * Prompts - Externalized for localization *********************************************/ var prompts = require('./const/prompts'); /********************************************* * Connect to Mongo DB for user Auth and * data persistence. *********************************************/ mongoUtil.connectDb(function (err) { console.log('Connected to MongoDb at %s', params.MONGODBURL); Util.loadViolenceDatabase(); }); /********************************************* * Bot Setup *********************************************/ // Setup Restify Server var server = restify.createServer(); server.listen(params.PORT, function () { console.log("%s - %s (v %s) by %s", myPackage.name, myPackage.description, myPackage.version, myPackage.author.name); console.log('%s listening to %s', server.name, server.url); }); //Create chat bot var connector = new builder.ChatConnector( { appId : params.MICROSOFT_APP_ID, appPassword: params.MICROSOFT_APP_PASSWORD } ); var bot = new builder.UniversalBot(connector); /********************************************* * Imported Dialogs *********************************************/ bot.library(require('./dialogs/AddressDialog')); bot.library(require('./dialogs/CauseNumberDialog')); bot.library(require('./dialogs/CustomerSurveyLibrary')); bot.library(require('./dialogs/CountyDialog')); bot.library(require('./dialogs/OriginalAnswerDialogs')); bot.library(require('./dialogs/PaymentDialogs')); bot.library(require('./dialogs/QualifyJurisdictionDialog')); bot.library(require('./dialogs/UserProfileDialogs')); var ConfirmDialog = require("./dialogs/ConfirmDialog"); ConfirmDialog.create(bot); var ChoiceDialog = require("./dialogs/ChoiceDialog"); ChoiceDialog.create(bot); var FVProtectiveOrder = require('./dialogs/FamilyViolenceProtectiveOrder'); server.post('/api/messages', connector.listen()); /********************************************* * Bot's Dialogs *********************************************/ Util.setBot(bot); FVProtectiveOrder.createDialogs(bot, builder); //See if the user's profile needs to be updated or we need to do anything else by reason of a software update since the //last time the user was here. bot.use(builder.Middleware.firstRun({ version : 4.5, dialogId: 'userProfile:/firstRun', upgradeDialogId: 'userProfile:/upgrade', upgradeDialogArgs: {toVersion: "4.5"} })); /* * On each incoming message from the user, see what kind of a delay there was since the last message. * On an insignificant delay, just continue. * On a minor but noticeable delay, welcome the user back, reload his or her profile, and continue. * On a major delay, start the conversation over. * * In the future we could log the delay relating to each question and see if user's tend to get stuck in the same * place or places. */ var checker = function (options) { var mw = { botbuilder: function (session, next) { if (!session.userData.hasOwnProperty("lastBotbuilderTime")) session.userData.lastBotbuilderTime = (new Date()).getTime(); var delay = (new Date()).getTime() - session.userData.lastBotbuilderTime; session.userData.lastBotbuilderTime = (new Date()).getTime(); //////// Here to reinstantiate userData as a class with methods, not just data if (session.userData.hasOwnProperty("userProfile")) session.userData.userProfile = Types.revive(session.userData.userProfile); if (session.userData.hasOwnProperty("case")) session.userData.case = Types.revive(session.userData.case); //////// END REINSTANTIATE //Minor Delay /** @property {number} mwDelayMilliseconds - Less than this # ms between messages = active session */ if (delay > params.mwDelayMilliseconds && delay < params.mwDelayRestartMilliseconds) { /** * @param session - Our ever-present session object * @param {boolean} isLoaded - Indicates whether the profile was successfully reloaded */ Util.getUserProfile(session) .then(function (isLoaded) { var salutation = (session.userData.hasOwnProperty("userProfile") ? session.userData.userProfile.name.salutation : session.message.user.name); var prompt = session.gettext(Util.getRandomElement(prompts.sayWelcomeAfterDelay), {uname: salutation}); session.send(prompt); next(); }) .catch(function (reason) { console.log("Error loading userProfile"); console.log(reason); }); } //Major Delay /** * @property {number} mwDelayRestartMilliseconds - After the user has been inactive this # ms, we restart */ else if (delay > params.mwDelayRestartMilliseconds) { session.send(prompts.sayYouveBeenAwayForSoLong); session.send("Resetting session."); //session.replaceDialog("*:/"); //session.endConversation(prompts.sayHiToBegin); session.reset("*:/"); } //Insignificant Delay else { next(); } } }; return mw; }; bot.use(checker({})); /* * Once we have some sort of user profile, this is where the bot begins */ //Cause of action model var model = params.LUIS_SERVICE_JDBOT; var recognizer = new builder.LuisRecognizer(model); var dialog = new builder.IntentDialog({recognizers: [recognizer]}); dialog.matches('plead.original.answer', [ function (session, args, next) { session.beginDialog('originalAnswer:/', {entities: args.entities || {}}); } ]); dialog.matches('plead.divorce', [ function (session, args, next) { session.send("OK, you need a divorce."); } ]); dialog.matches('draft.qdro', [ function (session) { session.send("One day I'll be able to draft a QDRO for you."); } ]); dialog.matches('update.profile', [ function (session, args) { session.beginDialog("userProfile:/Verify"); }, function (session) { session.send(prompts.askWhatElseCanIDoForYou); } ]); dialog.matches('show.menu', [ function (session, args, next) { session.beginDialog('/menuInterface'); } ]); dialog.onDefault([ function (session, args) { var config = { prompt : prompts.askShowMenu, helpMessage: "Say 'YES' if you would like to see a list of things I can do for you." }; ConfirmDialog.confirm(session, config); }, function (session, results, next) { if (results.hasOwnProperty("navigation")) { switch (results.navigation) { case "quit": session.endConversation(prompts.sayHiToBegin); break; case "restart": session.endConversation(prompts.sayHiToBegin); break; case "back": session.send(prompts.howCanIHelpYouMessage); break; } } else if (results.response) { session.beginDialog("/menuInterface"); } } ]); bot.dialog('/recognize', dialog); bot.dialog('/', [ function (session, args, next) { session.send(prompts.howCanIHelpYouMessage); session.beginDialog("/recognize"); } ]); bot.dialog('/menuInterface', [ function (session) { //Main menu, so to speak var choices = Object.keys(prompts.abilities); //Util.cleanupSession(session); //In case Microsoft's State Machine gets messed up, we can put in some dummy data to keep the //program runnning. if (!session.userData.userProfile) session.userData.userProfile = {}; console.log("app: *:/menuInterface: channelId (%s)", session.message.address.channelId); console.log(session.message.address); ChoiceDialog.choice(session, prompts.howCanIHelpYouMessage, choices); // session.userData.config.PromptChoiceOptions); }, //Dispatch to requested function function (session, results) { if (results.hasOwnProperty("navigation")) { switch (results.navigation) { case "quit": session.endConversation(prompts.sayHiToBegin); break; case "restart": session.endConversation(prompts.sayHiToBegin); break; case "back": session.send(prompts.howCanIHelpYouMessage); break; } } else if (results.response.hasOwnProperty("entity")) { session.beginDialog(prompts.abilities[results.response.entity].dialogName) } else { session.replaceDialog("*:/menuInterface"); } } ] );