Host a Custom Skill as an AWS Lambda Function

The easiest way to build the cloud-based service for a custom Alexa skill is by using AWS Lambda, an Amazon Web Services offering that runs your code only when it’s needed and scales automatically, so there is no need to provision or continuously run servers. You upload the code for your Alexa skill to a Lambda function and Lambda does the rest, executing it in response to Alexa voice interactions and automatically managing the compute resources for you.

About Lambda Functions and Custom Skills

Using a Lambda function for your service eliminates some of the complexity around setting up and managing your own endpoint:

  • You do not need to administer or manage any of the compute resources for your service.
  • You do not need an SSL certificate.
  • You do not need to verify that requests are coming from the Alexa service yourself. Access to execute your function is controlled by permissions within AWS instead.
  • AWS Lambda runs your code only when you need it and scales with your usage, so there is no need to provision or continuously run servers.
  • Alexa encrypts its communications with Lambda utilizing TLS. See also AWS security best practices.
  • For most developers, the Lambda free tier is sufficient for the function supporting an Alexa skill. The first one million requests each month are free. Note that the Lambda free tier does not automatically expire, but is available indefinitely.

AWS Lambda supports code written in Node.js, Java, Python, C#, or Go. You can copy and edit Node.js or Python code in the inline code editor in the AWS Lambda console or upload it in a zip file. For basic testing, you can invoke your function manually by sending it JSON requests in the Lambda console.

For an overview of AWS Lambda, see What Is AWS Lambda?

The Lambda functions must adhere to the same service interface and handle the three types of requests sent by Alexa. For details about handling Alexa requests, see Handling Requests Sent by Alexa. For details about the JSON interface, see the JSON Interface Reference for Custom Skills.

Lambda functions for custom skills can be hosted in one of these regions:

  • Asia Pacific (Tokyo)
  • EU (Ireland)
  • US East (N. Virginia)
  • US West (Oregon)

This document covers creating a new Lambda function for a custom skill. If you are using the Smart Home Skill API, you use Lambda to create a skill adapter. See Steps to Create an Alexa Smart Home Skill.

Create a Lambda Function for an Alexa Skill

You use the Lambda console to create a new Lambda function and do basic testing. You can use a blueprint to create a new function with code for a basic function that implements a simple skill in Node.js or Python. Alternatively, skip the blueprint step to create a Lambda function from scratch.

If you want to code your service in Java, but haven't yet set up a Java project, you may want to use one of the samples as a starting point for your function.

Before you create the Lambda function, create the skill in the developer console and copy the skill ID.

To create a new Lambda function:

  1. If you do not already have an account on AWS, go to Amazon Web Services and create an account.
  2. Log in to the AWS Management Console and navigate to AWS Lambda.
  3. Click the region drop-down in the upper-right corner of the console and select one of the regions supported for Alexa skills: Asia Pacific (Tokyo), EU (Ireland), US East (N. Virginia), or US West (Oregon).
  4. If you have no Lambda functions yet, click Get Started Now. Otherwise, click Create a Lambda Function.
  5. To start with sample code in Node.js or Python, click Blueprints, select one of the Alexa Skills Kit blueprints and then click Configure.
    • alexa-skill-kit-sdk-factskill
    • alexa-skill-kit-sdk-triviaskill
    • alexa-skills-kit-color-expert
    • alexa-skill-kit-sdk-howtoskill
    • alexa-skills-kit-color-expert-python

    You can see more about these samples at the Alexa organization on GitHub.

  6. Enter a Name for the function.
  7. Select the Role for the function. This defines the AWS resources the function can access.
  8. Select the language you want to use for the Runtime (Node.js, Java, or Python).
    • If you select Java, you need to also upload your Java code in a zip file.
    • Note that you cannot change the language for a function once it is saved.
    • If you selected a blueprint, the code language is pre-configured.
  9. Click Create function.
  10. Configure the Alexa Skills Kit trigger for the function as described below.
  11. See below to test the function in the console.

