Microsoft Bot Framework and the IScorable interface
Get link
Facebook
Twitter
Pinterest
Email
Other Apps
Using the IScorable interface and hook your implementation into the AutoFac dependency injection container supplied by the Microsoft Bot Framework team, you can create multiple separate global chat logic handlers:
BOT: Hi and Welcome!
Human: Do you like candy?
-> CandyResponseHandler
BOT: I certainly do! Licorice is my favourite!
Human: How are you feeling today?
-> FeelingResponseHandler
BOT: Never better! I just had some licorice a little while ago!
Let's create the candy response handler together before we move on:
public class CandyResponseHandler : IScorable
{
private readonly IDialogStack _stack;
public CandyResponseHandler(IDialogStack stack)
{
SetField.NotNull(out _stack, nameof(stack), stack);
}
public async Task// We only deal with string responses
public double GetScore(IActivity item, object state) => state is string ? 1 : 0; // If we *have* a response, we consider ourselves mighty important - 100% scoring; otherwise, we're insignificant - 0% scoring
public Task PostAsync(IActivity item, object state, CancellationToken token)
{
var message = item as IMessageActivity;
IDialog dialog = new MessageOutputDialog(state as string);
var interruption = dialog.Void(_stack);
_stack.Call(interruption, null);
return Task.CompletedTask;
}
public Task DoneAsync(IActivity item, object state, CancellationToken token)
=> Task.CompletedTask;
}
I left some comments in there so that you know what's going on: When hooked up, your handler will run for each message that arrives to your bot.
The handlers get a chance to prepare their data in their PrepareAsync method. Here's where you decide whether or not you understand what's going on.
Our handler understand what's going on, if the very specific question Do you like candy? is passed in. Otherwise, it's clueless.
Returning the data to the framework allows it to pass it back in for the two methods HasScore and GetScore.
HasScore is meant to quickly determine whether or not calling GetScore is useful.
GetScore returns this instance judgements of its validity (or the confidence of its decision/lookup/computation).
It's worth noting here, that a handler returning 100% confidence (that is score=1) short-circuits the handler execution, so the handlers are an excellent place to handle special bot commands ('help', 'reset', ...), language detection and other magic.
If the handler is elected for execution, its PostAsync method is invoked.
Those of you who have experience with the Bot framework will now question what this MessageOutputDialog is. It looks like this:
[Serializable]
public class MessageOutputDialog : IDialog
{
private readonly string _message;
public MessageOutputDialog(string message)
{
_message = HttpUtility.HtmlDecode(message);
}
public async Task StartAsync(IDialogContext context)
{
await context.PostAsync(_message);
context.Done((object)null);
}
}
The dialog allows you to pass a message to the user, participating in the already set-up dialog stack.
OK, so how do you actually inject your global message handler? That happens in your WebApiApplication.Application_Start method in Global.asax.cs:
var builder = new ContainerBuilder();
// Order of execution
builder.RegisterType()
.As< IScorable< IActivity, double >>()
.InstancePerLifetimeScope();
builder.RegisterType()
.As< IScorable< IActivity, double >>()
.InstancePerLifetimeScope();
builder.Update(Conversation.Container);
TL;DR: Yes, they will. Thank you for your time. 😄 Background At Redgate, engineers enjoy a great benefit in that we get are expected to spend 10% of our time to improve on our craft. Having suffered this week with manually having to copy a bunch of properties from a domain object to its HTTP representation, I decided to spend this week's 10% time to see if I could answer the following questions: Can use AutoMapper to simplify mapping between two types? Does it also allow me to map between a regular type and a record type? What about the other way around? Can I use this to reduce the maintenance burden in my product? Mapping between two types [automapper fundamentals] To started and get a basic mapping done, created a .NET 5 ASP.NET Web API project, added the below package references and configured automapper : < PackageReference Include ="AutoMapper" Version ="10.1.1" /> < PackageReference Include ="AutoMapper.Extensions.Microsoft.DependencyInj
In our last installment , we discovered how to start unit testing our Azure Functions, looking at the HTTP Trigger (and evaulating the function's HTTP response). This time, we'll take a look at using the QueueTrigger, getting supporting data from table storage and outputting Blobs. Yup, I'm tossing you into the deep end! What are we trying to accomplish? This time, we will test a function that performs some arbitrary business logic on bank accounts. The function responds to a storage queue request, logs each command and ensures that each received command is executed exactly once. Almost like a real-world function, huh? ;-) In the function above, we are introduced to three types that we need to deal with in our unit tests - the IQueryable interface, IAsyncCollector and the CloudBlockBlob concrete type. IQueryable is easy enough to work with: Introducing the Testable Async Collector When I first started exploring this topic, I figured I could just use my favourit
This article discusses the following error messages that you might receive from a WCF service An error occurred when verifying security for the message HTTP/1.1 415 Cannot process the message because the content type 'application/soap+xml;charset=UTF-8;action="..."' was not the expected type 'application/soap+msbin1' When doing analysis work on existing services, invoking them in a safe test environment is a handy way of getting an understanding of their operations, especially if the documentation has gone missing (or was never written). SoapUI is a tool that can be used to test WCF Services, but did you know that Visual Studio also comes with its own set of tools? Let's start with SoapUI, which is available from http://www.soapui.org/ . Its operations are quite straight-forward; however, you might run into issues when trying to access services that are protected by user credentials, or when accessing services with binary endpoints. I
Comments