2016-12-14_13-57-09

An emerging trend in technology is the idea of conversational computing. Instead of issuing a series of commands via taps and clicks, commands will be extracted from natural conversations. We use conversation as an organic way to interact with analog world, and Xamarin makes it easy to add a native conversational interface to the digital world and to your next app. Combine the chat interface with the Microsoft Bot Framework, and the end result is a natural, conversational dialog that will allow you to interact with your users in a new, but familiar, way.

A Chat Interface in Your App

The power of conversation as an interface is that the act of conversation is so natural, seamless and intuitive. To foster such an interaction, it is important the the UI feels natural as well. With Xamarin, we are able to design such an interface, one that fits perfectly within the expectations of the app platform. To demonstrate this, we are going to design an iOS chat interface, inspired by the Xamarin Shopping app. We will design an interface that acts as a customer support chat client for the shopping app. To get started, we will create a Blank App (iPhone) in Visual Studio.

 

ios_newproject

Our iOS app is going to utilize a fantastic messaging view controller, called JSQMessagesViewController, which is available in the Xamarin Component Store. You should be able to add it to your app by opening the Component Store and adding JSQMessagesViewController to the app.

viewcontrolcomp

Furthermore, since we will be making some HTTP calls, we will need to add System.Net.Http via the Add Reference dialog.

systemnethttp

Now that we have those requirements in place, we can get down to the writing the code! Our first requirement will be to add a UIViewController to our app, which will host the chat interface. For the sample, I created a UIViewController named ChatPageViewController, with a base class of MessagesViewController.

Once we have our view controller created, we must declare a few class level variables, and instantiate an HttpClient object to manage the communication with the Bot in Azure. Our class level variables should look as follows:

Within the ViewDidLoad method, we need to must instantiate an HttpClient object using the class level variable we declared, as well as set a few view options, and print a welcome message. The ViewDidLoad method should look similar to:

As our MessageViewController is essentially a customized UICollectionViewController, we must add some methods in to build the
UICollectionView.

Finally, we have a few classes to create to handle our messages and identities.

Now that we have all of our objects created and variables set, we can get down to the business of sending and receiving messages from our Bot! Our first task is to respond to the button click on the “send” button. Here we want to gather the message, display some indicators, and send the message to our Bot:

Now we come down to our last bit of code for our view controller, which is the SendMessage method. Here, we take the text input from PressedSendButton and communicate with our Bot via DirectLine.

Finally, we must use the AppDelegate to launch the ChatPageViewController when the application is opened, and we do this via:

Now that the app is designed, we will want to configure a bot for the conversation.

Adding Microsoft Bot Framework

The bot service consists of two parts, one being the language processor (LUIS) and the other being the Bot Service application, which we will host in Azure. For our purposes, we are going to import a custom LUIS app created for this sample. To get LUIS configured, you will want to go to luis.ai and sign in using your Microsoft account. Once on the main page, you will want click on “New App” and then “Import Existing App”.  You can download the LUIS app in JSON format from GitHub.

Now that we have a LUIS service created, it is time to get busy creating the Bot application! You may have noticed that for the client, we only need to make a few HTTP calls. This is because most of the processing for the conversation is done within the Bot Service application. This allows you to use the exact same Bot service for many different platforms, including integrations such as Skype. To get started, you will want to ensure that you have the bot template installed. These items can be downloaded from the Bot Framework page.

newproject

The bot project consists of a controller and a dialog. The template includes a default controller which will echo input back to the user. Once we have our dialog configured, we will circle back to our controller and tell it to use the newly created dialog. To create the dialog, add a new class file to your project, naming it something reasonable. The class itself should inherit from the base class of LuisDialog and you will also want to mark the class as [Serializable].

Within the class we just created, we need to create a method for each Intent defined within our LUIS app.

As you can see from the code snippet, we create a “public async” method which returns a Task and takes an IDialogContext and a LuisResult as inputs. The IDialogContext is the conversation that is taking place, while the LuisResult is the JSON string returned from the LUIS service. Furthermore, the method is marked with an attribute of [LuisIntent("")], which denotes which LUIS Intent the given method is designed to respond to. When the Intent is blank, it becomes the catchall for any utterance which can’t be matched to a known intent. If this method were intended to handle all utterances that are matched with the “Customer Service” intent, we would mark this method with the attribute [LuisIntent("CustomerService")]. However, as this is the catchall intent, we want inform the user that we could not understand what was said, and to suggest some things they can ask about. We post the message to the user via context.PostAsync(message) and mark this conversation as complete.

For more complex conversations, or for conversations where data lookups or other tasks need to occur, there may  be a need to call upon other methods from one of our LuisIntent marked methods. For example, the following snippet from a LuisIntent marked method denotes a completion handler to call upon receiving the results of a question prompted to the user.

In this truncated method, we detect that the user is asking a question regarding their password, so we want to verify the user by requesting their email address. PromptDialog.Text requests information from the user, and contains a completion handler which calls SupportUsernameEntered.

Within this method, we confirm the account, and send a reset email if the account is found. Once this email is sent, we can consider this interaction completed and end the conversation. In order to have a natural dialog between the user and the app, the Bot service should include many of these conversation paths. Much of these child actions can be defined in LUIS as well, though in our example the conversation is more basic and linear.

Now that we have a basic Bot created, we will need to publish the Bot to Azure. For our purposes, the official documentation should be followed.

Finally, we need to set up a service to communicate with the bot in Azure, using a service called Direct Line. This is a simple REST service which allows for communication between a custom client and the Bot. The Direct Line documentation covers the steps required to connect DirectLine to your bot instance. Once Direct Line is configured, you must modify the DirectLineKey variable within your iOS View Controller to match the API Key for Direct Line.

And that’s it! If we run our app, we can have a realistic conversation with our Bot, as seen below:

sd

The Microsoft Bot Framework is an incredibly powerful system, and we have only scratched the surface of what is possible. To try out the full sample, download it from GitHub.