Things used in this project

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

Code

index.jsJavaScript
'use strict';
const Alexa = require('alexa-sdk');

var APP_ID = undefined;

//This function returns a descriptive sentence about your data.  Before a user starts a quiz, they can ask about a specific data element,
//like "Delhi."  The skill will speak the sentence from this function, pulling the data values from the appropriate record in your data.
function getSpeechDescription(item)
{
  var sentence = "The capital of " + item.State_UT_Name + " is " + item.State_UT_Capital + ", and the abbreviation for " + item.State_UT_Name + " is <break strength='strong'/><say-as interpret-as='spell-out'>" + item.State_UT_Abbreviation + "</say-as>.  I've added " + item.State_UT_Name + " to your Alexa app.  Which other state or union territory would you like to know about?";
  return sentence;
}

//We have provided two ways to create your quiz questions.  The default way is to phrase all of your questions like: "What is X of Y?"
//If this approach doesn't work for your data, take a look at the commented code in this function.  You can write a different question
//structure for each property of your data.
function getQuestion(counter, property, item)
{
    return "Here is your " + counter + "th question.  What is the " + formatCasing(property) + " of "  + item.State_UT_Name + "?";

    /*
    switch(property)
    {
        case "City":
            return "Here is your " + counter + "th question.  In what city do the " + item.League + "'s "  + item.Mascot + " play?";
        break;
        case "Sport":
            return "Here is your " + counter + "th question.  What sport do the " + item.City + " " + item.Mascot + " play?";
        break;
        case "HeadCoach":
            return "Here is your " + counter + "th question.  Who is the head coach of the " + item.City + " " + item.Mascot + "?";
        break;
        default:
            return "Here is your " + counter + "th question.  What is the " + formatCasing(property) + " of the "  + item.Mascot + "?";
        break;
    }
    */
}

//This is the function that returns an answer to your user during the quiz.  Much like the "getQuestion" function above, you can use a
//switch() statement to create different responses for each property in your data.  For example, when this quiz has an answer that includes
//a state abbreviation, we add some SSML to make sure that Alexa spells that abbreviation out (instead of trying to pronounce it.)
function getAnswer(property, item)
{
    switch(property)
    {
        case "Abbreviation":
            return "The " + formatCasing(property) + " of " + item.State_UT_Name + " is <say-as interpret-as='spell-out'>" + item[property] + "</say-as>. "
        break;
        default:
            return "The " + formatCasing(property) + " of " + item.State_UT_Name + " is " + item[property] + ". "
        break;
    }
}

//This is a list of positive speechcons that this skill will use when a user gets a correct answer.  For a full list of supported
//speechcons, go here: https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/speechcon-reference
var speechConsCorrect = ["Booya", "All righty", "Bam", "Bazinga", "Bingo", "Boom", "Bravo", "Cha Ching", "Cheers", "Dynomite", 
"Hip hip hooray", "Hurrah", "Hurray", "Huzzah", "Oh dear.  Just kidding.  Hurray", "Kaboom", "Kaching", "Oh snap", "Phew", 
"Righto", "Way to go", "Well done", "Whee", "Woo hoo", "Yay", "Wowza", "Yowsa"];

//This is a list of negative speechcons that this skill will use when a user gets an incorrect answer.  For a full list of supported
//speechcons, go here: https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/speechcon-reference
var speechConsWrong = ["Argh", "Aw man", "Blarg", "Blast", "Boo", "Bummer", "Darn", "D'oh", "Dun dun dun", "Eek", "Honk", "Le sigh",
"Mamma mia", "Oh boy", "Oh dear", "Oof", "Ouch", "Ruh roh", "Shucks", "Uh oh", "Wah wah", "Whoops a daisy", "Yikes"];

//This is the welcome message for when a user starts the skill without a specific intent.
var WELCOME_MESSAGE = "Welcome to the India States Quiz Game!  You can ask me about any of the thirty-six states and union territories,  and their capitals, or you can ask me to start a quiz.  What would you like to do?";  

//This is the message a user will hear when they start a quiz.
var START_QUIZ_MESSAGE = "OK.  I will ask you 10 questions about India.";

//This is the message a user will hear when they try to cancel or stop the skill, or when they finish a quiz.
var EXIT_SKILL_MESSAGE = "Thank you for playing the India Quiz Game!  Let's play again soon!";

