followupEventInput does not trigger the corresponding intent - dialogflow-es

The followupEventInput does always trigger the 'default fallback intent'. I have no idea why it doesn't trigger the corresponding intent.
Any help would be appreciated!
my code:
return {
"followup_event_input": {
"name": "example"
}
}

Can you share some details on the two input context , also as you are trying to invoke the intent via custom event , you can remove the input context. If you want to keep the input context make sure that the context are alive before hitting the intent.
Also , were are you referencing this from :return { "followup_event_input": { "name": "example" } }
You can follow this link to get more idea around custom events :Custom Events

Related

How to call one intent from another intent in lambda (nodejs)

I have a lex bot which triggers lambda where slot conditions are checked(eg:phone number should be 10 digit) and it returns a closing response of text.
function closeresponse(intent_request, session_attributes, fulfillment_state, message) {
return {
"sessionState": {
"sessionAttributes": session_attributes,
"dialogAction": {
"type": "Close"
},
"intent": {
'name': intent_request[ENTITY.sessionState][ENTITY.intent][ENTITY.name],
'state': fulfillment_state
}
},
"messages": [message],
"sessionId": intent_request["sessionId"],
"requestAttributes": intent_request[ENTITY.requestAttributes] ? intent_request[ENTITY.requestAttributes] : {}
}
}
after closing response i am not able trigger any function
i need to trigger another intent which has yes or no response card in same lambda function
If you want to confirm this intent dialogAction have to be confirmIntent.
If you want to call another intent from this intent the dialogAction have to be elicitIntent.
The dialogAction Close indicates that there will not be a response from the user. In other words, this type doesn't take any further input and will end the entire intent. Therefore, Lex doesn't expect further input from the user.
For your case, you need to accept further input from the user so Close isn't the right dialogAction here. As Jinen said, try changing the dialogAction type to ConfirmIntent or ElicitSlot.
If you need the intent to end after the user responds with yes/no, I think ConfirmIntent is right in line with what you're looking to do. For this one, Lex asks the user a yes or no question on if the intent is complete and ready to be fulfilled.
This piece of documentation explains the different types of dialogAction. It's a useful reference for if you get stuck :)

Problem cancelling intent while filling intent parameter with word "disregard"

