In this step, we will convert the canHandle
intent and state structure of an ASK SDK v2 Alexa Skill project into the Jovo Framework intent and state routing format.
- Introduction to Intent and State Handling in Jovo
- Migrating our First Intent
- Migrating from canHandle to Nested States and Intents
- Summary
- Next Step
Introduction to Intent and State Handling in Jovo
Compared to the canHandle
and handle
methods of ASK SDK v2, Jovo works with intents and nested states in handler object.
For example, the Hello World handler in a Jovo app looks like this:
Jovo also comes with support to use states, a way to track where in the conversation the user is in.
States can be nested in Jovo and look like this:
Before we dive deeper into state management, let's convert our first intent to the Jovo Framework structure.
Migrating our First Intent
To be honest, technically it's the LaunchRequest
, not an intent that we're taking a look at first. This is the first interaction users have with your voice app, for example when they say "Alexa, open Quiz Game".
For cross-platform compatibility, Jovo maps Alexa LaunchRequests
to a built-in LAUNCH
intent. If you go back to the example above, this looks like this:
In three steps, we're now going to convert the LaunchRequestHandler
of the ASK SDK app to Jovo and then do some testing to see if it worked:
From LaunchRequestHandler to LAUNCH
Let's take a look at the LaunchRequest
part in the app that is using ASK SDK (find the code here):
This adds a speak
command and feeds it with the welcomeMessage
constant (more on that in the next step), and also adds a helpMessage
as reprompt.
Jovo typically uses the ask
method for this, which has a speech
and reprompt
parameter. So in this specific case, it could look like this:
Before we can test this out, let's import constants like welcomeMessage
and helpMessage
along with other helper methods from the original project.
Adding Helper Methods and Constants
In the sample code provided by Amazon, there are a bunch of constants that are used to store speech output like welcomeMessage
and helpMessage
, for example (find the code here):
There are also quite a few helper methods (find them here):
For now, let's just copy everything below our handlers. We will tweak some things here and there (and delete some helpers later), but for now this should be enough.
Initial Testing
To test the current state of the app, try to run the Jovo Webhook again:
At first, this will throw an error with the message Cannot read property 'custom' of undefined
. This is because of the following (first) line of the constants (find it here):
You can delete this entirely. We don't need it for Jovo projects.
After this, if you run
the Jovo development server again, you should be able to try out LAUNCH
in the Jovo Debugger:
First intent is done! Let's take a look at the other intents.
Migrating from canHandle to Nested States and Intents
As we learned above, ASK SDK v2 projects are typically organized into different handlers that look like this:
In the next steps, we're going through the handlers to set up the intent and state structure as used in Jovo projects. For this, we will mostly focus on the canHandle
part and deal with the logic (handle
) later.
We're starting with this handler structure from the previous step:
Let's take a look at some more intents of the Quiz Game.
Building the Handler Structure
In the QuizHandler
(find code here), ...
Deal with AMAZON.StartOverIntent
later.
The DefinitionHandler
(find code here) ...
The return attributes.state !== states.QUIZ
is interesting here. This handler is only triggered when the voice app is not in the QUIZ
state.
Jovo nested states:
// Example
Here, we're referencing the states from an object:
We can add them like this:
However, for this, we would need to move the states
object above the setHandler
method (otherwise it would be undefined when the handler is set, and throw an error). For readability, we will get rid of the states
object and use the Jovo convention to add State
behind every state name:
QuizAnswerHandler
(find code here) ...
Only different behavior for QUIZ
state, so it can be added outside, no need to add it to the START
state:
intentMap
Both the RepeatHandler
(find code here) and HelpHandler
(find code here) use so called built-in intents provided by Amazon, AMAZON.RepeatIntent
and AMAZON.HelpIntent
:
You can add these intents to the handler like below. Note that they need to be added in quotation marks because of the .
in the name (otherwise they would be treated as nested object):
For readability and cross-platform capabilities, it can make sense to not use the AMAZON
prefix for the intents in the handler. For this, Jovo offers an intentMap
that can be helpful with a variety of things.
For example, the intentMap
(which you can find in the config.js
file in the src
folder) of a Jovo "Hello World" project already maps AMAZON.StopIntent
to the Jovo END
intent:
In the below example, we map AMAZON.RepeatIntent
to just RepeatIntent
, and do the same für AMAZON.HelpIntent
:
In the handler, it would then look like this:
Intent Redirects
In the QuizHandler
(find code here), ...
Same functionality for both QuizIntent
and AMAZON.StartOverIntent
. We could solve this with the intentMap
as described in the previous section:
This would solve the problem. However, intent mapping is global, so for every state, the AMAZON.StartOverIntent
would be mapped to QuizIntent
. This could lead to problems if we wanted to use StartOverIntent
in different contexts.
For this you can use Intent Redirects instead of the intentMap
. Redirects like toIntent
route the handler to a different intent, to keep everything organized and readable:
We keep the AMAZON.StartOverIntent
in the intentMap
though, and map it to StartOverIntent
:
END and Error Requests
The ExitHandler
(find code here) uses three different intents, AMAZON.StopIntent
, AMAZON.PauseIntent
, and AMAZON.CancelIntent
:
If we take a look at the intentMap
again, we can see that AMAZON.StopIntent
is already mapped to END
. We can go ahead and also add the other ones:
The END
standard intent in Jovo alrady maps SessionEndedRequests
by Alexa and can be used to do some cleanup and also to send a last response (not possible for all types of requests). Let's add it:
There is one more interesting handler in the ASK SDK project: The ErrorHandler
(find code here) is triggered when there is an error in the Alexa Skill:
For this, Jovo offers the ON_ERROR
handler:
Summary
If you followed all the previous steps, your handler should look like this:
As you can see here, the START
state doesn't seem to be used, so we can get rid of that for now. This leaves us with the following intent and state structure:
Next Step
In the next step, we're going to add some life to the app. Let's do some work on the application logic.