//This is the message a user will hear after they ask (and hear) about a specific data element.
var REPROMPT_SPEECH = "Which other state or capital would you like to know about?";

//This is the message a user will hear when they ask Alexa for help in your skill.
var HELP_MESSAGE = "I know lots of things about India.  You can ask me about a state or a capital, and I'll tell you what I know.  You can also test your knowledge by asking me to start a quiz.  What would you like to do?";


//This is the response a user will receive when they ask about something we weren't expecting.  For example, say "pizza" to your
//skill when it starts.  This is the response you will receive.
function getBadAnswer(item) { return "I'm sorry. " + item + " is not something I know very much about in this skill. " + HELP_MESSAGE; }

//This is the message a user will receive after each question of a quiz.  It reminds them of their current score.
function getCurrentScore(score, counter) { return "Your current score is " + score + " out of " + counter + ". "; }

//This is the message a user will receive after they complete a quiz.  It tells them their final score.
function getFinalScore(score, counter) { return "Your final score is " + score + " out of " + counter + ". "; }

//These next four values are for the Alexa cards that are created when a user asks about one of the data elements.
//This only happens outside of a quiz.

//If you don't want to use cards in your skill, set the USE_CARDS_FLAG to false.  If you set it to true, you will need an image for each
//item in your data.
var USE_CARDS_FLAG = true;

//This is what your card title will be.  For our example, we use the name of the state the user requested.
function getCardTitle(item) { return item.State_UT_Name;}

//This is the small version of the card image.  We use our data as the naming convention for our images so that we can dynamically
//generate the URL to the image.  The small image should be 720x400 in dimension.
function getSmallImage(item) { return "https://m.media-amazon.com/images/G/01/mobile-apps/dex/alexa/alexa-skills-kit/tutorials/quiz-game/state_flag/720x400/" + item.Abbreviation + "._TTH_.png"; }

//This is the large version of the card image.  It should be 1200x800 pixels in dimension.
function getLargeImage(item) { return "https://m.media-amazon.com/images/G/01/mobile-apps/dex/alexa/alexa-skills-kit/tutorials/quiz-game/state_flag/1200x800/" + item.Abbreviation + "._TTH_.png"; }

