Permalink
Browse files

Updated to support standard Amazon Alexa syntax.

Include launch method.
  • Loading branch information...
1 parent f7e3307 commit 9d838c91355080e3b9145ae1b1b99c31faaef286 @primaryobjects committed Aug 19, 2016
Showing with 288 additions and 21 deletions.
  1. +72 −0 guessinggame.js
  2. +37 −0 hello.js
  3. +98 −11 lib/chatskills.js
  4. +3 −3 package.json
  5. +78 −7 readme.md
View
@@ -0,0 +1,72 @@
+var chatskills = require('./lib/chatskills');
+var readlineSync = require('readline-sync');
+
+// Allow this module to be reloaded by hotswap when changed
+module.change_code = 1;
+chatskills.verbose = true;
+
+// Define an alexa-app
+var app = chatskills.app('guessinggame'); //new alexa.app('guessinggame');
+
+app.launch(function(req,res) {
+ var number = Math.floor(Math.random()*99)+1;
+ res.session('number',number);
+ res.session('guesses',0);
+ var prompt = "Guess a number between 1 and 100!";
+ res.say(prompt).reprompt(prompt).shouldEndSession(false);
+});
+
+app.intent('run', {
+ "slots": {},
+ "utterances": ["{to|} {run|start|go|launch}"]
+ }, function(req, res) {
+ var number = Math.floor(Math.random()*99)+1;
+ res.session('number',number);
+ res.session('guesses',0);
+ var prompt = "Guess a number between 1 and 100!";
+ res.say(prompt).reprompt(prompt).shouldEndSession(false);
+ }
+);
+
+app.intent('guess',{
+ "slots":{"guess":"NUMBER"}
+ ,"utterances":["{1-100|guess}"]
+ },
+ function(req,res) {
+ var guesses = (+req.session('guesses'))+1;
+ var guess = req.slot('guess');
+ var number = +req.session('number');
+ if (!guess) {
+ res.say("Sorry, I didn't hear a number. The number was "+number);
+ }
+ else if (guess==number) {
+ res.say("Congratulations, you guessed the number in " + guesses + (guesses==1?" try":" tries"));
+ }
+ else {
+ if (guess > number) {
+ res.say("Guess lower");
+ }
+ else if (guess < number) {
+ res.say("Guess higher");
+ }
+ res.reprompt("Sorry, I didn't hear a number. Try again.");
+ res.session('guesses',guesses);
+ res.shouldEndSession(false);
+ }
+ }
+);
+module.exports = app;
+
+// Start running our skill. You can also just create a "start" intent and ask, "chatskills, ask guessinggame start".
+chatskills.launch(app);
+
+// Console client.
+var text = ' ';
+while (text.length > 0 && text != 'quit') {
+ text = readlineSync.question('> ');
+
+ // Respond to input.
+ chatskills.respond(text, function(response) {
+ console.log(response);
+ });
+}
View
@@ -0,0 +1,37 @@
+var chatskills = require('./lib/chatskills');
+var readlineSync = require('readline-sync');
+
+// Create a skill.
+var hello = chatskills.app('hello');
+
+// Launch method to run at startup.
+hello.launch(function(req,res) {
+ res.say("Ask me to say hi!");
+
+ // Keep session open.
+ res.shouldEndSession(false);
+});
+
+// Create an intent.
+hello.intent('helloWorld', {
+ 'slots': {},
+ 'utterances': [ '{to |}{say|speak|tell me} {hi|hello|howdy|hi there|hiya|hi ya|hey|hay|heya}' ]
+ },
+ function(req, res) {
+ res.say('Hello, World!');
+ }
+);
+
+// Start running our skill.
+chatskills.launch(hello);
+
+// Console client.
+var text = ' ';
+while (text.length > 0 && text != 'quit') {
+ text = readlineSync.question('> ');
+
+ // Respond to input.
+ chatskills.respond(text, function(response) {
+ console.log(response);
+ });
+}
View
@@ -9,6 +9,41 @@ License MIT
var alexa = require('alexa-app');
+function ReqResHelper(namespace, sessionId) {
+ this.namespace = namespace;
+ this.sessionId = sessionId || 1;
+ this.sessions = {};
+
+ this.initialize = function() {
+ var text = ChatSkillsManager.id + ', ask ' + this.namespace + ' empty.';
+ this.sessions[this.sessionId] = ChatSkillsManager.session(text, this.sessionId);
+
+ return this;
+ }
+
+ this.session = function(key, value) {
+ this.sessions[this.sessionId].slots[key] = value;
+ return this;
+ }
+
+ this.say = function(text) {
+ console.log(text);
+ return this;
+ }
+
+ this.reprompt = function(text) {
+ // Unsupported.
+ return this;
+ }
+
+ this.shouldEndSession = function(isEnd) {
+ this.sessions[this.sessionId] = isEnd ? null : this.sessions[this.sessionId];
+ return this;
+ }
+
+ this.initialize();
+};
+
var ChatSkillsManager = {
verbose: false,
timeout: 3600, // session timeout in seconds (0 to disable)
@@ -23,12 +58,37 @@ var ChatSkillsManager = {
add: function(namespace) {
// Add a new skill (app namespace).
this.apps[namespace] = new alexa.app(namespace);
-
return this.apps[namespace];
},
app: function(namespace) {
- return this.apps[namespace];
+ return this.add(namespace);
+ },
+
+ launch: function(namespace, sessionId) {
+ var app = null;
+
+ if (typeof namespace == 'string') {
+ // Launch app.
+ app = this.apps[namespace];
+ }
+ else if (namespace) {
+ app = namespace;
+ }
+ else {
+ if (this.verbose) {
+ console.log("Error: Please provide a namespace or app to chatskills.launch(namespace, sessionId). Example: chatskills.launch('myskill') or chatskills.launch(app)");
+ }
+ }
+
+ if (app) {
+ // Instantiation will start a new session for this skill.
+ var req = new ReqResHelper(app.name, sessionId);
+ if (app.launchFunc) {
+ // Run the skill's app.launch() method.
+ app.launchFunc(req, req);
+ }
+ }
},
expire: function(sessionId) {
@@ -111,10 +171,10 @@ var ChatSkillsManager = {
sessionId = sessionId || 1;
// Get a new or existing session.
- var session = this.session(input, sessionId);
- if (session) {
- var app = session.app;
- input = session.input;
+ var currentSession = this.session(input, sessionId);
+ if (currentSession) {
+ var app = currentSession.app;
+ input = currentSession.input;
var result = null;
// Go through each intent in the skill to find a valid response.
@@ -138,26 +198,36 @@ var ChatSkillsManager = {
result = ChatSkillsManager.parse(input, utterances, app.intents[key].schema.slots);
if (result.isValid) {
+ var shouldContinueSession = false;
+
// This intent is valid for the input. Set slots.
for (var j in result.pairs) {
var pair = result.pairs[j];
- session.slots[pair.name] = pair.value;
+ currentSession.slots[pair.name] = pair.value;
};
// Call intent.
var continueSession = app.intents[key]['function'](
{
// Request
input: input,
- slots: session.slots,
+ slots: currentSession.slots,
variables: result.pairs,
get: function(key) {
- return session.slots[key];
+ return currentSession.slots[key];
},
set: function(key, value) {
- session.slots[key] = value;
+ currentSession.slots[key] = value;
+ },
+
+ session: function(key, value) {
+ return value ? this.set(key, value) : this.get(key);
+ },
+
+ slot: function(key) {
+ return this.get(key);
}
},
{
@@ -166,10 +236,27 @@ var ChatSkillsManager = {
if (callback) {
callback(text);
}
+
+ return this;
+ },
+
+ reprompt: function(text) {
+ // Unsupported.
+ return this;
+ },
+
+ session: function(key, value) {
+ currentSession.slots[key] = value;
+ },
+
+ shouldEndSession: function(isEnd) {
+ // Support for: res.shouldEndSession(false) to tell chatskills to keep session alive (even though default return from response is false, meaning end session).
+ shouldContinueSession = !isEnd;
+ return this;
}
});
- if (!continueSession) {
+ if (!continueSession && !shouldContinueSession) {
// Intent returned false, so end the session.
delete this.sessions[sessionId];
View
@@ -1,7 +1,7 @@
{
"name": "chatskills",
- "version": "0.0.10",
- "description": "Build a simple chatbot using Alexa-style skills and intents.",
+ "version": "0.0.11",
+ "description": "Run Alexa apps on the command-line. Run them in Slack. Run them anywhere! Supports Amazon Alexa skills and intents.",
"author": {
"name": "Kory Becker",
"email": "kbecker@primaryobjects.com",
@@ -47,6 +47,6 @@
"AI",
"artificial intelligence"
],
- "_id": "chatskills@0.0.10",
+ "_id": "chatskills@0.0.11",
"_from": "chatskills"
}
Oops, something went wrong.

0 comments on commit 9d838c9

Please sign in to comment.