Bot - Load Anonymous Dialogs, Recognizers, Events, Intents
//See: https://github.com/DanielEgan/botstarter
SAMPLE CODE FROM: botstarter/server.js
...
let fs = require('fs');
let path = require('path');
let readdir = require('readdir-enhanced');
...
let bot = new builder.UniversalBot(connector, function (session) {
session.beginDialog('/default');
});
//events
getFileNames('./app/events')
.map(file => Object.assign(file, { fx: require(file.path) }))
//for each one, execute the function (what ever the module returns becomes function (fx))
.forEach(event => event.fx(event.name, bot));
// // recognizers
getFileNames('./app/recognizers')
.map(file => Object.assign(file, { recognizer: require(file.path) }))
.forEach(r => bot.recognizer(r.recognizer));
getFileNames('./app/dialogs')
.map(file => Object.assign(file, { fx: require(file.path) }))
.forEach(dialog => dialog.fx(dialog.name, bot));
...
//Takes a directory and using fs to loop through the files in the directory
//this is how we get the names of our dialogs. By looking at the file names in the dialogs folder
//it is used the same way for recognizers, actions, etc.
//filter by .js files
function getFileNames(dir) {
return readdir.sync(dir, { deep: true })
.map(item => `.${path.posix.sep}${path.posix.join(dir, path.posix.format(path.parse(item)))}`) //normalize paths
.filter(item => !fs.statSync(item).isDirectory() && /.js$/.test(item)) //filter out directories
.map(file => ({ name: path.basename(file, '.js'), path: file }))
}
EXAMPLE: botstarter/APP/DIALOGS/DEFAULT.JS
module.exports = function (name, bot) {
bot.dialog(`/${name}`, [
function (session, args, next) {
session.endDialog("greeting");
}
])
};
EXAMPLE: botstarter/APP/DIALOGS/SAMPLE.JS
//This is an intent dialog. its trigger
//fires when an intent matches name (which corresponds to the file name)
module.exports = function (name, bot) {
bot.dialog(`/${name}`, [
function (session, args, next) {
session.endDialog(`${name} reached`);
}
]).triggerAction({matches:name})//triggered if action matches "name"
};
EXAMPLE: botstarter/APP/DIALOGS/WATERFALL.JS
let builder = require('botbuilder');
module.exports = function (name, bot) {
bot.dialog(`/${name}`, [
// should have customer id
// prompt for future order id
function (session, args, next) {
builder.Prompts.choice(session, `Which order?`, "111|222|333", {
listStyle: builder.ListStyle.button
});
},
function (session, args, next) {
let futureOrderID = args.response.entity;
session.endDialog(`edit ${futureOrderID}`);
}
])
.triggerAction({matches:name})
};
EXAMPLE: botstarter/APPS/EVENTS/conversationUpdate.js
et builder = require('botbuilder');
module.exports = function (name, bot) {
bot.on(name, function (message) {
if (message.action === 'add') {
var name = message.user ? message.user.name : null;
var reply = new builder.Message()
.address(message.address)
.text("Hi. Now we are in conversatin update.");
bot.send(reply);
} else {
// delete their data
}
})
};
EXAMPLE: /APPS/EVENTS/contactRelationUpdate.js
let builder = require('botbuilder');
module.exports = function (name, bot) {
bot.on(name, function (message) {
if (message.action === 'add') {
var name = message.user ? message.user.name : null;
var reply = new builder.Message()
.address(message.address)
.text("Hi. Thanks for adding me. Say 'hello' to see what I can do.");
bot.send(reply);
} else {
// delete their data
}
})
};
EXAMPLE: botstarter/app/recognizers/greeting.js
const greetings = [
'hi',
'hi there',
'hey',
'hey there',
'hello',
'hello hello',
'hello there',
'what up',
'what\'s up',
'whatup',
'salute',
'morning',
'good morning',
'how are you',
'how r u'
];
module.exports = {
recognize: function(context, callback) {
const text = context.message.text.replace(/[!?,.\/\\\[\]\{\}\(\)]/g, '').toLowerCase();
let isGreeting = greetings.some(g => text === g);
let recognized = {
entities: [],
intent: (isGreeting ? 'greeting' : null),
matched: undefined,
expression: undefined,
intents: [],
score: (isGreeting ? 1 : 0)
}
callback.call(null, null, recognized);
}
};
EXAMPLE:botstarter/app/recognizers/luisSample.js
//you can have multiple luis models you just need to point to seperate enDpoints
//in a different recognizer files
let builder = require("botbuilder");
const envx = require("envx");
module.exports = new builder.LuisRecognizer(envx("LUIS_ENDPOINT"));
EXAMPLE:botstarter/app/recognizers/qna.js
//this recognizer requires a modified version of the botbuilder-cognitiveservices module
//currently living at http://github.com/codefoster/botbuilder-cognitiveservices
//clone repo - git clone http://github.com/codefoster/botbuilder-cognitiveservices
//In a command window navigate to that repo run : npm link
//In a command window navigate to this project (botstarter) run npm link botbuilder-cognitiveservices
//You will also need to add your keys from QnAMaker
//you can have multiple QnA makers you just need to have seperate files
//and different intent names (intentName:"qna2")
const envx = require("envx");
let builder = require("botbuilder");
var bbcs = require('botbuilder-cognitiveservices');
module.exports = new bbcs.QnAMakerRecognizer({
knowledgeBaseId: envx("QNA_ID"),
subscriptionKey: envx("QNA_KEY"),
intentName: "qna"
});
EXAMPLE:botstarter/app/services/sampleService.js
let customers = [
{ customerId: 1, type: 'tech', name: 'Loretta Rayes', phone: '(345) 501-2527', onCall: true, pendingAppt: false },
{ customerId: 2, type: 'tech', name: 'Gary Foster', phone: '(662) 588-7043', onCall: false },
{ customerId: 3, type: 'customer', name: 'Kenneth Coleman', phone: '(510) 266-3583', pendingAppt: false },
{
customerId: 4, type: 'customer', name: 'Tim Hiatt', phone: '(497) 889-1015', pendingAppt: true,
orders: [
{ orderId: 1, date: '1/31/2016' },
{ orderId: 2, date: '2/14/2017' },
{ orderId: 3, date: '2/23/2017' }
]
}
];
module.exports.customers = customers;
module.exports.findCustomer = function (customerId) {
return customers.filter(x => x.customerId == customerId);
}