Things used in this project

Hardware components:
Amazon echo dot
Amazon Alexa Echo Dot
×1
Software apps and online services:
Screen%20shot%202015 07 20%20at%206.10.26%20pm
Amazon Web Services AWS Lambda
Dp image kit 02
Amazon Alexa Alexa Skills Kit

Schematics

Interaction Model Example 1
Mjvauffdc5nq99vskqyt
Interaction Model Example 2
Ueo5iv3abnrudzf0dbad
Skill Architecture
Fggmmpspaqapmwbn1fjq

Code

Intent SchemaJSON
{
  "intents": [
    {
      "intent": "SearchEvents",
      "slots": [
        {
          "name": "City",
          "type": "CITY"
        },
        {
          "name": "Date",
          "type": "AMAZON.DATE"
        }
      ]
    },
    {
      "intent": "SpecifyCity",
      "slots": [
        {
          "name": "City",
          "type": "CITY"
        }
      ]
    },
    {
      "intent": "ShouldGetMoreInfo",
      "slots": [
        {
          "name": "YesNo",
          "type": "YES_NO"
        }
      ]
    },
    {
      "intent": "SpecifyEvent",
      "slots": [
        {
          "name": "EventNumber",
          "type": "AMAZON.NUMBER"
        }
      ]
    },
    {
      "intent": "AMAZON.HelpIntent"
    },
    {
      "intent": "AMAZON.StopIntent"
    },
    {
      "intent": "AMAZON.CancelIntent"
    }
  ]
}
Sample Utterancessnippets
SearchEvents what to do in {City}
SearchEvents what's' going on in {City}
SearchEvents what events are in {City}
SearchEvents about events in {City}
SearchEvents what events in {City}
SearchEvents what to do in {City}
SearchEvents search events in {City}
SearchEvents what's' going on in {City} on {Date}
SearchEvents what's' going on in {City} {Date}
SearchEvents what events are in {City} on {Date}
SearchEvents what events are in {City} {Date}
SearchEvents about events in {City} on {Date}
SearchEvents about events in {City} {Date}
SearchEvents what events in {City} on {Date}
SearchEvents what events in {City} {Date}
SearchEvents what to do in {City} on {Date}
SearchEvents what to do in {City} {Date}
SearchEvents search events in {City} on {Date}
SearchEvents search events in {City} {Date}
SearchEvents what's' going on {Date} in {City}
SearchEvents what events are on {Date} in {City}
SearchEvents about events in {Date} {City}
SearchEvents what to do on {Date} in {City}
SearchEvents what to do {Date} in {City}
SearchEvents search events on {Date} in {City}
SpecifyCity {City}
SpecifyCity in {City}
SpecifyCity about {City}
ShouldGetMoreInfo {YesNo}
SpecifyEvent {EventNumber}
SpecifyEvent event number {EventNumber}
SpecifyEvent number {EventNumber}
Lambda Fuction CodeJavaScript
The URL of the external API has been removed from the script
var APP_ID = /* removed */;

var AlexaSkill = require('./AlexaSkill');
var http = require("http");
var CryptoJS = require("crypto-js");

var GOODBYE_SENTENCES = ["Have a nice day!", "Goodbye!", "Bye!", "Cheers!"];
var EVENTS_KEY = "eventsJson";
var CARDTEXT_KEY = "cardText";

var EventMaster = function () {
    AlexaSkill.call(this, APP_ID);
};

EventMaster.prototype = Object.create(AlexaSkill.prototype);
EventMaster.prototype.constructor = EventMaster;

EventMaster.prototype.eventHandlers.onSessionStarted = function (sessionStartedRequest, session) {
    console.log("EventMaster onSessionStarted requestId: " + sessionStartedRequest.requestId
        + ", sessionId: " + session.sessionId);

    // any session init logic would go here
};

EventMaster.prototype.eventHandlers.onLaunch = function (launchRequest, session, response) {
    console.log("EventMaster onLaunch requestId: " + launchRequest.requestId + ", sessionId: " + session.sessionId);
    getWelcomeResponse(session, response);
};

EventMaster.prototype.eventHandlers.onSessionEnded = function (sessionEndedRequest, session) {
    console.log("EventMaster onSessionEnded requestId: " + sessionEndedRequest.requestId
        + ", sessionId: " + session.sessionId);

    // any session cleanup logic would go here
};

EventMaster.prototype.intentHandlers = {
    "SearchEvents": function (intent, session, response) {
        getEventsResponse(intent, session, response);
    },
	
	"SpecifyCity": function (intent, session, response) {
        getEventsResponse(intent, session, response);
    },
	
	"ShouldGetMoreInfo": function (intent, session, response) {
        shouldGetMoreInfo(intent, session, response);
    },
	
	"SpecifyEvent": function (intent, session, response) {
        getMoreEventInfo(intent, session, response);
    },

    "AMAZON.HelpIntent": function (intent, session, response) {
        getWelcomeResponse(session, response);
    },

    "AMAZON.StopIntent": function (intent, session, response) {
        response.tell(GOODBYE_SENTENCES[Math.floor(Math.random() * GOODBYE_SENTENCES.length)]);
    },

    "AMAZON.CancelIntent": function (intent, session, response) {
        response.tell(GOODBYE_SENTENCES[Math.floor(Math.random() * GOODBYE_SENTENCES.length)]);
    }
};

function getEventsResponse(intent, session, response) {
	var outText = '';
	
	var city = intent.slots.City;
	if (typeof city === 'undefined' || !('value' in city))
	{
		getWelcomeResponse(session, response);
	}
	
	var url = /* removed */ + "?location=" + city.value;
	
	var date = intent.slots.Date;
	if (typeof date !== 'undefined' && 'value' in date)
	{
	    url = url + "&date=" + date.value;
	}
	
	console.log("Calling URL: " + url)
	
	http.get(url, function (result) {
		console.log('Response code: ' + result.statusCode);
		
		if (result.statusCode == 200) {
			outText = 'Done!';
			var body = '';
			result.on('data', function (chunk) {
				body += chunk;
			});
			result.on('end', function () {
				
				var responseObject = JSON.parse(body);
				session.attributes[EVENTS_KEY] = body;

				if (responseObject['status'] === 'CITY_NOT_FOUND' || responseObject['status'] === 'EVENTS_NOT_FOUND') {
					console.log("city or events not found");
					outText = responseObject['textToSay'];
					var responseType = AlexaSkill.speechOutputType.PLAIN_TEXT;
					console.log(responseObject['responseType']);
					if (responseObject['responseType'] === 'SSML') {
						responseType = AlexaSkill.speechOutputType.SSML;
					}
					var speechOutput = {
						speech: outText,
						type: responseType
					};
					response.tell(speechOutput);
				} else {
					console.log("city found");
					outText = responseObject['textToSay'];
					var responseType = AlexaSkill.speechOutputType.PLAIN_TEXT;
					console.log(responseObject['responseType']);
					if (responseObject['responseType'] === 'SSML') {
						responseType = AlexaSkill.speechOutputType.SSML;
					}
					console.log(responseType);
					var speechOutput = {
						speech: outText,
						type: responseType
					};
					
					var repromptOutput = {
						speech: "Would you like to hear more? Say yes or no.",
						type: AlexaSkill.speechOutputType.PLAIN_TEXT
					};
					
					session.attributes[CARDTEXT_KEY] = responseObject['cardContent'];
					var cardTitle = responseObject['cardTitle'];
					var cardContent = responseObject['cardContent'];
					response.askWithCard(speechOutput, repromptOutput, cardTitle, cardContent);
				}
			});
		}
		else
		{
			outText = 'There was a problem, I am not able to retrieve information from Internet. Sorry!';
			var speechOutput = {
				speech: outText,
				type: AlexaSkill.speechOutputType.PLAIN_TEXT
			};
			response.tell(speechOutput);
		}
		
	});
}

