Upload file to Box API from string using Node.js - node.js

I'm using version 2 of Box's API and attempting to upload files. I have Oauth 2 all working, but I'm having trouble making actual uploads.
I'm using Node.js and Express, along with the "request" module. My code looks something like this:
request.post({
url: 'https://upload.box.com/api/2.0/files/content',
headers: {
Authorization: 'Bearer ' + authToken
},
form: {
filename: ????,
parent_id: '0'
}
}, function (error, response, body) {
// ...
});
For now, I'm trying to upload to the root folder which, if I understand correctly, has an ID of '0'.
What I'm really not sure about is what value to give "filename". I don't have a true file to read from, but I do have a lengthy string representing the file contents I would like to upload.
How best should I upload this "file"?

For Box, I believe you want to use requests multi-part/form-data implementation.
It should look something like this:
var request = require('request');
var fs = require('fs');
var r = request.post(...);
var form = r.form();
form.append('filename', new Buffer("FILE CONTENTS"), {filename: 'file.txt'});
form.append('parent_id', 0);

var fs = require('fs');
var request = require('request');
var path = require('path');
function requestCallback(err, res, body) {
console.log(body);
}
var accessToken = 'SnJzV20iEUw1gexxxxvB5UcIdopHRrO4';
var parent_folder_id = '1497942606';
var r = request.post({
url: 'https://upload.box.com/api/2.0/files/content',
headers: { 'Authorization': 'Bearer ' + accessToken }
}, requestCallback);
var form = r.form();
form.append('folder_id', parent_folder_id);
form.append("filename", fs.createReadStream(path.join(__dirname, 'test.mp4')));

Related

how to read image from local and convert it into file object using node.js

I have a .png file in my node project folder and I want to read that file and send that file to a remote REST api which accepts form-data format and returns the image url after uploading it to S3.
I have previously used the same api for image upload in front-end using JavaScript. In my JS application I was using input type file to upload a image, which was giving me image in file format and then I was passing that to api after adding that file into formData object like this:
let formData = new FormData();
formData.append("content_file", file)
but when I'm trying to do the same in node.js, I'm not able to read that file into file format, due to which Api is not accepting the request body.
I'm new to node js, I'm not even sure that I'm reading the file in right way or not. Please help!
var express = require('express');
var fs = require('fs');
var path = require('path');
var Request = require("request");
var FormData = require('form-data');
var app = express();
// for reading image from local
app.get('/convertHtml2image1', function (req, res) {
fs.readFile(`image_path`, (err, data) => {
if (err) res.status(500).send(err);
let extensionName = path.extname(`banner.png`);
let base64Image = new Buffer(data, 'binary').toString('base64');
let imgSrcString = `data:image/${extensionName.split('.').pop()};base64,${base64Image}`;
// for converting it to formData
let formData = new FormData();
formData.append("content_file", data)
// for calling remote REST API
Request.post({
"headers": { "token": "my_token" },
"url": "api_url",
"body": formData
}, (error, response, body) => {
if (error) {
return console.log(error);
}
let result = JSON.parse(body)
res.send("image_url: " + result.url)
});
})
})
app.listen(5000);
As far as I understand, you try to create Blobs in Nodejs. It is not defined but it is basically an arraybuffer with file information. Maybe, you can use an external npm package to make it blob. Check this
Instead of fs.readFile() use fs.createReadStream() and don't upload image inside file stream, first read the file then add it to formData and then upload(or send it to api) because instead of file you were uploading the stream here.
var express = require('express');
var fs = require('fs');
var path = require('path');
var Request = require("request");
var FormData = require('form-data');
var app = express();
app.get('/convertHtml2image', function (req, res) {
var formData = {
name: 'content_file',
content_file: {
value: fs.createReadStream('banner.png'),
options: {
filename: 'banner.png',
contentType: 'image/png'
}
}
};
Request.post({
"headers": {
"Content-Type": "multipart/form-data",
"token": my_token
},
"url": api_url,
"formData": formData
}, (error, response, body) => {
if (error) {
return console.log("Error: ", error);
}
let result = JSON.parse(body)
res.send("image_url: " + result.url)
});
})
app.listen(5000);

Access files on Dropbox with NodeJS

