# Sunday, 23 September 2018

The Microsoft Bot Framework makes it easier to create a chatbot. But a chatbot is only good if your users have a way of calling it. Microsoft bots can be accessed via a number of channels, including Facebook Messenger, Microsoft Teams, Skype, Slack, and Twilio.

Bot Settings

Once you have deployed a bot to Azure, you can view its properties in the Azure Portal, as shown in Fig. 1.

Fig01-BotProperties
Fig. 1

Click "Settings" to display the "Settings" blade, as shown in Fig. 2.

Fig02-BotSettingsBlade
Fig. 2

You will need the "Microsoft App ID" value (Fig. 3)

Fig03-MicrosoftAppId
Fig. 3

Copy this value and save it somewhere, such as in a text file. You will need it later.

Bot Channel

Next, create a Channel for your bot. To do this, do the following:

Click "Channels" to display the "Connect to Channels" blade, as shown in Fig. 4.

Fig04-ChannelsBlade
Fig. 4

Click the "Configure Direct Line Channel" icon (Fig. 5) to display the "Configure Direct Line" dialog (Fig. 6)

Fig05-DirectLineChannelIcon
Fig. 5

Fig06-ConfigureDirectLine
Fig. 6

The Secret Keys are hidden by default. Click the "Show" link next to one of them to display this key, as shown in Fig. 7

Fig07-ShowSecretKey
Fig. 7

Copy this value and save it somewhere, such as in a text file. You will need it later.

Click the [Done] button to close the "Configure Direct Line Channel" dialog.

Create Web Page

Now, you are ready to create a web page to allow users to use your chatbot.

The chat functionality is exposed through web services; but you can simplify calling these by using the Web Chat control. The source code for this open source project is here; but you don't need the source code unless you plan to modify or extend it.

Instead, you can link to the JavaScript file from your HTML with the following tag:

<script src="https://cdn.botframework.com/botframework-webchat/latest/botchat.js"></script>
  

Add a div to your web page with the id "mybot", as shown below

<div id="mybot"></div>

Then, add the following JavaScript to configure the WebChat client:

<script>
	BotChat.App({
		'directLine': { 'secret': 'DirectLineSecretKey' },
		'user': { id: 'UserId' },
		'bot': { id: 'MicrosoftAppId' },
		'resize': 'detect'
	}, document.getElementById("mybot"));
</script>
  

where:

  • DirectLineSecretKey is from one of the 'Secret Keys' fields of the Bot's Direct Line channel blade, that you copied earlier.
  • MicrosoftAppId is from the 'Microsoft App Id' field of the bot's 'Settings' blade, that you copied earlier.
  • UserId can be any string you like. These will display in the UI next to text submitted by the user.

The WebChat project also provides a stylesheet that you can use by adding the following tag within the <HEAD> tag:

<link href="https://cdn.botframework.com/botframework-webchat/latest/botchat.css" rel="stylesheet" />
  

Below is the full HTML and JavaScript with some dummy values for DirectLineSecretKey, user, and MicrosoftAppId.

<!DOCTYPE html>
<html>
<head>
    <title>Cubic Chatbot</title>
    <link href="https://cdn.botframework.com/botframework-webchat/latest/botchat.css" rel="stylesheet" />
</head>
<body>
    <div id="mybot"></div>
    <script src="https://cdn.botframework.com/botframework-webchat/latest/botchat.js"></script>
    <script>
        BotChat.App({
            'directLine': { 'secret': 'pdWb0xfE48M.wcA.dQI.YQgum240I2x9dVGc6S28u5Xik2Xt3A_TakzR24uGgjs' },
            'user': { id: 'Customer01' },
            'bot': { id: 'ac0438dc-a820-40fb-ae87-6448403ed1ad' },
            'resize': 'detect'
        }, document.getElementById("mybot"));
    </script>
</body>
</html>
  

In a browser, this page renders as shown in Fig. 8.

Fig08-BotClient
Fig. 8

Fig. 9 shows how it looks when you connect to a bot that echoes back what the user sends.

Fig09-BotClient
Fig. 9

If you want this control to be displayed within another web page, you can add an iframe to that other page, as below.

<iframe src="botclientpage.html"></iframe>
  

In this article, I showed you how to create a web page that communicates with a Microsoft Bot.

Sunday, 23 September 2018 18:25:43 (GMT Daylight Time, UTC+01:00)
# Tuesday, 18 September 2018

The Microsoft Bot framework provides the IBotDataStore interface as a mechanism for storing stateful data. When you create a new Bot in Visual Studio, your application is configured by default to store data in memory using the InMemoryDataStore class.

You can see this setup in the following line of the Application_Start() method of  Global.asax.cs :

var store = new InMemoryDataStore();
  

This is fine for testing, but memory is fragile and temporary; so, you will want a more persistent way to store stateful data in production. You can see this by running the app we created in this article.

If we run the bot described in that article, we can connect to it with the Bot Framework Emulator; then, stop and re-start the app and connect again, as shown in Fig. 1

Fig01-StartStopInMemory
Fig. 1

Notice that all the stateful information is reset after the app restarts, because the app memory is flushed.

We can modify the app so that it saves stateful data to something more persistent, like Azure Storage. To do this, we must first create a new Azure storage account.

In the Azure Portal, create a new Storage account (Fig. 2). If you have never created an Azure storage account, you can find instructions here.

Fig02-StorageAccount
Fig. 2

Once the account is created, open the "Access keys" blade, as shown in Fig. 3.

Fig03-StorageAccessKeys
Fig. 3

Copy either of the connection strings and save it. You will need to add it to your application.

In the Bot application, open the web.config file and paste the following anywhere directly inside the <configuration> tag.

<connectionStrings> 
 <add name="BotAzureStorage" connectionString="StorageConnectionString" /> 
</connectionStrings> 
  

where StorageConnectionString is the connection string you copied from the Azure portal.

Open the Global.asax.cs file and find the following line:

var store = new InMemoryDataStore();
  

Replace this line with the following code:

var azureStorageConnectionString 
  = System.Configuration.ConfigurationManager.ConnectionStrings["BotAzureStorage"].ConnectionString; 
var store = new TableBotDataStore(azureStorageConnectionString);
  

Now, compile and run the application.

Use the Bot Emulator to connect to it. Stateful information will now be saved to a Microsoft Azure Storage table named "botdata".

Notice that as you start and stop the app, the stateful data remains the same, as shown in Fig. 4.

Fig04-StartStopAzureTable
Fig. 4

In this article, I showed you how to save stateful data to an Azure Storage table.

You can find this code in the SavingStateToAzureDemo folder of the Bot-Framework-Demos on my GitHub page.  

Tuesday, 18 September 2018 09:34:00 (GMT Daylight Time, UTC+01:00)
# Friday, 14 September 2018

A chatbot provides an electronic exchange between a user and a computer. For example, each exchange might consist of a question from the user and an answer from the computer or a question from the computer and an answer from the user.

As with most interactions that take place across the Internet, a chatbot is, by default, stateless - meaning it remembers nothing from one exchange to the next.

Often, we would like to remember answers from one question to the next or even from one conversation to the next. If the bot asks a person's name, that name could be used to respond to a question asked later in the same conversation; or even in a different conversation.

This is why we implement State in our bots.

There are two key issues when managing state:

  • What is the scope of the data?
  • Where is stateful information stored?

In this article, we will focus on the first question and store all state data in memory.

What is the scope of the data?

The first question we ask ourselves is: When we save the data, when and where will it be seen?

We have 3 options, corresponding to 3 properties of the context (IDialogContext Interface)

  • ConversationData. Data stored here is available to anyone within the current conversation.
  • PrivateConversationData. Data stored here is available to the current user within the current conversation.
  • UserData. Data stored here is available to the current user in any conversation. This means he/she can come back the next day and the bot will remember his/her data.

Each of the 3 options above is a property of the IDialogContext interface. The context object, which is passed into the MessageReceivedAsync, implements this interface, so we can read and write to the appropriate storage by reading and writing to objects stored in context.

Below is a simple example that reads to and writes from the three different storage options.

