How to get the output context in dialogflow? - dialogflow-es

I have created the bot and it contains two intents, each intent is having 20 follow up intents, after completion of one intent it automatically calls the follow-up intent. So the problem is if the user has answered 10 prompts i.e up to 10 follow-up intents and after sometime, the user wants to continue from 11th follow-up intent. Is there any possibility to do that. Currently, I am saving the data of the user previous conversation and trying to start from that conversation point, but after starting the conversation it automatically ask the 11th followup intent prompts and then again it goes to the default-welcome intent instead of continuing with the 12th follow-up intent.

Apart from the lifeSpan that we set in the context, there is also a time-limit for the contexts. After 10 minutes all the contexts expires so it might be the problem in your case.
In the documentation, it is given that time-out is 20 minutes, but after a lot of testing, it was observed that time-out is indeed 10 minutes.
What you can do is store the context in the some cache or DB after each call, and before calling Dialogflow, append the context with your query from the cache/DB.
I have done the same thing and it is working flawlessly.
Hope it helps.

I don't know if you did this but I would recommend setting the lifespan of each output context to 1. You might also want to programmatically modify the outpu context if you're using the fulfillment funcitonality. You said you're already keeping track of the previous conversation so I'm assuming that setting it programmatically would be a viable solution for you.

Related

DialogFlow: if an intent is triggered three times, how to store and reuse the parameters' value of each time (1st, 2nd, and 3rd)?

In DialogFlow: I have an intent that users would possibly trigger multiple times. How can I store and reuse the parameters' value each time?
For instance, the intent name is called "progress_tracking", another intent is "get_progress_report".
First time triggering "progress_tracking" intent:
User: I have finished only 1/5 of the project in the first 10 minutes. I'm not very confident.
Chatbot: thanks for sharing the progress. You should believe in yourself!
Second time triggering "progress_tracking" intent:
User: I have finished only 1/2 of the project. It used 5 minutes. I think I can finish it on time.
Chatbot: Glad you progressed from 1/5 to 1/2. Earlier you are not very confident. How are you feeling now?
3rd time triggering "progress_tracking" intent:
User: I've done my work! It took me only 30 minutes!
Chatbot: well-done!
triggering "get_progress_report" intent:
User: can you give me a report about my progress?
Chatbot: sure! in the first session, you completed 1/5 of the work in 10 minutes. In the second session, you ...........
Looking for some guidance! Thank you in advance!
For your use case I used the concept of Input and Output Contexts in my Intents. I also used the concept of conversational turns.
You can refer to the below mentioned steps:
I created Intents and passed the Input and output contexts into it.
I created one custom Entity i.e #values to store the fractional data (½,⅕ etc) as #sys.number which returns decimal values (0.2,0.5).
I passed the parameter value from one Intent to another by using the #context-name.parameter-name and for the same Intent I passed the parameter values by using $parameter-name as per this doc.
You can refer to the below output screenshot as per your requirement
output 1 :
output 2 :
You can use the below Agent on your end to check for the flow of contexts inside the intents. You need to import the Zip agent to your project as per this doc and it will work.
Zip file : Agent Zip file

How to manage the conversation flow if face timeout limit (5 seconds) in Dialogflow / Api.ai?

