Skip to content

Instantly share code, notes, and snippets.

@picsoung
Created January 13, 2016 15:01
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save picsoung/0f9aef4a551b6d408f0a to your computer and use it in GitHub Desktop.
Save picsoung/0f9aef4a551b6d408f0a to your computer and use it in GitHub Desktop.
This is the code for the Amazon Echo app for APIstrat Austin conference. Using the app you can ask for the schedule of the conference.
'use strict';
/**
* Author: Nicolas Grenié, @pisoung
* Date: November 2015
* This is the code for the Amazon Echo app for APIstrat Austin conference. Using the app you can ask for the schedule of the conference.
* It uses APIstrat API developed by Kin Lane
*/
require('jaws-core-js/env');
var request = require('request');
var _ = require('underscore');
var Q = require('q');
var moment = require('moment');
module.exports.handler = function (event, context) {
try {
console.log("event.session.application.applicationId=" + event.session.application.applicationId);
if (event.session.new) {
onSessionStarted({requestId: event.request.requestId}, event.session);
}
if (event.request.type === "LaunchRequest") {
onLaunch(event.request,
event.session,
function callback(sessionAttributes, speechletResponse) {
context.succeed(buildResponse(sessionAttributes, speechletResponse));
});
} else if (event.request.type === "IntentRequest") {
onIntent(event.request,
event.session,
function callback(sessionAttributes, speechletResponse) {
context.succeed(buildResponse(sessionAttributes, speechletResponse));
});
} else if (event.request.type === "SessionEndedRequest") {
onSessionEnded(event.request, event.session);
context.succeed();
}
} catch (e) {
context.fail("Exception: " + e);
}
};
/**
* Called when the session starts.
*/
function onSessionStarted(sessionStartedRequest, session) {
console.log("onSessionStarted requestId=" + sessionStartedRequest.requestId +
", sessionId=" + session.sessionId);
}
/**
* Called when the user launches the skill without specifying what they want.
*/
function onLaunch(launchRequest, session, callback) {
console.log("onLaunch requestId=" + launchRequest.requestId +
", sessionId=" + session.sessionId);
// Dispatch to your skill's launch.
getWelcomeResponse(callback);
}
/**
* Called when the user specifies an intent for this skill.
*/
function onIntent(intentRequest, session, callback) {
console.log("onIntent requestId=" + intentRequest.requestId +
", sessionId=" + session.sessionId);
var intent = intentRequest.intent,
intentName = intentRequest.intent.name;
console.log("INTENT",intentName);
// Dispatch to your skill's intent handlers
if ("WhenIsSpeakerTalkingIntent" === intentName) {
getSpeakerTalkingSession(intent,callback);
} else if("WhatsNowIntent"===intentName){
getWhatsNowProgram(callback)
}else if("WhenIsSessionIntent"===intentName){
getWhenIsSession(intent,callback)
} else {
throw "Invalid intent";
}
}
/**
* Called when the user ends the session.
* Is not called when the skill returns shouldEndSession=true.
*/
function onSessionEnded(sessionEndedRequest, session) {
console.log("onSessionEnded requestId=" + sessionEndedRequest.requestId +
", sessionId=" + session.sessionId);
// Add cleanup logic here
}
// --------------- Function to get when is a specific session-----------------------
function getWhenIsSession(intent,callback){
console.log(intent);
var sessionName = intent.slots.SessionName.value;
var cardTitle = "Info about session "+sessionName;
var repromptText = "";
var cardContent = "";
var speechOutput = "";
var sessionAttributes = {};
var shouldEndSession = true;
var URL = "http://api.austin2015.apistrat.com/schedule/search/";
URL +="?query="+sessionName;
console.log(URL);
request.get(URL,function(err,resp,body){
if(err && err.code == 'ETIMEDOUT'){
speechOutput += "<s>Oh no, looks like the APIstrat API is down.</s>"
speechOutput += "<s>You can now find Kin Lane and complain about it</s>"
speechOutput += "</speak>"
callback(sessionAttributes,
buildSpeechletResponse(cardTitle, speechOutput, cardContent, repromptText, shouldEndSession));
}
if(resp){
var body = JSON.parse(body)
console.log(body);
speechOutput = "<speak>"
if(body.length ==0){ //no result
speechOutput += "<s>I am sorry I could not find info about this session in the program</s>"
speechOutput += "</speak>"
cardContent = "Could not find any information regarding this session in the program"
callback(sessionAttributes,
buildSpeechletResponse(cardTitle, speechOutput, cardContent, repromptText, shouldEndSession));
}else{ //speaker found
var sessions = body;
speechOutput += "<s>I've found "+sessions.length+" sessions for the criteria: "+sessionName+"</s>";
cardContent = sessions.length+" sessions found for the criteria: "+sessionName
_.each(sessions,function(s){
speechOutput += "<s>"+s.title+" in "+s.location + " on "+moment(s.start_time).calendar()+"</s>"
speechOutput += "<s>With ";
var nbSpeakers = s.speakers.length;
_.each(s.speakers, function(speaker,index){
speechOutput += speaker.name +" from "+speaker.company;
if(index < nbSpeakers -1)
speechOutput += " and ";
}) //end each on speakers
speechOutput +="</s>"
}) //end each on sessions
speechOutput += "</speak>"
console.log(speechOutput);
callback(sessionAttributes,
buildSpeechletResponse(cardTitle, speechOutput, cardContent, repromptText, shouldEndSession));
} //end of if
}
})
}
// --------------- Function to find info about speaker -----------------------
function getSpeakerTalkingSession(intent,callback){
var cardTitle = "Info about speaker "+intent.slots.SpeakerName.value;
var repromptText = "";
var cardContent = "";
var speechOutput = "";
var sessionAttributes = {};
var shouldEndSession = true;
var URL = "http://api.austin2015.apistrat.com/speakers/";
URL +="?query="+intent.slots.SpeakerName.value
console.log(URL);
request.get(URL, {timeout: 1500},function(err,resp,body){
console.log("ERR",err);
if(err && err.code == 'ETIMEDOUT'){
speechOutput += "<s>Oh no, looks like the APIstrat API is down.</s>"
speechOutput += "<s>You can now find Kin Lane and complain about it</s>"
speechOutput += "</speak>"
callback(sessionAttributes,
buildSpeechletResponse(cardTitle, speechOutput, cardContent, repromptText, shouldEndSession));
}
if(resp){
var body = JSON.parse(body)
console.log(body);
speechOutput = "<speak>"
if(body.length ==0){ //no result
speechOutput += "<s>I am sorry I could not find info about this speaker</s>"
speechOutput += "</speak>"
cardContent = "Could not find any information regarding this speaker"
callback(sessionAttributes,
buildSpeechletResponse(cardTitle, speechOutput, cardContent, repromptText, shouldEndSession));
}else{ //speaker found
var speaker = body[0];
speechOutput += "<s>I've found "+speaker.sessions.length+" sessions for "+speaker.name+"</s>";
cardContent = speaker.sessions.length+" sessions for "+speaker.name+" "
_.each(speaker.sessions,function(s){
speechOutput += "<s>"+s.title+" in "+s.location + " on "+moment(s.start_time).calendar()+"</s>"
cardContent += s.title+" in "+s.location + " on "+moment(s.start_time).calendar()+" "
});
speechOutput += "</speak>"
callback(sessionAttributes,
buildSpeechletResponse(cardTitle, speechOutput, cardContent, repromptText, shouldEndSession));
}
}
})
}
// --------------- Function to get what's happening now -----------------------
function getWhatsNowProgram(callback){
var cardTitle = "APIstrat";
var repromptText = "";
var cardContent = "";
var speechOutput = "";
var sessionAttributes = {};
var shouldEndSession = true;
var URL = "http://api.austin2015.apistrat.com/schedule/now/";
request.get(URL,function(err,resp,body){
if(err && err.code == 'ETIMEDOUT'){
speechOutput += "<s>Oh no, looks like the APIstrat API is down.</s>"
speechOutput += "<s>You can now find Kin Lane and complain about it</s>"
speechOutput += "</speak>"
callback(sessionAttributes,
buildSpeechletResponse(cardTitle, speechOutput, cardContent, repromptText, shouldEndSession));
}
if(resp){
var body = JSON.parse(body)
speechOutput = "<speak>"
if(body.length ==0){
speechOutput += "<s>Sadly nothing is happening now at APIstrat</s>"
speechOutput += "</speak>"
cardContent = "Nothing happening at the moment"
}else if(body.length == 1){
var event = body[0]
speechOutput += "<s>There is "+event.title+" happening now on "+event.location+" by "+event.speakers[0].name+" from "+event.speakers[0].company+"</s>";
speechOutput += "</speak>"
cardContent = "There is "+event.title+"happening now on "+event.location+" by "+event.speakers[0].name+" from "+event.speakers[0].company
//TODO if multiple speakers
}else{
}
callback(sessionAttributes,
buildSpeechletResponse(cardTitle, speechOutput,cardContent, repromptText, shouldEndSession));
}
}) //end request.get
}
function getWelcomeResponse(callback) {
// If we wanted to initialize the session to have some attributes we could add those here.
var sessionAttributes = {};
var cardTitle = "Welcome";
var speechOutput = "Welcome to the Alexa Skills Kit sample, " +
"Please tell me your favorite color by saying, " +
"my favorite color is red";
// If the user either does not reply to the welcome message or says something that is not
// understood, they will be prompted again with this text.
var repromptText = "Please tell me your favorite color by saying, " +
"my favorite color is red";
var shouldEndSession = false;
callback(sessionAttributes,
buildSpeechletResponse(cardTitle, speechOutput, repromptText, shouldEndSession));
}
// --------------- Helpers that build all of the responses -----------------------
function buildSpeechletResponse(title, speechOutput, cardContent, repromptText, shouldEndSession) {
return {
outputSpeech: {
type: "SSML",
ssml: speechOutput,
},
card: {
type: "Simple",
title: "APIstrat - " + title,
content: "APIstrat - " + cardContent
},
reprompt: {
outputSpeech: {
type: "PlainText",
text: repromptText
}
},
shouldEndSession: shouldEndSession
};
}
function buildResponse(sessionAttributes, speechletResponse) {
return {
version: "1.0",
sessionAttributes: sessionAttributes,
response: speechletResponse
};
}
@rajava
Copy link

rajava commented Aug 26, 2017

How did this code work? isn't there a problem in line 275 shouldEndSession: shouldEndSession

I guess this causes an Alexa custom skill (nodejs) to always timeout and not end at the wish of the user or naturally when session is requested to end.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment