7/29/2018 Webmaster
Calling The Microsoft Bot Framework Using The Direct Line API (MS Bot Framework V4 Preview Edition)
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.
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
- Visual Studio 2017 (or higher) with the following workloads:
- ASP.NET and web development
- Azure development
- The code from the article: Creating a Hello World! Bot (MS Bot Framework V4 Preview Edition) (it is on the Downloads page of this site)
- Bot Framework Emulator (download the latest version even if it is “Alpha”)
- A Microsoft Azure Subscription
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 the Microsoft 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:
- Create a Direct Line Channel in the Bot Channels Registration for the Bot
- 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).
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.
Click on Channels then the Direct Line channel icon.
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.
Direct Line will show in the list of the configured channels for the Bot.
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.
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 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
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 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):
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
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