I am very new to bot builder. I need to use LUIs intents and then eventually call azure-search to search the intent.
However, below is my code. In the Aco-Saerch intent, I want to extract the intent from the user's message and then want to pass to the query in the azure-search.
In the dialog SearchDialog, waterfall functions are not proceeding after the first function. Can anyone help me out whats wrong here.
I am trying the use the azure search code and libraries from this git-hub shared code: Realstate azure search node js code
In future, I want to add QnA recognizer too. Aim is : search the query in qnA base, if found, return else, use the LUIS to find out the intent and then pass it the azure search.
var util = require('util');
var _ = require('lodash');
var builder = require('botbuilder');
var restify = require('restify');
/// <reference path="../SearchDialogLibrary/index.d.ts" />
var SearchLibrary = require('../SearchDialogLibrary');
var AzureSearch = require('../SearchProviders/azure-search');
// Setup Restify Server
var server = restify.createServer();
server.listen(process.env.port || process.env.PORT || 3978, function () {
console.log('%s listening to %s', server.name, server.url);
});
// Create chat bot and listen for messages
var connector = new builder.ChatConnector({
appId: process.env.MICROSOFT_APP_ID,
appPassword: process.env.MICROSOFT_APP_PASSWORD
});
server.post('/api/messages', connector.listen());
// Bot Storage: Here we register the state storage for your bot.
// Default store: volatile in-memory store - Only for prototyping!
// We provide adapters for Azure Table, CosmosDb, SQL Azure, or you can implement your own!
// For samples and documentation, see: https://github.com/Microsoft/BotBuilder-Azure
var inMemoryStorage = new builder.MemoryBotStorage();
const LuisModelUrl = 'https://westeurope.api.cognitive.microsoft.com/luis/v2.0/apps/180a9aaa-9d67-4d40-b3d3-121917f4dbb8?subscription-key=39155bb750dc4b2abd84d410d80fce21&timezoneOffset=0&q=';
var recognizer = new builder.LuisRecognizer(LuisModelUrl);
// Bot with main dialog that triggers search and display its results
var bot = new builder.UniversalBot(connector, function (session, args) {
session.send('You reached the default message handler. You said \'%s\'.', session.message.text);
}).set('storage', inMemoryStorage);
bot.recognizer(recognizer);
bot.dialog('GreetingDialog',
(session) => {
session.send('You reached the Greeting intent. You said \'%s\'.', session.message.text);
session.endDialog();
}
).triggerAction({
matches: 'Greeting'
})
bot.dialog('HelpDialog',
(session) => {
session.send('You reached the Help intent. You said \'%s\'.', session.message.text);
session.endDialog();
}
).triggerAction({
matches: 'Help'
})
bot.dialog('CancelDialog',
(session) => {
session.send('You reached the Cancel intent. You said \'%s\'.', session.message.text);
session.endDialog();
}
).triggerAction({
matches: 'Cancel'
})
bot.dialog('SearchDialog', [
function (session, args) {
var intent = args.intent;
var title = builder.EntityRecognizer.findEntity(intent.entities, 'businessterm');
console.log(title.entity);
session.send('You reached the Search.Aco intent. You enquire for the entitiy \'%s\'.', title.entity);
},
function (session, args, results) {
// Trigger Search
console.log("Inside the SearchLibrary.begin");
SearchLibrary.begin(session);
console.log("after the SearchLibrary.begin");
},
function (session, args, results) {
// Process selected search results
session.send(
'Done! For future reference, you selected these properties: %s',
args.selection.map(function (i) { return i.key; }).join(', '));
}
]).triggerAction({
matches: 'Search.Aco'
});
var azureSearchClient = AzureSearch.create('aco-intel2', '4105C6676D0CDD9B2E7891952B9E9E00', 'azureblob-index');
var jobsResultsMapper = SearchLibrary.defaultResultsMapper(jobToSearchHit);
// Register Search Dialogs Library with bot
bot.library(SearchLibrary.create({
multipleSelection: true,
search: function (query) { return azureSearchClient.search(query).then(jobsResultsMapper); },
refiners: ['people', 'content', 'location']
}));
// Maps the AzureSearch Job Document into a SearchHit that the Search Library can use
function jobToSearchHit(acosearch) {
console.log("inside jobToSearchHit");
console.log("inside acosearch.DocUrl" + acosearch.DocUrl + "-------" + acosearch.metadata_storage_name);
return {
key: acosearch.id,
title: acosearch.metadata_storage_name,
description: acosearch.content.substring(0, 100)+"...",
documenturl:acosearch.DocUrl,
imageUrl: acosearch.imageurl
};
}
Your dialog isn't advancing as there is nothing for it to act on. Thus, it reaches the end of the first function with nowhere to move on to. You have a few options. You can:
You can include a prompt or button (i.e. some sort of action) to move the dialog along. Ex:
bot.dialog('SearchDialog', [
function (session, args) {
var intent = args.intent;
var title = builder.EntityRecognizer.findEntity(intent.entities, 'businessterm');
console.log(title.entity);
session.send('You reached the Search.Aco intent. You enquire for the entitiy \'%s\'.', title.entity);
builder.Prompts.choice(session, "Start search?", "Yes|No", { listStyle: builder.ListStyle["button"] });
},
function (session, args, results) {
// Trigger Search
console.log("Inside the SearchLibrary.begin");
SearchLibrary.begin(session);
console.log("after the SearchLibrary.begin");
}
You can marry the first and second function. However, again, you will need something to move the dialog along from the search function to the search results function.
bot.dialog('SearchDialog', [
function (session, args) {
var intent = args.intent;
var title = builder.EntityRecognizer.findEntity(intent.entities, 'businessterm');
console.log(title.entity);
session.send('You reached the Search.Aco intent. You enquire for the entitiy \'%s\'.', title.entity);
// Trigger Search
console.log("Inside the SearchLibrary.begin");
SearchLibrary.begin(session);
console.log("after the SearchLibrary.begin");
},
function (session, args, results) {
// Process selected search results
session.send(
'Done! For future reference, you selected these properties: %s',
args.selection.map(function (i) { return i.key; }).join(', '));
}
]).triggerAction({
matches: 'Search.Aco'
});
You can make the search function a separate dialog that is initiated at the end of the first dialog function and, once completes, returns and continues the original dialog.
bot.dialog('SearchDialog', [
function (session, args) {
var intent = args.intent;
var title = builder.EntityRecognizer.findEntity(intent.entities, 'businessterm');
console.log(title.entity);
session.send('You reached the Search.Aco intent. You enquire for the entitiy \'%s\'.', title.entity);
session.beginDialog('/searchAzure');
},
function (session, args, results) {
// Process selected search results
session.send(
'Done! For future reference, you selected these properties: %s',
args.selection.map(function (i) { return i.key; }).join(', '));
}
]).triggerAction({
matches: 'Search.Aco'
});
bot.dialog('/searchAzure', [
function (session) {
// Trigger Search
console.log("Inside the SearchLibrary.begin");
SearchLibrary.begin(session);
console.log("after the SearchLibrary.begin");
session.endDialog();
}
]);