How to build a simple conversation bot with Microsoft Bot Framework
Lets build a simple conversation bot who will decode our emotions & will try to cheer us.
Basic Idea is to get, how the user is feeling now, then pass the feelings to Cognitive services & get the sentiment score.
If the sentiment score is high or neutral then pop a joke to the user.
If the sentiment score is low, try to show a motivational message.
Hope everyone has the environment setup for the bot app, else just check my earlier blog post
First we need to create a new bot project. Choose Bot Application
Give it a name & lets start exploring.
The project will create a controller - MessagesController.cs which is the starting point for our bot.
Controller consists of a task Post which handles the messages received by the bot.
It should look like below.
I am just trying to pass the flow to a RootDialog which is bot framework dialog.
The RootDialog looks like this
RootDialog welcomes the user & asks about how he/she is feeling now.
Those feelings get passed to cognitive services in GetUserFeelings task.
Once the SentimentScore is received, depending on the score we will popup Happy, Neutral or Sad dialogs.
HappyDialog will look like this.
Here I am popping up a question to user if he/she wants to read a Joke? (using PromptDialog restricting user inputs to Yes or No).
If answer is Yes, i read a local JSON file containing jokes & present a random one.
We then ask user if he/she want to read another & the cycle will go on.
User can disengage by choosing No.
Same process will happen for Neutral & Sad Dialogs.
To Test the bot, run your project from Visual Studio. It will fire up IISExpress & host the bot locally.
Use Bot Framework Emulator to connect to the running bot.
The url to connect the bot should look like below, change could be the port.
http://localhost:3979/api/messages
Try saying Hi to the Bot & enjoy.
You can try this with my Bot Emo.
Add him to your Skype Contacts.