When you are ready to add your own code, edit the function and scroll to the Function code section. From here, you can do any of the following:

  • Write your code directly in the code editor in the Lambda console (Node.js or Python).
  • Write your code offline and copy and paste it into the Lambda console editor (Node.js or Python).
  • Write your code offline and upload it to the Lambda function in a zip file (C#, Node.js, Python, or Java).
  • Use the Eclipse IDE and the AWS Toolkit for Eclipse (Java). For details, see Using AWS Lambda with the Toolkit for Eclipse.

Defining a New Role for the Function

The role specifies the AWS resources your function can access. To create a new role while configuring your function:

  1. For Role (under Lambda function handler and role), select Create new role from template(s).
  2. Enter the Role Name.
  3. From the Policy templates list, select Simple Microservice permissions.

Configure the Alexa Skills Kit Triggers

You must configure at least one trigger for your function to grant Alexa the necessary invocation permissions for your function.

When you add the Alexa Skills Kit as a trigger, it is recommended that you also enable skill ID verification for the function and provide the skill ID (also called the application ID) for your skill. This means your function can be invoked only if the skill ID in the Alexa Skills Kit request matches the skill ID configured in the trigger.

When using skill ID verification, you do not need to include code to verify that the request is intended for your service. Requests from unverified skills do not invoke your function.

Multiple Skills Calling the Same Function

You can configure multiple triggers if you want to invoke the same Lambda function from multiple skills. In this case, each trigger must be configured with a unique skill ID.

Add an Alexa Skills Kit Trigger

Before you add the trigger, copy the skill ID from the developer console:

  1. Go to developer.amazon.com/alexa.
  2. Click Your Alexa Consoles and then click Skills. This opens the developer console and displays any skills you have already created.
  3. Find the skill in the list. The ID is displayed below the skill name.

Once you have your skill ID, add the trigger to the function:

  1. Log in to the AWS Management Console and navigate to AWS Lambda.
  2. Click your function in the list to open the configuration details.
  3. Make sure you are on the Configuration page.
  4. In the Designer section, under Add triggers, click Alexa Skills Kit to select the trigger.
  5. Under Configure triggers, select Enable for Skill ID verification.
  6. Enter your skill ID in the Skill ID edit box.
  7. Click Add.
  8. Click Save to save the change.

It is highly recommended that you limit invocation permissions to just Alexa and enable skill ID verification to protect your function from malicious callers.

Remove an Alexa Skills Kit Trigger

You can remove a trigger from your function in the Lambda console. This also removes the skill ID verification for any skill ID included in the trigger.

  1. Log in to the AWS Management Console and navigate to AWS Lambda.
  2. Click your function in the list to open the configuration details.
  3. Make sure you are on the Configuration page. Existing triggers for the function are displayed in the Designer section at the top of the page.
  4. Click the Alexa Skills Kit box in the Designer section to display the Alexa Skills Kit triggers previously added to your skill. They are shown in an Alexa Skills Kit section at the bottom of the page.
  5. Click the Delete button next to each trigger to delete.
  6. Click Save to save the change.

Change an Existing Trigger

You cannot edit an existing trigger for a Lambda function. To change a trigger (for instance, to add or change the skill ID), remove the old trigger, then add a new trigger.

Configure Triggers with the AWS CLI or Lambda API

AWS Lambda provides both an API and command line interface (CLI) for managing Lambda functions. You can use these tools to add or remove the Alexa Skills Kit trigger as well. These let you add a resource-based policy granting the Alexa Skills Kit permission to invoke the function.

For the Alexa Skills Kit trigger, you need to set the following:

  • Action must be lambda:InvokeFunction.
  • Principal must be alexa-appkit.amazon.com.
  • EventSourceToken is the ID for your skill.

For example, this CLI command adds the trigger to the Lambda function hello_world:

aws lambda add-permission
    --function-name hello_world
    --statement-id 1
    --action lambda:InvokeFunction
    --principal alexa-appkit.amazon.com
    --event-source-token amzn1.ask.skill.xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

See AddPermission and add-permission for details about the API and CLI.

Triggers added with the API or CLI are displayed in the Lambda console just like all other triggers.

Disable Skill ID Verification

You can configure your function to not use skill ID verification if absolutely necessary. For instance, you may want to turn off the verification in an environment in which you have a large number of skills invoking the same function for testing purposes. It is still recommended that you re-enable verification before publishing your skill.

To disable skill ID verification in the Lambda console:

  1. Remove any existing triggers that are configured with skill ID verification
  2. Add a new Alexa Skills Kit trigger as described above and select Disable for Skill ID verification.

To disable skill ID verification with the Lambda API or CLI:

  1. Remove any existing triggers that are configured with skill ID verification. See RemovePermission (API) and remove-permission (CLI) for details about the API and CLI.
  2. Add a new resource-based policy granting the Alexa Skills Kit permission to invoke the function, but do not set the EventSourceToken.

For example, this CLI command adds the trigger to the Lambda function hello_world, but without skill ID verification:

aws lambda add-permission
    --function-name hello_world
    --statement-id 1
    --action lambda:InvokeFunction
    --principal alexa-appkit.amazon.com

See AWS documentation for details about using the Lambda API or CLI.

If you later want to re-enable skill ID verification (recommended before publishing the skill), delete any triggers that don't include the EventSourceToken, then add a new trigger and include the skill ID.

Test a Lambda Function in the Console

You can manually test a Lambda function in the Lambda console by sending sample JSON events formatted in the same way as requests sent by Alexa. Sample events are provided for testing within the console. You can use these events as a starting point and modify them to represent requests that the Alexa service would send to your own function. Note that you can also send events to a Lambda function using the AWS CLI.

The Lambda console does not check the conditions on the function's triggers, so your test event does not need to have a matching skill ID when you use skill ID verification.

See Request and Response JSON Reference for details about the JSON interface.

To test your function, you need to create a new test event:

  1. In the Function list, click the function name to open the details for the function.
  2. In the upper right corner of the screen, click the Select a test event drop-down list and click Configure test events.
  3. Select Create new test event and then select one of the sample Alexa requests from the Event template list:
    • Alexa Start Session
    • Alexa Intent (multiple samples available)
    • Alexa End Session
  4. Enter an Event name.
  5. Click Create.
  6. On the main function configuration page, make sure your event is selected and click the Test button.

You can configure multiple events to test sending different requests to your function.

After the function runs, the Execution result section shows the response returned by the function, in JSON format. You should see a response appropriate for the request pasted into the Sample event box. For example, for a LaunchRequest, a function built from the alexa-skills-kit-color-expert blueprint returns a response similar to this:

{
  "version": "1.0",
  "sessionAttributes": {},
  "response": {
    "outputSpeech": {
      "type": "PlainText",
      "text": "Welcome to the Alexa Skills Kit sample, Please tell me your favorite color by saying, my favorite color is red"
    },
    "card": {
      "type": "Simple",
      "title": "SessionSpeechlet - Welcome",
      "content": "SessionSpeechlet - Welcome to the Alexa Skills Kit sample, Please tell me your favorite color by saying, my favorite color is red"
    },
    "reprompt": {
      "outputSpeech": {
        "type": "PlainText",
        "text": "Please tell me your favorite color by saying, my favorite color is red"
      }
    },
    "shouldEndSession": false
  }
}

The Log output section shows any log messages generated by the code. The sample writes a log message for each type of request, so you should see something like the following:

2015-05-18T23:53:22.357Z    0f885f98-fdb9-11e4-80af-1b9f8363b496    onIntent requestId=amzn1.echo-api.request.6919844a-733e-4e89-893a-fdcb77e2ef0d, sessionId=amzn1.echo-api.session.abeee1a7-aee0-41e6-8192-e6faaed9f5ef

Sample Interaction Model for the Color Expert Blueprint

If you created the Lambda function using either the alexa-skills-kit-color-expert or alexa-skills-kit-color-expert-python blueprint, you may want to test the sample skill with either an Alexa-enabled device or the Test page. To do this, you need to create a new skill and provide an interaction model for the skill. You can copy the JSON for the model directly into a skill.

  1. Create a new skill and select Custom for the interaction model.
  2. Navigate to Custom > Interaction Model > JSON Editor.
  3. Delete the default code, then paste in the JSON shown below, then click Save Model and Build Model.
  4. Navigate to Custom > Endpoint, select AWS Lambda ARN, then enter or paste the ARN for your Lambda function in the Default Region box.

JSON version the interaction model:

{
  "interactionModel": {
    "languageModel": {
      "invocationName": "color expert",
      "intents": [
        {
          "name": "MyColorIsIntent",
          "slots": [
            {
              "name": "Color",
              "type": "LIST_OF_COLORS"
            }
          ],
          "samples": [
            "my favorite color is {Color}"
          ]
        },
        {
          "name": "WhatsMyColorIntent",
          "slots": [],
          "samples": [
            "what's my favorite color",
            "what is my favorite color",
            "what's my color",
            "what is my color",
            "my color",
            "my favorite color",
            "get my color",
            "get my favorite color",
            "give me my favorite color",
            "give me my color",
            "what my color is",
            "what my favorite color is",
            "yes",
            "yup",
            "sure",
            "yes please"
          ]
        },
        {
          "name": "AMAZON.HelpIntent",
          "samples": []
        }
      ],
      "types": [
        {
          "name": "LIST_OF_COLORS",
          "values": [
            {
              "name": {
                "value": "green"
              }
            },
            {
              "name": {
                "value": "red"
              }
            },
            {
              "name": {
                "value": "blue"
              }
            },
            {
              "name": {
                "value": "orange"
              }
            },
            {
              "name": {
                "value": "gold"
              }
            },
            {
              "name": {
                "value": "silver"
              }
            },
            {
              "name": {
                "value": "yellow"
              }
            },
            {
              "name": {
                "value": "black"
              }
            },
            {
              "name": {
                "value": "white"
              }
            }
          ]
        }
      ]
    }
  }
}

For additional Node.js and Java samples you can use with Lambda, see: