Microsoft Bot Framework – Forms dialog from JSON Schema.

What’s up guys, Eze is here. I’ve already written few posts about Microsoft Bot Framework, in case you missed it you can check it here. Today we are going deeper and review another really good feature of the Form Dialog, the possibility to create a form using a JObject. As we did before the Form Dialog is going to create a form and allow our Bot to ask field by field until completes the form but instead of using a static c# class to define our form we are going to provide a JSON Schema.

In order to utilize this feature you need to ensure that you add the NuGet project Microsoft.Bot.Builder.FormFlow.Json to your project. This defines the new namespace Microsoft.Bot.Builder.FormFlow.Json that contains the code to allows using JSON Schema for FormFlow.

Creating the JSON Schema

Now we need to define our form, this time we are going to create a json file to do it.  In the References property we are going to define all the dependencies for our form. In the same way under the Imports property we define all the namespaces to include. And another important property for our form is the OnCompletion property, here we are going to put a C# script to execute after our bot complete to fulfill the form. And then we have the properties field where we are going to place the fields we want our bot ask to the customer.

{
 "References": [ "CityTimerBot.dll" ],
 "Imports": [ "CityTimerBot.Models" ],
 "type": "object",
 "required": [
   "SelectedPlace"
 ],
 "Templates": {
 "NotUnderstood": {
 "Patterns": [ "I do not understand \"{0}\".", "Try again, I don't get \"{0}\"." ]
 }
 },
 "properties": {
 "PlaceName": {
 "Prompt": { "Patterns": [ "Name a place to know the current date-time {||}" ] },
 "Before": [ { "Message": [ "Welcome to the City Timer bot!" ] } ],
 "Describe": "Name of the place",
 "type": [
 "string",
 "null"
 ]
 },
 "SelectedPlace": {
 "Prompt": { "Patterns": [ "Select a place {||}" ] },
 "Before": [ { "Message": [ "Welcome to the City Timer bot!" ] } ],
 "Describe": "Place to find the current date time",
 "type": [
 "string",
 "null"
 ]
 }
 },
 "OnCompletion": "var businesLogic = new CityTimerBot.Models.LocationBL(); var response = businesLogic.GetCityInfoFromPlaceId(state.SelectedPlace);var reply = string.Empty;if (!string.IsNullOrEmpty(response.cityName) && !string.IsNullOrEmpty(response.convertedLocalTime)){ reply = $\"Current date time at {response.cityName} is {response.convertedLocalTime}\"; }else{ reply = $\"Sorry we could not find any location called {state.PlaceName}\"; } await context.PostAsync(reply);"
}

Once we have defined the schema file we need create a method to return an object which implements the IForm interface as we did las time. As you can see in the code below we need use the FormBuilderJson object and we just pass the schema in the constructor.

 public static IForm<JObject>; BuildJsonForm()
 {
    using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("CityTimerBot.LocationTemplate.json"))
    {
       var schema = JObject.Parse(new StreamReader(stream).ReadToEnd());
       return new FormBuilderJson(schema)
         .AddRemainingFields()
         .Build();
    }
 }

As you can see this feature gives us the flexibility to define custom forms and the availability to change it dynamically.  Thinking out loud I can imagine an use case where we want to provide to our customers a way to model their forms so we can define the form as a JSON Schema and provide them an admin screen to change it.

bot_fields

For mode details of Microsoft Bot Framework you can use this link.

If you found this post useful please don’t forget to press the like button and share it. If you are in doubt don’t hesitate to ask a question and as always thank you for reading.

Advertisements

Microsoft Bot Framework – Forms Dialog and how to add dynamic options.

What’s up guys, Eze is here. As you know I’ve already written a post about Microsoft Bot Framework, in case you missed it you can check it here. Today I want to go deeper and explain a really good feature: Form Dialog. This feature is used to create a form and allow our Bot to ask field by field until completes the form and in particular I want to explain how to add dynamic options to our font so let dive into the description right away.

Creating the form

Let’s suppose we have a form and we want our bot to ask for each property in our form to the user in order to complete it so first we need to define our form. In my case I’m using the same I have in my working example. As always the working example is available here.

