LinkedIn not reading JSON request - json

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:

Related

REST API Post Error: The body of the request is not valid JSON

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'

Slack API call to postMessage not working

I'm just trying to make a simple postMessage call from a google apps script with an image attached, but I get the following response:
"{"ok":false,"error":"invalid_arg_name"}"
Here is the function that creates the payload:
function getPostMessagePayload(fileUrl) {
var content = {
"channel":"#data-vis",
"token": ACCESS_TOKEN,
"text":"Chart update:",
"attachments": [
{
"title": "Chart",
"fallback": "Fallback",
"text": "Testing chart",
"image_url": fileUrl
}
]
};
return content;
}
And here is where I make the request:
var POST_MESSAGE_ENDPOINT = 'https://slack.com/api/chat.postMessage';
function performPostMessage(payload) {
var res = UrlFetchApp.fetch(
POST_MESSAGE_ENDPOINT,
{
method: "post",
payload: JSON.stringify(payload),
muteHttpExceptions: true,
}).getContentText();
return res;
}
It's impossible to tell what the actual problem is. I've tried making my token obviously incorrect, the URL obviously incorrect, and deleting/adding random args and it gives the same response every time.
When I use the webhook to do this rather than the API, it works fine.
My app has the following permissions in Slack:
chat:write:bot
incoming-webhook
Problem
You are sending a JSON object as payload with your POST request, whilst the contentType parameter of the fetch() method is defaulted to application/x-www-form-urlencoded.
Solution 1
In addition to JSON.stringify(), to ensure the payload is sent correctly, wrap it in an encodeURIComponent() built-in function. If the issue persists, continue to solution 2.
Update to solution 1
Nearly forgot how fetch() method treats objects passed to payload with default x-www-form-urlencoded content type. Remove the JSON.stringify() entirely (and add encodeURI() / encodeURIComponent() if needed).
Solution 2
Slack API supports application/json content type of POST requests. In your case it might be easier to send the request with contentType parameter set to application.json (note that you will have to move authorization from payload to headers):
//fetch part;
var res = UrlFetchApp.fetch(
POST_MESSAGE_ENDPOINT,
{
method : 'post',
contentType : 'application/json',
headers : {
Authorization : 'Bearer ' + ACCESS_TOKEN
},
payload : JSON.stringify(payload),
muteHttpExceptions : true,
})
//payload part;
var payload = {
"channel" : "#data-vis",
"text" : "Chart update:",
"attachments" : [
{
"title" : "Chart",
"fallback" : "Fallback",
"text" : "Testing chart",
"image_url" : fileUrl
}
]
};
Useful links
fetch() method reference;
postMessage method reference (Slack API);

How can I use Airtable as a backend?

