Creating a Hello World! Bot Using The Microsoft Bot Framework

Jul 9

Written by:
7/9/2016 4:21 PM  RssIcon

Note: This article has been updated to Microsoft Bot Framework version 3.0

image

The Microsoft Bot Framework allows you to easily create bots.

image

You can create bots that interact with your users naturally wherever they are, including Facebook, text, Skype, Office 365 email mail, and other popular services.

image

The Microsoft Bot Framework contains the following components:

  • Bot Connector – A service that connects your bot to communication channels such as Facebook, Skype, and email.
  • Bot Builder – A C# and Node.js library that provides a powerful framework for constructing bots that can handle freeform and guided interactions.
  • Bot Directory – A directory of Bots that you can connect to.

image

The Bot Connector helps you connect your Bot to communication channels. You can write a Bot and expose the Microsoft Bot Framework-compatible API on the internet.

The Bot  Connector will forward messages to users, and will send the user messages back to your Bot.

image

The Bot Builder SDK is an open source SDK hosted on GitHub that provides everything you need to build dialogs. This library was created by bot developers at Microsoft to encapsulate functionality required for conversational bots.

 

Creating A Hello World! Bot

image

Download the Visual Studio 2015 template (using this link)

Save the .zip file in the templates directory (located at: %USERPROFILE%\Documents\Visual Studio 2015\Templates\ProjectTemplates\Visual C# ).

This creates a template that you can use in Visual Studio to create Bot projects.

image

Open Visual Studio.

image

Create a new Project.

image

Select the Bot Application template and name the project HelloWorldBot.

image

Open the MessagesController.cs file in the Controllers folder.

Change the Post method to the following:

 

    public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
    {
        if (activity.Type == ActivityTypes.Message)
        {
            ConnectorClient connector = new ConnectorClient(new Uri(activity.ServiceUrl));
            // calculate something for us to return
            int length = (activity.Text ?? string.Empty).Length;
            // return our reply to the user
            Activity reply = activity.CreateReply($"Hello World! You sent {length} characters");
            await connector.Conversations.ReplyToActivityAsync(reply);
        }
        else
        {
            HandleSystemMessage(activity);
        }
        var response = Request.CreateResponse(HttpStatusCode.OK);
        return response;
    }

 

image

Hot F5 to run the project.

image

Note the web address.

you will need it in the next step.

Using The Bot Emulator

image

Download, install, and run the Bot Framework Emulator (Windows) (also see: Mac and Linux support using command line emulator if you don’t have Windows).

When the emulator starts, connect to to Bot by setting the address to the the one indicted in the web browser (however, add /api/messages to the end).

image

In the Bot Emulator, enter Hello in the text box and click the send key (or press enter).

You will see the response in the Chat window and the JSON contents of the response in the JSON window.

Saving User Data

An Important part of any conversation is remembering what a user has previously said.

We can do this using GetPrivateConversationData and SetPrivateConversationData.

To demonstrate how this is handled, add the following to the top of the MessagesController.cs file in the Controllers folder:

using System.Text;

Next, change the Post method in the MessagesController.cs file to the following:

 

   public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
    {
        // Global values
        bool boolAskedForUserName = false;
        string strUserName = "";
        if (activity.Type == ActivityTypes.Message)
        {
            // Get any saved values
            StateClient sc = activity.GetStateClient();
            BotData userData = sc.BotState.GetPrivateConversationData(
                activity.ChannelId, activity.Conversation.Id, activity.From.Id);
            boolAskedForUserName = userData.GetProperty<bool>("AskedForUserName");
            strUserName = userData.GetProperty<string>("UserName") ?? "";
            // Create text for a reply message   
            StringBuilder strReplyMessage = new StringBuilder();
            if (boolAskedForUserName == false) // Never asked for name
            {
                strReplyMessage.Append($"Hello, I am **AIHelpWebsite.com** Bot");
                strReplyMessage.Append($"\n");
                strReplyMessage.Append($"You can say anything");
                strReplyMessage.Append($"\n");
                strReplyMessage.Append($"to me and I will repeat it back");
                strReplyMessage.Append($"\n\n");
                strReplyMessage.Append($"What is your name?");
                // Set BotUserData
                userData.SetProperty<bool>("AskedForUserName", true);
            }
            else // Have asked for name
            {
                if (strUserName == "") // Name was never provided
                {
                    // If we have asked for a username but it has not been set
                    // the current response is the user name
                    strReplyMessage.Append($"Hello {activity.Text}!");
                    // Set BotUserData
                    userData.SetProperty<string>("UserName", activity.Text);
                }
                else // Name was provided
                {
                    strReplyMessage.Append($"{strUserName}, You said: {activity.Text}");
                }
            }
            // Save BotUserData
            sc.BotState.SetPrivateConversationData(
                activity.ChannelId, activity.Conversation.Id, activity.From.Id, userData);
            // Create a reply message
            ConnectorClient connector = new ConnectorClient(new Uri(activity.ServiceUrl));
            Activity replyMessage = activity.CreateReply(strReplyMessage.ToString());
            await connector.Conversations.ReplyToActivityAsync(replyMessage);
        }
        else
        {
            Activity replyMessage = HandleSystemMessage(activity);
            if (replyMessage != null)
            {
                ConnectorClient connector = new ConnectorClient(new Uri(activity.ServiceUrl));
                await connector.Conversations.ReplyToActivityAsync(replyMessage);
            }
        }
        // Return response
        var response = Request.CreateResponse(HttpStatusCode.OK);
        return response;
    }

 

Finally, alter the following section in the HandleSystemMessage method (in the MessagesController.cs file) to the following:

 

    if (message.Type == ActivityTypes.DeleteUserData)
    {
        // Get BotUserData
        StateClient sc = message.GetStateClient();
        BotData userData = sc.BotState.GetPrivateConversationData(
            message.ChannelId, message.Conversation.Id, message.From.Id);
        // Set BotUserData
        userData.SetProperty<string>("UserName", "");
        userData.SetProperty<bool>("AskedForUserName", false);
        // Save BotUserData
        sc.BotState.SetPrivateConversationData(
            message.ChannelId, message.Conversation.Id, message.From.Id, userData);
        // Create a reply message
        ConnectorClient connector = new ConnectorClient(new Uri(message.ServiceUrl));
        Activity replyMessage = message.CreateReply("Personal data has been deleted.");
        return replyMessage;
    }

 

image

Now when we chat with the Bot it can remember our name.

image

If we tell it to Delete User Data

image

It will respect our wishes.

Publishing The Bot

To connect your Bot to the Bot Connector, you will first need to publish it in a publically accessible location.

This can be any server, however, publishing to Azure is recommended because publishing to it has built-in support in Visual Studio.

First, go to https://azure.microsoft.com and create an account and a subscription if you don’t already have one.

image

Next, Right-click on the Project node (not the Solution node) in Visual Studio and select Publish.

image

Select Microsoft Azure Web Apps.

image

Sign into your Azure account, select a subscription, then click the New button.

image

Enter a unique Web App name, select your subscription, select or create a service plan, resource group and region, and click the Create button.

image

After the web app has been created, click the Publish button.

image

The web app will open in the web browser.

Note the web address, you will need it in a later step.

Registering The Bot With The Bot Connector

image

Go to the Microsoft Bot Framework portal at https://www.botframework.com and sign in with your Microsoft Account.

image

Select Register a bot.

image

Fill in all the fields.

Note: That the end point web address is what you saw when the web browser opened in the previous step. However, remember that you have to add “/api/messages” to the end of the address and use “https://” rather than “http://”.

image

At one point you will click a link to go to:

https://apps.dev.microsoft.com

It is there that you will get an Application ID and a password.

Make a note of them because you will need to use them to update the Visual Studio project later.

image

Click the Register button.

image

The Bot registration will be created.

image

Copy the Bot ID and MicrosoftAppId from the https://dev.botframework.com site, and MicrosoftAppPassword from the https://apps.dev.microsoft.com site to the web.config of the Bot in Visual Studio.

Note: If you forgot to note the MicrosoftAppPassword in the earlier step, you can click the Generate New Password button to create another one.

image

Publish the Bot again.

You are doing this because the Bot Connector will pass the Bot ID and MicrosoftAppId and MicrosoftAppPassword when it communicates with it.

image

You can now test your Bot using the Bot Connector web page.

image

If you desire, you can click the Publish button to submit your bot to the Bot Directory.

You can also configure channels to your Bot.

Even if you do not publish it to the Bot Directory, you can still call if from your own applications and through any channels you configure.

 

Links

Microsoft Bot Framework

Microsoft Application Registration Portal (https://apps.dev.microsoft.com)

Bot Builder (GitHub)

Bot Framework Forum (stack overflow)

Visual Studio 2015 Bot Project Template

Bot Framework Emulator (Windows)

 

Download

You can download the code from the Download page

9 comment(s) so far...


Gravatar

Re: Creating a Hello World! Bot Using The Microsoft Bot Framework

Thanks Michael :)
There is thing I need :)

