How to automate Instagram posts with Node.js and instagram-private-api (Instagram bot)

Automate instagram posts

Table of contents

Step 1: Install Node

I am assuming you have Node installed. If not, you will need to install it.

If you are not sure if you have Node installed, simply run

node -v

It should say something like

v16.14.2

Step 2: Create a new node app and install dependencies

Let's go ahead a create a new Node.js app with

npm init -y

This will create our package.json file for us. We will now add all the packages we will need for our bot.

npm install instagram-private-api
npm install request-promise
npm install dotenv
npm install cron
npm install express

Step 3: Create a .env file with your Instagram username and password

Go ahead and create a .env file that has your username and password for the account you'd like to post to. We will use these in our application.

.env
IG_USERNAME="<your-username>"
IG_PASSWORD="<your-password>"

Step 4: Login to Instagram using instagram-private-api

Create a file called index.js and require the necessary packages

index.js
require("dotenv").config();
const { IgApiClient } = require('instagram-private-api');
const { get } = require('request-promise');

Then, we will create a new async function called postToInsta, and add the code to log-in to Instagram

index.js
const postToInsta = async () => {
    const ig = new IgApiClient();
    ig.state.generateDevice(process.env.IG_USERNAME);
    await ig.account.login(process.env.IG_USERNAME, process.env.IG_PASSWORD);
}

Step 5: Download the image into a buffer, ready for upload

We now need to download our image from its source, and store it in a buffer. Note: If your image is already on your file system, and not hosted somewhere, you can follow the code in the official docs. The process is very similar.

Go ahead and add the following to your postToInsta function

index.js
const postToInsta = async () => {
    ...
    const imageBuffer = await get({
        url: 'https://i.imgur.com/BZBHsauh.jpg',
        encoding: null, 
    });
}

Step 6: Post to Instagram

All we need to do now is to post our image to Instagram

Add the following code to your postToInsta function

index.js
const postToInsta = async () => {
    ...
    await ig.publish.photo({
        file: imageBuffer,
        caption: 'Really nice photo from the internet!', // nice caption (optional)
    });
}

The photo method takes and object with different parameters. In this example, we are adding the file (mandatory) and the caption (optional). There are a number of other parameters we could add, have a look at this example to see what else you can add.

Step 7: Create a cron job

Generally, an application like this would post on a regular schedule, for example, every day. We can build on what we already have and add a cron job to our application. To do this, add the following line of code to the top of the index.js file.

index.js
const CronJob = require("cron").CronJob;

To create a cron job, we add the following

index.js
const cronInsta = new CronJob("30 * * * * *", async () => {
    postToInsta();
});

cronInsta.start();

What does this code do? It creates a cron job that will run when seconds are at 30, not every 30 seconds. I won't go into detail about what the 30 and stars mean, but have a look at this page which goes through what that syntax does. Similarly, there is this very handy online tool where you can build and edit cron syntax and it will tell you exactly when it will run.

Your final code for this section should look like

index.js
require("dotenv").config();
const { IgApiClient } = require('instagram-private-api');
const { get } = require('request-promise');
const CronJob = require("cron").CronJob;

const postToInsta = async () => {
    const ig = new IgApiClient();
    ig.state.generateDevice(process.env.IG_USERNAME);
    await ig.account.login(process.env.IG_USERNAME, process.env.IG_PASSWORD);

    const imageBuffer = await get({
        url: 'https://i.imgur.com/BZBHsauh.jpg',
        encoding: null, 
    });

    await ig.publish.photo({
        file: imageBuffer,
        caption: 'Really nice photo from the internet!',
    });
}

const cronInsta = new CronJob("30 * * * * *", async () => {
    postToInsta();
});

cronInsta.start();

Step 8: Add express (optional)

If you want to host this application on a hosting platform like heroku, you will need to add express to your node.js app. This is because when hosting node.js applications, they need a port to attach to.

To do that, simply add the following to your index.js file.

index.js
const express = require('express')
const app = express()
const port = process.env.PORT || 4000;

app.listen(port, () => {
  console.log(`Listening on port ${port}`)
})

Your final `index.js file should look like this

index.js
require("dotenv").config();

const express = require('express')
const app = express()
const port = process.env.PORT || 4000;

app.listen(port, () => {
  console.log(`Listening on port ${port}`)
})

const { IgApiClient } = require('instagram-private-api');
const { get } = require('request-promise');
const CronJob = require("cron").CronJob;

const postToInsta = async () => {
    const ig = new IgApiClient();
    ig.state.generateDevice(process.env.IG_USERNAME);
    await ig.account.login(process.env.IG_USERNAME, process.env.IG_PASSWORD);

    const imageBuffer = await get({
        url: 'https://i.imgur.com/BZBHsauh.jpg',
        encoding: null, 
    });

    await ig.publish.photo({
        file: imageBuffer,
        caption: 'Really nice photo from the internet!',
    });
}

const cronInsta = new CronJob("30 5 * * *", async () => {
    postToInsta();
});

cronInsta.start();

And that is it, your application to post to Instagram using node.js has been created. All that is left to do now is host your application on your favourite hosting platform.


Image of the Author, Ryan Carmody

About the Author

Open for work

Hi, I'm Ryan from Adelaide, South Australia.

I'm a web developer and computer science tutor. I also rock climb, play wheelchair basketball and brew beer.

Check out some of the games I made

WhereTaken

WhereTaken

Guess the country from a photo.

Retro Snake Game

Retro Snake

Eat the food but don’t hit the walls or your own body!

Retro Worldle

Worldle

Replica of the original but with extra features! Guess countries, flags and capitals.