A conversation is the exchange of ideas between two or more people. In other words, it's a series of questions and answers. The conversational app that you're building for your interaction also has two sides: the end-user can ask, "What happened today in the past?" and your bot will respond with an interesting fact from the fact and might also add, "Do you want me to send you a link to this article?" The end-user can then approve the offer or respond with something like, "No, please deliver it to my office." As we can see, a true contextual conversation isn't a simple Q&A. Each end user can use a different order or flow of information — and your app needs to handle all the different flows.
In a previous article, you built a "what happened today" conversational application that used Zapier to integrate with more than 750 web apps. In this tutorial, we will add contextual conversation to your application, Alexa skill, Google Home action, or chatbot.
Some of the information in this guide is more developer-centric, but don’t be discouraged if you're not a developer. If you follow the steps as they’re outlined, you will have a deployed, working "What happened today?" app.
Store and Retrieve Context
To store and retrieve a session context, you should use ConversationRequest's session object.
You can store a simple string using the set
method:
req.getSession().set("lastIndex", "1");
...and retrieve it later using get
:
req.getSession().get("lastIndex");
You can store JSON objects using JSON.stringify
:
req.getSession().set("myContextObject", JSON.stringify({lastIndex:1}));
And retrieve it later using JSON.parse
:
var myContextObject = JSON.parse(req.getSession().get("myContextObject"));
Use Session Data in Your App
In the previous version of the code, we chose a random event out of the list returned from the API. We will start by returning the events in a serial order instead.
Edit the code response of the whatHappenedToday
intent to the code:
var backendcontext = sdk.conversationHelper.getBackendContext(context, req, res);
if (!backendcontext) return;
var today = new Date();
var day = today.getDate();
var month = today.getMonth()+1;
return fetch("http://history.muffinlabs.com/date/"+month+"/"+day)
.then(function(res) {
return res.json();
}).then(function(json) {
var suffix = "";
var events = json.data.Events;
if (req.slot("eventType") == "who was born") {
var events = json.data.Births;
suffix = ", was born";
}
var eventIndex = 0;
if (typeof req.getSession().get("lastIndex") !== 'undefined' && req.getSession().get("lastIndex") !== null){
eventIndex = parseInt(req.getSession().get("lastIndex"))+1;
if (eventIndex >= events.length){
eventIndex = 0;
}
req.getSession().set("lastIndex", eventIndex);
}
else{
req.getSession().set("lastIndex", 0);
}
var selectedEvent = events[eventIndex];
res.say("Hi "+ backendcontext.firstname+".");
res.say('On this day,'+selectedEvent.year+' - '+selectedEvent.text.replace(/(\(.*\))/g,'')+suffix);
});
In lines 17-26, we fetch the stored index and save a new one.
Try It Out
Now that your app can "remember" session data, try out what you have so far.
In the chat console on the right, type in a request: "What happened today?" After you type the request, hit Send.
The chatbot will answer with an interesting event from the past.
Next, in the chat console on the right, type the request again: "What happened today?"After you type the request, hit Send.
The chatbot will answer with another event from the past. Note that the events are ordered by year, so each request will return a later event.
Add Context to Your App
Once your application can remember it an become contextual. For example, to respond to a user "yes" or "no" intent, we must be able to remember what we asked the user to confirm. In this tutorial, we will ask the user if he or she wants to listen to the next event in history. If the user confirms, we will return the next event.
Conversation.one has builtin handlers for "yes" and "no" intents, and normally, there is no need to change the default settings. We will show here how to utilize the default "yes" and "no" handlers to create a contextual conversational flow.
var cbData = {
callback: 'whatHappenedTodayFunction',
data: {
lastIndex: lastIndex,
eventType: req.slot("eventType")
}
};
req.getSession().set('onYes', JSON.stringify(cbData));
The code above instructs Conversation.one to call whatHappenedTodayFunction
when the user invokes the "yes" intent, with the data {lastIndex: lastIndex,eventType: req.slot("eventType")}
.
A similar code can be applied for "no" intents by replacing onYes
with onNo
.
Now let's modify our code to include a contextual flow.
- Add callback functions. In the Business Logic tab, add the following code:
function whatHappenedTodayOnYes(context, req, res, onYesData) { var eventIndex = onYesData.lastIndex + 1; var events = onYesData.events; var selectedEvent = events[eventIndex]; if (eventIndex + 1 < events.length) { res.say('On this day,' + selectedEvent.year + ' - ' + selectedEvent.text.replace(/(\(.*\))/g, '') + onYesData.suffix); req.getSession().set('onYes', JSON.stringify({ callback: 'whatHappenedTodayOnYes', data: { lastIndex: eventIndex, suffix: suffix, events: events } })); req.getSession().set('onNo', JSON.stringify({ callback: 'whatHappenedTodayOnNo', data: {} })); res.say(" Would you like to hear more?"); } else { sdk.conversationHelper.addAnythingElseMessage(res); } } function whatHappenedTodayOnNo(context, req, res, onNoData) { sdk.conversationHelper.addAnythingElseMessage(res); }
- We will modify the
whatHappenedToday
intent response with the new contextual flow:var backendcontext = sdk.conversationHelper.getBackendContext(context, req, res); if (!backendcontext) return; var today = new Date(); var day = today.getDate(); var month = today.getMonth()+1; return fetch("http://history.muffinlabs.com/date/"+month+"/"+day) .then(function(res) { return res.json(); }).then(function(json) { var suffix = ""; var events = json.data.Events; if (req.slot("eventType") == "who was born") { var events = json.data.Births; suffix = ", was born"; } var selectedEvent = events[0]; res.say("Hi "+ backendcontext.firstname+"."); res.say('On this day,'+selectedEvent.year+' - '+selectedEvent.text.replace(/(\(.*\))/g,'')+suffix); if (events.length > 1) { req.getSession().set('onYes', JSON.stringify({ callback: 'whatHappenedTodayOnYes', data: { lastIndex: 0, suffix:suffix, events: events } })); req.getSession().set('onNo', JSON.stringify({ callback: 'whatHappenedTodayOnNo', data: {} })); res.say(" Would you like to hear more?"); } else { sdk.conversationHelper.addAnythingElseMessage(res); } });
Whenever we do not have anything further to ask the user, we call sdk.conversationHelper.addAnythingElseMessage
to make sure the conversation flow is still opened.
Try It Out
Now that your app has contextual flow, try out what you have so far.
In the chat console on the right, type in a request: "What happened today?" After you type the request, hit Send.
The chatbot will answer with an interesting event from the past and will ask you if you would you like to hear more. Try to answer "yes" few times, then answer "no."
What's Next?
In the next part, you'll learn how to contextual conversations flow to gather missing data — a technique called entities filling.