private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
{
	var message = await result;
	var channelId = message.ChannelId;
	var conversationId = message.Conversation.Id;
	var userId = message.From.Id;

	var currentTime = DateTime.Now;

	DateTime firstLoginTimeThisConversationAnyUser = DateTime.MinValue;

	context.ConversationData.TryGetValue<DateTime>("FirstLoginTime", out firstLoginTimeThisConversationAnyUser);
	if (firstLoginTimeThisConversationAnyUser == System.DateTime.MinValue)
	{
		firstLoginTimeThisConversationAnyUser = System.DateTime.Now;
		context.ConversationData.SetValue<DateTime>("FirstLoginTime", firstLoginTimeThisConversationAnyUser);
	}

	DateTime firstLoginTimeEverForCurrentUser = DateTime.MinValue;
	context.UserData.TryGetValue<DateTime>("FirstLoginTime", out firstLoginTimeEverForCurrentUser);
	if (firstLoginTimeEverForCurrentUser == System.DateTime.MinValue)
	{
		firstLoginTimeEverForCurrentUser = currentTime;
		context.UserData.SetValue<DateTime>("FirstLoginTime", firstLoginTimeEverForCurrentUser);
	}

	DateTime firstLoginTimeCurrentConversationCurrentUser = DateTime.MinValue;
	context.PrivateConversationData.TryGetValue<DateTime>("FirstLoginTime", out firstLoginTimeCurrentConversationCurrentUser);
	if (firstLoginTimeCurrentConversationCurrentUser == System.DateTime.MinValue)
	{
		firstLoginTimeCurrentConversationCurrentUser = currentTime;
		context.PrivateConversationData.SetValue<DateTime>("FirstLoginTime", firstLoginTimeCurrentConversationCurrentUser);
	}

	var output = $"User: {userId}\nConversation: {conversationId}\nChannel: {channelId}\n\n";
	output += $"A user logged into this converstaion at {firstLoginTimeThisConversationAnyUser}.\n";
	output += $"You first logged into any conversation at {firstLoginTimeEverForCurrentUser}.\n";
	output += $"You first logged into this conversation at {firstLoginTimeCurrentConversationCurrentUser}.";
	await context.PostAsync(output);

	context.Wait(MessageReceivedAsync);
}
  

  Listing 1

Notice that we are checking each time to see if any new data is returned from a name-value pair ("FirstLoginTime"). If nothing is stored in a value, it will return DateTime.MinValue, which signifies an empty date. In this case, we set the value to the current time.

You can test this with the Bot Framework Emulator (available here and described here).

You can download a Visual Studio Solution that uses the code in Listing 1 from the SavingStateDemo of the Bot-Framework-Demos on my GitHub page.

Launch your bot from Visual Studio and connect to it with the Emulator. Type any message into the textbox and press [ENTER], as shown in Fig. 1.

Fig01-BotEmulator1
Fig. 1

You should see information about the user, channel, and conversation; along with the value just stored for the when users (including you) logged into this (or another) conversation. Notice all 3 values are the same because this is your first conversation and you are the first user in this conversation.

Again, type any message in the textbox and press [ENTER]. The values have not changed because they were set as stateful data last time (Fig. 2)

Fig02-BotEmulator2
Fig. 2

You can start a new conversation by clicking the ENPOINT on the left, opening a new tab. Type something into this tab's textbox and press [ENTER] (Fig. 3)

Fig03-BotEmulatorNewConversation
Fig. 3

Notice that the user is the same, but the Conversation ID is different.

Therefore, the bot updated the ConversationData and the PrivateConversationData values, but not the UserData value.

In this article, I showed you how to save stateful data from a conversation using the Microsoft Bot Framework.

Friday, 14 September 2018 09:42:00 (GMT Daylight Time, UTC+01:00)
# Wednesday, 12 September 2018

In the previous articles, I showed how to create a new chatbot using the Microsoft Bot Framework and I explained the relevant code in the sample chatbot you created.

In this article, I will show how to extend your bot by adding a new dialog.

Launch Visual Studio and create a new project based on the "Bot Builder Echo Bot", as shown in Fig. 1

Fig01-NewBotProject
Fig. 1

From the Visual Studio menu, select Build | Rebuild Solution.

In the Visual Studio Solution Explorer, right-click the "Dialogs" folder and select Add | Class from the context menu, as shown in Fig. 2.

Fig02-AddClassMenu
Fig. 2

A dialog displays, allowing you to name and add a new class, as shown in Fig. 4.

Fig03-AddClass
Fig. 3

Enter a name for this dialog class. I chose "TimeDialog.cs", because I plan to add code to display the current time. Click the [Add] button to create this class.

An editor with the default code in it displays. The default code is in Listing 1.

namespace MyBotWithDialog.Dialogs
{
    public class TimeDialog
    {
    }
}
  

Listing 1

Above the class declaration, add the [Serializable] tag.

After the class name, add the following to derive from the IDialog interface.

: IDialog<object>

The IDialog interface requires one method: StartAsync. Add this method as shown in Listing 2.

        public Task StartAsync(IDialogContext context)
        {
            context.Wait(MessageReceivedAsync);

            return Task.CompletedTask;
        }
  

Listing 2

Notice that StartAsync asynchronously calls MessageReceivedAsync, so you will have to add this method, as shown in Listing 3.

        private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<object> result)
        {
            var activity = await result as Activity;

            // Calculate something for us to return
            int length = (activity.Text ?? string.Empty).Length;

            // Return our reply to the user
            await context.PostAsync($"The time is now {System.DateTime.Now}!");

            context.Wait(MessageReceivedAsync);
        }
  

Listing 3

Note that the output sent back to the channel is a string containing the current time.

Finally, you will need to add using statements at the top to resolve any errors. Add the following to the top of the file.

using Microsoft.Bot.Builder.Dialogs;

using Microsoft.Bot.Connector;

Listing 4

When you are finished, the class should look like Listing 5 below.

using System;
using System.Threading.Tasks;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Connector;

namespace MyBotWithDialog.Dialogs
{
    [Serializable]
    public class RootDialog : IDialog<object>
    {
        public Task StartAsync(IDialogContext context)
        {
            context.Wait(MessageReceivedAsync);

            return Task.CompletedTask;
        }

        private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<object> result)
        {
            var activity = await result as Activity;

            // Calculate something for us to return
            int length = (activity.Text ?? string.Empty).Length;

            // Return our reply to the user
            await context.PostAsync($"The current time is {System.DateTime.Now}!");

            context.Wait(MessageReceivedAsync);
        }
    }
}
  

Listing 5

Next, modify the controller to point to your new Dialog. Open MessageController.cs and find the following line of code.

await Conversation.SendAsync(activity, () => new Dialogs.RootDialog());

Replace this line with the following:

await Conversation.SendAsync(activity, () => new Dialogs.TimeDialog());

Now, build and run your bot. When it loads, use the Bot Framework Emulator (available here and described here) to test it.

Connect to your Bot from the Emulator and enter any text in the "Type your message" textbox and press ENTER.

The bot should respond by displaying the current date and time, as shown in Fig. 3.

Fig04-BotFrameworkEmulator
Fig. 4

In this article, I showed how to create and use a new Dialog class to an Bot Builder Echo Bot project. You can find this code in the NewDialogDemo of the Bot-Framework-Demos on my GitHub page.

Wednesday, 12 September 2018 09:41:00 (GMT Daylight Time, UTC+01:00)
# Saturday, 08 September 2018

The Microsoft Bot Framework provides a template that creates a simple bot: The "Bot Builder Echo Bot". It is named this because it echoes back any text you send it, along with the length of that text.

The bot is simply an ASP.NET Web API application that exposes web services to Channel clients. As such, it uses the default routing for Web API applications of "api/controllername"

where controllername is the name of the Controller class with the word “Controller” removed.