I am using the Dropbox API with Node JS. I was able to upload files to my Dropbox using HTTP requests, but I am not able to download them with it. My intent is to use HTTP request to view content of the file in the dropbox.
This is the code for uploading files:
var request = require('request')
var fs = require('fs')
var token = "XXXXXXXXXXXXXXXXX"
var filename = "path/to/file/file.txt"
var content = fs.readFileSync(filename)
options = {
method: "POST",
url: 'https://content.dropboxapi.com/2/files/upload',
headers: {
"Content-Type": "application/octet-stream",
"Authorization": "Bearer " + token,
"Dropbox-API-Arg": "{\"path\": \"/files/"+filename+"\",\"mode\": \"overwrite\",\"autorename\": true,\"mute\": false}",
},
body:content
};
request(options,function(err, res,body){
console.log("Err : " + err);
console.log("res : " + res);
console.log("body : " + body);
})
Now what should the request function be for downloading this file? I was attempting something like this:
var request = require('request')
var fs = require('fs')
var token = "XXXXXXXXXXXXXXXXXXXXXXXXXXXX"
var filename = "path/to/file/file.txt"
var content = fs.readFileSync(filename)
options = {
method: "GET",
url: 'https://content.dropboxapi.com/2/files/upload',
headers: {
"Content-Type": "application/octet-stream",
"Authorization": "Bearer " + token,
"Dropbox-API-Arg": "{\"path\": \"/files/"+filename+"\",\"mode\": \"overwrite\",\"autorename\": true,\"mute\": false}",
},
};
request(options,function(err, res){
console.log("Err : " + err);
console.log("res : " + res);
})
But the res just gives object Object
How do I download the file?
You failed to download the file because the URL used(https://content.dropboxapi.com/2/files/upload) is incorrect. According to Dropbox API document, the correct URL endpoint is:
https://content.dropboxapi.com/2/files/download
However, it is better to use npm module such as dropbox to implement the requirement, as it has already wrapped the logic. The code would look like:
var fetch = require('isomorphic-fetch');
var Dropbox = require('dropbox').Dropbox;
var dbx = new Dropbox({ accessToken: 'YOUR_ACCESS_TOKEN_HERE', fetch: fetch });
dbx.filesDownload({path: '...'})
.then(function(data) {
...
});

Pass custom headers using request module

I am using npm request module (https://www.npmjs.com/package/request) to post binary content to a servlet. The binary content is received as part of http request, using the npm request module it is then posted to the J2ee server.
Along with the post, I need to pass some custom headers. I am using the below code to do that
var req = require('request');
function upload(request, response) {
var options = {
headers: {
'customheader1': 'val1',
'customheader2': 'val2'
}
};
var target = req.post('http://'+host+':'+port+'/myapp/Upload', options);
request.pipe(target);
target.on('finish', function() {
console.log('Uploaded with headers');
})
}
However, the headers are going as blank to the server. What would be the right way to pass headers using request.post?
As per request Docs (http://github.com/request/request)
var req = require('request');
function upload(request, response) {
var options = {
url: 'http://'+host+':'+port+'/myapp/Upload',
headers: {
'customheader1': 'val1',
'customheader2': 'val2'
}
};
var target = req.post( options, function(err,data){
console.log('uploaded with headers')
})
request.pipe(target);
}

Node file upload ends with 502 Gateway Error

I am trying to upload a file using request module to Telegram's Bot API. However, I end up with a 502 Gateway Error. Here's my code:
var request = require("request");
var fs = require("fs");
fs.readFile("image.png",function(err,data){
var formdata = {};
formdata.chat_id = <chatid>;
formdata.photo = data;
if(err)
console.log(err);
request({
url : "https://api.telegram.org/bot<token>/sendPhoto",
method : "POST",
headers : {
"Content-Type" : "multipart/form-data"
},
formData : formdata
},function(err,res,body){
if(err)
console.log(err)
console.log(body);
})
});
Is this the proper way to upload a file or am I making a mistake somewhere?
I suggest, it's better for you to use form field of request object, which gives you possibility to send file using createReadStream function of fs module.For example:
var r = request.post({
url: url
},someHandler);
var form = r.form();
form.append('file',fs.createReadStream(filePath));
For proper use read:
https://nodejs.org/api/fs.html#fs_fs_createreadstream_path_options
https://github.com/request/request#forms

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) {});
}
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.

Resources