Skip to content

Instantly share code, notes, and snippets.

@dam1
Created January 8, 2018 13:44
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save dam1/f77fcbea52ca9124ff50f3598d280710 to your computer and use it in GitHub Desktop.
Save dam1/f77fcbea52ca9124ff50f3598d280710 to your computer and use it in GitHub Desktop.
Resumable Upload Google Drive Api - Node Js
var fs = require('fs');
var request = require('request');
var EventEmitter = require('events').EventEmitter;
var mime = require('mime');
var util = require('util');
function resumableUpload() {
this.byteCount = 0; //init variables
this.tokens = {};
this.filepath = '';
this.metadata = {};
this.query = '';
this.retry = -1;
this.host = 'www.googleapis.com';
this.api = '/upload/drive/v3/files';
};
util.inherits(resumableUpload, EventEmitter);
//Init the upload by POSTing google for an upload URL (saved to self.location)
resumableUpload.prototype.upload = function () {
var self = this;
var options = {
url: 'https://' + self.host + self.api + '?uploadType=resumable' + self.query,
headers: {
'Host': self.host,
'Authorization': 'Bearer ' + self.tokens.access_token,
'Content-Length': new Buffer(JSON.stringify(self.metadata)).length,
'Content-Type': 'application/json',
'X-Upload-Content-Length': fs.statSync(self.filepath).size,
'X-Upload-Content-Type': mime.getType(self.filepath)
},
body: JSON.stringify(self.metadata)
};
//Send request and start upload if success
request.post(options, function (err, res, body) {
if (err || !res.headers.location) {
self.emit('error', new Error(err));
self.emit('progress', 'Retrying ...');
if ((self.retry > 0) || (self.retry <= -1)) {
self.retry--;
self.upload(); // retry
} else {
return;
}
}
self.location = res.headers.location;
self.send();
});
}
//Pipes uploadPipe to self.location (Google's Location header)
resumableUpload.prototype.send = function () {
var self = this;
var options = {
url: self.location, //self.location becomes the Google-provided URL to PUT to
headers: {
'Authorization': 'Bearer ' + self.tokens.access_token,
'Content-Length': fs.statSync(self.filepath).size - self.byteCount,
'Content-Type': mime.getType(self.filepath)
}
};
try {
//creates file stream, pipes it to self.location
var uploadPipe = fs.createReadStream(self.filepath, {
start: self.byteCount,
end: fs.statSync(self.filepath).size
});
} catch (e) {
self.emit('error', new Error(e));
return;
}
var health = setInterval(function () {
self.getProgress(function (err, res, body) {
if (!err && typeof res.headers.range !== 'undefined') {
self.emit('progress', res.headers.range.substring(8));
}
});
}, 5000);
uploadPipe.pipe(request.put(options, function (error, response, body) {
clearInterval(health);
if (!error) {
self.emit('success', body);
return;
}
self.emit('error', new Error(error));
if ((self.retry > 0) || (self.retry <= -1)) {
self.retry--;
self.getProgress(function (err, res, b) {
if (typeof res.headers.range !== 'undefined') {
self.byteCount = res.headers.range.substring(8); //parse response
} else {
self.byteCount = 0;
}
self.send();
});
}
}));
}
resumableUpload.prototype.getProgress = function (handler) {
var self = this;
var options = {
url: self.location,
headers: {
'Authorization': 'Bearer ' + self.tokens.access_token,
'Content-Length': 0,
'Content-Range': 'bytes */' + fs.statSync(self.filepath).size
}
};
request.put(options, handler);
}
module.exports = resumableUpload;
var ResumableUpload = require('./resumableUpload');
module.exports = function (client, folderId, cb) {
var resumableUpload = new ResumableUpload(); //create new ResumableUpload
resumableUpload.tokens = client; //Google OAuth2 tokens
resumableUpload.filepath = './pdf.pdf';
resumableUpload.metadata = {
name: 'pdf.pdf',
parents: [folderId]
};
resumableUpload.query = '&supportsTeamDrives=true';
resumableUpload.retry = 3; // Maximum retries when upload failed.
resumableUpload.upload();
resumableUpload.on('progress', function (progress) {
console.log(progress);
});
resumableUpload.on('success', function (success) {
cb(success)
});
resumableUpload.on('error', function (error) {
console.log(error);
});
};
@BonsoirDiep
Copy link

BonsoirDiep commented Sep 21, 2018

srr bro, "usage.js"
resumableUpload.on('xx', blah..blah..blah); resumableUpload.upload();

@SebTota
Copy link

SebTota commented Feb 6, 2021

Did you publish this under any specific license? Do you allow free use?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment