Access files on Dropbox with NodeJS - node.js

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

Related

How to add file attachment to soap request with node-soap library ?

I need to add an file attachment to a soap request from node.js application.
I am able to send request with node-soap library, and now I need to add a file to the request.
I did it with a java client or with soapUI, but I have to do it in node.js, maybe it's possible to do that overriding default request object ?
I didn't find a solution with node-soap, I had to build manually my soap request :
var soapHeader = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Header/><soapenv:Body><ws:method>';
var soapFooter = '</ws:method></soapenv:Body></soapenv:Envelope>';
function sendSoapRequestWithAttachments(soap,files){
var soapRequest = jsonToXml.buildObject(mail);
var finalSoapRequest = soapHeader + soapRequest + soapFooter;
var multipartMail = [];
// Add soap request
multipartMail.push({
'Content-Type': 'text/xml; charset=utf-8',
body: finalSoapRequest
});
// Add attachments
if (files) {
files.forEach(function (file) {
multipartMail.push({
'Content-Id': '<' + file.uuid + '>',
'Content-Type': 'application/octet-stream',
'Content-Transfer-Encoding': 'binary',
body: fs.createReadStream(file.path)
});
});
}
var options = {
uri: URL,
method: 'POST',
multipart: multipartMail
};
request.post(options, function (error, response) {
...
}
}
I found a way to send attachment using node-soap using base64 encoding
here is an example
import soap from 'soap'
import fs from 'fs'
async function main(){
const filepath = '/path/to/attachment/file.extension'
const client = await soap.createClientAsync(/* ... */)
const result = await client.AnApiMethodAsync({
expectedKeyForTheFile: await fs.readFileAsync(filepath, 'base64')
})
}
main()

How to OneDrive API file uploads with node.js?

After a time I finally figure out how to use oAuth2 and how to create a access token with the refresh token. But I can´t find node.js samples for upload files the only thing I found was this module https://www.npmjs.com/package/onedrive-api
But this didn´t work for me because I get this error { error: { code: 'unauthenticated', message: 'Authentication failed' } }
Also if I would enter accessToken: manually with 'xxxxxxx' the result would be the same.
But I created before the upload the access token so I don´t know if this really can be a invalid credits problem. But the funny thing is if I would take the access token from https://dev.onedrive.com/auth/msa_oauth.htm where you can generate a 1h access token the upload function works. I created my auth with the awnser from this question. OneDrive Code Flow Public clients can't send a client secret - Node.js
Also I only used the scope Files.readWrite.all do I maybe need to allow some other scopes ? My code is
const oneDriveAPI = require('onedrive-api');
const onedrive_json_configFile = fs.readFileSync('./config/onedrive.json', 'utf8');
const onedrive_json_config = JSON.parse(onedrive_json_configFile);
const onedrive_refresh_token = onedrive_json_config.refresh_token
const onedrive_client_secret = onedrive_json_config.client_secret
const onedrive_client_id = onedrive_json_config.client_id
// use the refresh token to create access token
request.post({
url:'https://login.microsoftonline.com/common/oauth2/v2.0/token',
form: {
redirect_uri: 'http://localhost/dashboard',
client_id: onedrive_client_id,
client_secret: onedrive_client_secret,
refresh_token: onedrive_refresh_token,
grant_type: 'refresh_token'
}
}, function(err,httpResponse,body){
if (err) {
console.log('err: ' + err)
}else{
console.log('body full: ' + body)
var temp = body.toString()
temp = temp.match(/["]access[_]token["][:]["](.*?)["]/gmi)
//console.log('temp1: ', temp)
temp = temp.join("")
temp = temp.replace('"access_token":"','')
temp = temp.replace('"','')
temp = temp.replace('\n','')
temp = temp.replace('\r','')
//console.log('temp4: ', temp)
oneDriveAPI.items.uploadSimple({
accessToken: temp,
filename: 'box.zip',
parentPath: 'test',
readableStream: fs.createReadStream('C:\\Exports\\box.zip')
})
.then((item,body) => {
console.log('item file upload OneDrive: ', item);
console.log('body file upload OneDrive: ', body);
// returns body of https://dev.onedrive.com/items/upload_put.htm#response
})
.catch((err) => {
console.log('Error while uploading File to OneDrive: ', err);
});
} // else from if (err) { from request.post
}); // request.post({ get access token with refresh token
Can you send me your sample codes please to upload a file to OneDrive API with node.js. Would be great. Thank you
Edit: I also tried to upload a file with this
var uri = 'https://api.onedrive.com/v1.0/drive/root:/' + 'C:/files/file.zip' + ':/content'
var options = {
method: 'PUT',
uri: uri,
headers: {
Authorization: "Bearer " + accesstoken
},
json: true
};
request(options, function (err, res, body){
if (err) {
console.log('#4224 err:', err)
}
console.log('#4224 body:', body)
});
Same code: 'unauthenticated' stuff :/
How about this sample script? The flow of this sample is as follows.
Retrieve access token using refresh token.
Upload a file using access token.
When you use this sample, please import filename, your client id, client secret and refresh token. The detail information is https://dev.onedrive.com/items/upload_put.htm.
Sample script :
var fs = require('fs');
var mime = require('mime');
var request = require('request');
var file = 'c:/Exports/box.zip'; // Filename you want to upload on your local PC
var onedrive_folder = 'samplefolder'; // Folder name on OneDrive
var onedrive_filename = 'box.zip'; // Filename on OneDrive
request.post({
url: 'https://login.microsoftonline.com/common/oauth2/v2.0/token',
form: {
redirect_uri: 'http://localhost/dashboard',
client_id: onedrive_client_id,
client_secret: onedrive_client_secret,
refresh_token: onedrive_refresh_token,
grant_type: 'refresh_token'
},
}, function(error, response, body) {
fs.readFile(file, function read(e, f) {
request.put({
url: 'https://graph.microsoft.com/v1.0/drive/root:/' + onedrive_folder + '/' + onedrive_filename + ':/content',
headers: {
'Authorization': "Bearer " + JSON.parse(body).access_token,
'Content-Type': mime.lookup(file),
},
body: f,
}, function(er, re, bo) {
console.log(bo);
});
});
});
If I misunderstand your question, I'm sorry.

Node.js post video from s3 to Facebook via Graph API

I have a video file on s3 that I want to post to a user Facebook account:
https.get(signedUrlOfObjectInS3, function(httpRes){
var form = new formData(); // that's form-data module https://github.com/felixge/node-form-data
form.append('source', httpRes);
var options = {
method: 'post',
host: 'graph-video.facebook.com',
path: '/me/videos?access_token=' + user_access_token,
headers: form.getHeaders(),
}
var buffer = '';
var apiCall = https.request(options, function (res){
res.on('data',function(chunk){
buffer += chunk;
});
res.on('end',function(){
var data = JSON.parse(buffer);
console.log('data from fb is: ' + util.inspect(data));
});
});
form.pipe(apiCall);
});
The response I get from Facebook is:
(#352) Sorry, the video file you selected is in a format that we don\'t support.
The video file on s3 is a mov file with a content type of video/quicktime.
OK, so apparently Facebook ignores the content type in the headers and guesses it from the file name. Since the s3 signed url doesn't end with filename.mov for example, it doesn't get it...
All I had to do was concating a '&f=filename.mov' to the end of the signedUrl, and now Facebook get that...
The following code actually worked fine for me for me:
https.get(signedUrlOfObjectInS3, function(httpRes) {
var form = new FormData(); // that's form-data module https://github.com/felixge/node-form-data
form.append('source', httpRes);
var options = {
method: 'post',
host: 'graph-video.facebook.com',
path: '/me/videos?access_token=' + user_access_token,
headers: form.getHeaders(),
}
var apiCall = https.request(options);
form.pipe(apiCall);
apiCall.on('response', function(res) {
console.log(res.statusCode);
});
});
try making the small difference in apiCall postback ,
other explanation might be that i've used a public amazon URL...

How to upload assets to a github release from node.js

I am trying to automatically post some assets on a Github release I programmatically create.
Here is my upload function:
function uploadFile(fileName, uploadUrl, callback){
var uploadEndPoint = url.parse(uploadUrl.substring(0,uploadUrl.indexOf('{')));
options.host = uploadEndPoint.hostname;
options.path = uploadEndPoint.pathname+'?name=' + fileName;
options.method = 'POST';
options.headers['content-type'] = 'application/zip';
var uploadRequest = https.request(options, callback);
uploadRequest.on('error', function(e) {
console.log('release.js - problem with uploadRequest request: ' + e.message);
});
var readStream = fs.ReadStream(path.resolve(__dirname,'builds',fileName));
readStream.pipe(uploadRequest);
readStream.on('close', function () {
req.end();
console.log('release.js - ' + fileName + ' sent to the server');
});
}
At the end of this I get a 404 not found
I tried auth from token and user/password
I checked the url
I though it might be because of SNI, but I don't know how to check that.
Any clue ? Thanks !
I found a solution to that problem by NOT using the low level node.js modules and using instead restler which is a library that handles SNI.
Here is how is used it:
rest = require('restler'),
path = require('path'),
fs = require('fs');
fs.stat(path.resolve(__dirname,'builds',fileName), function(err, stats){
rest.post(uploadEndPoint.href+'?name=' + fileName, {
multipart: true,
username: GITHUB_OAUTH_TOKEN,
password: '',
data: rest.file(path.resolve(__dirname,'builds',fileName), null, stats.size, null, 'application/zip')
}).on('complete', callback);
});
Hope that will help someone :)
EDIT on 27/02/2015: We recently switched from restler to request.
var
request = require('request'),
fs = require('fs');
var stats = fs.statSync(filePath);
var options = {
url: upload_url.replace('{?name}', ''),
port: 443,
auth: {
pass: 'x-oauth-basic',
user: GITHUB_OAUTH_TOKEN
},
json:true,
headers: {
'User-Agent': 'Release-Agent',
'Accept': 'application/vnd.github.v3+json',
'Content-Type': 'application/zip',
'Content-Length': stats.size
},
qs: {
name: assetName
}
};
// Better as a stream
fs.createReadStream(filePath).pipe(request.post(options, function(err, res){
// Do whatever you will like with the result
}));
The upload_uri can be retrieved through a get request on an existing release or in the response directly after the release creation.

Upload file to Box API from string using 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')));

Resources