A channel will submit an HTTP POST to a URL containing "api/message", which will call the Post method in the MessagesController class. Let's take a look at this class.

    [BotAuthentication]
    public class MessagesController : ApiController
    {
        /// <summary>
        /// POST: api/Messages
        /// Receive a message from a user and reply to it
        /// </summary>
        public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
        {
            if (activity.GetActivityType() == ActivityTypes.Message)
            {
                await Conversation.SendAsync(activity, () => new Dialogs.RootDialog());
            }
            else
            {
                HandleSystemMessage(activity);
            }
            var response = Request.CreateResponse(HttpStatusCode.OK);
            return response;
        }

        private Activity HandleSystemMessage(Activity message)
        {
            string messageType = message.GetActivityType();
            if (messageType == ActivityTypes.DeleteUserData)
            {
                // Implement user deletion here
                // If we handle user deletion, return a real message
            }
            else if (messageType == ActivityTypes.ConversationUpdate)
            {
                // Handle conversation state changes, like members being added and removed
                // Use Activity.MembersAdded and Activity.MembersRemoved and Activity.Action for info
                // Not available in all channels
            }
            else if (messageType == ActivityTypes.ContactRelationUpdate)
            {
                // Handle add/remove from contact lists
                // Activity.From + Activity.Action represent what happened
            }
            else if (messageType == ActivityTypes.Typing)
            {
                // Handle knowing that the user is typing
            }
            else if (messageType == ActivityTypes.Ping)
            {
            }

            return null;
        }
  

Listing 1

A channel posts an activity to the service. If the activity type is anything other than "Message", it calls the HandleSystemMessage method. Notice that nothing is actually implemented in this method. You will have to write this yourself.

However, if the activity type is "Message", the Post method asynchronously calls the Dialogs.RootDialog class. Here is that class:

    [Serializable]
    public class RootDialog : IDialog<object>
    {
        public Task StartAsync(IDialogContext context)
        {
            context.Wait(MessageReceivedAsync);

            return Task.CompletedTask;
        }

        private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<object> result)
        {
            var activity = await result as Activity;

            // Calculate something for us to return
            int length = (activity.Text ?? string.Empty).Length;

            // Return our reply to the user
            await context.PostAsync($"You sent {activity.Text} which was {length} characters");

            context.Wait(MessageReceivedAsync);
        }
    }
  

Listing 2

The StartAsync method is called first, which waits for a message to be completely received; then, calls the MessageReceivedAsync method.

This method reads the text of the activity and forms a string that contains the original message text and the length of that text. It then Posts this back to the channel with the line below:

await context.PostAsync($"You sent {activity.Text} which was {length} characters");

Finally, it waits for the next message to come in via the following line

context.Wait(MessageReceivedAsync);

The rest of this project is Web API plumbing, setting up things like routing and where to store state information.

As you can see, this is a fairly simple architecture built on an established framework (Web API). This makes it easier to understand and to modify.

This simple bot is a good starting place that demonstrates the structure of a bot. You can modify this dialog, add new dialogs, or modify the logic as suits your purposes.

Saturday, 08 September 2018 09:15:00 (GMT Daylight Time, UTC+01:00)
# Friday, 07 September 2018

Microsoft Visual Studio makes it very simple to create a new bot with the Microsoft Bot Framework.

Launch Visual Studio 2017 (You can download a free version here)

From the menu, select File | New | Project.

The "New Project" dialog displays, as shown in Fig. 1.

Fig01-NewProjectDialog
Fig. 1

Create a new "Bot Builder Echo Bot" project. From this dialog, you find this template by either expanding Visual C# | Bot Framework in the navigation tree on the left; or by entering "Bot Builder" in the search box at the top right.

Enter a name and location for your project and click the [OK] button.

When the project loads, select Build | Rebuild Solution from the menu to compile the solution and validate all references.

This simple bot receives a message and echoes back the same message, along with the length of that message. The relevant code is in the MessageReceivedAsync method of the RootDialog class, which is shown in Listing 1.

private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<object> result)
{
  var activity = await result as Activity;

  // Calculate something for us to return
  int length = (activity.Text ?? string.Empty).Length;

  // Return our reply to the user
  await context.PostAsync($"You sent {activity.Text} which was {length} characters");

  context.Wait(MessageReceivedAsync);
}
  

Listing 1

After the solution is rebuilt, select Debug | Start Debugging from the menu to launch the bot. This will host a web service and a web page on your local machine. The web page will display in your browser, as shown in Fig. 2.

Fig02-BotRunning
Fig. 2

Note the URL of this page, which will look something like

http://localhost:nnnn/

where nnnn is the port number on which this web application is running.

You can call the bot's web service from many sources; but the easiest way to test it is with the Bot Framework emulator. You can find detailed information on this emulator here. You can download the latest version of the emulator from here, as shown in Fig. 3.

Fig03-DownloadBotFramework
Fig. 3

Download and run the most recent EXE file from this site to install the emulator on your local PC.

Launch the emulator to view the form shown in Fig. 4.

Fig04-BotFrameworkEmulator
Fig. 4

Click the [Open Bot] button on the "Welcome" tab of the emulator. A JSON file containing configuration about your bot was created for you and saved in the Visual Studio project folder. Its root name will be the same as the project, but it will have a ".bot" extension. Select this file and click the [Choose file] button, as shown in Fig. 5.

Fig05-OpenBotConfiguration
Fig. 5

The format of this file looks like the sample in Listing 1.

{
  "name": "MyBot",
  "secretKey": "",
  "services": [
    {
      "appId": "",
      "id": "http://localhost:3978/api/messages",
      "type": "endpoint",
      "appPassword": "",
      "endpoint": "http://localhost:3978/api/messages",
      "name": "MyBot"
    }
  ]
}
  

Listing 2

NOTE: When you return to the emulator, you can click the [Open Bot] button or click a shortcut link below the button to re-load the configuration.

After you save (or open) a configuration file, a "Live Chat" tab displays in the emulator, as shown in Fig. 6

Fig06-BotEmulatorRunning
Fig. 6

To test the bot, type a message into the "Type your message" textbox and press [ENTER]. Your message will display. A short time later, a response will display with your message, followed by the number of characters.

You can find this code in the SimpleBotDemo project of the Bot-Framework-Demos on my GitHub page.

In future articles, I will show you how to enhance your bot, deploy it to a public site, such as Azure, and call it from a variety of clients. But this is the simplest way to create, run, and test a bot.

Friday, 07 September 2018 09:05:00 (GMT Daylight Time, UTC+01:00)
# Wednesday, 05 September 2018

The Bots are taking over.

A chatbot is an automated process that can respond to questions or commands via voice or text. They are useful for simulating a conversation and handling some of the tasks that would ordinarily require a call center staffed with people. Uses include processing orders, checking status, and answering questions. If you can understand the question and figure out the answer, you can probably write a chatbot to handle it.

Advantages of Chatbots

Chatbots have some advantages over human interactions.

Operating Cost. Labor costs tend to be among the highest cost of any business and operators in a call center can be expensive. Once deployed, a chatbot's cost tends to be a fraction of the cost of paying a person.

Availability. Chatbots can scale up to increase demand, so that users, customers, and potential customers do not need to wait for the next available operator. If activity rises unexpectedly, it is far easier and faster to deploy new resources to support a chatbot than it is to bring in more people to answer calls.

Speed. A computer can often look up information much faster than a human can.

Flexibility. A chatbot can be wired up to a variety of communication channels, allowing you to use the same code base to connect to different clients in different ways. For example, you can write a chatbot and connect to users via Facebook, SMS, a web page, or any number of other platforms.

Disadvantages of Chatbots

Of course, chatbots will not solve all your problems. Here are some disadvantages.

Startup cost. There tends to be a larger startup costs for chatbots. They must be programmed, tested, and deployed. This cost is only justified if they will yield sufficient savings over the lifetime the chatbot is deployed. Tools like the Microsoft Bot Framework can reduce development time; but that early cost still exists.

Impersonal. Chatbots are not people and some customers prefer talking to a human being over talking to a machine. The cost of human interaction is worth it when you wish to cultivate a personal relationship with your customer or partner. 

Too human. With advances in natural language processing, it can be difficult for people to determine whether they are interacting with a person or a computer. Some people are turned off by this ambiguity. They feel cheated when a computer represents itself as a person.

Real-time flexibility. For many interactions, it is impossible to anticipate every potential question or command from your customers. Humans can react to these very well. Generally, you need to program a chatbot to anticipate each question or command.

Finally

There is no question that chatbots are becoming more and more important as companies interact with their customers. But how your company uses them can determine how successful your chatbot strategy is.

Some scenarios call for starting an interaction with a chatbot; then bringing in a person only if the chatbot cannot adequately help the customer.

Understanding the needs of your customer and the problem you are trying to solve is a key to effective use of chatbots.

Wednesday, 05 September 2018 09:02:00 (GMT Daylight Time, UTC+01:00)