Upload image file to Google Drive



2016/3/10
This article is out-of-date. Please use Google APIs Node.js Client .
For more details, read Accessing to Google Drive using Google APIs Node.js Client library

I wanted upload my image file to Google Drive from node.js.
This topic related to the previous article "Accessing to my Google Drive from node.js".


Step1) Get refresh token

See the previous article "Accessing to my Google Drive from node.js".


Step2) Understand Google Drive API

Step2-A> Type of Upload (Request Query Parameter)

Google explains how to upload an file to Google Drive.
https://developers.google.com/drive/v2/reference/files/insert

There are three ways to upload an file:

    • Simple upload
      Send the contents only, Google drive then return meta data such as title.  But this way, you can not specify the file name.
    • Multipart upload
      You need to send metadata and contents.
    • Resumable upload
      I haven't read the method Resumable upload yet ;p
In this time, I use Multipart upload.
You need specify one of these upload types as uploadType of query parameter.

Step2-B> Request Body

You can put the metadata and the contents of the file into request body like this. 
POST /upload/drive/v2/files?uploadType=multipart HTTP/1.1
Host: www.googleapis.com
Authorization: your_auth_token
Content-Type: multipart/related; boundary="foo_bar_baz"
Content-Length: number_of_bytes_in_entire_request_body

--foo_bar_baz
Content-Type: application/json; charset=UTF-8

{
  "title": "My File"
}

--foo_bar_baz
Content-Type: image/jpeg

JPEG data

--foo_bar_baz--

More details about Multipart uploading, read this page.
https://developers.google.com/drive/manage-uploads#multipart

Step3) Read a binary file

To read a binary file into node.js, use fs and buffer modules.

First, open a file with fs.open() method, which passes fileDescripter as second argument to callback. Then read the file using fs.read() and buffer like this.

var fstatus = fs.statSync(PNG_FILE);
fs.open(PNG_FILE, 'r', function(status, fileDescripter) {
  if (status) {
    callback(status.message);
    return;
  }
  var buffer = new Buffer(fstatus.size);
  fs.read(fileDescripter, buffer, 0, fstatus.size, 0, function(err, num) {
    console.log(buffer);
  });
});

Step4) Send the data to Google Drive

Now that send the file data to Google Drive.
I like request module which handles HTTP request simply.

request.post({
  'url': 'https://www.googleapis.com/upload/drive/v2/files',
  'qs': {
    'uploadType': 'multipart'
  },
  'headers' : {
    'Authorization': 'Bearer ' + accessToken
  },
  'multipart':  [
    {
      'Content-Type': 'application/json; charset=UTF-8',
      'body': JSON.stringify({
         'title': PNG_FILE,
         'parents': [
           {
             'id': PARENT_FOLDER_ID
           }
         ]
       })
    },
    {
      'Content-Type': 'image/png',
      'body': buffer
    }
  ]
}, callback);

Final) Conjunction with all steps

This is my code which uploads an png file to Google Drive as new file.

var GoogleTokenProvider = require('refresh-token').GoogleTokenProvider;

const CLIENT_ID = 'your_client_id';
const CLIENT_SECRET = 'your_client_secret';
const REFRESH_TOKEN = 'your_refresh_token';
const ENDPOINT_OF_GDRIVE = 'https://www.googleapis.com/drive/v2';
const PARENT_FOLDER_ID = 'your_parent_folder_id';

const PNG_FILE = 'test.png';

var async = require('async'),
    request = require('request'),
    fs = require('fs');

async.waterfall([
  //-----------------------------
  // Obtain a new access token
  //-----------------------------
  function(callback) {
    var tokenProvider = new GoogleTokenProvider({
      'refresh_token': REFRESH_TOKEN,
      'client_id': CLIENT_ID,
      'client_secret': CLIENT_SECRET
    });
    tokenProvider.getToken(callback);
  },

  function(accessToken, callback) {
    
    var fstatus = fs.statSync(PNG_FILE);
    fs.open(PNG_FILE, 'r', function(status, fileDescripter) {
      if (status) {
        callback(status.message);
        return;
      }
      
      var buffer = new Buffer(fstatus.size);
      fs.read(fileDescripter, buffer, 0, fstatus.size, 0, function(err, num) {
          
        request.post({
          'url': 'https://www.googleapis.com/upload/drive/v2/files',
          'qs': {
             //request module adds "boundary" and "Content-Length" automatically.
            'uploadType': 'multipart'

          },
          'headers' : {
            'Authorization': 'Bearer ' + accessToken
          },
          'multipart':  [
            {
              'Content-Type': 'application/json; charset=UTF-8',
              'body': JSON.stringify({
                 'title': PNG_FILE,
                 'parents': [
                   {
                     'id': PARENT_FOLDER_ID
                   }
                 ]
               })
            },
            {
              'Content-Type': 'image/png',
              'body': buffer
            }
          ]
        }, callback);
        
      });
    });
  },

  //----------------------------
  // Parse the response
  //----------------------------
  function(response, body, callback) {
    var body = JSON.parse(body);
    callback(null, body);
  },

], function(err, results) {
  if (!err) {
    console.log(results);
  } else {
    console.error('---error');
    console.error(err);
  }
});

Congratulation!

SHARE

Oscar perez

Arquitecto especialista en gestion de proyectos si necesitas desarrollar algun proyecto en Bogota contactame en el 3006825874 o visita mi pagina en www.arquitectobogota.tk

  • Image
  • Image
  • Image
  • Image
  • Image
    Blogger Comment
    Facebook Comment

0 comentarios:

Publicar un comentario