Steps to Build a Smart Home Skill

This documentation contains the steps for creating a Smart Home skill. The steps walk you through creating a skill in the developer console, creating an AWS Lambda function, configuring and testing your skill, and submitting your skill for certification.

Prerequisites

To develop a Smart Home skill you must have the following:

  • An Alexa developer account. Registration is free.
  • A connected device such as a light, thermostat, camera, lock, or other device with a cloud API to control it.
  • An Alexa-enabled device such as Amazon Echo.
  • An AWS account. You host your skill code in an AWS Lambda function.
  • Knowledge of JSON and one of the supported languages for AWS Lambda: Node.js, Java, Python, C#, or Go.
  • Understanding of OAuth 2.0.

Create the Skill

  1. Open the Alexa developer console.
  2. Click the Create Skill button.
  3. Enter the Skill name. Note that your skill's name must not indicate that it's functionality is limited. For example, you should not use "basic", "reduced" or "simple" in the title of your skill. The skill language defaults to English (US). Change the Default language using the drop-down, if you are targeting a different region/language. For details, see Build Smart Home Skills in Multiple Languages to see the device categories that are supported for each language.
  4. Under Choose a model to add to your skill page, select Smart Home, which is a pre-built model, and click Create skill.
  5. Under Payload Version, select v3.
  6. Click Save and copy Your Skill ID to the clipboard. The ID is in a format similar to the following: amzn1.ask.skill.1a2b55555-c325-1234-d56e-1f234d5e6a78

For more information on how to use the developer console, see Manage Skills in the Developer Console.

Next, you create a Lambda function so that you can configure the Smart Home service endpoint.

Add a Lambda Function

You need an AWS account and some basic knowledge of AWS. The code for your Smart Home skill is hosted as a Lambda function on AWS. AWS Lambda is a service that lets you run code in the cloud without managing servers. Alexa sends your skill a request. Your code inspects the request, performs actions, such as turning on a light, and sends a response event back to Alexa.

To get started, sign in to your AWS account.

Create an IAM Role for Lambda

If you haven't worked with Lambda before, create an Identity and Access Management (IAM) role that enables you to run Lambda functions. To create an IAM role, navigate to the IAM console. If you already have a role that enables you to run Lambda functions, skip to the next section.

  1. Choose Roles and click Create a new role.
  2. Select AWS Lambda under AWS Service Role.
  3. Type "basic" in the filter box and choose the AWSLambdaBasicExecutionRole, and click Next Step.
  4. Enter a name that identifies this role and click Create role.

Create a Lambda function and add code

  1. On the AWS Console, under Compute, select Lambda.
  2. Select the correct Lambda function region for your region and skill language.

    The region appears in the upper right corner. For discovery of smart home devices to succeed, you must choose the region where the devices are located. Choosing the correct region also helps reduce latency. To support multiple languages and regions, you must deploy your code to each region. For more information, see Deploy Your Lambda Function to Multiple Regions.

  3. Click Create a Lambda function.
  4. Select Author from scratch, and enter the following information:

    • Name: Provide a name for your Lambda function. This name is appears in the AWS console and is also returned by the AWS command line interface (CLI) ListFunctions API. It should be unique across your Lambda functions.
    • Runtime: To use the sample code provided in this topic, choose Node.js 6.10 or alternatively, select the runtime for the code you plan to write. Supported languages are: Node.js, Java, Python, C#, or Go.
    • For Role, select a role you previously created, or a role with Lambda basic execution policy attached.
  5. Click Create Function. Your function is created and the Configuration page opens.
  6. In the Configuration designer, under Add triggers select the Alexa Smart Home trigger.
  7. In the Configure triggers section, add the Skill ID from the developer console in the box specified. 
  8. Leave Enable trigger checked. This enables the Amazon Alexa service to call your Lambda function. If you don't enable it when you create your skill, you can't enable it in the console later.
  9. Click Add and then click Save.
  10. At the top of the page, select the Lambda function to display the function code. Following is an example of the Lambda function.
  11. In the Function code section make sure Edit code inline is selected. Leave the Runtime and Handler set to their defaults.
  12. Paste in the following code, completely replacing the code in index.js.
