I am using Parse Cloud Code to make a 'DELETE' HTTP Request to Delete Multiple Messages from Iron.io.
It is using exactly the same headers and url as 'GET' request to Get Message from the Queue:
headers: {
'Content-Type': 'application/json;charset=utf-8',
'Authorization': 'OAuth ' + ironToken
},
The 'GET' request does work, whether I put method: 'GET' or not inside Parse.Cloud.httpRequest().
It does work even if I send some data as body: (which are ignored).
However, for a 'DELETE' request, I need to send body:
body: {
'ids': ['someMessageId']
}
And this requests fails with very unhelpful message:
{
"status":400,"headers":
{"Access-Control-Allow-Origin":"*",
"Connection":"keep-alive",
"Content-Length":"32",
"Content-Type":"application/json",
"Date":"Tue, 06 May 2014 10:15:27 GMT"
},
"text":"{\"msg\":\"Failed to decode JSON.\"}",
"data":{"msg":"Failed to decode JSON."},
"buffer":[ ...],
"cookies":{}
}
Any idea why this happens and what else can I test?
body: {
'ids': ['someMessageId']
}
Is not valid json object. You need double quotes everywhere:
"body": {
"ids": ["someMessageId"]
}
Related
I am doing a post request from react client via axios. The post request is to microsoft custom translator api. For some reason , I keep getting 400 error.
When I checked the error response under chrome's network tab, I see this error => {"code":400074,"message":"The body of the request is not valid JSON."}
This post request works perfectly fine with postman. What am I missing here ?
let config = {
headers: {
'Content-Type': 'application/json',
'Ocp-Apim-Subscription-Key': '<valid-key>',
},
params: {
'api-version': '3.0',
'to': 'de',
'category': '<valid-category-id>'
}
}
let data = {
"body" : [
{"Text": "Hello"}
]
}
axios.post('https://api.cognitive.microsofttranslator.com/translate/', data, config)
.then((res) => console.log(res))
.catch((err) => console.log(err));
It worked after I got rid of the "body" key.
let data = [
{"Text": "Hello"}
]
A post request does not usually have a trailing forward slash. Try removing the last forward slash so you url becomes:
'https://api.cognitive.microsofttranslator.com/translate'
Trying to 'share' on LinkedIn: https://developer.linkedin.com/docs/share-on-linkedin
Which is basically a POST to 'https://api.linkedin.com/v1/people/~/shares?format=json'
in its simplest form is with json:
{
"comment": "Check out developer.linkedin.com! http://linkd.in/1FC2PyG",
"visibility": {
"code": "anyone"
}
}
This requires setting http headers:
Content-Type: application/json
x-li-format: json
I'm trying to do this using OAuth.io, but LinkedIn seems to be still reading the body in XML.
See my example here: https://jsfiddle.net/Lv3jtpkb/2/
I get the following error from it:
Invalid xml {Element 'share#http://api.linkedin.com/v1' with element-only content type cannot have text content.}
I have checked if from OAuth.io server to LinkedIn API endpoint the headers specified here at frontend were somehow altered and can confirm that they have not been.
You're almost there. There are 2 errors.
Your data are formatted as a JS object. The method you're using doesn't seem to be converting the object to JSON automatically.
This line of code isn't doing anything, and is causing exceptions:
.then(user => { console.log("next:",user) })
Remove it.
Working code snippet:
$('#linkedin-button').on('click', function() {
// Initialize with your OAuth.io app public key
OAuth.initialize('A5oDtHv-oUEVlR7q7hDolXxC7RE');
alert('init');
OAuth.popup('linkedin2').then(linkedin => {
alert('logged in');
linkedin.post({
url: "/v1/people/~/shares?format=json",
data: JSON.stringify({
"comment": "Hello world!",
"visibility": {
"code": "anyone"
}
}),
headers: {
"x-li-format": "json",
"Content-Type": "application/json"
}
}).then(data => {
console.log("success:", data);
}).fail(err => { console.log("err:",err) });
})
})
Success in console:
aloha all,
Im create a integration with linkedin and google apps script, for post in company page.
All is good, in terms of oauth2, i have the tokens, but the problem is the body request, look:
var payload = {"visibility": {"code": "anyone"},"comment": "Testing a full company share!","content": {"submitted-url": "https://www.google.com","title": "Test Share with Content","description": "content description","submitted‐image-url": "https://www.wired.com/wp-content/uploads/2015/09/google-logo.jpg"}};
var headers = {Authorization': 'Bearer ' + Service.getAccessToken()};
var options = {method:'post',headers:headers,payload:payload,muteHttpExceptions:true};
var response = UrlFetchApp.fetch("https://api.linkedin.com/v1/companies/2414183/shares?format=json", options);
THE REQUES IS GOOD, BECAUSE I USE APIGEE FOR TEST MY JSON REQUEST. THIS IS THE RESPONSE OF THE SERVER:
[16-12-12 22:38:13:411 EST] {
"errorCode": 0,
"message": "Couldn't parse share document: error: Unexpected element: CDATA",
"requestId": "XNZ80U0LCX",
"status": 400,
"timestamp": 1481600293335
}
IN SEVERAL FORUMS SAY THAT THE HEARDER I SHOUD PUT:
'Content-Type': 'application/json', 'x-li-format': 'json'
BUT WHEN PUT THIS CODE ON HEADER THE ERROR OF SERVER IS:
[16-12-12 22:40:00:344 EST] {
"errorCode": 0,
"message": "Couldn't parse Json body: Unexpected character ('v' (code 118)): expected a valid value (number, String, array, object, 'true', 'false' or 'null')\n at [Source: java.io.StringReader#c3576e8; line: 1, column: 2]",
"requestId": "YQFPJKZTMC",
"status": 400,
"timestamp": 1481600400231
}
THANKS ALL
For payload you need to provide valid JSON e.g.:
var payload = JSON.stringify(object):
Not:
var payload = object;
I'd also add the content type to the headers, setting it to application/json:
var options = {
'contentType': 'application/json',
'payload': JSON.stringify(payload)
};
UrlFetchApp.fetch('https://www.example.com', options);
One change... Per the Linkedin developer docs:
If you opt to provide a JSON-formatted body, make sure your HTTP request includes the following headers:
Content-Type: application/json
x-li-format: json
https://developer.linkedin.com/docs/share-on-linkedin
I try to get a JSON object from a webservice with
MashupPlatform.http.makeRequest(url, {
method: 'GET',
requestHeaders: {"Accept": "application/json"},
forceProxy: true,
onSuccess: function (response) {
console.log("response: " + JSON.stringify(response));
success(response);
},
onFailure: function (response) {
error(response);
},
onComplete: function () {
complete();
}
});
but in the console every time an empty element ({}) gets logged. If I use curl to request that exact same URL I get the response I need. Is the wirecloud proxy unable to request application/json? In my browsers network analysis I see the request including the correct response, but the success function seems to not get that data.
WireCloud proxy supports application/json without any problem. Although the problem may be caused by other parameters, I think that your problem is related to a bad access to the response data. You should use response.responseText instead of using directly the response object (see this link for more info).
On Parse.com, from CloudCode I need to send httpRequest to AWS (Kinesis); they are signed and it all work when sent from the browser side (extension). I have tried the following header content-type in my request in CloudCode:
"content-type": "application/json"
AWS refused it: {"Output":{"__type":"com.amazon.coral.service#UnknownOperationException","message":null},"Version":"1.0"}
"content-type": "application/x-amz-json-1.1"
parse.cloud.httprequest refused it: Result: Uncaught Error: Don't know how to convert httpRequest body Object to application/x-amz-json-1.1. To send raw bytes, please assign httpRequest body to a Buffer object containing your data.
"content-type": "application/x-www-form-urlencoded"
AWS refused it: Request failed with response code 403
AWS documentation mentions the "application/x-amz-json-1.1" content-type everywhere and I cannot see any alternative. So, I'm assuming that's the way to go, so:
How can I ask Parse.Cloud.httpRequest to send the request with this X-AMZ-JSON header but use "application/json" ‘internally’?
update: I tried to use "http" and "xmlhttp" modules taken from Node; but none of them worked—I'm happy to try any suggestions you may have.
update: this is the actual request I'm making
Parse.Cloud.httpRequest({
method: 'POST',
url: awsKinesisUrl,
headers: {
"Authorization": concat_string,
"action": "PutRecord",
"acl": "public-read",
'awsaccesskeyid': "__XXX__",
"content-type": "application/x-amz-json-1.1",
"dategenerated": date_generated+"",
"region": "eu-west-1",
"version": "2013-12-02",
"X-Amz-Date": date_generated_TZ+"",
"X-Amz-Target": "Kinesis_20131202.PutRecords"
},
body: {
body: http_req_body
},
success: function(httpResponse) {
var message = httpResponse.text;
res.render('json', {message: '{response:\''+message+'\'}' });
},
error: function(httpResponse) {
var message = httpResponse.status;
res.render('json', {message: '{response:\''+message+'\'}' });
}
});
Check out the blog post on sending raw bytes through httpRequest: http://blog.parse.com/2013/04/04/sending-bytes-from-cloud-code/
If http_req_body is a JS object, then you can use the following method call:
// Require can go at the global scope
var Buffer = require('buffer').Buffer;
Parse.Cloud.httpRequest({
method: 'POST',
url: awsKinesisUrl,
headers: {
"Authorization": concat_string,
"action": "PutRecord",
"acl": "public-read",
'awsaccesskeyid': "__XXX__",
"content-type": "application/x-amz-json-1.1",
"dategenerated": date_generated+"",
"region": "eu-west-1",
"version": "2013-12-02",
"X-Amz-Date": date_generated_TZ+"",
"X-Amz-Target": "Kinesis_20131202.PutRecords"
},
body: new Buffer(JSON.stringify(http_req_body))
}).always(function(httpResponse) {
var message = httpResponse.text;
res.render('json', {message: '{response:\''+message+'\'}' });
});
I also took the liberty of replacing your success/error callback with the newer Promise technique (http://blog.parse.com/2013/01/29/whats-so-great-about-javascript-promises/). This not only lets you manage several API requests more easily but let you consolidate the handlers you were rewriting for both success and error conditions.