My FeedDiscussionsHeadless CMS
New
Sign in
Log inSign up
Learn more about Hashnode Headless CMSHashnode Headless CMS
Collaborate seamlessly with Hashnode Headless CMS for Enterprise.
Upgrade ✨Learn more
Easiest way to automate image upload to cloudinary using nodejs

Easiest way to automate image upload to cloudinary using nodejs

Saurabh Mhatre's photo
Saurabh Mhatre
·May 5, 2017

Cloudinary is a cloud service that offers a solution to a project's entire image management pipeline by which we can easily upload images & videos to cloud. It offers comprehensive APIs and administration capabilities and is easy to integrate with any mobile or web application.

In today's article we are going to write a simple nodejs script to automatically upload images to cloudinary cdn when someone adds a new image to a folder on local machine or remote server. Run "npm init" command in a folder and following command to install required npm modules:

npm install --save express chokidar cloudinary

Let us start by spinning up a simple express server:

const express = require('express');
let app = express();
let port = process.env.PORT || 5000;
//start server on specified port
app.listen(port);
console.log("serve listening on port", port);

We will be using chokidar npm module to listen for changes in image source folder to check if new files are added anywhere inside the folder. You can find an excellent tutorial explaining it's usage in detail with all available options here: Tutorial.

We set up chokidar to listen for changes as follows:

const express = require('express');
let app = express();
const chokidar = require('chokidar');
const filepath = '/home/saurabh/Pictures/Apps/';
let watcher = chokidar.watch(filepath, {
  ignored: /[\/\\]\./, persistent: true
});

let log = console.log.bind(console);
let scanComplete = false;

watcher
  .on('add', function (path) {
    if (scanComplete) {
     //add image uploading code here   
   }
  })
  .on('addDir', function (path) {
    // log('Directory', path, 'has been added'); 
  })
  .on('error', function (error) { log('Error happened', error); })
  .on('ready', function () {
    log('Initial scan complete. Ready for changes.');
    scanComplete = true;
  })
  .on('raw', function (event, path, details) {
    // log('Raw event info:', event, path, details);
  })

Here we first specify folderpath in which we are going to add files on line 4. Then we set up watcher to watch files in folder on next line. Watcher has multiple event listeners on which appropriate callbacks are fired. It will first add all existing files in folder in watcher. In order to prevent uploading of existing files to cdn we first set scanComplete flag to false. When chokidar has finished scanning all files it fires ready event. In that case we can set scanComplete flag to true so that we can upload the next incoming files to cdn. Whenever a new file is added anywhere inside the source folder the _add _event is fired and since initial scan is now complete we can now add new files to cdn.

Now let us focus on setting up upload to cloudinary cdn. First we need to set up access to cloudinary cdn:

...
let scanComplete = false;
const cloudinary = require('cloudinary');
cloudinary.config({
  cloud_name: 'yourcloudname',
  api_key: 'your cloudinary api key',
  api_secret: 'api secret key'
});

You will get the cloudname,api_key and api_secret from dashboard of cloudinary cdn. Create an account if you don't have one and go to dashboard to get all the required credentials. Click on reveal to get api_secret in the dashboard tab.

Next we will upload files to cloudinary cdn when chokidar watcher detects addition of new file to filepath.

...
.on('add', function (path) {
    if (scanComplete) {
      let pathArray = path.split('/');
      if (!pathArray[pathArray.length - 1].includes("crdownload")) {
        log('File', path, 'has been added');
        // console.log(pathArray.length, pathArray[pathArray.length - 2]);
        let destfolder = pathArray[pathArray.length - 2];
        let destfileName = pathArray[pathArray.length - 1];
        cloudinary.v2.uploader.upload(path, {
          folder: destfolder,
          use_filename:true,
          tags:[destfolder]
        }, function (error, result) {
          if (error) {
            console.log("error ocurred", error);
          }
          else {
            console.log("result of upload \n", result.secure_url,"\n insecure url: \n",result.url);
          }
        });
      }
    }
  })

When file is added we first split path in individual names using split method in line 4.

For example if filepath is '/home/saurabh/Pictures/Apps/imgcat1/img1.jpg' we get pathArray as ['','home','saurabh','Pictures','Apps','imgcat1','img1.jpg']

Now I download images from chrome due to which it first creates a temporary ".crdownload" file while file download is in progress. In order to prevent uploading of temp files to cdn we have added an if condition in the next line. Once filedownload is complete I prefer to upload the file in a specific remote folder in cloudinary cdn rather than uploading files directly to base path. We first get destinationfolder name which might be imgcat1(second last element in pathArray variable) in the above example and destfileName which is last element in pathArray variable.

Next we call uploader method from cloudinary module to upload file from path variable that chokidar watcher returns. The second parameter in upload function is a json containing extra parameters which customizing upload to cdn. You can get detailed list of upload option here: Upload Api Reference

We first specify that we will upload the image inside destfolder at cloudinary cdn. Please create appropriate folder on the cdn by going to cloudinary dashboard, clicking on media library and creating new folder to avoid any unwanted issues. Next we set "use_filename" flag to true so that filesnames are not assigned random names on cdn and specify appropriate tags to have easier indexing and usage of images in future.

You can find the complete source code for the script here: GithubGist

Bonus Tip:

Tip #1: Even if you don't use cloudinary as your cdn you can still use chokidar module for variety of purposes like updating file/content metadata when new files are uploaded into server or run some simple automation tasks based on your needs.

Tip #2: You can also upload video files to cloudinary cdn and if video files using same upload function by following documentation here: Video Upload Api Reference

Connect Deeper:

In the next article I will probably try to cover creation of progressive web app using reactjs and nodejs/firebase backend. If you would like to get notified about upcoming articles then you can follow our facebook page: Technoetics or subscribe to our mailing list below: