Introduction

Running out of idea what to cook? Try What's Cooking!

What's Cooking finds recipes that use as many of the given ingredients as possible and have as little as possible missing ingredients. It shows you the instructions of the recipe too.

Get started by saying something like "Alexa Ask what's cooking give me recipe for chicken".

You can add or remove ingredients. Say 'no' to get the next recipe and say 'yes' to get the instructions.

Since there are a lot of tutorials which describe how to setup lambda and Alexa skill. Please follow the link listed below to setup this skill.

Setup Alexa Skill

Follow Step 1. Setting up Your Alexa Skill in the Developer Portal of this guide.

Intent Schema and Sample Utterances are provided in the code section below.

Setup AWS Lambda

Follow Step 2: Creating Your Skill Logic Using AWS Lambda of this guide.

Use the index.js and package.json at the code section to setup the lambda zip file.

Refer to Alexa Skills Kit SDK for Node.js for details.

Link lambda to skill

Follow Step 3: Add Your Lambda Function to Your Skill of this guide.

Test the skill

Follow Step 4: Testing Your Skill of the same guide above.

Code (node.js)

First add required node libraries, setup app ID and registers skill handlers.

var Alexa = require("alexa-sdk"); var appId = 'amzn1.echo-sdk-ams.app.your-skill-id'; var unirest = require('unirest'); exports.handler = function(event, context, callback) { var alexa = Alexa.handler(event, context); alexa.appId = appId; alexa.dynamoDBTableName = 'whatsCooking'; alexa.registerHandlers(handlers); alexa.execute(); };

Then here are the handlers' implementation.

NewIngredientIntent handler starts a new ingredient list.

'NewIngredientIntent': function () { this.attributes['currentIndex'] = 0; var ingredients = this.event.request.intent.slots.ingredients; if (ingredients && ingredients.value) { this.attributes['ingredients'] = ingredients.value.split(" "); } else { this.attributes['ingredients'] = []; } this.emit('FindRecipes', this); },

AddIngredientIntent handler adds a new ingredient to the list.

'AddIngredientIntent': function () { this.attributes['currentIndex'] = 0; var newIngredientsList = []; var ingredientsToAdd = this.event.request.intent.slots.ingredients; if (ingredientsToAdd.value) { var ingredientsToAddArray = ingredientsToAdd.value.split(" "); newIngredientsList = this.attributes['ingredients'].concat(ingredientsToAddArray); newIngredientsList = newIngredientsList.filter( function(value, index, self) { return self.indexOf(value) === index; } ); this.attributes['ingredients'] = newIngredientsList; } this.emit('FindRecipes', this); },

RemoveIngredientIntent handler removes an ingredient from the list.

'RemoveIngredientIntent': function () { this.attributes['currentIndex'] = 0; var newIngredientsList = []; var ingredientsToRemove = this.event.request.intent.slots.ingredients; if (ingredientsToRemove.value) { var ingredientsToRemoveArray = ingredientsToRemove.value.split(" "); for (var i = 0; i < this.attributes['ingredients'].length; i++) { if (ingredientsToRemoveArray.indexOf(this.attributes['ingredients'][i]) === -1) { newIngredientsList.push(this.attributes['ingredients'][i]); } } this.attributes['ingredients'] = newIngredientsList; } this.emit('FindRecipes', this); },

YesIntent handler gets the instructions of the interested recipe, with the GetInstructions helper function.

// get instructions using rest call 'AMAZON.YesIntent': function () { this.emit('GetInstructions', this); },

GetInstructions helper function makes the REST API call to fetch the recipe's instructions.

'GetInstructions': function (that) { var url = "https://spoonacular-recipe-food-nutrition-v1.p.mashape.com/recipes/" + that.attributes['lastResult'][that.attributes['currentIndex']].id + "/information?includeNutrition=false"; unirest.get(url).header("X-Mashape-Key", "ZVrobra1Wgmshu4HXd0zXIDreW7wp1Fxv2MjsnbTtMiT0jmH9X") .header("Accept", "application/json") .end(function (result) { console.log(result.status, result.headers, result.body); var speechOutput = ''; if (!result.body.instructions) { speechOutput = "There is no instruction. Good-bye."; } else { speechOutput = "Here are the instructions: " + result.body.instructions; } that.emit(':tell', speechOutput); }); }

NoIntent handler get the next recipe from the returned list of recipes. At the end of the list, you will be asked to remove an ingredient so the different recipes will be fetched.

// get next recipe from last result 'AMAZON.NoIntent': function () { this.attributes['currentIndex']++; if (!this.attributes['currentIndex'] || !this.attributes['lastResult'] || !this.attributes['lastResult'].length) { this.emit('AMAZON.HelpIntent'); } else { var speechOutput = ''; var repromptSpeech = ''; if (this.attributes['lastResult'].length <= this.attributes['currentIndex']) { speechOutput = "No additional recipe containing " + this.attributes['ingredients'].join(" ") + " Try removing an ingredient."; repromptSpeech = "Try saying, remove " + this.attributes['ingredients'][0]; } else { speechOutput = "Do you like " + this.attributes['lastResult'][this.attributes['currentIndex']].title + "?"; repromptSpeech = "Or maybe you want to add or remove an ingredient?"; } this.emit(':ask', speechOutput, repromptSpeech); } },

FindRecipes handler makes the API call to fetch a list of recipes made with the list of ingredients. You can add and remove ingredients during the session to fine tune your search results.

'FindRecipes': function (that) { var url = "https://spoonacular-recipe-food-nutrition-v1.p.mashape.com/recipes/findByIngredients?fillIngredients=false&ingredients=" + this.attributes['ingredients'].join(",") +"&limitLicense=false&number=5&ranking=1"; unirest.get(url).header("X-Mashape-Key", "ZVrobra1Wgmshu4HXd0zXIDreW7wp1Fxv2MjsnbTtMiT0jmH9X") .header("Accept", "application/json") .end(function (result) { console.log(result.status, result.headers, result.body); var recipes = result.body; var speechOutput = ''; var repromptSpeech = ''; if (recipes.length == 0) { speechOutput = "No recipe containing " + that.attributes['ingredients'].join(" ") + " Try removing an ingredient."; repromptSpeech = "Try saying, remove " + that.attributes['ingredients'][0]; } else { that.attributes['lastResult'] = recipes; speechOutput = "Do you like " + recipes[0].title + "?"; repromptSpeech = "Or maybe you want to add or remove an ingredient?"; } that.emit(':ask', speechOutput, repromptSpeech); }); },

VUI

Skill Link

Here is the link.