function shouldGetMoreInfo(intent, session, response) {
	if (typeof session.attributes[EVENTS_KEY] === "undefined") {
		getWelcomeResponse(session, response)
	} else {
		var answer = intent.slots.YesNo;
		if (typeof answer !== 'undefined' && ('value' in answer) &&
			answer.value.toLowerCase() === 'yes') 
		{
			var events = JSON.parse(session.attributes[EVENTS_KEY]);
			
			if (events['events'].length == 1)
			{
				getMoreEventInfo(intent, session, response);
				return;
			}
			
			var speechText = "Good. Tell me the number of the event on which you are interested about: ";
			var numberList = "";
			for (var i = 0; i < events['events'].length; i++) {
				if (i == (events['events'].length - 1))
				{
					numberList = numberList + " or " + (i + 1);
				}
				else if (i == 0)
				{
					numberList = numberList + (i + 1);
				}
				else
				{
					numberList = numberList + ", " + (i + 1);
				}
			}
			
			var speechOutput = {
				speech: speechText + numberList,
				type: AlexaSkill.speechOutputType.PLAIN_TEXT
			};
			
			var repromptOutput = {
				speech: "Please specify the number of the event: " + numberList,
				type: AlexaSkill.speechOutputType.PLAIN_TEXT
			};
			
			var cardTitle = "Event Choice";
			var cardContent = session.attributes[CARDTEXT_KEY];
			
			response.askWithCard(speechOutput, repromptOutput, cardTitle, cardContent);
		}
		else
		{
			response.tell("Ok fine. " + GOODBYE_SENTENCES[Math.floor(Math.random() * GOODBYE_SENTENCES.length)]);
		}
	}
}

function getMoreEventInfo(intent, session, response) {
	if (typeof session.attributes[EVENTS_KEY] === "undefined") {
		getWelcomeResponse(session, response)
	} else {
		var events = JSON.parse(session.attributes[EVENTS_KEY]);
		var eventNumber = intent.slots.EventNumber;
		
		if (events['events'].length == 1 || (typeof eventNumber !== 'undefined' && ('value' in eventNumber) &&
			eventNumber.value > 0 && eventNumber.value <= events['events'].length))
		{
			var index = 0;
			if (events['events'].length == 1)
			{
				index = 0;
			}
			else
			{
				index = parseInt(eventNumber.value) - 1;
			}
			
			console.log(index);
			var speech = "";
			speech += events['events'][index]['name'] + ".\n ";
			speech += events['events'][index]['infoDescriptionHeader'] + ".\n ";
			speech += events['events'][index]['description'];
			
			var cardText = events['events'][index]['name'] + "\n";
			cardText += events['events'][index]['address'] + "\n";
			cardText += events['events'][index]['description'] + "\n\n";
			cardText += events['events'][index]['url'] + "\n\n";
			
			var cardTitle = events['events'][index]['name'];
			
			response.tellWithCard(speech, cardTitle, cardText);
		}
		else
		{
			response.tell("Sorry, the event number is not valid.");
		}
	}
}

function getWelcomeResponse(session, response) {
	var speechText = "Welcome to the Event Master. Tell me the city, or city plus the date, and I will tell you what events are on the schedule. Which city are you interested about?";
	var repromptText = "Please tell me a city.";
	var speechOutput = {
		speech: speechText,
		type: AlexaSkill.speechOutputType.PLAIN_TEXT
	};
	var repromptOutput = {
		speech: repromptText,
		type: AlexaSkill.speechOutputType.PLAIN_TEXT
	};
	response.ask(speechOutput, repromptOutput);
}

// Create the handler that responds to the Alexa Request.
exports.handler = function (event, context) {
    var eventMaster = new EventMaster();
    eventMaster.execute(event, context);
};

Credits

9b04fb2e94b94892f738dc5cf6879863
Alessio Barducci
0 projects • 1 follower
Contact

Replications

Did you replicate this project? Share it!

I made one

Love this project? Think it could be improved? Tell us what you think!

Give feedback

Comments

Sign up / LoginProjectsPlatformsTopicsContestsLiveAppsBetaBlog