I have an intent with webhook and slotfilling enabled for validation and it have 4 parameters marked as required, so my server can validade the parameter value.
The strategy that I'm trying to use is: reset the context for invalid parameter value, so the dialogflow can ask it again.
Here is an example entering an invalid value:
On responding "Brasília" the webhook makes a request to my server. My server knows that is an invalid value and respond with the context presented on the previous image.
This is the result:
Notice that the first 4 context match with the previous image, its everything ok here. But dialogflow adds another context. That context is a request for the next parameter, called "motivo" and if I respond back, the response will be stored on this param. After this, dialogflow prompts back for the "local" param.
The conversation runs like this:
User: I want to register a call
Dialogflow: From where you want to register? Aracaju, CAB, Itabuna or Salvador?
User: Brasília
Dialogflow: Please, describe the reason
User: My network wireless is not working
Dialogflow: From where you want to register? Aracaju, CAB, Itabuna or Salvador?
...
What was supose to be:
User: I want to register a call
Dialogflow: From where you want to register? Aracaju, CAB, Itabuna or Salvador?
User: Brasília
Dialogflow: From where you want to register? Aracaju, CAB, Itabuna or Salvador?
...
What I need to know: Am'I responding with the correct contexts? Is there a way to prevent dialogflow creating this new "registrar_dialog_params_motivo" after responding with a new contexts?
Obs.: I'm using a Nodejs server, responding the webhook as the docs suggests.
Edit 1: I know that I can use an entity for this situation. However there is some cases that I need to make multiple validations on backend to procede, something like an user id, etc.
If the intent “Intent_Name” has some input_context defined already, then you need to set that context again as output_context and reply something like you have entered an invalid location, and please enter again.
If the intent does not have any input_context, then you can simply reply you have entered an invalid location. Please enter again, and your intent should be able to catch that too. However, this can cause problems as well.
What I would recommend is having another intent “Intent_Name_followup” with an input_context as location_validation_failed in the logic. If the location is incorrect, you can set this in the output_context to reply to the user.
Related
my project is to have a chatbot that can sell electronic device like resistor, diode and so on.
There are many type of resistor and diode
I have my intents in dialogflow so when user choose one item I need to store it into php session variable so when user have finished so I need to restore that items in session variable but it doesnt work
Recieve dialogflow intent that is called "tomar_cantidad"
if (intent_recibido("tomar_cantidad")) {
$modelo = obtener_variables3('modelo');
$cantidad = obtener_variables2('cantidad');
//enviar_texto(print_r($cantidad));
$datos_usuario = array('modelo'=>$modelo,'cantidad'=>$cantidad);
$_SESSION['datos_usuario'][]= $datos_usuario;
enviar_texto(print_r($_SESSION['datos_usuario']));
}
enviar_texto is a method to send information to dialogflow(that is for testing purposes).
I recieve session variable but only store the last item that user choose not all items
The issue is that the PHP $_SESSION variable is tied to an HTTP session, which is usually implemented with an HTTP cookie. But Dialogflow doesn't manage HTTP cookies when it sends messages to a webhook, so each fulfillment call is a new session each time.
You have a few ways you can approach this:
Get the Dialogflow session ID and store the information against this ID
Store any values you want to store between turns in the conversation as a parameter in an Output Context. You should set the lifespan for the Context to a large number, 99 is typical, or re-set this as the Output Context each time. Then, you can read the parameter in the named Context when you need the information.
Creating a chatbot using IBM's Watson Assistant, and I need to make a determination I'm trying to send the zip code to a third party API that will return the city and state so I know where the client is located so I can (a) know which services are available and (b) have a better idea on how to direct the conversation from there. But I am at a loss as to how to do this.
I can do this from within Python, but trying to code it in a JSON editor doesn't work.
Webhooks are used to do this from inside the Dialog skill in an Assistant.
IBM Watson Assistant webhooks documentation
The docs do not mention it, but the Assistant will POST to the URL with a JSON body containing the parameters you specify as key value pairs. For example if in the Dialog Node the context variable $zipcode equals '99501' and you specify the parameters "key" = zipcode and "value" = "$zipcode".
Then the HTTP post body is
{ "zipcode" : "99501" }
The response from the service is put into another context variable, and this can then be used for other things. For example in the Dialog Node which calls the webhook, in the "Return variable" section put webhook_result_zipcode to put the response into that context variable.
You can also in the dialog node Assistant responds section, return a message which contains some part of the webhook response. For example in the Dialog Node editor
"If assistant recognizes" $webhook_result_zipcode "Respond with" The code is "$webhook_result_zipcode.response.result.sent" This will tell the user the code which is returned deep within the webhook response in response.result.sent in the response body.
You can also click the Cog next to the response, and in the dialog, click ... next to "Assistant responds" and open the context editor. This opens a context editor (at the top of the dialog) which allows setting of another context variable from part of the webhook response. For example under "Then set context" for "Variable" set zipcode and for "Value" set "$webhook_result_zipcode.response.result.sent.zipcode". This will extract a zipcode value from deep within the webhook response and place it in the context variable zipcode.
Of course then you must find a zipcode location service which accepts a HTTP post and looks for the code in the body.
I have an Action that integrates with Dialogflow which as part of the conversation requests access to the user's location.
This is fulfilled via a webhook:
app.intent('actions_intent_PERMISSION', async (conv, params, permissionGranted) => {
if (!permissionGranted) {
app.intent('actions_intent_PERMISSION - no', (conv, params) => {
conv.ask('sad face, you said no to my permission request!');
});
// conv.ask(`Ok, no worries. I'll have to figure out how to get your postcode. follow-up intent I suppose`);
} else {
conv.data.postcode = conv.device.location.zipCode;
conv.ask(`Ok great - please give me a minute, I have to get data from a few different places.`);
//use postcode to make some other API calls
}
});
Everything is fine when the user gives permission but when they don't give permission I would like to pass off to an intent that asks for their location manually ('what is your postcode/zipcode?').
As per the screenshot I tried creating a followup intent to actions_intent_PERMISSION called actions_intent_PERMISSION - no but this causes the app to crash.
What is the best way to pass the conversation to another intent is the value of permissionGranted is false?
Your question doesn't quite make sense the way you've asked it. Intents represent what the user has said and not what you do with it - that is what your webhook does in an Intent Handler. There is nothing (technically) stopping you from replying to the user asking for their zip code by just replying differently.
If you want users to be able to trigger some Intents if they have given permissions, and other Intents if they have not, you can set a different Context for each. Then you would set some Intents to only be triggered if the "permitted" context was set, and others only if the "notpermitted" context was set.
However, you have a non-technical problem to consider. If they aren't giving you permission to get their location, why would they tell you their location? It also is likely that the reviewers would reject it, saying that you should be getting location information through the provided API.
Is there a way to temporarily redirect from one intent to another in order to fill slots or session attributes and then return to the original intent to be responded to or fulfilled?
My use-case is for asking for an account PIN as a secondary authentication after account linking. For instance, if someone asks "What are my account details?", I want that intent to change in the session attributes if it exists and if not, temporarily redirect to an intent that will prompt them for the PIN and set it...then come back and answer their account details request. Similar to the example below:
const IntentHandler = {
canHandle(input) {
return (
input.requestEnvelope.request.type === 'IntentRequest' &&
input.requestEnvelope.request.intent.name === 'MyIntent'
},
handle(input) {
const { accessToken } = input.requestEnvelope.context.System.user
// ... do stuff with accessToken
if (!input.attributesManager.getSessionAttributes().pin) {
// redirect to other intent to set the pin session attribute
}
// ...response to intent request
}
}
I can get this working with a single intent using slot filling prompts but this is a common task for several intents and would like to separate it out so it doesn't have to be configured in the console for all that require it.
FYI: using the ask-sdk for Node.js
Is this possible with the current version of the ask-sdk?
Yes, Alexa makes it easy now to switch between intents and jump right into eliciting a specific slot for the new intent.
I would use the ElicitSlot Dialog Directive and include the updatedIntent object for the new intent.
updatedIntent
Use this to change intents during the dialog or set slot values and confirmation status. See Change the intent or update slot values during the dialog. If you don't need to change the intent, slot values, or confirmation statuses, you can leave this property out of your response.
When you switch intents with this parameter, Alexa attempts to elicit the specified slot value on the new intent. The next IntentRequest to your skill will be the new intent, not the original.
Example:
Intent A is missing access token.
Intent A directs Alexa to elicitSlot "pin" from Intent B. (include info in sessionAttributes such as "previousIntent" or "nextIntent" to use as direction to Intent B)
Alexa responds to user with Intent B's elicit prompt for slot "pin".
User provides pin.
Alexa provides user input to Intent B (not A) with slot "pin" filled and Intent B sets the access token in sessionAttribtues.
Then Intent B checks sessionAttribtues for direction of which intent to return to and which slot to elicit from that intent. So you can either confirmIntent or elicitSlot for Intent A.
Intent A will receive the next user input and now detects access token.
Notice that you will have to address the user with something between switching intents. If you are using confirmIntent then it can be a simple Yes/No confirmation question such as, "Thank you for your pin, would you like me to retrieve your account details now?". The user says "Yes", and that is sent back to Intent A to complete what it started.
If you don't want this extra back and forth with the user, then as far as I know, you'll have to build the pin slot into each intent you may need to elicit it. That way, you just stay within Intent A. Less efficient code, but more efficient conversation, so it's a bit of a trade off.
I am building an Alexa skill in node using the alexa-sdk. I am using a dialog model to handle the user interaction. I am having some trouble passing the flow along to new request types, such as from the launch request to an intent request.
Below is an example of my handlers and what I want ideally. My specific usecase is that I would like to ask some questions of the user and then send them to different intents based on what they answer. In the intents I would like to have access to the request objects, as if they entered that intent originally, so the dialog model can do its work.
const handlers = {
'LaunchRequest': function () {
this.emit('Entry'); // this does not do what I want
},
'Entry': function () {
let request = this.event.request; // this is the launch request object.
// I would like to get the request object for Entry, like if the user started here
// ask some questions, potentially passing the torch to a new intent based on the answers
}
};
So, is there any way to "call" an intent like the user originally made a request to that intent? Sorry if I missed something obvious in the documentation, I searched around pretty thoroughly I think, but there is A LOT of documentation. ps: I could manually construct the request object of course, but I really should not have to I feel.
I am pretty sure there is no way yet to call on an intent as you are asking.
If you go through the syntax description of dialog directieves here, it says:
Note that you cannot change intents when returning a Dialog directive, so the intent name and set of slots must match the intent sent to your skill.
With returning a dialog directive you are able to 'elicit' or 'confirm' slots or intents, or even let a delegate handle your dialog for you, with prompts and reprompts set in the Skill Builder.
As far as i know, the only solution to trigger a specific intent is to make the user invoke it. You can guide the user into saying a specific utternace to trigger your intent.
As for saving older requests, you can use session attributes. Just build a response after your Launch with a session attribute containing the whole LaunchRequest.
"sessionAttributes": {
"oldRequest": this.event.request
}