By Luu Van Tuan on   7/6/2016 8:13 PM
Gravatar

Re: Creating a Hello World! Bot Using The Microsoft Bot Framework

This really is a great tutorial to get you started and your first bot up and running. It worked perfectly via the emulator a few days ago. As I ran it today to publish it to Azure it broke because of the functionality of the Activity class. Will the properties and/or methods that are unavailable in this class be resolved in the near future?

By Wuf_Fang on   10/12/2016 4:28 PM
Gravatar

Re: Creating a Hello World! Bot Using The Microsoft Bot Framework

@Wuf_Fang - I just did a test. I downloaded the code for this article from the Download page on this site(aihelpwebsite.com/Downloads) and it worked fine. I upgraded Microsoft.Bot.Builder to version 3.2.1 and it still worked. What was your specific error? Please make a post to the forums on this site rather than in the comments of this blog post because you can attach screen shots.

By Administrator on   10/12/2016 6:24 PM
Gravatar

Re: Creating a Hello World! Bot Using The Microsoft Bot Framework

Great tutorial and it helped me learn a few things, but it might need a bit of an update.

Not sure if it's because of a change in the framework, but your code as it stands doesn't send any response for the "Delete User Data" System Message. I changed it, so don't know if it's the most efficient way but it outputs the message now. This issue exists in the bot template from Microsoft as well (unless I have missed something Crucial).