[Serializable]
 [Template(TemplateUsage.NotUnderstood, "I do not understand \"{0}\".", "Try again, I don't get \"{0}\".")]
 public class PlaceTemplate
 {
    [Prompt("Name a place to know the current date-time {||}")]
    [Describe("Name of the place")]
    public string PlaceName { get; set; }
    [Prompt("Select a place {||}")]
    [Describe("Place to find the current date time")]
    public string SelectedPlace { get; set; }

As you can see in the code above we just define a new class and the properties of this class are going to be used by our bot to complete the form. Then we need to define a static method to return a IForm<object>. As you can see below this method create an instance of the class FormBuilder and then just return the method Build(). In this FormBuilder it’s going to define which field we want to ask to the user, to do that we are going to use the method Field(). And then using the OnCompletion() method we will define the behavior for our bot after populate all the requested fields. As you can see this is a good way to guide our user through a form.

 
 public static IForm<PlaceTemplate> BuildPlaceForm()
{
var logic = new LocationBL();
OnCompletionAsyncDelegate<PlaceTemplate> process = async (context, state) =>
{
var businesLogic = new LocationBL();
var response = businesLogic.GetCityInfoFromPlaceId(state.SelectedPlace);
var reply = string.Empty;
if (!string.IsNullOrEmpty(response.cityName) && !string.IsNullOrEmpty(response.convertedLocalTime))
{
reply = $"Current date time at {response.cityName} is {response.convertedLocalTime}";
}
else
{
reply = $"Sorry we could not find any location called {state.PlaceName}";
}
await context.PostAsync(reply);
};
var builder = new FormBuilder<PlaceTemplate>()
.Message("Welcome to the City Timer bot!")
.Field(nameof(PlaceName))
.Field(new FieldReflector<PlaceTemplate>(nameof(SelectedPlace))
.SetType(null)
.SetActive((state) =>
{
return string.IsNullOrEmpty(state.SelectedPlace);
})
.SetPrompt(new PromptAttribute("Please select one of the following options: {||}")
{
ChoiceStyle = ChoiceStyleOptions.Buttons

})
.SetDefine((state, field) =>
{
var result = logic.GetPlaces(state.PlaceName);
foreach (var item in result)
{
field
.AddDescription(item.Item1, item.Item2)
.AddTerms(item.Item1, item.Item2);
}

return Task.FromResult(true);
}))
.OnCompletion(process);
return builder.Build();
}

Adding dynamic options to a field.

I saw a lot of examples where the use can chose one of many options but those options are always defined using an Enum. In my case I want to define the options dynamically so to do that our field needs to be an instance of FieldReflector. This new object has a method SetDefine as you can see in the code above which is used in my example to get the list of places and return a list to the user to select one option.

As you can see creating a form using the Microsoft Bot Framework it’s really easy and adding dynamic options to a field is even easier.

bot_fields.PNG

For mode details of Microsoft Bot Framework you can use this link.

If you found this post useful please don’t forget to press the like button and share it. If you are in doubt don’t hesitate to ask a question and as always thank you for reading.

Firebase + Azure Functions + Azure Service Bus + Microsoft Bot Framework – Connecting the dots. Part II

What’s up guys, Eze is here. In my last post I’ve described a system which has several parts such as Firebase, AngularJs and Azure Functions interconnected. I also added new tools like Microsof Bot Framework and Azure Service Bus to enhance our app in a decouple way. As always the working example is available here.  Yesterday I put my focus on the NodeJs Azure Funtion, but today I’ll describe the Microsoft Bot Framework. As I said in my last post (in case you missed it you can check it here), the idea is to create a bot that receives a place name and response with the current date time at that location. After the bot parse the input and generate the proper response puts into the Azure Service Bus a message that will trigger our NodeJs Azure Funtion to store the data in Firebase, pretty cool, isn’t it? You can check the working version here.

Microsoft Bot Framework

Microsoft has created an awesome framework that allows us to create a bot, yes a conversational tool able to interact with our customers. The Bot itself is a web api application that can run in any web server. Then we just register our bot in the Microsoft Bot framework website and under the configuration page we define different channels where our bot is going to run. And that’s it, as simple as that our bot will be able to interact with customer from Skype, Facebook chat or Tulio.

bot

 

Creating the Bot

I already told you the bot is just a web api that can run in any server and the reason I said that is because Microsoft Bot Framework has two different versions, of course a Bot Builder for .Net and a Bot Builder for NodeJs.

 [ResponseType(typeof(void))]
public virtual async Task<HttpResponseMessage> Post([FromBody] Activity activity)
{
if (activity != null)
{
// one of these will have an interface and process it
switch (activity.GetActivityType())
{
case ActivityTypes.Message:
await Conversation.SendAsync(activity, () => EchoChainDialog.dialog);
break;

case ActivityTypes.ConversationUpdate:
case ActivityTypes.ContactRelationUpdate:
case ActivityTypes.Typing:
case ActivityTypes.DeleteUserData:
case ActivityTypes.Ping:
default:
Trace.TraceError($"Unknown activity type ignored: {activity.GetActivityType()}");
break;
}
}
return new HttpResponseMessage(System.Net.HttpStatusCode.Accepted);
}

As you can see in the code above we only need to define a post action in our webapi controller which will be the SPOC of our bot. Every message is going to be route to this action. In my case based on the activity type I let my bot response. In this example we are creating a new instance of the class  EchoChainDialog. This dialog entity is going to handle the conversation base on what we define. In my case I just use a switch method from the IDialog object to parse the text and response to our customer.

Azure Service Bus

I’ve created as well an Azure Service Bus to use as a trigger for my NodeJs Azure Function. What that means? Ok the idea is like this after the Bot process the request and generates a response it puts a message into the Azure Service Bus. As you can see below the code to do that it’s really simple. We just need the Service Bus connection string and the queue name. When a new message arrives to this particular queue in the Azure Service Bus that will trigger our NodeJs Azure Function we created yesterday. This mechanism is created and configure in Azure.

 try
{
var client = QueueClient.CreateFromConnectionString("connectionString", "queueName");
var message = new BrokeredMessage(JsonConvert.SerializeObject(responseData));
client.Send(message);
}
catch
{
}

 

For more details of Azure Service Bus you can use this link.

For mode details of Microsoft Bot Framework you can use this link.

For more details of Azure Functions you can use this link.

 

If you found this post useful please don’t forget to press the like button and share it. If you are in doubt don’t hesitate to ask a question and as always thank you for reading.

Firebase + Azure Functions + Azure Service Bus + Microsoft Bot Framework – Connecting the dots.

What’s up guys, Eze is here. I’ve been working in an example that you can check it here, this example uses Firebase, AngularJs and Azure Functions. I used a bunch of cool tools to create rapidly powerful front-end app, in case you missed it you can check here. Today I’ll add couple of new tools like Microsof Bot Framework and Azure Service Bus to enhance our app in a decouple way. The idea is to create a bot that receives a place name and response with the current date time at that location. After the bot parse the input and generate the proper response puts into the Azure Service Bus a message that will trigger our NodeJs Azure Funtion to store the data in Firebase, pretty cool, isn’t it? You can check the working version here.

NodeJs Azure Function

Today we are going to put the focus only in our Azure Function so I’ll talk about how to create a NodeJs Azure function and how to configure it in order to be able to use Firebase from a NodeJs Azure function.

As we did last time, in case you missed it you can check here our Azure function is composed for two files the function.json (function metadata) and because this one is a NodeJs function we need to have an index.js file to place our code to execute. All JavaScript functions must export a single function via module.exports for the runtime to find the function and run it. This function must always include a context object. In the example below you can see how I configure my function.

module.exports = function(context, mySbMsg) {
   if(!app) {
      context.log('Initializing Firebase App');
      app = firebase.initializeApp(config);
   }
   var defaultAuth = app.auth();
   if(!_user){
      defaultAuth.signInAnonymously()
                 .catch(function(error) {
                    context.log('Anonymous login failed: ' + error.message);
                    context.done();
                 });
   }

   defaultAuth.onAuthStateChanged(function(user) {
   if (user) {
      _user = user;
      context.log('User is signed in. user uid: ' + _user.uid);
      var defaultDatabase = app.database().ref().child('requests').child(_user.uid).child('userRequests');
      mySbMsg['userName'] = 'Anonymous';
      defaultDatabase.push(mySbMsg)
                     .then(function() {
                          context.log('JavaScript ServiceBus queue trigger function processed message', mySbMsg);
                          context.done();
                     })
                     .catch(function(error) {
                          context.log('Synchronization failed');
                          context.done();
                      });
    } else {
       context.log('User is signed out.');
       context.done();
    }});
};

Configuring the environment

Before going further with the explanation of the function I want to explain first how to configure the Azure function to use Firebase node package. Let’s remember that this function is going to run in Azure serverless. That only means that we don’t have full control over our server but we still can run npm install  in the function app’s SCM (Kudu) command line interface in order to add packages to our app:

  1. Navigate to: https://<function_app_name&gt;.scm.azurewebsites.net.
  2. Click Debug Console > CMD.
  3. Navigate to D:\home\site\wwwroot\<function_name>.
  4. Run npm install firebase --save.

kudu

After doing this we will be able to import our Firebase library like this:

var firebase = require('firebase');

After that we can use our firebase object as we did before so let’s dive directly into our function so I can explain you what’s going on. First I use the method signInAnonymously under the object auth and this is because I need a logged in user to write in my database, don’t worry we didn’t talk about it yet but believe me I’m going to explain you more about database rules and authentication with Firebase.

Then I use the object that I receive as parameter from my Azure Service Bus and directly store it in our database. During this week I’ll be posting about the other parts of this system so you can know more about Microsoft Bot Framework and Azure Service Bus

For more details of Azure Functions you can use this link.

For more details of NodeJs Azure Functions you can use this link.

For mode details of Firebase npm package us this link.

If you found this post useful please don’t forget to press the like button and share it. If you are in doubt don’t hesitate to ask a question and as always thank you for reading.