Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nodejs - Download a PDF with Dropbox Core API and save to disk

I have managed to do this without any problems before with Python and the Python SDK from Dropbox, but now that i am using Nodejs and the Dropbox HTTP API something goes wrong. When i save the PDF file locally i can only see parts of the original PDF, and when i compare it to the original file with for example WinMerge i see that the files are not equal and are different sized. The only difference i can think of is that it might be getting saved with a different encoding than the original, but i have tried most of them with iconv-lite and none of them gives a good result.

I also tried to use https://github.com/dropbox/dropbox-js to see if it gave a different result, and also https://www.npmjs.com/package/request instead of node-rest-client, but without success.

Has any one implemented this and made it work?

This is my code:

var fs = require('fs'),
    RestClient = require('node-rest-client').Client;

var args = {
    headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/pdf',
        'Authorization': 'Bearer xxx'
    }
};

var restClient = new RestClient();
var url = 'https://api-content.dropbox.com/1/files/auto/' + dropboxPath;
var filePath = '/var/temp/' + fileName;

restClient.get(url, arguments, function(body, response) {
    fs.writeFile(filePath, response, function (error, written, buffer) {});
}

when testing with different encodings it looked something like this:

var fs = require('fs'),
    RestClient = require('node-rest-client').Client,
    iconvlite = require('iconv-lite');

iconvlite.extendNodeEncodings();

var args = {
    headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/pdf',
        'Authorization': 'Bearer xxx'
    }
};

var restClient = new RestClient();
var url = 'https://api-content.dropbox.com/1/files/auto/' + dropboxPath;
var filePath = '/var/temp/' + fileName;
var options = { encoding: 'UTF-8' };

restClient.get(url, arguments, function(body, response) {
    fs.writeFile(filePath, response, options, function (error, written, buffer) {});
}
like image 246
missemisa Avatar asked Nov 22 '25 00:11

missemisa


1 Answers

I think node-rest-client always converts the returned data to a string, so it will end up corrupting binary data. See https://github.com/aacerox/node-rest-client/blob/master/lib/node-rest-client.js#L396.

The request library seems to have a similar issue when using a callback, but you can bypass that by piping directly to the file:

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

var accessToken = '123xyz456';
var filename = 'myfile.pdf';

request('https://api-content.dropbox.com/1/files/auto/' + filename, {
    auth: { bearer: accessToken }
}).pipe(fs.createWriteStream(filename));

EDIT: I filed an issue on GitHub for the node-rest-client issue, and it looks like the library maintainer has already prepared a fix (in a branch). See https://github.com/aacerox/node-rest-client/issues/72.

like image 66
user94559 Avatar answered Nov 24 '25 17:11

user94559



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!