I am using chatconnector to connect my Bot to an frontend chat app and writing the bot's response to my own database. The problem is when I am validating a prompt the bot responds but there's no API for me to grab the validation response.
bot.dialog('/', [
function (session) {
builder.Prompts.choice(session, "Which color?", "red|green|blue");
},
function (session, results, next) {
//after the user respond, the bot validates the input, if it's not
//one of the choices, this next function in the waterfall doesn't
//even run, therefore I have no way to write the bot response
//into my own chat database and render it for the user
}])
Is there anyway I can grab the bot's response to the failed validation?
Short answer: No.
Long answer: This is not currently a feature of the SDK. If the input response to a choice prompt does not match any of the provided options, aka "intents", then the waterfall dialog does not proceed to step 2 because there is no match response. The system design is to warn the user and wait for them to input one of the provided choices either by name or number (depending on the channel). Eg. if the answer does not match any of the choice options, the framework will prompt the user with "I didn't understand. Please choose an option from the list." until a valid option is input.
Hacker answer: You would need to modify the SDK to suit your needs in this scenario, and then deploy you bot using your customized version of the SDK. The file you are looking for is Microsoft/BotBuilder/Node/core/src/dialogs/PromptChoice.ts
I have written a custom recognizer that allows Choice Prompts to be configured as optional. I.e. if a user does not click a button, but instead enters text that cannot be matched to a given choice, your waterfall dialog will proceed and you can handle the given user input individually.
Have a look at this:
https://gist.github.com/vwart/faddaee279aab5127707862ec4994574
The provided snippets are not compilable or runnable, I copied them together from my productive code. But it should be enough for you to apply the solution for your bot.
How it works:
CustomChoiceOptions:
When you start a Choice Prompt you pass a new bool flag called "optional" within the options.
OptionalPromptRecognizer:
A global recognizer registered at bot initialization. It is looking for messages in reply to a prompts that carries this optional flag. If it finds one, it will dispatch you a dummy dialog with a low score. The low score is important, so that other recognizers can beat it. E.g. LUIS Recognizer or the actual choice recognizer, which will return a score of 1.0 if the user actually hits a choice button.
If there is no recognizer that claims a reasonable score, our recognizer will be considered the best option and therefore our dummy dialog is triggered.
optional-choice-dispatcher:
The dummy dialog does nothing but creating a fake PromptChoiceResult with the index -1 and an entity that holds the actual user input. This result is then passed down your dialog stack, that means your next step can handle it.
This case can be identified due to the index of -1.
Have fun!
Related
I'm having an issue when attempting to enter specific intents based on the value of a property.
I currently have a question that gets asked, which then fires off to the Microsoft Translator via a HTTP Request and from that, it fires off to the LUIS API with that text.
After that, I would like to enter an intent based on the top intent that the LUIS API Call brought back.
I have the Translator and The LUIS API bringing back values and I can output these using Send Responses:
However, when I attempt to call an intent based on the value of the property, I just get an Object Reference error:
Is what I'm trying to do possible and if so am I going about this entirely the wrong way causing more issues for myself?
Thanks In Advance
I'm trying to understand exactly what you are trying to achieve. Do I summarize it correctly as following?
You start a main dialog. In that dialog you take some user input.
You translate the input, and manually send the the translated text off to LUIS for intent recognition.
Based on the recognized intent, you want to start a specific sub dialog.
I don't believe you can just 'call an intent'. An intent is the result of a LUIS or Regex recognizer, which is processed automatically by Bot Framework. The recognizer is processed at every user input. There is no need to call LUIS yourself as a HTTP request. The recognizer (LUIS or RegEx) is configured on the main dialog properties in Bot Framework Composer:
Although in this case it looks like you are manually doing the LUIS intent recognition, because you want to do translation upfront. To achieve that scenario with the built-in recognizer, you would need a translation middleware. There is a short discussion going on here on Github about translation middleware for Bot Framework Composer, although the sample code is not ready yet.
While there is no code samples for the translation middleware yet, I believe what could already help you today is to start a subdialog based on the recognized intent, similar to what you already show in your screenshots.
Basically instead of "Send a response" at the end of your dialog, you would have something following like:
My sample here uses user input instead of the recognized intent. You would replace the user input with your intent variable instead. Based on the recognized intent, you would be able to spin up a specific dialog to handle that recognized intent.
The result would look something like:
About triggers, what you currently configured in your screenshot shows "no editor for null". I believe this might cause the "object reference" issue. Normally it should display a trigger phrase. For example, the below means:
If user inputs the text "triggerphrase"
And the dialog variable 'topintent' was previously set to 'test', then run this trigger.
I have a custom Alexa Skill similar to some Q&A skill , in which I'm asking the user for a response (say option_1, option_2, option_3), but when the user responds with one of these asked options a different intent (say ruleIntent) is triggered because the option text is somewhat similar to its utterances.
I think it is not a good design if more than one IntentHandler is triggered for same( or similar) phrase, but then I don't know the text of options in advance to avoid this (or what the user is going to speak out as the answer of asked question). What if I can somehow maintain the context of user's response, I think that will be one of the solutions.
Example : -
1.User : Start a Science test {Invokes testIntent }.
2.Alexa : Okay, but before starting do you want to know the rules. Please answer in Yes or No. { response generated from testIntentHandler}
3.User : Yes { invokes many intents }
In line 3 even if I hard-code this to a Intent (say ruleIntent) , then what will happen if some question contains its options as Yes or No. How will I differentiate that and map that to the response of asked question.
One way to deal with this is to track the state using persistent or session attributes.
You can do a check of the state in the canhandle method to route the user to appropriate test intent
One way to solve this could be to use Dialogs. You can use auto delegation for dialogs
Enable auto delegation, either for the entire skill or for specific
intents. In this case, Alexa completes all of the dialog steps based
on your dialog model. Alexa sends your skill a single IntentRequest
when the dialog is complete
Delegate the Dialog to Alexa
Currently I'm creating an Action for the Google Assistant.
In this Action, I ask the user to provide its phone number. After this, another intent will repeat the phone number given, and asks if it's correct. If the user responds with 'no', I would like to redirect the user back to the first intent, so it can provide its phone number again. It should be a kind of loop.
(I'm working in a local environment, so only the intents are created within Dialogflow.)
I tried to apply contexts for this case, but in someway it won't succeed.
Thank you guys!
Remember that Intents represent what the user has said, and not what you are doing with that data. So saying that "another intent will repeat the phone number" suggests that you're making some things more complicated.
A better design is likely to have the Intent that collected the data to several things:
Repeat the phone number back
Prompt if this is correct
Set a content indicating you have prompted for confirmation
You can then have another Intent handle the "yes" or "no" statements responding to this prompt. The user may say other things, remember, including giving a correction to the phone number.
See also these articles (based on a StackOverflow question and answer) on designing a conversation and the Dialogflow Intents based on that conversation:
Thinking for Voice: Design conversations, not logic
Conversation to Code (Part 1)
I'm currently working on Microsoft Botframework Node.js SDK.
I was wondering if there was a way to hard code a user response for a prompt through the code?
The scenario is to add/ remove people to the meeting. The dialog contains 2 waterfall functions. The first is used to handle card actions, and display the default prompt to enter a username to search for. The second function searches for the username and displays the results in a carousel. Selecting a user from the card adds the person to the meeting (handled in first waterfall function).
Once a user is added to the meeting, the first waterfall function displays the currently added people in the meeting with the option to remove, followed by the default prompt to search users. Since it expects a prompt response, the "remove" actions causes a break and the bot's response is: "I didn't understand. Please try again.".
So is it possible to hard code a null user response through the code when the "remove" action is triggered? Or is there any other way to bypass a prompt without any input from the user's end?
What I'd like to incorporate into my bot is a way to prompt the user for essentially free-form, natural language text and then save it.
I thought this would be simple enough using:
builder.Prompts.text(session, prompt);
But it appears the UniversalBot is attempting to interpret and route based on the text supplied by the user.
I do have LUIS wired into the bot as the recognizer and it's clear that's what is coming into play here because it's resolving to one of my defined intents. Or at least it's saying it recognizes that intent but it doesn't actually take the user to that dialog.
Is there some way to achieve what I'm after? Essentially disabling the recognizer while receiving the response to a prompt?
I'm coding in Node.
You can disable the LuisRecognizer by using .onEnabled(). You can find an example here on it in action. You'll need a condition to to enable and disable the LuisRecognizer, which could be checking the dialogStack, or setting a property inside of session.conversationData.
Alternatively, if you're okay with triggering the None intent, you can use .onFilter(). This will allow you to change the recognized intent to the None intent. Your condition here would be checking to make sure the dialogStack is empty. You can find an example for onFilter() here.