Microsoft Bot Framework .NET - Build flexible conversations using Scorable Dialogs

By: James E Mann

9   0   1088

Uploaded on 04/18/2017

In this video we take a look at how we can use a technique to allow users to change their minds or back out of conversations. Scorable dialogs allow this by decoupling the conversation hierarchy.

We take a look at an existing hierarchical bot using a traditional conversation tree and see how to improve it using scorable dialogs.

https://github.com/jamesemann/scorablebot

Take a look at Gary Pretty's blog where he explains in detail about setting up Scorable Dialogs http://www.garypretty.co.uk/2017/04/13/using-scorables-for-global-message-handling-and-interrupt-dialogs-in-bot-framework/

Comments (5):

By anonymous    2017-09-20

This is how I did it, I made a scorable for the word "cancel" this way from any point in the conversation you can start over. Also here is a good simple video to watch

    namespace PizzaBot.Dialogs
{
    using System;
    using System.Threading;
    using System.Threading.Tasks;
    using Microsoft.Bot.Builder.Dialogs.Internals;
    using Microsoft.Bot.Builder.Internals.Fibers;
    using Microsoft.Bot.Connector;
    using Microsoft.Bot.Builder.Scorables.Internals;

    public class CancelScorable : ScorableBase<IActivity, string, double>
    {
        private readonly IDialogTask task;

        public CancelScorable(IDialogTask task)
        {
            SetField.NotNull(out this.task, nameof(task), task);
        }

        protected override async Task<string> PrepareAsync(IActivity activity, CancellationToken token)
        {
            var message = activity as IMessageActivity;

            if (message != null && !string.IsNullOrWhiteSpace(message.Text))
            {
                if (message.Text.Equals("cancel", StringComparison.InvariantCultureIgnoreCase))
                {
                    return message.Text;
                }
            }
            return null;
        }

        protected override bool HasScore(IActivity item, string state)
        {
            return state != null;
        }

        protected override double GetScore(IActivity item, string state)
        {
            return 1.0;
        }

        protected override async Task PostAsync(IActivity item, string state, CancellationToken token)
        {
            this.task.Reset();
        }

        protected override Task DoneAsync(IActivity item, string state, CancellationToken token)
        {
            return Task.CompletedTask;
        }
    }
}

then in my message controller i built a special case to handle it where await SendGetStarted(iActivity, activity); just starts the bot from the beginning:

    public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
{

    if (activity.Type == ActivityTypes.Message)
    {               
        try
        {
           await Conversation.SendAsync(activity, () => new RootDialog(activity.ChannelId));
        }
        catch (Exception e)
        {
            IActivity iActivity = activity as IActivity;
            await SendGetStarted(iActivity, activity);
        }
    }
    else
    {
        await HandleSystemMessage(activity);
    }
    if (activity.Text == "cancel")
    {
        IActivity iActivity = activity as IActivity;
        await SendGetStarted(iActivity, activity);
    }
    var response = this.Request.CreateResponse(HttpStatusCode.OK);
    return response;
}

you also nneed to add something like this to your Golbal.asax

       var builder = new ContainerBuilder();
        builder.RegisterType<CancelScorable>()
            .As<IScorable<IActivity, double>>()
            .InstancePerLifetimeScope();

        builder.Update(Conversation.Container);`

Original Thread

By anonymous    2017-09-20

There is a few options you have here.

  1. You could use a list entity in LUIS. Although it does not sound as if you are using LUIS already.
  2. You could use scorable or an if statement in your ActivityType.Message section to catch the word "search" (or something similar) then implement logic to search a collection of some sort based on the user's next message. great video on scorables here
  3. You could create a card with a text box input that you could implement logic to use that to search some sort of collection.

    There is node/c# versions of all of this

    rich cards samples
    Rich cards doc
    Adaptive cards doc
    Adaptive cards sample

    I'm sure there is more solutions others can add as well

Original Thread

By anonymous    2017-11-20

This may be a good use case for a Scorable. There will be some tradeoffs though.

Your user would just have to type "unsubscribe" at any point or click a button with the postback/imback value of "unsubscribe". You can choose any text you desire as the recognized value. This way your unsubscribe logic will run independent of any other logic and you will not get trapped in your flow as you are now. Since the unsubscribe event will be handled by the global handler (Scorable) you can just handle any other message sent by the user as you normally would, in your case in a LuisDialog.

If you do not want your user to be able to unsubscribe at any point this solution will probably not work for you. In this case please post your code as @Ezequiel asked so we can better understand your flow. This would not be the only way in which to handle your flow.

Here is some info to look over:
Scorable Video

Scorable Blog

Scorable Blog

Original Thread

Recommended Books

    Popular Videos 500

    livinlifeloudd

    Submit Your Video

    If you have some great dev videos to share, please fill out this form.