Microsoft Bot Framework - Part 2

By: Rachel Scanlon on 1/11/2017

Welcome to Part 2 of our Microsoft Bot blog post series. If you are not familiar with part 1, head on over now otherwise, let's jump back in!

  1. Configuring your environment for BOT Development

For this tutorial, I’m assuming you have installed all the components listed in section “What components do developers need to use Microsoft Bot Framework and Microsoft Cognitive Services to create intelligent bots?” from Microsoft Bot Framework- Part 1. If not, then you will need to go back and install them. You will need them to follow this tutorial and the one for Part 3.

  1. Setting up a test project for a basic BOT using the Bot Framework Channel Emulator

First, we need to create a new project using the Bot Application template we installed in Part 1.

Bot-New Project
Once you have created your BOT application, run it and you will see this in your browser.

You should then open the Bot Framework Channel Emulator and test your BOT.

As you are testing locally at this point you don’t need to supply any credentials. For me leaving them in the web.config (even blank) was giving me a 401 unauthorized error when I sent a message. If this happens just follow the 3 steps below.

  1. Comment out the highlighted lines in the web.config.


  2. Make sure these values are also blank in the BOT Framework Channel Emulator


  3. Finally go to the MessagesController class and comment out the highlighted line

At this point the BOT is dumb and will just tell you what you typed and how many character it has, but we know that everything is configured and working correctly.

Let’s explore the functionality of this very simple BOT.

At this point it all takes place in the MessagesController class. If you look at the “Post” method, you will see that the message gets passed to the method in the form of an Activity object. It then checks what the ActivityType is. There are many ActivityTypes, but for our example it is of the type “Message”. We then create a ConnectorClient which accepts the ServiceUrl from the Activity Object and uses this as the endpoint to send replies to.

We then create a new Activity and assign some text to its “CreateReply” property which, in this case, is just repeating their message back to them, along with the number of characters.

Finally, we can pass this new Activity (and the reply) back the user via the ConnectorClient’s ReplyToActivityAsync method.

Facebook Messenger Bot

Finally, in this blog post we will create a more useful BOT which will communicate with users via Facebook’s messenger app. With the increased presence of businesses on Facebook, more and more customers are starting to communicate with them that way, I feel this will become an important automated feature to compliment your business’ FB presence.

First we must change the controller class (MessagesController.cs) to remember the user’s input. The methods provided to accomplish this are “GetPrivateConversationData” and “SetPrivateConversationData”.

Replace the code in the “Post” method with the code below.

public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
{
    bool userNameRequested = false;
    string userName = "";

    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);
        userNameRequested = userData.GetProperty<bool>("RequestedUserName");
        userName = userData.GetProperty<string>("UserName") ?? "";

        // Create text for a reply message
        StringBuilder replyMessage = new StringBuilder();

        if (userNameRequested == false) // Never asked for name
        {
            replyMessage.Append($"Type some text and the messenger bot will repeat it.");
            replyMessage.Append($"\n\n");
            replyMessage.Append($"Who am I speaking to?");

            userData.SetProperty<bool>("RequestedUserName", true);
        }
        else // Have asked for name
        {
            if (userName == "") // Name was never provided
            {
                // If we have asked for a username but it has not been set
                // the current response is the user name
                replyMessage.Append($"Hello {activity.Text}!");

                userData.SetProperty<string>("UserName", activity.Text);
            }
            else // Name was provided
            {
                replyMessage.Append($"{userName}, You typed {activity.Text}");
            }
        }

        // Save BotUserData
        sc.BotState.SetPrivateConversationData(
        activity.ChannelId, activity.Conversation.Id, activity.From.Id, userData);

        // Create a reply
        ConnectorClient connector = new ConnectorClient(new Uri(activity.ServiceUrl));
        Activity replyMessage = activity.CreateReply(replyMessage.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);
        }
    }

    var response = Request.CreateResponse(HttpStatusCode.OK);
    return response;
}

Replace the code in the “HandleSystemMessage” method with the following.

private Activity HandleSystemMessage(Activity message)
{
    // Get BotUserData
    StateClient sc = message.GetStateClient();

    BotData userData = sc.BotState.GetPrivateConversationData(message.ChannelId, message.Conversation.Id, message.From.Id);
    userData.SetProperty<string>("UserName", "");
    userData.SetProperty<bool>("RequestedUserName", 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("User data deleted.");
    return replyMessage;
}


Steps to set up Facebook for development

  1. Create a page in Facebook


You should end up with a page like this.

  1. Go to the Facebook developer website and register as a developer

https://developers.facebook.com/docs/apps/register

Select “Create Developer Account”.

  1. Create a Facebook application

Select “Create new Facebook App”.

On creation, you will be redirected to this page.

Select the page you created previously from the dropdown list

Navigate to this page and select the app that you want.

https://developers.facebook.com/apps/

Save the App ID somewhere. You’ll need it later.

Select “Messenger” to add Facebook Messenger to your app.

  1. Configure Facebook Messenger to talk to the Microsoft Bot Connector

We will now walk through the steps necessary to register a new BOT.

https://dev.botframework.com/

Select “Register a bot”.

Fill in all the information needed to register your new bot

Select “Create Microsoft App ID and password” and save the app id and password.

Select “My Bots” and add “Facebook

Expand the node that says, “Set webhook callback url and verify token.” Save the callback url and

Click “I’m done configuring Facebook Messenger”.

Go back to https://developers.facebook.com/ and select your application.

In the settings for Messenger, select “Setup webhooks” and enter the values you saved in the previous step. Select all of the Subscription fields with the exception of message_echoes and message_reads and then hit the verify and save button.

Select the relevant page. If you get an “Insufficient Permissions” error, check that you have the same page selected in the “Token Generation” section of this page.

Copy the Page Access Token under “Token Generation”

Configure the Microsoft Bot Connector

Go to https://dev.botframework.com/bots?id=botmessengerapp and select “Facebook Messenger”.


If you go to the https://www.messenger.com/t/{ Page ID}/ you will now be able to converse with your BOT. Right now it asks the user their name and uses it to address them in future posts.

In the third part of this tutorial we will explore how to include a custom chat bot on your businesses website (ASP.NET MVC). We will use LUIS to make this BOT even more intelligent than our Facebook Messenger Bot. You can, however, easily use these same principles to expand our Facebook Messenger Bot. However, for the purposes of this tutorial, I wanted to demonstrate how you can utilize the Microsoft Bot Framework from directly within your business website.

Source Code