exports.handler = function (request, context) {
    if (request.directive.header.namespace === 'Alexa.Discovery' && request.directive.header.name === 'Discover') {
        log("DEBUG:", "Discover request",  JSON.stringify(request));
        handleDiscovery(request, context, "");
    }
    else if (request.directive.header.namespace === 'Alexa.PowerController') {
        if (request.directive.header.name === 'TurnOn' || request.directive.header.name === 'TurnOff') {
            log("DEBUG:", "TurnOn or TurnOff Request", JSON.stringify(request));
            handlePowerControl(request, context);
        }
    }

    function handleDiscovery(request, context) {
        var payload = {
            "endpoints":
            [
                {
                    "endpointId": "demo_id",
                    "manufacturerName": "Smart Device Company",
                    "friendlyName": "Bedroom Outlet",
                    "description": "Smart Device Switch",
                    "displayCategories": ["SWITCH"],
                    "cookie": {
                        "key1": "arbitrary key/value pairs for skill to reference this endpoint.",
                        "key2": "There can be multiple entries",
                        "key3": "but they should only be used for reference purposes.",
                        "key4": "This is not a suitable place to maintain current endpoint state."
                    },
                    "capabilities":
                    [
                        {
                          "type": "AlexaInterface",
                          "interface": "Alexa",
                          "version": "3"
                        },
                        {
                            "interface": "Alexa.PowerController",
                            "version": "3",
                            "type": "AlexaInterface",
                            "properties": {
                                "supported": [{
                                    "name": "powerState"
                                }],
                                 "retrievable": true
                            }
                        }
                    ]
                }
            ]
        };
        var header = request.directive.header;
        header.name = "Discover.Response";
        log("DEBUG", "Discovery Response: ", JSON.stringify({ header: header, payload: payload }));
        context.succeed({ event: { header: header, payload: payload } });
    }

    function log(message, message1, message2) {
        console.log(message + message1 + message2);
    }

    function handlePowerControl(request, context) {
        // get device ID passed in during discovery
        var requestMethod = request.directive.header.name;
        var responseHeader = request.directive.header;
        responseHeader.namespace = "Alexa";
        responseHeader.name = "Response";
        responseHeader.messageId = responseHeader.messageId + "-R";
        // get user token pass in request
        var requestToken = request.directive.endpoint.scope.token;
        var powerResult;

        if (requestMethod === "TurnOn") {

            // Make the call to your device cloud for control
            // powerResult = stubControlFunctionToYourCloud(endpointId, token, request);
            powerResult = "ON";
        }
       else if (requestMethod === "TurnOff") {
            // Make the call to your device cloud for control and check for success
            // powerResult = stubControlFunctionToYourCloud(endpointId, token, request);
            powerResult = "OFF";
        }
        var contextResult = {
            "properties": [{
                "namespace": "Alexa.PowerController",
                "name": "powerState",
                "value": powerResult,
                "timeOfSample": "2017-09-03T16:20:50.52Z", //retrieve from result.
                "uncertaintyInMilliseconds": 50
            }]
        };
        var response = {
            context: contextResult,
            event: {
                header: responseHeader,
                endpoint: {
                    scope: {
                        type: "BearerToken",
                        token: requestToken
                    },
                    endpointId: "demo_id"
                },
                payload: {}
            }
        };
        log("DEBUG", "Alexa.PowerController ", JSON.stringify(response));
        context.succeed(response);
    }
};