From
else
{
HandleSystemMessage(activity);
}

To
else
{
Activity replyMessage = HandleSystemMessage(activity);
if (replyMessage != null)
{
ConnectorClient connector = new ConnectorClient(new Uri(activity.ServiceUrl));
await connector.Conversations.ReplyToActivityAsync(replyMessage);
}
}

By Jarrod on   11/29/2016 4:01 AM
Gravatar

Re: Creating a Hello World! Bot Using The Microsoft Bot Framework

@Jarrod - You are correct, the delete user data code does work, but the response was not tested that is why I did not show it in the article. I updated the article and the code download. Thank you for your support.

By Administrator on   11/29/2016 6:11 AM
Gravatar

Re: Creating a Hello World! Bot Using The Microsoft Bot Framework

Hello,
My application works fine in localhost. However the moment I deploy it on Server I start to get 500 Error. I do have a SSL installed correctly for my domain pocchatbot.kelloggs-psstudio.co.uk
Below are the details, could you please confirm if I need to make any change on server ports or the code itself except what you have recommended

500 InternalServerError
System.Net.Http.HttpRequestException: An error occurred while sending the request. ---> System.Net.WebException: Unable to connect to the remote server ---> System.Net.Sockets.SocketException: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond 52.56.77.126:443
at System.Net.Sockets.Socket.EndConnect(IAsyncResult asyncResult)
at System.Net.ServicePoint.ConnectSocketInternal(Boolean connectFailure, Socket s4, Socket s6, Socket& socket, IPAddress& address, ConnectSocketState state, IAsyncResult asyncResult, Exception& exception)
--- End of inner exception stack trace ---
at System.Net.HttpWebRequest.EndGetRequestStream(IAsyncResult asyncResult, TransportContext& context)
at System.Net.Http.HttpClientHandler.GetRequestStreamCallback(IAsyncResult ar)
--- End of inner exception stack trace ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Intercom.DevPortal.Server.Controllers.BotManagerController.d__76.MoveNext() in D:\a\1\s\DevPortalLib\Controllers\BotManagerController.cs:line 2038

By Rahul on   2/7/2017 11:43 PM
Gravatar

Re: Creating a Hello World! Bot Using The Microsoft Bot Framework

@Rahul,

The bot connector is expecting you to have code at "https://pocchatbot.kelloggs-psstudio.co.uk/api/messages". Also because the comments section of this blog is bad for back and forth conversations, please open a thread in the Forums (on this site).

By Administrator on   2/8/2017 5:18 AM
Gravatar

Re: Creating a Hello World! Bot Using The Microsoft Bot Framework

Thats a great post.!

I'm trying deploy the solution, but in the bot framework emulator, at the time of sending the message, the message "not sent" appears under my message.

By Sebastian Contreras on   11/20/2017 12:08 PM
Gravatar

Re: Creating a Hello World! Bot Using The Microsoft Bot Framework

@Sebastian Contreras - It should work when you deploy it to Azure and test it using the app on the web page.

By Administrator on   11/20/2017 1:01 PM