Tutorial: Migrate From Alexa for Apps V1 to V2
This tutorial is for developers who have an existing skill that uses Alexa for Apps V1, and want to migrate their skill to Alexa for Apps V2.
The V2 API enables your skill to bridge voice-to-app experiences starting on any Alexa-enabled device, including Echo devices.
User experience difference between V1 and V2
The main difference between V1 and V2 is that in V1 your skill could only bridge users to your app on mobile devices. In V2, your skill can also bridge users from your skill to your app on any Alexa-enabled device, such as an Amazon Echo device.
Migration workflow
The following task list outlines the steps that you must follow to migrate your skill to Alexa for Apps V2.
- Step 1: Update your skill manifest
- Step 2: Update your skill endpoint code
- Step 3: Test your Alexa for Apps V2 skill
Step 1: Update your skill manifest
Update your skill manifest to declare support for Alexa for Apps V2 and declare intents.
To update your skill manifest
-
Open the Alexa Skills Kit Command Line Interface (ASK CLI).
-
In the skill manifest of your custom skill, in the
manifest.apis.custom.interfacessection, replace"type": "APP_LINKS"with"type": "APP_LINKS_V2"This declaration tells Alexa that your skill can support the AppLink V2 interface. You can't declare both AppLink V1 and AppLink V2 interfaces.
-
To add the Send to Phone push permission, under
manifest.permissions, addalexa::devices:app:push_notifications.This permission is for the user to allow your skill to send push notifications in the Alexa app. Alexa for Apps handles scenarios where the user hasn't yet enabled the permission, using voice consent. Your skill doesn't need to check for this permission or prompt the user to enable it. You only need to add this line to the permissions section of your manifest.
-
If your skill uses Android custom intents, update the
appLinksection in the skill manifest as shown in the following example.Note: In Alexa for Apps V1, your skill could send an Android custom intent without you having to declare it. In V2, you must declare Android custom intents."appLink": { "linkedApplications": [ { "friendlyName": { "default": "GrubbHouse", "localizedNames": [ { "locale": "de-DE", "name": "GrubbHaus" } ] }, "catalogInfo": { "type": "GOOGLE_PLAY_STORE", "identifier": "com.someapp" }, "customSchemes": [ "grubbhouse://", "grbh://" ], "domains": [ "grubbhouse.com", "grbh.com" ], # declaring an Android custom intent "androidCustomIntents": [ { "component": "com.someapp.SomeActivity", "action": "com.someapp.SOME_ACTION" } ] } ] } -
If you're adding deep-link types that are new in Alexa for Apps V2 (website-only links, common URI schemes, or Android common intents), update the
appLinksection to add any neededlinkedWebDomains,linkedCommonSchemes, orlinkedAndroidCommonIntentsproperties as shown in the following example.For details, see Alexa for Apps V2 Skill Connection Request Reference.
"appLink": { "linkedWebDomains": [ "grubbhouse.com", "amazon.com", "yahoo.com" ], "linkedCommonSchemes": { "IOS_APP_STORE": [ "MAPS", "TEL" ], "GOOGLE_PLAY_STORE": [ "MAPS", "TEL" ] }, "linkedAndroidCommonIntents": [ { "intentName": "SHOW_IN_MAP", "catalogType": "GOOGLE_PLAY_STORE" } ] }
Step 2: Update your skill endpoint code
In Step 1 you declared support for Alexa for Apps V2 in your skill manifest. This declaration results in changes to the following payloads:
- The request payload that your skill receives in an inbound request
- The request payload that your skill sends in a skill connection request
- The skill connection response payload that your skill receives
In this step, you update your skill endpoint code to handle these changes.
Step 2a: Parse the updated incoming request payload
The skill request payload is the object that your skill receives in inbound requests. There are two sections in this object that change in Alexa for Apps V2: context.System.device.supportedInterfaces and context.AppLink. If your skill request handlers expect these sections, you must update your code so it parses them correctly.
In the context.System.device.supportedInterfaces section, the presence of an AppLink property indicates that your skill can make an Alexa for Apps request. In V1, the AppLink property is an empty object. In V2, it contains a version field with value "2.0", as shown in the following example. This value indicates that the request is an Alexa for Apps V2 request.
"supportedInterfaces": {
"AudioPlayer": {...},
===== ALEXA FOR APPS ADDITIONS START =====
"AppLink": {
"version": "2.0"
},
===== ALEXA FOR APPS ADDITIONS END =====
}
In Alexa for Apps V1, the context.AppLink object contains only a supportedCatalogTypes field, which indicates the mobile OS the user is using. In Alexa for Apps V2, this object adds the directLaunch and sendToDevice fields to indicate support for the mobile and non-mobile experiences. The directLaunch field indicates whether a direct launch of the app is possible. The sendToDevice field indicates whether a push notification flow is possible.
The OS type for mobile requests moved to a child object underneath the directLaunch property.
Request from a mobile device
As in Alexa for Apps V1, when a user makes a request on a mobile device, you typically have the option to use either a direct launch or a push notification. More often, it's easier for the user to have your app launched hands-free. You send a notification if you want to be less intrusive by having your skill keep talking to the user instead of directly launching your app or website.
To determine whether the mobile direct launch experience is possible
-
Have your skill examine the
context.AppLink.directLaunchfield.If the request came from an iOS device, this property includes the key
"IOS_APP_STORE", as shown in the following example."AppLink": { "directLaunch": { "IOS_APP_STORE": {} } }If the request comes from an Android device, this property includes the key
"GOOGLE_PLAY_STORE", as shown in the following example."AppLink": { "directLaunch": { "GOOGLE_PLAY_STORE": {} } }
Request from an Alexa-enabled device
When the request comes from an Alexa-enabled device, such as an Amazon Echo, your skill can send links to the user's mobile device in a notification from the Alexa app.
To determine whether your skill can send a notification to a user's phone
-
Have your skill check the
context.AppLink.sendToDevicefield, as shown in the following example."AppLink": { "sendToDevice": {} }The following example shows a skill receiving a request from an iOS device that can handle both direct launch and Send to Phone.
"AppLink": { "directLaunch": { "IOS_APP_STORE": {} }, "sendToDevice": {} }
Step 2b: Send the new payload format in the skill connection request
Alexa for Apps V2 adds a new URI endpoint for you to use when it makes your skill connection request to launch an app directly or to send the user a notification with a deep link. The Alexa for Apps request payload structure has changed format, though much of the actual information that you provide is the same. For details, see Alexa for Apps V2 Skill Connection Request Reference.
Make the following changes in your skill connections payload that you send to Alexa for Apps to request a deep-link.
To request a deep link
- In the
response.directives.urifield, append"/2"to your skill'sLinkAppconnections URI as shown in the following example."uri": "connection://AMAZON.LinkApp/2" - In the
response.directives.inputfield, make the following changes:-
Provide any verbal response that precedes your deep-link by using the
response.outputSpeechproperty.For example, an airline skill might say, "Your flight is on time and leaves Los Angeles International Airport at 2pm PT", and then send the user a deep link to their flight details page.
-
Remove the
onAppLinkedandonScreenLockedfields, and add a"topic"field, which Alexa for Apps uses to respond in various scenarios.
For example, if a user has their phone locked when they make a request that triggers a deep-link, Alexa for Apps responds, "To see your messages, please unlock your device." Limit the topic to 23 characters, and make it an action clause — in English this is an imperative phrase, such as
"see your messages"or"view the lasagna recipe". This format makes it possible for Alexa to reuse the topic in sentences such as "I'll send John a link to view the lasagna recipe."- Suppress the default, unlocked mobile direct-launch helper text-to-speech (TTS) of "Here's <myAppName>." by setting
input.prompt.directLaunchDefaultPromptBehaviorto"SUPPRESS".
Note: You can no longer specify or suppress the locked device helper response. -
-
Provide deep links for each catalog type you support.
Alexa selects the appropriate links to use based on the user's receiving device (iOS or Android).
By default, if a request originates from a mobile device, Alexa for Apps attempts to open your app on the user's phone.
To disable the behavior when a request originates from a mobile device
-
Set
directLaunch.enabledtofalsein the skill connection request payload.If a request originates from an Alexa-enabled device, Alexa for Apps by default attempts to send a push notification to the user's phone.
Example: Direct launch only — Android Custom Intent with intent extras
The following example shows a payload for a skill connection request that uses an ANDROID_CUSTOM_INTENT deep link. Because the skill only wants to launch the app directly on a mobile device, it explicitly sets the value of the sendToDevice.enabled property to false.
{
"version": "1.0",
"sessionAttributes": {},
"response": {
"outputSpeech": {...},
"card": {...},
"reprompt": {...},
"directives": [
================== ALEXA FOR APPS ADDITIONS START ==================
{
"type": "Connections.StartConnection",
"uri": "connection://AMAZON.LinkApp/2",
"input": {
"links": {
"GOOGLE_PLAY_STORE": {
"primary": {
"ANDROID_CUSTOM_INTENT": {
"appIdentifier": "com.cityguide.app",
"intentSchemeUri": "intent:#Intent;package=com.cityguide.app;component=com.cityguide.app.SearchActivity;i.some_int=100;S.some_str=hello;end"
}
}
}
},
"prompt": {
"topic": "see your search detail",
},
"sendToDevice": {
"enabled": false
}
},
================== ALEXA FOR APPS ADDITIONS END ====================
]
}
}
Example: Send to phone only — Android Common Intent and Common Scheme
The following example shows a payload for a skill connection request that uses both an Android common intent and a common URI scheme for deep links. This approach is less intrusive, because it only sends a push notification and doesn't directly launch the app on the user's phone. To disable launching the app, the skill explicitly sets the value of directLaunch.enabled to false.
{
"version": "1.0",
"sessionAttributes": {},
"response": {
"outputSpeech": {...},
"card": {...},
"reprompt": {...},
"directives": [
================== ALEXA FOR APPS ADDITIONS START ==================
{
"type": "Connections.StartConnection",
"uri": "connection://AMAZON.LinkApp/2",
"input": {
"links": {
"GOOGLE_PLAY_STORE": {
"primary": {
"ANDROID_COMMON_INTENT": {
"intentName": "OPEN_SETTINGS",
"intentSchemeUri": "intent:#Intent;action=android.settings.WIFI_SETTINGS;end"
}
}
},
"IOS_APP_STORE": {
"primary": {
"COMMON_SCHEME": {
"scheme": "TEL",
"uri": "tel:1234567"
}
}
}
},
"prompt": {
"topic": "see your settings"
},
"directLaunch": {
"enabled": false
}
},
================== ALEXA FOR APPS ADDITIONS END ====================
]
}
}
Step 2c: Handle the updated Alexa for Apps response payload
In Alexa for Apps V2, the cause.result field in the response payload contains either directLaunch or sendToDevice. The presence of directLaunch indicates that Alexa for Apps attempted to launch your app. The presence of sendToDevice indicates that Alexa for Apps attempted to send a link to the user's mobile device.
To handle the updated Alexa for Apps response payload
- Have your response handler check to see whether
directLaunchorsendToDeviceis present. - Have your response handler check the status code and error code to determine whether the attempted action was successful.
In all cases where Alexa for Apps attempts the sendToDevice experience, your skill can resume interaction with the user.
Example response for direct launch
{
"type": "SessionResumedRequest",
"requestId": "<string>",
"timestamp": "<string>",
"locale": "<string>",
"cause": {
"type": "ConnectionCompleted",
"token": "1234",
"status": {
"code": "200", // This is the status code for the connection call itself
"message": "OK"
},
"result": {
"directLaunch": { // This indicates that Alexa attempted a direct launch
"primary": {
"status": "FAILURE",
"errorCode": "APP_INCOMPATIBLE" // The primary link failed
},
"fallback": {
"status": "SUCCESS" // Fallback was successful
}
}
}
}
}
Example response for Send to phone
{
"type": "SessionResumedRequest",
"requestId": "<string>",
"timestamp": "<string>",
"locale": "<string>",
"cause": {
"type": "ConnectionCompleted",
"token": "1234",
"status": {
"code": "200",
"message": "OK"
},
"result": {
"sendToDevice": {
"status": "SUCCESS"
}
}
}
}
Step 3: Test your Alexa for Apps V2 skill
To test your Alexa for Apps V2 Developer Preview skill
- For instructions about how to test your Developer Preview skill, see Step 3: Test your Alexa for Apps V2 skill.
Related topics
- Add Alexa for Apps to Your Custom Skill
- Alexa for Apps Skill Manifest Reference
- Alexa for Apps Skill Connection Request Reference
- Understand Custom Skills
- Understand Skill Connections
Last updated: May 03, 2024