Create Your Own Azure Chat Bot

Introduction

Bot Service provides an integrated environment that is purpose-built for bot development, enabling you to build, connect, test, deploy, and manage intelligent bots, all from one place. Bot Service leverages the Bot Builder SDK with support for .NET and Node.js. You can write a bot, connect, test, deploy, and manage it from your web browser with no separate editor or source control required.

For simple bots, you may not need to write code at all. Bot Service accelerates bot development with five bot templates you can choose from when you create a bot. You can further modify your bot directly in the browser using the Azure editor or in an Integrated Development Environment (IDE), such as Visual Studio and Visual Studio Code

Here are some key features of Bot Service,

  • Multiple language support

    • Bot Service leverages Bot Builder with support for .NET and Node.js.

  • Bot templates

    • Bot Service templates allow you to quickly create a bot with the code and features you need. Choose from a Basic bot, a Forms bot for collecting user input, a Language understanding bot that leverages LUIS to understand user intent, a QnA bot to handle FAQs, or a Proactive bot that alerts users of events.

  • Bring your own dependencies

    • Bots support NuGet and NPM, so you can use your favorite packages in your bot.

  • Flexible development

    • Code your bot right in the Azure portal or set up continuous integration and deploy your bot through GitHub, Visual Studio Team Services, and other supported development tools. You can also publish from Visual Studio.

  • Connect to channels

    • Bot Service supports several popular channels for connecting your bots and the people that use them. Users can start conversations with your bot on any channel that you've configured your bot to work with, including Skype, Facebook, Teams, Slack, SMS, and several others.

  • Tools and services

    • Test your bot with the Bot Framework Emulator and preview your bot on different channels with the Channel Inspector.

  • Open source

    • The Bot Builder SDK is open-source and available on GitHub

In this post, I will show how to create Azure bot that is integrated with Entity Framework to retrieve the employee vacation balance from Azure SQL database.

Prerequisites

  1. Visual Studio 2017.
  2. In Visual Studio, update all extensions to their latest versions.
  3. Bot template for C#.

Create Chat Bot

First, you'll need to download and install the Bot template, to download click on the following URL: https://marketplace.visualstudio.com/items?itemName=BotBuilder.BotBuilderV3 

After the download completes, double-click on BotBuilderVSIX.vsix and install it.

Then, you'll need to download and install the emulator. Open the following URL https://emulator.botframework.com/  to download the emulator. After the download completes, launch the executable and complete the installation process.

Now, open Visual Studio, select Bot framework, change the name, and click OK.

Create your own Azure Chat Bot

Now, we need to create Employee Order form to collect the employee select service. To do that create a new class named EmployeeOrder.cs and replace the original class code with the following one.

  1. public enum ServiceType  
  2.   {  
  3.       GetVacationBalance,  
  4.       LeaveRequest  
  5.   }  
  6.   [Serializable]  
  7.   public class EmployeeOrder  
  8.   {  
  9.       [Describe(Description = "Service", Image = "")]  
  10.       [Prompt("Please select the service you want. {||}")]  
  11.       public ServiceType? Service { get; set; }  
  12.   
  13.       public static IForm<EmployeeOrder> BuildForm()  
  14.       {  
  15.   
  16.           //PromptAttribute  
  17.           return new FormBuilder<EmployeeOrder>()  
  18.               .Field(nameof(Service))  
  19.               .Confirm("No verification will be shown", state => false)  
  20.               .Build();  
  21.       }  
  22.   }  

Next, we need to create a Vacation Form by creating Vacation.cs class.

  1. [Serializable]  
  2.     public class Vacation  
  3.     {  
  4.         [Describe(Description = "Employee ID")]  
  5.         [Numeric(1, 100000)]  
  6.         [Prompt("Please give me your employee identification number")]  
  7.         public int? EmployeeId { get; set; }  
  8.         public static IForm<Vacation> BuildForm()  
  9.         {  
  10.   
  11.             //PromptAttribute  
  12.             return new FormBuilder<Vacation>()  
  13.                 .Message("Your Select Vacation Balance Service")  
  14.                 .Field(nameof(EmployeeId))  
  15.                     .Confirm("No verification will be shown", state => false)  
  16.             .Build();  
  17.         }  
  18.     }  

Next, we need to connect the form to the framework. Open MessagesController and then add the following methods.

  1. public static IDialog<EmployeeOrder> MakeEmployeeDialog()  
  2.   {  
  3.       return Chain.From(() => FormDialog.FromForm(EmployeeOrder.BuildForm));  
  4.   }  
  5.   public static IDialog<Vacation> MakeVacationDialog()  
  6.   {  
  7.       return Chain.From(() => FormDialog.FromForm(Vacation.BuildForm));  
  8.   }  

