7/29/2018 Webmaster

Calling The Microsoft Bot Framework Using The Direct Line API (MS Bot Framework V4 Preview Edition)


image

The Microsoft Bot Framework V4 allows you to create intelligent bots that interact naturally wherever your users are (text/SMS to Skype, Slack, Office 365 mail and other popular services). In preview now, the Bot Builder V4 Preview SDK offers new features and is extensible with a pluggable middleware model.

image

You may need to call your Microsoft Bot Framework Bot directly from a custom application, a service, or a website. The Microsoft Bot Connector Direct Line REST API allows you to do this. In addition, it allows you to authenticate a user in your application, and securely communicate with the Bot as that user.

The Direct Line API exposes a REST API that allows you to communicate with a single Bot that has been registered with the Microsoft Bot Connector Service. This API is intended for developers who want to communicate with their Bot from their own client applications, such as mobile apps, a service, or even an Amazon Alexa.


Requirements

Sample

We will start with the code from: Creating a Hello World! Bot (MS Bot Framework V4 Preview Edition) (it is on the Downloads page of this site).

We will enable it to work with theMicrosoft Bot Connector Direct Line REST API.

Configuring The Direct Line Connector

We want to configure the Direct Line connector for our Bot.

The procedure for working with the Direct Line API is:

  1. Create a Direct Line Channel in the Bot Channels Registration for the Bot
  2. Use the secret key obtained from Direct Line Channel registration to make REST based calls to communicate with the Bot (in our example, we will use the Microsoft.Bot.Connector.DirectLine Nuget package to help us make the calls).

image

Go to https://portal.azure.com and log in.

Locate the Bot Channels Registration created in following the tutorial: Creating a Hello World! Bot (MS Bot Framework V4 Preview Edition).

Click on it.

image

Click on Channels then the Direct Line channel icon.

image

When the Configure Direct Line page appears, click the show link to display the secret key.

Copy the key and save it, you will need it later.

Ensure 3.0 is selected and click the Done button.

image

Direct Line will show in the list of the configured channels for the Bot.

image

Click on the Settings tab.

Copy the Bot handle (this is your BotID).

Copy the name and save it, you will need it later.

Create The Project

Open Visual Studio.

image

From the toolbar in Visual Studio, select File, then New, then Project.

image

Select Web, then ASP.NET Web Application (.Net Framework).

Enter DirectLineBot for the Name.

Select the Create directory for solution box.

Press OK.

image

When the application configuration box appears, select the MVC template.

Ensure that Individual User Accounts is selected for Authentication (if not, click the Change Authentication button and change it).

Press OK.

image

The application will be created.

image

We need to add the Microsoft.Bot.Connector.DirectLine Nuget package that will allow us to easily communicate with the DirectLine API.

In the Solution Explorer, right-click on the DirectLineBot project node (not the Solution node), and select Manage Nuget Packages.

image

When the Nuget Packages configuration window appears…

Click the Browse button.

Enter Microsoft.Bot.Connector.DirectLine in the search box to conduct the search.

When the Microsoft.Bot.Connector.DirectLine package shows up, click on it (so that it’s properties appears in the window on the right).

Click the Install button to install the package.

image

Click Ok when the Preview window shows.

image

Click the I Accept button when the License Acceptance window appears.

image

The Microsoft.Bot.Connector.DirectLine assembly will be installed.

image

Hit F5 to debug and run the application.

The application will open in the web browser.

image

You will see that the default web application, created by the MVC template, contains an About and a Contact page. We can stop the application (by closing the web browser), and remove the code for these pages because we don’t need them.

If you don’t know how to do that, you can leave them in the application ( note: You can download the completed application from the downloads page on this site).

What we do care about is the ability to click the Register button to create a new account.

We can also click the Log in button to log in using a registered account.

Complete The Web Application

image

We will update the home page to show the chat box and the Bot response only if the user has created an account and logged in.

Open the Index.cshtml file (in the Views/Home folder), and replace all the code with the following code:

  @model DirectLine.Controllers.Chat <h2>Direct Line Bot Example</h2> @using (Html.BeginForm("Index", "Home", FormMethod.Post)) {     <p>         Hello: @((User.Identity.IsAuthenticated == true)          ? User.Identity.Name          : "[Unknown]")     </p>     @Html.TextBoxFor(m => m.ChatMessage,     new { style = "width:600px" })     <input type="submit" value="Send" /> } <br /> <p>@Html.Raw(Model.ChatResponse)</p>
							

image

