10/9/2016 Webmaster
Calling The Microsoft Bot Framework Using The Direct Line API
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 a HoloLens.
The procedure for working with the API is:
- Register your Bot with the Microsoft Bot Connector
- Configure the Direct Line Connector
- Use the credentials obtained from the Bot Framework developer portal 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).
Note, the rendering of the output will be the responsibility of the developer of the custom application that is calling the Direct Line API.
Media such a images, cards, and buttons will require custom code to render in a manner that is appropriate for the particular application.
The example application we will build, will create a custom client that will allow a user to create an account, sign-in, and securely communicate with the same Bot that was deployed in the article: Creating a Skype Bot Using The Microsoft Bot Framework and updated and enhanced in the article: Implementing Language Understanding Intelligent Service (LUIS) In Microsoft Bot Framework.
Configuring The Direct Line Connector
We want to configure the Direct Line connector for our Bot.
Go to: https://dev.botframework.com/, log in, and select My Bots.
Open a Bot that has been deployed (using the directions in the article: Creating a Skype Bot Using The Microsoft Bot Framework and further enhanced in the article: Implementing Language Understanding Intelligent Service (LUIS) In Microsoft Bot Framework).
The first step is to make a note of the Bot handle you gave your Bot. You will need this later when you create the Web Application.
Under Add another channel, click the Add button next to Direct Line.
When the Configure Direct Line screen appears, click the Generate Direct Line secret button.
Copy the Secret code. You will need this later when you create the Web Application.
Click the I’m done configuring Direct Line button.
The screen will close.
Create The Web Application
Open Visual Studio.
From the toolbar in Visual Studio, select File, then New, then Project.
Select Web, then ASP.NET Web Application (.Net Framework).
Enter DirectLineBot for the Name.
Select the Create directory for solution box.
Press OK.
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.
The application will be created.
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.
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.
Click Ok when the Preview window shows.
Click the I Accept button when the License Acceptance window appears.
The Microsoft.Bot.Connector.DirectLine assembly will be installed.
Hit F5 to debug and run the application.
The application will open in the web browser.
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
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>
Open the HomeController.cs file (in the Controllers folder), and replace all the code with the following code:
using Microsoft.Bot.Connector.DirectLine; using Microsoft.Bot.Connector.DirectLine.Models; 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 = client.Conversations.NewConversation(); } // Use the text passed to the method (by the user) // to create a new message Message message = new Message { FromProperty = User.Identity.Name, Text = paramMessage }; // Post the message to the Bot await client.Conversations.PostMessageAsync(conversation.ConversationId, message); // 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) { // 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) { // Get any messages related to the conversation since the last watermark var messages = await client.Conversations.GetMessagesAsync(conversationId, watermark); // Set the watermark to the message received watermark = messages?.Watermark; // Get all the messages var messagesFromBotText = from message in messages.Messages where message.FromProperty == botId select message; // Loop through each message foreach (Message message in messagesFromBotText) { // We have Text if (message.Text != null) { // Set the text response // to the message text objChat.ChatResponse += " " + message.Text.Replace("\n\n", "<br />"); } // We have an Image if (message.Images.Count > 0) { // Set the text response as an HTML link // to the image objChat.ChatResponse += " " + RenderImageHTML(message.Images[0]); } } // 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
When there is an image that is returned by the Bot, the ReadBotMessagesAsync method calls the RenderImageHTML method.
To implement it, add the following method to the HomeController class:
#region private static string RenderImageHTML(string ImageLocation) private static string RenderImageHTML(string ImageLocation) { // Construct a URL to the image string strReturnHTML = String.Format(@"<img src='{0}/{1}'><br />", DiretlineUrl, ImageLocation); return strReturnHTML; } #endregion
Run The Application
Hit F5 to run the application.
The application will open in the web browser. Initially we are not logged in so we will be unable to communicate with the Bot.
Click the Register button to create an account.
Fill in the required information and click the Register button.
After you have created an account, you can click the Log in button to log in (if you are not already logged in).
You will know you are logged in when you see your email address in the menu bar and on the Home page.
You can now communicate with the Bot and run the same code that was created and deployed in the article: Implementing Language Understanding Intelligent Service (LUIS) In Microsoft Bot Framework.
When we look at the data in the database on Azure (see: Implementing A SQL Server Database With The Microsoft Bot Framework to see how this is configured and deployed), we see that the UserID, and UserName, for messages posted to the Bot, are completely under the control of the following custom code:
// Use the text passed to the method (by the user) // to create a new message Message message = new Message { FromProperty = User.Identity.Name, Text = paramMessage }; // Post the message to the Bot await client.Conversations.PostMessageAsync(conversation.ConversationId, message);
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.
Microsoft Links
Bot Framework Forum (stack overflow)
Download
You can download the code from the Download page