Finish configuring and test the Lambda function

  1. Click Save.
  2. If you want to perform a quick test of the Discovery request in the Lambda code editor, you can click Test. The Configure test event page appears.
  3. Leave Create new test event selected. For Event template, leave the default Hello World. In the Event name, enter discovery and replace the entire contents in the editor with the following code.
{
    "directive": {
        "header": {
            "namespace": "Alexa.Discovery",
            "name": "Discover",
            "payloadVersion": "3",
            "messageId": "1bd5d003-31b9-476f-ad03-71d471922820"
        },
        "payload": {
            "scope": {
                "type": "BearerToken",
                "token": "access-token-from-skill"
            }
        }
    }
}
  • Click Create, and then Test. If successful, the Execution Result should be similar to the following:
{
  "event": {
    "header": {
      "correlationToken": "12345692749237492",
      "messageId": "1bd5d003-31b9-476f-ad03-71d471922820",
      "name": "Discover.Response",
      "namespace": "Alexa.Discovery",
      "payloadVersion": "3"
    },
    "payload": {
      "endpoints": [
        {
          "endpointId": "demo_id",
          "manufacturerName": "Smart Device Company",
          "friendlyName": "Bedroom Outlet",
          "description": "Smart Device Switch",
          "displayCategories": ["SWITCH"],
          "cookie": {
            "key1": "arbitrary key/value pairs for skill to reference this endpoint.",
            "key2": "There can be multiple entries",
            "key3": "but they should only be used for reference purposes.",
            "key4": "This is not a suitable place to maintain current endpoint state."
          },
          "capabilities": [
            {
              "type": "AlexaInterface",
              "interface": "Alexa",
              "version": "3"
            },
            {
              "interface": "Alexa.PowerController",
              "version": "3",
              "type": "AlexaInterface",
              "properties": {
                "supported": [
                  {
                    "name": "powerState"
                  }
                ],
                "retrievable": true
              }
            }
          ]
        }
      ]
    }
  }
}

Configure the service endpoint

You must provide the ARN for your Lambda function in the skill configuration in the developer console.

  1. Navigate back to your skill in the developer console.
  2. Under Smart Home service endpoint, in the Default endpoint box, provide the ARN number from the Lambda function you created and click Save. If you are creating multiple language versions of your skill, you must provide geographic-specific endpoints. For more information, see Deploy Your Lambda Function to Multiple Regions.
  • If your skill only supports one language/region, provide the same ARN for the default ARN and the selected regional ARN.
  • If your skill supports multiple languages/regions, you must provide ARNs for each region. Provide one of the regional ARNs for the default.

Provide account linking information

For an overview of account linking in Smart Home skills, see Understand Account Linking and Account Linking for Smart Home and Other Domains.

In Section 3. Account Linking, click Setup Account Linking. This section requires account information from your OAuth 2.0 provider, which enables customers to associate their device cloud account with your Smart Home skill. You can use Login with Amazon or another OAuth provider for this section.

You provide:

  • Authorization URI for your OAuth provider
  • Client ID for your OAuth provider
  • A Scope, if your OAuth provider requires it
  • Access token URI for your OAuth provider
  • Client Secret associated with your Client ID

For details about the required fields, see Configure an Authorization Code Grant.

Implement state and change reporting

We recommend that you implement state reporting in your Smart Home skill, because state reporting displays the current state of devices to users. State reporting is required for Smart Home skills that target devices that are certified as Works With Alexa.

For details, see Understand State and Change Reporting.

Complete the following steps to implement state reporting:

  • Code your skill to respond to ReportState directives with StateReport events. Examples of StateReport events are available in the documentation for each interface.
  • Request permission to send events to the Alexa event gateway.
  • Add code to handle the AcceptGrant directive to obtain authentication credentials. For details, see Alexa.Authorization.
  • Add code to send ChangeReport events to the Alexa event gateway using the stored customer authentication tokens. Examples of ChangeReport events are available in the documentation for each interface.

Test your skill

For options to test and debug your Smart Home skill, see Test and Debug Your Smart Home Skill.