I have a google Action with intents that require slot/parameter filling. My Action was recently rejected by Google for leaving the mic open without prompting the user and I cannot resolve the issue.
As an example I have an intent named "trunk" which has a parameter "vehiclename".
I invoke the “trunk” intent without filling the vehiclename parameter. The assistant attempts to fill the first parameter by asking me “what is the vehicle name?” (verbiage I've defined to help with the slot filling). I respond with “disregard”. Then the assistant replies with “Sure, cancelling.” (or another similar phrase). I want to know where this response is coming from. The detailed response json is:
{
"conversationToken": "[]",
"expectUserResponse": true,
"expectedInputs": [
{
"inputPrompt": {
"richInitialPrompt": {
"items": [
{
"simpleResponse": {
"textToSpeech": "Sure, cancelling.",
"displayText": "Sure, cancelling."
}
}
]
}
},
"possibleIntents": [
{
"intent": "assistant.intent.action.TEXT"
}
],
"speechBiasingHints": [
"$vehiclename"
]
}
],
"responseMetadata": {
"status": {
"message": "Success (200)"
},
"queryMatchInfo": {
"queryMatched": true,
"intent": "686ab942-5132-451b-9a16-16dbe8648ad0"
}
}
}
This response body has “expectUserResponse”: true which explains why the mic is being left open. And since the phrase "sure, cancelling" doesn't prompt the user, it violates google's design guidelines.
What’s important about this is that I have not created this response! It is nowhere in our intents, and it is not being returned by our API webhook. Our webhook is not even being called in any of this example.
Syntactically it makes sense that google assistant would treat “disregard” as any of the other stop words (e.g. “stop”, “cancel”, “never mind”, etc.) but it doesn’t treat it the same. Any of those other words exits the app as one would expect.
Furthermore, none of these stop words are invoking a “quit” intent which has the actions_intent_CANCEL event attached to it. According to google’s documentation here: https://developers.google.com/assistant/df-asdk/conversation-exits when uttering any of these exit words, the conversation should be routed through to our “quit” intent, but it doesn’t.
I’ve also tried attaching the actions_intent_NO_INPUT action to our quit intent, but that also isn’t triggered in this situation. After the assistant has responded with “sure, cancelling”, the conversation is basically stuck there and I can’t invoke another intent or provide any more dialog to prompt the user.
Main takeaway:
Where is this “sure, cancelling” response coming from?
How do we route the conversation to another intent from that response so that we can prompt the user again OR
How do we route the word “disregard” in such a way to avoid this errant response? Can we disable it?
reminder: this is only an issue when trying to fill an intent parameter, and it is only an issue with the word “disregard”

What is the best practice to avoid utterance conflicts in an Alexa Skill

In the screenshot below, I have got an utterance conflict, which is obvious because I am using similar patterns of samples in both the utterances.
My question is, the skill I am developing requires similar kind of patterns in multiple utterances and I cannot force users to say something like “Yes I want to continue”, or “I want to store…”, something like this.
In such a scenario what is the best practice to avoid utterance conflicts and that too having the multiple similar patterns?
I can use a single utterance and based on what a user says, I can decide what to do.
Here is an example of what I have in my mind:
User says something against {note}
In the skill I check this:
if(this$inputs.note.value === "no") {
// auto route to stop intent
} else if(this$inputs.note.value === "yes") {
// stays inside the same intent
} else {
// does the database stuff and saves the value.
// then asks the user whether he wants to continue
}
The above loop continues until the user says “no”.
But is this the right way to do it? If not, what is the best practice?
Please suggest.
The issue is really that for those two intents you have slots with no context around them. I'm also assuming you're using these slots as catch-all slots meaning you want to capture everything the person says.
From experience: this is very difficult/annoying to implement and will not result in a good user experience.
For the HaveMoreNotesIntent what you want to do is have a separate YesIntent and NoIntent and then route the user to the correct function/intent based on the intent history (aka context). You'll have to just enable this in your config file.
YesIntent() {
console.log(this.$user.$context.prev[0].request.intent);
// Check if last intent was either of the following
if (
['TutorialState.TutorialStartIntent', 'TutorialLearnIntent'].includes(
this.$user.$context.prev[0].request.intent
)
) {
return this.toStateIntent('TutorialState', 'TutorialTrainIntent');
} else {
return this.toStateIntent('TutorialState', 'TutorialLearnIntent');
}
}
OR if you are inside a state you can have yes and no intents inside that state that will only work in that state.
ISPBuyState: {
async _buySpecificPack() {
console.log('_buySpecificPack');
this.$speech.addText(
'Right now I have a "sports expansion pack". Would you like to hear more about it?'
);
return this.ask(this.$speech);
},
async YesIntent() {
console.log('ISPBuyState.YesIntent');
this.$session.$data.productReferenceName = 'sports';
return this.toStatelessIntent('buy_intent');
},
async NoIntent() {
console.log('ISPBuyState.NoIntent');
return this.toStatelessIntent('LAUNCH');
},
async CancelIntent() {
console.log('ISPBuyState.CancelIntent()');
return this.toStatelessIntent('LAUNCH');
}
}
I hope this helps!

Alexa voice with Jovo Framework: Is this possible to get IntentName by utterance? How can I decide which intent to jump to based on user utterance?

I have built an Alexa skill with the following flow:
LAUNCH -> AccountLinkingIntent -> CampaignIntent
In AccountLinkingIntent, presently I am routing to CampaignIntent if Account is already linked.
Up to this everything is working fine. Now I have to add another Intent ActiveContactIntent so that the flow becomes:
LAUNCH -> AccountLinkingIntent -> CampaignIntent / ActiveContactIntent
i.e, From AccountLinking I need to decide which Intent to route to.
The invocation goes like this (CampaignIntent):
Alexa, ask <invocation_name> to get my latest campaign result
OR (ActiveContactIntent)
Alexa, ask <invocation_name> who is my most active contact
Based on the utterance, I need to tell Alexa where to go. So far I have the following in AccountLinkingIntent
...
return this.toIntent("CampaignIntent");
...
But now I need to decide the same as this:
...
if( ... ) {
return this.toIntent("CampaignIntent");
} else {
return this.toIntent("ActiveContactIntent");
}
...
Is there any way to get the IntentName by the utterance so that I can check by the same such as:
...
if( intent_name_by_utterance === "CampaignIntent" ) {
return this.toIntent("CampaignIntent");
} else {
return this.toIntent("ActiveContactIntent");
}
...
Or probably, if it is possible to get intent_name_by_utterance I may also pass the value as the argument of toIntent method if it is allowed to pass a variable!
return this.toIntent(intent_name_by_utterance);
UPDATE:
I have tried the following to see whether the intent name is being returned:
LAUNCH() {
return this.toIntent("LinkAccountIntent");
},
async LinkAccountIntent() {
const intent_name = this.$request.getIntentName();
this.tell(Current intent is: ${intent_name});
},
Invoked the skill in following two fashions:
Alexa, ask <invocation-name> to give me my latest campaign results
Alexa, ask <invocation-name> who is my most active contact
give me my latest campaign results AND who is my most active contact are the utterances for respective intents.
I am using Alexa Test console for testing. In both cases, I was expecting the name of the intent (this.$request.getIntentName()), ending up with
Hmm, I don't know that one.
My intention is to call an intent by its utterance directly by waking up the skill using its invocation name.
Any suggestion?
I think you should treat both intends separately and not through the launch, because for example in the case
"Alexa, ask who is my most active contact"
Alexa skips the launch and jumps directly to resolve the intend ActiveContactIntent.
So just as you have the LAUNCH(){} function you must also have CampaignIntent(){} and ActiveContactIntent(){}.
That way you will avoid Alexa answering
Hmm, I don't know that one.
To verify that the user has already linked his account, you would have to enter a code like the one below:
if (!this.$request.getAccessToken()) {
this.$alexaSkill.showAccountLinkingCard();
this.tell('Please link you Account');
} else {
//code for your respective action
}
I recommend you to check the documentation about "routing with jovo" to have a little more clarity about this topic. You can review it at the following link:
https://www.jovo.tech/docs/routing

Dialogflow node.js fulfilment with multiple entities

I hope someone can help me with this.
I have built an application that uses node.js to fulfil my intent in dialogflow.
For example, I have an intent with one required action:
It goes to my fulfilment:
// Handle the Dialogflow intent named 'Default Welcome Intent'.
app.intent(DEFAULT_INTENT, (conv, params) => {
let categoryId = params.category;
let options = {
'method': 'GET',
'url': apiUrl + 'questions/categories/' + categoryId + '/scenario',
'json': true
};
return request(options).then(response => {
// TODO: What happens if there is more than one question?
let question = response[0];
conv.ask(question.text);
}, error => {
conv.ask('There was an issue with the request: ' + options.url);
});
});
As you can see, this asks a question based on the category sent to the fulfilment.
The problem I have is that the response I want from the user is different for each question.
Once they have responded, it will also have a fulfilment that will ask another question.
Is it possible to do it this way and if so, can someone give me an example of how? If not, can someone help me work out what the alternative is?
The approach you're using makes sense. The key thing to remember is that Intents capture what the user says, not how you handle what they say. You can influence which Intent gets triggered by setting an Input Context, and making sure you have previously set an Output Context for it.
One possible approach would be that for each question you're asking, you set a corresponding Output Context for that question. You can then have one or more Intents that take this as the Input Context. These are otherwise regular Intents, so you'd handle them normally. You might want to clear the context (by setting its lifespan to 0) after it matches, so you don't accidentally match it later.
For example, if your question contains, not only the text of the question, but also the context name of the question, the code might look something like this:
conv.ask( question.text );
conv.contexts.set( question.contextName, 5 );
Let's say that the question object looks something like this
{
text: "What is your favorite color?",
contextName: "color-favorite"
}
You might have a Dialogflow Intent that handles this that looks something like this
Note that the Output Context has explicitly set it to 0, which will remove it. You can also do this in your fulfillment code with something like
conv.contexts.delete( 'color-favorite' );

Resources