My wife and I often struggle with the same question on many evenings: what movies haven't we seen yet or are worth to be watched again? Streaming services offer tons of movies but it takes a lot of time to navigate through all categories and pages and in the end you can't decide...
Imagine a friend tells you about a good movie. Chances are high that you will consider watching it because a someone directly addressed you and your brain's auditory center was involved. That's where Alexa comes in handy and can make a difference to the tons of movie recommendation websites and streaming services: Simple, easy to use and without any distractions: A couple of movie recommendations matching your mood, plus the ratings of millions of others.
This Alexa skill makes use of the new Alexa Conversations features.
What it does
It asks you what genre (or list of genres!) you're up to today. Also if you'd like to see blockbusters only or if you're less picky today. Alexa will then look up movies matching your criteria and prepare a list for you. She will also tell you if others are loving the movie or if it's an acquired taste. Movie Finder knows over 550,000 movies and you can pick from 28 different genres: Romance, Documentary, News, Sport, Biography, Drama, Crime, Adventure, Fantasy, Comedy, War, Family, History, Sci-Fi, Western, Thriller, Mystery, Horror, Action, Music, Animation, Musical, Film-Noir, Adult, Reality-TV, Game-Show, Talk-Show, Short.
How I built it
I made use of a free but reliable data source for movie meta data. The data is stored in a RDS that can be queried efficiently by my Alexa skill. I built up the skill with a combination of Alexa Conversations (for asking what the user likes to watch) and traditional skill invocation to get the best out of both worlds. I tested it on the simulator and on an Echo Dot. Not to forgot to mention that I was happy I had some great debugging assistance by Kevindra from the Alexa team when it got tricky...
Let's get started... It's always a good plan to first draw a picture of what it should look like before getting the hands dirty and the tools warmed up. So I used a virtual whiteboard to draw the dialogs and states I wished to have in the end which would provide simplicity, meaningful results and a great UX. For example, by what criteria should the user be able to filter? If it's only one, the results will be fuzzy. If there are too many filter questions by Alexa, the result list will become more precise but the user will become annoyed by the many filters before delivering results. I also conducted a user interview with my wife, asking about her strategy when looking for movies. So I ended up drawing a Alexa conversation only asking for two things: genre and rating of others.
Then I checked out the Pizza reference example and watched some Q&A sessions on Twitch first to get me started to Alexa skills.
When it comes to a skill like this, it's all about the data. So I checked if there are any free-to-use APIs or databases out there. I personally found IMDb to be the source for movie related questions. I always check it out before watching a movie (but need to fiddle around with my laptop or mobile...) IMDb offers a free database for personal and non-commercial use.
The raw data about movies, titles, genres, average ratings and number of votings from others is available as a zipped csv and was uploaded by me to S3. It's then imported into an Aurora RDS. Aurora has a nice feature: The statement LOAD DATA FROM S3 loads data from csv files stored in an Amazon S3 bucket into the database without the need to write scripts or performing millions of INSERTs from your laptop.
I then optimized the data and table structure for efficient searchability when asking for one or many genres (see section Challenges I ran into below). A separate M:N table in combination with indexes do the job.
At start, my Alexa skill speaks out how to get the search started (= what utterance the user can use to start a search). The skill then hands over to Alexa Conversations which will handle the back-and-forth, asking the user what genre they're up to and if they care about the ratings of others. A RDS query is performed and the result stored in Session Attributes. Then Alexa Conversations hands back to the skill which will let the user hear about the results.
Each movie result contains the English title, genre (in case the user gave a list of genres) and the average rating of other watchers. If it's a match, fine. If the user has seen this movie recently or doesn't like it for some reason, an utterance like "next" steps forward to the next item on the list.
Challenges I ran into
Database First, I considered using DynamoDB for holding my data because I considered its high availability but also because I wanted to do a project with it. Also, many rows in the data source are different in completeness, so a key-value store could be an elegant solution without assuming what values are known from a movie. Another one was that a search should be performed in the range of milliseconds. But after doing the first steps I quickly learned that indexes can only be put on top-level objects, so no lists like genres (each movie can be tagged with zero, one or multiple genres).
So I chose Aurora. After the raw data was imported elegantly from S3 I optimized the tables and data for search efficiency. I later wanted to be able to search for genres but the tricky part is that a movie can be tagged with multiple genres (e.g. Thriller and Action) and the datasource just provided a comma separated string for each row. So I needed to parse that string, dissect it into its list of values and then put that information into an M:N table allowing a fast and efficient lookup for particular genre(s). An RDS also has the elegancy of allowing complex join operations and conditions over multiple tables like ratings, title information and genres.
I also created the necessary indexes for a fast lookup, especially when doing complex joins over three of my tables.
Debugging I used a non-US Alexa Developer account and I lost a lot of time during debugging wondering why certain things appear in CloudWatch and others don't. I started some skill sessions without a log being written. At that time I didn't realize what went wrong. Together with the Alexa support team I figured out that CloudWatch logs in the North Virginia region were only on Alexa Conversations logs when using a non-US developer account. I had a sudden idea once to look into the Ireland region and ... tada, there were the skill's logs. A bit cumbersome to always open two regions and merge logs together by timestamp during debugging but finding this out solved it for me.
Accomplishments that I'm proud of
Well, of course, building my first Alexa skill ever. Then, playing around with the beta of AC and see what's it capable of, making it easier for developers to concentrate on the content and not on state management. And last but not least, having something which helps us during my evening struggle, deciding on a movie to watch!
What I learned
Learning about some more features of Aurora, DynamoDB, Lambdas, some Node.js libraries and of course the Alexa SDK and APL-A editor was a good time for me.
What's next for Movie Finder
One ideal extension would be to send a link to the IMDb webpage, but unfortunately the Alexa app doesn't allow this. Hint: Feature request ;) A user could also want to hear about movies their favorite actor or actress has starred in. So an extension to search by actor could be done. And of course i18n for other regions.