Next, we need to connect to the database by using Entity Framework by creating the data context and entity classes.

First, we need to create EmployeeContext class.

  1. public EmployeeContext():base("name=dbCs")  
  2.      {  
  3.      }  
  4.      public DbSet<Employee> Employees { get; set; }  

Next, create the Employee class.

  1. public class Employee  
  2.     {  
  3.         public int Id { get; set; }  
  4.         public string Name { get; set; }  
  5.         public DateTime JoinDate { get; set; }  
  6.         public decimal VacationBalance { get; set; }  
  7.         public DateTime UpdateDate { get; set; }  
  8.         public decimal Salary { get; set; }  
  9.   
  10.     }  

Then, add the connection string in web.config.

  1. <connectionStrings>  
  2.   <add name="dbCs" connectionString="Data Source=.;Initial Catalog=EmployeeDb;User ID={UserId};Password={password};MultipleActiveResultSets=True"  
  3.        providerName="System.Data.SqlClient" />  
  4. </connectionStrings>   

Next, open RootDialog class and add the following code.

  1. private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<object> result)  
  2.      {  
  3.          var activity = await result as Activity;  
  4.          var _order = activity.Text.ToLower();  
  5.   
  6.          // defined welcome message  
  7.          var _WelcomeMsg2 = context.MakeMessage();  
  8.          _WelcomeMsg2.Attachments.Add(new Attachment()  
  9.          {  
  10.              ContentUrl = "https://cdn.dribbble.com/users/722835/screenshots/4082720/bot_icon_teaser.gif",  
  11.              ContentType = "image/gif",  
  12.              Name = "HR Bot"  
  13.          });  
  14.   
  15.          _WelcomeMsg2.Text = $"Hello. How I can help you?";  
  16.   
  17.          // Return our reply to the user  
  18.          await context.PostAsync(_WelcomeMsg2);  
  19.   
  20.          // Go to Employee Dialog  
  21.          var _employeeServiceDialog = MessagesController.MakeEmployeeDialog();  
  22.          await context.Forward(_employeeServiceDialog, this.ResumeAfterNewOrderDialog, activity, CancellationToken.None);  
  23.   
  24.   
  25.      }  
  26.   
  27.      private async Task ResumeAfterNewOrderDialog(IDialogContext context, IAwaitable<EmployeeOrder> result)  
  28.      {  
  29.          // Store the value that NewOrderDialog returned.   
  30.          // (At this point, new order dialog has finished and returned some value to use within the root dialog.)  
  31.          var resultFromNewOrder = await result;  
  32.   
  33.          switch (resultFromNewOrder.Service.Value)  
  34.          {  
  35.              case ServiceType.GetVacationBalance:  
  36.   
  37.                  // Your select Vacation Balance  
  38.                  // Go to Vacation Dialog  
  39.                  var _VacationDialog = MessagesController.MakeVacationDialog();  
  40.                  await context.Forward(_VacationDialog, ResumeAfterVacationBalanceDialog, null, CancellationToken.None);  
  41.   
  42.                  break;  
  43.                  case ServiceType.LeaveRequest:  
  44.   
  45.                  await context.PostAsync($"This Service is Not Yet Available!");  
  46.   
  47.                  PromptDialog.Confirm(  
  48.                                  context,  
  49.                                  AfterConfirmAsync,  
  50.                                  "Do you need any other service?",  
  51.                                  "Didn't get that!",  
  52.                                  promptStyle: PromptStyle.Keyboard);  
  53.                  break;  
  54.   
  55.          }  
  56.   
  57.   
  58.      }  
  59.   
  60.      private async Task ResumeAfterVacationBalanceDialog(IDialogContext context, IAwaitable<Vacation> result)  
  61.      {  
  62.          var resultFromVacation = await result;  
  63.   
  64.          // wating till get employee vacation balance from database.  
  65.          var _msgWait = context.MakeMessage();  
  66.          _msgWait.Type = ActivityTypes.Typing;  
  67.          _msgWait.InputHint = InputHints.IgnoringInput;  
  68.   
  69.          await context.PostAsync(_msgWait);  
  70.   
  71.   
  72.          // create new Data Context object from EmployeeContext Class  
  73.          EmployeeContext db = new EmployeeContext();  
  74.          var employee = await db.Employees.FindAsync(resultFromVacation.EmployeeId.Value);  
  75.   
  76.          // check if the user exist  
  77.          if (employee != null)  
  78.          {  
  79.              var _msg = context.MakeMessage();  
  80.   
  81.              //To create an Adaptive Card using .NET, install the Microsoft.AdaptiveCards NuGet package.   
  82.              AdaptiveCard card = new AdaptiveCard();  
  83.              // Add text to the card.  
  84.              card.Body.Add(new TextBlock()  
  85.              {  
  86.                  Text = "Your Vacation Balance is:",  
  87.                  Size = TextSize.Large,  
  88.                  Weight = TextWeight.Bolder  
  89.   
  90.              });  
  91.              // Add text to the card.  
  92.              card.Body.Add(new TextBlock()  
  93.              {  
  94.                  Text = $"{employee.VacationBalance.ToString("G2")} Days",  
  95.                  Weight = TextWeight.Bolder  
  96.              });  
  97.   
  98.              // Create the attachment.  
  99.              Attachment attachment = new Attachment()  
  100.              {  
  101.                  ContentType = AdaptiveCard.ContentType,  
  102.                  Content = card  
  103.              };  
  104.              _msg.Attachments.Add(attachment);  
  105.   
  106.              await context.PostAsync(_msg);  
  107.          }  
  108.          else  
  109.          {  
  110.              await context.PostAsync($"There is no employee with this #: [{resultFromVacation.EmployeeId}].");  
  111.          }  
  112.   
  113.          
  114.   
  115.          PromptDialog.Confirm(  
  116.              context,  
  117.              AfterConfirmAsync,  
  118.              "Do you need any other service?",  
  119.              "Didn't get that!",  
  120.              promptStyle: PromptStyle.Keyboard);  
  121.      }  
  122.   
  123.      private async Task AfterConfirmAsync(IDialogContext context, IAwaitable<bool> result)  
  124.      {  
  125.   
  126.          var confirm = await result;  
  127.          if (confirm)  
  128.          {  
  129.              // Go to Employee Dialog  
  130.              var _employeeServiceDialog = MessagesController.MakeEmployeeDialog();  
  131.              await context.Forward(_employeeServiceDialog, this.ResumeAfterNewOrderDialog, null, CancellationToken.None);  
  132.               
  133.          }  
  134.          else  
  135.          {  
  136.              await context.PostAsync("Thanks. Goodbye.");  
  137.              context.EndConversation("");  
  138.          }  
  139.      }  

