Paul Langdon
Published © CC BY-SA

AntonymScalia

Ask Alexa what the opposite word for fast is and she will tell you. Alexa will make you sound smarter as you broaden your vocabulary.

IntermediateProtip1 hour579
AntonymScalia

Things used in this project

Story

Read more

Schematics

VUI

Code

Lambda Service

JavaScript
// Route the incoming request based on type (LaunchRequest, IntentRequest,
// etc.) The JSON body of the request is provided in the event parameter.

var http = require('http');

exports.handler = function (event, context) {
    try {
        console.log("event.session.application.applicationId=" + event.session.application.applicationId);

        /**
         * Uncomment this if statement and populate with your skill's application ID to
         * prevent someone else from configuring a skill that sends requests to this function.
         */
        /*
        if (event.session.application.applicationId !== "amzn1.echo-sdk-ams.app.[unique-value-here]") {
             context.fail("Invalid Application ID");
        }
        */

        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;

    // Dispatch to your skill's intent handlers
    if ("SynonymIntent" === intentName) {
        getSyn(intent, session, callback);
    } else if ("AMAZON.HelpIntent" === intentName) {
        getHelpResponse(callback);
    } else if ("AMAZON.StopIntent" === intentName || "AMAZON.CancelIntent" === intentName) {
        handleSessionEndRequest(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
}

// --------------- Functions that control the skill's behavior -----------------------

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 Antonym Scalia. " +
        "Please ask me a single word you would like a antonym for. Only single words, for example fast and not fat cat.";
    // 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 = "You can get help by saying, " +
       "help!";
    var shouldEndSession = false;

    callback(sessionAttributes,
        buildSpeechletResponse(cardTitle, speechOutput, repromptText, shouldEndSession));
}

function getHelpResponse(callback) {
    // If we wanted to initialize the session to have some attributes we could add those here.
    var sessionAttributes = {};
    var cardTitle = "Welcome";
    var speechOutput = "To use Antonym Scalia " +
        "you may ask me a word you would like a antonym for. Only single words, for example fast and not fat cat.";
    // 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 = "Just say the word you want the antonym for.";
    
    var shouldEndSession = false;

    callback(sessionAttributes,
        buildSpeechletResponse(cardTitle, speechOutput, repromptText, shouldEndSession));
}

function handleSessionEndRequest(callback) {
    var cardTitle = "Session Ended";
    var speechOutput = "Thank you for using Antonym Scalia to make yourself look smart. Have a nice day!";
    // Setting this to true ends the session and exits the skill.
    var shouldEndSession = true;

    callback({}, buildSpeechletResponse(cardTitle, speechOutput, null, shouldEndSession));
}



function makeTheoRequest(word, theoResponseCallback) {
    
   if (word===undefined) {
     theoResponseCallback(new Error('undefined'));
   }
   
   console.log(`Got word: ${word}`);


  var query_url ='http://words.bighugelabs.com/api/2/yourkeyhere/' + word + '/json';
  var body = '';
  var jsonObject;

  http.get(query_url, (res) => {
    console.log(`Got response: ${res.statusCode}`);
    if (res.statusCode==200) {
        res.setEncoding('utf8');
        res.on('data', function (chunk) {
          body += chunk;
        });
        res.on('end', () => {
          console.log("RequestBody: " + body)
          jsonObject = JSON.parse(body);
          
           theoResponseCallback(null, body);
       
        })
    }
    else if (res.statusCode==303) {
        console.log("RequestBody: " + res.statusMessage);
        query_url ='http://words.bighugelabs.com/api/2/66085f7fc451de7a05f363da7981c898/' +res.statusMessage + '/json';
        console.log("url: " + query_url);
        http.get(query_url, (res2) => {
            console.log(`Got response: ${res2.statusCode}`);
            res2.setEncoding('utf8');
            res2.on('data', function (chunk) {
              body += chunk;
            });
            res2.on('end', () => {
              console.log("RequestBody: " + body)
              jsonObject = JSON.parse(body);
              
               theoResponseCallback(null, body);
            
            })
            });
    
    }
    else {
      console.log(`Got error: ${res.statusCode}`);
      theoResponseCallback(new Error(res.statusCode));
    }
  }).on('error', (e) => {
    console.log(`Got error: ${e.message}`);
     theoResponseCallback(new Error(e.message));
  });
}




function getSyn(intent, session, callback) {
    var repromptText = null;
    var sessionAttributes = {};
    var shouldEndSession = true;
    var speechOutput = "";
    var maxLength = 0;


 

    makeTheoRequest( intent.slots.queryword.value, function theoResponseCallback(err, theoResponseBody) {
        var speechOutput;

        if (err) {
            if (err=='undefiend'){
                 speechOutput = "Sorry, Antonym Scalia can only handle single word, for example fast. Multiple words such as race car, marching band, tuna fish and golden retriever will not work.";
                shouldEndSession = false;
                repromptText = "Antonym Scalia can only handle single word, for example fast. Multiple words such as race car, marching band, tuna fish and golden retriever will not work.";
            }
            else {
                speechOutput = "Sorry, Antonym Scalia is experiencing a problem with your request. Try again or try a different singular word.";
                shouldEndSession = false;
                repromptText = "Antonym Scalia can only handle single word, for example fast. Multiple words such as race car, marching band, tuna fish and golden retriever will not work.";
            }
            
        } else {
            
            var theoResponse = JSON.parse(theoResponseBody);
            
            speechOutput = "Here's what I found: ";
            
            
             if (theoResponse.hasOwnProperty('noun')&&theoResponse.noun.hasOwnProperty('ant')){
                speechOutput += 'An antonym for ' + intent.slots.queryword.value;
                speechOutput += ', used as a noun, ';
                maxLength = Object.keys(theoResponse.noun.ant).length;
                if (Object.keys(theoResponse.noun.ant).length>5)
                {
                    maxLength = 5;
                }
                
                for(var i=0;i<maxLength;i++) {
                if (i>0){
                    speechOutput += ", or ";
                }
                speechOutput +=  theoResponse.noun.ant[i];
                
                }
                speechOutput += '. '
            }
            
            if (theoResponse.hasOwnProperty('verb')&&theoResponse.verb.hasOwnProperty('ant')){
                speechOutput +=  'An antonym for ' + intent.slots.queryword.value;
                speechOutput += ', used as a verb, ';
                maxLength = Object.keys(theoResponse.verb.ant).length;
                if (Object.keys(theoResponse.verb.ant).length>5)
                {
                    maxLength = 5;
                }
                
                for(var i=0;i<maxLength;i++) {
                if (i>0){
                    speechOutput += ", or ";
                }
                speechOutput +=  theoResponse.verb.ant[i];
                
                }
                speechOutput += '. '
            }
            
            
            if (theoResponse.hasOwnProperty('adverb')&&theoResponse.adverb.hasOwnProperty('ant')){
                speechOutput +=  'An antonym for ' + intent.slots.queryword.value;
                speechOutput += ', used as an adverb, ';
                maxLength = Object.keys(theoResponse.adverb.ant).length;
                if (Object.keys(theoResponse.adverb.ant).length>5)
                {
                    maxLength = 5;
                }
                
                for(var i=0;i<maxLength;i++) {
                if (i>0){
                    speechOutput += ", or ";
                }
                speechOutput +=  theoResponse.adverb.ant[i];
                
                }
                speechOutput += '. '
            }
            
            
            
            if (theoResponse.hasOwnProperty('adjective')&&theoResponse.adjective.hasOwnProperty('ant')){
                speechOutput +=  'An antonym for ' + intent.slots.queryword.value;
                speechOutput += ', used as an adjective, ';
                maxLength = Object.keys(theoResponse.adjective.ant).length;
                if (Object.keys(theoResponse.adjective.ant).length>5)
                {
                    maxLength = 5;
                }
                
                for(var i=0;i<maxLength;i++) {
                if (i>0){
                    speechOutput += ", or ";
                }
                speechOutput +=  theoResponse.adjective.ant[i];
                
                }
                speechOutput += '. '
            }
            
            
            
        }

        
        if (speechOutput==="Here's what I found: "){
            
            speechOutput = 'I cound not find an antonym for ' + intent.slots.queryword.value;
            speechOutput +=  '. My best advice is to use: not ' + intent.slots.queryword.value;
        }
        
        

        callback(sessionAttributes,
             buildSpeechletResponse(intent.name, speechOutput, repromptText, shouldEndSession));
    });
    
}


// --------------- Helpers that build all of the responses -----------------------

function buildSpeechletResponse(title, output, repromptText, shouldEndSession) {
    return {
        outputSpeech: {
            type: "PlainText",
            text: output
        },
        /*
        card: {
            type: "Simple",
            title: "SessionSpeechlet - " + title,
            content: "SessionSpeechlet - " + output
        },
        */
        reprompt: {
            outputSpeech: {
                type: "PlainText",
                text: repromptText
            }
        },
        shouldEndSession: shouldEndSession
    };
}

function buildResponse(sessionAttributes, speechletResponse) {
    return {
        version: "1.0",
        sessionAttributes: sessionAttributes,
        response: speechletResponse
    };
}

Intents

JSON
{
  "intents": [
    {
      "intent": "SynonymIntent",
      "slots": [
        {
          "name": "queryword",
          "type": "WORDS"
        }
      ]
    },
    {
      "intent": "AMAZON.HelpIntent"
    },
    {
      "intent": "AMAZON.StopIntent"
    },
    {
      "intent": "AMAZON.CancelIntent"
    }
  ]
}

Utterances

JSON
SynonymIntent what is the opposite word for {beauty|queryword}
SynonymIntent how else would I say the opposite {fast|queryword}
SynonymIntent what's a smart way to say the opposite of {slow|queryword}
SynonymIntent what's the opposite word for {happy|queryword}
SynonymIntent how would an english major say the opposite of {crazy|queryword}
SynonymIntent {bloated|queryword}

Credits

Paul Langdon

Paul Langdon

49 projects • 317 followers
Working as a cloud architect for an IoT hardware company

Comments