I'm trying to perform an API call to Squarespace using node-fetch.
const FormData = new FormData();
formData.append(
"file",
"testimage.jpg",
fs.createReadStream("testimg.jpg")
);
const send_img = await fetch(
"https://api.squarespace.com/1.0/commerce/products/" + img_id + "/images",
{
method: "POST",
headers: {
Authorization: "Bearer " + process.env.SQUARESPACE_API_KEY,
"User-Agent": "foobar",
"Content-Type": "multipart/form-data",
},
body: formData,
}
);
After performing this call I was getting the error
{
type: 'INVALID_REQUEST_ERROR',
subtype: null,
message: "Expected exactly one file part named 'file', but found none.",
details: null,
contextId: 'IEBROFREUTEWDREAYEAF'
}
The following cURL call successfully uploads the image
curl "https://api.squarespace.com/1.0/commerce/products/63ab0ff8796311649603ee49/images" \
-i \;
-H "Authorization: Bearer <myAPIKey>" \
-H "User-Agent: foobar" \
-H "Content-Type: multipart/form-data" \
-X POST \
-F file=#testimg.png
What if -F and what is the equivalent of it in a fetch call?
Squarespace API reference:
https://developers.squarespace.com/commerce-apis/upload-product-image
Related
I have tried every way I can think of to format this cURL request into something I can do server side on node and I keep getting back an invalid credentials response. I know the creds are valid so I must come to the conclusion that the code is making the wrong type of request.
cURL request:
curl --request GET \
--url https://api.timekit.io/v2/bookings\
--header 'Content-Type: application/json' \
--user : api_key_dfagafrgaegrfareVhROys9V1bUJ1z7
my format:
var options = {
url: 'https://api.timekit.io/v2/bookings',
headers:{
"Content-Type": "application/json",
'user': APP_KEY
},
method:'GET'
};
function callback(error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body);
}
}
request(options, callback);
I think you mean --user user:password in your curl command.
When you pass --user to curl, it sends it to the server as an basic authorization header (with the user:password encoded using base64). You can try this by running it against httpbin.org:
curl --request GET --url http://httpbin.org/headers --header 'Content-Type: application/json' --user foo:bar
{
"headers": {
"Accept": "*/*",
"Authorization": "Basic Zm9vOmJhcg==",
"Connection": "close",
"Content-Type": "application/json",
"Host": "httpbin.org",
"User-Agent": "curl/7.61.1"
}
}
As you can see, they received the header "Authorization": "Basic Zm9vOmJhcg==" where Zm9vOmJhcg== is the base64 encode of foo:bar
I am trying to transform this curl command
curl '<url>' -X POST \
--data-urlencode 'To=<phone>' \
--data-urlencode 'From=<phone>' \
--data-urlencode 'Body=<message>' \
-u '<user>:<pass>'
into this Node.js code
var request = require('request');
var options = {
url: 'url',
method: 'POST',
auth: {
'user': 'user',
'pass': 'pass'
}
};
function callback(error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body);
}
}
request(options, callback);
I don't get how I can add the --data-urlencode option in the Node.js version of this code.
From curl documentation :
--data-urlencode
(HTTP) This posts data, similar to the other -d, --data options with
the exception that this performs URL-encoding.
So you would use form option to send form URL encoded like this :
var options = {
url: 'url',
method: 'POST',
auth: {
'user': 'user',
'pass': 'pass'
},
form: {
To: 'phone',
From: 'phone',
Body: 'message'
},
headers: {
'Accept': '*/*'
}
};
Note that you can use request-debug to show the actual request where you could check that body is :
To=phone&From=phone&Body=message
And to show the actual data sent by curl use as stated here, use --trace-ascii /dev/stdout :
curl '<url>' -X POST --data-urlencode "Body=<message>" -u <user>:<pass> --trace-ascii /dev/stdout
I need to set the password for Neo4j and can do it from the command line like this:
curl -H "Content-Type: application/json" \
-H "Authorization: Basic `echo -n 'neo4j:neo4j' | base64`" \
-X POST -d '{"password":"nopass"}' \
http://localhost:7474/user/neo4j/password
but I'm now trying to do it in node.js like this:
var f = require('node-fetch');
var url = 'http://neo4j:n0p4ss#localhost:7474/user/neo4j/password';
var auth = new Buffer('neo4j:neo4j').toString('base64');
f(url, {
method: 'POST',
body: {'password': 'nopass'},
headers: {
'Content-Type': 'application/json',
'Authorization': 'Basic ' + auth
}
})
.then(res => res.text())
.then(txt => { console.log(txt); });
however, what I get back is:
{
"errors" : [ {
"code" : "Neo.ClientError.Request.InvalidFormat",
"message" : "Required parameter 'password' is missing."
} ]
}
which to me means the body: {...} isn't getting sent correctly. can anyone see what's wrong with my code?
ah. figured it out. it needs:
body: JSON.stringify({'password': 'nopass'}),
I am using nodejs to get bearer token i my code looks like
var fs = require("fs");
var https = require("https");
var querystring = require("querystring");
var bearer = "cunsomer_key:cunsomer_secret"
var base64ed = new Buffer(bearer).toString("base64");
var options = {
port: 443,
hostname: "api.twitter.com",
path: "/oauth2/token",
method: "post",
headers: {
Authorization: "Basic " + base64ed,
"Content-Type": "Content-Type: application/x-www-form-urlencoded;charset=UTF-8",
"User-Agent": "socialginie"
},
key: fs.readFileSync("./testssl.key"),
cert: fs.readFileSync("./testcert.cert"),
}
var req = https.request(options, res => {
res.on("data", d => {
console.log(d.toString());
})
})
req.on("error", e => {
console.log(e);
});
req.write(querystring.stringify({
"grant_type": 'client_credentials'
}))
req.end();
The expected return from the api is my bearer token and it does so in postman app but here i get the error {"errors":[{"code":170,"message":"Missing required parameter: grant_type","label":"forbidden_missing_parameter"}]}
Does anyone have any idea why api server cannot read the grant type
Your problem is just a typo. On this line:
"Content-Type": "Content-Type: application/x-www-form-urlencoded;charset=UTF-8",
you are specifying "Content-Type" as part of the header value.
When I use this curl command, sending your invalid Content-Type, I see the same error you do:
$ curl --data "grant_type=client_credentials" -H "Authorization: Basic <credentials-omitted>" -H "Content-Type:" -H "Content-Type: Content-Type: application/x-www-form-urlencoded;charset=UTF-8" https://api.twitter.com/oauth2/token
{"errors":[{"code":170,"message":"Missing required parameter: grant_type","label":"forbidden_missing_parameter"}]}
If I correct the header, I get a token:
$ curl --data "grant_type=client_credentials" -H "Authorization: Basic <credentials-omitted>" -H "Content-Type:" -H "Content-Type: application/x-www-form-urlencoded;charset=UTF-8" https://api.twitter.com/oauth2/token
{"token_type":"bearer","access_token":"<token-omitted>"}
I was using bash to do a task. And had some mess while trying to parse the response. Now I am using nodejs for the task. But I get following error:
"httpStatus" : 415,
"messages" : [ {
"errorCode" : "305",
"message" : "Unsupported media type 'application/x-www-form-urlencoded'"
} ]
This used to be my curl request in bash file:
curl --include\
--request POST \
--user "$USERNAME:$PASSWORD" \
--header "Content-Type: application/vnd.profitbricks.resource+json" \
--data-binary "{
\"properties\": {
\"name\": \"$servername\",
\"ram\": $RAM,
\"cores\": $CORES
}
}" \
https://api.profitbricks.com/rest/datacenters/$ID/servers ;
This is my current request:
var request = require('request');
var reqoptions = {
method: 'POST',
uri: 'https://api.profitbricks.com/rest/datacenters/'+options.vdcID+'/servers',
form:{
"properties":{
"cores": options.cores,
"ram": options.ramsize,
"name": options.servername
}
},
headers: {
'Authorization': 'Basic ' + new Buffer(options.user+':'+options.password).toString('base64'),
'Content-Type': 'application/vnd.profitbricks.resource+json'
}
};
request(reqoptions, function(err, res, body){});
form option changing content-type to form-urlencoded
you shouldn't use form in request options
send a binary data like here nodejs/express and binary data in POST
so use body: myBuffer instead of form: {...}
The problem was serialization. I stringified the object. Now it works.
var request = require('request');
var body = {
"properties":{
"cores": options.cores,
"ram": options.ramsize,
"name": options.servername
}
}
var reqoptions = {
method: 'POST',
uri: 'https://api.profitbricks.com/rest/datacenters/'+options.vdcID+'/servers',
body: JSON.stringify(body),
headers: {
'Authorization': 'Basic ' + new Buffer(options.user+':'+options.password).toString('base64'),
'Content-Type': 'application/vnd.profitbricks.resource+json'
}
};
request(reqoptions, function(err, res, body){});
This did the trick.