Microsoft Bot Framework, LUIS, take some action when the message dont have a intent

2k views Asked by At

I started learn the Microsoft Bot Framework recently, so I started make a Chatbot and I guess I making it wrong

I making the chatbot this way:

--> I get the message's user
--> send to LUIS
--> get the intent and the entities
--> select my answer and send it.

it's ok, but get the following situation:

USER: I wanna change my email. --> intent : ChangeInfo entities: email/value:email

CHATBOT: Tell me your new Email please. --> intent: noIntent entities: noEntities

USER: [email protected] --> intent: IDon'tKnow entities: email/value:[email protected]

I take this situation, when the USER send his email, I send to LUIs, but a email dont have a intent, just have a entity, but a email can be used in a lot Different situations, My question is, How My bot know the context of conversation to understand this email is for change email and not send a email, or update this email or another thing.

my code on gitHub here, its a ugly code, i know, but i make this just to understand the bot framework, after I will let this code more beautiful

2

There are 2 answers

5
Ezequiel Jadib On BEST ANSWER

This should be as simple as using a LuisDialog and a set of Prompts to manage the users flow. Below you will find some quick code I put together to show you how this could be done. You don't need extra steps or adding extra entities, or going to Luis with the email provided by the user.

I would recommend you to read a bit more about LuisDialog and Dialogs in general as the way you are using Luis in your controller I don't think is the way to go.

Here is a good Luis Sample and here a good one around multi-dialogs.

Sample Code

namespace MyNamespace
{
    using System;
    using System.Threading.Tasks;
    using Microsoft.Bot.Builder.Dialogs;
    using Microsoft.Bot.Builder.Internals.Fibers;
    using Microsoft.Bot.Builder.Luis;
    using Microsoft.Bot.Builder.Luis.Models;
    using Microsoft.Bot.Connector;

    [Serializable]
    [LuisModel("YourModelId", "YourSubscriptionKey")]
    public class MyLuisDialog : LuisDialog<object>
    {
        [LuisIntent("")]
        [LuisIntent("None")]
        public async Task None(IDialogContext context, LuisResult result)
        {
            string message = "Não entendi, me diga com outras palavras!";

            await context.PostAsync(message);
            context.Wait(this.MessageReceived);
        }

        [LuisIntent("ChangeInfo")]
        public async Task ChangeInfo(IDialogContext context, IAwaitable<IMessageActivity> activity, LuisResult result)
        {
            // no need to go to luis again..
            PromptDialog.Text(context, AfterEmailProvided, "Tell me your new email please?");
        }

        private async Task AfterEmailProvided(IDialogContext context, IAwaitable<string> result)
        {
            try
            {
                var email = await result;

                // logic to store your email...
            }
            catch
            {
                // here handle your errors in case the user doesn't not provide an email
            }

          context.Wait(this.MessageReceived);
        }

        [LuisIntent("PaymentInfo")]
        public async Task Payment(IDialogContext context, IAwaitable<IMessageActivity> activity, LuisResult result)
        {
            // logic to retrieve the current payment info..
            var email = "[email protected]";

            PromptDialog.Confirm(context, AfterEmailConfirmation, $"Is it {email} your current email?");
        }

        private async Task AfterEmailConfirmation(IDialogContext context, IAwaitable<bool> result)
        {
            try
            {
                var response = await result;

                // if the way to store the payment email is the same as the one used to store the email when going through the ChangeInfo intent, then you can use the same After... method; otherwise create a new one
                PromptDialog.Text(context, AfterEmailProvided, "What's your current email?");
            }
            catch
            {
                // here handle your errors in case the user doesn't not provide an email
            }

            context.Wait(this.MessageReceived);
        }
    }
}
4
owaisafaq On

In my bot flow, I'm using a step variable that I change from the front-end. And another step variable that I change from the bot. This helps me identify which step I am in the conversation. You can do the same to identify what your bot is asking the user.

var data = {step: "asked_email"};
var msg = builder.Message(session).addEntity(data).text("Your message.");
session.send(msg);

If you don't want to send a specific step to LUIS for recognition, you can handle that in the onBeginDialog handler:

intents.onBegin(function (session, args, next) {
  if (session.message.step !== "email") {
    next();
  } else {
    //Do something else and not go to LUIS.
    session.endDialog();
  }
});

You can find the reference to LUIS onBeginDialog here: https://docs.botframework.com/en-us/node/builder/chat/IntentDialog/#onbegin--ondefault-handlers

Details about message data can be found here: https://docs.botframework.com/en-us/node/builder/chat-reference/classes/_botbuilder_d_.message.html#entities