Let's Create a Twitter Bot using Node.js and Heroku (2/3)
Tags: node, twitter, javascript, tutorial
Published: 2020-02-05 20:07:28

Welcome to Part 2 of creating your own twitter bot. If you haven't already had a chance, check out [Part 1](https://dev.to/developer_buddy/let-s-create-a-twitter-bot-using-node-js-and-heroku-1-3-43kb) on setting up your twitter account and getting access to Twitter's API. 

Now, we get to make the magic happen and code out our twitter bot in Node.js. Let's get down to business. 


# 1. Installing Node

First things first you're going to need to install node onto your computer. If you've ever worked with npm before you will already have it installed. If you're unsure just run the following command in your terminal

### node -v

If your terminal displays something like `v13.3.0` in your terminal than move ahead to step 2. If not, then you'll have to complete the steps to download and install the Node package which you can find [here](https://nodejs.org/en/download/). After downloading rerun the above command to verify it's properly installed before moving on 

# 2. Creating Your Files

Now we want to create our directories and files for the project. Open up your terminal and run the following commands.  

``` javascript
mkdir tweetbot
cd tweetbot
touch README.md bot.js touch.js .env .gitignore
```

What we just did here was: 

##### 1. Make a directory named tweetbot
##### 2. Change directories into our tweetbot folder
##### 3. Make some files inside of our tweetbot directory (which we'll get back to later)

