How to build "Compost Helper Alexa Skill"
Bài đăng này đã không được cập nhật trong 7 năm
Using Software apps and online services:
Step by step build "Alexa skill" I wanted to build a very simple skill that tells a user if an item can be added to compost. My hope is that a skill like this encourages others to do more composting (and reduce what is added to landfills). The skill is straight-forward: a user can ask about a specific item or for information about items in general (which prompt the skill to send a website link to the user).
"Alexa, ask Compost Helper can I compost newspaper?" "Alexa, ask Compost Helper can I compost rice?" "Alexa, ask Compost Helper what can I compost?"
Logic
The skill was written using the Fact Skill as a template, with the following key changes:
- I created a custom slot called "LIST_OF_ITEMS". This slot contains 100+ household items that a user might inquire about
- I created a JSON list of the items, with the following attributes: Item (oranges), Answer (yes), AddOn (" you add them in small amounts and you open split the fruit").
- I use the Fuse.js library to do "fizzy matching" against the JSON list to find the best match (e.g. napkins = paper napkins = used napkins)
- The JSON attributes are used to construct the reply: "Yes, you can compost oranges if you add them in small amounts and you split open the fruit"
User Interaction
The user interaction is straight-forward. A user asks if an item can be added to compost, and Alexa replies yes or no.
User: "Alexa, ask Compost Helper can I compost milk?" Alexa: "No, you cannot compost milk. "
If the user does not indicate an item, Alexa asks the user to provide an item to validate:
User: "Alexa, ask Compost Helper can I compost?" Alexa: "I did not hear the name of the item that you want me to validate. Can you tell me the item you are asking about? " User: "Coffee" Alexa: "Yes, you can compost coffee grounds."
Finally, Alexa provides a website with more information if the user wants to know what s/he can compost.
User: "Alexa, ask Compost Helper what can I compost?" Alexa: "There are a large number of items you can compost. I've sent a website to the Alexa app. Check out the site for a list of items you can compost."
CODE
- List of Items (JSON)
[
{
"item": "water",
"answer": "Yes",
"addOn": ""
},
{
"item": "fruit",
"answer": "Yes",
"addOn": ""
},
{
"item": "vegetables",
"answer": "Yes",
"addOn": ""
},
{
"item": "fruit scraps",
"answer": "Yes",
"addOn": ""
},
{
"item": "vegetable scraps",
"answer": "Yes",
"addOn": "you crush them first"
},
{
"item": "egg shells",
"answer": "Yes",
"addOn": ""
},
{
"item": "coffee grounds",
"answer": "Yes",
"addOn": ""
},
{
"item": "coffee filters",
"answer": "Yes",
"addOn": ""
},
{
"item": "tea bags",
"answer": "Yes",
"addOn": "they are made of natural materials. If in doubt, just compost the team leaves"
},
{
"item": "loose leaf tea",
"answer": "Yes",
"addOn": ""
},
{
"item": "tea leaves",
"answer": "Yes",
"addOn": ""
},
{
"item": "tea",
"answer": "Yes",
"addOn": ""
},
{
"item": "soy milk",
"answer": "Yes",
"addOn": "it only if it is spoiled"
},
{
"item": "rice milk",
"answer": "Yes",
"addOn": "it only if it is spoiled"
},
{
"item": "almond milk",
"answer": "Yes",
"addOn": "it only if it is spoiled"
},
{
"item": "coconut milk",
"answer": "Yes",
"addOn": "it only if it is spoiled"
},
{
"item": "paper napkins",
"answer": "Yes",
"addOn": "it is not dirty from oil, grease, or chemicals."
},
{
"item": "paper towels",
"answer": "Yes",
"addOn": "it is not dirty from oil, grease, or chemicals."
},
{
"item": "paper plates",
"answer": "Yes",
"addOn": "it is not waxy and not dirty from oil, grease, or chemicals."
},
{
"item": "pizza boxes",
"answer": "Yes",
"addOn": "it is unwaxed, and cut into small pieces"
},
{
"item": "paper bags",
"answer": "Yes",
"addOn": "it shredded"
},
{
"item": "Paper towel rolls",
"answer": "Yes",
"addOn": "it shredded"
},
{
"item": "Paper towel dowels",
"answer": "Yes",
"addOn": "it shredded"
},
{
"item": "crackers",
"answer": "Yes",
"addOn": "it is stale"
},
{
"item": "cereal",
"answer": "Yes",
"addOn": "it is stale"
},
{
"item": "nut shells",
"answer": "Yes",
"addOn": "they are not walnut shells"
},
{
"item": "tofu",
"answer": "Yes",
"addOn": "it is stale"
},
{
"item": "tempeh",
"answer": "Yes",
"addOn": "it is stale"
},
{
"item": "seaweed",
"answer": "Yes",
"addOn": ""
},
{
"item": "kelp",
"answer": "Yes",
"addOn": ""
},
{
"item": "nori",
"answer": "Yes",
"addOn": ""
},
{
"item": "popcorn kernels",
"answer": "Yes",
"addOn": "they are burnt or unpopped"
},
{
"item": "spices",
"answer": "Yes",
"addOn": ""
},
{
"item": "herbs",
"answer": "Yes",
"addOn": ""
},
{
"item": "pretzels",
"answer": "Yes",
"addOn": "they are stale"
},
{
"item": "candy",
"answer": "Yes",
"addOn": "it is stale and crushed or chopped"
},
{
"item": "protein bars",
"answer": "Yes",
"addOn": "they are stale"
},
{
"item": "energy bars",
"answer": "Yes",
"addOn": "they are stale"
},
{
"item": "pizza crusts",
"answer": "Yes",
"addOn": ""
},
{
"item": "oatmeal",
"answer": "Yes",
"addOn": ""
},
{
"item": "peanut shells",
"answer": "Yes",
"addOn": ""
},
{
"item": "egg cartons",
"answer": "Yes",
"addOn": "they are cardboard and are cut up"
},
{
"item": "pumpkin seeds",
"answer": "Yes",
"addOn": "they are cut up so they can't sprout"
},
{
"item": "sunflower seeds",
"answer": "Yes",
"addOn": "they are cut up so they can't sprout"
},
{
"item": "sesame seeds",
"answer": "Yes",
"addOn": "they are cut up so they can't sprout"
},
{
"item": "avocado pits",
"answer": "Yes",
"addOn": "they are cut up so they can't sprout"
},
{
"item": "wine corks",
"answer": "Yes",
"addOn": "they are chopped up"
},
{
"item": "jelly",
"answer": "Yes",
"addOn": ""
},
{
"item": "jam",
"answer": "Yes",
"addOn": ""
},
{
"item": "preserves",
"answer": "Yes",
"addOn": ""
},
{
"item": "beer",
"answer": "Yes",
"addOn": ""
},
{
"item": "wine",
"answer": "Yes",
"addOn": ""
},
{
"item": "pumpkin seeds",
"answer": "Yes",
"addOn": "you break the shell into smaller pieces"
},
{
"item": "pumpkins",
"answer": "Yes",
"addOn": ""
},
{
"item": "avocados",
"answer": "Yes",
"addOn": ""
},
{
"item": "avocado pits",
"answer": "Yes",
"addOn": "they are cut up so they can't sprout"
},
{
"item": "tomatoes",
"answer": "Yes",
"addOn": ""
},
{
"item": "oranges",
"answer": "Yes",
"addOn": "you have a small amout and you split open the fruit"
},
{
"item": "lemons",
"answer": "Yes",
"addOn": "you have a small amout and you split open the fruit"
},
{
"item": "limes",
"answer": "Yes",
"addOn": "you have a small amout and you split open the fruit"
},
{
"item": "grapefruits",
"answer": "Yes",
"addOn": ""
},
{
"item": "grapes",
"answer": "Yes",
"addOn": ""
},
{
"item": "melon",
"answer": "Yes",
"addOn": "you split open the fruit"
},
{
"item": "apples",
"answer": "Yes",
"addOn": ""
},
{
"item": "pears",
"answer": "Yes",
"addOn": ""
},
{
"item": "strawberries",
"answer": "Yes",
"addOn": ""
},
{
"item": "bananas",
"answer": "Yes",
"addOn": ""
},
{
"item": "mangoes",
"answer": "Yes",
"addOn": "you remove the mango stone"
},
{
"item": "pineapples",
"answer": "Yes",
"addOn": "you cut up the skin and crown"
},
{
"item": "potatoes",
"answer": "Yes",
"addOn": "you cut them into pieces to they don't sprout"
},
{
"item": "onions",
"answer": "Yes",
"addOn": "you cut them into pieces to they don't sprout"
},
{
"item": "broccoli",
"answer": "Yes",
"addOn": ""
},
{
"item": "carrots",
"answer": "Yes",
"addOn": ""
},
{
"item": "kale",
"answer": "Yes",
"addOn": ""
},
{
"item": "lettuce",
"answer": "Yes",
"addOn": ""
},
{
"item": "cucumbers",
"answer": "Yes",
"addOn": ""
},
{
"item": "parsnips",
"answer": "Yes",
"addOn": "you cut them into pieces"
},
{
"item": "olives",
"answer": "Yes",
"addOn": "you remove the pits and they are not covered in oil"
},
{
"item": "cauliflower",
"answer": "Yes",
"addOn": ""
},
{
"item": "peppers",
"answer": "Yes",
"addOn": ""
},
{
"item": "beans",
"answer": "Yes",
"addOn": ""
},
{
"item": "mushrooms",
"answer": "Yes",
"addOn": ""
},
{
"item": "corn",
"answer": "Yes",
"addOn": ""
},
{
"item": "corn on the cob",
"answer": "Yes",
"addOn": "you cut the cob into pieces"
},
{
"item": "corn cobs",
"answer": "Yes",
"addOn": "you cut the cob into pieces"
},
{
"item": "corn husks",
"answer": "Yes",
"addOn": ""
},
{
"item": "garlic",
"answer": "Yes",
"addOn": "you cut them into pieces to they don't sprout"
},
{
"item": "leeks",
"answer": "Yes",
"addOn": ""
},
{
"item": "spinach",
"answer": "Yes",
"addOn": ""
},
{
"item": "newspaper",
"answer": "Yes",
"addOn": "the newspaper is wet and you mix with other materials"
},
{
"item": "cardboard",
"answer": "Yes",
"addOn": "the cardboard is not shiny, which indcates it has a plastic coating"
},
{
"item": "shredded paper",
"answer": "Yes",
"addOn": ""
},
{
"item": "brown paper",
"answer": "Yes",
"addOn": ""
},
{
"item": "cut flowers",
"answer": "Yes",
"addOn": ""
},
{
"item": "toilet roll tubes",
"answer": "Yes",
"addOn": ""
},
{
"item": "flour",
"answer": "Yes",
"addOn": "you disperse it evenly in your compost pile"
},
{
"item": "oil",
"answer": "No",
"addOn": ""
},
{
"item": "motor oil",
"answer": "No",
"addOn": ""
},
{
"item": "olive oil",
"answer": "No",
"addOn": ""
},
{
"item": "milk",
"answer": "No",
"addOn": ""
},
{
"item": "cheese",
"answer": "No",
"addOn": ""
},
{
"item": "yogurt",
"answer": "No",
"addOn": ""
},
{
"item": "tampons",
"answer": "No",
"addOn": ""
},
{
"item": "condoms",
"answer": "No",
"addOn": ""
},
{
"item": "shampoo",
"answer": "No",
"addOn": ""
},
{
"item": "magazines",
"answer": "No",
"addOn": ""
},
{
"item": "take out menus",
"answer": "No",
"addOn": ""
},
{
"item": "diapers",
"answer": "No",
"addOn": ""
},
{
"item": "catalogs",
"answer": "No",
"addOn": ""
},
{
"item": "cream",
"answer": "No",
"addOn": ""
},
{
"item": "plums",
"answer": "No",
"addOn": ""
},
{
"item": "meat",
"answer": "No",
"addOn": ""
},
{
"item": "butter",
"answer": "No",
"addOn": ""
},
{
"item": "shortening",
"answer": "No",
"addOn": ""
},
{
"item": "cooking oil",
"answer": "No",
"addOn": ""
},
{
"item": "vegetable oil",
"answer": "No",
"addOn": ""
},
{
"item": "pasta",
"answer": "No",
"addOn": ""
},
{
"item": "rice",
"answer": "No",
"addOn": ""
},
{
"item": "cooked pasta",
"answer": "No",
"addOn": ""
},
{
"item": "cooked rice",
"answer": "No",
"addOn": ""
},
{
"item": "bread",
"answer": "No",
"addOn": ""
},
{
"item": "pitas",
"answer": "No",
"addOn": ""
},
{
"item": "tortillas",
"answer": "No",
"addOn": ""
},
{
"item": "potato chips",
"answer": "No",
"addOn": ""
},
{
"item": "tortilla chips",
"answer": "No",
"addOn": ""
},
{
"item": "fish",
"answer": "No",
"addOn": ""
},
{
"item": "seafood",
"answer": "No",
"addOn": ""
},
{
"item": "chicken",
"answer": "No",
"addOn": ""
},
{
"item": "poultry",
"answer": "No",
"addOn": ""
},
{
"item": "beef",
"answer": "No",
"addOn": ""
},
{
"item": "pork",
"answer": "No",
"addOn": ""
},
{
"item": "cakes",
"answer": "No",
"addOn": ""
},
{
"item": "pies",
"answer": "No",
"addOn": ""
},
{
"item": "desserts",
"answer": "No",
"addOn": ""
},
{
"item": "bakes beans",
"answer": "No",
"addOn": ""
},
{
"item": "face pads",
"answer": "No",
"addOn": ""
},
{
"item": "face wipes",
"answer": "No",
"addOn": ""
},
{
"item": "dog waste",
"answer": "No",
"addOn": ""
},
{
"item": "human waste",
"answer": "No",
"addOn": ""
},
{
"item": "wrapping paper",
"answer": "No",
"addOn": ""
},
{
"item": "gift paper",
"answer": "No",
"addOn": ""
},
{
"item": "wall paper",
"answer": "No",
"addOn": ""
},
{
"item": "pet waste",
"answer": "No",
"addOn": ""
},
{
"item": "cat waste",
"answer": "No",
"addOn": ""
},
{
"item": "cat litter",
"answer": "No",
"addOn": ""
}
]
CREDITS
- Index.js
/**
* Compost helper Alexa skill
* Darian Johnson @darianbjohnson (Twitter)
**/
'use strict';
const Alexa = require('alexa-sdk');
const APP_ID = undefined; // TODO replace with your app ID (OPTIONAL).
var list = require('./list_of_items.json');
var Fuse = require('fuse.js');
const handlers = {
'LaunchRequest': function () {
this.emit('AMAZON.HelpIntent');
},
'GetCompostAnswer': function () {
var intentObj = this.event.request.intent;
if (!intentObj.slots.Items.value){
var message = "You did not tell me the name of an item to validate. Can you tell me the item you are asking about?";
var reprompt = "Tell me the item you are asking about."
this.emit(':ask', message, reprompt);
}else{
console.log(intentObj.slots.Items.value);
if(intentObj.slots.Items.value == "?" ){
var message = "I did not understand the name of the item that you want me to validate. Can you tell me again?";
var reprompt = "Tell me the item you are asking about."
this.emit(':ask', message, reprompt);
}
else if (intentObj.slots.Items.value == "post"){
var message = "I did not hear the name of the item that you want me to validate. Can you tell me the item you are asking about?";
var reprompt = "Tell me the item you are asking about."
this.emit(':ask', message, reprompt);
}
else{
var options = {
shouldSort: true,
threshold: 0.2,
location: 0,
distance: 10,
maxPatternLength: 10,
minMatchCharLength: 2,
keys: [
"item"
]
};
var fuse = new Fuse(list, options); // "list" is the item array
var result = fuse.search(intentObj.slots.Items.value);
var message = ""
if (result.length < 1){
this.emit(':tell', "I'm sorry, I didn't understand the item you are asking about. It might not be in my database.");
}else{
var can=", you can compost ";
if (result[0].answer == "No" ){can = ", you cannot compost " };
var message = result[0].answer + can + result[0].item
if (result[0].addOn.length >0){
message = message + " if " + result[0].addOn
};
message = message + ".";
this.emit(':tell', message);
}
}
}
},
'AMAZON.HelpIntent': function () {
const speechOutput = "The Compost Helper will tell you if a household item can be added to your compost. To get started, tell me the item you want to ask about."
const reprompt = "What item do you want to inquire about?"
this.emit(':ask', speechOutput, reprompt);
},
'WhatCanICompost': function () {
var cardTitle = 'What Can I Compost?';
var cardContent = 'Check out this link for a list of items to compost: http://www.compostthis.co.uk';
const speechOutput = "There are a large number of items you can compost. I've sent a website to the Alexa app. Check out the site for a list of items you can compost."
this.emit(':tellWithCard', speechOutput, cardTitle, cardContent, null);
},
'AMAZON.CancelIntent': function () {
this.emit(':tell', "OK.");
},
'AMAZON.StopIntent': function () {
this.emit(':tell', "OK.");
},
};
exports.handler = function (event, context) {
const alexa = Alexa.handler(event, context);
alexa.APP_ID = APP_ID;
// To enable string internationalization (i18n) features, set a resources object.
//alexa.resources = languageStrings;
alexa.registerHandlers(handlers);
alexa.execute();
};
- Sample Utterances (Plain text)
GetCompostAnswer {Items}
GetCompostAnswer can i compost {Items}
GetCompostAnswer could i compost {Items}
GetCompostAnswer should i compost {Items}
GetCompostAnswer is {Items} compostable
GetCompostAnswer can I add {Items} to the compost
GetCompostAnswer can I put {Items} in the compost
WhatCanICompost what can I compost
WhatCanICompost what should I compost
WhatCanICompost give me a list of what I can compost
- List of Items (Custom Slot values)
fruit
vegetables
fruit scraps
vegetable scraps
egg shells
coffee grounds
coffee filters
tea bags
loose leaf tea
tea leaves
tea
soy milk
rice milk
almond milk
coconut milk
paper napkins
paper towels
paper plates
pizza boxes
paper bags
Paper towel rolls
Paper towel dowels
crackers
cereal
nut shells
tofu
tempeh
seaweed
kelp
nori
popcorn kernels
spices
herbs
pretzels
candy
protein bars
energy bars
pizza crusts
oatmeal
peanut shells
egg cartons
sunflower seeds
sesame seeds
avocado pits
wine corks
jelly
jam
preserves
beer
wine
pumpkin seeds
pumpkins
avocados
tomatoes
oranges
lemons
limes
grapefruits
grapes
melon
apples
pears
strawberries
bananas
mangos
pineapples
potatoes
onions
broccoli
carrots
kale
lettuce
cucumbers
parsnips
olives
cauliflower
peppers
beans
mushrooms
corn
corn on the cob
corn cobs
corn husks
garlic
leeks
spinach
newspaper
cardboard
shredded paper
brown paper
cut flowers
toilet roll tubes
flour
oil
motor oil
olive oil
milk
cheese
yogurt
tampons
condoms
shampoo
magazines
take out menus
diapers
catalogs
cream
plums
meat
butter
shortening
cooking oil
vegetable oil
pasta
rice
cooked pasta
cooked rice
bread
pitas
tortillas
potato chips
tortilla chips
fish
seafood
chicken
poultry
cakes
pies
desserts
bakes beans
face pads
face wipes
dog waste
human waste
wrapping paper
gift paper
wall paper
pet waste
cat waste
cat litter
water
beef
pork
- Intent Schema
{
"intents": [
{
"slots": [
{
"name": "Items",
"type": "LIST_OF_ITEMS"
}
],
"intent": "GetCompostAnswer"
},
{
"intent": "AMAZON.HelpIntent"
},
{
"intent": "AMAZON.CancelIntent"
},
{
"intent": "AMAZON.StopIntent"
},
{
"intent": "WhatCanICompost"
}
]
}
Sourse : https://www.hackster.io
All rights reserved