Open the HomeController.cs file (in the Controllers folder), and replace all the code with the following code:

      using Microsoft.Bot.Connector.DirectLine;     using Newtonsoft.Json;     using System;     using System.Linq;     using System.Threading.Tasks;     using System.Web.Mvc;     namespace DirectLine.Controllers     {         #region public class Chat         public class Chat         {             public string ChatMessage { get; set; }             public string ChatResponse { get; set; }             public string watermark { get; set; }         }         #endregion         public class HomeController : Controller         {             private static string DiretlineUrl                 = @"https://directline.botframework.com";             private static string directLineSecret =                 "** INSERT YOUR SECRET CODE HERE **";             private static string botId =                 "** INSERT YOUR BOTID HERE **";             #region public async Task<ActionResult> Index()             public async Task<ActionResult> Index()             {                 // Create an Instance of the Chat object                 Chat objChat = new Chat();                 // Only call Bot if logged in                 if (User.Identity.IsAuthenticated)                 {                     // Pass the message to the Bot                      // and get the response                     objChat = await TalkToTheBot("Hello");                 }                 else                 {                     objChat.ChatResponse = "Must be logged in";                 }                 // Return response                 return View(objChat);             }             #endregion         }     }
							

At this point the code is not complete, however, it sets up the basic framework.

Remember to replace, ** INSERT YOUR SECRET CODE HERE ** and ** INSERT YOUR BOTID HERE ** with the values from you own published Bot.

When a logged in user loads the page, or submits text to the Bot, the TalkToTheBot method is called.

To implement it, add the following method to the HomeController class:

								#region private async Task<Chat> TalkToTheBot(string paramMessage)         private async Task<Chat> TalkToTheBot(string paramMessage)         {             // Connect to the DirectLine service             DirectLineClient client = new DirectLineClient(directLineSecret);             // Try to get the existing Conversation             Conversation conversation =                 System.Web.HttpContext.Current.Session["conversation"] as Conversation;             // Try to get an existing watermark              // the watermark marks the last message we received             string watermark =                 System.Web.HttpContext.Current.Session["watermark"] as string;             if (conversation == null)             {                 // There is no existing conversation                 // start a new one                 conversation = await client.Conversations.StartConversationAsync();             }             // Use the text passed to the method (by the user)             // to create a new message             Activity userMessage = new Activity             {                 From = new ChannelAccount(User.Identity.Name),                 Text = paramMessage,                 Type = ActivityTypes.Message             };             // Post the message to the Bot             await client.Conversations.PostActivityAsync(conversation.ConversationId, userMessage);             // Get the response as a Chat object             Chat objChat =                 await ReadBotMessagesAsync(client, conversation.ConversationId, watermark);             // Save values             System.Web.HttpContext.Current.Session["conversation"] = conversation;             System.Web.HttpContext.Current.Session["watermark"] = objChat.watermark;             // Return the response as a Chat object             return objChat;         }         #endregion
							

The TalkToTheBot method calls the ReadBotMessagesAsync method to read the response from the Bot.

To implement it, add the following method to the HomeController class:

								#region private async Task<Chat> ReadBotMessagesAsync(DirectLineClient client, string conversationId, string watermark)         private async Task<Chat> ReadBotMessagesAsync(             DirectLineClient client, string conversationId, string watermark)         {             // Create an Instance of the Chat object             Chat objChat = new Chat();             // We want to keep waiting until a message is received             bool messageReceived = false;             while (!messageReceived)             {                 // Retrieve the activity set from the bot.                 var activitySet = await client.Conversations.GetActivitiesAsync(conversationId, watermark);                 // Set the watermark to the message received                 watermark = activitySet?.Watermark;                 // Extract the activies sent from our bot.                 var activities = (from Activity in activitySet.Activities                                   where Activity.From.Id == botId                                   select Activity).ToList();                 // Analyze each activity in the activity set.                 foreach (Activity activity in activities)                 {                     // Set the text response                     // to the message text                     objChat.ChatResponse                         += " "                         + activity.Text.Replace("\n\n", "<br />");                     // Are there any attachments?                     if (activity.Attachments != null)                     {                         // Extract each attachment from the activity.                         foreach (Attachment attachment in activity.Attachments)                         {                             switch (attachment.ContentType)                             {                                 case "image/png":                                     // Set the text response as an HTML link                                     // to the image                                     objChat.ChatResponse                                         += " "                                         + attachment.ContentUrl;                                     break;                             }                         }                     }                 }                 // Mark messageReceived so we can break                  // out of the loop                 messageReceived = true;             }             // Set watermark on the Chat object that will be              // returned             objChat.watermark = watermark;             // Return a response as a Chat object             return objChat;         }         #endregion
							

We also need the following method to call the code when the user enters text and clicks the Submit button:

								#region public async Task<ActionResult> Index(Chat model)         [HttpPost]         public async Task<ActionResult> Index(Chat model)         {             // Create an Instance of the Chat object             Chat objChat = new Chat();             // Only call Bot if logged in             if (User.Identity.IsAuthenticated)             {                 // Pass the message to the Bot                  // and get the response                 objChat = await TalkToTheBot(model.ChatMessage);             }             else             {                 objChat.ChatResponse = "Must be logged in";             }             // Return response             return View(objChat);         }         #endregion
							

Run The Project

image

Hit F5 to run the application.

image

The application will open in the web browser. Initially we are not logged in so we will be unable to communicate with the Bot.

image

Click the Register button to create an account.

image

Fill in the required information and click the Register button.

image

After you have created an account, you can click the Log in button to log in (if you are not already logged in).

image

You will know you are logged in when you see your email address in the menu bar and on the Homepage.

You can now communicate with the Bot and run the same code that was created and deployed in the article: Creating a Hello World! Bot (MS Bot Framework V4 Preview Edition):

image

image

image

This demonstrates that we are able to authenticate users using our own custom code, and have them communicate with the Bot securely, when using the Direct Line API.

Links

How to create a Direct Line bot and client

Connect a bot to Direct Line

alexa-bridge

Azure Bot Service Documentation for the v4 SDK

Conversational AI: Best Practices for Building Bots

Find Your Azure Bot’s AppID and AppSecret

Download

You can download the code from the Download page

An error has occurred. This application may no longer respond until reloaded. Reload 🗙