I am trying to use Airtable as backend for a submit form in my project. However, I cannot seem to integrate the API and I don’t know the problem. I am using React and axios.
I am very new to both JS and Airtable.
Below is my error code:
Error in the browser after submiting the form:
Airtable error: {“error”:{“type”:“INVALID_REQUEST_MISSING_FIELDS”,“message”:“Could not find field “fields” in the request body”}}
Could somebody please what I am doing wrong? Thanks a lot in advance!
Below is my code:
var form = document.querySelector("#bize-ulasin");
if(form) {
form.addEventListener("submit", function(event) {
event.preventDefault();
axios.post(airtable_write_endpoint,
{
"Content-Type": "application/json"
} ,
{
"fields": {
"AdSoyad": document.getElementById("#Ad-Soyad"),
"Email": document.getElementById("#Email"),
"Telefon": document.getElementById("#Telefon"),
"Konu": document.getElementById("#Konu"),
"Mesaj": document.getElementById("#Mesaj"),
"Ortam": "Websitesi"
}
})
.then(function(response) {
console.log(response);
})
.catch(function(error) {
console.log(error);
})
})
};
This looks like an error with how you are structuring your axios call. It looks like you are actually passing {"Content-Type": "application/json"} as the payload in your POST call instead of the second parameter. You should be able to fix by re-ordering the parameters in your call:
axios.post(airtable_write_endpoint,
{
"fields": {
"AdSoyad": document.getElementById("#Ad-Soyad"),
"Email": document.getElementById("#Email"),
"Telefon": document.getElementById("#Telefon"),
"Konu": document.getElementById("#Konu"),
"Mesaj": document.getElementById("#Mesaj"),
"Ortam": "Websitesi"
},
}
{
headers: { "Content-Type": "application/json"}
})
.then(function(response) {
console.log(response);
})
.catch(function(error) {
console.log(error);
})
})
Hope that helps!
Airtable has a JavaScript package which gives you programmatic access to any base within any of your Airtable worksheets. Airtable also generates the full API documentation for your bases. You can find your API when you go to: https://airtable.com/api
Select a base and you'll see a fully-fledged API with examples calls and all.
It shows the full JavaScript example:
EXAMPLE USING ENVIRONMENT VARIABLE
# Shell:
$ export AIRTABLE_API_KEY=YOUR_API_KEY
# Node:
const base = require('airtable').base('YOUR_AIRTABLE_BASE');
EXAMPLE USING CUSTOM CONFIGURATION
var Airtable = require('airtable');
Airtable.configure({
endpointUrl: 'https://api.airtable.com',
apiKey: 'YOUR_API_KEY'
});
var base = Airtable.base('YOUR_AIRTABLE_BASE');
"AdSoyad": document.getElementById("idname") select related html element,no value
you can solve with "AdSoyad": document.getElementById("Ad-Soyad").value and without id tag(#),you already wrote getElementById that doesn't need #

How to return a JSON object from an Azure Function with Node.js

With Azure Functions, what do you need to do to return a JSON object in the body from a function written in node.js? I can easily return a string, but when I try to return a json object as shown below I appear to have nothing returned.
context.res = {
body: jsonData,
contentType: 'application/json'
};
Based on my recent testing (March 2017). You have to explicitly add content type to response headers to get json back otherwise data shows-up as XML in browser.
"Content-Type":"application/json"
res = {
status: 200, /* Defaults to 200 */
body: {message: "Hello " + (req.query.name || req.body.name)},
headers: {
'Content-Type': 'application/json'
}
};
Full Sample below:
module.exports = function (context, req) {
context.log('JavaScript HTTP trigger function processed a request.');
context.log(context);
if (req.query.name || (req.body && req.body.name)) {
res = {
// status: 200, /* Defaults to 200 */
body: {message: "Hello " + (req.query.name || req.body.name)},
headers: {
'Content-Type': 'application/json'
}
};
}
else {
res = {
status: 400,
body: "Please pass a name on the query string or in the request body"
};
}
context.done(null, res);
};
If your data is a JS object, then this should just work, e.g.
module.exports = function(context, req) {
context.res = {
body: { name: "Azure Functions" }
};
context.done();
};
This will return an application/json response.
If instead you have your data in a json string, you can have:
module.exports = function(context, req) {
context.res = {
body: '{ "name": "Azure Functions" }'
};
context.done();
};
Which will return an application/json response because it sniffs that it is valid json.
module.exports = function (context, req) {
context.log('JavaScript HTTP trigger function processed a request.');
if (req.query.name || (req.body && req.body.name)) {
context.res = {
// status: 200, /* Defaults to 200 */
body: {"data":"Hello"},
headers: {
'Content-Type': 'application/json'
}
};
}
else {
// res = {
// status: 400,
// body: "Please pass a name on the query string or in the request body"
// };
}
context.done(null,res);
I would like to add one more point. Apart from making the body: a JSON object, the request should also contain proper headers telling server what content type we are interested in. I could see that same Azure function when just invoked via browser using URL gives XML response, but when invoking from script or tools like Postman it gives JSON.
I feel like the answer has been given but it hasn't been clearly presented so I thought I'd answer as well in case it will help anyone coming behind me. I too have created a function that most definitely returns a Javascript object but if I copy and paste the URL in the Azure Function UI and just open a new tab in Chrome and try to view the output, I actually get back an XML document that tells me there's an error (not surprising there's an error as many characters in the Javascript would have blown up the XML). So, as others have mentioned, the key is sending the appropriate headers with your request. When you copy/paste the URL into your browser, the browser is sending a request header that looks similar to this:
text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8
When that happens, you see the XML return as described in this link:
https://github.com/strongloop/strong-remoting/issues/118
In order to get around this problem and see what the data would look like with a JSON request, either use a utility like Postman:
https://chrome.google.com/webstore/detail/postman/fhbjgbiflinjbdggehcddcbncdddomop?hl=en
Accept: application/json
Or use a CURL command and pass in the proper Accept header.
As you can see in the screenshot above, when I provided the proper header, I get back the JSON response I would expect.
You can also use JSON.stringify() to make a valid json string out of your js-object:
jsonData = { value: "test" }:
context.res = {
body: JSON.stringify(jsonData)
};

using Parse.Cloud.httpRequest I am unable to set correct header for AWS request?

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.