Couch Potato Alexa Skill 1.0

This commit is contained in:
Joseph Schmitt 2016-03-27 14:35:30 -04:00
commit e2b616829f
16 changed files with 1181 additions and 0 deletions

12
.env Normal file
View File

@ -0,0 +1,12 @@
AWS_ENVIRONMENT=
AWS_SESSION_TOKEN=
AWS_REGION=us-east-1
AWS_FUNCTION_NAME=couchpotato
AWS_HANDLER=index.handler
AWS_MODE=event
AWS_MEMORY_SIZE=128
AWS_TIMEOUT=10
AWS_DESCRIPTION=
AWS_RUNTIME=nodejs
CP_URL=http://url-to-couch-potato-server
CP_API_KEY=apiKey

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
deploy.env
lambda.zip
node_modules/

53
README.md Normal file
View File

@ -0,0 +1,53 @@
# Couch Potato Alexa Skill
This is a skill built for Amazon's Alexa service that tells you about your Couch Potato queue. It
allows you to ask Alexa the following:
> Alexa, ask Couch Potato to add The Godfather
> Alexa, ask Couch Potato if The Dark Knight is on the list
If you're just getting started developing skills for Alexa, I'd recommend reading [Getting Started
with the Alexa Skills
Kit](https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/getting-started-guide) and
[Developing an Alexa Skill as a Lambda
Function](https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/developing-an-alexa-skill-as-a-lambda-function) to get familiar with the process.
## Configuring The Skill
To configure the skill, open up the `.env` file and fill in the correct values for `CP_URL`, which
should point to your Couch Potato server, and `CP_API_KEY` which should have your server's API key.
## Testing The Skill Locally
You can use [node-lambda](https://github.com/motdotla/node-lambda) to test this skill locally. In
the `test_events` directory are several event files you can use for testing, and they should map
pretty well to each Intent. To test an intent, simply copy the contents of one of the json files in
that directory and overwrite the contents of `event.json`. Then run `node-lambda run` from the
command line.
## Setting up the Skill
To set up the skill, head on over to [Alexa skills kit
development console](https://developer.amazon.com/edw/home.html) and add a new skill. Fill in the
basic skill information however you choose. For Endpoint, you'll need to fill in your Lambda ARN
which you'll get in the next step. Next, head on over to Interaction Model. In the Intent
Schema field, copy and paste the contents of the `interaction_model/intent_schema.json` file. Then
in the Sample Utterances field, copy and paste the contents of
`interaction_model/sample_utterances.txt`.
## Hosting the Skill
The skill is built to be easily hosted on Amazon's [AWS
Lambda service](https://aws.amazon.com/lambda/). Create your Lambda function (using the
alexa-skills-kit-color-expert blueprint) and make sure you choose Node.js as the runtime.
To deploy to Lambda, first makes sure you do an `npm install` at the root of the project.
Once all the dependencies are installed, run `npm run bundle`, which will create a lambda.zip file.
You can then upload that zip file to Lambda for use in your function and skill.
You can also use [node-lambda](https://github.com/motdotla/node-lambda) to deploy to your Lambda
function directly from the command line. Simply add a deploy.env file with your environment
configuration (and double check the supplied .env file in this repository) and then run
`node-lambda deploy`. Please visit the [node-lambda](https://github.com/motdotla/node-lambda)
project page for more information on deploying from the command line.

26
event.json Normal file
View File

@ -0,0 +1,26 @@
{
"session": {
"sessionId": "SessionId.1234",
"application": {
"applicationId": "amzn1.echo-sdk-ams.app.1234"
},
"user": {
"userId": "amzn1.echo-sdk-account.1234"
},
"new": true
},
"request": {
"type": "IntentRequest",
"requestId": "EdwRequestId.1234",
"timestamp": "2016-01-01T00:00:00Z",
"intent": {
"name": "FindMovie",
"slots": {
"movieName": {
"name": "movieName",
"value": "the godfather"
}
}
}
}
}

BIN
icon-108x108.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

4
index.js Normal file
View File

@ -0,0 +1,4 @@
'use strict';
var app = require('./lib');
exports.handler = app.lambda();

View File

@ -0,0 +1,31 @@
{
"intents": [
{
"intent": "AddMovie",
"slots": [
{
"name": "movieName",
"type": "AMAZON.LITERAL"
}
]
},
{
"intent": "FindMovie",
"slots": [
{
"name": "movieName",
"type": "AMAZON.LITERAL"
}
]
},
{
"intent": "AMAZON.YesIntent"
},
{
"intent": "AMAZON.NoIntent"
},
{
"intent": "AMAZON.CancelIntent"
}
]
}

View File

@ -0,0 +1,34 @@
AddMovie add {The Godfather|movieName}
AddMovie add {Star Wars|movieName}
AddMovie add {Star Wars Episode Four A New Hope|movieName}
AddMovie add {The Avengers|movieName}
AddMovie add {The Dark Knight|movieName}
AddMovie add {Live or Let Die|movieName}
FindMovie is {The Godfather|movieName} on the list
FindMovie is {Star Wars|movieName} on the list
FindMovie is {Star Wars Episode Four A New Hope|movieName} on the list
FindMovie is {The Avengers|movieName} on the list
FindMovie is {The Dark Knight|movieName} on the list
FindMovie is {Live or Let Die|movieName} on the list
FindMovie if {The Godfather|movieName} is on the list
FindMovie if {Star Wars|movieName} is on the list
FindMovie if {Star Wars Episode Four A New Hope|movieName} is on the list
FindMovie if {The Avengers|movieName} is on the list
FindMovie if {The Dark Knight|movieName} is on the list
FindMovie if {Live or Let Die|movieName} is on the list
FindMovie is {The Godfather|movieName} already
FindMovie is {Star Wars|movieName} already
FindMovie is {Star Wars Episode Four A New Hope|movieName} already
FindMovie is {The Avengers|movieName} already
FindMovie is {The Dark Knight|movieName} already
FindMovie is {Live or Let Die|movieName} already
FindMovie if {The Godfather|movieName} is already
FindMovie if {Star Wars|movieName} is already
FindMovie if {Star Wars Episode Four A New Hope|movieName} is already
FindMovie if {The Avengers|movieName} is already
FindMovie if {The Dark Knight|movieName} is already
FindMovie if {Live or Let Die| movieName} is already

133
lib/handlers.js Normal file
View File

@ -0,0 +1,133 @@
'use strict';
var CouchPotato = require('node-couchpotato');
var utils = require('./utils.js');
var WELCOME_DESCRIPTION = 'This skill allows you to manage your Couch Potato movie list.';
var HELP_RESPONSE = ['You can ask Couch Potato about the movies in your queue or add new movies',
'to it. Try asking "is The Godfather on the list?". If it\'s not and you want to add it, try',
'saying "add The Godfather".'].join(' ');
var config = require('dotenv').config();
var cp = new CouchPotato({
url: config.CP_URL,
apikey: config.CP_API_KEY
});
function handleLaunchIntent(req, resp) {
resp
.say(WELCOME_DESCRIPTION)
.say(HELP_RESPONSE)
.send();
}
function handleFindMovieIntent(req, resp) {
var movieName = req.slot('movieName');
cp.movie.list({search: movieName, limit_offset: 5}).then(function (searchResp) {
var movies = searchResp.movies;
var result;
if (!movies || !movies.length) {
resp.say('Couldn\'t find ' + movieName + ' queued for download. ');
cp.movie.search(movieName).then(function (searchResults) {
utils.sendSearchResponse(searchResults, resp);
});
}
else {
result = movies[0].info;
resp
.say([
'It looks like', result.original_title,
'(' + result.year + ')', 'is already on your list.'
].join(' '))
.send();
}
});
//Async response
return false;
}
function handleAddMovieIntent(req, resp) {
var movieName = req.slot('movieName');
cp.movie.search(movieName).then(function (movies) {
utils.sendSearchResponse(movies, resp);
});
//Async response
return false;
}
function handleYesIntent(req, resp) {
var promptData = req.session('promptData');
var movie;
if (!promptData) {
console.log('Got a AMAZON.YesIntent but no promptData. Ending session.');
resp.send();
}
else if (promptData.yesAction === 'addMovie') {
movie = promptData.searchResults[0];
cp.movie.add({
title: movie.titles[0],
identifier: movie.imdb
}).then(function () {
resp
.say(promptData.yesResponse)
.send();
});
//Async response
return false;
}
else {
console.log("Got an unexpected yesAction. PromptData:");
console.log(promptData);
resp.send();
}
}
function handleNoIntent(req, resp) {
var promptData = req.session('promptData');
if (!promptData) {
console.log('Got a AMAZON.YesIntent but no promptData. Ending session.');
resp.send();
}
else if (promptData.noAction === 'endSession') {
resp.say(promptData.noResponse).send();
}
else if (promptData.noAction === 'suggestNextMovie') {
var movies = promptData.searchResults;
resp
.say(promptData.noResponse)
.session('promptData', utils.buildPrompt(movies.slice(1)))
.shouldEndSession(false)
.send();
}
else {
console.log("Got an unexpected noAction. PromptData:");
console.log(promptData);
resp.send();
}
}
function handleCancelIntent(req, resp) {
resp.shouldEndSession(true).send();
}
function handleCancelIntent(req, resp) {
resp.say(HELP_RESPONSE).send();
}
module.exports = {
handleFindMovieIntent: handleFindMovieIntent,
handleAddMovieIntent: handleAddMovieIntent,
handleYesIntent: handleYesIntent,
handleNoIntent: handleNoIntent,
handleCancelIntent: handleCancelIntent
};

15
lib/index.js Normal file
View File

@ -0,0 +1,15 @@
'use strict';
var handlers = require('./handlers.js');
var alexa = require('alexa-app');
var app = new alexa.app('couchPotato');
app.launch(handlers.handleLaunchIntent);
app.intent('FindMovie', handlers.handleFindMovieIntent);
app.intent('AddMovie', handlers.handleAddMovieIntent);
app.intent('AMAZON.YesIntent', handlers.handleYesIntent);
app.intent('AMAZON.NoIntent', handlers.handleNoIntent);
app.intent('AMAZON.CancelIntent', handlers.handleCancelIntent);
module.exports = app;

160
lib/old.js Normal file
View File

@ -0,0 +1,160 @@
var alexa = require('alexa-app');
var request = require('request');
var dotenv = require('dotenv').config();
var CouchPotato = require('node-couchpotato');
var app = new alexa.app();
var cp = new CouchPotato({
url: dotenv.CP_URL,
apikey: dotenv.CP_API_KEY,
debug: true
});
function buildNextMovieSuggestionPrompt(movies) {
var promptData = {
searchResults: movies.slice(0, 5),
yesAction : 'addMovie',
yesResponse: 'Added ' + movies[0].original_title + ' (' + movies[0].year + ')' + ' to your list of movies to download.'
};
if (movies.length > 1) {
promptData.noAction = 'suggestNextMovie';
promptData.noResponse = 'Ok, did you mean ' + movies[1].original_title + ' (' + movies[1].year + ')' + '?';
}
else {
promptData.noAction = 'endSession';
promptData.noResponse = 'Ok. I\'m out of suggestions. Sorry about that.';
}
return promptData;
}
function formatMovieSearchResponse(movies, resp) {
if(!movies || !movies.length) {
resp.say("No movie found for " + movieName);
return resp.send();
}
var speechText = 'Add ' + movies[0].original_title + ' (' + movies[0].year + ')' + ' to your list?';
// console.log('movie found', speechText);
// console.log('reprompt data', buildNextMovieSuggestionPrompt(movies.slice(0, 5)));
resp
.say(speechText)
.session('promptData', buildNextMovieSuggestionPrompt(movies.slice(0, 5)))
.shouldEndSession(false)
.send();
}
app.intent('FindMovie', function (req, resp) {
var movieName = req.slot('movieName');
// console.log('search for movie in list', movieName);
cp.movie.list({search: movieName, limit_offset: 5}).then(function (searchResp) {
var movies = searchResp.movies;
var result;
var speechText;
if (!movies || !movies.length) {
speechText = "Couldn't find " + movieName + " queued for download. ";
resp.say(speechText);
// console.log('no movie found', speechText);
cp.movie.search(movieName).then(function (searchResults) {
formatMovieSearchResponse(searchResults, resp);
});
}
else {
result = movies[0].info;
speechText = 'It looks like ' + result.original_title + ' (' + result.year + ')' + ' is already on your list.';
// console.log('movie found', speechText);
resp
.say(speechText)
.send();
}
return false;
// console.log('reprompt data', buildNextMovieSuggestionPrompt(movies.slice(0, 5)));
});
return false;
});
app.intent('AddMovie', function (req, resp) {
var movieName = req.slot('movieName');
// console.log('search for movie', movieName);
cp.movie.search(movieName).then(function (movies) {
formatMovieSearchResponse(movies, resp);
});
return false;
});
app.intent('AMAZON.YesIntent', function (req, resp) {
var promptData = req.session('promptData');
if (!promptData) {
console.log('Got a AMAZON.YesIntent but no promptData. Ending session.');
return resp.send();
}
if (promptData.yesAction === 'addMovie') {
// console.log('promptData', promptData);
var movie = promptData.searchResults[0];
// console.log('Add the movie', movie.original_title);
cp.movie.add({
title: movie.titles[0],
identifier: movie.imdb
}).then(function () {
resp
.say(promptData.yesResponse)
.send();
});
}
else {
console.log("Got an unexpected yesAction. PromptData:");
console.log(promptData);
return resp.send();
}
return false;
});
app.intent('AMAZON.NoIntent', function (req, resp) {
var promptData = req.session('promptData');
if (!promptData) {
console.log('Got a AMAZON.YesIntent but no promptData. Ending session.');
return resp.send();
}
if (promptData.noAction === 'endSession') {
return resp.say(promptData.noResponse).send();
}
else if (promptData.noAction === 'suggestNextMovie') {
var movies = promptData.searchResults;
return resp
.say(promptData.noResponse)
.session('promptData', buildNextMovieSuggestionPrompt(movies.slice(1)))
.shouldEndSession(false)
.send();
}
else {
console.log("Got an unexpected noAction. PromptData:");
console.log(promptData);
return resp.send();
}
return false;
});
app.intent('AMAZON.CancelIntent', function (req, resp) {
resp.shouldEndSession(true).send();
});
exports.handler = app.lambda();

35
lib/utils.js Normal file
View File

@ -0,0 +1,35 @@
function buildPrompt(movies) {
var promptData = {
searchResults: movies.slice(0, 5),
yesAction : 'addMovie',
yesResponse: 'Added ' + movies[0].original_title + ' (' + movies[0].year + ')' + ' to your list of movies to download.'
};
if (movies.length > 1) {
promptData.noAction = 'suggestNextMovie';
promptData.noResponse = 'Ok, did you mean ' + movies[1].original_title + ' (' + movies[1].year + ')' + '?';
}
else {
promptData.noAction = 'endSession';
promptData.noResponse = 'Ok. I\'m out of suggestions. Sorry about that.';
}
return promptData;
}
function sendSearchResponse(movies, resp) {
if(!movies || !movies.length) {
return resp.say('No movie found for ' + movieName).send();
}
resp
.say(['Add', movies[0].original_title, '(' + movies[0].year + ')', 'to your list?'].join(' '))
.session('promptData', buildPrompt(movies.slice(0, 5)))
.shouldEndSession(false)
.send();
}
module.exports = {
buildPrompt: buildPrompt,
sendSearchResponse: sendSearchResponse
};

21
package.json Normal file
View File

@ -0,0 +1,21 @@
{
"name": "alexa-couchpotato",
"version": "1.0.0",
"description": "A skill to ask Alexa about your Couch Potato queue.",
"main": "index.js",
"scripts": {
"bundle": "mkdir -p bundle && cp -r {.env,index.js,lib,node_modules} bundle/ && cd bundle && bestzip ../lambda.zip * .env && rm -rf ../bundle"
},
"author": "Joe Schmitt",
"license": "MIT",
"dependencies": {
"alexa-app": "^2.3.2",
"dotenv": "^2.0.0",
"node-couchpotato": "^0.1.4",
"node-lambda": "^0.7.1"
},
"devDependencies": {
"bestzip": "^1.1.3",
"node-lambda": "^0.7.1"
}
}

View File

@ -0,0 +1,27 @@
{
"session": {
"sessionId": "SessionId.1234",
"application": {
"applicationId": "amzn1.echo-sdk-ams.app.1234"
},
"user": {
"userId": "amzn1.echo-sdk-account.1234"
},
"new": true
},
"request": {
"type": "IntentRequest",
"requestId": "EdwRequestId.1234",
"timestamp": "2016-01-01T00:00:00Z",
"intent": {
"name": "AddMovie",
"slots": {
"movieName": {
"name": "movieName",
"value": "the godfather"
}
}
}
},
"version": "1.0"
}

View File

@ -0,0 +1,26 @@
{
"session": {
"sessionId": "SessionId.1234",
"application": {
"applicationId": "amzn1.echo-sdk-ams.app.1234"
},
"user": {
"userId": "amzn1.echo-sdk-account.1234"
},
"new": true
},
"request": {
"type": "IntentRequest",
"requestId": "EdwRequestId.1234",
"timestamp": "2016-01-01T00:00:00Z",
"intent": {
"name": "FindMovie",
"slots": {
"movieName": {
"name": "movieName",
"value": "the godfather"
}
}
}
}
}

View File

@ -0,0 +1,601 @@
{
"session": {
"sessionId": "SessionId.1234",
"application": {
"applicationId": "amzn1.echo-sdk-ams.app.1234"
},
"attributes": {
"promptData": {
"searchResults": [
{
"rating": {
"imdb": [
6.9,
992
]
},
"tmdb_id": 321258,
"actor_roles": {
"Diana Hardcastle": "Mrs. Heelshire",
"Rupert Evans": "Malcolm",
"James Russell": "James",
"Jim Norton": "Mr. Heelshire",
"Lauren Cohan": "Greta"
},
"via_imdb": true,
"via_tmdb": true,
"titles": [
"The Boy",
"The Inhabitant",
"?? ?????"
],
"imdb": "tt3882082",
"year": 2016,
"images": {
"poster": [
"https://image.tmdb.org/t/p/w154/lISBWF6UUF3cQPcoLE8pMxnyJty.jpg",
"http://ia.media-imdb.com/images/M/MV5BMTc1MjcxNzcwMV5BMl5BanBnXkFtZTgwMTE0NTE2NzE@._V1_.jpg",
"http://ia.media-imdb.com/images/M/MV5BMTQ1NzAwNTg1M15BMl5BanBnXkFtZTgwNDQwOTQ0NzE@._V1_SX300.jpg"
],
"extra_thumbs": [],
"poster_original": [
"https://image.tmdb.org/t/p/original/lISBWF6UUF3cQPcoLE8pMxnyJty.jpg"
],
"actors": {
"Diana Hardcastle": "https://image.tmdb.org/t/p/w185/hl58zPrWbo1mfatgVxEnGsKGZ1b.jpg",
"Rupert Evans": "https://image.tmdb.org/t/p/w185/AuPOKHD18bE2jKXONvrMLGVQ744.jpg",
"Jim Norton": "https://image.tmdb.org/t/p/w185/lndFtmSwtCzoeWkgjqJBqVRKGk2.jpg",
"Lauren Cohan": "https://image.tmdb.org/t/p/w185/5W4AV3ZXn38NlEMqPy9QPjwRRz8.jpg"
},
"backdrop_original": [
"https://image.tmdb.org/t/p/original/aOvgn3E5OjJDepApd1WtS2doqMF.jpg"
],
"backdrop": [
"https://image.tmdb.org/t/p/w1280/aOvgn3E5OjJDepApd1WtS2doqMF.jpg"
]
},
"plot": "A nanny, working for a family whose son has just passed away, finds herself put in charge of caring for a lifelike doll that the couple treat as a real child.",
"genres": [
"Horror",
"Thriller"
],
"in_library": false,
"released": "2016-01-22",
"mpaa": "PG-13",
"original_title": "The Boy",
"directors": [
"William Brent Bell"
],
"writers": [
"Stacey Menear"
],
"in_wanted": {
"status": "active",
"info": {
"rating": {
"imdb": [
6.9,
815
]
},
"genres": [
"Horror",
"Thriller"
],
"tmdb_id": 321258,
"plot": "An American nanny is shocked that her new English family's boy is actually a life-sized doll. After violating a list of strict rules, disturbing events make her believe that the doll is really alive.",
"tagline": "",
"release_date": {
"dvd": 1459461600,
"expires": 1453930027,
"theater": 1453417200,
"bluray": true
},
"year": 2016,
"original_title": "The Boy",
"actor_roles": {
"Diana Hardcastle": "Mrs. Heelshire",
"Rupert Evans": "Malcolm",
"Jim Norton": "Mr. Heelshire",
"James Russell": "James",
"Lauren Cohan": "Greta"
},
"via_imdb": true,
"images": {
"disc_art": [],
"poster": [
"http://ia.media-imdb.com/images/M/MV5BMTQ1NzAwNTg1M15BMl5BanBnXkFtZTgwNDQwOTQ0NzE@._V1_SX300.jpg"
],
"backdrop": [
"https://image.tmdb.org/t/p/w1280/aOvgn3E5OjJDepApd1WtS2doqMF.jpg"
],
"extra_thumbs": [],
"poster_original": [
"https://image.tmdb.org/t/p/original/lISBWF6UUF3cQPcoLE8pMxnyJty.jpg"
],
"actors": {
"Diana Hardcastle": "https://image.tmdb.org/t/p/w185/hl58zPrWbo1mfatgVxEnGsKGZ1b.jpg",
"Rupert Evans": "https://image.tmdb.org/t/p/w185/AuPOKHD18bE2jKXONvrMLGVQ744.jpg",
"Lauren Cohan": "https://image.tmdb.org/t/p/w185/5W4AV3ZXn38NlEMqPy9QPjwRRz8.jpg",
"Jim Norton": "https://image.tmdb.org/t/p/w185/lndFtmSwtCzoeWkgjqJBqVRKGk2.jpg"
},
"backdrop_original": [
"https://image.tmdb.org/t/p/original/aOvgn3E5OjJDepApd1WtS2doqMF.jpg"
],
"clear_art": [],
"logo": [],
"banner": [],
"landscape": [],
"extra_fanart": []
},
"directors": [
"William Brent Bell"
],
"titles": [
"The Boy",
"The Inhabitant",
"?? ?????"
],
"imdb": "tt3882082",
"mpaa": "PG-13",
"via_tmdb": true,
"actors": [
"Lauren Cohan",
"Rupert Evans",
"Ben Robson",
"Diana Hardcastle"
],
"writers": [
"Stacey Menear"
],
"runtime": 97,
"type": "movie",
"released": "2016-01-22"
},
"_t": "media",
"title": "The Boy",
"_rev": "000c14b5",
"profile_id": "e57930f7c49e4419a7ce764460921cd1",
"_id": "0a39772ec4484b628b739791a7b43b9f",
"tags": [],
"profile": {
"core": false,
"_rev": "0002f338",
"finish": [
true,
true
],
"minimum_score": 1,
"_id": "e57930f7c49e4419a7ce764460921cd1",
"_t": "profile",
"label": "HD",
"qualities": [
"1080p",
"720p"
],
"stop_after": [
0,
0
],
"wait_for": [
5,
5
],
"order": 0,
"3d": [
0,
0
]
},
"last_edit": 1453695473,
"type": "movie",
"files": {
"image_poster": [
"/Users/jayjo/Library/Application Support/CouchPotato/cache/d8f54038b9a50cdd52642a92916299da.jpg"
]
},
"identifiers": {
"imdb": "tt3882082"
}
},
"actors": [
"Lauren Cohan",
"Rupert Evans",
"Ben Robson",
"Diana Hardcastle"
],
"runtime": 97,
"type": "movie"
},
{
"rating": {
"imdb": [
4.6,
23396
]
},
"tmdb_id": 241251,
"actor_roles": {
"John Corbett": "Garrett Peterson",
"Hill Harper": "Principal Edward Warren",
"Bailey Chase": "Benny",
"Jennifer Lopez": "Claire Peterson",
"Fran?ois Chau": "Detective Johnny Chou",
"Lexi Atkins": "Allie Callahan",
"Raquel Gardner": "Barbara",
"Ian Nelson": "Kevin Peterson",
"Ryan Guzman": "Noah Sandborn",
"Kristin Chenoweth": "Vicky Lansing"
},
"via_imdb": true,
"via_tmdb": true,
"titles": [
"The Boy Next Door",
"Le gar?on d'? c?t?",
"Obsesi?n"
],
"imdb": "tt3181822",
"year": 2015,
"images": {
"poster": [
"https://image.tmdb.org/t/p/w154/h28t2JNNGrZx0fIuAw8aHQFhIxR.jpg",
"http://ia.media-imdb.com/images/M/MV5BMTgxNTEyMTYzOV5BMl5BanBnXkFtZTgwNzQ4OTg5MjE@._V1_SX300.jpg"
],
"extra_thumbs": [],
"poster_original": [
"https://image.tmdb.org/t/p/original/h28t2JNNGrZx0fIuAw8aHQFhIxR.jpg"
],
"actors": {
"John Corbett": "https://image.tmdb.org/t/p/w185/r66d7CFycEOwzFnRlAgv5HX8r1R.jpg",
"Hill Harper": "https://image.tmdb.org/t/p/w185/6Dz2mV1Jdfnv0789JTFY8G08ju2.jpg",
"Bailey Chase": "https://image.tmdb.org/t/p/w185/1Lmy7WGlthUPwjUDbj1ODTdWUZA.jpg",
"Jennifer Lopez": "https://image.tmdb.org/t/p/w185/mxBDIyt8u4q5eJcQkGipNYTtlvz.jpg",
"Fran?ois Chau": "https://image.tmdb.org/t/p/w185/r8EocoGAJVky0bQ6gyfxcabuTPz.jpg",
"Lexi Atkins": "https://image.tmdb.org/t/p/w185/fRq4XQ2X52lDqeDiHTRdSHU9xQC.jpg",
"Raquel Gardner": "https://image.tmdb.org/t/p/w185/rONhpmIXABWcJJgKjicQ87tJLEu.jpg",
"Ian Nelson": "https://image.tmdb.org/t/p/w185/e5UxvFTHRFI2o8RDiTAjb9tJXLL.jpg",
"Ryan Guzman": "https://image.tmdb.org/t/p/w185/yJR4t5PlBdsiPAP9JdGjqomkVv7.jpg",
"Kristin Chenoweth": "https://image.tmdb.org/t/p/w185/nZuynlyNec2G1QEIj0iHbKToaft.jpg"
},
"backdrop_original": [
"https://image.tmdb.org/t/p/original/vj4IhmH4HCMZYYjTMiYBybTWR5o.jpg"
],
"backdrop": [
"https://image.tmdb.org/t/p/w1280/vj4IhmH4HCMZYYjTMiYBybTWR5o.jpg"
]
},
"plot": "A recently cheated on married woman falls for a younger man who has moved in next door, but their torrid affair soon takes a dangerous turn.",
"genres": [
"Thriller",
"Mystery"
],
"in_library": false,
"released": "2015-01-23",
"tagline": "A Moment She Couldn't Resist. An Obsession He Can't Control.",
"original_title": "The Boy Next Door",
"directors": [
"Rob Cohen"
],
"writers": [
"Barbara Curry"
],
"in_wanted": false,
"mpaa": "R",
"actors": [
"Jennifer Lopez",
"Ryan Guzman",
"Ian Nelson",
"John Corbett"
],
"runtime": 91,
"type": "movie"
},
{
"rating": {
"imdb": [
6.9,
72919
]
},
"tmdb_id": 9319,
"actor_roles": {
"Halle Berry": "Cory",
"Bill Medley": "Himself",
"Billy Blanks": "Billy Cole",
"Bruce Willis": "Joe Hallenbeck",
"Dick Butkus": "Himself",
"Bruce McGill": "Mike Matthews",
"Badja Djola": "Alley Thug",
"Verne Lundquist": "Himself",
"Ken Kells": "Head Coach",
"Joe El Rady": "Kid",
"Michael J. Fisher": "Wounded Player",
"Lynn Swann": "Himself",
"Morris Chestnut": "Locker Room Kid",
"Danielle Harris": "Darian Hallenbeck",
"Doug Simpson": "Wounded Player",
"Chelcie Ross": "Senator Baynard",
"Clarence Felder": "McCoskey",
"Chelsea Field": "Sarah Hallenbeck",
"Damon Wayans": "James Alexander 'Jimmy' Dix",
"Frank Collison": "Pablo",
"Kim Coates": "Chet",
"Noble Willingham": "Sheldon Marcone",
"Taylor Negron": "Milo",
"Joe Santos": "Bessalo",
"Tony Longo": "Big Ray Walston"
},
"via_imdb": true,
"via_tmdb": true,
"titles": [
"The Last Boy Scout",
"Den siste scouten",
"????????? ????????",
"Last Boy Scout",
"Le Dernier boy scout"
],
"imdb": "tt0102266",
"year": 1991,
"images": {
"poster": [
"https://image.tmdb.org/t/p/w154/cTl2WqsERuZ5vYmAmtfsPIJBLr0.jpg",
"http://ia.media-imdb.com/images/M/MV5BMTUxNjQxMTAwMV5BMl5BanBnXkFtZTcwNTI5ODMyMQ@@._V1_.jpg",
"http://ia.media-imdb.com/images/M/MV5BMTUxNjQxMTAwMV5BMl5BanBnXkFtZTcwNTI5ODMyMQ@@._V1_SX300.jpg"
],
"extra_thumbs": [],
"poster_original": [
"https://image.tmdb.org/t/p/original/cTl2WqsERuZ5vYmAmtfsPIJBLr0.jpg"
],
"actors": {
"Halle Berry": "https://image.tmdb.org/t/p/w185/AmCXHowNbUXpNf41dNrxNB0naM2.jpg",
"Bill Medley": "https://image.tmdb.org/t/p/w185/gZix2FrZ9Dw4OvAh0Spu8IfRp6Z.jpg",
"Billy Blanks": "https://image.tmdb.org/t/p/w185/hkbllU1QR9irZ2AmW0eLelKoZSS.jpg",
"Bruce Willis": "https://image.tmdb.org/t/p/w185/kI1OluWhLJk3pnR19VjOfABpnTY.jpg",
"Dick Butkus": "https://image.tmdb.org/t/p/w185/eF8Bg3YPzJw9DH1B3QlAJfdsZgH.jpg",
"Bruce McGill": "https://image.tmdb.org/t/p/w185/n5lXakx8RP8LkRl4rXtHSOSIjPl.jpg",
"Badja Djola": "https://image.tmdb.org/t/p/w185/i5j8WpNKydvBs2Vu3cYJyXNBy3V.jpg",
"Verne Lundquist": "https://image.tmdb.org/t/p/w185/AkUVqg2rkExTneawEUSYFjYnv8O.jpg",
"Ken Kells": "https://image.tmdb.org/t/p/w185/n0hKRviE0p0I5UqJ5BVJ1gamM15.jpg",
"Lynn Swann": "https://image.tmdb.org/t/p/w185/hK8KMKumG0kCARGUBmN3P0UrBRN.jpg",
"Morris Chestnut": "https://image.tmdb.org/t/p/w185/xHgWktsqPDsSsq8RWTe98IwxIIM.jpg",
"Danielle Harris": "https://image.tmdb.org/t/p/w185/q3wQP4ZwVjfBerFK0iVZPzaF5BL.jpg",
"Chelcie Ross": "https://image.tmdb.org/t/p/w185/gtUOc36bK5MrjdRPQJi1b0cc0LT.jpg",
"Clarence Felder": "https://image.tmdb.org/t/p/w185/hbioULG0wwkHlXcjXy89eZIPt2J.jpg",
"Chelsea Field": "https://image.tmdb.org/t/p/w185/9NnerSpNB4Ro3f3iMRorv1uvYlA.jpg",
"Damon Wayans": "https://image.tmdb.org/t/p/w185/rQ1KV896Hm0jzLTOdksbHoXh67l.jpg",
"Frank Collison": "https://image.tmdb.org/t/p/w185/mrFWmvxe72WwrjyYOZXtNpJLLfQ.jpg",
"Kim Coates": "https://image.tmdb.org/t/p/w185/xGoPaGsqRWCsDDDmY1gNR8eoxTA.jpg",
"Noble Willingham": "https://image.tmdb.org/t/p/w185/stdQUjYtyjfuJRgA89DyzkZEyai.jpg",
"Taylor Negron": "https://image.tmdb.org/t/p/w185/wk0bOBqw47cMntR7IJvlE9hE372.jpg",
"Joe Santos": "https://image.tmdb.org/t/p/w185/7D7ddztwCyW1D0DIxNR0JDAWu0d.jpg",
"Tony Longo": "https://image.tmdb.org/t/p/w185/1kRcEeiz6cFAX41xz9ttCDE2MfG.jpg"
},
"backdrop_original": [
"https://image.tmdb.org/t/p/original/3BRLjwxF2rmVFedrQkjNdPcd8Uw.jpg"
],
"backdrop": [
"https://image.tmdb.org/t/p/w1280/3BRLjwxF2rmVFedrQkjNdPcd8Uw.jpg"
]
},
"plot": "When the girl that detective Joe Hallenback is protecting gets murdered, the boyfriend of the murdered girl (ex-football player Jimmy Dix) attempts to investigate and solve the case. What they discover is that there is deep seated corruption going on between a crooked politician and the owner of a pro football team.",
"genres": [
"Adventure",
"Action",
"Comedy",
"Thriller",
"Crime",
"Mystery"
],
"in_library": false,
"released": "1991-12-12",
"tagline": "Everyone had counted them out. But they're about to get back in the game.",
"original_title": "The Last Boy Scout",
"directors": [
"Tony Scott"
],
"writers": [
"Shane Black (story)",
"Greg Hicks (story)",
"Shane Black (screenplay)"
],
"in_wanted": false,
"mpaa": "R",
"actors": [
"Bruce Willis",
"Damon Wayans",
"Chelsea Field",
"Noble Willingham"
],
"runtime": 105,
"type": "movie"
},
{
"rating": {
"imdb": [
6.3,
1175
]
},
"genres": [
"Fantasy",
"Adventure",
"Comedy",
"Sci-Fi"
],
"in_library": false,
"titles": [
"The Invisible Boy",
"Il ragazzo invisibile"
],
"tmdb_id": 303542,
"plot": "Michele is thirteen year old, shy, unpopular at school, and in love with Stella. After wearing a costume for a Halloween party, he finds out that he's invisible.",
"mpaa": "T",
"original_title": "Il ragazzo invisibile",
"actor_roles": {
"Fabrizio Bentivoglio": "Basilli",
"Valeria Golino": "Giovanna",
"Kseniya Rappoport": "Yelena",
"Assil Kandil": "Candela",
"Noa Zatta": "Stella",
"Vilius Tumalavicius": "Biondo",
"Ludovico Girardello": "Michele",
"Christo Jivkov": "Andreij"
},
"via_imdb": true,
"images": {
"poster_original": [
"https://image.tmdb.org/t/p/original/eYkOI2sLAoUhj8UgVhY03LAR8yW.jpg"
],
"poster": [
"https://image.tmdb.org/t/p/w154/eYkOI2sLAoUhj8UgVhY03LAR8yW.jpg",
"http://ia.media-imdb.com/images/M/MV5BYWMzNzAxOTktMmE3ZS00OTQxLWJiZWQtYjM3MWQxZmJlMTE5XkEyXkFqcGdeQXVyMTAxNTc3Nzk@._V1_.jpg"
],
"actors": {
"Kseniya Rappoport": "https://image.tmdb.org/t/p/w185/8CRRe5lTddGGUTF2pjNHAeYw12n.jpg",
"Fabrizio Bentivoglio": "https://image.tmdb.org/t/p/w185/uODahcGkpEJJNPPZNw06ET5V9d5.jpg",
"Christo Jivkov": "https://image.tmdb.org/t/p/w185/rRoYhDGVsXhCeVyhVa0lnhl6HSc.jpg",
"Valeria Golino": "https://image.tmdb.org/t/p/w185/kK13NzfxGQBJ8Th9SiPbu0FFJq7.jpg"
},
"backdrop_original": [
"https://image.tmdb.org/t/p/original/woLLDo3tal0R2jBykWyw6QJiDJk.jpg"
],
"backdrop": [
"https://image.tmdb.org/t/p/w1280/woLLDo3tal0R2jBykWyw6QJiDJk.jpg"
]
},
"directors": [
"Gabriele Salvatores"
],
"writers": [
"Alessandro Fabbri",
"Ludovica Rampoldi",
"Stefano Sardo"
],
"in_wanted": false,
"year": 2014,
"via_tmdb": true,
"imdb": "tt3078296",
"actors": [
"Ludovico Girardello",
"Valeria Golino",
"Fabrizio Bentivoglio",
"Christo Jivkov"
],
"type": "movie",
"runtime": 100
},
{
"rating": {
"imdb": [
7.8,
123130
]
},
"genres": [
"Drama",
"War"
],
"in_library": false,
"titles": [
"The Boy in the Striped Pajamas",
"The Boy in the Striped Pyjamas",
"O Rapaz do Pijama ?s Riscas",
"???????",
"????????",
"O Menino do Pijama Listrado"
],
"tmdb_id": 14574,
"plot": "Set during World War II, a story seen through the innocent eyes of Bruno, the eight-year-old son of the commandant at a concentration camp, whose forbidden friendship with a Jewish boy on the other side of the camp fence has startling and unexpected consequences.",
"tagline": "Lines may divide us, but hope will unite us.",
"year": 2008,
"original_title": "The Boy in the Striped Pyjamas",
"actor_roles": {
"Zsuzsa Holl": "Berlin Cook",
"Richard Johnson": "Grandpa",
"Cara Horgan": "Maria",
"Jack Scanlon": "Shmuel",
"Asa Butterfield": "Bruno",
"Vera Farmiga": "Mother",
"Rupert Friend": "Lieutenant Kurt Kotler",
"Iv?n Vereb?ly": "Meinberg",
"Charlie Baker": "Palm Court Singer",
"B?la Fesztbaum": "Schultz",
"L?szl? ?ron": "Lars",
"Sheila Hancock": "Grandma",
"Zac Mattoon O'Brien": "Leon",
"Henry Kingsmill": "Karl",
"Amber Beattie": "Gretel",
"David Thewlis": "Father"
},
"via_imdb": true,
"images": {
"poster_original": [
"https://image.tmdb.org/t/p/original/f40R9to84FGF7T5bp3KGB84Lklb.jpg"
],
"poster": [
"https://image.tmdb.org/t/p/w154/f40R9to84FGF7T5bp3KGB84Lklb.jpg",
"http://ia.media-imdb.com/images/M/MV5BMTMzMTc3MjA5NF5BMl5BanBnXkFtZTcwOTk3MDE5MQ@@._V1_.jpg",
"http://ia.media-imdb.com/images/M/MV5BMTMzMTc3MjA5NF5BMl5BanBnXkFtZTcwOTk3MDE5MQ@@._V1_SX300.jpg"
],
"actors": {
"Rupert Friend": "https://image.tmdb.org/t/p/w185/tYDs9R1TDHUgIT3bnXZo6GoyzTI.jpg",
"Richard Johnson": "https://image.tmdb.org/t/p/w185/miDA5sN3ijfED6M4oRZ0NTdBfBR.jpg",
"Cara Horgan": "https://image.tmdb.org/t/p/w185/wXPFyDpKemvplSq1X9YFUrZc0ev.jpg",
"Jack Scanlon": "https://image.tmdb.org/t/p/w185/lZXxoJ2dyv3tD0ookIKNx5hkxsF.jpg",
"Asa Butterfield": "https://image.tmdb.org/t/p/w185/zvaIeivqGmWgCtWusKmItMq3eeC.jpg",
"Vera Farmiga": "https://image.tmdb.org/t/p/w185/dNeyqIgD29efuzdoDFGqPZYa1Y0.jpg",
"Charlie Baker": "https://image.tmdb.org/t/p/w185/dweX5EVhUh4JfcKgVuaMAgjbyaJ.jpg",
"Sheila Hancock": "https://image.tmdb.org/t/p/w185/jZv0I2HNE4BbFTatSXPotNvZWRS.jpg",
"Zac Mattoon O'Brien": "https://image.tmdb.org/t/p/w185/oiVl4lzBroQbCa4iOydICQF2Tz6.jpg",
"Amber Beattie": "https://image.tmdb.org/t/p/w185/6wl7bpIIvkSG5fFUHjHTc62liv8.jpg",
"David Thewlis": "https://image.tmdb.org/t/p/w185/ozGL5i87RkvO2FTd43awnoJzFo7.jpg"
},
"backdrop_original": [
"https://image.tmdb.org/t/p/original/prhrYZvQN1eXxBeZdLlNSyLfPQb.jpg"
],
"backdrop": [
"https://image.tmdb.org/t/p/w1280/prhrYZvQN1eXxBeZdLlNSyLfPQb.jpg"
]
},
"directors": [
"Mark Herman"
],
"writers": [
"John Boyne (novel)",
"Mark Herman (screenplay)"
],
"in_wanted": false,
"mpaa": "PG-13",
"via_tmdb": true,
"imdb": "tt0914798",
"actors": [
"Asa Butterfield",
"Zac Mattoon O'Brien",
"Domonkos N?meth",
"Henry Kingsmill"
],
"type": "movie",
"runtime": 94
}
],
"yesAction": "addMovie",
"yesResponse": "Added The Boy (2016) to your list of movies to download.",
"noAction": "suggestNextMovie",
"noResponse": "Ok, did you mean The Boy Next Door (2015)?"
}
},
"user": {
"userId": "amzn1.echo-sdk-account.1234"
},
"new": false
},
"request": {
"type": "IntentRequest",
"requestId": "EdwRequestId.1234",
"timestamp": "2016-01-01T00:00:00Z",
"intent": {
"name": "AMAZON.NoIntent",
"slots": {}
}
}
}