//=========================================================================================================================================
//TODO: Replace this data with your own.
//=========================================================================================================================================
var data = [
                {State_UT_Name: "Andaman and Nicober Islands",  State_UT_Capital: "Port Blair" , State_UT_Abbreviation: "AN"},
                {State_UT_Name: "Chandigarh",  State_UT_Capital: "Chandigarh", State_UT_Abbreviation: "CH"},
                {State_UT_Name: "Dadra and Nagar Haveli", State_UT_Capital: "Silvassa", State_UT_Abbreviation: "DN"},
                {State_UT_Name: "Daman and Diu",  State_UT_Capital: "Daman", State_UT_Abbreviation: "DD"},
                {State_UT_Name: "Delhi",  State_UT_Capital: "Delhi", State_UT_Abbreviation: "DL"},
                {State_UT_Name: "Lakshadweep",  State_UT_Capital: "Kavaratti", State_UT_Abbreviation: "LD"},
                {State_UT_Name: "Puducherry",  State_UT_Capital: "Puducherry", State_UT_Abbreviation: "PY"},
                {State_UT_Name: "Andhra Pradesh",  State_UT_Capital: "Hyderabad", State_UT_Abbreviation: "AP"},
                {State_UT_Name: "Arunachal Pradesh",  State_UT_Capital: "Itanagar", State_UT_Abbreviation: "AR"},
                {State_UT_Name: "Assam",  State_UT_Capital: "Dispur", State_UT_Abbreviation: "AS"},
                {State_UT_Name: "Bihar",  State_UT_Capital: "Patna", State_UT_Abbreviation: "BR"},
                {State_UT_Name: "Chhattisgarh",  State_UT_Capital: "Naya Raipur", State_UT_Abbreviation: "CT"},
                {State_UT_Name: "Goa",  State_UT_Capital: "Panaji", State_UT_Abbreviation: "GA"},
                {State_UT_Name: "Gujarat",  State_UT_Capital: "Gandhinagar", State_UT_Abbreviation: "GJ"},
                {State_UT_Name: "Haryana",  State_UT_Capital: "Chandigarh", State_UT_Abbreviation: "HR"},
                {State_UT_Name: "Himachal Pradesh",  State_UT_Capital: "Shimla", State_UT_Abbreviation: "HP"},
                {State_UT_Name: "Jammu and Kashmir",  State_UT_Capital: "Srinagar during Summer and Jammu during Winter", State_UT_Abbreviation: "JK"},
                {State_UT_Name: "Jharkhand",  State_UT_Capital: "Ranchi", State_UT_Abbreviation: "JH"},
                {State_UT_Name: "Karnataka",  State_UT_Capital: "Bengaluru", State_UT_Abbreviation: "KA"},
                {State_UT_Name: "Kerala",  State_UT_Capital: "Thiruvananthapuram", State_UT_Abbreviation: "KL"},
                {State_UT_Name: "Madhya Pradesh",  State_UT_Capital: "Bhopal", State_UT_Abbreviation: "MP"},
                {State_UT_Name: "Maharashtra",  State_UT_Capital: "Mumbai", State_UT_Abbreviation: "MH"},
                {State_UT_Name: "Manipur",  State_UT_Capital: "Imphal", State_UT_Abbreviation: "MN"},
                {State_UT_Name: "Meghalaya",  State_UT_Capital: "Shillong", State_UT_Abbreviation: "ML"},
                {State_UT_Name: "Mizoram",  State_UT_Capital: "Aizawl", State_UT_Abbreviation: "MZ"},
                {State_UT_Name: "Nagaland",  State_UT_Capital: "Kohima", State_UT_Abbreviation: "NL"},
                {State_UT_Name: "Odisha",  State_UT_Capital: "Bhubaneswar", State_UT_Abbreviation: "OR"},
                {State_UT_Name: "Punjab",  State_UT_Capital: "Chandigarh", State_UT_Abbreviation: "PB"},
                {State_UT_Name: "Rajasthan",  State_UT_Capital: "Jaipur", State_UT_Abbreviation: "RJ"},
                {State_UT_Name: "Sikkim",  State_UT_Capital: "Gangtok", State_UT_Abbreviation: "SK"},
                {State_UT_Name: "Tamil Nadu",  State_UT_Capital: "Chennai", State_UT_Abbreviation: "TN"},
                {State_UT_Name: "Telangana",  State_UT_Capital: "Hyderabad", State_UT_Abbreviation: "TG"},
                {State_UT_Name: "Tripura",  State_UT_Capital: "Agartala", State_UT_Abbreviation: "TR"},
                {State_UT_Name: "Uttar Pradesh",  State_UT_Capital: "Dehradun", State_UT_Abbreviation: "UP"},
                {State_UT_Name: "Uttarakhand",  State_UT_Capital: "Lucknow", State_UT_Abbreviation: "UT"},
                {State_UT_Name: "West Bengal",  State_UT_Capital: "Kolkata", State_UT_Abbreviation: "WB"}
           ];

//=========================================================================================================================================
//Editing anything below this line might break your skill.  
//=========================================================================================================================================

var counter = 0;

var states = {
    START: "_START",
    QUIZ: "_QUIZ"
};

const handlers = {
     "LaunchRequest": function() {
        this.handler.state = states.START;
        this.emitWithState("Start");
     },
    "QuizIntent": function() {
        this.handler.state = states.QUIZ;
        this.emitWithState("Quiz");
    },
    "AnswerIntent": function() {
        this.handler.state = states.START;
        this.emitWithState("AnswerIntent");
    },
    "AMAZON.HelpIntent": function() {
        this.emit(":ask", HELP_MESSAGE, HELP_MESSAGE);
    },
    "Unhandled": function() {
        this.handler.state = states.START;
        this.emitWithState("Start");
    }
};

var startHandlers = Alexa.CreateStateHandler(states.START,{
    "Start": function() {
        this.emit(":ask", WELCOME_MESSAGE, HELP_MESSAGE);
    },
    "AnswerIntent": function() {
        var item = getItem(this.event.request.intent.slots);

        if (item[Object.getOwnPropertyNames(data[0])[0]] != undefined)
        {
            if (USE_CARDS_FLAG)
            {
                var imageObj = {smallImageUrl: getSmallImage(item), largeImageUrl: getLargeImage(item)};
                this.emit(":askWithCard", getSpeechDescription(item), REPROMPT_SPEECH, getCardTitle(item), getTextDescription(item), imageObj);
            }
            else
            {
                this.emit(":ask", getSpeechDescription(item), REPROMPT_SPEECH);
            }
        }
        else
        {
            this.emit(":ask", getBadAnswer(item), getBadAnswer(item));
            
        }
    },
    "QuizIntent": function() {
        this.handler.state = states.QUIZ;
        this.emitWithState("Quiz");
    },
    "AMAZON.StopIntent": function() {
        this.emit(":tell", EXIT_SKILL_MESSAGE);
    },
    "AMAZON.CancelIntent": function() {
        this.emit(":tell", EXIT_SKILL_MESSAGE);
    },
    "AMAZON.HelpIntent": function() {
        this.emit(":ask", HELP_MESSAGE, HELP_MESSAGE);
    },
    "Unhandled": function() {
        this.emitWithState("Start");
    }
});


var quizHandlers = Alexa.CreateStateHandler(states.QUIZ,{
    "Quiz": function() {
        this.attributes["response"] = "";
        this.attributes["counter"] = 0;
        this.attributes["quizscore"] = 0;
        this.emitWithState("AskQuestion");
    },
    "AskQuestion": function() {
        if (this.attributes["counter"] == 0)
        {
            this.attributes["response"] = START_QUIZ_MESSAGE + " ";
        }

        var random = getRandom(0, data.length-1);
        var item = data[random];

        var propertyArray = Object.getOwnPropertyNames(item);
        var property = propertyArray[getRandom(1, propertyArray.length-1)];

        this.attributes["quizitem"] = item;
        this.attributes["quizproperty"] = property;
        this.attributes["counter"]++;

        var question = getQuestion(this.attributes["counter"], property, item);
        var speech = this.attributes["response"] + question;

        this.emit(":ask", speech, question);
    },
    "AnswerIntent": function() {
        var response = "";
        var item = this.attributes["quizitem"];
        var property = this.attributes["quizproperty"]

        var correct = compareSlots(this.event.request.intent.slots, item[property]);

        if (correct)
        {
            response = getSpeechCon(true);
            this.attributes["quizscore"]++;
        }
        else
        {
            response = getSpeechCon(false);
        }

        response += getAnswer(property, item);

        if (this.attributes["counter"] < 10)
        {
            response += getCurrentScore(this.attributes["quizscore"], this.attributes["counter"]);
            this.attributes["response"] = response;
            this.emitWithState("AskQuestion");
        }
        else
        {
            response += getFinalScore(this.attributes["quizscore"], this.attributes["counter"]);
            this.emit(":tell", response + " " + EXIT_SKILL_MESSAGE);
        }
    },
    "AMAZON.StartOverIntent": function() {
        this.emitWithState("Quiz");
    },
    "AMAZON.StopIntent": function() {
        this.emit(":tell", EXIT_SKILL_MESSAGE);
    },
    "AMAZON.CancelIntent": function() {
        this.emit(":tell", EXIT_SKILL_MESSAGE);
    },
    "AMAZON.HelpIntent": function() {
        this.emit(":ask", HELP_MESSAGE, HELP_MESSAGE);
    },
    "Unhandled": function() {
        this.emitWithState("AnswerIntent");
    }
});

function compareSlots(slots, value)
{
    for (var slot in slots)
    {
        if (slots[slot].value != undefined)
        {
            if (slots[slot].value.toString().toLowerCase() == value.toString().toLowerCase())
            {
                return true;
            }
        }
    }
    return false;
}

function getRandom(min, max)
{
    return Math.floor(Math.random() * (max-min+1)+min);
}

function getRandomSymbolSpeech(symbol)
{
    return "<say-as interpret-as='spell-out'>" + symbol + "</say-as>";
}

function getItem(slots)
{
    var propertyArray = Object.getOwnPropertyNames(data[0]);
    var value;
    
    for (var slot in slots)
    {
        if (slots[slot].value !== undefined)
        {
            value = slots[slot].value;
            for (var property in propertyArray)
            {
                var item = data.filter(x => x[propertyArray[property]].toString().toLowerCase() === slots[slot].value.toString().toLowerCase());
                if (item.length > 0)
                {
                    return item[0];
                }
            }
        }
    }
    return value;
}

