I am trying to upload a file to Box drive using its upload API, but I get Malformed Stream error response. I cannot figure out why?
var axios = require('axios');
var data = '\n--------------------------foo_bar_baz\ncontent-disposition: form-data; name="attributes"\n\n{"name":"ENC-mob.key.lock", "parent":{"id":"115921805292"}}\n--------------------------foo_bar_baz\ncontent-disposition: form-data; name="file"; filename="ENC-mob.key.lock"\ncontent-type: text/plain\n\n1\n\n--------------------------foo_bar_baz--';
var config = {
method: 'post',
url: 'https://upload.box.com/api/2.0/files/content',
headers: {
'Content-Type': 'multipart/form-data; boundary=------------------------foo_bar_baz',
'Authorization': 'Bearer ' + this.credentials.access_token,
},
data : data
};
console.log("Data: " + _params);
try {
let response: any = await axios(config)
console.log(JSON.stringify(response));
return response;
} catch(error) {
console.log(error + "\nError Message: " + error.message + "\nError response: " + JSON.stringify(error.response));
return error;
};
Related
Is there a way that we can upload files to shared drive using POST Method? I don't know how to call the Drive ID of the shared drive and target it to the URL fetch function, is this possible?
This is my code:
var DriveScope = 'https://www.googleapis.com/auth/drive';
var ServiceAccountPrivateKey ="-----BEGIN PRIVATE KEY----"
var ServiceAccountEmail = "drive-uploads#xxxxxxx.com";
function testinRest(){
var service = getDriveService();
var driveID = "XXXXXXXX";
var APIKey = "XXXXXXXXXXXXX";
var resumeBlob = Utilities.newBlob('Hire me!', 'text/plain', 'resume.txt');
var formData = {
'name': 'Bob Smith',
'email': 'bob#example.com',
'resume': resumeBlob
};
var url = 'https://www.googleapis.com/drive/v3/drives';
var output = UrlFetchApp.fetch(url, {
method: 'get',
headers: { 'Authorization': 'Bearer ' + service.getAccessToken() },
contentType: 'application/json'
}).getContentText();
var response= JSON.parse(output);
for(var i=0; i < response.drives.length; i++){
if(driveID == response.drives[i].id){
service.reset()
if (service.hasAccess()) {
var newPresentationName = "RJ POGI";
var url = 'https://www.googleapis.com/upload/drive/v3/files?supportsAllDrives=true&key=' + APIKey;
var body = {
"name": newPresentationName,
"parents": [driveID]
};
var params = {
headers: {
Authorization: 'Bearer ' + service.getAccessToken(),
Referer:'https://explorer.apis.google.com'
},
method: 'post',
payload: formData,//JSON.stringify(body),
contentType: 'application/json',
muteHttpExceptions: true
};
var response = UrlFetchApp.fetch(url, params).getContentText();
Logger.log('response: ' + response);
var id = JSON.parse(response).id;
return id;
}
}
}
}
function getDriveService(){
var service = OAuth2.createService('drive').setTokenUrl('https://accounts.google.com/o/oauth2/token').setPrivateKey(ServiceAccountPrivateKey).setClientId(ServiceAccountEmail).setPropertyStore(PropertiesService.getUserProperties()).setScope(DriveScope);
//console.log("Service::" + service);
//console.log('Service Has Access::' + service.hasAccess());
if (!service.hasAccess()) {
Logger.log('Authentication error: %s', service.getLastError());
return;
}else{
return service;
}
}
function reset() {
var service = getDriveService();
service.reset();
}
On this example, I want the resumeBlob to be inserted on the targeted DriveID. Any help will be appreciated. Thanks!
Your problem needs to be divided in three steps:
Create a file on the drive with UrlFetchApp
Pass a content to the file
Insert the file into a shared drive
Now, you original question - 3. is easy to solve, you just need to specify in your requestsupportsTeamDrives=true.
More difficult is the combination of 1. and 2..
The Files: create method offers either an URI for media upload only requests, or for metadata-only.
The workaround would be to perform a resumable Upload, which allows you to post the metadata first, and add the file contents later.
The URI you need to use would be "https://www.googleapis.com/upload/drive/v3/files?supportsTeamDrives=true&uploadType=resumable".
Sample:
function uploadToSharedDrive(){
var url = "https://www.googleapis.com/upload/drive/v3/files?supportsTeamDrives=true&uploadType=resumable";
var resumeBlob = Utilities.newBlob('Hire me!');
var formData = {
'name': 'Bob Smith',
'mimeType': 'text/plain',
'parents': [
"ID of the shared drive"
]
};
params = {
headers: {
Authorization: 'Bearer ' + service.getAccessToken()
},
contentType: 'application/json',
method: 'post',
payload: JSON.stringify(formData),
}
var response = UrlFetchApp.fetch(url, params);
Logger.log(response.getContentText());
data = resumeBlob.getBytes();
var params2 = {
method: "put",
payload: data,
muteHttpExceptions: true,
};
var location = response.getHeaders().Location;
var response = UrlFetchApp.fetch(location, params2);
Logger.log(response.getContentText())
}
I have a simple app with two routes, which I use locally and on IBM Cloud/Cloud Foundry (512 M RAM)
/
returns "Hello World!" & 200 locally and on the IBM Cloud
/getData
returns some data locally & 200
on cloud it returns 400, no logs
Edit:
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
var cors = require("cors"); // Cors
app.use(cors());
var port = process.env.PORT || 3000;
app.get('/', (req, res) => res.send('Hello World!'))
// *************** GETDATA ***************************************
app.get('/getData', function (req, res) {
var request = require("request");
var httpHeaderOptions = {
accept: "application/json",
"content-type": "application/json",
apikey: req.headers.apikey
};
var restoptions = {
method: "GET",
url: req.headers.route,
headers: httpHeaderOptions
};
// console.log("headers: " + JSON.stringify(req.headers));
// console.log("GET DOCS: \n", JSON.stringify(restoptions));
request(restoptions, function (error, response, body) {
console.log(typeof (body));
body_json = JSON.parse(body);
if (error) {
console.error("Failed: %s", error.message);
body = {
"error": error.message
};
res.status(400).json(body);
} else {
console.log("Success: \n", body);
res.status(200).json(body_json);
}
});
});
// *************** POST DOC ***************************************
app.post('/postData', function (req, res) {
var request = require("request");
var httpHeaderOptions = {
accept: "application/json",
"content-type": "application/json",
apikey: req.headers.apikey
};
var restoptions = {
method: "POST",
url: req.headers.route,
headers: httpHeaderOptions,
body: req.body,
json: true
};
console.log("headers: " + JSON.stringify(req.headers));
console.log("POST DOC: \n", JSON.stringify(restoptions));
request(restoptions, function (error, response, body) {
if (typeof (body) == 'object' && Object.keys(body).length === 0) {
// unknown error, empty resposne
res.status(400).json(body);
} else {
console.log("body: " + JSON.stringify(body));
if (error) {
console.error("Failed: %s", error.message);
body = {
"error": error.message
};
res.status(400).json(body);
} else {
console.log("Success: \n", JSON.stringify(body));
res.status(200).json(body);
}
}
});
});
// *********************
app.post('/watsonAssistant', function (req, res) {
var request = require("request");
var reqURL = "https://hackathon-jps.eu-de.mybluemix.net/watsonAssistant";
console.log("URL: \n", reqURL);
console.log("POST Body: \n", JSON.stringify(req.body));
var httpHeaderOptions = {
accept: "application/json",
"content-type": "application/json",
};
var restoptions = {
method: "POST",
url: reqURL,
headers: httpHeaderOptions,
body: req.body,
json: true
};
console.log("send request \n");
request(restoptions, function (error, response, body) {
console.log("in request \n");
if (error) {
console.error("Failed: %s", error.message);
body = {
"error": error.message
};
res.status(400).json(body);
} else {
console.log("Success: \n", body[0]);
res.status(200).json(body[0]);
}
});
});
// Start the server
app.listen(port, function () {
console.log('simple forward server is running')
});
link to the code
This will be because whatever req.headers.route is set to, is not visible to the app when it is running in the cloud. Your first check should be on error. Your second check should be if body is not null, and an object instead you immediately JSON.parse body, which may be throwing a parsing exception.
Can any one tel that how to GET Blob XHR request and XMLHttpRequest in ionic 2 , i have to fetch image url from the api .
This is my Ajax Code, i want in ionic 2
xhr.open('GET', "https://getbytitle('LE_COE_Mapping')/items(2)/AttachmentFiles('3.jpg')/$value");
xhr.responseType = 'blob';
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
// xhr.setRequestHeader('Authorization', 'Token token="' + token + '"');
xhr.setRequestHeader('Authorization', token);
xhr.onload = function (e) {
var img = new Image();
var url = window.URL || window.webkitURL;
img.src = url.createObjectURL(this.response);
document.getElementById('Doctitle').appendChild(img);
// alert(url.createObjectURL(this.response));
};
xhr.send();
Please i am stuck in this from the last two days.
Please Help me.
Thanks
I also got stuck in same problem once then this what I did :
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if (this.readyState == 4 && this.status == 200){
//this.response is your final response
console.log(this.response, typeof this.response);
var img = // your img syntax
//your any custom code goes here
}else{
//show error message if you want to show
}
}
xhr.open('GET', 'http://Your image url');// image url be like http://ab.cd/img.png
xhr.responseType = 'blob';
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
//xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
//send authorisation if you sending token
xhr.send();
Hope this will help you.
what i solved this below:
this.array: this is the url which we pass to get the blob url of the particular url:
const headers1 = new HttpHeaders({
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': "Bearer " + this.accessToken,
'X-Requested-With': 'XMLHttpRequest'
})
const response = await this.http.get(this.array + "/$value", { headers: headers1, responseType: 'blob' }).toPromise();
let b: any = new Blob([response], { type: 'application/octet-stream' });
var url = window.URL.createObjectURL(b);
console.log("this is url BLOB " + url);
https://instance.service-now.com/sys_report_template.do?CSV&jvar_report_id=xxxxx
This URL will only download report for which id is mentioned without mentioning the report_id how can i get all the reports?
This is some rough nodejs code, but should get you started;
var https = require('https');
var username = '';
var password = '';
var url = 'dev32369.service-now.com';
var auth = 'Basic ' + new Buffer(username + ':' + password).toString('base64');
https.request({
host: url,
port: 443,
path: '/api/now/table/sys_report?sysparm_query=field_listISNOTEMPTY&sysparm_fields=sys_id,title,filter,field,table,field_list&sysparm_limit=2',
method: 'GET',
headers: {
'Authorization': auth,
'Accept': 'application/json',
'Content-Type': 'application/json'
}
}, function (reportResponse) {
console.log('STATUS: ' + reportResponse.statusCode);
// console.log('HEADERS: ' + JSON.stringify(res.headers));
var reportResponseBody = '';
reportResponse.setEncoding('utf8');
reportResponse.on('data', function (chunk) {
reportResponseBody += chunk;
// console.log('BODY: ' + chunk);
});
reportResponse.on('end', function () {
var reports = JSON.parse(reportResponseBody).result;
console.log(reports);
if (reports[0].field_list != '') {
for (var x = 0; x < reports.length; x++) {
var report = reports[x];
var path = '';
path += '/api/now/table/' + report.table;
path += '?sysparm_fields=' + report.field_list;
path += '&sysparm_query=' + encodeURIComponent(report.filter);
path += '&sysparm_display_value=true';
path += '&sysparm_exclude_reference_link=true';
// path += '&sysparm_limit=2';
console.log(path);
var optionsCSV = {
host: url,
port: 443,
path: path,
method: 'GET',
headers: {
'Authorization': auth,
'Accept': 'application/json',
'Content-Type': 'application/json'
}
};
console.log(optionsCSV);
https.request(optionsCSV, function (csvResponse) {
try {
var csvResponseBody = '';
csvResponse.on('data', function (chunk) {
console.log('downloading report[' + report.title + ']...');
csvResponseBody += chunk;
});
csvResponse.on('end', function () {
//console.log(csvResponseBody);
var csvResponseObj = JSON.parse(csvResponseBody).result;
console.log(csvResponseObj);
//this is a json obj but you can rewriet is csv here
});
csvResponse.on('error', function (err) {
console.log(err);
});
} catch (e) {
console.log(e);
}
}).end();
}
}
});
}).end();
My http call is returning 200 but no response is captured. My code inside subscribe is not being hit. The API is returning data when I test in postman. Here is my code.
getToken(authcode: string) {
var data = 'client_id=InspectWebApp_client&code=' + authcode + '&redirect_uri=http://localhost:3000&grant_type=authorization_code';
let headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded' });
let options = new RequestOptions({ headers: headers });
this.http.post('https://fedloginqa.test.com/as/token.oauth2', data, options)
.subscribe((res: Response) => {
var resultsToken = res.json();
localStorage.setItem("access_token",resultsToken.access_token)
//return this.inspections;
})
}
I was also facing the same problem. The problem was solved using the map function on Observables. Here is my implementation:
login(Username:string, Password:string) : Observable<Response>{
let headers = new Headers();
headers.append("Authorization", "Basic " + btoa(Username + ":" + Password));
headers.append("Content-Type", "application/x-www-form-urlencoded");
return this._http.post(this._baseUrl+"auth/login", " " , {headers: headers} )
.map((response: Response) => {
return response;
}).catch(this.handleError);
}
Here the handleError is a function to catch the excceptions generated. This is a function in login.service.ts that sends the username and password to the api to get data. You can see that I am returning response from the map function in this service. Now, this returned response can be caught in subscribe function in following way:
this._loginService.login(this.username, this.password)
.subscribe(
(response) => {
//Here you can map the response to a type.
this.apiResult = <IUser>response.json();
},
(err) => {
//Here you can catch the error
},
() => {this.router.navigate(['home'])}
);