Now, we need to test our bot, build the solution, open the bot file [filename.bot], and modify the endpoint and then click Save.

Create your own Azure Chat Bot

 

From debug, click start debugging or press F5.

Next, open the Bot emulator. On the welcome screen, click on "Open bot".

Create your own Azure Chat Bot

In open dialog, find the bot file [fileName.bot] which will be located in the same project files.

Create your own Azure Chat Bot

Create your own Azure Chat Bot

Now, the bot is ready to test. We need to type any message to start the chatting.

Create your own Azure Chat Bot

Next, we need to deploy the bot to Azure. Right-click on the project and select "Publish".

Create your own Azure Chat Bot

 

Select "Create new" then click "Publish".

Create your own Azure Chat Bot

In the "Create App Service" dialog, fill the app name, subscription, resource group, and hosting plan and then click on the "Create" button.

Create your own Azure Chat Bot

 

After deploying process is completed, open https://portal.azure.com, open resource groups, HRBot, and verify you find the app service

Create your own Azure Chat Bot

From the left menu create on create a resource.

Create your own Azure Chat Bot

 

From AI + Machine Learning select Bot Channels Registration then click create.

Create your own Azure Chat Bot

 

In Bot Channels Registration dialog fill in all required fields, for messaging endpoint type the app service URL  “https://appservise_url/api/messages” then click create.

Create your own Azure Chat Bot

 

Next, we need to get app id and password, go to Bot Channels Registration and open it, go to settings

Create your own Azure Chat Bot

Then click on Microsoft App ID (Manage) link, click on generate new password then copy it.

Create your own Azure Chat Bot

 

B=Go back to Bot Channels Registration settings and copy app id. Then Click save.

New open bot app service, go to application settings, under Application settings add the following keys,

Create your own Azure Chat Bot

 

Under Connection strings add the connections string then click save.

Create your own Azure Chat Bot

 

Back to Bot Channels Registration, click on Test on Web Chat,

Create your own Azure Chat Bot

 

Now we need to add a new channel, click on channels, then click on Skype,

Create your own Azure Chat Bot

 

Fill in the required fields and then click save. Now click on the Skype icon,

Create your own Azure Chat Bot

Create your own Azure Chat Bot

 

Click add to contacts to open on Skype.

Create your own Azure Chat Bot