When your implementation is complete, and you've tested your Lambda function, you can functionally test your Smart Home skill.

  1. Make sure you have a smart home trigger added and enabled. To check this, go to the Lambda console, select your Smart Home skill, and make sure you have an Alexa Smart Home trigger.
  2. Sign in to the Alexa app (available on Android, IOS or the web at https://alexa.amazon.com) with the same credentials as your developer account.
  3. Find your skill in the Alexa app. To do this, go to Skills, and tap Your Skills in the upper right corner of the All Skills page. Scroll to DEV SKILLS and find your skill.
  4. Click the ENABLE button to enable the skill, and you are directed to account-link the skill to a device cloud account. If you are unable to complete account linking, make sure you are using valid credentials for the device cloud. Otherwise, it is likely there is an issue with account-linking information you provided in the developer console. For help with this, see Alexa: Debugging account linking in the developer forums. If you want to remove account linking later, you should disable your skill in the Skills tab.
  5. Close the window and tap the DISCOVER DEVICES button in the Alexa app.
  6. If the skill does not discover devices, check the logs for your Lambda function to see if it received a discover directive from Alexa, and use the logs to troubleshoot the issue. Common issues include incorrectly formatted event responses.
  7. If your skill successfully discovers devices, return to the Test page of the developer console. On the Test page, move the test slider to Yes and use the Alexa Simulator to give Alexa commands using the device names found in the discovery process and utterances your skill supports. Make sure and test the skill with valid utterances and invalid ones, meaning ask your skill to do things that should work, and things that should not work, and in a variety of conditions, such as with a target device powered off.
  8. When you are satisfied with your Smart Home skill's performance, you can provide it for beta testing or submit it for certification.

Provide launch information

To provide your skill to customers for beta testing or submit your skill for certification, you must provide some information that is used to describe your skill in the Alexa app.

  • Select Distribution, and on the English (US) Store Preview page, specify:

    • Public Name.
    • One Sentence Description
    • Detailed Description
    • Example Phrases
    • Small Skill Icon
    • Large Skill Icon
    • Keywords
    • Privacy Policy URL
    • Terms of Use URL.

Use the tooltips provided on the page for assistance in completing these fields. For details, see Smart Home Skill Publishing Guide.

  • Click Save and Continue

On the Privacy and Compliance page, answer the questions provided. For Testing Instructions, provide test account credentials. You should make sure your testing instructions and other publishing information follows the guidelines in our Publishing Guide.

  • Click Save and Continue
  • On the Availability page, check whether your skill is public, or for use by Alexa for Business Organizations.
  • Select the countries and regions you would like to distribute your skill
  • Click Save and Continue

Optionally beta test your skill

At this point, the Beta Test button should be enabled, and you can complete information to start a beta test. For details, see Skills Beta Testing.

Submit your skill for certification

If you have completed all the fields successfully, you should see a large green check mark and Your skill is ready for submission.

  • At the bottom of the page, click Submit for review.

Submit changes to a live skill

After your skill is live, any changes to the skill must be certified. For example, your skill must be recertified as part of changing the information you provided about your skill in the developer console or changing the AWS Lambda function. The certification review varies depending on the changes, and updating the Lambda function might trigger additional review.

When a skill status is changed to live, a new Development version is automatically created in the developer console and displays immediately below the live skill. This version has the same information as the original live version. You can use it to continue to work on your skill to improve it and add features.

When you submit your updated skill to the developer console, in the Testing Instructions field, add a change log that provides a detailed description of all changes.

Update your Lambda function

Do the following to update your AWS Lambda function:

  1. Create a new Lambda function with a new ARN, and copy your live Lambda function into the new Lambda function.

  2. Make your updates in the new Lambda function. Avoid updating the live Lambda function that supports your live skill, and avoid Lambda aliases or versioning because they don't work reliably after your skill is updated.

  3. In the development stage for your skill, update the Lambda ARN configuration to point to the new Lambda ARN.

After your skill is recertified and pushed live, your skill points to the new Lambda ARN. You can then deprecate the previous Lambda function or use the function for future development or updates.