function getSpeechCon(type)
{
    var speechCon = "";
    if (type) return "<say-as interpret-as='interjection'>" + speechConsCorrect[getRandom(0, speechConsCorrect.length-1)] + "! </say-as><break strength='strong'/>";
    else return "<say-as interpret-as='interjection'>" + speechConsWrong[getRandom(0, speechConsWrong.length-1)] + " </say-as><break strength='strong'/>";    
}

function formatCasing(key)
{
    key = key.split(/(?=[A-Z])/).join(" ");
    return key;
}

function getTextDescription(item)
{
    var text = "";
    
    for (var key in item)
    {
        text += formatCasing(key) + ": " + item[key] + "\n";
    }
    return text;
}

exports.handler = (event, context) => {
    const alexa = Alexa.handler(event, context);
    alexa.appId = APP_ID;
    alexa.registerHandlers(handlers, startHandlers, quizHandlers);
    alexa.execute();
};
Intent SchemaJSON
Used in conjunction with Custom Slots - IN_STATE_UT, IN_CITY and IN_ABBR
{
  "intents": [
    {
      "slots": [
        {
          "name": "State_UT_Name",
          "type": "IN_STATE_UT"
        },
        {
          "name": "State_UT_Capital",
          "type": "IN_CITY"
        },
        {
          "name": "State_UT_Abbreviation",
          "type": "IN_ABBR"
        }
      ],
      "intent": "AnswerIntent"
    },
    {
      "intent": "QuizIntent"
    },
    {
      "intent": "AMAZON.StopIntent"
    },
    {
      "intent": "AMAZON.CancelIntent"
    },
    {
      "intent": "AMAZON.StartOverIntent"
    },
    {
      "intent": "AMAZON.HelpIntent"
    }
  ]
}
Sample UtterancesTextile
These are what people say to interact with your skill. Type or paste in all the ways that people can invoke the intents.

Up to 3 of these will be used as Example Phrases, which are hints to users.
AnswerIntent {State_UT_Name}
AnswerIntent {State_UT_Capital}
AnswerIntent {State_UT_Abbreviation}

AnswerIntent tell me about {State_UT_Name}
AnswerIntent tell me about {State_UT_Capital}
AnswerIntent tell me about {State_UT_Abbreviation}

AnswerIntent what do you know about {State_UT_Name}
AnswerIntent what do you know about {State_UT_Capital}
AnswerIntent what do you know about {State_UT_Abbreviation}

AnswerIntent {State_UT_Name} information
AnswerIntent {State_UT_Capital} information
AnswerIntent {State_UT_Abbreviation} information

QuizIntent start a quiz
QuizIntent start a quiz game
QuizIntent and start a quiz
QuizIntent and quiz me
QuizIntent for a quiz
QuizIntent a quiz

Credits

Professional
Rishabh Banga

Intel Software Innovator | Microsoft Certified Professional | IoT Evangelist

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

Similar projects you might like

Christmas Gift Box
Intermediate
  • 3,681
  • 595

Full instructions

Christmas Gift Box plays music and sends an email when it is opened.

IoT Red Phone
Intermediate
  • 2,828
  • 15

Work in progress

The phone will ring if you have an alert in your AWS Cloudwatch. If you pick up the handset, it tells you whats wrong.

Real-Time Workspace Occupancy Sensing Based on AWS IoT
Intermediate
  • 2,320
  • 13

Sensor-based presence detection for individual workstations: capturing occupancy trends and space utilization in real-time.

AWS IoT Environment for Home Assistant
Intermediate
  • 2,302
  • 13

Work in progress

Home Assistant is an automation platform that can track and control all kinds of devices and automate actions, which fits well with AWS IoT.

Bible Bee
Intermediate
  • 54
  • 0

Full instructions

A wonderful skill called BibleBee which tells you amazing unknown facts about THE GREATEST MAN WHO EVER LIVED ON THE EARTH - JESUS CHRIST. L

Bible Bee

Team care world

DRS for Sanitization needs of Baby
Intermediate
  • 1,186
  • 22

Full instructions

My Idea is about designing Amazon DRS enabled vending box for sanitizing needs of baby (i.e. baby diapers, baby soap and baby wipes).

Add projectSign up / Login