Bot in action – A more advanced hello world

Whenever i talk Bot i always think of those Sifi movies where you can have those super complex and intelligent digital beings. When I heard that the bot framework is out I wanted to try it and it wasn’t that easy to learn and develop. I know I am a bit late in this blog so the words might be new but the technology is not that recent. So lets start coding then.

So first off you need to follow this post to set up the environment and the template for the bot. So when you create a new bot project you will given some template files on which you can work directly and that is what we are going to do as well. I will directly use those templates and change them to more meaningful and understandable code.

If you see the template generate files you will observe that the code is divided into two main parts, Controller and Dialog. The Controller will send the message that will come from the user via the bot interface and it will send it to the dialog. The dialog will process the message and will reply accordingly. We can have multiple dialogs you can consider them as routes in a website.

How will we work

MessageController: No change here so we will use the same file as the template generate it.

RootDialog: Here we will instrust the dialog to get user profile information. Do remember that this class needs to be serializable.

using System;
using System.Threading.Tasks;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Connector;

namespace BotTry1.Dialogs
{
[Serializable]
public class RootDialog : IDialog<object>
{
public Task StartAsync(IDialogContext context)
{
context.Wait(MessageReceivedAsync);

return Task.CompletedTask;
}

private Task MessageReceivedAsync(IDialogContext context, IAwaitable<object> result)
{
context.Call<UserProfile>(new EnsureUserProfile(), ProfileEnsured);
return Task.CompletedTask;
}

private async Task ProfileEnsured(IDialogContext context, IAwaitable<UserProfile> result)
{
var profile = await result;
context.UserData.SetValue("profile", profile);
await context.PostAsync($@"Hello {profile.Name} we love {profile.Company}");
context.Wait(MessageReceivedAsync);
}
}
}

EnsureProfileDialog: This dialog will get the user profile from the user. You can also notice that this class is serializable

using System.Threading.Tasks;
using Microsoft.Bot.Builder.Dialogs;
using System;

namespace BotTry1.Dialogs
{
[Serializable]
class EnsureUserProfile : IDialog<UserProfile>
{
public Task StartAsync(IDialogContext context)
{
EnsureNameEntered(context);
return Task.CompletedTask;
}

private UserProfile _userProfile;
private void EnsureNameEntered(IDialogContext context)
{
var hasProfile = context.UserData.TryGetValue("profile", out _userProfile);
if (!hasProfile)
{
_userProfile = new UserProfile();
}
if (string.IsNullOrEmpty(_userProfile.Name))
{
PromptDialog.Text(context, NameEntered, "Please enter name");

}
else
EnsureCompanyName(context);

}

private void EnsureCompanyName(IDialogContext context)
{
if (string.IsNullOrWhiteSpace(_userProfile.Company))
{
PromptDialog.Text(context, CompanyNameEntered, @"What is your company name");

}
else
context.Done(_userProfile);
}

private async Task CompanyNameEntered(IDialogContext context, IAwaitable<string> result)
{
_userProfile.Company = await result;
context.Done(_userProfile);
}

private async Task NameEntered(IDialogContext context, IAwaitable<string> result)
{
_userProfile.Name = await result;
EnsureCompanyName(context);

}
}
}

UserProfile: This serializable datastrcuture will hold the actual profile information

using System;

namespace BotTry1.Dialogs
{
[Serializable]
public class UserProfile
{
public string Name { get; set; }
public string Company { get; set; }
}
}

This is how the bot will look like

bot hello world