I am making a bot on Dialogflow with a Fulfillment. Considering the given strict 5-second window in DialogFlow, I am getting [empty response] as a response.
I want to overcome this issue, but my web service requires more than 9 seconds for the execution.
I am considering to redesigning the conversation flow in such a way that we will start streaming audio till the Response is processed.
Example:
User Question: xx xxx xxx xxxx xxxxx?
Response: a). We'll play fixed audio to keep the user engaged for few seconds till it finds a response text in the back end; b).
Receive answers from the web service and save them in the session to
display further.
How can I achieve this and how can I handle the Timeout issue?
You're on the right track, but there are a number of other things to consider.
First, however, keep in mind that anything that is trying to "avoid" the 5 second timeout already indicates some issues with the design. Waiting 10 seconds for a reply is a pretty long time with something as interactive as voice! Even 5 seconds, which is the timeout, is a long time. (And there is no way to change this timeout.)
So the first thing you may want to do is consider if there is a better/faster way to do what you want.
If not, the rough approach would be something like this:
Get the request from the user.
Track a unique identifier, either tied to the user or tied to the session. You'll be using this as a key into some kind of database or data store.
Start the API call as part of an asynchronous request or in another thread.
Reply immediately that you're working on it in a way that the user will send another request. (See below for this issue.) You'll want to make sure that the ID is maintained as part of this session - so you'll need to save it as part of the Session data.
At this point - you're basically doing two things in parallel.
When the API call completes, it needs to save the result in the datastore against the identifier. (It can't save it in the session itself - that response was already sent back to the Assistant.)
You're also waiting for a reply from the user. When it comes in:
Check to see if you have a response saved for this session yet.
If not, then go back to step 4. (You may want to track how many times you get here and give up at some point.)
If you do have the result, reply to the user with the information.
There is an issue with how you reply in step 4, since you want to do something that will guarantee you another request from the person expecting an answer. There are a few possible approaches:
The most straightforward way would be to send back a Media response to play a few seconds of "hold music". This has the advantage that, when the music stops, it will send an event to Dialogflow which you can capture as an Intent and then continue with step 5.
But there are some problems:
Not all versions of the Assistant support the Media response. You will need to check to confirm the feature is supported before you use it and, if not, use another approach (see below).
The media player that is presented on some Assistants allow the user to stop playback, or will not correctly send an event when the audio stops in some situations. So you may never get another request in this session.
Another approach involves some more advanced conversation design tricks, so may not always be suitable for your conversation. Your response can say that you're looking up the results but then ask the user a question - possibly one that is related to other information that you will need. With their reply, you can collect this information (if you need it) and then see if you have a result yet.
In some conversations - this works really well. For example, if you're looking up flights to somewhere, while you're looking that up you might ask them if they will need a hotel or rental car, which you might ask about anyway.
Other conversations, however, don't easily have such questions. In these cases, you may need to ask something that isn't relevant while you stall for time.

Dialogflow: Call third party api from webhook and wait for response

I am creating a chatbot which have an intent with a payment link. So on trigger of this intent, I made call from webhook fulfillment to third party api which takes approx 20secs to respond. But in this period of time my response is timed out as it is limited to 5 sec from google.
Can you please suggest what approach should I follow. I just want to wait for approx 20 sec to respond.
Thanks.
one option is to keep the conversation alive using events (generated by the webhook) which trigger dedicated intents.
When a payment must be performed the webhook starts a background process to deal with the 3rd party payment API, and sleep for 4-5 sec, after that generates an event (setFollowupEvent PAYMENT_IN_PROGRESS). This event is associated to a DialogFlow Intent which fires as soon as the event is sent back to the platform.
At this point you have another incoming webhook call: check status of the payment, if it is still in progress (likely after 5 sec) then sleep 4-5 sec and send another event (setFollowupEvent PAYMENT_IN_PROGRESS_2) which produces the same workflow.
There are so many times you can do this (I think a max of 3), so you need to cater for the fact that the payment does not terminate in time (fallback scenario).
A smart option could be to keep engaging the user with the conversation, not always easy, depending on what your chatbot is about.
Hope it helps.
The short answer is that you can't.
The longer answer is that you need to think about this as a conversation. If you asked someone a question, and didn't get any response from them for 20 seconds - that would be pretty uncomfortable, wouldn't it?
Instead, we have come up with ways to compensate for that silence. In a physical conversation, people may engage with you and ask you questions to fill the time. If you're on the phone, they may play hold music. Or we may end the conversation for now and tell them later when there is a result.
When building an Action, we have similar parallels that may work better or worse based on our exact needs.
Engaging in conversation
One approach is that when we get the request from the user, we do two things:
Start a task that will execute the query and save the results in a separate "answer database", indexed against the user, a session ID, or some other temporary id we can generate and use later.
While the query is running, we reply to the user saying we're working on it, and asking them another question.
Then, when they reply with their answer to this other question, we can check if we have an answer for them in the database. If we do, we'll reply with it. If not, we'll repeat step 2 until we do.
This approach works well if we either have other questions to ask, or if we're in a good place to "make small talk". Picture booking an airline reservation - while we look up flights, we may want to ask if they prefer window or aisle seats (Which we'd need to ask later) or make small talk by asking if they're traveling for business or leisure.
Using "hold music"
A variant of this allows us to play some hold music while we're processing the answer.
Instead of asking a question in step 2 above, we reply with a Media Response that plays 20 seconds or so of music. When the music completes, our fulfillment webhook will be sent a MEDIA_STATUS event and we can either return the information from the answer database, or say we're still working on it and play more music.
This is less conversational, but may work better if we don't actually have anything to say in the meantime.
Sending a notification
If the response may take a very long time, then it may just be best to let them do other things and to send a notification or a text or email when you have a result. These cases, however, require the user to have registered with you in some way and are probably more appropriate if you have a long-standing relationship with the user.
Summary
You should be returning results as quickly as you can to keep it feeling like a conversation. When you can't, consider other means, just like how we would consider what it would be like if we were talking to another person.

Follow up intent for NO INPUT not firing with dialogflow

I have a "book reading" action and I tried to add a follow up intent for my read intent to reprompt a user if there was no response. Following the doc https://developers.google.com/actions/assistant/reprompts - my webhook never gets called.
However, if I add the no input handler as a main intent, I do get this event!
Is this a bug or did I miss something.
The no-input event is a little unusual, since it is handled differently internally compared to many other events. It would not surprise me if this difference requires it to be handled as a top-level Intent. You may also wish to just try setting the context in your book reading portion and having this as an input context for your no-input event.
However... this will also likely not do what you want it to do.
The no-input event will automatically terminate the conversation after three sequential events, even if you don't explicitly close the conversation.
The current way to handle this would be to use a Media Response after each portion you read. This would include a very short audio file. After the audio plays, your Action will be actions_intent_MEDIA_STATUS event, which you can use to trigger the next portion to be read.
No Input will be main intent as it can be reused by other intents. You may need to save bots response in a parameter in the context to check what the bot replied when handling the re-prompts from this generic No Input intent.

Pick up session later again

is there a possibility to preserve a session with Actions on Google?
I would like that users can leave the the current session, do something in between for a some minutes / an hour and then start with the next invocation exactly where they have been before. Is that possible?
It isn't impossible, but you would have to save the state yourself (ie - there is nothing that Actions provides that would do this for you automatically).
If you're using API.AI, for example, you could save all of the current contexts in your database. When the user returned, you could see if you have saved contexts and, if so, return them in the response as current contexts (along with any voice message saying you've done so).
As far as API.AI is concerned at that point - you're at the same place you were before.

Resources