Step 3: Migrating Intents and Handlers from ASK to Jovo

by Jan König on Apr 17, 2019

Migrating Alexa Intents and Handlers from ASK SDK to Jovo

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

Learn more about Jovo Routing here.

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

Learn more about Jovo Intent Handling here.

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:

Testing "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

Learn more about Jovo State Handling here.

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:


Learn more about the Jovo intentMap here.

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:


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.

Step 4: Migrating the App Logic

Jan König

Co-founder at Jovo

Comments and Questions

Any specific questions? Just drop them below or join the Jovo Community Forum.

Join Our Newsletter

Be the first to get our free tutorials, courses, and other resources for voice app developers.