I love films. I love recommending films to watch. I also love when people ask for my recommendations on what to watch. But sometimes this can become a little tedious, so a couple of months ago I started building a bot that recommends random (and good) movies when you mention it on Twitter. That's how @nosequever was born.
This is a simple guide on how to do it:
First let's install all the dependencies we'll use to build our bot. These are:
- Twit: it's a Twitter API client for Node.js. We'll use this client to "listen" for mentions in our account, and to tweet a response with our recommendation.
- Axios: an HTTP client for Node.js. This client will allow us to do a GET request to the TMDb API to get our random movie to recommend.
To install these dependencies, run inside your project's directory:
$ npm install --save twit axios
Once you've all our dependencies installed, we need to get all the credentials for the API's we'll be using: the Twitter API and the TMDb API. Let's create a config.js
file and paste those credentials:
module.exports = {
// Add your Twitter API Credentials
twitter_api: {
consumer_key: '',
consumer_secret: '',
access_token: '',
access_token_secret: ''
},
// Add the ID of the user you want to track
// You can find the ID of a twitter user in http://gettwitterid.com/
twitter_user_id: '',
// Add your TMBb API Credentials
movies_database_api_key: ''
}
Now we're ready to start building our bot! First, let's create an asynchronous function that returns the movie we'll recommend. This function will make a GET request to the TMDb API to retrieve a movie based in certain search parameters: a minimum number of votes and a minimum average score. In theory this will allow us to recommend only "good" movies, but it can fail (yes, we're talking to you Green Book). This request will return an array with different movies, and our recommendation we'll be a random index of that array.
const config = require('./config')
const Twit = require('twit')
const axios = require('axios')
// This will return the string with
// the recommended movie. If something
// goes wrong, returns an error message to tweet.
const getRecommendedMovie = async () => {
const tmdbApiKey = config.movies_database_api_key
const listPage = Math.floor(Math.random() * 234) + 1
const minimumVotes = 50
const minimumScore = 7
const requestURL =
'https://api.themoviedb.org/3/discover/movie?api_key=' +
tmdbApiKey +
'&language=en-US&sort_by=vote_average.desc&include_adult=false&include_video=false&page=' +
listPage +
'&vote_count.gte=' +
minimumVotes +
'&vote_average.gte=' +
minimumScore
// Stores the GET request into a variable
// that we'll return
const recommendedMovie = await axios
.get(requestURL)
.then((response) => {
if (response.status === 200) {
const moviesList = response.data.results
const listLength = moviesList.length
const randomIndex = Math.floor(Math.random() * listLength) + 1
// Yayy! We've our random movie to recommend!
const recommendedMovie = moviesList[randomIndex]
// Now, let's start putting together
// the string to tweet to the user
const movieID = recommendedMovie.id
const movieTitle = recommendedMovie.title
const movieReleaseYear = recommendedMovie.release_date.split('-')[0] // We just want the year
const movieURL = 'https://www.themoviedb.org/movie/' + movieID
// We'll tweet this to the user
const tweet =
' today you could watch ' +
movieTitle +
' (' +
movieReleaseYear +
'). More info: ' +
movieURL
return tweet
}
})
.catch(() => {
return ' seems like something went wrong π. Try again in a few minutes!'
})
return recommendedMovie
}
Alright! We've our movie recommendation. That was easy, wasn't it?
Now we need to initialize a Twit instance to "listen" for mentions in our account. If we're mentioned, we'll post a tweet in reply with our recommendation.
If you check Twit's documentation, in order to initialize an instance of it we need to pass our Twitter API credentials as a parameter. Once it's initialized we'll use the stream()
method to filter Twitter's public stream to search for mentions in our account, by using our Twitter account ID. Then, we can finally reply to that mention with our recommendation β€οΈ.
const config = require('./config')
const Twit = require('twit')
const axios = require('axios')
// This will return the string with
// the recommended movie. If something
// goes wrong, returns an error message to tweet.
const getRecommendedMovie = async () => {
const tmdbApiKey = config.movies_database_api_key // Your TMDb api key goes here
const listPage = Math.floor(Math.random() * 234) + 1
const minimumVotes = 50
const minimumScore = 7
const requestURL =
'https://api.themoviedb.org/3/discover/movie?api_key=' +
tmdbApiKey +
'&language=en-US&sort_by=vote_average.desc&include_adult=false&include_video=false&page=' +
listPage +
'&vote_count.gte=' +
minimumVotes +
'&vote_average.gte=' +
minimumScore
// Does a GET request to the TMDb API
// to get the random movie data
const recommendedMovie = await axios
.get(requestURL)
.then((response) => {
if (response.status === 200) {
const moviesList = response.data.results
const listLength = moviesList.length
const randomIndex = Math.floor(Math.random() * listLength) + 1
// Yayy! We've our random movie to recommend!
const recommendedMovie = moviesList[randomIndex]
// Now, let's start putting together
// the string to tweet to the user
const movieID = recommendedMovie.id
const movieTitle = recommendedMovie.title
const movieReleaseYear = recommendedMovie.release_date.split('-')[0] // We just want the year
const movieURL = 'https://www.themoviedb.org/movie/' + movieID
// We'll tweet this to the user
const tweet =
' today you could watch ' +
movieTitle +
' (' +
movieReleaseYear +
'). More info: ' +
movieURL
return tweet
}
})
.catch(() => {
return ' seems like something went wrong π. Try again in a few minutes!'
})
return recommendedMovie
}
// Our bot object
const bot = new Twit(config.twitter_api)
const myAccountId = config.twitter_user_id
// Twitter's public stream
const stream = bot.stream('statuses/filter', { follow: myAccountId })
// Every time our account receives a tweet,
// the `stream` object will run a function
// to verify if the tweet it's a mention
stream.on('tweet', async (eventMsg) => {
if (eventMsg.in_reply_to_screen_name === 'nosequever') {
const userToMention = eventMsg.user.screen_name
const toTweet = '@' + userToMention + ' ' + (await getRecommendedMovie()) // Remember getRecommendedMovie() it's asynchronous
const tweetParams = {
status: toTweet,
in_reply_to_status_id: eventMsg.id_str,
}
// ππ Tweets the recommendation ππ
bot.post('statuses/update', tweetParams)
}
})
π IT'S ALIVE π
You can test it by running node app.js
and then mentioning your bot account on Twitter. If you want it to run forever (wink, wink) you'll need to start a forever
process in your app.js
. You can do this by installing forever like this:
$ npm install --save forever
And then running
$ forever start app.js
β¨ That's it! You've successfully created a bot on Twitter β¨
Feel free to clone this project and make any improvements you want. You can even make a pull-request to add some features!
Hope you liked it. If you have any questions, you can ask me for help on Twitter at any time :)
Stay home, stay safe!
Top comments (0)