Now that we have our files created it's time to initialize our project. You'll want to open your tweetbot directory in the IDE of your choice(I recommend [VSCode](https://code.visualstudio.com/download)) and then run the following command in your terminal

### npm init

You'll be prompted to fill out some information. You can always change the info later so don't stress too much if you don't fill in everything. After you're done you should notice a `package.json` file in your folder. You'll want it to look like this 

```javascript
{
  "name": "tweetbot",
  "version": "1.0.0",
  "description": "Twitter bot",
  "main": "bot.js",
  "scripts": {
    "test": "test"
  },
  "author": "Buddy Agyin",
  "license": "ISC",
  "dependencies": {
    "dotenv": "^8.2.0",
    "twit": "^2.2.11"
  }
}
``` 

Inside of your `package.json file`, you'll want to add some code inside of "scripts" so it looks like this. All that this is doing is giving our bot a default command that we can use later on. 

```javascript

  "scripts": {
    "test": "test",
    "start": "node bot.js"
  }
```

Alright, now the final step is to get our dependencies added to our project. We want to install both twit and dotenv. The twit dependency is the Twitter API client while the dotenv dependency will allow us to load environment variables into our project. Run the following command in your terminal

### node install twit dotenv

These both will be automatically added to your package.json file. 

# 3. Creating Github Repo

Next, we'll be creating a [GitHub](https://github.com) repo for our project. This step isn't necessary and if you don't want to create a repo you can feel free to skip ahead to step 4. 

* Just a quick reminder that you never want to push your code up to Github with your access keys public. 

![Github create repo](https://help.github.com/assets/images/help/repository/repo-create.png)

If you already have an account login and create a new repo. If you need an account, go ahead and create one before creating a repo. 

![Github create repo form](https://github.com/agyin3/images/blob/master/Twitter%20Bot%20Blog/Screen%20Shot%202020-01-30%20at%2011.05.16%20PM.png?raw=true)

You'll want to name your repo and give it a brief description. For our purposes don't initialize your repo with a README file (we already have one created) or a license. 

After you've created your repo, you'll want to go back into your terminal. Make sure you're in the tweetbot directory before running the following command. This will initialize your project as a Git repository 

### git init

Now you'll want to add your files to your local repository and stage them for commit. Again in your terminal run the following command.  

### git add . 

Almost there, now you'll want to commit your files to the local repository. Run this command in your terminal

### git commit -m "commit all files"

Ok, now you'll want to copy the url from your GitHub repo which you can find at the top of your GitHub repository's Quick Setup page. Just click the clipboard to copy the remote repository URL.

![Github create repo form](https://help.github.com/assets/images/help/repository/copy-remote-repository-url-quick-setup.png)

Now back in the terminal you'll want to run the following code so you can set your remote repository as the location we want to push our local repository. Be sure to replace <remote repository URL> with the url you just copied from your GitHub repo.

```
$ git remote add origin <remote repository URL>
$ git remote -v
```

Finally, you'll want to push all of your files up to your GitHub repo with the following command inside your terminal. Once you do that, your GitHub repo will be all setup.

### git push -u origin master

# 4. Programming The Bot

We have the files set up and our Github repo made, let's finally program our bots. 

First things first we'll have to get our access keys configured. Open up your `.env` file and add your consumer keys and access tokens to the file. If you don't have these you can get them from your [Twitter Developer](https://https://developer.twitter.com/) account. 

You'll want to replace the X's with your keys.

```
CONSUMER_KEY=XXXXXXXXXXXXXXXXXXXXXXXXX
CONSUMER_SECRET=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ACCESS_TOKEN=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ACCESS_TOKEN_SECRET=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
```

Now head on over to your `config.js` file and enter the following code.

```javascript
require('dotenv').config()
module.exports = {
    consumer_key: process.env.CONSUMER_KEY,
    consumer_secret: process.env.CONSUMER_SECRET,
    access_token: process.env.ACCESS_TOKEN,
    access_token_secret: process.env.ACCESS_TOKEN_SECRET
}
```

Once that's all set up open up your `bots.js` file and place this code at the top of the file. 


```javascript
const Twit = require('twit');
const config = require('./config.js');
const tweetBot = new Twit(config);
```

All this is doing is importing our access keys from our `config.js` file and allowing us access to the Twitter API. 

Next, you'll want to add some parameters to tell your bot what to search for. You can do that by adding this code to your file.

```javascript
const params = {
    q: '#nature AND #photography filter:media',
    count: 10,
    lang: 'en'
}
```

Sweet. I'm telling my bot to search twitter for tweets tagged with both #nature `AND` #photography, have some type of media and are written in English. I'm also only returning 10 tweets with each search. 

Feel free to use the same parameters or switch it up to your liking. For more info on the different parameters check out Twitter's [guide](https://developer.twitter.com/en/docs/tweets/search/guides/standard-operators)

Ok, now we want to tell our bot what to do with these tweets, which in our case is retweet them.

```javascript
tweetBot.get('search/tweets', params,  (err, data, res) => {
    if(!err){
        for(let i=0; i < data.statuses.length; i++){
            let tweetID = {id: data.statuses[i].id_str}
            tweetBot.post('statuses/retweet', tweetID, (err, res) => {
                if(!err){
                    console.log(`Retweet successful`)
                }else{
                    console.log(err.message)
                }
            })
        }
    }else{
        console.log(err)
    }
})
```  

Here we're telling our bot to search for tweets with the parameters we set up. Our bot will then tell console out whether it was able to retweet the tweet. If it's a new tweet it will retweet it and give us the following message "Retweet Successful." If it has already been retweeted the bot will let us know. 

I also want my bot to be able to favorite tweets as well but using different search parameters. 

At the top of your `bots.js` file under your `params` add this add.

```javascript
const favParams = {
    q: '#photography OR #nature filter:media',
    count: 15,
    lang: 'en'
}
```

You'll notice that the code looks familiar but with a few differences. In this case, we're telling our bot to search for tweets tagged with #photography `OR` #nature, have some type of media and written in English. In this case, we'll be returning 15 tweets with each search.

Like before, feel free to change the parameters to your own choosing. 

Now we're going to want to tell our bot to search for these tweets and then favorite them. 

At the bottom of your file add the following code.

```javascript
tweetBot.get('search/tweets', favParams,  (err, data, res) => {
    if(!err){
        for(let i=0; i < data.statuses.length; i++){
            let tweetID = {id: data.statuses[i].id_str}
            tweetBot.post('favorites/create', tweetID, (err, res) => {
                if(!err){
                    console.log(`Favorite successful`)
                }else{
                    console.log(err.message)
                }
            })
        }
    }else{
        console.log(err)
    }
})
```  

Similar to the retweeting functionality, our bot will search for tweets with the parameters we set up. Our bot will then tell console out whether it was able to favorite the tweet. If it's a new tweet it will favorite it and give us the following message "Favorite Successful." If it has already been favorited the bot will let us know.

Your final code should look something like this:

```javascript
const Twit = require('twit');
const config = require('./config.js');
const tweetBot = new Twit(config);

const params = {
    q: '#nature AND #photography filter:media',
    count: 10,
    lang: 'en'
}

const favParams = {
    q: '#photography OR #nature filter:media',
    count: 15,
    lang: 'en'
}

tweetBot.get('search/tweets', params,  (err, data, res) => {
    if(!err){
        for(let i=0; i < data.statuses.length; i++){
            let tweetID = {id: data.statuses[i].id_str}
            tweetBot.post('statuses/retweet', tweetID, (err, res) => {
                if(!err){
                    console.log(`Retweet successful`)
                }else{
                    console.log(err.message)
                }
            })
        }
    }else{
        console.log(err)
    }
})

tweetBot.get('search/tweets', favParams,  (err, data, res) => {
    if(!err){
        for(let i=0; i < data.statuses.length; i++){
            let tweetID = {id: data.statuses[i].id_str}
            tweetBot.post('favorites/create', tweetID, (err, res) => {
                if(!err){
                    console.log(`Favorite successful`)
                }else{
                    console.log(err.message)
                }
            })
        }
    }else{
        console.log(err)
    }
})
```

# 5. Give Your Bot A Spin

Sweet! Your bot should be ready to test out. Go ahead and run the following code in your terminal. Make sure you're inside your tweetbot folder. 

### npm start

You should see a bunch of "Retweet Successful" and "Favorite Successful" outputs in your terminal. This means that your bot is doing its thing. You can check your twitter account just to verify that it actually worked. 

Now that our bot is alive, you'll want to push your changes up to your Github repo. Run the following commands in your terminal

```
git add .
git commit -m "bot working"
git push origin master
```

Congratulations! You just built your very own bot. But we don't want to only be able to run it in our terminal, so in the [third](https://dev.to/developer_buddy/let-s-create-a-twitter-bot-using-node-js-and-heroku-3-3-agk) and final post I'll show you how to automate this process. 

Feel free to check out my bot [@coolnatureshots](https://twitter.com/coolnatureshots) and the Github repo for it [here](https://github.com/agyin3/tweetbot-photo)