Build a foodie bot with JavaScript

first_imgToday, we are going to build a chatbot that can search for restaurants based on user goals and preferences. Let us begin by building Node.js modules to get data from Zomato based on user preferences. Create a file called zomato.js. Add a request module to the Node.js libraries using the following command in the console: This tutorial has been taken from Hands-On Chatbots and Conversational UI Development. > npm install request –save In zomato.js, add the following code to begin with: var request = require(‘request’);var baseURL = ‘https://developers.zomato.com/api/v2.1/’;var apiKey = ‘YOUR_API_KEY’;var catergories = null;var cuisines = null;getCategories();getCuisines(76); Replace YOUR_API_KEY with your Zomato key. Let’s build functions to get the list of categories and cuisines at startup. These queries need not be run when the user asks for a restaurant search because this information is pretty much static: function getCuisines(cityId){var options = {uri: baseURL + ‘cuisines’,headers: {‘user-key’: apiKey},qs: {‘city_id’:cityId},method: ‘GET’}var callback = function(error, response, body) {if (error) {console.log(‘Error sending messages: ‘, error)} else if (response.body.error) {console.log(‘Error: ‘, response.body.error)} else {console.log(body);cuisines = JSON.parse(body).cuisines;}}request(options,callback);} The preceding code will fetch a list of cuisines available in a particular city (identified by a Zomato city ID). Let us add the code for identifying the list of categories: function getCategories(){var options = {uri: baseURL + ‘categories’,headers: {‘user-key’: apiKey},qs: {},method: ‘GET’}var callback = function(error, response, body) {if (error) {console.log(‘Error sending messages: ‘, error)} else if (response.body.error) {console.log(‘Error: ‘, response.body.error)} else {categories = JSON.parse(body).categories;}}request(options,callback);} Now that we have the basic functions out of our way, let us code in the restaurant search code: function getRestaurant(cuisine, location, category){var cuisineId = getCuisineId(cuisine);var categoryId = getCategoryId(category);var options = {uri: baseURL + ‘locations’,headers: {‘user-key’: apiKey},qs: {‘query’:location},method: ‘GET’}var callback = function(error, response, body) {if (error) {console.log(‘Error sending messages: ‘, error)} else if (response.body.error) {console.log(‘Error: ‘, response.body.error)} else {console.log(body);locationInfo = JSON.parse(body).location_suggestions;search(locationInfo[0], cuisineId, categoryId);}}request(options,callback);}function search(location, cuisineId, categoryId){var options = {uri: baseURL + ‘search’,headers: {‘user-key’: apiKey},qs: {‘entity_id’: location.entity_id,’entity_type’: location.entity_type,’cuisines’: [cuisineId],’categories’: [categoryId]},method: ‘GET’}var callback = function(error, response, body) {if (error) {console.log(‘Error sending messages: ‘, error)} else if (response.body.error) {console.log(‘Error: ‘, response.body.error)} else {console.log(‘Found restaurants:’)var results = JSON.parse(body).restaurants;console.log(results);}}request(options,callback);} The preceding code will look for restaurants in a given location, cuisine, and category. For instance, you can search for a list of Indian restaurants in Newington, Edinburgh that do delivery. We now need to integrate this with the chatbot code. Let us create a separate file called index.js. Let us begin with the basics: var restify = require(‘restify’);var builder = require(‘botbuilder’);var request = require(‘request’);var baseURL = ‘https://developers.zomato.com/api/v2.1/’;var apiKey = ‘YOUR_API_KEY’;var catergories = null;var cuisines = null;Chapter 6[ 247 ]getCategories();//setTimeout(function(){getCategoryId(‘Delivery’)}, 10000);getCuisines(76);//setTimeout(function(){getCuisineId(‘European’)}, 10000);// Setup Restify Servervar 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 connector for communicating with// the Bot Framework Servicevar connector = new builder.ChatConnector({appId: process.env.MICROSOFT_APP_ID,appPassword: process.env.MICROSOFT_APP_PASSWORD});// Listen for messages from usersserver.post(‘/foodiebot’, connector.listen()); Add the bot dialog code to carry out the restaurant search. Let us design the bot to ask for cuisine, category, and location before proceeding to the restaurant search: var bot = new builder.UniversalBot(connector, [function (session) {session.send(“Hi there! Hungry? Looking for a restaurant?”);session.send(“Say ‘search restaurant’ to start searching.”);session.endDialog();}]);// Search for a restaurantbot.dialog(‘searchRestaurant’, [function (session) {session.send(‘Ok. Searching for a restaurant!’);builder.Prompts.text(session, ‘Where?’);},function (session, results) {session.conversationData.searchLocation = results.response;builder.Prompts.text(session, ‘Cuisine? Indian,Italian, or anything else?’);},function (session, results) {session.conversationData.searchCuisine = results.response; builder.Prompts.text(session, ‘Delivery or Dine-in?’);},function (session, results) {session.conversationData.searchCategory = results.response;session.send(‘Ok. Looking for restaurants..’);getRestaurant(session.conversationData.searchCuisine,session.conversationData.searchLocation,session.conversationData.searchCategory,session);}]).triggerAction({matches: /^search restaurant$/i,confirmPrompt: ‘Your restaurant search task will be abandoned.Are you sure?’}); Notice that we are calling the getRestaurant() function with four parameters. Three of these are ones that we have already defined: cuisine, location, and category. To these, we have to add another: session. This passes the session pointer that can be used to send messages to the emulator when the data is ready. Notice how this changes the getRestaurant() and search() functions: function getRestaurant(cuisine, location, category, session){var cuisineId = getCuisineId(cuisine);var categoryId = getCategoryId(category);var options = {uri: baseURL + ‘locations’,headers: {‘user-key’: apiKey},qs: {‘query’:location},method: ‘GET’}var callback = function(error, response, body) {if (error) {console.log(‘Error sending messages: ‘, error)} else if (response.body.error) {console.log(‘Error: ‘, response.body.error)} else {console.log(body);locationInfo = JSON.parse(body).location_suggestions;search(locationInfo[0], cuisineId,categoryId, session);}}request(options,callback);}function search(location, cuisineId, categoryId, session){var options = {uri: baseURL + ‘search’,headers: {‘user-key’: apiKey},qs: {‘entity_id’: location.entity_id,’entity_type’: location.entity_type,’cuisines’: [cuisineId],’category’: categoryId},method: ‘GET’}var callback = function(error, response, body) {if (error) {console.log(‘Error sending messages: ‘, error)} else if (response.body.error) {console.log(‘Error: ‘, response.body.error)} else {console.log(‘Found restaurants:’)console.log(body);//var results = JSON.parse(body).restaurants;//console.log(results);var resultsCount = JSON.parse(body).results_found;console.log(‘Found:’ + resultsCount);session.send(‘I have found ‘ + resultsCount +’ restaurants for you!’);session.endDialog();}}request(options,callback);} Once the results are obtained, the bot responds using session.send() and ends the dialog: Now that we have the results, let’s present them in a more visually appealing way using cards. To do this, we need a function that can take the results of the search and turn them into an array of cards: function presentInCards(session, results){var msg = new builder.Message(session);msg.attachmentLayout(builder.AttachmentLayout.carousel)var heroCardArray = [];var l = results.length;if (results.length > 10){l = 10;}for (var i = 0; i And we call this function from the search() function: function search(location, cuisineId, categoryId, session){var options = {uri: baseURL + ‘search’,headers: {‘user-key’: apiKey},qs: {‘entity_id’: location.entity_id,’entity_type’: location.entity_type,’cuisines’: [cuisineId],’category’: categoryId},method: ‘GET’}var callback = function(error, response, body) {if (error) {console.log(‘Error sending messages: ‘, error)} else if (response.body.error) {console.log(‘Error: ‘, response.body.error)} else {console.log(‘Found restaurants:’)console.log(body);var results = JSON.parse(body).restaurants;var msg = presentInCards(session, results);session.send(msg);session.endDialog();}}request(options,callback);} Here is how it looks: We saw how to build a restaurant search bot, that gives you restaurant suggestions as per your preference. If you found our post useful check out Chatbots and Conversational UI Development. Read Next Top 4 chatbot development frameworks for developers How to create a conversational assistant using Python My friend, the robot: Artificial Intelligence needs Emotional Intelligencelast_img read more