├── LICENSE ├── README.md ├── address ├── LICENSE ├── README.md ├── build.gradle ├── pom.xml ├── speechAssets │ ├── IntentSchema.json │ ├── SampleUtterances.txt │ └── SkillBuilder.json └── src │ ├── com │ └── amazon │ │ └── asksdk │ │ └── address │ │ ├── Address.java │ │ ├── AlexaDeviceAddressClient.java │ │ ├── DeviceAddressSpeechlet.java │ │ ├── DeviceAddressSpeechletRequestStreamHandler.java │ │ └── exceptions │ │ ├── DeviceAddressClientException.java │ │ └── UnauthorizedException.java │ └── resources │ └── log4j.properties ├── displaytutorial ├── LICENSE ├── README.md ├── build.gradle ├── pom.xml ├── speechAssets │ ├── IntentSchema.json │ ├── SampleUtterances.txt │ ├── SkillBuilder.json │ └── TEMPLATE_KIND_SLOT.txt └── src │ ├── com │ └── amazon │ │ └── asksdk │ │ └── displayguide │ │ ├── ActionTagScreen.java │ │ ├── BodyTemplate1Builder.java │ │ ├── BodyTemplate2Builder.java │ │ ├── BodyTemplate3Builder.java │ │ ├── BodyTemplate6Builder.java │ │ ├── DisplayGuide.java │ │ ├── DisplayGuideRequestStreamHandler.java │ │ ├── ElementSelectedRequestParser.java │ │ ├── GoodbyeScreen.java │ │ ├── HandlingListItemSelectionScreen.java │ │ ├── HelpScreen.java │ │ ├── HintTextsScreen.java │ │ ├── ImageResources.java │ │ ├── IndividualTemplateScreen.java │ │ ├── InlineImageScreen.java │ │ ├── IntentNames.java │ │ ├── IntentRequestParser.java │ │ ├── ItemList.java │ │ ├── ItemListForListTemplate1.java │ │ ├── ItemListForListTemplate2.java │ │ ├── LaunchRequestParser.java │ │ ├── ListContentGenerator.java │ │ ├── ListTemplate1Builder.java │ │ ├── ListTemplate2Builder.java │ │ ├── RequestDispatcher.java │ │ ├── RequestHandler.java │ │ ├── RequestParser.java │ │ ├── ResponseBuilder.java │ │ ├── SkillRequestInformation.java │ │ ├── SlotNames.java │ │ ├── TemplateBuilder.java │ │ ├── TemplateOverview.java │ │ ├── TextUtils.java │ │ ├── Tokens.java │ │ ├── TopicListScreen.java │ │ ├── UnhandledIntentRequestHandler.java │ │ ├── UnhandledRequestException.java │ │ ├── VideoInstructionalScreen.java │ │ ├── WatchVideo.java │ │ ├── WelcomeScreen.java │ │ └── package-info.java │ └── resources │ └── log4j.properties ├── helloworld ├── LICENSE ├── README.md ├── build.gradle ├── pom.xml ├── speechAssets │ ├── IntentSchema.json │ ├── SampleUtterances.txt │ └── SkillBuilder.json └── src │ ├── com │ └── amazon │ │ └── asksdk │ │ └── helloworld │ │ ├── HelloWorldSpeechlet.java │ │ └── HelloWorldSpeechletRequestStreamHandler.java │ └── resources │ └── log4j.properties ├── historybuff ├── LICENSE ├── README.md ├── build.gradle ├── pom.xml ├── speechAssets │ ├── IntentSchema.json │ ├── SampleUtterances.txt │ └── SkillBuilder.json └── src │ ├── com │ └── amazon │ │ └── asksdk │ │ └── historybuff │ │ ├── HistoryBuffSpeechlet.java │ │ └── HistoryBuffSpeechletRequestStreamHandler.java │ └── resources │ └── log4j.properties ├── minecrafthelper ├── LICENSE ├── README.md ├── build.gradle ├── pom.xml ├── speechAssets │ ├── IntentSchema.json │ ├── SampleUtterances.txt │ ├── SkillBuilder.json │ └── customSlotTypes │ │ └── LIST_OF_ITEMS └── src │ ├── com │ └── amazon │ │ └── asksdk │ │ └── minecrafthelper │ │ ├── MinecraftHelperSpeechletRequestStreamHandler.java │ │ ├── MinecraftSpeechlet.java │ │ └── Recipes.java │ └── resources │ └── log4j.properties ├── savvyconsumer ├── LICENSE ├── README.md ├── build.gradle ├── pom.xml ├── speechAssets │ ├── IntentSchema.json │ ├── SampleUtterances.txt │ ├── SkillBuilder.json │ └── customSlotTypes │ │ └── LIST_OF_CATEGORIES └── src │ ├── com │ └── amazon │ │ └── asksdk │ │ └── savvyconsumer │ │ ├── SavvyConsumerSpeechlet.java │ │ ├── SavvyConsumerSpeechletRequestStreamHandler.java │ │ └── SignedRequestsHelper.java │ └── resources │ └── log4j.properties ├── scorekeeper ├── LICENSE ├── README.md ├── build.gradle ├── pom.xml ├── speechAssets │ ├── IntentSchema.json │ ├── SampleUtterances.txt │ ├── SkillBuilder.json │ └── customSlotTypes │ │ └── LIST_OF_PLAYER_NAMES └── src │ ├── com │ └── amazon │ │ └── asksdk │ │ └── scorekeeper │ │ ├── ScoreKeeperManager.java │ │ ├── ScoreKeeperSpeechlet.java │ │ ├── ScoreKeeperSpeechletRequestStreamHandler.java │ │ ├── ScoreKeeperTextUtil.java │ │ ├── SkillContext.java │ │ └── storage │ │ ├── ScoreKeeperDao.java │ │ ├── ScoreKeeperDynamoDbClient.java │ │ ├── ScoreKeeperGame.java │ │ ├── ScoreKeeperGameData.java │ │ └── ScoreKeeperUserDataItem.java │ └── resources │ └── log4j.properties ├── session ├── LICENSE ├── README.md ├── build.gradle ├── pom.xml ├── speechAssets │ ├── IntentSchema.json │ ├── SampleUtterances.txt │ ├── SkillBuilder.json │ └── customSlotTypes │ │ └── LIST_OF_COLORS └── src │ ├── com │ └── amazon │ │ └── asksdk │ │ └── session │ │ ├── SessionSpeechlet.java │ │ └── SessionSpeechletRequestStreamHandler.java │ └── resources │ └── log4j.properties ├── spacegeek ├── LICENSE ├── README.md ├── build.gradle ├── pom.xml ├── speechAssets │ ├── IntentSchema.json │ ├── SampleUtterances.txt │ └── SkillBuilder.json └── src │ ├── com │ └── amazon │ │ └── asksdk │ │ └── spacegeek │ │ ├── SpaceGeekSpeechlet.java │ │ └── SpaceGeekSpeechletRequestStreamHandler.java │ └── resources │ └── log4j.properties ├── tidepooler ├── LICENSE ├── README.md ├── build.gradle ├── pom.xml ├── speechAssets │ ├── IntentSchema.json │ ├── SampleUtterances.txt │ ├── SkillBuilder.json │ └── customSlotTypes │ │ ├── LIST_OF_CITIES │ │ └── LIST_OF_STATES └── src │ ├── com │ └── amazon │ │ └── asksdk │ │ └── tidepooler │ │ ├── AlexaDateUtil.java │ │ ├── TidePoolerSpeechlet.java │ │ └── TidePoolerSpeechletRequestStreamHandler.java │ └── resources │ └── log4j.properties └── wiseguy ├── LICENSE ├── README.md ├── build.gradle ├── pom.xml ├── speechAssets ├── IntentSchema.json ├── SampleUtterances.txt ├── SkillBuilder.json └── customSlotTypes │ └── LIST_OF_SETUP_NAMES └── src ├── com └── amazon │ └── asksdk │ └── wiseguy │ ├── WiseGuySpeechlet.java │ └── WiseGuySpeechletRequestStreamHandler.java └── resources └── log4j.properties /LICENSE: -------------------------------------------------------------------------------- 1 | This repository contains multiple directories, each individually licensed. Please see the LICENSE file in each directory. 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # **These samples utilize a version of the Alexa Skills Kit SDK that is no longer supported. Please visit the project repository [here](https://github.com/alexa/alexa-skills-kit-sdk-for-java) to find resources for using the latest SDK** 2 | 3 | # Alexa Skills Kit SDK Java Samples 4 | 5 | ## Alexa Skills Kit Documentation 6 | The documentation for the Alexa Skills Kit is available on the [Amazon Apps and Services Developer Portal](https://developer.amazon.com/appsandservices/solutions/alexa/alexa-skills-kit/). 7 | 8 | ## Contents 9 | The included samples represent how to use Java AWS Lambda functions as Alexa Skills.The following samples are included (ordered by complexity, see the Using Alexa Skills Kit Samples link below for more details): 10 | - HelloWorld: a simple skill that repeats Hello World! on user input 11 | - SpaceGeek : a simple skill that responds to the user with a space fact. 12 | - Session: a simple skill that asks for your favorite color, then repeats it back to you using session attributes. 13 | - MinecraftHelper : a simple skill that responds to the user's recipe queries with formulas. 14 | - WiseGuy : a skill that tells knock knock jokes. 15 | - HistoryBuff : a skill that gives historical information that happened on a user provided day. 16 | - Savvy Consumer : a skill that looks up a category on Amazon and returns the best selling products. 17 | - TidePooler : a skill that looks up tide information for various cities. 18 | - ScoreKeeper : a skill that can keep score of a game. 19 | - Device Address : a skill that demonstrates how to use the Device Address API. 20 | - DisplayTutorial: a skill that showcases the features of the Amazon Echo Show. 21 | 22 | ## Usage 23 | Navigate to the README.md in each sub directory in the samples folder and follow the instructions for getting the sample up and running. 24 | 25 | ## Resources 26 | Here are a few direct links to our documentation: 27 | 28 | - [Using the Alexa Skills Kit Samples](https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/using-the-alexa-skills-kit-samples) 29 | - [Getting Started](https://developer.amazon.com/appsandservices/solutions/alexa/alexa-skills-kit/getting-started-guide) 30 | - [Invocation Name Guidelines](https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/choosing-the-invocation-name-for-an-alexa-skill) 31 | - [Developing an Alexa Skill as an AWS Lambda Function](https://developer.amazon.com/appsandservices/solutions/alexa/alexa-skills-kit/docs/developing-an-alexa-skill-as-a-lambda-function) 32 | -------------------------------------------------------------------------------- /address/README.md: -------------------------------------------------------------------------------- 1 | # Alexa Skill Kit SDK Sample - Address 2 | A simple [AWS Lambda](http://aws.amazon.com/lambda) function that demonstrates how to write a skill for the Amazon Echo using the Alexa SDK. 3 | 4 | ## Concepts 5 | This sample shows how to create a Lambda function for handling Alexa Skill requests that: 6 | 7 | - Web service: communicate with an external web service to retrieve the address of the current user. 8 | - Dialog and Session state: Handles two models, both a one-shot ask and tell model, and a multi-turn dialog model. 9 | 10 | ## Setup 11 | To run this example skill you need to do two things. The first is to deploy the example code in lambda, and the second is to configure the Alexa skill to use Lambda. 12 | 13 | ### AWS Lambda Setup 14 | 1. Go to the AWS Console and click on the Lambda link. Note: ensure you are in us-east or you wont be able to use Alexa with Lambda. 15 | 2. Click on the Create Function button. 16 | 3. Click Author from scratch. 17 | 4. In Configure triggers, add Alexa Skill kit as trigger. 18 | 5. Name the Lambda Function "Address-API-Example-Skill". 19 | 6. Select the runtime as Java 8. 20 | 7. Build a jar file to upload it into the lambda function. There are two ways: 21 | - Using maven: go to the directory containing pom.xml, and run 'mvn assembly:assembly -DdescriptorId=jar-with-dependencies package'. This will generate a zip file named "address-1.0-jar-with-dependencies.jar" in the target directory. 22 | - Using gradle: go to the directory containing build.gradle, and run 'gradle fatJar'. This will generate a zip file named "address-fat-1.0.jar" in the build/libs directory. 23 | 8. Select Code entry type as "Upload a .ZIP file" and then upload the jar file created in step 7 from the build directory to Lambda. 24 | 9. Set the Handler as com.amazon.asksdk.address.DeviceAddressSpeechletRequestStreamHandler (this refers to the Lambda RequestStreamHandler file in the zip). 25 | 10. Choose an existing role - lambda_basic_execution. 26 | 11. Increase the Timeout to 30 seconds under Basic Settings. 27 | 12. Leave the Advanced settings as the defaults. 28 | 13. Click "Next" and review the settings then click "Create Function". 29 | 14. Copy the ARN from the top right to be used later in the Alexa Skill Setup. 30 | 31 | ### Alexa Skill Setup 32 | 1. Go to the [Alexa Console](https://developer.amazon.com/edw/home.html) and click Add a New Skill. 33 | 2. Set "AddressSkill" as the skill name and "address skill" as the invocation name, this is what is used to activate your skill. For example you would say: "Alexa, Ask address Skill what's my address." 34 | 3. Select the Lambda ARN for the skill Endpoint and paste the ARN copied from above. Click Next. 35 | 4. Copy the contents of SpeechAssets. 36 | - If you are using the new Skill Builder, copy the Skill Builder from included SkillBuilder.json. 37 | - Otherwise, copy the Intent Schema from the included IntentSchema.json. Copy the Sample Utterances from the included SampleUtterances.txt. Click Next. 38 | 5. Go back to the skill Information tab and copy the appId. Paste the appId into the DeviceAddressSpeechletRequestStreamHandler.java file for the variable supportedApplicationIds, 39 | then update the lambda source zip file with this change and upload to lambda again, this step makes sure the lambda function only serves request from authorized source. 40 | 6. You are now able to start testing your sample skill! You should be able to go to the [Echo webpage](http://echo.amazon.com/#skills) and see your skill enabled. 41 | 7. In order to test it, try to say some of the Sample Utterances from the Examples section below. 42 | 8. Your skill is now saved and once you are finished testing you can continue to publish your skill. 43 | 44 | ## Examples 45 | ### One-shot model: 46 | User: "Alexa, ask address Skill what's my address." 47 | Alexa: "Your address is ...." 48 | ### Dialog model: 49 | User: "Alexa, open address Skill" 50 | Alexa: "Welcome to the Sample Address API Skill! What do you want to ask?" 51 | User: "What's my address?" 52 | Alexa: "Your address is ...." 53 | -------------------------------------------------------------------------------- /address/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | 3 | group = "alexa-skills-kit-samples" 4 | version = '1.0' 5 | 6 | compileJava { 7 | targetCompatibility = JavaVersion.VERSION_1_8 8 | sourceCompatibility = JavaVersion.VERSION_1_8 9 | } 10 | 11 | jar { 12 | manifest { 13 | attributes 'Implementation-Title': 'Gradle Quickstart', 14 | 'Implementation-Version': version 15 | } 16 | } 17 | 18 | repositories { 19 | jcenter() 20 | mavenCentral() 21 | } 22 | 23 | sourceSets { 24 | main { 25 | java { 26 | srcDirs 'src' 27 | } 28 | resources { 29 | srcDirs 'src/resources' 30 | } 31 | } 32 | } 33 | 34 | dependencies { 35 | compile 'com.amazon.alexa:alexa-skills-kit:1.5.0' 36 | compile 'com.amazonaws:aws-lambda-java-core:1.0.0' 37 | compile 'com.amazonaws:aws-java-sdk-dynamodb:1.9.40' 38 | compile 'com.amazonaws:aws-lambda-java-log4j:1.0.0' 39 | 40 | compile 'log4j:log4j:1.2.17' 41 | compile 'org.apache.commons:commons-lang3:3.3.2' 42 | compile 'org.apache.directory.studio:org.apache.commons.io:2.4' 43 | compile 'org.eclipse.jetty:jetty-server:9.0.6.v20130930' 44 | compile 'org.eclipse.jetty:jetty-servlet:9.0.6.v20130930' 45 | compile 'org.slf4j:slf4j-api:1.7.10' 46 | } 47 | 48 | task fatJar(type: Jar) { 49 | baseName = project.name + '-fat' 50 | from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } 51 | with jar 52 | } 53 | 54 | build.dependsOn fatJar 55 | -------------------------------------------------------------------------------- /address/speechAssets/IntentSchema.json: -------------------------------------------------------------------------------- 1 | { 2 | "intents": [ 3 | { 4 | "intent": "GetAddress" 5 | }, 6 | { 7 | "intent": "AMAZON.HelpIntent" 8 | } 9 | ] 10 | } -------------------------------------------------------------------------------- /address/speechAssets/SampleUtterances.txt: -------------------------------------------------------------------------------- 1 | GetAddress where am I located 2 | GetAddress where do I live 3 | GetAddress whats my address 4 | GetAddress where am I 5 | GetAddress whats my address -------------------------------------------------------------------------------- /address/speechAssets/SkillBuilder.json: -------------------------------------------------------------------------------- 1 | { 2 | "languageModel": { 3 | "intents": [ 4 | { 5 | "name": "AMAZON.CancelIntent", 6 | "samples": [] 7 | }, 8 | { 9 | "name": "AMAZON.HelpIntent", 10 | "samples": [] 11 | }, 12 | { 13 | "name": "AMAZON.StopIntent", 14 | "samples": [] 15 | }, 16 | { 17 | "name": "GetAddress", 18 | "samples": [ 19 | "where am I located", 20 | "where do I live", 21 | "whats my address", 22 | "where am I" 23 | ], 24 | "slots": [] 25 | } 26 | ], 27 | "invocationName": "address skill" 28 | } 29 | } -------------------------------------------------------------------------------- /address/src/com/amazon/asksdk/address/Address.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use 5 | * this file except in compliance with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | package com.amazon.asksdk.address; 16 | 17 | /** 18 | * This is a wrapper class that mimics the JSON structure returned from the Alexa Device Address API. 19 | * Refer to the Alexa Device Address API documentation on https://developer.amazon.com/ for more info. 20 | * Note that depending on the API path that you hit, not all properties will be populated. 21 | */ 22 | public class Address { 23 | 24 | private String stateOrRegion; 25 | private String city; 26 | private String countryCode; 27 | private String postalCode; 28 | private String addressLine1; 29 | private String addressLine2; 30 | private String addressLine3; 31 | private String districtOrCounty; 32 | 33 | private Address() { 34 | 35 | } 36 | 37 | public String getStateOrRegion() { 38 | return stateOrRegion; 39 | } 40 | 41 | public String getAddressLine1() { 42 | return addressLine1; 43 | } 44 | 45 | public String getAddressLine2() { 46 | return addressLine2; 47 | } 48 | 49 | public String getAddressLine3() { 50 | return addressLine3; 51 | } 52 | 53 | public String getCity() { 54 | return city; 55 | } 56 | 57 | public String getCountryCode() { 58 | return countryCode; 59 | } 60 | 61 | public String getPostalCode() { 62 | return postalCode; 63 | } 64 | 65 | public String getDistrictOrCounty() { 66 | return districtOrCounty; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /address/src/com/amazon/asksdk/address/DeviceAddressSpeechletRequestStreamHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use 5 | * this file except in compliance with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | package com.amazon.asksdk.address; 16 | 17 | import java.util.HashSet; 18 | import java.util.Set; 19 | 20 | import com.amazon.speech.speechlet.lambda.SpeechletRequestStreamHandler; 21 | 22 | /** 23 | * This class could be the handler for an AWS Lambda function powering an Alexa Skills Kit 24 | * experience. To do this, simply set the handler field in the AWS Lambda console to 25 | * "address.DeviceAddressSpeechletRequestStreamHandler" For this to work, you'll also need to 26 | * build this project using the {@code lambda-compile} Ant task and upload the resulting zip file to 27 | * power your function. 28 | */ 29 | public class DeviceAddressSpeechletRequestStreamHandler extends SpeechletRequestStreamHandler { 30 | 31 | private static final Set supportedApplicationIds; 32 | 33 | static { 34 | /* 35 | * This Id can be found on https://developer.amazon.com/edw/home.html#/ "Edit" the relevant 36 | * Alexa Skill and put the relevant Application Ids in this Set. 37 | */ 38 | supportedApplicationIds = new HashSet(); 39 | // supportedApplicationIds.add("[unique-value-here]"); 40 | } 41 | 42 | public DeviceAddressSpeechletRequestStreamHandler() { 43 | super(new DeviceAddressSpeechlet(), supportedApplicationIds); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /address/src/com/amazon/asksdk/address/exceptions/DeviceAddressClientException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use 5 | * this file except in compliance with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | package com.amazon.asksdk.address.exceptions; 16 | 17 | import com.amazon.asksdk.address.AlexaDeviceAddressClient; 18 | 19 | /** 20 | * This is an exception thrown from the {@link AlexaDeviceAddressClient} that indicates that a failure occurred. 21 | */ 22 | public class DeviceAddressClientException extends Exception { 23 | 24 | public DeviceAddressClientException(String message, Exception e) { 25 | super(message, e); 26 | } 27 | 28 | public DeviceAddressClientException(String message) { 29 | super(message); 30 | } 31 | 32 | public DeviceAddressClientException(Exception e) { 33 | super(e); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /address/src/com/amazon/asksdk/address/exceptions/UnauthorizedException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). You may not use 5 | * this file except in compliance with the License. A copy of the License is located at 6 | * 7 | * http://aws.amazon.com/apache2.0/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | package com.amazon.asksdk.address.exceptions; 16 | 17 | import com.amazon.asksdk.address.DeviceAddressSpeechlet; 18 | 19 | /** 20 | * This exception indicates that the AlexaDeviceAddressClient failed because of a permission specific 21 | * reason. This is an exception aside from {@link DeviceAddressClientException} because permission related 22 | * issues should be handled separately from a generic failure. 23 | * 24 | * Refer to {@link DeviceAddressSpeechlet} to see how permission related errors are handled. 25 | */ 26 | public class UnauthorizedException extends DeviceAddressClientException { 27 | 28 | public UnauthorizedException(String message, Exception e) { 29 | super(message, e); 30 | } 31 | 32 | public UnauthorizedException(String message) { 33 | super(message); 34 | } 35 | } -------------------------------------------------------------------------------- /address/src/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log = . 2 | log4j.rootLogger = DEBUG, LAMBDA 3 | 4 | #Define the LAMBDA appender 5 | log4j.appender.LAMBDA=com.amazonaws.services.lambda.runtime.log4j.LambdaAppender 6 | log4j.appender.LAMBDA.layout=org.apache.log4j.PatternLayout 7 | log4j.appender.LAMBDA.layout.conversionPattern=%d{yyyy-MM-dd HH:mm:ss} <%X{AWSRequestId}> %-5p %c{1}:%L - %m%n 8 | -------------------------------------------------------------------------------- /displaytutorial/README.md: -------------------------------------------------------------------------------- 1 | Alexa Skill Kit SDK Sample - Display Interface Guide 2 | =================== 3 | 4 | 5 | Welcome to Display Interface Guide. The Display interface guide is a tutorial-style Alexa Skill that showcases the features of the Amazon Echo Show. It is written in Java using the Alexa Skills Kit Java SDK. 6 | 7 | ---------- 8 | 9 | 10 | Contents 11 | ------------- 12 | This skill shows how to create a Lambda function for handling Alexa Skill requests and sending responses in Echo Show with: 13 | 14 | - Render templates: 4 body templates and 2 list templates. 15 | - Inline images: each template allows different sizes of the image. 16 | - Videos: display and watch the video. 17 | - Selection by voice and touch: select an item in the list either by voice or by touch. 18 | - Action tag: create a clickable text. 19 | - Hints: include a hint text. 20 | 21 | 22 | 23 | 24 | 25 | Setup 26 | ------------- 27 | To run this example skill you need to do two things. The first is to deploy the example code in lambda, and the second is to configure the Alexa skill to use Lambda. 28 | 29 | AWS Lambda Setup 30 | ---------------------------- 31 | 1. Go to the [AWS Console](https://aws.amazon.com/) and click on the Lambda link. Note: ensure you are in us-east or you wont be able to use Alexa with Lambda. 32 | 2. Click on the Create Function button. 33 | 3. Click Author from scratch. 34 | 4. In Configure triggers, add Alexa Skill kit as trigger. 35 | 5. Name the Lambda Function "Display-Interface-Guide-Skill". 36 | 6. Select the runtime as Java 8. 37 | 7. Build a jar file to upload it into the lambda function. There are two ways: 38 | - Using maven: go to the directory containing pom.xml, and run 'mvn assembly:assembly -DdescriptorId=jar-with-dependencies package'. This will generate a zip file named "displaytutorial-1.0-jar-with-dependencies.jar" in the target directory. 39 | - Using gradle: go to the directory containing build.gradle, and run 'gradle fatJar'. This will generate a zip file named "displaytutorial-fat-1.0.jar" in the build/libs directory. 40 | 8. Select Code entry type as "Upload a .ZIP file" and then upload the jar file created in step 7 from the build directory to Lambda. 41 | 9. Set the Handler as com.amazon.asksdk.displayguide.DisplayGuideRequestStreamHandler (this refers to the Lambda RequestStreamHandler file in the zip). 42 | 10. Choose an existing role - lambda_basic_execution. 43 | 11. Increase the Timeout to 30 seconds under Basic Settings. 44 | 12. Leave the Advanced settings as the defaults. 45 | 13. Click "Next" and review the settings then click "Create Function". 46 | 14. Copy the ARN from the top right to be used later in the Alexa Skill Setup. 47 | 48 | Alexa Skill Setup 49 | ------------------------ 50 | 1. Go to the [Alexa Console](https://developer.amazon.com) and click Add a New Skill in Alexa link. 51 | 2. Set "Display interface Guide" as the skill name and "Display Guide" as the invocation name, this is what is used to activate your skill. For example you would say: "Alexa, Ask Display Guide to show me how to play a video." 52 | 3. Select the Lambda ARN for the skill Endpoint and paste the ARN copied from above. Click Next. 53 | 4. Copy the contents of SpeechAssets. 54 | - If you are using the new Skill Builder, copy the Skill Builder from included SkillBuilder.json. 55 | - Otherwise, copy the Intent Schema from the included IntentSchema.json. Copy the Sample Utterances from the included SampleUtterances.txt. Copy the custom slot types from the customSlotTypes folder. Each file in the folder represents a new custom slot type. The name of the file is the name of the custom slot type, and the values in the file are the values for the custom slot. Click Next. 56 | 5. Go back to the skill Information tab and copy the appId. Paste the appId into the DisplayGuideRequestStreamHandler.java file for the variable supportedApplicationIds, then update the lambda source zip file with this change and upload to lambda again, this step makes sure the lambda function only serves request from authorized source. 57 | 6. You are now able to start using your sample skill! You should be able to go to the [Echo webpage](https://alexa.amazon.com/) and see your skill enabled. 58 | 7. In order to test it, try to say some of the Sample Utterances from the Examples section below. 59 | 8. Your skill is now saved and once you are finished testing you can continue to publish your skill. 60 | 61 | Examples 62 | -------------- 63 | User: "Alexa, ask display guide to show me topics I can learn about" 64 | User: "how do I use a template" 65 | User: "how do I play a video" 66 | User: "how do I show an image inline with text" 67 | User: "how do I include an action tag" 68 | User: "how do I handle selection of list items" 69 | User: "how do I use a hint" 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /displaytutorial/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | 3 | group = "alexa-skills-kit-samples" 4 | version = '1.0' 5 | 6 | compileJava { 7 | targetCompatibility = JavaVersion.VERSION_1_8 8 | sourceCompatibility = JavaVersion.VERSION_1_8 9 | } 10 | 11 | jar { 12 | manifest { 13 | attributes 'Implementation-Title': 'Gradle Quickstart', 14 | 'Implementation-Version': version 15 | } 16 | } 17 | 18 | repositories { 19 | jcenter() 20 | mavenCentral() 21 | } 22 | 23 | sourceSets { 24 | main { 25 | java { 26 | srcDirs 'src' 27 | } 28 | resources { 29 | srcDirs 'src/resources' 30 | } 31 | } 32 | } 33 | 34 | dependencies { 35 | compile 'com.amazon.alexa:alexa-skills-kit:1.5.0' 36 | compile 'com.amazonaws:aws-lambda-java-core:1.0.0' 37 | compile 'com.amazonaws:aws-java-sdk-dynamodb:1.9.40' 38 | compile 'com.amazonaws:aws-lambda-java-log4j:1.0.0' 39 | 40 | compile 'log4j:log4j:1.2.17' 41 | compile 'org.apache.commons:commons-lang3:3.3.2' 42 | compile 'org.apache.directory.studio:org.apache.commons.io:2.4' 43 | compile 'org.eclipse.jetty:jetty-server:9.0.6.v20130930' 44 | compile 'org.eclipse.jetty:jetty-servlet:9.0.6.v20130930' 45 | compile 'org.slf4j:slf4j-api:1.7.10' 46 | } 47 | 48 | task fatJar(type: Jar) { 49 | baseName = project.name + '-fat' 50 | from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } 51 | with jar 52 | } 53 | 54 | build.dependsOn fatJar 55 | -------------------------------------------------------------------------------- /displaytutorial/speechAssets/IntentSchema.json: -------------------------------------------------------------------------------- 1 | { 2 | "intents": [ 3 | { 4 | "intent": "AMAZON.PreviousIntent" 5 | }, 6 | { 7 | "intent": "AMAZON.NextIntent" 8 | }, 9 | { 10 | "intent": "AMAZON.HelpIntent" 11 | }, 12 | { 13 | "intent": "AMAZON.ScrollUpIntent" 14 | }, 15 | { 16 | "intent": "AMAZON.ScrollLeftIntent" 17 | }, 18 | { 19 | "intent": "AMAZON.ScrollDownIntent" 20 | }, 21 | { 22 | "intent": "AMAZON.ScrollRightIntent" 23 | }, 24 | { 25 | "intent": "AMAZON.PageUpIntent" 26 | }, 27 | { 28 | "intent": "AMAZON.PageDownIntent" 29 | }, 30 | { 31 | "intent": "AMAZON.MoreIntent" 32 | }, 33 | { 34 | "intent": "AMAZON.NavigateHomeIntent" 35 | }, 36 | { 37 | "intent": "AMAZON.NavigateSettingsIntent" 38 | }, 39 | { 40 | "intent": "AMAZON.StopIntent" 41 | }, 42 | { 43 | "intent": "WelcomeIntent" 44 | }, 45 | { 46 | "intent": "TopicListIntent" 47 | }, 48 | { 49 | "intent": "TemplateOverviewIntent" 50 | }, 51 | { 52 | "intent": "IndividualTemplateIntent", 53 | "slots": [ 54 | { 55 | "name": "number", 56 | "type": "AMAZON.NUMBER" 57 | }, 58 | { 59 | "name": "template_kind", 60 | "type": "TEMPLATE_KIND_SLOT" 61 | } 62 | ] 63 | }, 64 | { 65 | "intent": "SelectItemIntent", 66 | "slots": [ 67 | { 68 | "name": "number", 69 | "type": "AMAZON.NUMBER" 70 | } 71 | ] 72 | }, 73 | { 74 | "intent": "WatchVideoIntent" 75 | }, 76 | { 77 | "intent": "VideoInstructionalIntent" 78 | }, 79 | { 80 | "intent": "InlineImageTagIntent" 81 | }, 82 | { 83 | "intent": "ActionTagIntent" 84 | }, 85 | { 86 | "intent": "ItemSelectionIntent" 87 | }, 88 | { 89 | "intent": "AMAZON.YesIntent" 90 | }, 91 | { 92 | "intent": "AMAZON.NoIntent" 93 | }, 94 | { 95 | "intent": "HintsIntent" 96 | } 97 | ] 98 | } -------------------------------------------------------------------------------- /displaytutorial/speechAssets/SampleUtterances.txt: -------------------------------------------------------------------------------- 1 | WelcomeIntent Welcome screen 2 | 3 | TopicListIntent show me topics I can learn about 4 | TopicListIntent topics 5 | 6 | TemplateOverviewIntent how do you render a template 7 | TemplateOverviewIntent how do I use a template 8 | TemplateOverviewIntent Rendering Templates 9 | TemplateOverviewIntent go back to the list of templates 10 | TemplateOverviewIntent list of templates 11 | TemplateOverviewIntent using the Render Template Directive 12 | TemplateOverviewIntent templates 13 | 14 | IndividualTemplateIntent {template_kind} template {number} 15 | IndividualTemplateIntent {template_kind} template {number} example 16 | 17 | 18 | SelectItemIntent select number {number} 19 | SelectItemIntent select {number} 20 | SelectItemIntent choose number {number} 21 | SelectItemIntent choose {number} 22 | SelectItemIntent number {number} 23 | 24 | VideoInstructionalIntent how do I play a video 25 | VideoInstructionalIntent show me how to play a video 26 | VideoInstructionalIntent showing videos 27 | VideoInstructionalIntent videos 28 | 29 | WatchVideoIntent watch video 30 | WatchVideoIntent watch sample video 31 | WatchVideoIntent watch the video 32 | WatchVideoIntent launch video 33 | WatchVideoIntent launch sample video 34 | WatchVideoIntent play the video 35 | 36 | InlineImageTagIntent image 37 | InlineImageTagIntent how do I show an image inline with text 38 | InlineImageTagIntent including images inline with text 39 | InlineImageTagIntent including images in rich text areas 40 | InlineImageTagIntent including images in rich text elements 41 | InlineImageTagIntent inline images 42 | InlineImageTagIntent include inline images 43 | 44 | ActionTagIntent actions 45 | ActionTagIntent action 46 | ActionTagIntent how do I include an action tag 47 | ActionTagIntent how do I use an action tag 48 | ActionTagIntent how do I use an action 49 | ActionTagIntent how do I use an action element 50 | ActionTagIntent how do I link between templates 51 | ActionTagIntent can you add a clickable link 52 | ActionTagIntent how do you include clickable actions 53 | ActionTagIntent how do you include an action 54 | ActionTagIntent how do you include and action tag 55 | ActionTagIntent text wrapped in an action tag is selectable on-screen 56 | ActionTagIntent clickable actions 57 | 58 | ItemSelectionIntent how do you handle selection of list items 59 | ItemSelectionIntent how do I handle selection of list items 60 | ItemSelectionIntent handling list item selection 61 | ItemSelectionIntent list item touch events 62 | ItemSelectionIntent select a list item by voice 63 | ItemSelectionIntent selecting list items 64 | ItemSelectionIntent list item selection 65 | 66 | HintsIntent hints 67 | HintsIntent what is a hint 68 | HintsIntent what is a hint text 69 | HintsIntent what is a hint phrase 70 | HintsIntent hint phrases 71 | HintsIntent hint texts 72 | HintsIntent how do I use a hint 73 | HintsIntent how do you include a hint text 74 | 75 | -------------------------------------------------------------------------------- /displaytutorial/speechAssets/TEMPLATE_KIND_SLOT.txt: -------------------------------------------------------------------------------- 1 | body 2 | list -------------------------------------------------------------------------------- /displaytutorial/src/com/amazon/asksdk/displayguide/ActionTagScreen.java: -------------------------------------------------------------------------------- 1 | /* 2 | *Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | *Licensed under the Amazon Software License (the "License"). You may not use 5 | * this file except in compliance with the License. A copy of the License is located at 6 | * 7 | *http://aws.amazon.com/asl/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or 11 | * implied. See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | package com.amazon.asksdk.displayguide; 16 | 17 | import com.amazon.speech.speechlet.SpeechletResponse; 18 | 19 | import static com.amazon.asksdk.displayguide.TextUtils.LINE_BREAK; 20 | import static com.amazon.asksdk.displayguide.TextUtils.wrapTextInAction; 21 | import static com.amazon.asksdk.displayguide.TextUtils.wrapTextInBold; 22 | import static com.amazon.asksdk.displayguide.TextUtils.escapeXML; 23 | import static com.amazon.asksdk.displayguide.TextUtils.makeRichText; 24 | 25 | /** 26 | * The ActionTagScreen class handles touch and intent request events for the Action Tag Screen 27 | * which describes to the user how to use an Action tag, and best practices for using an Action 28 | * tag. 29 | */ 30 | public class ActionTagScreen extends RequestHandler { 31 | @Override 32 | boolean canHandle(final SkillRequestInformation skillRequestInformation) { 33 | return isIntentOrItemFromTopicList(skillRequestInformation, IntentNames.ACTION_TAG_INTENT, "4"); 34 | } 35 | 36 | @Override 37 | SpeechletResponse handle(final SkillRequestInformation skillRequestInformation) { 38 | String title = "Including actions in rich text elements"; 39 | String shortDescription = "Text that is wrapped in an action tag is selectable by touch on the screen. " 40 | + "Try clicking the Welcome Screen action above to go back to the Display Interface Guide's welcome " 41 | + "screen. "; 42 | 43 | String speech = shortDescription + " Look to your Echo Show screen to read more."; 44 | 45 | String bodyText = wrapTextInAction("Welcome Screen", IntentNames.WELCOME_INTENT) + LINE_BREAK + LINE_BREAK 46 | + shortDescription + LINE_BREAK + LINE_BREAK 47 | + "Keep actions separate from the rest of the text. Make sure you also include an utterance that " 48 | + "matches the text of the action, so that users can say the action text and get the same response " 49 | + "as clicking the text. Don't display more than three actions per template. If you need to have more " 50 | + "than three selectable elements, use a list template instead." 51 | + LINE_BREAK + LINE_BREAK 52 | + "The format for including an action is: " + LINE_BREAK + LINE_BREAK 53 | + wrapTextInBold(escapeXML(" Selectable Text")) + LINE_BREAK 54 | + LINE_BREAK 55 | + "When a user clicks on the text, your skill will receive an event with a Display.ElementSelected " 56 | + "request with a token value of \"token\". You, as the skill developer, can then use the token to map" 57 | + " the touch interaction to an appropriate response. You can use your preferred methodology to name " 58 | + "the tokens."; 59 | 60 | return new ResponseBuilder() 61 | .setSpeech(speech) 62 | .addTemplateDirective(new BodyTemplate1Builder() 63 | .setPrimaryText(makeRichText(bodyText)) 64 | .setTitle(title) 65 | .setToken(Tokens.ACTION_TAG_SCREEN_TOKEN) 66 | .build()) 67 | .build(); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /displaytutorial/src/com/amazon/asksdk/displayguide/BodyTemplate1Builder.java: -------------------------------------------------------------------------------- 1 | /* 2 | *Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | *Licensed under the Amazon Software License (the "License"). You may not use 5 | * this file except in compliance with the License. A copy of the License is located at 6 | * 7 | *http://aws.amazon.com/asl/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or 11 | * implied. See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | package com.amazon.asksdk.displayguide; 16 | 17 | import com.amazon.speech.speechlet.interfaces.display.element.TextField; 18 | import com.amazon.speech.speechlet.interfaces.display.template.BodyTemplate1; 19 | 20 | /** 21 | * The BodyTemplate1Builder class provides an external Builder class for 3rd party skill code to 22 | * construct a BodyTemplate1 template at anytime. 23 | */ 24 | public class BodyTemplate1Builder extends TemplateBuilder { 25 | 26 | private BodyTemplate1.TextContent textContent = new BodyTemplate1.TextContent(); 27 | 28 | /** 29 | * Sets the primaryText field of the TextContent field of BodyTemplate1. 30 | * @param primaryText a TextField object (either RichText or PlainText) containing the desired primaryText string 31 | * @return the BodyTemplate1Builder object that the method was called upon with the new primaryText field 32 | */ 33 | public BodyTemplate1Builder setPrimaryText(final TextField primaryText) { 34 | this.textContent.setPrimaryText(primaryText); 35 | return this; 36 | } 37 | 38 | /** 39 | * Sets the secondaryText field of the TextContent field of BodyTemplate1. 40 | * @param secondaryText a TextField object (either RichText or PlainText) containing the desired secondaryText 41 | * string 42 | * @return the BodyTemplate1Builder object that the method was called upon with the new secondaryText field 43 | */ 44 | public BodyTemplate1Builder setSecondaryText(final TextField secondaryText) { 45 | this.textContent.setSecondaryText(secondaryText); 46 | return this; 47 | } 48 | 49 | /** 50 | * Sets the tertiaryText field of the TextContent field of BodyTemplate1. 51 | * @param tertiaryText a TextField object (either RichText or PlainText) containing the desired tertiaryText string 52 | * @return the BodyTemplate1Builder object that the method was called upon with the new tertiaryText field 53 | */ 54 | public BodyTemplate1Builder setTertiaryText(final TextField tertiaryText) { 55 | this.textContent.setTertiaryText(tertiaryText); 56 | return this; 57 | } 58 | 59 | /** 60 | * Builds a new BodyTemplate1 object with the current attributes of the BodyTemplate1Builder object. 61 | * @return a newly constructed BodyTemplate1 object 62 | */ 63 | @Override 64 | public BodyTemplate1 build() { 65 | BodyTemplate1 template = new BodyTemplate1(); 66 | template.setTitle(title); 67 | template.setToken(token); 68 | template.setTextContent(textContent); 69 | template.setBackgroundImage(bgImage); 70 | template.setBackButtonBehavior(backButtonBehavior); 71 | return template; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /displaytutorial/src/com/amazon/asksdk/displayguide/BodyTemplate2Builder.java: -------------------------------------------------------------------------------- 1 | /* 2 | *Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | *Licensed under the Amazon Software License (the "License"). You may not use 5 | * this file except in compliance with the License. A copy of the License is located at 6 | * 7 | *http://aws.amazon.com/asl/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or 11 | * implied. See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | package com.amazon.asksdk.displayguide; 16 | 17 | import com.amazon.speech.speechlet.interfaces.display.element.Image; 18 | import com.amazon.speech.speechlet.interfaces.display.element.TextField; 19 | import com.amazon.speech.speechlet.interfaces.display.template.BodyTemplate2; 20 | 21 | /** 22 | * The BodyTemplate2Builder class provides an external Builder class for 3rd party skill code to 23 | * construct a BodyTemplate2 template at anytime. 24 | */ 25 | public class BodyTemplate2Builder extends TemplateBuilder { 26 | 27 | private Image fgImage; 28 | private BodyTemplate2.TextContent textContent = new BodyTemplate2.TextContent(); 29 | 30 | /** 31 | * Sets the Image field of BodyTemplate2. The Image field of BodyTemplate2 is a foreground image on 32 | * the right side of the template. 33 | * @param fgImage an Image object containing a list of ImageInstance sources and an optional content description 34 | * @return the BodyTemplate2Builder object that the method was called upon with the new Image field 35 | */ 36 | public BodyTemplate2Builder setFgImage(final Image fgImage) { 37 | this.fgImage = fgImage; 38 | return this; 39 | } 40 | 41 | /** 42 | * Sets the primaryText field of the TextContent field of BodyTemplate2. 43 | * @param primaryText a TextField object (either RichText or PlainText) containing the desired primaryText string 44 | * @return the BodyTemplate2Builder object that the method was called upon with the new primaryText field 45 | */ 46 | public BodyTemplate2Builder setPrimaryText(final TextField primaryText) { 47 | this.textContent.setPrimaryText(primaryText); 48 | return this; 49 | } 50 | 51 | /** 52 | * Sets the secondaryText field of the TextContent field of BodyTemplate2. 53 | * @param secondaryText a TextField object (either RichText or PlainText) containing the desired secondaryText 54 | * string 55 | * @return the BodyTemplate2Builder object that the method was called upon with the new secondaryText field 56 | */ 57 | public BodyTemplate2Builder setSecondaryText(final TextField secondaryText) { 58 | this.textContent.setSecondaryText(secondaryText); 59 | return this; 60 | } 61 | 62 | /** 63 | * Sets the tertiaryText field of the TextContent field of BodyTemplate2. 64 | * @param tertiaryText a TextField object (either RichText or PlainText) containing the desired tertiaryText string 65 | * @return the BodyTemplate1Builder object that the method was called upon with the new tertiaryText field 66 | */ 67 | public BodyTemplate2Builder setTertiaryText(final TextField tertiaryText) { 68 | this.textContent.setTertiaryText(tertiaryText); 69 | return this; 70 | } 71 | 72 | /** 73 | * Builds a new BodyTemplate2 object with the current attributes of the BodyTemplate2Builder object. 74 | * @return a newly constructed BodyTemplate2 object 75 | */ 76 | @Override 77 | public BodyTemplate2 build() { 78 | BodyTemplate2 template = new BodyTemplate2(); 79 | template.setToken(token); 80 | template.setTitle(title); 81 | template.setImage(fgImage); 82 | template.setBackgroundImage(bgImage); 83 | template.setTextContent(textContent); 84 | template.setBackButtonBehavior(backButtonBehavior); 85 | return template; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /displaytutorial/src/com/amazon/asksdk/displayguide/BodyTemplate3Builder.java: -------------------------------------------------------------------------------- 1 | /* 2 | *Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | *Licensed under the Amazon Software License (the "License"). You may not use 5 | * this file except in compliance with the License. A copy of the License is located at 6 | * 7 | *http://aws.amazon.com/asl/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or 11 | * implied. See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | package com.amazon.asksdk.displayguide; 16 | 17 | import com.amazon.speech.speechlet.interfaces.display.element.Image; 18 | import com.amazon.speech.speechlet.interfaces.display.element.TextField; 19 | import com.amazon.speech.speechlet.interfaces.display.template.BodyTemplate3; 20 | 21 | /** 22 | * The BodyTemplate3Builder class provides an external Builder class for 3rd party skill code to 23 | * construct a BodyTemplate3 template at anytime. 24 | */ 25 | public class BodyTemplate3Builder extends TemplateBuilder { 26 | 27 | private Image fgImage; 28 | private BodyTemplate3.TextContent textContent = new BodyTemplate3.TextContent(); 29 | 30 | /** 31 | * Sets the Image field of BodyTemplate3. The Image field of BodyTemplate3 is a foreground image on 32 | * the left side of the template. 33 | * @param fgImage an Image object containing a list of ImageInstance sources and an optional content description 34 | * @return the BodyTemplate1Builder object that the method was called upon with the new Image field 35 | */ 36 | public BodyTemplate3Builder setFgImage(final Image fgImage) { 37 | this.fgImage = fgImage; 38 | return this; 39 | } 40 | 41 | /** 42 | * Sets the primaryText field of the TextContent field of BodyTemplate1. 43 | * @param primaryText a TextField object (either RichText or PlainText) containing the desired primaryText string 44 | * @return the BodyTemplate1Builder object that the method was called upon with the new primaryText field 45 | */ 46 | public BodyTemplate3Builder setPrimaryText(final TextField primaryText) { 47 | this.textContent.setPrimaryText(primaryText); 48 | return this; 49 | } 50 | 51 | /** 52 | * Sets the secondaryText field of the TextContent field of BodyTemplate1. 53 | * @param secondaryText a TextField object (either RichText or PlainText) containing the desired secondaryText 54 | * string 55 | * @return the BodyTemplate1Builder object that the method was called upon with the new secondaryText field 56 | */ 57 | public BodyTemplate3Builder setSecondaryText(final TextField secondaryText) { 58 | this.textContent.setSecondaryText(secondaryText); 59 | return this; 60 | } 61 | 62 | /** 63 | * Sets the tertiaryText field of the TextContent field of BodyTemplate3. 64 | * @param tertiaryText a TextField object (either RichText or PlainText) containing the desired tertiaryText string 65 | * @return the BodyTemplate1Builder object that the method was called upon with the new tertiaryText field 66 | */ 67 | public BodyTemplate3Builder setTertiaryText(final TextField tertiaryText) { 68 | this.textContent.setTertiaryText(tertiaryText); 69 | return this; 70 | } 71 | 72 | /** 73 | * Builds a new BodyTemplate3 object with the current attributes of the BodyTemplate3Builder object. 74 | * @return a newly constructed BodyTemplate2 object 75 | */ 76 | @Override 77 | public BodyTemplate3 build() { 78 | BodyTemplate3 template = new BodyTemplate3(); 79 | template.setTitle(title); 80 | template.setTextContent(textContent); 81 | template.setToken(token); 82 | template.setBackgroundImage(bgImage); 83 | template.setImage(fgImage); 84 | template.setBackButtonBehavior(backButtonBehavior); 85 | return template; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /displaytutorial/src/com/amazon/asksdk/displayguide/BodyTemplate6Builder.java: -------------------------------------------------------------------------------- 1 | /* 2 | *Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | *Licensed under the Amazon Software License (the "License"). You may not use 5 | * this file except in compliance with the License. A copy of the License is located at 6 | * 7 | *http://aws.amazon.com/asl/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or 11 | * implied. See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | package com.amazon.asksdk.displayguide; 16 | 17 | import com.amazon.speech.speechlet.interfaces.display.element.TextField; 18 | import com.amazon.speech.speechlet.interfaces.display.template.BodyTemplate6; 19 | 20 | /** 21 | * The BodyTemplate6Builder class provides an external Builder class for 3rd party skill code to 22 | * construct a BodyTemplate6 template at anytime. 23 | */ 24 | public class BodyTemplate6Builder extends TemplateBuilder { 25 | 26 | private BodyTemplate6.TextContent textContent = new BodyTemplate6.TextContent(); 27 | 28 | /** 29 | * Sets the primaryText field of the TextContent field of BodyTemplate6. 30 | * @param primaryText a TextField object (either RichText or PlainText) containing the desired primaryText string 31 | * @return the BodyTemplate6Builder object that the method was called upon with the new primaryText field 32 | */ 33 | public BodyTemplate6Builder setPrimaryText(final TextField primaryText) { 34 | this.textContent.setPrimaryText(primaryText); 35 | return this; 36 | } 37 | 38 | /** 39 | * Sets the secondaryText field of the TextContent field of BodyTemplate6. 40 | * @param secondaryText a TextField object (either RichText or PlainText) containing the desired secondaryText 41 | * string 42 | * @return the BodyTemplate6Builder object that the method was called upon with the new secondaryText field 43 | */ 44 | public BodyTemplate6Builder setSecondaryText(final TextField secondaryText) { 45 | this.textContent.setSecondaryText(secondaryText); 46 | return this; 47 | } 48 | 49 | /** 50 | * Sets the tertiaryText field of the TextContent field of BodyTemplate6. 51 | * @param tertiaryText a TextField object (either RichText or PlainText) containing the desired tertiaryText string 52 | * @return the BodyTemplate6Builder object that the method was called upon with the new tertiaryText field 53 | */ 54 | public BodyTemplate6Builder setTertiaryText(final TextField tertiaryText) { 55 | this.textContent.setTertiaryText(tertiaryText); 56 | return this; 57 | } 58 | 59 | /** 60 | * Builds a new BodyTemplate6 object with the current attributes of the BodyTemplate6Builder object. 61 | * @return a newly constructed BodyTemplate6 object 62 | */ 63 | @Override 64 | public BodyTemplate6 build() { 65 | BodyTemplate6 template = new BodyTemplate6(); 66 | template.setTextContent(textContent); 67 | template.setToken(token); 68 | template.setBackgroundImage(bgImage); 69 | template.setBackButtonBehavior(backButtonBehavior); 70 | return template; 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /displaytutorial/src/com/amazon/asksdk/displayguide/DisplayGuideRequestStreamHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | *Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | *Licensed under the Amazon Software License (the "License"). You may not use 5 | * this file except in compliance with the License. A copy of the License is located at 6 | * 7 | *http://aws.amazon.com/asl/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or 11 | * implied. See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | package com.amazon.asksdk.displayguide; 16 | 17 | import com.amazon.speech.speechlet.lambda.SpeechletRequestStreamHandler; 18 | 19 | import java.util.HashSet; 20 | import java.util.Set; 21 | 22 | /** 23 | * The DisplayGuideRequestStreamHandler class is the handler for an AWS Lambda function powering the Display 24 | * Interface Guide experience. 25 | */ 26 | public class DisplayGuideRequestStreamHandler extends SpeechletRequestStreamHandler { 27 | 28 | private static final Set supportedApplicationIds; 29 | static { 30 | /* 31 | * This Id can be found on https://developer.amazon.com/edw/home.html#/ "Edit" the relevant 32 | * Alexa Skill and put the relevant Application Ids in this Set. 33 | */ 34 | 35 | supportedApplicationIds = new HashSet(); 36 | // supportedApplicationIds.add("[unique-value-here]"); 37 | } 38 | 39 | /** 40 | * Constructor for the DisplayGuideRequestStreamHandler - uses base class constructor. 41 | */ 42 | public DisplayGuideRequestStreamHandler() { 43 | super(new DisplayGuide(), supportedApplicationIds); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /displaytutorial/src/com/amazon/asksdk/displayguide/ElementSelectedRequestParser.java: -------------------------------------------------------------------------------- 1 | /* 2 | *Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | *Licensed under the Amazon Software License (the "License"). You may not use 5 | * this file except in compliance with the License. A copy of the License is located at 6 | * 7 | *http://aws.amazon.com/asl/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or 11 | * implied. See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | package com.amazon.asksdk.displayguide; 16 | 17 | import com.amazon.speech.json.SpeechletRequestEnvelope; 18 | import com.amazon.speech.slu.Slot; 19 | import com.amazon.speech.speechlet.interfaces.display.request.ElementSelectedRequest; 20 | 21 | import java.util.HashMap; 22 | import java.util.Map; 23 | 24 | /** 25 | * The ElementSelectedRequestParser class is responsible for parsing information from the SpeechletRequestEnvelope 26 | * that is unique to an ElementSelecteRequest. 27 | */ 28 | public class ElementSelectedRequestParser implements RequestParser { 29 | 30 | /** 31 | * parses the token string in the ElementSelectedRequest into an IntentName and Slots -- this is a token naming 32 | * methodology, unique to the DisplayGuide skill, that allows for touch events and vocal intent requests to be 33 | * interpreted the same way by the derived classes of RequestHandler. 34 | * @param envelope SpeechletRequestEnvelope containing an ElementSelectedRequest 35 | * @return a SkillRequestInformation object containing the request type, the original token, and the intentName and 36 | * Slots parsed from the token 37 | */ 38 | @Override 39 | public SkillRequestInformation parseRequestEnvelope(final SpeechletRequestEnvelope envelope) { 40 | 41 | // Parse the envelope for token 42 | ElementSelectedRequest request = (ElementSelectedRequest) envelope.getRequest(); 43 | String token = request.getToken(); 44 | 45 | //parse token for intentName and Slots 46 | String[] tokenContents = token.split("\\|"); 47 | String intentName = tokenContents[0]; 48 | 49 | Map slots = new HashMap<>(); 50 | for (String tokenSubString : tokenContents) { 51 | if (tokenSubString.equals(tokenContents[0])) { 52 | continue; 53 | } 54 | String[] slot = tokenSubString.split(","); 55 | if (slot.length == 2) { 56 | String slotName = slot[0]; 57 | String slotValue = slot[1]; 58 | 59 | slots.put(slotName, 60 | Slot.builder() 61 | .withValue(slotValue) 62 | .withName(slotName) 63 | .build()); 64 | } 65 | } 66 | 67 | SkillRequestInformation skillRequestInformation = new SkillRequestInformation(); 68 | skillRequestInformation.setRequestType(SkillRequestInformation.RequestType.ELEMENT_SELECTED_REQUEST); 69 | skillRequestInformation.setToken(token); 70 | skillRequestInformation.setIntentName(intentName); 71 | skillRequestInformation.setSlots(slots); 72 | 73 | return skillRequestInformation; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /displaytutorial/src/com/amazon/asksdk/displayguide/GoodbyeScreen.java: -------------------------------------------------------------------------------- 1 | /* 2 | *Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | *Licensed under the Amazon Software License (the "License"). You may not use 5 | * this file except in compliance with the License. A copy of the License is located at 6 | * 7 | *http://aws.amazon.com/asl/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or 11 | * implied. See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | package com.amazon.asksdk.displayguide; 16 | 17 | import com.amazon.speech.speechlet.SpeechletResponse; 18 | 19 | import static com.amazon.asksdk.displayguide.TextUtils.makePlainText; 20 | 21 | /** 22 | * The GoodbyeScreen class handles request events to exit the skill. 23 | */ 24 | public class GoodbyeScreen extends RequestHandler { 25 | @Override 26 | boolean canHandle(final SkillRequestInformation skillRequestInformation) { 27 | 28 | String intentName = skillRequestInformation.getIntentName(); 29 | 30 | return IntentNames.AMAZON_STOP_INTENT.equals(intentName) || (IntentNames.AMAZON_NO_INTENT.equals(intentName) 31 | && Tokens.WELCOME_SCREEN_TOKEN.equals(skillRequestInformation.getToken())); 32 | } 33 | 34 | @Override 35 | SpeechletResponse handle(final SkillRequestInformation skillRequestInformation) { 36 | return new ResponseBuilder() 37 | .setShouldEndSession(true) 38 | .setSpeech("See you next time!") 39 | .setSimpleCard("Goodbye!", "Visit the Alexa Skills Kit website to learn more.") 40 | .addTemplateDirective(new BodyTemplate6Builder() 41 | .setPrimaryText(makePlainText("Goodbye!")) 42 | .build()) 43 | .build(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /displaytutorial/src/com/amazon/asksdk/displayguide/HandlingListItemSelectionScreen.java: -------------------------------------------------------------------------------- 1 | /* 2 | *Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | *Licensed under the Amazon Software License (the "License"). You may not use 5 | * this file except in compliance with the License. A copy of the License is located at 6 | * 7 | *http://aws.amazon.com/asl/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or 11 | * implied. See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | package com.amazon.asksdk.displayguide; 16 | 17 | import com.amazon.speech.speechlet.SpeechletResponse; 18 | 19 | import static com.amazon.asksdk.displayguide.TextUtils.*; 20 | 21 | /** 22 | * The HandlingListItemSelectionScreen handles touch and intent request events for the instructional screen regarding 23 | * handling selection of list items. 24 | */ 25 | public class HandlingListItemSelectionScreen extends RequestHandler { 26 | @Override 27 | boolean canHandle(final SkillRequestInformation skillRequestInformation) { 28 | return isIntentOrItemFromTopicList(skillRequestInformation, IntentNames.ITEM_SELECTION_INTENT, "5"); 29 | } 30 | 31 | @Override 32 | SpeechletResponse handle(final SkillRequestInformation skillRequestInformation) { 33 | String title = "Handling List Item Selection by Voice and Touch"; 34 | 35 | String speech = "There are two ways that a user can select an item from one of your list templates. You will " 36 | + "have to handle both of these in your skill code. Look to your Echo Show screen to read more."; 37 | 38 | String bodyText = wrapTextInBold("1. User selects an item by voice, by saying either its name or its number: ") 39 | + LINE_BREAK 40 | + "You will need to implement a custom intent(s) to handle this." + LINE_BREAK + LINE_BREAK 41 | + wrapTextInBold("2. User clicks an item: ") + LINE_BREAK 42 | + "Your skill will receive a Display.ElementSelected request with whatever token you " 43 | + "assigned to the list item that was clicked. You can then use this token to send your desired " 44 | + "response."; 45 | 46 | return new ResponseBuilder() 47 | .setSpeech(speech) 48 | .addTemplateDirective(new BodyTemplate1Builder() 49 | .setPrimaryText(makeRichText(bodyText)) 50 | .setTitle(title) 51 | .setToken(Tokens.ITEM_SELECTION_SCREEN_TOKEN) 52 | .build()) 53 | .build(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /displaytutorial/src/com/amazon/asksdk/displayguide/HelpScreen.java: -------------------------------------------------------------------------------- 1 | /* 2 | *Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | *Licensed under the Amazon Software License (the "License"). You may not use 5 | * this file except in compliance with the License. A copy of the License is located at 6 | * 7 | *http://aws.amazon.com/asl/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or 11 | * implied. See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | package com.amazon.asksdk.displayguide; 16 | 17 | import com.amazon.speech.speechlet.SpeechletResponse; 18 | 19 | /** 20 | * The HelpScreen class handles request for help at anytime during the skill experience, and presents a list of sample 21 | * utterances to the user, using List Template 1 22 | */ 23 | public class HelpScreen extends RequestHandler { 24 | @Override 25 | boolean canHandle(final SkillRequestInformation skillRequestInformation) { 26 | return IntentNames.AMAZON_HELP_INTENT.equals(skillRequestInformation.getIntentName()); 27 | } 28 | 29 | @Override 30 | SpeechletResponse handle(final SkillRequestInformation skillRequestInformation) { 31 | return getHelpScreenResponse(); 32 | } 33 | 34 | private SpeechletResponse getHelpScreenResponse() { 35 | String title = "Help | Alexa..."; 36 | String description = "The Display Interface Guide can help you learn how to build Alexa Skills for Echo show " 37 | + "and Alexa-enabled devices with displays."; 38 | String speechText = description + " Here are a few things you can ask me."; 39 | String cardText = description + " You should support a user request for help in your skill. " 40 | + "It is common to use List Template 1 to display a list of example phrases users can say " 41 | + "to interact with your skill."; 42 | 43 | ItemListForListTemplate1 itemList = new ItemListForListTemplate1(); 44 | ListContentGenerator.generateHelpPhrasesList(itemList); 45 | 46 | return new ResponseBuilder() 47 | .setSpeech(speechText) 48 | .setSimpleCard(title, cardText) 49 | .setShouldEndSession(null) 50 | .addTemplateDirective( 51 | new ListTemplate1Builder() 52 | .setListItems(itemList.getItems()) 53 | .setToken(Tokens.HELP_SCREEN_TOKEN) 54 | .setTitle(title) 55 | .build()) 56 | .build(); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /displaytutorial/src/com/amazon/asksdk/displayguide/HintTextsScreen.java: -------------------------------------------------------------------------------- 1 | /* 2 | *Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | *Licensed under the Amazon Software License (the "License"). You may not use 5 | * this file except in compliance with the License. A copy of the License is located at 6 | * 7 | *http://aws.amazon.com/asl/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or 11 | * implied. See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | package com.amazon.asksdk.displayguide; 16 | 17 | import com.amazon.speech.speechlet.SpeechletResponse; 18 | 19 | import static com.amazon.asksdk.displayguide.TextUtils.*; 20 | 21 | /** 22 | * The HintTextScreen class handles all requests for information about Hint Texts, and demonstrates to the user how to 23 | * use a hint phrase. 24 | */ 25 | public class HintTextsScreen extends RequestHandler { 26 | @Override 27 | boolean canHandle(final SkillRequestInformation skillRequestInformation) { 28 | return isIntentOrItemFromTopicList(skillRequestInformation, IntentNames.HINTS_INTENT, "6"); 29 | } 30 | 31 | @Override 32 | SpeechletResponse handle(final SkillRequestInformation skillRequestInformation) { 33 | String shortDescription = "Hint phrases are optional, but a useful tool to help your user quickly understand " 34 | + "what to do next. List Template 2 and Body Templates 2 and 6 support hint texts. "; 35 | 36 | String speechText = shortDescription + " Look to your Echo Show screen to read more."; 37 | 38 | String bodyText = wrapTextInMediumFont(shortDescription + LINE_BREAK + LINE_BREAK 39 | + " To add a hint to one of your templates, send a HintDirective along with " 40 | + "the TemplateDirective in your skill's response. Hints are automatically formatted like this: " 41 | + LINE_BREAK 42 | + wrapTextInItalics(wrapTextInBold(escapeXML("Try, , "))) 43 | + LINE_BREAK 44 | + "This allows the device to change the wake word in the hint phrase, if the user is using one other " 45 | + "than the default. " + LINE_BREAK + LINE_BREAK 46 | + "Populate the hint field wherever possible. When you ask a question and listen for the user's " 47 | + "response, the blue voice chrome at the bottom of the screen partially blocks the hint. Because of " 48 | + "this, it's best not to add hints when asking a question; only use hints when the screen is static." 49 | + wrapTextInAction(".", "token")); 50 | 51 | String hintText = "what is a hint?"; 52 | 53 | return new ResponseBuilder() 54 | .setShouldEndSession(null) 55 | .setSpeech(speechText) 56 | .addHintDirective(hintText) 57 | .addTemplateDirective( 58 | new BodyTemplate6Builder() 59 | .setPrimaryText(makeRichText(bodyText)) 60 | .setToken(Tokens.HINTS_SCREEN_TOKEN) 61 | .build() 62 | ) 63 | .build(); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /displaytutorial/src/com/amazon/asksdk/displayguide/ImageResources.java: -------------------------------------------------------------------------------- 1 | /* 2 | *Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | *Licensed under the Amazon Software License (the "License"). You may not use 5 | * this file except in compliance with the License. A copy of the License is located at 6 | * 7 | *http://aws.amazon.com/asl/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or 11 | * implied. See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | package com.amazon.asksdk.displayguide; 16 | 17 | 18 | import com.amazon.speech.speechlet.interfaces.display.element.Image; 19 | import com.amazon.speech.speechlet.interfaces.display.element.ImageInstance; 20 | 21 | import java.util.ArrayList; 22 | import java.util.List; 23 | 24 | /** 25 | * The ImageResources enum constructs Image objects for all the image assets used in the skill 26 | */ 27 | public enum ImageResources { 28 | ALEXA_LOGO ("https://s3.amazonaws.com/mkusters-images/alexa-logo.png", 640, 290), 29 | BODY_TEMPLATE_1("https://s3.amazonaws.com/mkusters-images/Body_Template_1.png", 1024, 600), 30 | BODY_TEMPLATE_2("https://s3.amazonaws.com/mkusters-images/Body_Template_2.png", 1024, 600), 31 | BODY_TEMPLATE_3("https://s3.amazonaws.com/mkusters-images/Body_Template_3.png", 1024, 600), 32 | BODY_TEMPLATE_6("https://s3.amazonaws.com/mkusters-images/Body_Template_6.png", 1024, 600), 33 | LIST_TEMPLATE_1("https://s3.amazonaws.com/mkusters-images/List_Template_1.png", 1024, 600), 34 | LIST_TEMPLATE_2("https://s3.amazonaws.com/mkusters-images/List_Template_2.png", 1024, 600), 35 | BACKGROUND("https://s3.amazonaws.com/mkusters-images/road_background.png", 1024, 600), 36 | PORTRAIT_SAMPLE("https://s3.amazonaws.com/mkusters-images/portrait.png", 192, 280), 37 | SQUARE_SAMPLE("https://s3.amazonaws.com/mkusters-images/square.png", 280, 280), 38 | SUPER_WIDE_RATIO_SAMPLE("https://s3.amazonaws.com/mkusters-images/16_9ratio.png", 372, 280), 39 | WIDE_RATIO_SAMPLE("https://s3.amazonaws.com/mkusters-images/4_3ratio.png", 498, 280), 40 | FOUR_COLORS("https://s3.amazonaws.com/mkusters-images/four-colors.png", 200, 200), 41 | VIDEO_EXAMPLE("https://s3.amazonaws.com/mkusters-images/video_screenshot.jpeg", 650, 381); 42 | 43 | private Image image; 44 | 45 | ImageResources(final String stringURI, final int width, final int height) { 46 | 47 | ImageInstance imageInstance = new ImageInstance(); 48 | imageInstance.setUrl(stringURI); 49 | imageInstance.setHeightPixels(height); 50 | imageInstance.setWidthPixels(width); 51 | 52 | List imageSources = new ArrayList<>(); 53 | imageSources.add(imageInstance); 54 | 55 | this.image = new Image(); 56 | this.image.setSources(imageSources); 57 | } 58 | 59 | Image getImage() { 60 | return this.image; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /displaytutorial/src/com/amazon/asksdk/displayguide/InlineImageScreen.java: -------------------------------------------------------------------------------- 1 | /* 2 | *Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | *Licensed under the Amazon Software License (the "License"). You may not use 5 | * this file except in compliance with the License. A copy of the License is located at 6 | * 7 | *http://aws.amazon.com/asl/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or 11 | * implied. See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | package com.amazon.asksdk.displayguide; 16 | 17 | import com.amazon.speech.speechlet.SpeechletResponse; 18 | 19 | import static com.amazon.asksdk.displayguide.TextUtils.*; 20 | 21 | /** 22 | * The InlineImageScreen class handles all requests for the Inline Image Screen, which describes to the user how to include 23 | * inline images in a Rich Text element, and shows examples of one image being displayed with different pixels heights and 24 | * widths. 25 | */ 26 | public class InlineImageScreen extends RequestHandler { 27 | @Override 28 | public boolean canHandle(final SkillRequestInformation skillRequestInformation) { 29 | return isIntentOrItemFromTopicList(skillRequestInformation, IntentNames.INLINE_IMAGE_TAG_INTENT, "3"); 30 | } 31 | 32 | @Override 33 | public SpeechletResponse handle(final SkillRequestInformation skillRequestInformation) { 34 | 35 | String title = "Including images in rich text elements"; 36 | String shortDescription = "You can include images in a rich text element using the image tag. "; 37 | 38 | String speech = shortDescription + " Check out your Echo Show screen to see examples of inline images."; 39 | 40 | String bodyText = shortDescription + "All templates support rich text elements in their corresponding text fields. " + 41 | "Here is an example of an image included inline in a rich text element: " + 42 | inlineImageTag(ImageResources.FOUR_COLORS.getImage()) + LINE_BREAK + LINE_BREAK + 43 | "The format for including an image is: "+ LINE_BREAK + LINE_BREAK + 44 | wrapTextInBold(escapeXML("")) + 45 | LINE_BREAK + LINE_BREAK + 46 | "If the width and height provided are smaller than the actual dimensions of the image, then the image " + 47 | "will be cropped to that size from the top left corner." + 48 | LINE_BREAK + 49 | "If the dimensions provided are larger than the actual dimensions, then the image will be stretched to " + 50 | "fill the space." + 51 | LINE_BREAK + 52 | "The original image size is 200x200. Here the image is cropped to 150x150: " + 53 | inlineImageTag(ImageResources.FOUR_COLORS.getImage().getSources().get(0).getUrl(), 150, 150) + 54 | "Here is the image cropped to 100x100: " + 55 | inlineImageTag(ImageResources.FOUR_COLORS.getImage().getSources().get(0).getUrl(), 100, 100) + 56 | "Here is the image cropped to 150x200:" + 57 | inlineImageTag(ImageResources.FOUR_COLORS.getImage().getSources().get(0).getUrl(), 150, 200) + 58 | "Here is the image stretched to 300x500:" + 59 | inlineImageTag(ImageResources.FOUR_COLORS.getImage().getSources().get(0).getUrl(), 300, 500); 60 | 61 | return new ResponseBuilder() 62 | .setSpeech(speech) 63 | .addTemplateDirective(new BodyTemplate1Builder() 64 | .setPrimaryText(makeRichText(bodyText)) 65 | .setTitle(title) 66 | .setToken(Tokens.INLINE_IMAGE_SCREEN_TOKEN) 67 | .build()) 68 | .build(); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /displaytutorial/src/com/amazon/asksdk/displayguide/IntentNames.java: -------------------------------------------------------------------------------- 1 | /* 2 | *Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | *Licensed under the Amazon Software License (the "License"). You may not use 5 | * this file except in compliance with the License. A copy of the License is located at 6 | * 7 | *http://aws.amazon.com/asl/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or 11 | * implied. See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | package com.amazon.asksdk.displayguide; 16 | 17 | /** 18 | * The IntentNames class contains string constants for all Intent Names used in the skill's interaction model 19 | */ 20 | public class IntentNames { 21 | public static final String SELECT_ITEM_INTENT = "SelectItemIntent"; 22 | public static final String WELCOME_INTENT = "WelcomeIntent"; 23 | public static final String TOPIC_LIST_INTENT = "TopicListIntent"; 24 | public static final String TEMPLATE_OVERVIEW_INTENT = "TemplateOverviewIntent"; 25 | public static final String AMAZON_HELP_INTENT = "AMAZON.HelpIntent"; 26 | public static final String INDIVIDUAL_TEMPLATE_INTENT = "IndividualTemplateIntent"; 27 | public static final String AMAZON_PREVIOUS_INTENT = "AMAZON.PreviousIntent"; 28 | public static final String VIDEO_INSTRUCTIONAL_INTENT = "VideoInstructionalIntent"; 29 | public static final String WATCH_VIDEO_INTENT = "WatchVideoIntent"; 30 | public static final String INLINE_IMAGE_TAG_INTENT = "InlineImageTagIntent"; 31 | public static final String ACTION_TAG_INTENT = "ActionTagIntent"; 32 | public static final String ITEM_SELECTION_INTENT = "ItemSelectionIntent"; 33 | public static final String AMAZON_YES_INTENT = "AMAZON.YesIntent"; 34 | public static final String AMAZON_NO_INTENT = "AMAZON.NoIntent"; 35 | public static final String AMAZON_STOP_INTENT = "AMAZON.StopIntent"; 36 | public static final String HINTS_INTENT = "HintsIntent"; 37 | } 38 | 39 | -------------------------------------------------------------------------------- /displaytutorial/src/com/amazon/asksdk/displayguide/IntentRequestParser.java: -------------------------------------------------------------------------------- 1 | /* 2 | *Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | *Licensed under the Amazon Software License (the "License"). You may not use 5 | * this file except in compliance with the License. A copy of the License is located at 6 | * 7 | *http://aws.amazon.com/asl/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or 11 | * implied. See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | package com.amazon.asksdk.displayguide; 16 | 17 | import com.amazon.speech.json.SpeechletRequestEnvelope; 18 | import com.amazon.speech.slu.Intent; 19 | import com.amazon.speech.speechlet.IntentRequest; 20 | import com.amazon.speech.speechlet.interfaces.display.DisplayInterface; 21 | import com.amazon.speech.speechlet.interfaces.display.DisplayState; 22 | 23 | /** 24 | * The IntentRequestParser class is responsible for parsing information from the SpeechletRequestEnvelope that is unique 25 | * to an IntentRequest 26 | */ 27 | public class IntentRequestParser implements RequestParser { 28 | 29 | @Override 30 | public SkillRequestInformation parseRequestEnvelope(SpeechletRequestEnvelope envelope) { 31 | IntentRequest request = (IntentRequest) envelope.getRequest(); 32 | Intent intent = request.getIntent(); 33 | 34 | SkillRequestInformation skillRequestInformation = new SkillRequestInformation(); 35 | skillRequestInformation.setRequestType(SkillRequestInformation.RequestType.INTENT_REQUEST); 36 | skillRequestInformation.setIntentName(intent.getName()); 37 | skillRequestInformation.setSlots(intent.getSlots()); 38 | skillRequestInformation.setToken(getDisplayStateToken(envelope)); 39 | 40 | return skillRequestInformation; 41 | } 42 | 43 | private String getDisplayStateToken(SpeechletRequestEnvelope envelope) { 44 | DisplayState state = envelope.getContext().getState(DisplayInterface.class, DisplayState.class); 45 | String stateToken = ""; 46 | if (state != null) { 47 | stateToken = state.getToken(); 48 | } 49 | return stateToken; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /displaytutorial/src/com/amazon/asksdk/displayguide/ItemList.java: -------------------------------------------------------------------------------- 1 | /* 2 | *Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | *Licensed under the Amazon Software License (the "License"). You may not use 5 | * this file except in compliance with the License. A copy of the License is located at 6 | * 7 | *http://aws.amazon.com/asl/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or 11 | * implied. See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | package com.amazon.asksdk.displayguide; 16 | 17 | import com.amazon.speech.speechlet.interfaces.display.element.Image; 18 | import com.amazon.speech.speechlet.interfaces.display.element.TextField; 19 | import com.amazon.speech.speechlet.interfaces.display.element.TripleTextContent; 20 | 21 | /** 22 | * ItemList provides an interface for all operations used when constructing List Items for List Template 1 or 2 23 | */ 24 | public interface ItemList { 25 | 26 | void addItem(Image image, String token, TripleTextContent textContent); 27 | 28 | TripleTextContent makeTextContent(TextField primary); 29 | 30 | TripleTextContent makeTextContent(TextField primary, TextField secondary); 31 | 32 | TripleTextContent makeTextContent(TextField primary, TextField secondary, TextField tertiary); 33 | } 34 | -------------------------------------------------------------------------------- /displaytutorial/src/com/amazon/asksdk/displayguide/ItemListForListTemplate1.java: -------------------------------------------------------------------------------- 1 | /* 2 | *Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | *Licensed under the Amazon Software License (the "License"). You may not use 5 | * this file except in compliance with the License. A copy of the License is located at 6 | * 7 | *http://aws.amazon.com/asl/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or 11 | * implied. See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | package com.amazon.asksdk.displayguide; 16 | 17 | import com.amazon.speech.speechlet.interfaces.display.element.Image; 18 | import com.amazon.speech.speechlet.interfaces.display.element.TextField; 19 | import com.amazon.speech.speechlet.interfaces.display.element.TripleTextContent; 20 | import com.amazon.speech.speechlet.interfaces.display.template.ListTemplate1; 21 | 22 | import java.util.ArrayList; 23 | import java.util.List; 24 | 25 | /** 26 | * ItemListForListTemplate1 is a concrete implementation of the ItemList interface. It performs all operations for 27 | * constructing ListTemplate1 item lists. 28 | */ 29 | public class ItemListForListTemplate1 implements ItemList { 30 | 31 | private List items = new ArrayList<>(); 32 | 33 | /** 34 | * Constructs a ListTemplate1.ListItem object with the three arguments of this function and adds it to the ItemList 35 | * @param image an Image object containing a list of ImageInstance sources and an optional content description 36 | * @param token a String token associated with the list item 37 | * @param textContent a ListTemplate1.ListItem.TextContent object - use the {@link #makeTextContent(TextField)}, 38 | * {@link #makeTextContent(TextField, TextField)}, or {@link #makeTextContent(TextField, TextField, TextField)} 39 | * method to construct this argument 40 | */ 41 | @Override 42 | public void addItem(Image image, String token, TripleTextContent textContent) { 43 | ListTemplate1.ListItem item = new ListTemplate1.ListItem(); 44 | item.setToken(token); 45 | item.setImage(image); 46 | item.setTextContent((ListTemplate1.ListItem.TextContent)textContent); 47 | items.add(item); 48 | } 49 | 50 | @Override 51 | public ListTemplate1.ListItem.TextContent makeTextContent(TextField primary) { 52 | ListTemplate1.ListItem.TextContent textContent = new ListTemplate1.ListItem.TextContent(); 53 | textContent.setPrimaryText(primary); 54 | return textContent; 55 | } 56 | 57 | @Override 58 | public ListTemplate1.ListItem.TextContent makeTextContent(TextField primary, TextField secondary) { 59 | ListTemplate1.ListItem.TextContent textContent = makeTextContent(primary); 60 | textContent.setSecondaryText(secondary); 61 | return textContent; 62 | } 63 | 64 | @Override 65 | public ListTemplate1.ListItem.TextContent makeTextContent(TextField primary, TextField secondary, TextField tertiary) { 66 | ListTemplate1.ListItem.TextContent textContent = makeTextContent(primary, secondary); 67 | textContent.setTertiaryText(tertiary); 68 | return textContent; 69 | } 70 | 71 | List getItems() { 72 | return items; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /displaytutorial/src/com/amazon/asksdk/displayguide/ItemListForListTemplate2.java: -------------------------------------------------------------------------------- 1 | /* 2 | *Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | *Licensed under the Amazon Software License (the "License"). You may not use 5 | * this file except in compliance with the License. A copy of the License is located at 6 | * 7 | *http://aws.amazon.com/asl/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or 11 | * implied. See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | package com.amazon.asksdk.displayguide; 16 | 17 | import com.amazon.speech.speechlet.interfaces.display.element.Image; 18 | import com.amazon.speech.speechlet.interfaces.display.element.TextField; 19 | import com.amazon.speech.speechlet.interfaces.display.element.TripleTextContent; 20 | import com.amazon.speech.speechlet.interfaces.display.template.ListTemplate2; 21 | 22 | import java.util.ArrayList; 23 | import java.util.List; 24 | 25 | /** 26 | * ItemListForListTemplate1 is a concrete implementation of the ItemList interface. It performs all operations for 27 | * constructing ListTemplate1 item lists. 28 | */ 29 | public class ItemListForListTemplate2 implements ItemList { 30 | 31 | private List items = new ArrayList<>(); 32 | 33 | /** 34 | * Constructs a ListTemplate2.ListItem object with the three arguments of this function and adds it to the ItemList 35 | * @param image an Image object containing a list of ImageInstance sources and an optional content description 36 | * @param token a String token associated with the list item 37 | * @param textContent a ListTemplate2.ListItem.TextContent object - use the {@link #makeTextContent(TextField, TextField, TextField)}, 38 | * {@link #makeTextContent(TextField, TextField)}, or {@link #makeTextContent(TextField, TextField, TextField)} 39 | * method to construct this argument 40 | */ 41 | @Override 42 | public void addItem(Image image, String token, TripleTextContent textContent) { 43 | ListTemplate2.ListItem item = new ListTemplate2.ListItem(); 44 | item.setTextContent((ListTemplate2.ListItem.TextContent)textContent); 45 | item.setToken(token); 46 | item.setImage(image); 47 | 48 | items.add(item); 49 | } 50 | 51 | @Override 52 | public ListTemplate2.ListItem.TextContent makeTextContent(TextField primary) { 53 | ListTemplate2.ListItem.TextContent textContent = new ListTemplate2.ListItem.TextContent(); 54 | textContent.setPrimaryText(primary); 55 | return textContent; 56 | } 57 | 58 | @Override 59 | public ListTemplate2.ListItem.TextContent makeTextContent(TextField primary, TextField secondary) { 60 | ListTemplate2.ListItem.TextContent textContent = makeTextContent(primary); 61 | textContent.setSecondaryText(secondary); 62 | return textContent; 63 | } 64 | 65 | @Override 66 | public ListTemplate2.ListItem.TextContent makeTextContent(TextField primary, TextField secondary, TextField tertiary) { 67 | ListTemplate2.ListItem.TextContent textContent = makeTextContent(primary, secondary); 68 | textContent.setTertiaryText(tertiary); 69 | return textContent; 70 | } 71 | 72 | List getItems() { 73 | return items; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /displaytutorial/src/com/amazon/asksdk/displayguide/LaunchRequestParser.java: -------------------------------------------------------------------------------- 1 | /* 2 | *Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | *Licensed under the Amazon Software License (the "License"). You may not use 5 | * this file except in compliance with the License. A copy of the License is located at 6 | * 7 | *http://aws.amazon.com/asl/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or 11 | * implied. See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | package com.amazon.asksdk.displayguide; 16 | 17 | import com.amazon.speech.json.SpeechletRequestEnvelope; 18 | 19 | /** 20 | * The LaunchRequestParser class is responsible for parsing information from the SpeechletRequestEnvelope for a 21 | * Launch Request 22 | */ 23 | public class LaunchRequestParser implements RequestParser { 24 | @Override 25 | public SkillRequestInformation parseRequestEnvelope(SpeechletRequestEnvelope envelope) { 26 | SkillRequestInformation skillRequestInformation = new SkillRequestInformation(); 27 | skillRequestInformation.setToken(Tokens.LAUNCH_REQUEST_TOKEN); 28 | skillRequestInformation.setRequestType(SkillRequestInformation.RequestType.LAUNCH_REQUEST); 29 | 30 | return skillRequestInformation; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /displaytutorial/src/com/amazon/asksdk/displayguide/ListTemplate1Builder.java: -------------------------------------------------------------------------------- 1 | /* 2 | *Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | *Licensed under the Amazon Software License (the "License"). You may not use 5 | * this file except in compliance with the License. A copy of the License is located at 6 | * 7 | *http://aws.amazon.com/asl/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or 11 | * implied. See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | package com.amazon.asksdk.displayguide; 16 | 17 | import com.amazon.speech.speechlet.interfaces.display.template.ListTemplate1; 18 | 19 | import java.util.List; 20 | 21 | /** 22 | * The ListTemplate1Builder class provides an external Builder class for 3rd party skill code to 23 | * construct a ListTemplate1 template at anytime. 24 | */ 25 | public class ListTemplate1Builder extends TemplateBuilder { 26 | 27 | private List items; 28 | 29 | /** 30 | * Sets the List of items for ListTemplate1 31 | * @param items a List of type ListTemplate1.ListItem 32 | * @return the ListTemplate1Builder object that the method was called upon with the new list of items 33 | */ 34 | public ListTemplate1Builder setListItems(List items) { 35 | this.items = items; 36 | return this; 37 | } 38 | 39 | /** 40 | * Builds a new ListTemplate1 object with the current attributes of the ListTemplate1Builder object 41 | * @return a newly constructed ListTemplate1 object 42 | */ 43 | @Override 44 | public ListTemplate1 build() { 45 | ListTemplate1 template = new ListTemplate1(); 46 | template.setToken(token); 47 | template.setTitle(title); 48 | template.setBackgroundImage(bgImage); 49 | template.setListItems(items); 50 | template.setBackButtonBehavior(backButtonBehavior); 51 | return template; 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /displaytutorial/src/com/amazon/asksdk/displayguide/ListTemplate2Builder.java: -------------------------------------------------------------------------------- 1 | /* 2 | *Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | *Licensed under the Amazon Software License (the "License"). You may not use 5 | * this file except in compliance with the License. A copy of the License is located at 6 | * 7 | *http://aws.amazon.com/asl/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or 11 | * implied. See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | package com.amazon.asksdk.displayguide; 16 | 17 | import com.amazon.speech.speechlet.interfaces.display.template.ListTemplate2; 18 | 19 | import java.util.List; 20 | 21 | /** 22 | * The ListTemplate2Builder class provides an external Builder class for 3rd party skill code to 23 | * construct a ListTemplate2 template at anytime. 24 | */ 25 | public class ListTemplate2Builder extends TemplateBuilder { 26 | 27 | private List items; 28 | 29 | /** 30 | * Sets the List of items for ListTemplate2 31 | * @param items a List of type ListTemplate2.ListItem 32 | * @return the ListTemplate2Builder object that the method was called upon with the new list of items 33 | */ 34 | public ListTemplate2Builder setListItems(List items) { 35 | this.items = items; 36 | return this; 37 | } 38 | 39 | /** 40 | * Builds a new ListTemplate2 object with the current attributes of the ListTemplate2Builder object 41 | * @return a newly constructed ListTemplate2 object 42 | */ 43 | @Override 44 | public ListTemplate2 build() { 45 | ListTemplate2 template = new ListTemplate2(); 46 | template.setToken(token); 47 | template.setTitle(title); 48 | template.setBackgroundImage(bgImage); 49 | template.setListItems(items); 50 | template.setBackButtonBehavior(backButtonBehavior); 51 | return template; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /displaytutorial/src/com/amazon/asksdk/displayguide/RequestDispatcher.java: -------------------------------------------------------------------------------- 1 | /* 2 | *Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | *Licensed under the Amazon Software License (the "License"). You may not use 5 | * this file except in compliance with the License. A copy of the License is located at 6 | * 7 | *http://aws.amazon.com/asl/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or 11 | * implied. See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | package com.amazon.asksdk.displayguide; 16 | 17 | import com.amazon.speech.json.SpeechletRequestEnvelope; 18 | import com.amazon.speech.speechlet.SpeechletResponse; 19 | import com.amazon.speech.speechlet.interfaces.display.DisplayInterface; 20 | import com.amazon.speech.speechlet.interfaces.system.SystemInterface; 21 | import com.amazon.speech.speechlet.interfaces.system.SystemState; 22 | import com.fasterxml.jackson.databind.ObjectMapper; 23 | import org.slf4j.Logger; 24 | import org.slf4j.LoggerFactory; 25 | 26 | import java.util.ArrayList; 27 | import java.util.List; 28 | 29 | /** 30 | * The RequestDispatcher class is responsible for finding a handler to handle the request, and dispatching the 31 | * request to that handler. 32 | */ 33 | public class RequestDispatcher { 34 | private static final Logger log = LoggerFactory.getLogger(RequestDispatcher.class); 35 | 36 | private RequestParser requestParser; 37 | 38 | private static List handlers; 39 | static { 40 | handlers = new ArrayList<>(); 41 | handlers.add(new TemplateOverview()); 42 | handlers.add(new HelpScreen()); 43 | handlers.add(new TopicListScreen()); 44 | handlers.add(new IndividualTemplateScreen()); 45 | handlers.add(new VideoInstructionalScreen()); 46 | handlers.add(new WatchVideo()); 47 | handlers.add(new WelcomeScreen()); 48 | handlers.add(new InlineImageScreen()); 49 | handlers.add(new ActionTagScreen()); 50 | handlers.add(new HandlingListItemSelectionScreen()); 51 | handlers.add(new GoodbyeScreen()); 52 | handlers.add(new HintTextsScreen()); 53 | handlers.add(new UnhandledIntentRequestHandler()); 54 | } 55 | 56 | private RequestDispatcher() {} 57 | 58 | public RequestDispatcher(RequestParser requestParser) { 59 | this.requestParser = requestParser; 60 | } 61 | 62 | public SpeechletResponse dispatchRequest(SpeechletRequestEnvelope envelope) { 63 | 64 | SystemState system = envelope.getContext().getState(SystemInterface.class, SystemState.class); 65 | boolean hasDisplay = system.getDevice().getSupportedInterfaces().isInterfaceSupported(DisplayInterface.class); 66 | 67 | if (!hasDisplay) { 68 | String msg = "The Display Interface Guide requires an Echo device with a display, such as Echo Show. You " + 69 | "cannot use this skill on a headless Echo device."; 70 | return new ResponseBuilder() 71 | .setSpeech(msg) 72 | .setSimpleCard("Echo device with display required", msg) 73 | .setShouldEndSession(true) 74 | .build(); 75 | } 76 | 77 | SkillRequestInformation skillRequestInformation = requestParser.parseRequestEnvelope(envelope); 78 | 79 | for ( RequestHandler handler : handlers) { 80 | try { 81 | if (handler.canHandle(skillRequestInformation)) { 82 | SpeechletResponse response = handler.handle(skillRequestInformation); 83 | 84 | log.debug(new ObjectMapper() 85 | .writerWithDefaultPrettyPrinter() 86 | .writeValueAsString(response)); 87 | 88 | return response; 89 | } 90 | } catch (Exception e) { 91 | e.printStackTrace(); 92 | } 93 | } 94 | 95 | throw new UnhandledRequestException(String.format("intentName: %s token: %s slots: %s", 96 | skillRequestInformation.getIntentName(), 97 | skillRequestInformation.getToken(), 98 | skillRequestInformation.getSlots())); 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /displaytutorial/src/com/amazon/asksdk/displayguide/RequestHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | *Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | *Licensed under the Amazon Software License (the "License"). You may not use 5 | * this file except in compliance with the License. A copy of the License is located at 6 | * 7 | *http://aws.amazon.com/asl/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or 11 | * implied. See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | package com.amazon.asksdk.displayguide; 16 | 17 | import com.amazon.speech.slu.Slot; 18 | import com.amazon.speech.speechlet.SpeechletResponse; 19 | 20 | import java.util.Map; 21 | 22 | public abstract class RequestHandler { 23 | 24 | abstract boolean canHandle(final SkillRequestInformation skillRequestInformation); 25 | abstract SpeechletResponse handle(final SkillRequestInformation skillRequestInformation); 26 | 27 | protected boolean slotsContainNumberSlotWithValue(Map slots, String value) { 28 | Slot slot = slots.get(SlotNames.NUMBER_SLOT_NAME); 29 | return (slot != null) && slot.getValue().equals(value); 30 | } 31 | 32 | protected boolean isIntentOrItemFromTopicList(final SkillRequestInformation skillRequestInformation, String intentName, String topicListIndex) { 33 | return intentName.equals(skillRequestInformation.getIntentName()) || IntentNames.SELECT_ITEM_INTENT.equals(skillRequestInformation.getIntentName()) 34 | && Tokens.TOPICS_LIST_SCREEN_TOKEN.equals(skillRequestInformation.getToken()) 35 | && slotsContainNumberSlotWithValue(skillRequestInformation.getSlots(), topicListIndex); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /displaytutorial/src/com/amazon/asksdk/displayguide/RequestParser.java: -------------------------------------------------------------------------------- 1 | /* 2 | *Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | *Licensed under the Amazon Software License (the "License"). You may not use 5 | * this file except in compliance with the License. A copy of the License is located at 6 | * 7 | *http://aws.amazon.com/asl/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or 11 | * implied. See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | package com.amazon.asksdk.displayguide; 16 | 17 | import com.amazon.speech.json.SpeechletRequestEnvelope; 18 | 19 | /** 20 | * RequestParser defines an interface for parsers of all types of SpeechletRequests 21 | */ 22 | interface RequestParser { 23 | SkillRequestInformation parseRequestEnvelope(final SpeechletRequestEnvelope envelope); 24 | } 25 | -------------------------------------------------------------------------------- /displaytutorial/src/com/amazon/asksdk/displayguide/SkillRequestInformation.java: -------------------------------------------------------------------------------- 1 | /* 2 | *Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | *Licensed under the Amazon Software License (the "License"). You may not use 5 | * this file except in compliance with the License. A copy of the License is located at 6 | * 7 | *http://aws.amazon.com/asl/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or 11 | * implied. See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | package com.amazon.asksdk.displayguide; 16 | 17 | import com.amazon.speech.slu.Slot; 18 | 19 | import java.util.HashMap; 20 | import java.util.Map; 21 | 22 | /** 23 | * SkillRequestInformation is a class for storing data parsed from a SpeechletRequestEnvelope by a RequestParser 24 | * implementation 25 | */ 26 | public class SkillRequestInformation { 27 | 28 | private String intentName; 29 | private Map slots = new HashMap<>(); 30 | private String token; 31 | private RequestType requestType; 32 | 33 | public String getIntentName() { 34 | return intentName; 35 | } 36 | 37 | public void setIntentName(String intentName) { 38 | this.intentName = intentName; 39 | } 40 | 41 | public Map getSlots() { 42 | return slots; 43 | } 44 | 45 | public void setSlots(Map slots) { 46 | this.slots = slots; 47 | } 48 | 49 | public String getToken() { 50 | return token; 51 | } 52 | 53 | public void setToken(String token) { 54 | this.token = token; 55 | } 56 | 57 | public RequestType getRequestType() { 58 | return requestType; 59 | } 60 | 61 | public void setRequestType(RequestType requestType) { 62 | this.requestType = requestType; 63 | } 64 | 65 | enum RequestType { 66 | INTENT_REQUEST, ELEMENT_SELECTED_REQUEST, LAUNCH_REQUEST 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /displaytutorial/src/com/amazon/asksdk/displayguide/SlotNames.java: -------------------------------------------------------------------------------- 1 | /* 2 | *Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | *Licensed under the Amazon Software License (the "License"). You may not use 5 | * this file except in compliance with the License. A copy of the License is located at 6 | * 7 | *http://aws.amazon.com/asl/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or 11 | * implied. See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | package com.amazon.asksdk.displayguide; 16 | 17 | /** 18 | * The SlotNames class contains string constants for all Slot Names uses in the interaction model 19 | */ 20 | public class SlotNames { 21 | public static final String NUMBER_SLOT_NAME = "number"; 22 | public static final String TEMPLATE_KIND_SLOT_NAME = "template_kind"; 23 | } 24 | 25 | 26 | -------------------------------------------------------------------------------- /displaytutorial/src/com/amazon/asksdk/displayguide/TemplateBuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | *Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | *Licensed under the Amazon Software License (the "License"). You may not use 5 | * this file except in compliance with the License. A copy of the License is located at 6 | * 7 | *http://aws.amazon.com/asl/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or 11 | * implied. See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | package com.amazon.asksdk.displayguide; 16 | 17 | import com.amazon.speech.speechlet.interfaces.display.element.Image; 18 | import com.amazon.speech.speechlet.interfaces.display.template.Template; 19 | 20 | /** 21 | * An abstract base class for all TemplateBuilders containing setters for all attributes common among all templates 22 | * @param a derived class of TemplateBuilder - such as BodyTemplate1Builder 23 | */ 24 | public abstract class TemplateBuilder> { 25 | protected String title; 26 | protected String token; 27 | protected Image bgImage = ImageResources.BACKGROUND.getImage(); 28 | protected Template.BackButtonBehavior backButtonBehavior = Template.BackButtonBehavior.HIDDEN; 29 | 30 | /** 31 | * Sets the title field of the TemplateBuilder 32 | * @param title a String containing the desired title 33 | * @return the TemplateBuilder object that the method was called upon with the new title field 34 | */ 35 | public T setTitle(String title) { 36 | this.title = title; 37 | return (T)this; 38 | } 39 | 40 | /** 41 | * Sets the token field of the TemplateBuilder 42 | * @param token a String containing the desired token 43 | * @return the TemplateBuilder object that the method was called upon with the new token field 44 | */ 45 | public T setToken(String token) { 46 | this.token = token; 47 | return (T)this; 48 | } 49 | 50 | /** 51 | * Sets the bgImage field of the TemplateBuilder 52 | * @param image an Image object containing a list of ImageInstance sources and an optional content description 53 | * @return the TemplateBuilder that the method was called upon with the new image field 54 | */ 55 | public T setBgImage(Image image) { 56 | this.bgImage = image; 57 | return (T)this; 58 | } 59 | 60 | /** 61 | * Sets the backButtonBehavior field of the TemplateBuilder 62 | * @param backButtonBehavior a Template.BackButtonBehavior enum value - etiher HIDDEN or VISIBLE, the default is HIDDEN 63 | * @return the TemplateBuilder that the method was called upon with the new backButtonBehavior field 64 | */ 65 | public T setBackButtonBehavior(Template.BackButtonBehavior backButtonBehavior) { 66 | this.backButtonBehavior = backButtonBehavior; 67 | return (T)this; 68 | } 69 | 70 | /** 71 | * Builds a new Template object based on the type of derived concrete class 72 | * @return a newly constructed Template object 73 | */ 74 | public abstract Template build(); 75 | } 76 | -------------------------------------------------------------------------------- /displaytutorial/src/com/amazon/asksdk/displayguide/TemplateOverview.java: -------------------------------------------------------------------------------- 1 | /* 2 | *Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | *Licensed under the Amazon Software License (the "License"). You may not use 5 | * this file except in compliance with the License. A copy of the License is located at 6 | * 7 | *http://aws.amazon.com/asl/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or 11 | * implied. See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | package com.amazon.asksdk.displayguide; 16 | 17 | import com.amazon.speech.speechlet.SpeechletResponse; 18 | import org.slf4j.Logger; 19 | import org.slf4j.LoggerFactory; 20 | 21 | /** 22 | * The TemplateOverview class handles touch and intent request events for the Template Overview page which presents the 23 | * user with a list of all available templates, and their names, pictures, and descriptions. 24 | */ 25 | public class TemplateOverview extends RequestHandler { 26 | private static final Logger log = LoggerFactory.getLogger(TemplateOverview.class); 27 | @Override 28 | public boolean canHandle(final SkillRequestInformation skillRequestInformation) { 29 | String intentName = skillRequestInformation.getIntentName(); 30 | String token = skillRequestInformation.getToken(); 31 | 32 | log.debug("intentName: {} token: {}", intentName, token); 33 | 34 | return isIntentOrItemFromTopicList(skillRequestInformation, IntentNames.TEMPLATE_OVERVIEW_INTENT, "1") 35 | || (IntentNames.AMAZON_PREVIOUS_INTENT.equals(intentName) 36 | && tokenMatchesAnIndividualTemplateScreen(token)); 37 | } 38 | 39 | private boolean tokenMatchesAnIndividualTemplateScreen(String token) { 40 | return Tokens.BODY_TEMPLATE_1_SCREEN_TOKEN.equals(token) 41 | || Tokens.BODY_TEMPLATE_2_SCREEN_TOKEN.equals(token) 42 | || Tokens.BODY_TEMPLATE_3_SCREEN_TOKEN.equals(token) 43 | || Tokens.BODY_TEMPLATE_6_SCREEN_TOKEN.equals(token) 44 | || Tokens.LIST_TEMPLATE_1_SCREEN_TOKEN.equals(token) 45 | || Tokens.LIST_TEMPLATE_2_SCREEN_TOKEN.equals(token); 46 | } 47 | 48 | @Override 49 | public SpeechletResponse handle(final SkillRequestInformation skillRequestInformation){ 50 | return getTemplateOverviewScreenResponse(); 51 | } 52 | 53 | private SpeechletResponse getTemplateOverviewScreenResponse() { 54 | String title = "Render Template Directive"; 55 | String description = "There are 2 List templates and 4 Body templates. " + 56 | "All templates have a customizable background image and display your skill's icon in the " + 57 | "top right corner. " + 58 | "You can display a template by sending a Render Template Directive in your skill's response."; 59 | String speechText = description + " Select one to see an example."; 60 | String cardText = description + " Here is a link to more information on the Render Template directive: " + 61 | "https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/display-interface-reference"; 62 | String hintText = "select number 1"; 63 | 64 | ItemListForListTemplate2 itemList = new ItemListForListTemplate2(); 65 | ListContentGenerator.generateTemplateOverviewList(itemList); 66 | 67 | return new ResponseBuilder() 68 | .setShouldEndSession(null) 69 | .setSpeech(speechText) 70 | .setSimpleCard(title, cardText) 71 | .addHintDirective(hintText) 72 | .addTemplateDirective( 73 | new ListTemplate2Builder() 74 | .setListItems(itemList.getItems()) 75 | .setTitle(title) 76 | .setToken(Tokens.TEMPLATE_OVERVIEW_SCREEN_TOKEN) 77 | .build() 78 | ) 79 | .build(); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /displaytutorial/src/com/amazon/asksdk/displayguide/TextUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | *Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | *Licensed under the Amazon Software License (the "License"). You may not use 5 | * this file except in compliance with the License. A copy of the License is located at 6 | * 7 | *http://aws.amazon.com/asl/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or 11 | * implied. See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | package com.amazon.asksdk.displayguide; 16 | 17 | import com.amazon.speech.speechlet.interfaces.display.element.Image; 18 | import com.amazon.speech.speechlet.interfaces.display.element.ImageInstance; 19 | import com.amazon.speech.speechlet.interfaces.display.element.PlainText; 20 | import com.amazon.speech.speechlet.interfaces.display.element.RichText; 21 | import org.apache.commons.lang3.StringEscapeUtils; 22 | 23 | import java.util.List; 24 | 25 | public class TextUtils { 26 | 27 | static String LINE_BREAK = "
"; 28 | static String SPACE = " "; 29 | 30 | static PlainText makePlainText(String text) { 31 | PlainText plainText = new PlainText(); 32 | plainText.setText(text); 33 | return plainText; 34 | } 35 | 36 | static RichText makeRichText(String text) { 37 | RichText richText = new RichText(); 38 | richText.setText(text); 39 | return richText; 40 | } 41 | 42 | static String escapeXML(String text) { 43 | return StringEscapeUtils.escapeXml(text); 44 | } 45 | static String wrapTextInExtraSmallFont(String text) { 46 | return String.format("%s", text); 47 | } 48 | static String wrapTextInSmallFont(String text) { 49 | return String.format("%s", text); 50 | } 51 | static String wrapTextInMediumFont(String text) { 52 | return String.format("%s", text); 53 | } 54 | static String wrapTextInLargeFont(String text) { 55 | return String.format("%s", text); 56 | } 57 | static String wrapTextInBold(String text) { 58 | return String.format("%s", text); 59 | } 60 | static String wrapTextInItalics(String text) { 61 | return String.format("%s", text); 62 | } 63 | static String wrapTextInUnderline(String text) { 64 | return String.format("%s", text); 65 | } 66 | static String wrapTextInAction(String text, String token) { 67 | return String.format("%s", token, text); 68 | } 69 | 70 | static String inlineImageTag(Image image) { 71 | List sources = image.getSources(); 72 | ImageInstance imageInstance; 73 | if(sources.size() > 0) { 74 | imageInstance = sources.get(0); 75 | } else { 76 | return ""; 77 | } 78 | 79 | return inlineImageTag(imageInstance.getUrl(), imageInstance.getWidthPixels(), imageInstance.getHeightPixels()); 80 | } 81 | static String inlineImageTag(String url, int width, int height) { 82 | return String.format("", url, width, height); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /displaytutorial/src/com/amazon/asksdk/displayguide/Tokens.java: -------------------------------------------------------------------------------- 1 | /* 2 | *Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | *Licensed under the Amazon Software License (the "License"). You may not use 5 | * this file except in compliance with the License. A copy of the License is located at 6 | * 7 | *http://aws.amazon.com/asl/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or 11 | * implied. See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | package com.amazon.asksdk.displayguide; 16 | 17 | /** 18 | * The Tokens class contains String constants for all tokens assigned to elements in the skill 19 | */ 20 | public class Tokens { 21 | public static final String LAUNCH_REQUEST_TOKEN = "LaunchRequestToken"; 22 | 23 | public static final String TEMPLATE_OVERVIEW_LIST_ELEMENT_TOKEN = IntentNames.TEMPLATE_OVERVIEW_INTENT; 24 | public static final String VIDEO_TOPIC_LIST_ELEMENT_TOKEN = IntentNames.VIDEO_INSTRUCTIONAL_INTENT; 25 | public static final String INLINE_IMAGE_TAG_LIST_ELEMENT_TOKEN = IntentNames.INLINE_IMAGE_TAG_INTENT; 26 | public static final String ACTION_TAG_LIST_ELEMENT_TOKEN = IntentNames.ACTION_TAG_INTENT; 27 | public static final String ITEM_SELECTION_LIST_ELEMENT_TOKEN = IntentNames.ITEM_SELECTION_INTENT; 28 | public static final String HINTS_LIST_ELEMENT_TOKEN = IntentNames.HINTS_INTENT; 29 | 30 | public static final String ACTION_RICH_TEXT_ELEMENT_ACTION_TOKEN = IntentNames.ACTION_TAG_INTENT; 31 | public static final String IMAGE_RICH_TEXT_ELEMENT_ACTION_TOKEN = IntentNames.INLINE_IMAGE_TAG_INTENT; 32 | public static final String WATCH_VIDEO_ACTION_TOKEN = IntentNames.WATCH_VIDEO_INTENT; 33 | 34 | private static final String TEMPLATE_TOKEN_FORMAT_STRING = String.format("%s|%s,%s|%s,%s", IntentNames.INDIVIDUAL_TEMPLATE_INTENT, SlotNames.TEMPLATE_KIND_SLOT_NAME, "%s", SlotNames.NUMBER_SLOT_NAME, "%s"); 35 | private static final String BODY_TEMPLATE_TOKEN_FORMAT_STRING = String.format(TEMPLATE_TOKEN_FORMAT_STRING, "body", "%s"); 36 | private static final String LIST_TEMPLATE_TOKEN_FORMAT_STRING = String.format(TEMPLATE_TOKEN_FORMAT_STRING, "list", "%s"); 37 | 38 | public static final String BODY_TEMPLATE_1_LIST_ELEMENT_TOKEN = String.format(BODY_TEMPLATE_TOKEN_FORMAT_STRING, 1); 39 | public static final String BODY_TEMPLATE_2_LIST_ELEMENT_TOKEN = String.format(BODY_TEMPLATE_TOKEN_FORMAT_STRING, 2); 40 | public static final String BODY_TEMPLATE_3_LIST_ELEMENT_TOKEN = String.format(BODY_TEMPLATE_TOKEN_FORMAT_STRING, 3); 41 | public static final String BODY_TEMPLATE_6_LIST_ELEMENT_TOKEN = String.format(BODY_TEMPLATE_TOKEN_FORMAT_STRING, 6); 42 | public static final String LIST_TEMPLATE_1_LIST_ELEMENT_TOKEN = String.format(LIST_TEMPLATE_TOKEN_FORMAT_STRING, 1); 43 | public static final String LIST_TEMPLATE_2_LIST_ELEMENT_TOKEN = String.format(LIST_TEMPLATE_TOKEN_FORMAT_STRING, 2); 44 | 45 | public static final String WELCOME_SCREEN_TOKEN = "WelcomeScreenToken"; 46 | public static final String HELP_SCREEN_TOKEN = "HelpScreenToken"; 47 | public static final String TOPICS_LIST_SCREEN_TOKEN = "TopicsListScreenToken"; 48 | public static final String TEMPLATE_OVERVIEW_SCREEN_TOKEN = "TemplateOverviewScreenToken"; 49 | public static final String BODY_TEMPLATE_1_SCREEN_TOKEN = "BodyTemplate1ScreenToken"; 50 | public static final String BODY_TEMPLATE_2_SCREEN_TOKEN = "BodyTemplate2ScreenToken"; 51 | public static final String BODY_TEMPLATE_3_SCREEN_TOKEN = "BodyTemplate3ScreenToken"; 52 | public static final String BODY_TEMPLATE_6_SCREEN_TOKEN = "BodyTemplate6ScreenToken"; 53 | public static final String LIST_TEMPLATE_1_SCREEN_TOKEN = "ListTemplate1ScreenToken"; 54 | public static final String LIST_TEMPLATE_2_SCREEN_TOKEN = "ListTemplate2ScreenToken"; 55 | public static final String INLINE_IMAGE_SCREEN_TOKEN = "InlineImageScreenToken"; 56 | public static final String ACTION_TAG_SCREEN_TOKEN = "ActionTagScreenToken"; 57 | public static final String ITEM_SELECTION_SCREEN_TOKEN = "ItemSelectionScreenToken"; 58 | public static final String HINTS_SCREEN_TOKEN = "HintsScreenToken"; 59 | } 60 | -------------------------------------------------------------------------------- /displaytutorial/src/com/amazon/asksdk/displayguide/TopicListScreen.java: -------------------------------------------------------------------------------- 1 | /* 2 | *Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | *Licensed under the Amazon Software License (the "License"). You may not use 5 | * this file except in compliance with the License. A copy of the License is located at 6 | * 7 | *http://aws.amazon.com/asl/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or 11 | * implied. See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | package com.amazon.asksdk.displayguide; 16 | 17 | import com.amazon.speech.speechlet.SpeechletResponse; 18 | 19 | /** 20 | * The TopicListScreen class handles all requests for the Topic List Screen, including both 21 | * touch and intent requests for this screen. It displays a list of possible topics that the user 22 | * can interact with. 23 | */ 24 | public class TopicListScreen extends RequestHandler { 25 | @Override 26 | public boolean canHandle(final SkillRequestInformation skillRequestInformation) { 27 | 28 | String intentName = skillRequestInformation.getIntentName(); 29 | String token = skillRequestInformation.getToken(); 30 | 31 | return IntentNames.TOPIC_LIST_INTENT.equals(intentName) 32 | || (IntentNames.AMAZON_PREVIOUS_INTENT.equals(intentName) && tokenMatchesASubTopicScreenFromThisList(token)) 33 | || (IntentNames.AMAZON_YES_INTENT.equals(intentName) && Tokens.WELCOME_SCREEN_TOKEN.equals(token)); 34 | } 35 | 36 | private boolean tokenMatchesASubTopicScreenFromThisList(String token) { 37 | return Tokens.TEMPLATE_OVERVIEW_SCREEN_TOKEN.equals(token) 38 | || Tokens.ACTION_TAG_SCREEN_TOKEN.equals(token) 39 | || Tokens.ITEM_SELECTION_SCREEN_TOKEN.equals(token) 40 | || Tokens.INLINE_IMAGE_SCREEN_TOKEN.equals(token) 41 | || Tokens.HINTS_SCREEN_TOKEN.equals(token); 42 | } 43 | 44 | @Override 45 | public SpeechletResponse handle(final SkillRequestInformation skillRequestInformation) { 46 | return getTopicListScreenResponse(); 47 | } 48 | 49 | private SpeechletResponse getTopicListScreenResponse() { 50 | String speechText = "Here is a list of topics you can learn about. Select one to learn more."; 51 | 52 | ItemListForListTemplate1 itemList = new ItemListForListTemplate1(); 53 | ListContentGenerator.generateTopicsList(itemList); 54 | 55 | return new ResponseBuilder() 56 | .setShouldEndSession(null) 57 | .setSpeech(speechText) 58 | .setSimpleCard(null, speechText) 59 | .addTemplateDirective( 60 | new ListTemplate1Builder() 61 | .setListItems(itemList.getItems()) 62 | .setToken(Tokens.TOPICS_LIST_SCREEN_TOKEN) 63 | .build()) 64 | .build(); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /displaytutorial/src/com/amazon/asksdk/displayguide/UnhandledIntentRequestHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | *Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | *Licensed under the Amazon Software License (the "License"). You may not use 5 | * this file except in compliance with the License. A copy of the License is located at 6 | * 7 | *http://aws.amazon.com/asl/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or 11 | * implied. See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | package com.amazon.asksdk.displayguide; 16 | 17 | import com.amazon.speech.speechlet.SpeechletResponse; 18 | 19 | /** 20 | * The UnhandledRequestHandler class handles all unhandled intent request, by prompting the user to say something else 21 | */ 22 | public class UnhandledIntentRequestHandler extends RequestHandler { 23 | @Override 24 | boolean canHandle(final SkillRequestInformation skillRequestInformation) { 25 | return SkillRequestInformation.RequestType.INTENT_REQUEST == skillRequestInformation.getRequestType(); 26 | } 27 | 28 | @Override 29 | SpeechletResponse handle(final SkillRequestInformation skillRequestInformation) { 30 | return new ResponseBuilder() 31 | .setSimpleCard("Unhandled", "Sorry, I couldn't understand you.") 32 | .setSpeech("Sorry, I couldn't understand you. what did you want to learn about?") 33 | .setReprompt("Try asking for a topic, or say help for more options. What do you want to learn?") 34 | .setShouldEndSession(false) 35 | .build(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /displaytutorial/src/com/amazon/asksdk/displayguide/UnhandledRequestException.java: -------------------------------------------------------------------------------- 1 | /* 2 | *Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | *Licensed under the Amazon Software License (the "License"). You may not use 5 | * this file except in compliance with the License. A copy of the License is located at 6 | * 7 | *http://aws.amazon.com/asl/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or 11 | * implied. See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | package com.amazon.asksdk.displayguide; 16 | 17 | public class UnhandledRequestException extends RuntimeException { 18 | public UnhandledRequestException(String msg) { 19 | super("Unhandled Request: " + msg ); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /displaytutorial/src/com/amazon/asksdk/displayguide/VideoInstructionalScreen.java: -------------------------------------------------------------------------------- 1 | /* 2 | *Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | *Licensed under the Amazon Software License (the "License"). You may not use 5 | * this file except in compliance with the License. A copy of the License is located at 6 | * 7 | *http://aws.amazon.com/asl/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or 11 | * implied. See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | package com.amazon.asksdk.displayguide; 16 | 17 | import com.amazon.speech.speechlet.SpeechletResponse; 18 | 19 | import static com.amazon.asksdk.displayguide.TextUtils.*; 20 | 21 | /** 22 | * The VideoInstructionalScreen class handles touch and intent request for the Video Instructional Screen which 23 | * describes how to include videos in a skill. 24 | */ 25 | public class VideoInstructionalScreen extends RequestHandler { 26 | @Override 27 | public boolean canHandle(final SkillRequestInformation skillRequestInformation) { 28 | return isIntentOrItemFromTopicList(skillRequestInformation, IntentNames.VIDEO_INSTRUCTIONAL_INTENT, "2"); 29 | } 30 | 31 | @Override 32 | public SpeechletResponse handle(final SkillRequestInformation skillRequestInformation) { 33 | String title = "How to include Videos"; 34 | String shortDescription = "Including videos in your skill is easy thanks to the Video App Interface. " + 35 | "After sending a Launch Directive in your skill's response, the Video App takes over and handles " + 36 | "all video playback controls such as pause, play, and fast forward. "; 37 | String speech = shortDescription + " Look to your Echo Show screen to read more."; 38 | 39 | String description = wrapTextInAction("Watch Video", Tokens.WATCH_VIDEO_ACTION_TOKEN) + LINE_BREAK + 40 | wrapTextInItalics("Try clicking the blue action above to see the Video App in action.") + LINE_BREAK + 41 | LINE_BREAK + shortDescription + 42 | "When the user exits your video, your skill session resumes at the point where the video app was " + 43 | "launched. To send a VideoApp.Launch directive, include the URL of your video and an optional " + 44 | "title and subtitle. Your video must be hosted at a publicly-accessible HTTPS endpoint. See the " + 45 | "Video App Interface documentation on the Alexa Skills Kit website for more details."; 46 | 47 | return new ResponseBuilder() 48 | .setShouldEndSession(null) 49 | .setSpeech(speech) 50 | .addTemplateDirective(new BodyTemplate2Builder() 51 | .setTitle(title) 52 | .setPrimaryText(makeRichText(description)) 53 | .setFgImage(ImageResources.VIDEO_EXAMPLE.getImage()) 54 | .build()) 55 | .setSimpleCard("Launch Directive", "Video example") 56 | .build(); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /displaytutorial/src/com/amazon/asksdk/displayguide/WatchVideo.java: -------------------------------------------------------------------------------- 1 | /* 2 | *Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | *Licensed under the Amazon Software License (the "License"). You may not use 5 | * this file except in compliance with the License. A copy of the License is located at 6 | * 7 | *http://aws.amazon.com/asl/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or 11 | * implied. See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | package com.amazon.asksdk.displayguide; 16 | 17 | import com.amazon.speech.speechlet.SpeechletResponse; 18 | 19 | /** 20 | * The WatchVideo class handles touch and intent requests to watch an example video inside the skill 21 | */ 22 | public class WatchVideo extends RequestHandler { 23 | @Override 24 | public boolean canHandle(final SkillRequestInformation skillRequestInformation) { 25 | return IntentNames.WATCH_VIDEO_INTENT.equals(skillRequestInformation.getIntentName()); 26 | } 27 | 28 | @Override 29 | public SpeechletResponse handle(final SkillRequestInformation skillRequestInformation) { 30 | String videoURL = "https://s3.amazonaws.com/mkusters-images/guitar_video.mp4"; 31 | String videoTitle = "Sample Video Title"; 32 | String videosubTitle = "Sample Video SubTitle"; 33 | 34 | return new ResponseBuilder() 35 | .addVideoDirective(videoURL, videoTitle, videosubTitle) 36 | .build(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /displaytutorial/src/com/amazon/asksdk/displayguide/WelcomeScreen.java: -------------------------------------------------------------------------------- 1 | /* 2 | *Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | *Licensed under the Amazon Software License (the "License"). You may not use 5 | * this file except in compliance with the License. A copy of the License is located at 6 | * 7 | *http://aws.amazon.com/asl/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or 11 | * implied. See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | package com.amazon.asksdk.displayguide; 16 | 17 | import com.amazon.speech.speechlet.SpeechletResponse; 18 | 19 | import static com.amazon.asksdk.displayguide.TextUtils.*; 20 | 21 | /** 22 | * The WelcomeScreen class handles launch requests, and other intent requests to go back to the welcome screen 23 | */ 24 | public class WelcomeScreen extends RequestHandler { 25 | @Override 26 | public boolean canHandle(final SkillRequestInformation skillRequestInformation) { 27 | 28 | String intentName = skillRequestInformation.getIntentName(); 29 | String token = skillRequestInformation.getToken(); 30 | 31 | return Tokens.LAUNCH_REQUEST_TOKEN.equals(token) 32 | || IntentNames.WELCOME_INTENT.equals(intentName) 33 | || (IntentNames.AMAZON_PREVIOUS_INTENT.equals(intentName) && Tokens.TOPICS_LIST_SCREEN_TOKEN.equals(token)) 34 | || IntentNames.AMAZON_PREVIOUS_INTENT.equals(intentName); 35 | } 36 | 37 | @Override 38 | public SpeechletResponse handle(final SkillRequestInformation skillRequestInformation) { 39 | return getWelcomeScreenResponse(); 40 | } 41 | 42 | SpeechletResponse getWelcomeScreenResponse() { 43 | String bodyText = "Welcome to the Display Interface Guide"; 44 | String speechText = bodyText + ". Are you ready to begin?"; 45 | String hintText = "what topics can I learn about?"; 46 | 47 | String reprompt = "Say 'yes' to begin or say 'help' for more options. Are you ready to begin?"; 48 | 49 | return new ResponseBuilder() 50 | .setShouldEndSession(false) 51 | .setSpeech(speechText) 52 | .setSimpleCard(null, speechText) 53 | .setReprompt(reprompt) 54 | .addHintDirective(hintText) 55 | .addTemplateDirective( 56 | new BodyTemplate2Builder() 57 | .setFgImage(ImageResources.ALEXA_LOGO.getImage()) 58 | .setPrimaryText(makeRichText(wrapTextInLargeFont(bodyText))) 59 | .setToken(Tokens.WELCOME_SCREEN_TOKEN) 60 | .build()) 61 | .build(); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /displaytutorial/src/com/amazon/asksdk/displayguide/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | *Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | *Licensed under the Amazon Software License (the "License"). You may not use 5 | * this file except in compliance with the License. A copy of the License is located at 6 | * 7 | *http://aws.amazon.com/asl/ 8 | * 9 | * or in the "license" file accompanying this file. This file is distributed on 10 | * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or 11 | * implied. See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | package com.amazon.asksdk.displayguide; -------------------------------------------------------------------------------- /displaytutorial/src/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log = . 2 | log4j.rootLogger = DEBUG, LAMBDA 3 | 4 | #Define the LAMBDA appender 5 | log4j.appender.LAMBDA=com.amazonaws.services.lambda.runtime.log4j.LambdaAppender 6 | log4j.appender.LAMBDA.layout=org.apache.log4j.PatternLayout 7 | log4j.appender.LAMBDA.layout.conversionPattern=%d{yyyy-MM-dd HH:mm:ss} <%X{AWSRequestId}> %-5p %c{1}:%L - %m%n 8 | -------------------------------------------------------------------------------- /helloworld/README.md: -------------------------------------------------------------------------------- 1 | # Alexa Skills Kit SDK Sample - Hello World 2 | A simple [AWS Lambda](http://aws.amazon.com/lambda) function that demonstrates how to write a skill for the Amazon Echo using the Alexa SDK. 3 | 4 | ## Concepts 5 | This simple sample has no external dependencies or session management, and shows the most basic example of how to create a Lambda function for handling Alexa Skill requests. 6 | 7 | ## Setup 8 | To run this example skill you need to do two things. The first is to deploy the example code in lambda, and the second is to configure the Alexa skill to use Lambda. 9 | 10 | ### AWS Lambda Setup 11 | 1. Go to the AWS Console and click on the Lambda link. Note: ensure you are in us-east or you wont be able to use Alexa with Lambda. 12 | 2. Click on the Create Function button. 13 | 3. Click Author from scratch. 14 | 4. In Configure triggers, add Alexa Skill kit as trigger. 15 | 5. Name the Lambda Function "Hello-World-Example-Skill". 16 | 6. Select the runtime as Java 8. 17 | 7. Build a jar file to upload it into the lambda function. There are two ways: 18 | - Using maven: go to the directory containing pom.xml, and run 'mvn assembly:assembly -DdescriptorId=jar-with-dependencies package'. This will generate a zip file named "helloworld-1.0-jar-with-dependencies.jar" in the target directory. 19 | - Using gradle: go to the directory containing build.gradle, and run 'gradle fatJar'. This will generate a zip file named "helloworld-fat-1.0.jar" in the build/libs directory. 20 | 8. Select Code entry type as "Upload a .ZIP file" and then upload the jar file created in step 7 from the build directory to Lambda. 21 | 9. Set the Handler as com.amazon.asksdk.helloworld.HelloWorldSpeechletRequestStreamHandler (this refers to the Lambda RequestStreamHandler file in the zip). 22 | 10. Choose an existing role - lambda_basic_execution. 23 | 11. Increase the Timeout to 30 seconds under Basic Settings. 24 | 12. Leave the Advanced settings as the defaults. 25 | 13. Click "Next" and review the settings then click "Create Function". 26 | 14. Copy the ARN from the top right to be used later in the Alexa Skill Setup. 27 | 28 | ### Alexa Skill Setup 29 | 1. Go to the [Alexa Console](https://developer.amazon.com/edw/home.html) and click Add a New Skill. 30 | 2. Set "HelloWorld" as the skill name and "greeter" as the invocation name, this is what is used to activate your skill. For example you would say: "Alexa, tell Greeter to say hello." 31 | 3. Select the Lambda ARN for the skill Endpoint and paste the ARN copied from above. Click Next. 32 | 4. Copy the contents of SpeechAssets. 33 | - If you are using the new Skill Builder, copy the Skill Builder from included SkillBuilder.json. 34 | - Otherwise, copy the Intent Schema from the included IntentSchema.json. Copy the Sample Utterances from the included SampleUtterances.txt. Click Next. 35 | 5. Go back to the skill Information tab and copy the appId. Paste the appId into the HelloWorldSpeechletRequestStreamHandler.java file for the variable supportedApplicationIds, 36 | then update the lambda source zip file with this change and upload to lambda again, this step makes sure the lambda function only serves request from authorized source. 37 | 6. You are now able to start testing your sample skill! You should be able to go to the [Echo webpage](http://echo.amazon.com/#skills) and see your skill enabled. 38 | 7. In order to test it, try to say some of the Sample Utterances from the Examples section below. 39 | 8. Your skill is now saved and once you are finished testing you can continue to publish your skill. 40 | 41 | ## Examples 42 | ### One-shot model: 43 | User: "Alexa, tell Greeter to say hello." 44 | Alexa: "Hello World!" 45 | -------------------------------------------------------------------------------- /helloworld/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | 3 | group = "alexa-skills-kit-samples" 4 | version = '1.0' 5 | 6 | compileJava { 7 | targetCompatibility = JavaVersion.VERSION_1_8 8 | sourceCompatibility = JavaVersion.VERSION_1_8 9 | } 10 | 11 | jar { 12 | manifest { 13 | attributes 'Implementation-Title': 'Gradle Quickstart', 14 | 'Implementation-Version': version 15 | } 16 | } 17 | 18 | repositories { 19 | jcenter() 20 | mavenCentral() 21 | } 22 | 23 | sourceSets { 24 | main { 25 | java { 26 | srcDirs 'src' 27 | } 28 | resources { 29 | srcDirs 'src/resources' 30 | } 31 | } 32 | } 33 | 34 | dependencies { 35 | compile 'com.amazon.alexa:alexa-skills-kit:1.5.0' 36 | compile 'com.amazonaws:aws-lambda-java-core:1.0.0' 37 | compile 'com.amazonaws:aws-java-sdk-dynamodb:1.9.40' 38 | compile 'com.amazonaws:aws-lambda-java-log4j:1.0.0' 39 | 40 | compile 'log4j:log4j:1.2.17' 41 | compile 'org.apache.commons:commons-lang3:3.3.2' 42 | compile 'org.apache.directory.studio:org.apache.commons.io:2.4' 43 | compile 'org.eclipse.jetty:jetty-server:9.0.6.v20130930' 44 | compile 'org.eclipse.jetty:jetty-servlet:9.0.6.v20130930' 45 | compile 'org.slf4j:slf4j-api:1.7.10' 46 | } 47 | 48 | task fatJar(type: Jar) { 49 | baseName = project.name + '-fat' 50 | from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } 51 | with jar 52 | } 53 | 54 | build.dependsOn fatJar 55 | -------------------------------------------------------------------------------- /helloworld/speechAssets/IntentSchema.json: -------------------------------------------------------------------------------- 1 | { 2 | "intents": [ 3 | { 4 | "intent": "HelloWorldIntent" 5 | }, 6 | { 7 | "intent": "AMAZON.HelpIntent" 8 | } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /helloworld/speechAssets/SampleUtterances.txt: -------------------------------------------------------------------------------- 1 | HelloWorldIntent say hello 2 | HelloWorldIntent say hello world 3 | HelloWorldIntent hello 4 | HelloWorldIntent say hi 5 | HelloWorldIntent say hi world 6 | HelloWorldIntent hi 7 | HelloWorldIntent how are you -------------------------------------------------------------------------------- /helloworld/speechAssets/SkillBuilder.json: -------------------------------------------------------------------------------- 1 | { 2 | "languageModel": { 3 | "intents": [ 4 | { 5 | "name": "AMAZON.CancelIntent", 6 | "samples": [] 7 | }, 8 | { 9 | "name": "AMAZON.HelpIntent", 10 | "samples": [] 11 | }, 12 | { 13 | "name": "AMAZON.StopIntent", 14 | "samples": [] 15 | }, 16 | { 17 | "name": "HelloWorldIntent", 18 | "samples": [ 19 | "say hello", 20 | "say hello world", 21 | "hello", 22 | "say hi", 23 | "say hi world", 24 | "hi", 25 | "how are you" 26 | ], 27 | "slots": [] 28 | } 29 | ], 30 | "invocationName": "greeter" 31 | } 32 | } -------------------------------------------------------------------------------- /helloworld/src/com/amazon/asksdk/helloworld/HelloWorldSpeechletRequestStreamHandler.java: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2014-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at 5 | 6 | http://aws.amazon.com/apache2.0/ 7 | 8 | or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 9 | */ 10 | package com.amazon.asksdk.helloworld; 11 | 12 | import java.util.HashSet; 13 | import java.util.Set; 14 | 15 | import com.amazon.speech.speechlet.lambda.SpeechletRequestStreamHandler; 16 | 17 | /** 18 | * This class could be the handler for an AWS Lambda function powering an Alexa Skills Kit 19 | * experience. To do this, simply set the handler field in the AWS Lambda console to 20 | * "com.amazon.asksdk.helloworld.HelloWorldSpeechletRequestStreamHandler" For this to work, you'll also need to build 21 | * this project using the {@code lambda-compile} Ant task and upload the resulting zip file to power 22 | * your function. 23 | */ 24 | public final class HelloWorldSpeechletRequestStreamHandler extends SpeechletRequestStreamHandler { 25 | private static final Set supportedApplicationIds; 26 | static { 27 | /* 28 | * This Id can be found on https://developer.amazon.com/edw/home.html#/ "Edit" the relevant 29 | * Alexa Skill and put the relevant Application Ids in this Set. 30 | */ 31 | supportedApplicationIds = new HashSet(); 32 | // supportedApplicationIds.add("[unique-value-here]"); 33 | } 34 | 35 | public HelloWorldSpeechletRequestStreamHandler() { 36 | super(new HelloWorldSpeechlet(), supportedApplicationIds); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /helloworld/src/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log = . 2 | log4j.rootLogger = DEBUG, LAMBDA 3 | 4 | #Define the LAMBDA appender 5 | log4j.appender.LAMBDA=com.amazonaws.services.lambda.runtime.log4j.LambdaAppender 6 | log4j.appender.LAMBDA.layout=org.apache.log4j.PatternLayout 7 | log4j.appender.LAMBDA.layout.conversionPattern=%d{yyyy-MM-dd HH:mm:ss} <%X{AWSRequestId}> %-5p %c{1}:%L - %m%n 8 | -------------------------------------------------------------------------------- /historybuff/README.md: -------------------------------------------------------------------------------- 1 | # Alexa Skills Kit SDK Sample - History Buff 2 | A simple [AWS Lambda](http://aws.amazon.com/lambda) function that demonstrates how to write a skill for the Amazon Echo using the Alexa SDK. 3 | 4 | ## Concepts 5 | This sample shows how to create a Lambda function for handling Alexa Skill requests that: 6 | 7 | - Web service: communicate with an external web service to get events for specified days in history (Wikipedia API) 8 | - Pagination: after obtaining a list of events, read a small subset of events and wait for user prompt to read the next subset of events by maintaining session state 9 | - Dialog and Session state: Handles two models, both a one-shot ask and tell model, and a multi-turn dialog model. 10 | - SSML: Using SSML tags to control how Alexa renders the text-to-speech. 11 | 12 | ## Setup 13 | To run this example skill you need to do two things. The first is to deploy the example code in lambda, and the second is to configure the Alexa skill to use Lambda. 14 | 15 | ### AWS Lambda Setup 16 | 1. Go to the AWS Console and click on the Lambda link. Note: ensure you are in us-east or you wont be able to use Alexa with Lambda. 17 | 2. Click on the Create Function button. 18 | 3. Click Author from scratch. 19 | 4. In Configure triggers, add Alexa Skill kit as trigger. 20 | 5. Name the Lambda Function "History-Buff-Example-Skill". 21 | 6. Select the runtime as Java 8. 22 | 7. Build a jar file to upload it into the lambda function. There are two ways: 23 | - Using maven: go to the directory containing pom.xml, and run 'mvn assembly:assembly -DdescriptorId=jar-with-dependencies package'. This will generate a zip file named "historybuff-1.0-jar-with-dependencies.jar" in the target directory. 24 | - Using gradle: go to the directory containing build.gradle, and run 'gradle fatJar'. This will generate a zip file named "historybuff-fat-1.0.jar" in the build/libs directory. 25 | 8. Select Code entry type as "Upload a .ZIP file" and then upload the jar file created in step 7 from the build directory to Lambda. 26 | 9. Set the Handler as com.amazon.asksdk.historybuff.HistoryBuffSpeechletRequestStreamHandler (this refers to the Lambda RequestStreamHandler file in the zip). 27 | 10. Choose an existing role - lambda_basic_execution. 28 | 11. Increase the Timeout to 30 seconds under Basic Settings. 29 | 12. Leave the Advanced settings as the defaults. 30 | 13. Click "Next" and review the settings then click "Create Function". 31 | 14. Copy the ARN from the top right to be used later in the Alexa Skill Setup. 32 | 33 | ### Alexa Skill Setup 34 | 1. Go to the [Alexa Console](https://developer.amazon.com/edw/home.html) and click Add a New Skill. 35 | 2. Set "HistoryBuff" as the skill name and "history buff" as the invocation name, this is what is used to activate your skill. For example you would say: "Alexa, Ask History Buff what happened on August thirtieth.." 36 | 3. Select the Lambda ARN for the skill Endpoint and paste the ARN copied from above. Click Next. 37 | 4. Copy the contents of SpeechAssets. 38 | - If you are using the new Skill Builder, copy the Skill Builder from included SkillBuilder.json. 39 | - Otherwise, copy the Intent Schema from the included IntentSchema.json. Copy the Sample Utterances from the included SampleUtterances.txt. Click Next. 40 | 5. Go back to the skill Information tab and copy the appId. Paste the appId into the HistoryBuffSpeechletRequestStreamHandler.java file for the variable supportedApplicationIds, 41 | then update the lambda source zip file with this change and upload to lambda again, this step makes sure the lambda function only serves request from authorized source. 42 | 6. You are now able to start testing your sample skill! You should be able to go to the [Echo webpage](http://echo.amazon.com/#skills) and see your skill enabled. 43 | 7. In order to test it, try to say some of the Sample Utterances from the Examples section below. 44 | 8. Your skill is now saved and once you are finished testing you can continue to publish your skill. 45 | 46 | ## Examples 47 | ### One-shot model: 48 | User: "Alexa, ask History Buff what happened on August thirtieth." 49 | Alexa: "For August thirtieth, in 2003, [...] . Wanna go deeper in history?" 50 | User: "No." 51 | Alexa: "Good bye!" 52 | ### Dialog model: 53 | User: "Alexa, open History Buff" 54 | Alexa: "History Buff. What day do you want events for?" 55 | User: "August thirtieth." 56 | Alexa: "For August thirtieth, in 2003, [...] . Wanna go deeper in history?" 57 | User: "Yes." 58 | Alexa: "In 1995, Bosnian war [...] . Wanna go deeper in history?" 59 | User: "No." 60 | Alexa: "Good bye!" 61 | -------------------------------------------------------------------------------- /historybuff/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | 3 | group = "alexa-skills-kit-samples" 4 | version = '1.0' 5 | 6 | compileJava { 7 | targetCompatibility = JavaVersion.VERSION_1_8 8 | sourceCompatibility = JavaVersion.VERSION_1_8 9 | } 10 | 11 | jar { 12 | manifest { 13 | attributes 'Implementation-Title': 'Gradle Quickstart', 14 | 'Implementation-Version': version 15 | } 16 | } 17 | 18 | repositories { 19 | jcenter() 20 | mavenCentral() 21 | } 22 | 23 | sourceSets { 24 | main { 25 | java { 26 | srcDirs 'src' 27 | } 28 | resources { 29 | srcDirs 'src/resources' 30 | } 31 | } 32 | } 33 | 34 | dependencies { 35 | compile 'com.amazon.alexa:alexa-skills-kit:1.5.0' 36 | compile 'com.amazonaws:aws-lambda-java-core:1.0.0' 37 | compile 'com.amazonaws:aws-java-sdk-dynamodb:1.9.40' 38 | compile 'com.amazonaws:aws-lambda-java-log4j:1.0.0' 39 | 40 | compile 'log4j:log4j:1.2.17' 41 | compile 'org.apache.commons:commons-lang3:3.3.2' 42 | compile 'org.apache.directory.studio:org.apache.commons.io:2.4' 43 | compile 'org.eclipse.jetty:jetty-server:9.0.6.v20130930' 44 | compile 'org.eclipse.jetty:jetty-servlet:9.0.6.v20130930' 45 | compile 'org.slf4j:slf4j-api:1.7.10' 46 | } 47 | 48 | task fatJar(type: Jar) { 49 | baseName = project.name + '-fat' 50 | from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } 51 | with jar 52 | } 53 | 54 | build.dependsOn fatJar 55 | -------------------------------------------------------------------------------- /historybuff/speechAssets/IntentSchema.json: -------------------------------------------------------------------------------- 1 | { 2 | "intents": [ 3 | { 4 | "intent": "GetFirstEventIntent", 5 | "slots": [ 6 | { 7 | "name": "day", 8 | "type": "AMAZON.DATE" 9 | } 10 | ] 11 | }, 12 | { 13 | "intent": "GetNextEventIntent" 14 | }, 15 | { 16 | "intent": "AMAZON.HelpIntent" 17 | }, 18 | { 19 | "intent": "AMAZON.StopIntent" 20 | }, 21 | { 22 | "intent": "AMAZON.CancelIntent" 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /historybuff/speechAssets/SampleUtterances.txt: -------------------------------------------------------------------------------- 1 | GetFirstEventIntent get events for {day} 2 | GetFirstEventIntent give me events for {day} 3 | GetFirstEventIntent what happened on {day} 4 | GetFirstEventIntent what happened 5 | GetFirstEventIntent {day} 6 | 7 | GetNextEventIntent yes 8 | GetNextEventIntent yup 9 | GetNextEventIntent sure 10 | GetNextEventIntent yes please 11 | 12 | AMAZON.StopIntent no 13 | AMAZON.StopIntent nope 14 | AMAZON.StopIntent no thanks 15 | AMAZON.StopIntent no thank you 16 | -------------------------------------------------------------------------------- /historybuff/speechAssets/SkillBuilder.json: -------------------------------------------------------------------------------- 1 | { 2 | "languageModel": { 3 | "intents": [ 4 | { 5 | "name": "AMAZON.CancelIntent", 6 | "samples": [] 7 | }, 8 | { 9 | "name": "AMAZON.HelpIntent", 10 | "samples": [] 11 | }, 12 | { 13 | "name": "AMAZON.StopIntent", 14 | "samples": [ 15 | "no", 16 | "nope", 17 | "no thanks", 18 | "no thank you" 19 | ] 20 | }, 21 | { 22 | "name": "GetFirstEventIntent", 23 | "samples": [ 24 | "get events for {day}", 25 | "give me events for {day}", 26 | "what happened on {day}", 27 | "what happened", 28 | "{day}" 29 | ], 30 | "slots": [ 31 | { 32 | "name": "day", 33 | "type": "AMAZON.DATE" 34 | } 35 | ] 36 | }, 37 | { 38 | "name": "GetNextEventIntent", 39 | "samples": [ 40 | "yes", 41 | "yup", 42 | "sure", 43 | "yes please" 44 | ], 45 | "slots": [] 46 | } 47 | ], 48 | "invocationName": "history buff" 49 | } 50 | } -------------------------------------------------------------------------------- /historybuff/src/com/amazon/asksdk/historybuff/HistoryBuffSpeechletRequestStreamHandler.java: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2014-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at 5 | 6 | http://aws.amazon.com/apache2.0/ 7 | 8 | or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 9 | */ 10 | package com.amazon.asksdk.historybuff; 11 | 12 | import java.util.HashSet; 13 | import java.util.Set; 14 | 15 | import com.amazon.speech.speechlet.Speechlet; 16 | import com.amazon.speech.speechlet.lambda.SpeechletRequestStreamHandler; 17 | import com.amazon.speech.speechlet.services.DirectiveServiceClient; 18 | 19 | /** 20 | * This class could be the handler for an AWS Lambda function powering an Alexa Skills Kit 21 | * experience. To do this, simply set the handler field in the AWS Lambda console to 22 | * "historybuff.HistoryBuffSpeechletRequestStreamHandler" For this to work, you'll also need to 23 | * build this project using the {@code lambda-compile} Ant task and upload the resulting zip file to 24 | * power your function. 25 | */ 26 | public class HistoryBuffSpeechletRequestStreamHandler extends SpeechletRequestStreamHandler { 27 | 28 | private static final Set supportedApplicationIds; 29 | 30 | static { 31 | /* 32 | * This Id can be found on https://developer.amazon.com/edw/home.html#/ "Edit" the relevant 33 | * Alexa Skill and put the relevant Application Ids in this Set. 34 | */ 35 | supportedApplicationIds = new HashSet(); 36 | // supportedApplicationIds.add("[unique-value-here]"); 37 | } 38 | 39 | public HistoryBuffSpeechletRequestStreamHandler() { 40 | super(new HistoryBuffSpeechlet(new DirectiveServiceClient()), supportedApplicationIds); 41 | } 42 | 43 | public HistoryBuffSpeechletRequestStreamHandler(Speechlet speechlet, 44 | Set supportedApplicationIds) { 45 | super(speechlet, supportedApplicationIds); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /historybuff/src/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log = . 2 | log4j.rootLogger = DEBUG, LAMBDA 3 | 4 | #Define the LAMBDA appender 5 | log4j.appender.LAMBDA=com.amazonaws.services.lambda.runtime.log4j.LambdaAppender 6 | log4j.appender.LAMBDA.layout=org.apache.log4j.PatternLayout 7 | log4j.appender.LAMBDA.layout.conversionPattern=%d{yyyy-MM-dd HH:mm:ss} <%X{AWSRequestId}> %-5p %c{1}:%L - %m%n 8 | -------------------------------------------------------------------------------- /minecrafthelper/README.md: -------------------------------------------------------------------------------- 1 | # Alexa Skills Kit SDK Sample - Mine Craft Helper 2 | A simple [AWS Lambda](http://aws.amazon.com/lambda) function that demonstrates how to write a skill for the Amazon Echo using the Alexa SDK. 3 | 4 | ## Concepts 5 | This sample shows how to create a Lambda function for handling Alexa Skill requests that: 6 | 7 | - Custom slot type: demonstrates using custom slot types to handle a finite set of known values 8 | 9 | ## Setup 10 | To run this example skill you need to do two things. The first is to deploy the example code in lambda, and the second is to configure the Alexa skill to use Lambda. 11 | 12 | ### AWS Lambda Setup 13 | 1. Go to the AWS Console and click on the Lambda link. Note: ensure you are in us-east or you wont be able to use Alexa with Lambda. 14 | 2. Click on the Create Function button. 15 | 3. Click Author from scratch. 16 | 4. In Configure triggers, add Alexa Skill kit as trigger. 17 | 5. Name the Lambda Function "Minecraft-Helper-Example-Skill". 18 | 6. Select the runtime as Java 8. 19 | 7. Build a jar file to upload it into the lambda function. There are two ways: 20 | - Using maven: go to the directory containing pom.xml, and run 'mvn assembly:assembly -DdescriptorId=jar-with-dependencies package'. This will generate a zip file named "minecrafthelper-1.0-jar-with-dependencies.jar" in the target directory. 21 | - Using gradle: go to the directory containing build.gradle, and run 'gradle fatJar'. This will generate a zip file named "minecrafthelper-fat-1.0.jar" in the build/libs directory. 22 | 8. Select Code entry type as "Upload a .ZIP file" and then upload the jar file created in step 7 from the build directory to Lambda. 23 | 9. Set the Handler as com.amazon.asksdk.minecrafthelper.MinecraftHelperSpeechletRequestStreamHandler (this refers to the Lambda RequestStreamHandler file in the zip). 24 | 10.Choose an existing role - lambda_basic_execution. 25 | 11. Increase the Timeout to 30 seconds under Basic Settings. 26 | 12. Leave the Advanced settings as the defaults. 27 | 13. Click "Next" and review the settings then click "Create Function". 28 | 14. Copy the ARN from the top right to be used later in the Alexa Skill Setup. 29 | 30 | ### Alexa Skill Setup 31 | 1. Go to the [Alexa Console](https://developer.amazon.com/edw/home.html) and click Add a New Skill. 32 | 2. Set "MinecraftHelper" as the skill name and "minecraft helper" as the invocation name, this is what is used to activate your skill. For example you would say: "Alexa, Ask minecraft help how to make a door." 33 | 3. Select the Lambda ARN for the skill Endpoint and paste the ARN copied from above. Click Next. 34 | 4. Copy the contents of SpeechAssets. 35 | - If you are using the new Skill Builder, copy the Skill Builder from included SkillBuilder.json. 36 | - Otherwise, copy the Intent Schema from the included IntentSchema.json. Copy the Sample Utterances from the included SampleUtterances.txt. Copy the custom slot types from the customSlotTypes folder. Each file in the folder represents a new custom slot type. The name of the file is the name of the custom slot type, and the values in the file are the values for the custom slot. Click Next. 37 | 5. Go back to the skill Information tab and copy the appId. Paste the appId into the MinecraftHelperSpeechletRequestStreamHandler.java file for the variable supportedApplicationIds, 38 | then update the lambda source zip file with this change and upload to lambda again, this step makes sure the lambda function only serves request from authorized source. 39 | 6. You are now able to start testing your sample skill! You should be able to go to the [Echo webpage](http://echo.amazon.com/#skills) and see your skill enabled. 40 | 7. In order to test it, try to say some of the Sample Utterances from the Examples section below. 41 | 8. Your skill is now saved and once you are finished testing you can continue to publish your skill. 42 | 43 | ## Examples 44 | ### One-shot model: 45 | User: "Alexa, ask Minecraft Helper how to make paper." 46 | Alexa: "(reads back recipe for paper)" 47 | -------------------------------------------------------------------------------- /minecrafthelper/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | 3 | group = "alexa-skills-kit-samples" 4 | version = '1.0' 5 | 6 | compileJava { 7 | targetCompatibility = JavaVersion.VERSION_1_8 8 | sourceCompatibility = JavaVersion.VERSION_1_8 9 | } 10 | 11 | jar { 12 | manifest { 13 | attributes 'Implementation-Title': 'Gradle Quickstart', 14 | 'Implementation-Version': version 15 | } 16 | } 17 | 18 | repositories { 19 | jcenter() 20 | mavenCentral() 21 | } 22 | 23 | sourceSets { 24 | main { 25 | java { 26 | srcDirs 'src' 27 | } 28 | resources { 29 | srcDirs 'src/resources' 30 | } 31 | } 32 | } 33 | 34 | dependencies { 35 | compile 'com.amazon.alexa:alexa-skills-kit:1.5.0' 36 | compile 'com.amazonaws:aws-lambda-java-core:1.0.0' 37 | compile 'com.amazonaws:aws-java-sdk-dynamodb:1.9.40' 38 | compile 'com.amazonaws:aws-lambda-java-log4j:1.0.0' 39 | 40 | compile 'log4j:log4j:1.2.17' 41 | compile 'org.apache.commons:commons-lang3:3.3.2' 42 | compile 'org.apache.directory.studio:org.apache.commons.io:2.4' 43 | compile 'org.eclipse.jetty:jetty-server:9.0.6.v20130930' 44 | compile 'org.eclipse.jetty:jetty-servlet:9.0.6.v20130930' 45 | compile 'org.slf4j:slf4j-api:1.7.10' 46 | } 47 | 48 | task fatJar(type: Jar) { 49 | baseName = project.name + '-fat' 50 | from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } 51 | with jar 52 | } 53 | 54 | build.dependsOn fatJar 55 | -------------------------------------------------------------------------------- /minecrafthelper/speechAssets/IntentSchema.json: -------------------------------------------------------------------------------- 1 | { 2 | "intents": [ 3 | { 4 | "intent": "RecipeIntent", 5 | "slots": [ 6 | { 7 | "name" : "Item", 8 | "type": "LIST_OF_ITEMS" 9 | } 10 | ] 11 | }, 12 | { 13 | "intent": "AMAZON.HelpIntent" 14 | }, 15 | { 16 | "intent": "AMAZON.StopIntent" 17 | }, 18 | { 19 | "intent": "AMAZON.CancelIntent" 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /minecrafthelper/src/com/amazon/asksdk/minecrafthelper/MinecraftHelperSpeechletRequestStreamHandler.java: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2014-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at 5 | 6 | http://aws.amazon.com/apache2.0/ 7 | 8 | or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 9 | */ 10 | package com.amazon.asksdk.minecrafthelper; 11 | 12 | import java.util.HashSet; 13 | import java.util.Set; 14 | 15 | import com.amazon.speech.speechlet.lambda.SpeechletRequestStreamHandler; 16 | 17 | /** 18 | * This class is created by the Lambda environment when a request comes in. All calls will be 19 | * dispatched to the Speechlet passed into the super constructor. 20 | */ 21 | public final class MinecraftHelperSpeechletRequestStreamHandler extends 22 | SpeechletRequestStreamHandler { 23 | private static final Set supportedApplicationIds; 24 | 25 | static { 26 | /* 27 | * This Id can be found on https://developer.amazon.com/edw/home.html#/ "Edit" the relevant 28 | * Alexa Skill and put the relevant Application Ids in this Set. 29 | */ 30 | supportedApplicationIds = new HashSet(); 31 | // supportedApplicationIds.add("[unique-value-here]"); 32 | } 33 | 34 | public MinecraftHelperSpeechletRequestStreamHandler() { 35 | super(new MinecraftSpeechlet(), supportedApplicationIds); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /minecrafthelper/src/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log = . 2 | log4j.rootLogger = DEBUG, LAMBDA 3 | 4 | #Define the LAMBDA appender 5 | log4j.appender.LAMBDA=com.amazonaws.services.lambda.runtime.log4j.LambdaAppender 6 | log4j.appender.LAMBDA.layout=org.apache.log4j.PatternLayout 7 | log4j.appender.LAMBDA.layout.conversionPattern=%d{yyyy-MM-dd HH:mm:ss} <%X{AWSRequestId}> %-5p %c{1}:%L - %m%n 8 | -------------------------------------------------------------------------------- /savvyconsumer/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | 3 | group = "alexa-skills-kit-samples" 4 | version = '1.0' 5 | 6 | compileJava { 7 | targetCompatibility = JavaVersion.VERSION_1_8 8 | sourceCompatibility = JavaVersion.VERSION_1_8 9 | } 10 | 11 | jar { 12 | manifest { 13 | attributes 'Implementation-Title': 'Gradle Quickstart', 14 | 'Implementation-Version': version 15 | } 16 | } 17 | 18 | repositories { 19 | jcenter() 20 | mavenCentral() 21 | } 22 | 23 | sourceSets { 24 | main { 25 | java { 26 | srcDirs 'src' 27 | } 28 | resources { 29 | srcDirs 'src/resources' 30 | } 31 | } 32 | } 33 | 34 | dependencies { 35 | compile 'com.amazon.alexa:alexa-skills-kit:1.5.0' 36 | compile 'com.amazonaws:aws-lambda-java-core:1.0.0' 37 | compile 'com.amazonaws:aws-java-sdk-dynamodb:1.9.40' 38 | compile 'com.amazonaws:aws-lambda-java-log4j:1.0.0' 39 | 40 | compile 'log4j:log4j:1.2.17' 41 | compile 'org.apache.commons:commons-lang3:3.3.2' 42 | compile 'org.apache.directory.studio:org.apache.commons.io:2.4' 43 | compile 'org.eclipse.jetty:jetty-server:9.0.6.v20130930' 44 | compile 'org.eclipse.jetty:jetty-servlet:9.0.6.v20130930' 45 | compile 'org.slf4j:slf4j-api:1.7.10' 46 | } 47 | 48 | task fatJar(type: Jar) { 49 | baseName = project.name + '-fat' 50 | from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } 51 | with jar 52 | } 53 | 54 | build.dependsOn fatJar 55 | -------------------------------------------------------------------------------- /savvyconsumer/speechAssets/IntentSchema.json: -------------------------------------------------------------------------------- 1 | { 2 | "intents": [ 3 | { 4 | "intent": "TopSellers", 5 | "slots": [ 6 | { 7 | "name": "Category", 8 | "type": "LIST_OF_CATEGORIES" 9 | } 10 | ] 11 | }, 12 | { 13 | "intent": "HearMore" 14 | }, 15 | { 16 | "intent": "DontHearMore" 17 | }, 18 | { 19 | "intent": "AMAZON.HelpIntent" 20 | }, 21 | { 22 | "intent": "AMAZON.StopIntent" 23 | }, 24 | { 25 | "intent": "AMAZON.CancelIntent" 26 | } 27 | ] 28 | } -------------------------------------------------------------------------------- /savvyconsumer/speechAssets/SampleUtterances.txt: -------------------------------------------------------------------------------- 1 | TopSellers get top sellers for {Category} 2 | TopSellers get best sellers for {Category} 3 | TopSellers get me {Category} 4 | TopSellers top {Category} 5 | TopSellers top products in {Category} 6 | TopSellers top sellers in {Category} 7 | TopSellers {Category} 8 | 9 | HearMore yes 10 | HearMore yep 11 | HearMore yeah 12 | HearMore sure 13 | HearMore yes please 14 | HearMore affirmative 15 | 16 | DontHearMore no 17 | DontHearMore nope 18 | DontHearMore no thank you 19 | DontHearMore not now 20 | DontHearMore negative -------------------------------------------------------------------------------- /savvyconsumer/speechAssets/customSlotTypes/LIST_OF_CATEGORIES: -------------------------------------------------------------------------------- 1 | apparel 2 | appliances 3 | arts and crafts 4 | arts 5 | crafts 6 | automotive 7 | baby 8 | beauty 9 | books 10 | classical 11 | collectibles 12 | dvd 13 | dvds 14 | digital music 15 | electronics 16 | gift cards 17 | gourmet food 18 | food 19 | grocery 20 | health 21 | personal care 22 | home 23 | garden 24 | industrial 25 | jewelry 26 | kindle 27 | kitchen 28 | lawn and garden 29 | lawn 30 | mp3 31 | mp3s 32 | magazines 33 | miscellaneous 34 | mobile apps 35 | movie 36 | movies 37 | apps 38 | music 39 | musical instruments 40 | office products 41 | office 42 | outdoor living 43 | outdoor 44 | pc hardware 45 | pc 46 | pcs 47 | pet supplies 48 | pet 49 | photo 50 | shoes 51 | software 52 | sporting goods 53 | tools 54 | toys 55 | vhs 56 | video 57 | video games 58 | watches 59 | wireless 60 | wireless accessories -------------------------------------------------------------------------------- /savvyconsumer/src/com/amazon/asksdk/savvyconsumer/SavvyConsumerSpeechletRequestStreamHandler.java: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2014-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at 5 | 6 | http://aws.amazon.com/apache2.0/ 7 | 8 | or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 9 | */ 10 | package com.amazon.asksdk.savvyconsumer; 11 | 12 | import java.util.HashSet; 13 | import java.util.Set; 14 | 15 | import com.amazon.speech.speechlet.lambda.SpeechletRequestStreamHandler; 16 | 17 | /** 18 | * This class is created by the Lambda environment when a request comes in. All calls will be 19 | * dispatched to the Speechlet passed into the super constructor. 20 | */ 21 | public final class SavvyConsumerSpeechletRequestStreamHandler extends SpeechletRequestStreamHandler { 22 | private static final Set supportedApplicationIds; 23 | 24 | static { 25 | /* 26 | * This Id can be found on https://developer.amazon.com/edw/home.html#/ "Edit" the relevant 27 | * Alexa Skill and put the relevant Application Ids in this Set. 28 | */ 29 | supportedApplicationIds = new HashSet(); 30 | // supportedApplicationIds.add("[unique-value-here]"); 31 | } 32 | 33 | public SavvyConsumerSpeechletRequestStreamHandler() { 34 | super(new SavvyConsumerSpeechlet(), supportedApplicationIds); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /savvyconsumer/src/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log = . 2 | log4j.rootLogger = DEBUG, LAMBDA 3 | 4 | #Define the LAMBDA appender 5 | log4j.appender.LAMBDA=com.amazonaws.services.lambda.runtime.log4j.LambdaAppender 6 | log4j.appender.LAMBDA.layout=org.apache.log4j.PatternLayout 7 | log4j.appender.LAMBDA.layout.conversionPattern=%d{yyyy-MM-dd HH:mm:ss} <%X{AWSRequestId}> %-5p %c{1}:%L - %m%n 8 | -------------------------------------------------------------------------------- /scorekeeper/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | 3 | group = "alexa-skills-kit-samples" 4 | version = '1.0' 5 | 6 | compileJava { 7 | targetCompatibility = JavaVersion.VERSION_1_8 8 | sourceCompatibility = JavaVersion.VERSION_1_8 9 | } 10 | 11 | jar { 12 | manifest { 13 | attributes 'Implementation-Title': 'Gradle Quickstart', 14 | 'Implementation-Version': version 15 | } 16 | } 17 | 18 | repositories { 19 | jcenter() 20 | mavenCentral() 21 | } 22 | 23 | sourceSets { 24 | main { 25 | java { 26 | srcDirs 'src' 27 | } 28 | resources { 29 | srcDirs 'src/resources' 30 | } 31 | } 32 | } 33 | 34 | dependencies { 35 | compile 'com.amazon.alexa:alexa-skills-kit:1.5.0' 36 | compile 'com.amazonaws:aws-lambda-java-core:1.0.0' 37 | compile 'com.amazonaws:aws-java-sdk-dynamodb:1.9.40' 38 | compile 'com.amazonaws:aws-lambda-java-log4j:1.0.0' 39 | 40 | compile 'log4j:log4j:1.2.17' 41 | compile 'org.apache.commons:commons-lang3:3.3.2' 42 | compile 'org.apache.directory.studio:org.apache.commons.io:2.4' 43 | compile 'org.eclipse.jetty:jetty-server:9.0.6.v20130930' 44 | compile 'org.eclipse.jetty:jetty-servlet:9.0.6.v20130930' 45 | compile 'org.slf4j:slf4j-api:1.7.10' 46 | } 47 | 48 | task fatJar(type: Jar) { 49 | baseName = project.name + '-fat' 50 | from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } 51 | with jar 52 | } 53 | 54 | build.dependsOn fatJar 55 | -------------------------------------------------------------------------------- /scorekeeper/speechAssets/IntentSchema.json: -------------------------------------------------------------------------------- 1 | { 2 | "intents": [ 3 | { 4 | "intent": "AddPlayerIntent", 5 | "slots": [ 6 | { 7 | "name": "PlayerName", 8 | "type": "LIST_OF_PLAYER_NAMES" 9 | } 10 | ] 11 | }, 12 | { 13 | "intent": "AddScoreIntent", 14 | "slots": [ 15 | { 16 | "name": "PlayerName", 17 | "type": "LIST_OF_PLAYER_NAMES" 18 | }, 19 | { 20 | "name": "ScoreNumber", 21 | "type": "AMAZON.NUMBER" 22 | } 23 | ] 24 | }, 25 | { 26 | "intent": "ResetPlayersIntent" 27 | }, 28 | { 29 | "intent": "NewGameIntent" 30 | }, 31 | { 32 | "intent": "TellScoresIntent" 33 | }, 34 | { 35 | "intent": "AMAZON.HelpIntent" 36 | }, 37 | { 38 | "intent": "AMAZON.StopIntent" 39 | }, 40 | { 41 | "intent": "AMAZON.CancelIntent" 42 | } 43 | ] 44 | } 45 | -------------------------------------------------------------------------------- /scorekeeper/src/com/amazon/asksdk/scorekeeper/ScoreKeeperSpeechletRequestStreamHandler.java: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2014-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at 5 | 6 | http://aws.amazon.com/apache2.0/ 7 | 8 | or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 9 | */ 10 | package com.amazon.asksdk.scorekeeper; 11 | 12 | import java.util.HashSet; 13 | import java.util.Set; 14 | 15 | import com.amazon.speech.speechlet.lambda.SpeechletRequestStreamHandler; 16 | 17 | /** 18 | * This class could be the handler for an AWS Lambda function powering an Alexa Skills Kit 19 | * experience. To do this, simply set the handler field in the AWS Lambda console to 20 | * "ScoreKeeperSpeechletRequestStreamHandler" For this to work, you'll also need to 21 | * build this project using the {@code lambda-compile} Ant task and upload the resulting zip file to 22 | * power your function. 23 | */ 24 | public final class ScoreKeeperSpeechletRequestStreamHandler extends SpeechletRequestStreamHandler { 25 | private static final Set supportedApplicationIds; 26 | 27 | static { 28 | /* 29 | * This Id can be found on https://developer.amazon.com/edw/home.html#/ "Edit" the relevant 30 | * Alexa Skill and put the relevant Application Ids in this Set. 31 | */ 32 | supportedApplicationIds = new HashSet(); 33 | // supportedApplicationIds.add("[unique-value-here]"); 34 | } 35 | 36 | public ScoreKeeperSpeechletRequestStreamHandler() { 37 | super(new ScoreKeeperSpeechlet(), supportedApplicationIds); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /scorekeeper/src/com/amazon/asksdk/scorekeeper/ScoreKeeperTextUtil.java: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2014-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at 5 | 6 | http://aws.amazon.com/apache2.0/ 7 | 8 | or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 9 | */ 10 | package com.amazon.asksdk.scorekeeper; 11 | 12 | import java.util.Arrays; 13 | import java.util.List; 14 | 15 | /** 16 | * Util containing various text related utils. 17 | */ 18 | public final class ScoreKeeperTextUtil { 19 | 20 | private ScoreKeeperTextUtil() { 21 | } 22 | 23 | /** 24 | * List of player names blacklisted for this app. 25 | */ 26 | private static final List NAME_BLACKLIST = Arrays.asList("player", "players"); 27 | 28 | /** 29 | * Text of complete help. 30 | */ 31 | public static final String COMPLETE_HELP = 32 | "Here's some things you can say. Add John, give John 5 points, tell me the score, " 33 | + "new game, reset, and exit."; 34 | 35 | /** 36 | * Text of next help. 37 | */ 38 | public static final String NEXT_HELP = "You can give a player points, add a player, get the " 39 | + "current score, or say help. What would you like?"; 40 | 41 | /** 42 | * Cleans up the player name, and sanitizes it against the blacklist. 43 | * 44 | * @param recognizedPlayerName 45 | * @return 46 | */ 47 | public static String getPlayerName(String recognizedPlayerName) { 48 | if (recognizedPlayerName == null || recognizedPlayerName.isEmpty()) { 49 | return null; 50 | } 51 | 52 | String cleanedName; 53 | if (recognizedPlayerName.contains(" ")) { 54 | // the name should only contain a first name, so ignore the second part if any 55 | cleanedName = recognizedPlayerName.substring(recognizedPlayerName.indexOf(" ")); 56 | } else { 57 | cleanedName = recognizedPlayerName; 58 | } 59 | 60 | // if the name is on our blacklist, it must be mis-recognition 61 | if (NAME_BLACKLIST.contains(cleanedName)) { 62 | return null; 63 | } 64 | 65 | return cleanedName; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /scorekeeper/src/com/amazon/asksdk/scorekeeper/SkillContext.java: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2014-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at 5 | 6 | http://aws.amazon.com/apache2.0/ 7 | 8 | or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 9 | */ 10 | package com.amazon.asksdk.scorekeeper; 11 | 12 | /** 13 | * Contains session scoped settings. 14 | */ 15 | public class SkillContext { 16 | private boolean needsMoreHelp = true; 17 | 18 | public boolean needsMoreHelp() { 19 | return needsMoreHelp; 20 | } 21 | 22 | public void setNeedsMoreHelp(boolean needsMoreHelp) { 23 | this.needsMoreHelp = needsMoreHelp; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /scorekeeper/src/com/amazon/asksdk/scorekeeper/storage/ScoreKeeperDao.java: -------------------------------------------------------------------------------- 1 | package com.amazon.asksdk.scorekeeper.storage; 2 | 3 | import com.amazon.speech.speechlet.Session; 4 | 5 | /** 6 | * Contains the methods to interact with the persistence layer for ScoreKeeper in DynamoDB. 7 | */ 8 | public class ScoreKeeperDao { 9 | private final ScoreKeeperDynamoDbClient dynamoDbClient; 10 | 11 | public ScoreKeeperDao(ScoreKeeperDynamoDbClient dynamoDbClient) { 12 | this.dynamoDbClient = dynamoDbClient; 13 | } 14 | 15 | /** 16 | * Reads and returns the {@link ScoreKeeperGame} using user information from the session. 17 | *

18 | * Returns null if the item could not be found in the database. 19 | * 20 | * @param session 21 | * @return 22 | */ 23 | public ScoreKeeperGame getScoreKeeperGame(Session session) { 24 | ScoreKeeperUserDataItem item = new ScoreKeeperUserDataItem(); 25 | item.setCustomerId(session.getUser().getUserId()); 26 | 27 | item = dynamoDbClient.loadItem(item); 28 | 29 | if (item == null) { 30 | return null; 31 | } 32 | 33 | return ScoreKeeperGame.newInstance(session, item.getGameData()); 34 | } 35 | 36 | /** 37 | * Saves the {@link ScoreKeeperGame} into the database. 38 | * 39 | * @param game 40 | */ 41 | public void saveScoreKeeperGame(ScoreKeeperGame game) { 42 | ScoreKeeperUserDataItem item = new ScoreKeeperUserDataItem(); 43 | item.setCustomerId(game.getSession().getUser().getUserId()); 44 | item.setGameData(game.getGameData()); 45 | 46 | dynamoDbClient.saveItem(item); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /scorekeeper/src/com/amazon/asksdk/scorekeeper/storage/ScoreKeeperDynamoDbClient.java: -------------------------------------------------------------------------------- 1 | package com.amazon.asksdk.scorekeeper.storage; 2 | 3 | import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; 4 | import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper; 5 | 6 | /** 7 | * Client for DynamoDB persistance layer for the Score Keeper skill. 8 | */ 9 | public class ScoreKeeperDynamoDbClient { 10 | private final AmazonDynamoDBClient dynamoDBClient; 11 | 12 | public ScoreKeeperDynamoDbClient(final AmazonDynamoDBClient dynamoDBClient) { 13 | this.dynamoDBClient = dynamoDBClient; 14 | } 15 | 16 | /** 17 | * Loads an item from DynamoDB by primary Hash Key. Callers of this method should pass in an 18 | * object which represents an item in the DynamoDB table item with the primary key populated. 19 | * 20 | * @param tableItem 21 | * @return 22 | */ 23 | public ScoreKeeperUserDataItem loadItem(final ScoreKeeperUserDataItem tableItem) { 24 | DynamoDBMapper mapper = createDynamoDBMapper(); 25 | ScoreKeeperUserDataItem item = mapper.load(tableItem); 26 | return item; 27 | } 28 | 29 | /** 30 | * Stores an item to DynamoDB. 31 | * 32 | * @param tableItem 33 | */ 34 | public void saveItem(final ScoreKeeperUserDataItem tableItem) { 35 | DynamoDBMapper mapper = createDynamoDBMapper(); 36 | mapper.save(tableItem); 37 | } 38 | 39 | /** 40 | * Creates a {@link DynamoDBMapper} using the default configurations. 41 | * 42 | * @return 43 | */ 44 | private DynamoDBMapper createDynamoDBMapper() { 45 | return new DynamoDBMapper(dynamoDBClient); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /scorekeeper/src/com/amazon/asksdk/scorekeeper/storage/ScoreKeeperGameData.java: -------------------------------------------------------------------------------- 1 | package com.amazon.asksdk.scorekeeper.storage; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | /** 9 | * Contains player and score data to represent a score keeper game. 10 | */ 11 | public class ScoreKeeperGameData { 12 | private List players; 13 | private Map scores; 14 | 15 | public ScoreKeeperGameData() { 16 | // public no-arg constructor required for DynamoDBMapper marshalling 17 | } 18 | 19 | /** 20 | * Creates a new instance of {@link ScoreKeeperGameData} with initialized but empty player and 21 | * score information. 22 | * 23 | * @return 24 | */ 25 | public static ScoreKeeperGameData newInstance() { 26 | ScoreKeeperGameData newInstance = new ScoreKeeperGameData(); 27 | newInstance.setPlayers(new ArrayList()); 28 | newInstance.setScores(new HashMap()); 29 | return newInstance; 30 | } 31 | 32 | public List getPlayers() { 33 | return players; 34 | } 35 | 36 | public void setPlayers(List players) { 37 | this.players = players; 38 | } 39 | 40 | public Map getScores() { 41 | return scores; 42 | } 43 | 44 | public void setScores(Map scores) { 45 | this.scores = scores; 46 | } 47 | 48 | @Override 49 | public String toString() { 50 | return "[ScoreKeeperGameData players: " + players + "] scores: " + scores + "]"; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /scorekeeper/src/com/amazon/asksdk/scorekeeper/storage/ScoreKeeperUserDataItem.java: -------------------------------------------------------------------------------- 1 | package com.amazon.asksdk.scorekeeper.storage; 2 | 3 | import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAttribute; 4 | import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey; 5 | import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMarshaller; 6 | import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMarshalling; 7 | import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTable; 8 | import com.fasterxml.jackson.core.JsonProcessingException; 9 | import com.fasterxml.jackson.core.type.TypeReference; 10 | import com.fasterxml.jackson.databind.ObjectMapper; 11 | 12 | /** 13 | * Model representing an item of the ScoreKeeperUserData table in DynamoDB for the ScoreKeeper 14 | * skill. 15 | */ 16 | @DynamoDBTable(tableName = "ScoreKeeperUserData") 17 | public class ScoreKeeperUserDataItem { 18 | private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); 19 | 20 | private String customerId; 21 | 22 | private ScoreKeeperGameData gameData; 23 | 24 | @DynamoDBHashKey(attributeName = "CustomerId") 25 | public String getCustomerId() { 26 | return customerId; 27 | } 28 | 29 | public void setCustomerId(String customerId) { 30 | this.customerId = customerId; 31 | } 32 | 33 | @DynamoDBAttribute(attributeName = "Data") 34 | @DynamoDBMarshalling(marshallerClass = ScoreKeeperGameDataMarshaller.class) 35 | public ScoreKeeperGameData getGameData() { 36 | return gameData; 37 | } 38 | 39 | public void setGameData(ScoreKeeperGameData gameData) { 40 | this.gameData = gameData; 41 | } 42 | 43 | /** 44 | * A {@link DynamoDBMarshaller} that provides marshalling and unmarshalling logic for 45 | * {@link ScoreKeeperGameData} values so that they can be persisted in the database as String. 46 | */ 47 | public static class ScoreKeeperGameDataMarshaller implements 48 | DynamoDBMarshaller { 49 | 50 | @Override 51 | public String marshall(ScoreKeeperGameData gameData) { 52 | try { 53 | return OBJECT_MAPPER.writeValueAsString(gameData); 54 | } catch (JsonProcessingException e) { 55 | throw new IllegalStateException("Unable to marshall game data", e); 56 | } 57 | } 58 | 59 | @Override 60 | public ScoreKeeperGameData unmarshall(Class clazz, String value) { 61 | try { 62 | return OBJECT_MAPPER.readValue(value, new TypeReference() { 63 | }); 64 | } catch (Exception e) { 65 | throw new IllegalStateException("Unable to unmarshall game data value", e); 66 | } 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /scorekeeper/src/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log = . 2 | log4j.rootLogger = DEBUG, LAMBDA 3 | 4 | #Define the LAMBDA appender 5 | log4j.appender.LAMBDA=com.amazonaws.services.lambda.runtime.log4j.LambdaAppender 6 | log4j.appender.LAMBDA.layout=org.apache.log4j.PatternLayout 7 | log4j.appender.LAMBDA.layout.conversionPattern=%d{yyyy-MM-dd HH:mm:ss} <%X{AWSRequestId}> %-5p %c{1}:%L - %m%n 8 | -------------------------------------------------------------------------------- /session/README.md: -------------------------------------------------------------------------------- 1 | # Alexa Skills Kit SDK Sample - Session 2 | A simple [AWS Lambda](http://aws.amazon.com/lambda) function that demonstrates how to write a skill for the Amazon Echo using the Alexa SDK. 3 | 4 | ## Concepts 5 | This sample shows how to create a Lambda function for handling Alexa Skill requests that: 6 | 7 | - Custom slot type: demonstrates using custom slot types to handle a finite set of known values 8 | - Dialog and Session state: Handles two models, both a one-shot ask and tell model, and a multi-turn dialog model. 9 | 10 | ## Setup 11 | To run this example skill you need to do two things. The first is to deploy the example code in lambda, and the second is to configure the Alexa skill to use Lambda. 12 | 13 | ### AWS Lambda Setup 14 | 1. Go to the AWS Console and click on the Lambda link. Note: ensure you are in us-east or you wont be able to use Alexa with Lambda. 15 | 2. Click on the Create Function button. 16 | 3. Click Author from scratch. 17 | 4. In Configure triggers, add Alexa Skill kit as trigger. 18 | 5. Name the Lambda Function "Session-Example-Skill". 19 | 6. Select the runtime as Java 8. 20 | 7. Build a jar file to upload it into the lambda function. There are two ways: 21 | - Using maven: go to the directory containing pom.xml, and run 'mvn assembly:assembly -DdescriptorId=jar-with-dependencies package'. This will generate a zip file named "session-1.0-jar-with-dependencies.jar" in the target directory. 22 | - Using gradle: go to the directory containing build.gradle, and run 'gradle fatJar'. This will generate a zip file named "session-fat-1.0.jar" in the build/libs directory. 23 | 8. Select Code entry type as "Upload a .ZIP file" and then upload the jar file created in step 7 from the build directory to Lambda. 24 | 9. Set the Handler as com.amazon.asksdk.session.SessionSpeechletRequestStreamHandler (this refers to the Lambda RequestStreamHandler file in the zip). 25 | 10. Choose an existing role - lambda_basic_execution. 26 | 11. Increase the Timeout to 30 seconds under Basic Settings. 27 | 12. Leave the Advanced settings as the defaults. 28 | 13. Click "Next" and review the settings then click "Create Function". 29 | 14. Copy the ARN from the top right to be used later in the Alexa Skill Setup. 30 | 31 | ### Alexa Skill Setup 32 | 1. Go to the [Alexa Console](https://developer.amazon.com/edw/home.html) and click Add a New Skill. 33 | 2. Set "Session" as the skill name and "session" as the invocation name, this is what is used to activate your skill. For example you would say: "Alexa, tell session my color is green." 34 | 3. Select the Lambda ARN for the skill Endpoint and paste the ARN copied from above. Click Next. 35 | 4. Copy the contents of SpeechAssets. 36 | - If you are using the new Skill Builder, copy the Skill Builder from included SkillBuilder.json. 37 | - Otherwise, copy the Intent Schema from the included IntentSchema.json. Copy the Sample Utterances from the included SampleUtterances.txt. Copy the custom slot types from the customSlotTypes folder. Each file in the folder represents a new custom slot type. The name of the file is the name of the custom slot type, and the values in the file are the values for the custom slot. Click Next. 38 | 5. Go back to the skill Information tab and copy the appId. Paste the appId into the SessionWorldSpeechletRequestStreamHandler.java file for the variable supportedApplicationIds, 39 | then update the lambda source zip file with this change and upload to lambda again, this step makes sure the lambda function only serves request from authorized source. 40 | 6. You are now able to start testing your sample skill! You should be able to go to the [Echo webpage](http://echo.amazon.com/#skills) and see your skill enabled. 41 | 7. In order to test it, try to say some of the Sample Utterances from the Examples section below. 42 | 8. Your skill is now saved and once you are finished testing you can continue to publish your skill. 43 | 44 | ## Examples 45 | ### One-shot model: 46 | User: "Alexa, tell session my color is green." 47 | Alexa: "I now know that your favorite color is green..." 48 | -------------------------------------------------------------------------------- /session/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | 3 | group = "alexa-skills-kit-samples" 4 | version = '1.0' 5 | 6 | compileJava { 7 | targetCompatibility = JavaVersion.VERSION_1_8 8 | sourceCompatibility = JavaVersion.VERSION_1_8 9 | } 10 | 11 | jar { 12 | manifest { 13 | attributes 'Implementation-Title': 'Gradle Quickstart', 14 | 'Implementation-Version': version 15 | } 16 | } 17 | 18 | repositories { 19 | jcenter() 20 | mavenCentral() 21 | } 22 | 23 | sourceSets { 24 | main { 25 | java { 26 | srcDirs 'src' 27 | } 28 | resources { 29 | srcDirs 'src/resources' 30 | } 31 | } 32 | } 33 | 34 | dependencies { 35 | compile 'com.amazon.alexa:alexa-skills-kit:1.5.0' 36 | compile 'com.amazonaws:aws-lambda-java-core:1.0.0' 37 | compile 'com.amazonaws:aws-java-sdk-dynamodb:1.9.40' 38 | compile 'com.amazonaws:aws-lambda-java-log4j:1.0.0' 39 | 40 | compile 'log4j:log4j:1.2.17' 41 | compile 'org.apache.commons:commons-lang3:3.3.2' 42 | compile 'org.apache.directory.studio:org.apache.commons.io:2.4' 43 | compile 'org.eclipse.jetty:jetty-server:9.0.6.v20130930' 44 | compile 'org.eclipse.jetty:jetty-servlet:9.0.6.v20130930' 45 | compile 'org.slf4j:slf4j-api:1.7.10' 46 | } 47 | 48 | task fatJar(type: Jar) { 49 | baseName = project.name + '-fat' 50 | from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } 51 | with jar 52 | } 53 | 54 | build.dependsOn fatJar 55 | -------------------------------------------------------------------------------- /session/speechAssets/IntentSchema.json: -------------------------------------------------------------------------------- 1 | { 2 | "intents": [ 3 | { 4 | "intent": "MyColorIsIntent", 5 | "slots": [ 6 | { 7 | "name": "Color", 8 | "type": "LIST_OF_COLORS" 9 | } 10 | ] 11 | }, 12 | { 13 | "intent": "WhatsMyColorIntent" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /session/speechAssets/SampleUtterances.txt: -------------------------------------------------------------------------------- 1 | MyColorIsIntent my color is {Color} 2 | MyColorIsIntent my favorite color is {Color} 3 | WhatsMyColorIntent whats my color 4 | WhatsMyColorIntent what is my color 5 | WhatsMyColorIntent say my color 6 | WhatsMyColorIntent tell me my color 7 | WhatsMyColorIntent whats my favorite color 8 | WhatsMyColorIntent what is my favorite color 9 | WhatsMyColorIntent say my favorite color 10 | WhatsMyColorIntent tell me my favorite color 11 | WhatsMyColorIntent tell me what my favorite color is 12 | -------------------------------------------------------------------------------- /session/speechAssets/SkillBuilder.json: -------------------------------------------------------------------------------- 1 | { 2 | "languageModel": { 3 | "types": [ 4 | { 5 | "name": "LIST_OF_COLORS", 6 | "values": [ 7 | { 8 | "id": null, 9 | "name": { 10 | "value": "green", 11 | "synonyms": [] 12 | } 13 | }, 14 | { 15 | "id": null, 16 | "name": { 17 | "value": "blue", 18 | "synonyms": [] 19 | } 20 | }, 21 | { 22 | "id": null, 23 | "name": { 24 | "value": "purple", 25 | "synonyms": [] 26 | } 27 | }, 28 | { 29 | "id": null, 30 | "name": { 31 | "value": "red", 32 | "synonyms": [] 33 | } 34 | }, 35 | { 36 | "id": null, 37 | "name": { 38 | "value": "orange", 39 | "synonyms": [] 40 | } 41 | }, 42 | { 43 | "id": null, 44 | "name": { 45 | "value": "yellow", 46 | "synonyms": [] 47 | } 48 | } 49 | ] 50 | } 51 | ], 52 | "intents": [ 53 | { 54 | "name": "AMAZON.CancelIntent", 55 | "samples": [] 56 | }, 57 | { 58 | "name": "AMAZON.HelpIntent", 59 | "samples": [] 60 | }, 61 | { 62 | "name": "AMAZON.StopIntent", 63 | "samples": [] 64 | }, 65 | { 66 | "name": "MyColorIsIntent", 67 | "samples": [ 68 | " my color is {Color}", 69 | " my favorite color is {Color}" 70 | ], 71 | "slots": [ 72 | { 73 | "name": "Color", 74 | "type": "LIST_OF_COLORS" 75 | } 76 | ] 77 | }, 78 | { 79 | "name": "WhatsMyColorIntent", 80 | "samples": [ 81 | "whats my color", 82 | "what is my color", 83 | "say my color", 84 | "tell me my color", 85 | "whats my favorite color", 86 | "what is my favorite color", 87 | "say my favorite color", 88 | "tell me my favorite color", 89 | "tell me what my favorite color is" 90 | ], 91 | "slots": [] 92 | } 93 | ], 94 | "invocationName": "session" 95 | } 96 | } -------------------------------------------------------------------------------- /session/speechAssets/customSlotTypes/LIST_OF_COLORS: -------------------------------------------------------------------------------- 1 | green 2 | blue 3 | purple 4 | red 5 | orange 6 | yellow -------------------------------------------------------------------------------- /session/src/com/amazon/asksdk/session/SessionSpeechletRequestStreamHandler.java: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2014-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at 5 | 6 | http://aws.amazon.com/apache2.0/ 7 | 8 | or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 9 | */ 10 | package com.amazon.asksdk.session; 11 | 12 | import java.util.HashSet; 13 | import java.util.Set; 14 | 15 | import com.amazon.speech.speechlet.lambda.SpeechletRequestStreamHandler; 16 | 17 | /** 18 | * This class could be the handler for an AWS Lambda function powering an Alexa Skills Kit 19 | * experience. To do this, simply set the handler field in the AWS Lambda console to 20 | * "session.SessionWorldSpeechletRequestStreamHandler" For this to work, you'll also need to build 21 | * this project using the {@code lambda-compile} Ant task and upload the resulting zip file to power 22 | * your function. 23 | */ 24 | public class SessionSpeechletRequestStreamHandler extends SpeechletRequestStreamHandler { 25 | private static final Set supportedApplicationIds; 26 | 27 | static { 28 | /* 29 | * This Id can be found on https://developer.amazon.com/edw/home.html#/ "Edit" the relevant 30 | * Alexa Skill and put the relevant Application Ids in this Set. 31 | */ 32 | supportedApplicationIds = new HashSet(); 33 | // supportedApplicationIds.add("[unique-value-here]"); 34 | } 35 | 36 | public SessionSpeechletRequestStreamHandler() { 37 | super(new SessionSpeechlet(), supportedApplicationIds); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /session/src/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log = . 2 | log4j.rootLogger = DEBUG, LAMBDA 3 | 4 | #Define the LAMBDA appender 5 | log4j.appender.LAMBDA=com.amazonaws.services.lambda.runtime.log4j.LambdaAppender 6 | log4j.appender.LAMBDA.layout=org.apache.log4j.PatternLayout 7 | log4j.appender.LAMBDA.layout.conversionPattern=%d{yyyy-MM-dd HH:mm:ss} <%X{AWSRequestId}> %-5p %c{1}:%L - %m%n 8 | -------------------------------------------------------------------------------- /spacegeek/README.md: -------------------------------------------------------------------------------- 1 | # Alexa Skills Kit SDK Sample - Space Geek 2 | A simple [AWS Lambda](http://aws.amazon.com/lambda) function that demonstrates how to write a skill for the Amazon Echo using the Alexa SDK. 3 | 4 | ## Concepts 5 | This simple sample has no external dependencies or session management, and shows the most basic example of how to create a Lambda function for handling Alexa Skill requests. 6 | 7 | ## Setup 8 | To run this example skill you need to do two things. The first is to deploy the example code in lambda, and the second is to configure the Alexa skill to use Lambda. 9 | 10 | ### AWS Lambda Setup 11 | 1. Go to the AWS Console and click on the Lambda link. Note: ensure you are in us-east or you wont be able to use Alexa with Lambda. 12 | 2. Click on the Create Function button. 13 | 3. Click Author from scratch. 14 | 4. In Configure triggers, add Alexa Skill kit as trigger. 15 | 5. Name the Lambda Function "Space-Geek-Example-Skill". 16 | 6. Select the runtime as Java 8. 17 | 7. Build a jar file to upload it into the lambda function. There are two ways: 18 | - Using maven: go to the directory containing pom.xml, and run 'mvn assembly:assembly -DdescriptorId=jar-with-dependencies package'. This will generate a zip file named "spacegeek-1.0-jar-with-dependencies.jar" in the target directory. 19 | - Using gradle: go to the directory containing build.gradle, and run 'gradle fatJar'. This will generate a zip file named "spacegeek-fat-1.0.jar" in the build/libs directory. 20 | 8. Select Code entry type as "Upload a .ZIP file" and then upload the jar file created in step 7 from the build directory to Lambda. 21 | 9. Set the Handler as com.amazon.asksdk.spacegeek.SpaceGeekSpeechletRequestStreamHandler (this refers to the Lambda RequestStreamHandler file in the zip). 22 | 10. Choose an existing role - lambda_basic_execution. 23 | 11. Increase the Timeout to 30 seconds under Basic Settings. 24 | 12. Leave the Advanced settings as the defaults. 25 | 13. Click "Next" and review the settings then click "Create Function". 26 | 14. Copy the ARN from the top right to be used later in the Alexa Skill Setup. 27 | 28 | ### Alexa Skill Setup 29 | 1. Go to the [Alexa Console](https://developer.amazon.com/edw/home.html) and click Add a New Skill. 30 | 2. Set "SpaceGeek" as the skill name and "space geek" as the invocation name, this is what is used to activate your skill. For example you would say: "Alexa, ask Space Geek for a space fact." 31 | 3. Select the Lambda ARN for the skill Endpoint and paste the ARN copied from above. Click Next. 32 | 4. Copy the contents of SpeechAssets. 33 | - If you are using the new Skill Builder, copy the Skill Builder from included SkillBuilder.json. 34 | - Otherwise, copy the Intent Schema from the included IntentSchema.json. Copy the Sample Utterances from the included SampleUtterances.txt. Click Next. 35 | 5. Go back to the skill Information tab and copy the appId. Paste the appId into the SpaceGeekSpeechletRequestStreamHandler.java file for the variable supportedApplicationIds, 36 | then update the lambda source zip file with this change and upload to lambda again, this step makes sure the lambda function only serves request from authorized source. 37 | 6. You are now able to start testing your sample skill! You should be able to go to the [Echo webpage](http://echo.amazon.com/#skills) and see your skill enabled. 38 | 7. In order to test it, try to say some of the Sample Utterances from the Examples section below. 39 | 8. Your skill is now saved and once you are finished testing you can continue to publish your skill. 40 | 41 | ## Examples 42 | ### One-shot model: 43 | User: "Alexa, ask Space Geek for a space fact." 44 | Alexa: "Here's your space fact: ..." 45 | -------------------------------------------------------------------------------- /spacegeek/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | 3 | group = "alexa-skills-kit-samples" 4 | version = '1.0' 5 | 6 | compileJava { 7 | targetCompatibility = JavaVersion.VERSION_1_8 8 | sourceCompatibility = JavaVersion.VERSION_1_8 9 | } 10 | 11 | jar { 12 | manifest { 13 | attributes 'Implementation-Title': 'Gradle Quickstart', 14 | 'Implementation-Version': version 15 | } 16 | } 17 | 18 | repositories { 19 | jcenter() 20 | mavenCentral() 21 | } 22 | 23 | sourceSets { 24 | main { 25 | java { 26 | srcDirs 'src' 27 | } 28 | resources { 29 | srcDirs 'src/resources' 30 | } 31 | } 32 | } 33 | 34 | dependencies { 35 | compile 'com.amazon.alexa:alexa-skills-kit:1.5.0' 36 | compile 'com.amazonaws:aws-lambda-java-core:1.0.0' 37 | compile 'com.amazonaws:aws-java-sdk-dynamodb:1.9.40' 38 | compile 'com.amazonaws:aws-lambda-java-log4j:1.0.0' 39 | 40 | compile 'log4j:log4j:1.2.17' 41 | compile 'org.apache.commons:commons-lang3:3.3.2' 42 | compile 'org.apache.directory.studio:org.apache.commons.io:2.4' 43 | compile 'org.eclipse.jetty:jetty-server:9.0.6.v20130930' 44 | compile 'org.eclipse.jetty:jetty-servlet:9.0.6.v20130930' 45 | compile 'org.slf4j:slf4j-api:1.7.10' 46 | } 47 | 48 | task fatJar(type: Jar) { 49 | baseName = project.name + '-fat' 50 | from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } 51 | with jar 52 | } 53 | 54 | build.dependsOn fatJar 55 | -------------------------------------------------------------------------------- /spacegeek/speechAssets/IntentSchema.json: -------------------------------------------------------------------------------- 1 | { 2 | "intents": [ 3 | { 4 | "intent": "GetNewFactIntent" 5 | }, 6 | { 7 | "intent": "AMAZON.HelpIntent" 8 | }, 9 | { 10 | "intent": "AMAZON.StopIntent" 11 | }, 12 | { 13 | "intent": "AMAZON.CancelIntent" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /spacegeek/speechAssets/SampleUtterances.txt: -------------------------------------------------------------------------------- 1 | GetNewFactIntent a fact 2 | GetNewFactIntent a space fact 3 | GetNewFactIntent tell me a fact 4 | GetNewFactIntent tell me a space fact 5 | GetNewFactIntent give me a fact 6 | GetNewFactIntent give me a space fact 7 | GetNewFactIntent tell me trivia 8 | GetNewFactIntent tell me a space trivia 9 | GetNewFactIntent give me trivia 10 | GetNewFactIntent give me a space trivia 11 | GetNewFactIntent give me some information 12 | GetNewFactIntent give me some space information 13 | GetNewFactIntent tell me something 14 | GetNewFactIntent give me something 15 | -------------------------------------------------------------------------------- /spacegeek/speechAssets/SkillBuilder.json: -------------------------------------------------------------------------------- 1 | { 2 | "languageModel": { 3 | "intents": [ 4 | { 5 | "name": "AMAZON.CancelIntent", 6 | "samples": [] 7 | }, 8 | { 9 | "name": "AMAZON.HelpIntent", 10 | "samples": [] 11 | }, 12 | { 13 | "name": "AMAZON.StopIntent", 14 | "samples": [] 15 | }, 16 | { 17 | "name": "GetNewFactIntent", 18 | "samples": [ 19 | "a fact", 20 | "a space fact", 21 | "tell me a fact", 22 | "tell me a space fact", 23 | "give me a fact", 24 | "give me a space fact", 25 | "tell me trivia", 26 | "tell me a space trivia", 27 | "give me trivia", 28 | "give me a space trivia", 29 | "give me some information", 30 | "give me some space information", 31 | "tell me something", 32 | "give me something" 33 | ], 34 | "slots": [] 35 | } 36 | ], 37 | "invocationName": "space geek" 38 | } 39 | } -------------------------------------------------------------------------------- /spacegeek/src/com/amazon/asksdk/spacegeek/SpaceGeekSpeechletRequestStreamHandler.java: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2014-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at 5 | 6 | http://aws.amazon.com/apache2.0/ 7 | 8 | or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 9 | */ 10 | package com.amazon.asksdk.spacegeek; 11 | 12 | import java.util.HashSet; 13 | import java.util.Set; 14 | 15 | import com.amazon.speech.speechlet.lambda.SpeechletRequestStreamHandler; 16 | 17 | /** 18 | * This class could be the handler for an AWS Lambda function powering an Alexa Skills Kit 19 | * experience. To do this, simply set the handler field in the AWS Lambda console to 20 | * "SpaceGeekSpeechletRequestStreamHandler" For this to work, you'll also need to build 21 | * this project using the {@code lambda-compile} Ant task and upload the resulting zip file to power 22 | * your function. 23 | */ 24 | public final class SpaceGeekSpeechletRequestStreamHandler extends SpeechletRequestStreamHandler { 25 | private static final Set supportedApplicationIds; 26 | 27 | static { 28 | /* 29 | * This Id can be found on https://developer.amazon.com/edw/home.html#/ "Edit" the relevant 30 | * Alexa Skill and put the relevant Application Ids in this Set. 31 | */ 32 | supportedApplicationIds = new HashSet(); 33 | // supportedApplicationIds.add("[unique-value-here]"); 34 | } 35 | 36 | public SpaceGeekSpeechletRequestStreamHandler() { 37 | super(new SpaceGeekSpeechlet(), supportedApplicationIds); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /spacegeek/src/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log = . 2 | log4j.rootLogger = DEBUG, LAMBDA 3 | 4 | #Define the LAMBDA appender 5 | log4j.appender.LAMBDA=com.amazonaws.services.lambda.runtime.log4j.LambdaAppender 6 | log4j.appender.LAMBDA.layout=org.apache.log4j.PatternLayout 7 | log4j.appender.LAMBDA.layout.conversionPattern=%d{yyyy-MM-dd HH:mm:ss} <%X{AWSRequestId}> %-5p %c{1}:%L - %m%n 8 | -------------------------------------------------------------------------------- /tidepooler/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | 3 | group = "alexa-skills-kit-samples" 4 | version = '1.0' 5 | 6 | compileJava { 7 | targetCompatibility = JavaVersion.VERSION_1_8 8 | sourceCompatibility = JavaVersion.VERSION_1_8 9 | } 10 | 11 | jar { 12 | manifest { 13 | attributes 'Implementation-Title': 'Gradle Quickstart', 14 | 'Implementation-Version': version 15 | } 16 | } 17 | 18 | repositories { 19 | jcenter() 20 | mavenCentral() 21 | } 22 | 23 | sourceSets { 24 | main { 25 | java { 26 | srcDirs 'src' 27 | } 28 | resources { 29 | srcDirs 'src/resources' 30 | } 31 | } 32 | } 33 | 34 | dependencies { 35 | compile 'com.amazon.alexa:alexa-skills-kit:1.5.0' 36 | compile 'com.amazonaws:aws-lambda-java-core:1.0.0' 37 | compile 'com.amazonaws:aws-java-sdk-dynamodb:1.9.40' 38 | compile 'com.amazonaws:aws-lambda-java-log4j:1.0.0' 39 | 40 | compile 'log4j:log4j:1.2.17' 41 | compile 'org.apache.commons:commons-lang3:3.3.2' 42 | compile 'org.apache.directory.studio:org.apache.commons.io:2.4' 43 | compile 'org.eclipse.jetty:jetty-server:9.0.6.v20130930' 44 | compile 'org.eclipse.jetty:jetty-servlet:9.0.6.v20130930' 45 | compile 'org.slf4j:slf4j-api:1.7.10' 46 | } 47 | 48 | task fatJar(type: Jar) { 49 | baseName = project.name + '-fat' 50 | from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } 51 | with jar 52 | } 53 | 54 | build.dependsOn fatJar 55 | -------------------------------------------------------------------------------- /tidepooler/speechAssets/IntentSchema.json: -------------------------------------------------------------------------------- 1 | { 2 | "intents": [ 3 | { 4 | "intent": "OneshotTideIntent", 5 | "slots": [ 6 | { 7 | "name": "City", 8 | "type": "LIST_OF_CITIES" 9 | }, 10 | { 11 | "name": "State", 12 | "type": "LIST_OF_STATES" 13 | }, 14 | { 15 | "name": "Date", 16 | "type": "AMAZON.DATE" 17 | } 18 | ] 19 | }, 20 | { 21 | "intent": "DialogTideIntent", 22 | "slots": [ 23 | { 24 | "name": "City", 25 | "type": "LIST_OF_CITIES" 26 | }, 27 | { 28 | "name": "State", 29 | "type": "LIST_OF_STATES" 30 | }, 31 | { 32 | "name": "Date", 33 | "type": "AMAZON.DATE" 34 | } 35 | ] 36 | }, 37 | { 38 | "intent": "SupportedCitiesIntent" 39 | }, 40 | { 41 | "intent": "AMAZON.HelpIntent" 42 | }, 43 | { 44 | "intent": "AMAZON.StopIntent" 45 | }, 46 | { 47 | "intent": "AMAZON.CancelIntent" 48 | } 49 | ] 50 | } 51 | -------------------------------------------------------------------------------- /tidepooler/speechAssets/customSlotTypes/LIST_OF_CITIES: -------------------------------------------------------------------------------- 1 | seattle 2 | los angeles 3 | monterey 4 | san diego 5 | san francisco 6 | boston 7 | new york 8 | miami 9 | wilmington 10 | tampa 11 | galveston 12 | morehead 13 | new orleans 14 | beaufort 15 | myrtle beach 16 | virginia beach 17 | charleston -------------------------------------------------------------------------------- /tidepooler/speechAssets/customSlotTypes/LIST_OF_STATES: -------------------------------------------------------------------------------- 1 | california 2 | florida 3 | louisiana 4 | massachusetts 5 | new york 6 | north carolina 7 | south carolina 8 | texas 9 | virginia 10 | washington -------------------------------------------------------------------------------- /tidepooler/src/com/amazon/asksdk/tidepooler/TidePoolerSpeechletRequestStreamHandler.java: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2014-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at 5 | 6 | http://aws.amazon.com/apache2.0/ 7 | 8 | or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 9 | */ 10 | package com.amazon.asksdk.tidepooler; 11 | 12 | import java.util.HashSet; 13 | import java.util.Set; 14 | 15 | import com.amazon.speech.speechlet.Speechlet; 16 | import com.amazon.speech.speechlet.lambda.SpeechletRequestStreamHandler; 17 | 18 | /** 19 | * This class could be the handler for an AWS Lambda function powering an Alexa Skills Kit 20 | * experience. To do this, simply set the handler field in the AWS Lambda console to 21 | * "TidePoolerSpeechletRequestStreamHandler" For this to work, you'll also need to build 22 | * this project using the {@code lambda-compile} Ant task and upload the resulting zip file to power 23 | * your function. 24 | */ 25 | public class TidePoolerSpeechletRequestStreamHandler extends SpeechletRequestStreamHandler { 26 | 27 | private static final Set supportedApplicationIds; 28 | 29 | static { 30 | /* 31 | * This Id can be found on https://developer.amazon.com/edw/home.html#/ "Edit" the relevant 32 | * Alexa Skill and put the relevant Application Ids in this Set. 33 | */ 34 | supportedApplicationIds = new HashSet(); 35 | // supportedApplicationIds.add("[unique-value-here]"); 36 | } 37 | 38 | public TidePoolerSpeechletRequestStreamHandler() { 39 | super(new TidePoolerSpeechlet(), supportedApplicationIds); 40 | } 41 | 42 | public TidePoolerSpeechletRequestStreamHandler(Speechlet speechlet, 43 | Set supportedApplicationIds) { 44 | super(speechlet, supportedApplicationIds); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /tidepooler/src/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log = . 2 | log4j.rootLogger = DEBUG, LAMBDA 3 | 4 | #Define the LAMBDA appender 5 | log4j.appender.LAMBDA=com.amazonaws.services.lambda.runtime.log4j.LambdaAppender 6 | log4j.appender.LAMBDA.layout=org.apache.log4j.PatternLayout 7 | log4j.appender.LAMBDA.layout.conversionPattern=%d{yyyy-MM-dd HH:mm:ss} <%X{AWSRequestId}> %-5p %c{1}:%L - %m%n 8 | -------------------------------------------------------------------------------- /wiseguy/README.md: -------------------------------------------------------------------------------- 1 | # Alexa Skills Kit SDK Sample - Wise Guy 2 | A simple [AWS Lambda](http://aws.amazon.com/lambda) function that demonstrates how to write a skill for the Amazon Echo using the Alexa SDK. 3 | 4 | ## Concepts 5 | This sample shows how to create a Lambda function for handling Alexa Skill requests that: 6 | 7 | - Session State: Handles a multi-turn dialog model. 8 | - Custom slot type: demonstrates using custom slot types to handle a finite set of known values 9 | - SSML: Using SSML tags to control how Alexa renders the text-to-speech. 10 | 11 | ## Setup 12 | To run this example skill you need to do two things. The first is to deploy the example code in lambda, and the second is to configure the Alexa skill to use Lambda. 13 | 14 | ### AWS Lambda Setup 15 | 1. Go to the AWS Console and click on the Lambda link. Note: ensure you are in us-east or you wont be able to use Alexa with Lambda. 16 | 2. Click on the Create Function button. 17 | 3. Click Author from scratch. 18 | 4. In Configure triggers, add Alexa Skill kit as trigger. 19 | 5. Name the Lambda Function "WiseGuy-Example-Skill". 20 | 6. Select the runtime as Java 8 21 | 7. Build a jar file to upload it into the lambda function. There are two ways: 22 | - Using maven: go to the directory containing pom.xml, and run 'mvn assembly:assembly -DdescriptorId=jar-with-dependencies package'. This will generate a zip file named "wiseguy-1.0-jar-with-dependencies.jar" in the target directory. 23 | - Using gradle: go to the directory containing build.gradle, and run 'gradle fatJar'. This will generate a zip file named "wiseguy-fat-1.0.jar" in the build/libs directory. 24 | 9. Set the Handler as com.amazon.asksdk.wiseguy.WiseGuySpeechletRequestStreamHandler (this refers to the Lambda RequestStreamHandler file in the zip). 25 | 10. Choose an existing role - lambda_basic_execution. 26 | 11. Increase the Timeout to 30 seconds under Basic Settings. 27 | 12. Leave the Advanced settings as the defaults. 28 | 13. Click "Next" and review the settings then click "Create Function". 29 | 14. Copy the ARN from the top right to be used later in the Alexa Skill Setup. 30 | 31 | ### Alexa Skill Setup 32 | 1. Go to the [Alexa Console](https://developer.amazon.com/edw/home.html) and click Add a New Skill. 33 | 2. Set "WiseGuy" as the skill name and "wise guy" as the invocation name, this is what is used to activate your skill. For example you would say: "Alexa, Ask wise guy for a joke." 34 | 3. Select the Lambda ARN for the skill Endpoint and paste the ARN copied from above. Click Next. 35 | 4. Copy the contents of SpeechAssets. 36 | - If you are using the new Skill Builder, copy the Skill Builder from included SkillBuilder.json. 37 | - Otherwise, copy the Intent Schema from the included IntentSchema.json. Copy the Sample Utterances from the included SampleUtterances.txt. Copy the custom slot types from the customSlotTypes folder. Each file in the folder represents a new custom slot type. The name of the file is the name of the custom slot type, and the values in the file are the values for the custom slot. Click Next. 38 | 5. Go back to the skill Information tab and copy the appId. Paste the appId into the WiseGuySpeechletRequestStreamHandler.java file for the variable supportedApplicationIds, 39 | then update the lambda source zip file with this change and upload to lambda again, this step makes sure the lambda function only serves request from authorized source. 40 | 6. You are now able to start testing your sample skill! You should be able to go to the [Echo webpage](http://echo.amazon.com/#skills) and see your skill enabled. 41 | 7. In order to test it, try to say some of the Sample Utterances from the Examples section below. 42 | 8. Your skill is now saved and once you are finished testing you can continue to publish your skill. 43 | 44 | ## Examples 45 | ### Dialog model: 46 | User: "Alexa, ask Wise Guy to tell me a knock knock joke." 47 | Alexa: "Knock knock" 48 | User: "Who's there?" 49 | Alexa: "" 50 | User: " who" 51 | Alexa: "" 52 | -------------------------------------------------------------------------------- /wiseguy/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | 3 | group = "alexa-skills-kit-samples" 4 | version = '1.0' 5 | 6 | compileJava { 7 | targetCompatibility = JavaVersion.VERSION_1_8 8 | sourceCompatibility = JavaVersion.VERSION_1_8 9 | } 10 | 11 | jar { 12 | manifest { 13 | attributes 'Implementation-Title': 'Gradle Quickstart', 14 | 'Implementation-Version': version 15 | } 16 | } 17 | 18 | repositories { 19 | jcenter() 20 | mavenCentral() 21 | } 22 | 23 | sourceSets { 24 | main { 25 | java { 26 | srcDirs 'src' 27 | } 28 | resources { 29 | srcDirs 'src/resources' 30 | } 31 | } 32 | } 33 | 34 | dependencies { 35 | compile 'com.amazon.alexa:alexa-skills-kit:1.5.0' 36 | compile 'com.amazonaws:aws-lambda-java-core:1.0.0' 37 | compile 'com.amazonaws:aws-java-sdk-dynamodb:1.9.40' 38 | compile 'com.amazonaws:aws-lambda-java-log4j:1.0.0' 39 | 40 | compile 'log4j:log4j:1.2.17' 41 | compile 'org.apache.commons:commons-lang3:3.3.2' 42 | compile 'org.apache.directory.studio:org.apache.commons.io:2.4' 43 | compile 'org.eclipse.jetty:jetty-server:9.0.6.v20130930' 44 | compile 'org.eclipse.jetty:jetty-servlet:9.0.6.v20130930' 45 | compile 'org.slf4j:slf4j-api:1.7.10' 46 | } 47 | 48 | task fatJar(type: Jar) { 49 | baseName = project.name + '-fat' 50 | from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } 51 | with jar 52 | } 53 | 54 | build.dependsOn fatJar 55 | -------------------------------------------------------------------------------- /wiseguy/speechAssets/IntentSchema.json: -------------------------------------------------------------------------------- 1 | { 2 | "intents": [ 3 | { 4 | "intent": "TellMeAJokeIntent" 5 | }, 6 | { 7 | "intent": "WhosThereIntent" 8 | }, 9 | { 10 | "intent": "SetupNameWhoIntent", 11 | "slots":[ 12 | { 13 | "name": "SetupName", 14 | "type": "LIST_OF_SETUP_NAMES" 15 | } 16 | ] 17 | }, 18 | { 19 | "intent": "AMAZON.HelpIntent" 20 | }, 21 | { 22 | "intent": "AMAZON.StopIntent" 23 | }, 24 | { 25 | "intent": "AMAZON.CancelIntent" 26 | } 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /wiseguy/speechAssets/SampleUtterances.txt: -------------------------------------------------------------------------------- 1 | TellMeAJokeIntent tell me a joke 2 | TellMeAJokeIntent tell a joke 3 | TellMeAJokeIntent say a joke 4 | TellMeAJokeIntent make a joke 5 | TellMeAJokeIntent give me a joke 6 | TellMeAJokeIntent tell me a knock knock joke 7 | TellMeAJokeIntent tell a knock knock joke 8 | TellMeAJokeIntent say a knock knock joke 9 | TellMeAJokeIntent make a knock knock joke 10 | TellMeAJokeIntent give me a knock knock joke 11 | TellMeAJokeIntent a joke 12 | TellMeAJokeIntent a knock knock joke 13 | TellMeAJokeIntent the joke 14 | TellMeAJokeIntent the knock knock joke 15 | TellMeAJokeIntent what's a joke 16 | TellMeAJokeIntent what is a joke 17 | TellMeAJokeIntent if it can tell me a joke 18 | TellMeAJokeIntent will it tell me a joke 19 | TellMeAJokeIntent can it tell me a joke 20 | TellMeAJokeIntent to tell me a joke 21 | TellMeAJokeIntent what's a knock knock joke 22 | TellMeAJokeIntent what is a knock knock joke 23 | TellMeAJokeIntent if it can tell me a knock knock joke 24 | TellMeAJokeIntent will it tell me a knock knock joke 25 | TellMeAJokeIntent can it tell me a knock knock joke 26 | TellMeAJokeIntent to tell me a knock knock joke 27 | 28 | WhosThereIntent who is there 29 | WhosThereIntent who's there 30 | WhosThereIntent who there 31 | WhosThereIntent who is this 32 | WhosThereIntent who's this 33 | 34 | SetupNameWhoIntent {SetupName} who -------------------------------------------------------------------------------- /wiseguy/speechAssets/SkillBuilder.json: -------------------------------------------------------------------------------- 1 | { 2 | "languageModel": { 3 | "types": [ 4 | { 5 | "name": "LIST_OF_SETUP_NAMES", 6 | "values": [ 7 | { 8 | "id": null, 9 | "name": { 10 | "value": "to", 11 | "synonyms": [] 12 | } 13 | }, 14 | { 15 | "id": null, 16 | "name": { 17 | "value": "beets", 18 | "synonyms": [] 19 | } 20 | }, 21 | { 22 | "id": null, 23 | "name": { 24 | "value": "little Old Lady", 25 | "synonyms": [] 26 | } 27 | }, 28 | { 29 | "id": null, 30 | "name": { 31 | "value": "a broken pencil", 32 | "synonyms": [] 33 | } 34 | }, 35 | { 36 | "id": null, 37 | "name": { 38 | "value": "snow", 39 | "synonyms": [] 40 | } 41 | }, 42 | { 43 | "id": null, 44 | "name": { 45 | "value": "boo", 46 | "synonyms": [] 47 | } 48 | }, 49 | { 50 | "id": null, 51 | "name": { 52 | "value": "woo", 53 | "synonyms": [] 54 | } 55 | }, 56 | { 57 | "id": null, 58 | "name": { 59 | "value": "spell", 60 | "synonyms": [] 61 | } 62 | }, 63 | { 64 | "id": null, 65 | "name": { 66 | "value": "atch", 67 | "synonyms": [] 68 | } 69 | }, 70 | { 71 | "id": null, 72 | "name": { 73 | "value": "owls", 74 | "synonyms": [] 75 | } 76 | }, 77 | { 78 | "id": null, 79 | "name": { 80 | "value": "berry", 81 | "synonyms": [] 82 | } 83 | } 84 | ] 85 | } 86 | ], 87 | "intents": [ 88 | { 89 | "name": "AMAZON.CancelIntent", 90 | "samples": [] 91 | }, 92 | { 93 | "name": "AMAZON.HelpIntent", 94 | "samples": [] 95 | }, 96 | { 97 | "name": "AMAZON.StopIntent", 98 | "samples": [] 99 | }, 100 | { 101 | "name": "SetupNameWhoIntent", 102 | "samples": [ 103 | "{SetupName} who" 104 | ], 105 | "slots": [ 106 | { 107 | "name": "SetupName", 108 | "type": "LIST_OF_SETUP_NAMES" 109 | } 110 | ] 111 | }, 112 | { 113 | "name": "TellMeAJokeIntent", 114 | "samples": [ 115 | "tell me a joke", 116 | "tell a joke", 117 | "say a joke", 118 | "make a joke", 119 | "give me a joke", 120 | "tell me a knock knock joke", 121 | "tell a knock knock joke", 122 | "say a knock knock joke", 123 | "make a knock knock joke", 124 | "give me a knock knock joke", 125 | "a joke", 126 | "a knock knock joke", 127 | "the joke", 128 | "the knock knock joke", 129 | "what's a joke", 130 | "what is a joke", 131 | "if it can tell me a joke", 132 | "will it tell me a joke", 133 | "can it tell me a joke", 134 | "to tell me a joke", 135 | "what's a knock knock joke", 136 | "what is a knock knock joke", 137 | "if it can tell me a knock knock joke", 138 | "will it tell me a knock knock joke", 139 | "can it tell me a knock knock joke", 140 | "to tell me a knock knock joke" 141 | ], 142 | "slots": [] 143 | }, 144 | { 145 | "name": "WhosThereIntent", 146 | "samples": [ 147 | "who is there", 148 | "who's there", 149 | "who there", 150 | "who is this", 151 | "who's this" 152 | ], 153 | "slots": [] 154 | } 155 | ], 156 | "invocationName": "wise guy" 157 | } 158 | } -------------------------------------------------------------------------------- /wiseguy/speechAssets/customSlotTypes/LIST_OF_SETUP_NAMES: -------------------------------------------------------------------------------- 1 | to 2 | beets 3 | little Old Lady 4 | a broken pencil 5 | snow 6 | boo 7 | woo 8 | spell 9 | atch 10 | owls 11 | berry -------------------------------------------------------------------------------- /wiseguy/src/com/amazon/asksdk/wiseguy/WiseGuySpeechletRequestStreamHandler.java: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2014-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at 5 | 6 | http://aws.amazon.com/apache2.0/ 7 | 8 | or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 9 | */ 10 | package com.amazon.asksdk.wiseguy; 11 | 12 | import java.util.HashSet; 13 | import java.util.Set; 14 | 15 | import com.amazon.speech.speechlet.Speechlet; 16 | import com.amazon.speech.speechlet.lambda.SpeechletRequestStreamHandler; 17 | 18 | /** 19 | * This class could be the handler for an AWS Lambda function powering an Alexa Skills Kit 20 | * experience. To do this, simply set the handler field in the AWS Lambda console to 21 | * "WiseGuySpeechletRequestStreamHandler" For this to work, you'll also need to build this 22 | * project using the {@code lambda-compile} Ant task and upload the resulting zip file to power your 23 | * function. 24 | */ 25 | public class WiseGuySpeechletRequestStreamHandler extends SpeechletRequestStreamHandler { 26 | 27 | private static final Set supportedApplicationIds; 28 | 29 | static { 30 | /* 31 | * This Id can be found on https://developer.amazon.com/edw/home.html#/ "Edit" the relevant 32 | * Alexa Skill and put the relevant Application Ids in this Set. 33 | */ 34 | supportedApplicationIds = new HashSet(); 35 | // supportedApplicationIds.add("[unique-value-here]"); 36 | } 37 | 38 | public WiseGuySpeechletRequestStreamHandler() { 39 | super(new WiseGuySpeechlet(), supportedApplicationIds); 40 | } 41 | 42 | public WiseGuySpeechletRequestStreamHandler(Speechlet speechlet, 43 | Set supportedApplicationIds) { 44 | super(speechlet, supportedApplicationIds); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /wiseguy/src/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log = . 2 | log4j.rootLogger = DEBUG, LAMBDA 3 | 4 | #Define the LAMBDA appender 5 | log4j.appender.LAMBDA=com.amazonaws.services.lambda.runtime.log4j.LambdaAppender 6 | log4j.appender.LAMBDA.layout=org.apache.log4j.PatternLayout 7 | log4j.appender.LAMBDA.layout.conversionPattern=%d{yyyy-MM-dd HH:mm:ss} <%X{AWSRequestId}> %-5p %c{1}:%L - %m%n 8 | --------------------------------------------------------------------------------