From e5ade7a70cfdf1b9ce7ae9e7f134ccaadaad2cca Mon Sep 17 00:00:00 2001 From: Karl Date: Mon, 28 Nov 2016 22:09:45 +0000 Subject: [PATCH] First commit --- AlexaSkill | 175 +++++++++++++++++++++++++++++++++++++++++++++++ IntentSchema | 13 ++++ SampleUtterances | 6 ++ index | 90 ++++++++++++++++++++++++ index.zip | Bin 0 -> 2780 bytes 5 files changed, 284 insertions(+) create mode 100644 AlexaSkill create mode 100644 IntentSchema create mode 100644 SampleUtterances create mode 100644 index create mode 100644 index.zip diff --git a/AlexaSkill b/AlexaSkill new file mode 100644 index 0000000..f9804e4 --- /dev/null +++ b/AlexaSkill @@ -0,0 +1,175 @@ +// Alexa SDK for JavaScript v1.0.00 +// Copyright (c) 2014-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. Use is subject to license terms. +'use strict'; +function AlexaSkill(appId) { + this._appId = appId; +} + +AlexaSkill.prototype.requestHandlers = { + LaunchRequest: function (event, context, response) { + this.eventHandlers.onLaunch.call(this, event.request, event.session, response); + }, + + IntentRequest: function (event, context, response) { + this.eventHandlers.onIntent.call(this, event.request, event.session, response); + }, + + SessionEndedRequest: function (event, context) { + this.eventHandlers.onSessionEnded(event.request, event.session); + context.succeed(); + } +}; + +/** + * Override any of the eventHandlers as needed + */ +AlexaSkill.prototype.eventHandlers = { + /** + * Called when the session starts. + * Subclasses could have overriden this function to open any necessary resources. + */ + onSessionStarted: function (sessionStartedRequest, session) { + }, + + /** + * Called when the user launches the skill without specifying what they want. + * The subclass must override this function and provide feedback to the user. + */ + onLaunch: function (launchRequest, session, response) { + throw "onLaunch should be overriden by subclass"; + }, + + /** + * Called when the user specifies an intent. + */ + onIntent: function (intentRequest, session, response) { + var intent = intentRequest.intent, + intentName = intentRequest.intent.name, + intentHandler = this.intentHandlers[intentName]; + if (intentHandler) { + console.log('dispatch intent = ' + intentName); + intentHandler.call(this, intent, session, response); + } else { + throw 'Unsupported intent = ' + intentName; + } + }, + + /** + * Called when the user ends the session. + * Subclasses could have overriden this function to close any open resources. + */ + onSessionEnded: function (sessionEndedRequest, session) { + } +}; + +/** + * Subclasses should override the intentHandlers with the functions to handle specific intents. + */ +AlexaSkill.prototype.intentHandlers = {}; + +AlexaSkill.prototype.execute = function (event, context) { + try { + console.log("session applicationId: " + event.session.application.applicationId); + + // Validate that this request originated from authorized source. + if (this._appId && event.session.application.applicationId !== this._appId) { + console.log("The applicationIds don't match : " + event.session.application.applicationId + " and " + + this._appId); + throw "Invalid applicationId"; + } + + if (!event.session.attributes) { + event.session.attributes = {}; + } + + if (event.session.new) { + this.eventHandlers.onSessionStarted(event.request, event.session); + } + + // Route the request to the proper handler which may have been overriden. + var requestHandler = this.requestHandlers[event.request.type]; + requestHandler.call(this, event, context, new Response(context, event.session)); + } catch (e) { + console.log("Unexpected exception " + e); + context.fail(e); + } +}; + +var Response = function (context, session) { + this._context = context; + this._session = session; +}; + +Response.prototype = (function () { + var buildSpeechletResponse = function (options) { + var alexaResponse = { + outputSpeech: { + type: 'PlainText', + text: options.output + }, + shouldEndSession: options.shouldEndSession + }; + if (options.reprompt) { + alexaResponse.reprompt = { + outputSpeech: { + type: 'PlainText', + text: options.reprompt + } + }; + } + if (options.cardTitle && options.cardContent) { + alexaResponse.card = { + type: "Simple", + title: options.cardTitle, + content: options.cardContent + }; + } + var returnResult = { + version: '1.0', + response: alexaResponse + }; + if (options.session && options.session.attributes) { + returnResult.sessionAttributes = options.session.attributes; + } + return returnResult; + }; + + return { + tell: function (speechOutput) { + this._context.succeed(buildSpeechletResponse({ + session: this._session, + output: speechOutput, + shouldEndSession: true + })); + }, + tellWithCard: function (speechOutput, cardTitle, cardContent) { + this._context.succeed(buildSpeechletResponse({ + session: this._session, + output: speechOutput, + cardTitle: cardTitle, + cardContent: cardContent, + shouldEndSession: true + })); + }, + ask: function (speechOutput, repromptSpeech) { + this._context.succeed(buildSpeechletResponse({ + session: this._session, + output: speechOutput, + reprompt: repromptSpeech, + shouldEndSession: false + })); + }, + askWithCard: function (speechOutput, repromptSpeech, cardTitle, cardContent) { + this._context.succeed(buildSpeechletResponse({ + session: this._session, + output: speechOutput, + reprompt: repromptSpeech, + cardTitle: cardTitle, + cardContent: cardContent, + shouldEndSession: false + })); + } + }; +})(); + +module.exports = AlexaSkill; diff --git a/IntentSchema b/IntentSchema new file mode 100644 index 0000000..98876fb --- /dev/null +++ b/IntentSchema @@ -0,0 +1,13 @@ +{ + "intents": [ + { + "intent": "desk", + "slots": [ + { + "name": "Control", + "type": "Control_List" + } + ] + } + ] +} \ No newline at end of file diff --git a/SampleUtterances b/SampleUtterances new file mode 100644 index 0000000..ce1f62c --- /dev/null +++ b/SampleUtterances @@ -0,0 +1,6 @@ +desk to turn {Control} +desk can you turn {Control} +desk to turn {Control} please +desk {Control} +desk to turn the {Control} +desk to {Control} \ No newline at end of file diff --git a/index b/index new file mode 100644 index 0000000..1c44cf8 --- /dev/null +++ b/index @@ -0,0 +1,90 @@ +var http = require('http'); // if going through a proxy that uses SSL change to "require('https');" + +// Your external IP. Alexa can only access publically-accessible IPs. No LAN access unfortunately. +// In my case I had to move receiver to DMZ +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +var local_ip = 'home.k-world.me.uk'; +var local_port = '8088'; +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * App ID for the skill + */ + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +var APP_ID = "amzn1.ask.skill.8f9502ec-5452-4c18-a8e5-6f2aed86d676"; +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** +* The AlexaSkill prototype and helper functions + */ +var AlexaSkill = require('./AlexaSkill'); + +var DTVControl = function () { + AlexaSkill.call(this, APP_ID); +}; + + +// Extend AlexaSkill +DTVControl.prototype = Object.create(AlexaSkill.prototype); +DTVControl.prototype.constructor = DTVControl; + +//Ignore Certificate errors if using HTTPS communication +process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"; + +DTVControl.prototype.intentHandlers = { + desk: function (intent, session, response) { + + //No matter what she wants to tell you her opinion. + + function satisfyAlexa() { + response.tell("Desk Updated"); + }; + + // Obtain User Intent + switch(intent.slots.Control.value) { + + // List of triggers and URL to goto + case "red": + path = '/DeskControl/red.php'; + break; + + case "blue": + path = '/DeskControl/blue.php'; + break; + + case "green": + path = '/DeskControl/green.php'; + break; + + case "off": + path = '/DeskControl/off.php'; + break; + + + + default: + + response.tell("Sorry, I didnt understand that desk request."); + break; + + + } + var options = { + host: local_ip, + port: local_port, // default port for webserver + path: '' + path, // Modify if path is prefixed + method: 'POST' //, //(remove first comment slashes if using the "auth" option below) + // auth: 'username:password' // this is used if going through authenticated proxy (this is BASIC AUTH) + }; + var req = http.request(options, satisfyAlexa); + req.end(); + } +} + + +exports.handler = function (event, context) { + + var dtvControl = new DTVControl(); + dtvControl.execute(event, context); + +}; diff --git a/index.zip b/index.zip new file mode 100644 index 0000000000000000000000000000000000000000..e103102e091764148b800e0e51f9f45523710450 GIT binary patch literal 2780 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