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

Update your skill manifest to declare support for Alexa for Apps V2 and declare intents.

To update your skill manifest

  1. Open the Alexa Skills Kit Command Line Interface (ASK CLI).

  2. In the skill manifest of your custom skill, in the manifest.apis.custom.interfaces section, 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.

  3. To add the Send to Phone push permission, under manifest.permissions, add alexa::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.

  4. If your skill uses Android custom intents, update the appLink section in the skill manifest as shown in the following example.

    "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"
                }
             ]
          }
       ]
    }
    
  5. 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 appLink section to add any needed linkedWebDomains, linkedCommonSchemes, or linkedAndroidCommonIntents properties 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.directLaunch field.

    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.sendToDevice field, 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

  1. In the response.directives.uri field, append "/2" to your skill's LinkApp connections URI as shown in the following example.
    "uri": "connection://AMAZON.LinkApp/2"
    
  2. In the response.directives.input field, make the following changes:
    • Provide any verbal response that precedes your deep-link by using the response.outputSpeech property.

      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 onAppLinked and onScreenLocked fields, 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.directLaunchDefaultPromptBehavior to "SUPPRESS".
  3. 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.enabled to false in 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

  1. Have your response handler check to see whether directLaunch or sendToDevice is present.
  2. 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


Was this page helpful?

Last updated: Nov 17, 2023