or chat with him on Bing
Try on Bing
Happy Coding,
Parshuram
Basic Idea is to get, how the user is feeling now, then pass the feelings to Cognitive services & get the sentiment score.
If the sentiment score is high or neutral then pop a joke to the user.
If the sentiment score is low, try to show a motivational message.
Hope everyone has the environment setup for the bot app, else just check my earlier blog post
First we need to create a new bot project. Choose Bot Application
Give it a name & lets start exploring.
The project will create a controller - MessagesController.cs which is the starting point for our bot.
Controller consists of a task Post which handles the messages received by the bot.
It should look like below.
I am just trying to pass the flow to a RootDialog which is bot framework dialog.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public async Task<HttpResponseMessage> Post([FromBody]Activity activity) | |
{ | |
if (activity.Type == ActivityTypes.Message) | |
{ | |
await Conversation.SendAsync(activity, () => new RootDialog()); | |
} | |
else | |
{ | |
HandleSystemMessage(activity); | |
} | |
var response = Request.CreateResponse(HttpStatusCode.OK); | |
return response; | |
} |
The RootDialog looks like this
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class RootDialog : IDialog<object> | |
{ | |
public async Task StartAsync(IDialogContext context) | |
{ | |
context.Wait(this.MessageReceivedAsync); | |
} | |
private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> result) | |
{ | |
var message = await result; | |
await this.SendWelcomeMessageAsync(context); | |
} | |
private async Task SendWelcomeMessageAsync(IDialogContext context) | |
{ | |
await context.PostAsync("Hi there, How are you feeling now?"); | |
context.Wait(GetUserFeelings); | |
} | |
private async Task GetUserFeelings(IDialogContext context, IAwaitable<IMessageActivity> result) | |
{ | |
var message = await result; | |
const string apiKey = "Microsoft Cognitive services API Key"; | |
const string queryUri = "https://westus.api.cognitive.microsoft.com/text/analytics/v2.0/sentiment"; | |
var client = new HttpClient | |
{ | |
DefaultRequestHeaders = { | |
{"Ocp-Apim-Subscription-Key", apiKey}, | |
{"Accept", "application/json"} | |
} | |
}; | |
DocumentRequest test = new DocumentRequest { Id = "1", Language = "en", Text = message.Text }; | |
var sentimentInput = new BatchInput | |
{ | |
documents = new List<DocumentInput> { | |
new DocumentInput { | |
id = 1, | |
text = message.Text, | |
} | |
} | |
}; | |
var sentimentPost = await client.PostAsync(queryUri, new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(sentimentInput), Encoding.UTF8, "application/json")); | |
var sentimentRawResponse = await sentimentPost.Content.ReadAsStringAsync(); | |
object JsonConvert = null; | |
var sentimentJsonResponse = Newtonsoft.Json.JsonConvert.DeserializeObject<BatchResult>(sentimentRawResponse); | |
var sentimentScore = sentimentJsonResponse?.documents?.FirstOrDefault()?.score ?? 0; | |
if (sentimentScore > 0.7) | |
{ | |
context.Call<object>(new HappyDialog(sentimentScore), AfterChildDialogIsDone); | |
} | |
else if (sentimentScore < 0.3) | |
{ | |
context.Call<object>(new SadDialog(sentimentScore), AfterChildDialogIsDone); | |
} | |
else | |
{ | |
context.Call<object>(new NeutralDialog(sentimentScore), AfterChildDialogIsDone); | |
} | |
} | |
private async Task AfterChildDialogIsDone(IDialogContext context, IAwaitable<object> result) | |
{ | |
context.Wait(MessageReceivedAsync); | |
} | |
} | |
public class BatchInput | |
{ | |
public List<DocumentInput> documents { get; set; } | |
} | |
public class DocumentInput | |
{ | |
public double id { get; set; } | |
public string text { get; set; } | |
} | |
// Classes to store the result from the sentiment analysis | |
public class BatchResult | |
{ | |
public List<DocumentResult> documents { get; set; } | |
} | |
public class DocumentResult | |
{ | |
public double score { get; set; } | |
public string id { get; set; } | |
} | |
public class quote | |
{ | |
public int Id { get; set; } | |
public string Quote { get; set; } | |
} |
RootDialog welcomes the user & asks about how he/she is feeling now.
Those feelings get passed to cognitive services in GetUserFeelings task.
Once the SentimentScore is received, depending on the score we will popup Happy, Neutral or Sad dialogs.
HappyDialog will look like this.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class HappyDialog : IDialog<string> | |
{ | |
private double userSentiment; | |
public HappyDialog (double sentiment) | |
{ | |
userSentiment = sentiment; | |
} | |
public async Task StartAsync(IDialogContext context) | |
{ | |
PromptDialog.Choice(context, OnOptionSelected, | |
new List<string>() { "Yes", "No" }, "That's great to hear! Do you want to read a joke?", "Not a valid option", 3); | |
} | |
private async Task OnOptionSelected(IDialogContext context, IAwaitable<string> result) | |
{ | |
try | |
{ | |
string optionSelected = await result; | |
switch (optionSelected) | |
{ | |
case "Yes": | |
List<quote> jokes = JsonConvert.DeserializeObject<List<quote>>(File.ReadAllText(AppDomain.CurrentDomain.BaseDirectory + @"\" + @"jokes.json")); | |
Random random = new Random(); | |
string joke = jokes[random.Next(102)].Quote; | |
PromptDialog.Choice(context, OnOptionSelected, | |
new List<string>() { "Yes", "No" }, joke + "\n\n" + "Do you want to read one more?", "Not a valid option", 3); | |
break; | |
case "No": | |
context.Done(new object()); | |
break; | |
} | |
} | |
catch (TooManyAttemptsException ex) | |
{ | |
await context.PostAsync($"Ooops! Too many attemps :(. But don't worry, I'm handling that exception and you can try again!"); | |
context.Done(new object()); | |
} | |
} | |
} |
Here I am popping up a question to user if he/she wants to read a Joke? (using PromptDialog restricting user inputs to Yes or No).
If answer is Yes, i read a local JSON file containing jokes & present a random one.
We then ask user if he/she want to read another & the cycle will go on.
User can disengage by choosing No.
Same process will happen for Neutral & Sad Dialogs.
To Test the bot, run your project from Visual Studio. It will fire up IISExpress & host the bot locally.
Use Bot Framework Emulator to connect to the running bot.
The url to connect the bot should look like below, change could be the port.
http://localhost:3979/api/messages
Try saying Hi to the Bot & enjoy.
You can try this with my Bot Emo.
Add him to your Skype Contacts.

or chat with him on Bing
Try on Bing
Happy Coding,
Parshuram
Comments