Tweeting with an image using Node JS
Tags: javascript, node, twitter
Published: 2021-07-10 15:21:41

###Introduction
This is my fourth tutorial about using Twitter API with Node JS. My previous tutorials are listed up there 👆.

In my first tutorial, I showed how to tweet with only text using Twitter API and Node JS, see [here](https://dev.to/ahmed_mahallawy/tweeting-using-node-js-5986).
Then I got a question on how to tweet with an image, thanks to @thomasbnt and @generativexbot , so here I'll explain my way to do this.

###Before we start
You need to have a Twitter Developer account and for the basic configurations please go [here](https://dev.to/ahmed_mahallawy/tweeting-using-node-js-5986) for more explanation as I follow the same structure.

###Let's start
To tweet an image, the process will consist of two requests:
1- Uploading the image
2- Tweeting with that image

- The new thing here is that each request uses a different subdomain in the Twitter API url, which means that a small change will be done on the config.js file.

```
const twitter = require('twitter-lite');

exports.newClient = function (subdomain = 'api') {
    return new twitter({
        subdomain,
        consumer_key: '',
        consumer_secret: '',
        access_token_key: '',
        access_token_secret: ''
    });
}
```

- Here I changed the configurations to be returned as a function instead of a JSON object. The function returns a twitter lite client that I moved its definition here for simplicity. The reason I did that is the new configuration attribute **subdomain**, which can be set from the function parameter.

-Now, we are ready to edit the index.js file. Some changes must be made after changing the config.js file:
1- Remove twitter lite definition
2- Define twitter lite clients for both subdomains to be used later

```
const apiClient = config.newClient();
const uploadClient = config.newClient('upload');
```

- I got this photo to be used with the tweet
![hello_world.png](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bqawdp4gil1arcvj0iv4.png)

- Then we deal with the image file and make it ready for the upload by defining the **fs** and **path** modules.

```
const fs = require('fs');
const path = require('path');
```

- Then, read the file as a 64 based file.

```
const mediaFile = fs.readFileSync(path.join(__dirname, 'hello_world.png'));
const base64image = Buffer.from(mediaFile).toString('base64');
```

- Next, it's similar to what we did in this [tutorial](https://dev.to/ahmed_mahallawy/like-retweet-and-follow-in-twitter-using-node-js-5gbc) where a request is depending on the result of another request.

- The first request is for uploading image using **media/upload** endpoint and the uploading subdomain. This means using *uploadClient* here and returns an object with media_id attribute which we save for the next step.

```
// Uploading an image
uploadClient.post('media/upload', { media_data: base64image })
    .then(media => {
    
    console.log('You successfully uploaded media');

    var media_id = media.media_id_string;
}).catch(console.error);
```
- You can see full details for this request [here](https://developer.twitter.com/en/docs/twitter-api/v1/media/upload-media/api-reference/post-media-upload).

- The second request is the normal tweeting using **statuses/update** endpoint to tweet with the image, which uses the *apiClient*.

```
// tweeting with text and image
apiClient.post('statuses/update', { status: 'Hello world!', media_ids: media_id })
    .then(tweet => {
    
    console.log('Your image tweet is posted successfully');
}).catch(console.error);
```

- You can see full details for this request [here](https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/post-statuses-update).

- everything in place now and we can run the app in *Command Prompt* using:

```
node index.js
```

- That's it and your image is added to your tweet and takes its place in your friends timeline 😁.

Here's is the full code for index.js file:

```
const fs = require('fs');
const path = require('path');
const config = require('./config');
const apiClient = config.newClient();
const uploadClient = config.newClient('upload');

const mediaFile = fs.readFileSync(path.join(__dirname, 'hello_world.png'));
const base64image = Buffer.from(mediaFile).toString('base64');

uploadClient.post('media/upload', { media_data: base64image })
    .then(media => {
    
    console.log('You successfully uploaded media');

    var media_id = media.media_id_string;
    apiClient.post('statuses/update', { status: 'Hello world!', media_ids: media_id })
        .then(tweet => {

        console.log('Your image tweet is posted successfully');
    }).catch(console.error);

}).catch(console.error);
```

In the following tutorial, we are going to explore more about twitter API. I have several ideas to share with you, so stay tuned 😉

For the full code, you can visit [my github page](https://github.com/amahallawy/MediaTweetBot).

If you like my tutorials, support me here [![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/F2F41UH5T) and follow me on Twitter [![Twitter URL](https://img.shields.io/twitter/url/https/twitter.com/ahmed_mahallawy.svg?style=social&label=Follow%20%40ahmed_mahallawy)](https://twitter.com/ahmed_mahallawy)