From 92b75ff9f4ea45b0b4f1277b1268b3dc5d6c7bae Mon Sep 17 00:00:00 2001 From: Duran Date: Wed, 5 Apr 2017 00:41:09 -0700 Subject: [PATCH] Committing in sample NodeJS skill that uses the Alexa Device Address API --- LICENSE.txt | 26 ++++ README.md | 42 ++++++ index.js | 11 ++ package.json | 23 +++ speechAssets/IntentSchema.json | 16 +++ speechAssets/SampleUtterances_en_US.txt | 5 + src/AlexaDeviceAddressClient.js | 98 +++++++++++++ src/Events.js | 40 ++++++ src/Handlers.js | 177 ++++++++++++++++++++++++ src/Intents.js | 39 ++++++ src/Messages.js | 41 ++++++ src/index.js | 21 +++ 12 files changed, 539 insertions(+) create mode 100644 LICENSE.txt create mode 100644 README.md create mode 100644 index.js create mode 100644 package.json create mode 100644 speechAssets/IntentSchema.json create mode 100644 speechAssets/SampleUtterances_en_US.txt create mode 100644 src/AlexaDeviceAddressClient.js create mode 100644 src/Events.js create mode 100644 src/Handlers.js create mode 100644 src/Intents.js create mode 100644 src/Messages.js create mode 100644 src/index.js diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..1ffbcba --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,26 @@ +Amazon Software License +1. Definitions +“Licensor” means any person or entity that distributes its Work. + +“Software” means the original work of authorship made available under this License. + +“Work” means the Software and any additions to or derivative works of the Software that are made available under this License. + +The terms “reproduce,” “reproduction,” “derivative works,” and “distribution” have the meaning as provided under U.S. copyright law; provided, however, that for the purposes of this License, derivative works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work. + +Works, including the Software, are “made available” under this License by including in or with the Work either (a) a copyright notice referencing the applicability of this License to the Work, or (b) a copy of this License. +2. License Grants +2.1 Copyright Grant. Subject to the terms and conditions of this License, each Licensor grants to you a perpetual, worldwide, non-exclusive, royalty-free, copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, sublicense and distribute its Work and any resulting derivative works in any form. +2.2 Patent Grant. Subject to the terms and conditions of this License, each Licensor grants to you a perpetual, worldwide, non-exclusive, royalty-free patent license to make, have made, use, sell, offer for sale, import, and otherwise transfer its Work, in whole or in part. The foregoing license applies only to the patent claims licensable by Licensor that would be infringed by Licensor’s Work (or portion thereof) individually and excluding any combinations with any other materials or technology. +3. Limitations +3.1 Redistribution. You may reproduce or distribute the Work only if (a) you do so under this License, (b) you include a complete copy of this License with your distribution, and (c) you retain without modification any copyright, patent, trademark, or attribution notices that are present in the Work. +3.2 Derivative Works. You may specify that additional or different terms apply to the use, reproduction, and distribution of your derivative works of the Work (“Your Terms”) only if (a) Your Terms provide that the use limitation in Section 3.3 applies to your derivative works, and (b) you identify the specific derivative works that are subject to Your Terms. Notwithstanding Your Terms, this License (including the redistribution requirements in Section 3.1) will continue to apply to the Work itself. +3.3 Use Limitation. The Work and any derivative works thereof only may be used or intended for use with the web services, computing platforms or applications provided by Amazon.com, Inc. or its affiliates, including Amazon Web Services, Inc. +3.4 Patent Claims. If you bring or threaten to bring a patent claim against any Licensor (including any claim, cross-claim or counterclaim in a lawsuit) to enforce any patents that you allege are infringed by any Work, then your rights under this License from such Licensor (including the grants in Sections 2.1 and 2.2) will terminate immediately. +3.5 Trademarks. This License does not grant any rights to use any Licensor’s or its affiliates’ names, logos, or trademarks, except as necessary to reproduce the notices described in this License. +3.6 Termination. If you violate any term of this License, then your rights under this License (including the grants in Sections 2.1 and 2.2) will terminate immediately. +4. Disclaimer of Warranty. +THE WORK IS PROVIDED “AS IS” WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WARRANTIES OR CONDITIONS OF M ERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE OR NON-INFRINGEMENT. YOU BEAR THE RISK OF UNDERTAKING ANY ACTIVITIES UNDER THIS LICENSE. SOME STATES’ CONSUMER LAWS DO NOT ALLOW EXCLUSION OF AN IMPLIED WARRANTY, SO THIS DISCLAIMER MAY NOT APPLY TO YOU. +5. Limitation of Liability. +EXCEPT AS PROHIBITED BY APPLICABLE LAW, IN NO EVENT AND UNDER NO LEGAL THEORY, WHETHER IN TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE SHALL ANY LICENSOR BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR RELATED TO THIS LICENSE, THE USE OR INABILITY TO USE THE WORK (INCLUDING BUT NOT LIMITED TO LOSS OF GOODWILL, BUSINESS INTERRUPTION, LOST PROFITS OR DATA, COMPUTER FAILURE OR MALFUNCTION, OR ANY OTHER COMM ERCIAL DAMAGES OR LOSSES), EVEN IF THE LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +Effective Date – April 18, 2008 © 2008 Amazon.com, Inc. or its affiliates. All rights reserved. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..bad9466 --- /dev/null +++ b/README.md @@ -0,0 +1,42 @@ +# NodeJS ASK Alexa Device Address API Integration Sample Project + +The Alexa Skills Kit now allows developers to build skills that can retrieve a user's address via the new Alexa Device Address API. +## How to Run the Sample + +1. Clone the project and package the skill: +```bash +git clone git@github.com:alexa/skill-sample-node-device-address-api.git +cd skill-sample-node-device-address-api +npm install +``` +2. Create or login to an [AWS account](https://aws.amazon.com/). In the AWS Console: + + 1. Create an AWS Role in IAM with access to Lambda, CloudWatch Logs and DynamoDB. + ![create_role_1](https://cloud.githubusercontent.com/assets/7671574/17451098/09f64f40-5b19-11e6-82ee-b82c98387052.png "AWS Create Role Screenshot 1") + ![create_role_2](https://cloud.githubusercontent.com/assets/7671574/17451100/0c3ef928-5b19-11e6-9aca-8cd353106396.png "AWS Create Role Screenshot 2") + ![create_role_3](https://cloud.githubusercontent.com/assets/7671574/18011103/7b05f2b2-6b68-11e6-8dc3-3aa9ead6d83e.png "AWS Create Role Screenshot 3") + + 2. Create an AWS Lambda function named DeviceAddressLambdaFunction being sure to select the role created above, configuring "Alexa Skills Kit" as the "Trigger" and using the zip file created above as the source. + ![alt text](https://s3.amazonaws.com/lantern-public-assets/audio-player-assets/aws-lambda-role.PNG "AWS Lambda Role") + ![alt text](https://s3.amazonaws.com/lantern-public-assets/audio-player-assets/aws-lambda-ask-trigger.PNG "AWS Lambda Trigger") + 3. After creation, take note of the ARN on the upper right, which you'll configure in the Developer Console below. + +3. Create or login to an [Amazon Developer account](https://developer.amazon.com). In the Developer Console: + + 1. [Create an Alexa Skill](https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/developing-an-alexa-skill-as-a-lambda-function) named MySkill and using the invocation name "my skill". + 2. Copy the contents of `speechAssets/intentSchema.json` and `speechAssets/Utterances.txt` into the intent schema and sample utterances fields on the Interaction Model tab. + ![alt text](https://s3.amazonaws.com/lantern-public-assets/permissions-assets/intentSchema.png "Developer Portal Interaction Model") + ![alt text](https://s3.amazonaws.com/lantern-public-assets/permissions-assets/utterances.png "Developer Portal Interaction Model") + 3. Specify that you'll need permissions for access to the user's address. For the scope of this sample skill, you'll want the full address. + ![alt text](https://s3.amazonaws.com/lantern-public-assets/permissions-assets/permissions.png "Developer Portal Configuration") + +4. Edit the src/index.js file. You'll want to make APP_ID equal the Application Id for your skill. + +5. Compress your skill's source code into a single archive: +``` +zip -r packagedSkill.zip * +``` + +6. Upload the packagedSkill.zip from earlier to your Lambda function via the Code tab on the AWS Lambda Console. + +7. You can start using the skill on your device or in the simulator using the invocation phrase "Alexa, ask my skill what's my address". \ No newline at end of file diff --git a/index.js b/index.js new file mode 100644 index 0000000..ec8c61e --- /dev/null +++ b/index.js @@ -0,0 +1,11 @@ +'use strict'; + +/** + * This is a simple file that aliases your skill handler to a root + * level file so that you don't have to tinker with Lambda handler paths. + * This will make the default lambda value of "index.handler" work. + */ + +const MyAlexaSkill = require('./src/index'); + +exports.handler = MyAlexaSkill.handler; \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..0057775 --- /dev/null +++ b/package.json @@ -0,0 +1,23 @@ +{ + "name": "skill-sample-node-device-address-api", + "version": "1.0.0", + "description": "A Device Address API sample skill.", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [ + "alexa", + "skill", + "settings" + ], + "author": "Amazon.com", + "license": "SEE LICENSE IN LICENSE.txt", + "dependencies": { + "alexa-sdk": "^1.0.8" + }, + "repository" : { + "type" : "git", + "url" : "" + } +} \ No newline at end of file diff --git a/speechAssets/IntentSchema.json b/speechAssets/IntentSchema.json new file mode 100644 index 0000000..4775089 --- /dev/null +++ b/speechAssets/IntentSchema.json @@ -0,0 +1,16 @@ +{ + "intents": [ + { + "intent": "GetAddress" + }, + { + "intent": "AMAZON.CancelIntent" + }, + { + "intent": "AMAZON.HelpIntent" + }, + { + "intent": "AMAZON.StopIntent" + } + ] +} \ No newline at end of file diff --git a/speechAssets/SampleUtterances_en_US.txt b/speechAssets/SampleUtterances_en_US.txt new file mode 100644 index 0000000..142ab2b --- /dev/null +++ b/speechAssets/SampleUtterances_en_US.txt @@ -0,0 +1,5 @@ +GetAddress where am I located +GetAddress where do I live +GetAddress whats my address +GetAddress where am I +GetAddress whats my location \ No newline at end of file diff --git a/src/AlexaDeviceAddressClient.js b/src/AlexaDeviceAddressClient.js new file mode 100644 index 0000000..974df24 --- /dev/null +++ b/src/AlexaDeviceAddressClient.js @@ -0,0 +1,98 @@ +'use strict'; + +const Https = require('https'); + +/** + * This is a small wrapper client for the Alexa Address API. + */ +class AlexaDeviceAddressClient { + + /** + * Retrieve an instance of the Address API client. + * @param apiEndpoint the endpoint of the Alexa APIs. + * @param deviceId the device ID being targeted. + * @param consentToken valid consent token. + */ + constructor(apiEndpoint, deviceId, consentToken) { + console.log("Creating AlexaAddressClient instance."); + this.deviceId = deviceId; + this.consentToken = consentToken; + this.endpoint = apiEndpoint.replace(/^https?:\/\//i, ""); + } + + /** + * This will make a request to the Address API using the device ID and + * consent token provided when the Address Client was initialized. + * This will retrieve the full address of a device. + * @return {Promise} promise for the request in flight. + */ + getFullAddress() { + const options = this.__getRequestOptions(`/v1/devices/${this.deviceId}/settings/address`); + + return new Promise((fulfill, reject) => { + this.__handleDeviceAddressApiRequest(options, fulfill, reject); + }); + } + + /** + * This will make a request to the Address API using the device ID and + * consent token provided when the Address Client was initialized. + * This will retrieve the country and postal code of a device. + * @return {Promise} promise for the request in flight. + */ + getCountryAndPostalCode() { + const options = this.__getRequestOptions( + `/v1/devices/${this.deviceId}/settings/address/countryAndPostalCode`); + + return new Promise((fulfill, reject) => { + this.__handleDeviceAddressApiRequest(options, fulfill, reject); + }); + } + + /** + * This is a helper method that makes requests to the Address API and handles the response + * in a generic manner. It will also resolve promise methods. + * @param requestOptions + * @param fulfill + * @param reject + * @private + */ + __handleDeviceAddressApiRequest(requestOptions, fulfill, reject) { + Https.get(requestOptions, (response) => { + console.log(`Device Address API responded with a status code of : ${response.statusCode}`); + + response.on('data', (data) => { + let responsePayloadObject = JSON.parse(data); + + const deviceAddressResponse = { + statusCode: response.statusCode, + address: responsePayloadObject + }; + + fulfill(deviceAddressResponse); + }); + }).on('error', (e) => { + console.error(e); + reject(); + }); + } + + /** + * Private helper method for retrieving request options. + * @param path the path that you want to hit against the API provided by the skill event. + * @return {{hostname: string, path: *, method: string, headers: {Authorization: string}}} + * @private + */ + __getRequestOptions(path) { + return { + hostname: this.endpoint, + path: path, + method: 'GET', + 'headers': { + 'Authorization': 'Bearer ' + this.consentToken + } + }; + } +} + +module.exports = AlexaDeviceAddressClient; \ No newline at end of file diff --git a/src/Events.js b/src/Events.js new file mode 100644 index 0000000..586de11 --- /dev/null +++ b/src/Events.js @@ -0,0 +1,40 @@ +'use strict'; + +/** + * This file contains all the events that we'll be + * interested in outside of a normal intent. + */ + +/** + * Your skill will receive a NewSession event when a + * session has been started on your skill. An example of this would be + * when a user says "open skill blah blah blah". + */ +const NEW_SESSION = "NewSession"; + +/** + * Your service receives a LaunchRequest when the user invokes the skill with the + * invocation name, but does not provide any command mapping to an intent. + * Refer to the following URL for documentation: + * https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/handling-requests-sent-by-alexa#launchrequest + */ +const LAUNCH_REQUEST = "LaunchRequest"; + +/** + * Your service receives a SessionEndedRequest when a currently open session is closed. + * https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/handling-requests-sent-by-alexa#sessionendedrequest + */ +const SESSION_ENDED = "SessionEndedRequest"; + +/** + * Your skill will receive an Unhandled event when it receives an intent that + * it has not registered for. + */ +const UNHANDLED = "Unhandled"; + +module.exports = { + "NEW_SESSION": NEW_SESSION, + "LAUNCH_REQUEST": LAUNCH_REQUEST, + "SESSION_ENDED": SESSION_ENDED, + "UNHANDLED": UNHANDLED +}; \ No newline at end of file diff --git a/src/Handlers.js b/src/Handlers.js new file mode 100644 index 0000000..d16a436 --- /dev/null +++ b/src/Handlers.js @@ -0,0 +1,177 @@ +'use strict'; + +/** + * This class contains all handler function definitions + * for the various events that we will be registering for. + * For an understanding of how these Alexa Skill event objects + * are structured refer to the following documentation: + * https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/alexa-skills-kit-interface-reference + */ + +// Internal imports +const AlexaDeviceAddressClient = require('./AlexaDeviceAddressClient'); +const Intents = require('./Intents'); +const Events = require('./Events'); +const Messages = require('./Messages'); + +/** + * Another Possible value if you only want permissions for the country and postal code is: + * read::alexa:device:all:address:country_and_postal_code + * Be sure to check your permissions settings for your skill on https://developer.amazon.com/ + */ +const ALL_ADDRESS_PERMISSION = "read::alexa:device:all:address"; + +const PERMISSIONS = [ALL_ADDRESS_PERMISSION]; + +/** + * This is the handler for the NewSession event. + * Refer to the Events.js file for more documentation. + */ +const newSessionRequestHandler = function() { + console.info("Starting newSessionRequestHandler()"); + + if(this.event.request.type === Events.LAUNCH_REQUEST) { + this.emit(Events.LAUNCH_REQUEST); + } else if (this.event.request.type === "IntentRequest") { + this.emit(this.event.request.intent.name); + } + + console.info("Ending newSessionRequestHandler()"); +}; + +/** + * This is the handler for the LaunchRequest event. Refer to + * the Events.js file for more documentation. + */ +const launchRequestHandler = function() { + console.info("Starting launchRequestHandler()"); + this.emit(":ask", Messages.WELCOME + Messages.WHAT_DO_YOU_WANT, Messages.WHAT_DO_YOU_WANT); + console.info("Ending launchRequestHandler()"); +}; + +/** + * This is the handler for our custom GetAddress intent. + * Refer to the Intents.js file for documentation. + */ +const getAddressHandler = function() { + console.info("Starting getAddressHandler()"); + + const consentToken = this.event.context.System.user.permissions.consentToken; + + // If we have not been provided with a consent token, this means that the user has not + // authorized your skill to access this information. In this case, you should prompt them + // that you don't have permissions to retrieve their address. + if(!consentToken) { + this.emit(":tellWithPermissionCard", Messages.NOTIFY_MISSING_PERMISSIONS, PERMISSIONS); + + // Lets terminate early since we can't do anything else. + console.log("User did not give us permissions to access their address."); + console.info("Ending getAddressHandler()"); + return; + } + + const deviceId = this.event.context.System.device.deviceId; + const apiEndpoint = this.event.context.System.apiEndpoint; + + const alexaDeviceAddressClient = new AlexaDeviceAddressClient(apiEndpoint, deviceId, consentToken); + let deviceAddressRequest = alexaDeviceAddressClient.getFullAddress(); + + deviceAddressRequest.then((addressResponse) => { + switch(addressResponse.statusCode) { + case 200: + console.log("Address successfully retrieved, now responding to user."); + const address = addressResponse.address; + + const ADDRESS_MESSAGE = Messages.ADDRESS_AVAILABLE + + `${address['addressLine1']}, ${address['stateOrRegion']}, ${address['postalCode']}`; + + this.emit(":tell", ADDRESS_MESSAGE); + break; + case 204: + // This likely means that the user didn't have their address set via the companion app. + console.log("Successfully requested from the device address API, but no address was returned."); + this.emit(":tell", Messages.NO_ADDRESS); + break; + case 403: + console.log("The consent token we had wasn't authorized to access the user's address."); + this.emit(":tellWithPermissionCard", Messages.NOTIFY_MISSING_PERMISSIONS, PERMISSIONS); + break; + default: + this.emit(":ask", Messages.LOCATION_FAILURE, Messages.LOCATION_FAILURE); + } + + console.info("Ending getAddressHandler()"); + }); + + deviceAddressRequest.catch((error) => { + this.emit(":tell", Messages.ERROR); + console.error(error); + console.info("Ending getAddressHandler()"); + }); +}; + +/** + * This is the handler for the SessionEnded event. Refer to + * the Events.js file for more documentation. + */ +const sessionEndedRequestHandler = function() { + console.info("Starting sessionEndedRequestHandler()"); + this.emit(":tell", Messages.GOODBYE); + console.info("Ending sessionEndedRequestHandler()"); +}; + +/** + * This is the handler for the Unhandled event. Refer to + * the Events.js file for more documentation. + */ +const unhandledRequestHandler = function() { + console.info("Starting unhandledRequestHandler()"); + this.emit(":ask", Messages.UNHANDLED, Messages.UNHANDLED); + console.info("Ending unhandledRequestHandler()"); +}; + +/** + * This is the handler for the Amazon help built in intent. + * Refer to the Intents.js file for documentation. + */ +const amazonHelpHandler = function() { + console.info("Starting amazonHelpHandler()"); + this.emit(":ask", Messages.HELP, Messages.HELP); + console.info("Ending amazonHelpHandler()"); +}; + +/** + * This is the handler for the Amazon cancel built in intent. + * Refer to the Intents.js file for documentation. + */ +const amazonCancelHandler = function() { + console.info("Starting amazonCancelHandler()"); + this.emit(":tell", Messages.GOODBYE); + console.info("Ending amazonCancelHandler()"); +}; + +/** + * This is the handler for the Amazon stop built in intent. + * Refer to the Intents.js file for documentation. + */ +const amazonStopHandler = function() { + console.info("Starting amazonStopHandler()"); + this.emit(":ask", Messages.STOP, Messages.STOP); + console.info("Ending amazonStopHandler()"); +}; + + +const handlers = {}; +// Add event handlers +handlers[Events.NEW_SESSION] = newSessionRequestHandler; +handlers[Events.LAUNCH_REQUEST] = launchRequestHandler; +handlers[Events.SESSION_ENDED] = sessionEndedRequestHandler; +handlers[Events.UNHANDLED] = unhandledRequestHandler; + +// Add intent handlers +handlers[Intents.GET_ADDRESS] = getAddressHandler; +handlers[Intents.AMAZON_CANCEL] = amazonCancelHandler; +handlers[Intents.AMAZON_STOP] = amazonStopHandler; +handlers[Intents.AMAZON_HELP] = amazonHelpHandler; + +module.exports = handlers; \ No newline at end of file diff --git a/src/Intents.js b/src/Intents.js new file mode 100644 index 0000000..7eb3a46 --- /dev/null +++ b/src/Intents.js @@ -0,0 +1,39 @@ +'use strict'; + +/** + * This file contains constant definitions of intents that we're + * interested in for our skill. + * + * Refer to the following link for a list of built-in intents, + * and what those intents do. + * https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/built-in-intent-ref/standard-intents + */ + +/** + * This is a custom intent for our skill. It will indicate + * When received, we should retrieve the customer's data from + * the Address API. + */ +const GET_ADDRESS = "GetAddress"; + +/** + * This is an Amazon built-in intent. + */ +const AMAZON_HELP = "AMAZON.HelpIntent"; + +/** + * This is an Amazon built-in intent. + */ +const AMAZON_CANCEL = "AMAZON.CancelIntent"; + +/** + * This is an Amazon built-in intent. + */ +const AMAZON_STOP = "AMAZON.StopIntent"; + +module.exports = { + "GET_ADDRESS": GET_ADDRESS, + "AMAZON_HELP": AMAZON_HELP, + "AMAZON_CANCEL": AMAZON_CANCEL, + "AMAZON_STOP": AMAZON_STOP +}; \ No newline at end of file diff --git a/src/Messages.js b/src/Messages.js new file mode 100644 index 0000000..65e16c8 --- /dev/null +++ b/src/Messages.js @@ -0,0 +1,41 @@ +'use strict'; + +/** + * This file contains a map of messages used by the skill. + */ + +const WELCOME = "Welcome to the Sample Device Address API Skill!"; + +const WHAT_DO_YOU_WANT = "What do you want to ask?"; + +const NOTIFY_MISSING_PERMISSIONS = "Please enable Location permissions in the Amazon Alexa app."; + +const NO_ADDRESS = "It looks like you don't have an address set. You can set your address from the companion app."; + +const ADDRESS_AVAILABLE = "Here is your full address: "; + +const ERROR = "Uh Oh. Looks like something went wrong."; + +const LOCATION_FAILURE = "There was an error with the Device Address API. Please try again."; + +const GOODBYE = "Bye! Thanks for using the Sample Device Address API Skill!"; + +const UNHANDLED = "This skill doesn't support that. Please ask something else."; + +const HELP = "You can use this skill by asking something like: whats my address?"; + +const STOP = "There is nothing to stop. Did you mean to ask something else?"; + +module.exports = { + "WELCOME": WELCOME, + "WHAT_DO_YOU_WANT": WHAT_DO_YOU_WANT, + "NOTIFY_MISSING_PERMISSIONS": NOTIFY_MISSING_PERMISSIONS, + "NO_ADDRESS": NO_ADDRESS, + "ADDRESS_AVAILABLE": ADDRESS_AVAILABLE, + "ERROR": ERROR, + "LOCATION_FAILURE": LOCATION_FAILURE, + "GOODBYE": GOODBYE, + "UNHANDLED": UNHANDLED, + "HELP": HELP, + "STOP": STOP +}; \ No newline at end of file diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..8ae6121 --- /dev/null +++ b/src/index.js @@ -0,0 +1,21 @@ +'use strict'; + +// External imports +const Alexa = require('alexa-sdk'); + +// Local imports +const Handlers = require('./Handlers'); + +// Constants +const APP_ID = ""; // This value would be your Skill ID. You can find this on https://developer.amazon.com/ + +exports.handler = function (event, context, callback) { + let alexa = Alexa.handler(event, context); + + alexa.appId = APP_ID; + alexa.registerHandlers(Handlers); + + console.log(`Beginning execution for skill with APP_ID=${alexa.appId}`); + alexa.execute(); + console.log(`Ending execution for skill with APP_ID=${alexa.appId}`); +}; \ No newline at end of file