This is my first Alexa Skill. I have developed a skill to get information about movies, actors etc. Right now the the functionality is limited to few but I will be adding more going forward. I am using TMDb (The Movie DB)'s Public API for getting movie information and other details. The API is free for developers. The application is hosted as Lambda Function in Amazon AWS.
Prerequisites- Basic Knowledge of JavaScript and Node.js
- A Redis Database - You can user either Amazon ElastiCache for Redis or Azure Redis Cache or RedisLabs
- Amazon AWS Account for deploying Lambda Function
- Amazon Developer Account for publishing the skill
- bespoken.tools for Testing
- Echosim.io for Testing
- Mocha for testing
- Gulp for packaging
Here is an Quick Start tutorial on how to publish a Alexa Skill with Node.js and Lambda Function. Also here is a nice article in Hackster on getting started as well.
FunctionalityThe Movie Buff at the current state has three functionalities:
- Search for a movie and know more about it along with the its casts and similar movies.
- Suggest a movie based on a particular genre or based on favorite genre of the user which they can set any time. Also a movie recommended shouldn't be recommended again.
- Find top movies acted by a actor or directed by a director.
The application uses four custom intents:
- MovieInfo Intent - To know more about a movie, its cast and similar movies.
- FavouriteGenre Intent - Save favorite genre of the user to the database.
- Recommendation Intent - To get a movie recommendation based on a genre or user's favorite genre. When recommending a movie save it to db so that won't be recommended again.
- PersonMovies Intent - To know about top movies by a actor or director.
And other Inbuilt Intents like AMAZON.YesIntent, AMAZON.NoIntent, AMAZON.HelpIntent. The Intent Schema is as follows:
{
"intents": [
{
"intent": "AMAZON.CancelIntent"
},
{
"intent": "AMAZON.HelpIntent"
},
{
"intent": "AMAZON.StopIntent"
},
{
"intent": "AMAZON.YesIntent"
},
{
"intent": "AMAZON.NoIntent"
},
{
"intent": "FavouriteGenre",
"slots": [
{
"name": "Genre",
"type": "GENRE_LIST"
}
]
},
{
"intent": "MovieInfo",
"slots": [
{
"name": "Name",
"type": "MOVIE_NAMES"
}
]
},
{
"intent": "Recommendation",
"slots": [
{
"name": "Genre",
"type": "GENRE_LIST"
}
]
},
{
"intent": "PersonMovies",
"slots": [
{
"name": "PersonName",
"type": "PERSON_NAMES"
}
]
}
]
And here is the list of sample utterances:
MovieInfo say about {Name}
MovieInfo say details about {Name}
MovieInfo find about {Name}
MovieInfo about {Name}
Recommendation suggest me a movie
Recommendation suggest a movie
Recommendation recommend me a movie
Recommendation recommend a movie
Recommendation suggest me a {Genre} movie
Recommendation suggest a {Genre} movie
Recommendation recommend me a {Genre} movie
Recommendation recommend a {Genre} movie
FavouriteGenre {Genre} is my favourite genre
FavouriteGenre my favourite genre is {Genre}
FavouriteGenre set my favourite genre as {Genre}
PersonMovies find movies acted by {PersonName}
PersonMovies find movies by {PersonName}
PersonMovies find movies casting {PersonName}
PersonMovies find {PersonName} movies
AMAZON.YesIntent yes
AMAZON.NoIntent no
As you can see, there are three custom slots as below.
GENRE_LIST
Action
Adventure
Animation
Comedy
Crime
Documentary
Family
Fantasy
History
Horror
Romance
Romantic
Science Fiction
SiFi
Si Fi
Thriller
War
MOVIE_NAMES
The Matrix
Lord Of The Rings
PERSON_NAMES
Will Smith
Tom Cruise
Johnny Depp
Steven Spielberg
James Cameron
Here as you can see I can't specify a definite list for MOVIE_NAMES and PERSON_NAMES as it would be very difficult to list all of them. I don't want to use the inbuilt Literal Intent as it is going to be depreciated soon. Instead I just added a few sample name just for the fact that I can't leave the list empty. Alexa will parse any movie or person name correctly anyway and give it as the slot value.
CodeAs mentioned earlier, the whole coding is in Node.js. There are Node.js libraries to libraries to easily handle the Alexa request and response which would reduce the lines of code. But I want to make sure people understand the basics of the input and output. So I haven't used any of the libraries, which make the code a little bloated, but it gives me more understanding for my future Alexa applications. The code handles raw input from Alexa and responds with a JSON directly to Alexa. I have used SSML to give a more humanly speech. I have also used card to display movie and person info.
The code is self explanatory with proper comments. It follows ES2015 standard for certain extend. It can be found here.
TestingThanks to Travis Teague for pointing me to bespoken.tools. It helped me a lot in testing the code quickly without have to deploy anything. It reduced a lot of development effort and I highly recommended it. They provide multiple tools for Alexa, and I personally use proxy and emulator a lot. The testing script is developed with Mocha, so make sure the prerequisites are installed. To run the test do the following:
mocha test
Packaging and DeploymentSince the code has many dependencies, it can't be directly deployed with Lambda code editor. We have to create a zip file along with the dependencies and upload it to Lambda. To first create the zip file run the Gulp task:
gulp package
This will create a zip file in "dist
" folder. Then go to Lambda function and upload the zip file.
Also, you need to configure the two following environmental variables.
- MDB_API_KEY - API key obtained from TMDb
- REDIS_URL - Connection string of the Redis db
Since I don't have an Echo device with me, I couldn't show a real demo. Instead I chose to record with Echoism. But unfortunately Echoism is not that reliable, it keeps on failing (I am seeing 500 error in developer console often). So I have recorded quick demos while it worked but I couldn't show the full interaction.
Skill StatusThe Application ID is amzn1.ask.skill.79d81511-acbb-4ca6-9d08-dc57763122d5
I have submitted it for certification, but due to a misunderstanding I marked YES when asked about whether it targets children. It got rejected and I am unable to resubmit again even after correcting the mistake. So I have submitted it as new skill with proper details. I do hope it gets certified soon.
Future PlansWill be adding more functionality going forward and keep updating the skill. And of course the code will be updated in the Github as well.
Your comments and suggestions are welcome as always.
Comments