Allen Helton
Created December 1, 2016

Beer Genius

Get all information you could want about any commercial beer!

84

Things used in this project

Hardware components

Amazon Echo
Amazon Alexa Amazon Echo
×1

Software apps and online services

Alexa Skills Kit
Amazon Alexa Alexa Skills Kit
AWS Lambda
Amazon Web Services AWS Lambda
BreweryDB
The public facing API I used to query the beer information

Story

Read more

Schematics

Web Schematic

This is the web schematic from the client (echo) to the web service

Code

index.js

JavaScript
This is the logic behind the web service for the skill
/**
 * App ID for the skill
 */
var APP_ID = 'amzn1.ask.skill.44da0b47-2e22-42f2-b842-23265a62199d'; 

var http = require('http');

/**
 * The AlexaSkill Module that has the AlexaSkill prototype and helper functions
 */
var AlexaSkill = require('./AlexaSkill');

/**
 * URL prefix to download beer data from BreweryDB
 */
var urlPrefix = 'http://api.brewerydb.com/v2/search?type=beer&format=json&withBreweries=y&q=';

/**
 * API Key for Brewery DB
 */
var API_KEY = '6cad244c5d5724aeff270899cc1db35c';

var url = function(beerName){
    if(beerName === null || beerName == undefined){
        beerName = "";
    }
	beerName = beerName.replace(" ", "%20");
	return urlPrefix + beerName + '&key=' + API_KEY;
};

var getJsonFromWebService = function(beerName, callback) {
    http.get(url(beerName), function(res) {
        var body = '';

        res.on('data', function (data) {
            body += data;
        });

        res.on('end', function () {
            var result = JSON.parse(body);
            callback(result);
        });
    }).on('error', function (e) {
        console.log("Got error: ", e);
    });
};

var handleGetBeerRequest = function (intent, session, response) {
    //console.log("handleGetBeerRequest. Has beerName: " + intent.slots.beerName);
    if(intent.slots.beerName === null || intent.slots.beerName == undefined || intent.slots.beerName.value === "" || intent.slots.beerName.value == undefined){
        var speechOutput = "Hmm. I didn't catch that. What beer would you like to know about?";
        var repromptOutput = "What beer would you like to know about?";
        response.ask(speechOutput, repromptOutput);
        
        return;
    }
    getJsonFromWebService(intent.slots.beerName.value, function(data){
		var speechText = "";
		var cardHeader = "";
		var cardContent = "";
		var beerName = intent.slots.beerName.value;
		var breweryName = "";
        if (data.length === 0 || data.data === null || data.data == undefined) {
            speechText = "I could not find a beer with the name " + intent.slots.beerName.value + ".";
            cardContent = speechText;
        } else {
			var searchableBeerName = beerName.toUpperCase();
            var foundBeer, potentialBeer;
            for(var i = 0; i < data.data.length; i++) {
              var beer = data.data[i];
              
              if((beer.name != undefined && beer.name.toUpperCase() == searchableBeerName) || (beer.nameDisplay != undefined && beer.nameDisplay.toUpperCase() == searchableBeerName)
              || (beer.name != undefined && beer.name.toUpperCase().startsWith(searchableBeerName)) || (beer.nameDisplay != undefined && beer.nameDisplay.toUpperCase().startsWith(searchableBeerName))){
                potentialBeer = beer;
				if(intent.slots.breweryName !== null && intent.slots.breweryName.value !== "" && intent.slots.breweryName != undefined  && intent.slots.breweryName.value != undefined){
				  breweryName = intent.slots.breweryName.value.toUpperCase();
                  var searchBreweryName = breweryName;
				  for(var bi = 0; bi < beer.breweries.length; bi++){
                    var brewery = beer.breweries[bi];
                    var name = brewery.name.toUpperCase();
                    var shortName = brewery.nameShortDisplay.toUpperCase();
                    if(name == searchBreweryName || shortName == searchBreweryName || name.startsWith(searchBreweryName) || shortName.startsWith(searchBreweryName) ){
                      foundBeer = beer;
                      break;
                    }
                  }
				}
				if(foundBeer != undefined){
                      break;
                }
              }
            }

            if(potentialBeer != undefined && foundBeer == undefined){
              foundBeer = potentialBeer;
            } else  if (potentialBeer == undefined && foundBeer == undefined){
              foundBeer = data.data[0];
            }
             
			if(foundBeer !== null){
			  speechText = foundBeer.nameDisplay + " is a " + foundBeer.abv + "% " + foundBeer.style.shortName + " from " + foundBeer.breweries[0].name 
			    + " in " + foundBeer.breweries[0].locations[0].locality + " " + foundBeer.breweries[0].locations[0].region;
				
				if(foundBeer.description != null && foundBeer.description != undefined){
				    speechText = speechText + " described by the brewer as, " + foundBeer.description + ".";
				}
				
			  cardContent = speechText;
			  cardHeader = beerName;
			  if(breweryName !== ""){
			  	cardHeader = cardHeader + " by " + breweryName;
			  }
			} else{
			  speechText = "I was unable to find a beer with the name " + beerName + ". Try asking about a different beer.";
			  cardHeader = "Could not find beer";
			}		
        }
		response.tellWithCard(speechText, cardHeader, cardContent);
	});	
};

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

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

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

    // This skill is all one-shot, so no session initialization logic needed.
};

BeerGeniusSkill.prototype.eventHandlers.onLaunch = function (launchRequest, session, response) {
    var output = "With Beer Genius, you can get the details for any beer. For example, you could say describe Sculpin by Ballast Point, or tell me about Prairie Bomb.";
    var reprompt = "What beer do you want to know about?";
	
	response.ask(output, reprompt);
	console.log("BeerGeniusSkill onLaunch requestId: " + launchRequest.requestId + ", sessionId: " + session.sessionId);
};

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

    // This skill is all one-shot, so no session cleanup logic needed.
};

BeerGeniusSkill.prototype.intentHandlers = {

    GetBeer: function (intent, session, response) {
        handleGetBeerRequest(intent, session, response);
    },    

    "AMAZON.HelpIntent": function (intent, session, response) {
        var speechText = "With Beer Genius, you can get the details for any beer.  " +
            "For example, you could say describe Sculpin by Ballast Point, or tell me about Prairie Bomb";
        var repromptText = "Which beer do you want to know about?";
        
        response.ask(speechText, repromptText);
    },
    
    "AMAZON.StopIntent": function (intent, session, response) {
        var speechText = "Goodbye.";
        response.tell(speechText);
    },

    "AMAZON.CancelIntent": function (intent, session, response) {
       var speechText = "Goodbye.";
        response.tell(speechText);
    }
};


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

Credits

Allen Helton

Allen Helton

1 project • 0 followers

Comments