Send a POST request with an image URL? --- Needle library - node.js

Trying to figure out the right way to send a RESTful request to an API using the Node.js Needle library. I think everything is right except the code concerning the image URL. No matter how I try to change what it looks like or where I put it, I keep getting an error that says it's an invalid image, but it's not, the URL is fine. So, my guess is my code is wrong and so whatever it thinks is the URL for the image, is probably not the URL (but maybe some other code or code in a location that should be where the body/image URL is).
const imageUrl = 'https://upload.wikimedia.org/wikipedia/commons/3/37/Dagestani_man_and_woman.jpg'
// Request parameters.
const params = {
returnFaceId: true,
returnFaceLandmarks: false,
returnFaceAttributes: 'age,gender,headPose,smile,facialHair,glasses,emotion,hair,makeup,occlusion,accessories,blur,exposure,noise'
}
var options = {
body: '{"url": ' + '"' + imageUrl + '"}',
headers: {
'Content-Type': 'application/json',
'Ocp-Apim-Subscription-Key': subscriptionKey
}
}
needle.post(endpoint, params, options, function (err, res, body) {
console.log(`Status: ${res.statusCode}`)
console.log('Body: ', body)
console.log('ERROR: ' + err)
//console.log(res)
})
I have also tried to write the body like a plain ol' object: body = { 'url': imageURL}, but still getting the same error.
Error:
Status: 400
Body: { error: { code: 'InvalidURL', message: 'Invalid image URL.' } }
Here is the API I am trying to call, which has been confirmed to work with other samples:
https://westus.dev.cognitive.microsoft.com/docs/services/563879b61984550e40cbbe8d/operations/563879b61984550f30395236

For this request you have a combination of parameters:
Some of them as query strings (your 'params')
Some of them as a body payload (your options.body)
Therefore, it seems that you cannot use needle.post directly because it can do query string params OR body param but not both at the same time.
So there are several options:
Set your query string params in the URL field
Change your lib
For the 1st option, here is an example:
const imageUrl = 'https://upload.wikimedia.org/wikipedia/commons/3/37/Dagestani_man_and_woman.jpg'
// Request parameters.
const params = {
returnFaceId: true,
returnFaceLandmarks: false,
returnFaceAttributes: 'age,gender,headPose,smile,facialHair,glasses,emotion,hair,makeup,occlusion,accessories,blur,exposure,noise'
}
// Adding params to query string
serialize = function(obj) {
var str = [];
for (var p in obj)
if (obj.hasOwnProperty(p)) {
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
}
return str.join("&");
}
endpoint = endpoint + "?" + serialize(params)
// Setting body and options
var body = '{ "url": ' + '"' + imageUrl + '"}'
var options = {
headers: {
'Content-Type': 'application/json',
'Ocp-Apim-Subscription-Key': subscriptionKey
}
}
needle.post(endpoint, body, options, function (err, res, body) {
console.log(`Status: ${res.statusCode}`)
console.log('Body: ', body)
console.log('ERROR: ' + err)
//console.log(res)
})

Related

Binance signature error : "code":-1022,"msg":"Signature for this request is not valid."

I have an issue with binance API signature for their REST API.
When trying to hit the route 'http://binance.com/api/v3/account', I get the following error:
{"code":-1022,"msg":"Signature for this request is not valid."}
I use nodejs and express.
I've seen there is a few questions on this subject but none seems to solve my problem so:
I define keys and urls there
const binanceConfig = {
API_URL: 'http://binance.com',
API_ENDPOINT: '/api/v3/account',
API_KEY: 'API_KEY_EXAMPLE',
API_SECRET: 'API_SECRET_EXAMPLE'
}
I create the signature
function generateSignature() {
const dataQueryString = "recvWindow=60000&timestamp=" + Date.now();
return crypto
.createHmac('sha256', binanceConfig['API_SECRET'])
.update(dataQueryString)
.digest('hex');
}
I define query parameters here
const queryParameters = {
timestamp: Date.now(),
signature: generateSignature(),
recvWindow: '60000',
}
Set the header
var header = {
'Accept': 'Application/json',
'X-MBX-APIKEY': binanceConfig['API_KEY']
};
Create the route to call the API
router.get('/userInfo', (req, res) => {
var stringTest = `timestamp=${queryParameters['timestamp']}`
requestUrl = binanceConfig['API_URL'] + binanceConfig['API_ENDPOINT'] + "?" + stringTest + "&" + "signature=" + queryParameters['signature'] + "&recvWindow=" + queryParameters['recvWindow'];
const options = {
url: requestUrl,
headers: header,
method: 'GET'
}
request(options, (error, response) => {
if (error) { console.log('ERROR'); }
console.log(`Response: ${response.statusCode}`);
console.log(response.body);
});
});
If anyone has any idea why I get this error I'd be gratefull ! Thanks !
You need to have the timestamp and signature (respectively) as the last parameters.
Source

I Try to request post but error Invalid URI " / " Rest API

const req = require('request')
let base = 'https://openapi-v2.kucoin.com';
let endpoint = '/api/v1/orders';
let url = base + endpoint;
req.post(url,params,config,(err,body,res)=>{
if (err) { return console.log(err); }
console.log(res)
})
i try to request post but error lnvalid URI " / "
I don't know how to fix this.
Error Photo
According to the request's document, The post method does not receive 4 arguments. Set your config and data into the first argument:
request.post({
url:'http://service.com/upload',
form: {key:'value'}
}, function(err,httpResponse,body){ /* ... */ })
Also the order of err,body,res is incorrect.
Use something like this one:
req.post({
url: url,
params: data,
X: config.X,
Y: config.Y
}, (err,httpResponse,body)=>{
if (err) { return console.log(err); }
console.log(res)
})

how to convert image raw data to image

I want to show user's document file which is return by spring boot api in nodejs
but the file is not showing.
Here is my code of spring boot api
httpServletResponse.setHeader("Content-Disposition", "inline; filename=" + storeDocName + "");
httpServletResponse.setContentType(fileType);
httpServletResponse.setContentLengthLong(Files.readAllBytes(file.toPath()).length);
httpServletResponse.getOutputStream().write(Files.readAllBytes(file.toPath()));
Here is my node js code
requestMethodGetForImageData: function(url, form, header) {
return new Promise((resolve, reject) => {
//SET ALL THESE PARATMETER TO MAKE REQUEST
request.get({ url: url, qs: form, headers: header }, function(error, response, body) {
var result = {
body: response.body,
header: response.headers['content-type']
};
resolve(result);
}
});
});
},
I am using request module of nodejs to send the request to spring api and in nodejs here, I am calling this request function
router.get("/loadStoreDocument", function(req, res) {
var url = httpProtocol + httpServer + servicePort + serviceUrl;
//SET HEADER
headers = {
'Authorization': "token"
};
//SET FORM DATA
form = {
account_id: "id",
token_type: "token_type",
document_child_id: "id"
};
requestHandling.requestMethodGetForImageData(url, form, headers)
.then((result) => {
res.header("content-type", result.header);
res.send(result.body);
}).catch((err) => {
console.log("ERROR IN GET STORE PROFILE");
console.log(err);
res.send(err);
});
});
But when I call this URL(loadStoreDocument) then it returns image like this
enter image description here
Response of spring api is here(image data)
enter image description here
Please help me, I search this everywhere but couldn't find any solution.
You need to set encoding: null in request.get() options.
request.get({ url: url, qs: form, headers: header, encoding: null })
From request docs:
encoding - encoding to be used on setEncoding of response data. If
null, the body is returned as a Buffer. Anything else (including the
default value of undefined) will be passed as the encoding parameter
to toString() (meaning this is effectively utf8 by default). (Note: if
you expect binary data, you should set encoding: null.)

nodejs set encoding of body using request module

I have to send a post request with a body containing russian characters to a service which seems to only accept win1251 encoding. I am doing this in node.js using the request module.
This is how I am sending the request
var rawbody = "i1=&i2=&i3=" + query + "&i4=&i5=&i8=";
var options = {
url: this.initiate_endpoint,
jar: this.session,
cert: this.fs.readFileSync('resources/r.crt.pem', 'utf-8'),
key: this.fs.readFileSync('resources/r.key.pem', 'utf-8'),
timeout: 20000,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: rawbody
};
let cookie = this.session;
request.post(options,
function (error, response, body) {
if( error ) {
callback(cookie, error);
}
else if( response.statusCode !== 200 ) {
callback(cookie, 'Responded with status code: ' + response.statusCode);
}
else {
callback(cookie, false);
}
});
Whenever the query variable is containing russian letters the request will fail.
For example:
var query = 'Путин';
So my questions are how to actually convert the encoding from the query variable to win1251 and furthermore how to set the encoding of the actual raw postbody, because I think those two things could be the cause of the issue.

Podio API addItem call

I'm trying to implement https://developers.podio.com/doc/items/add-new-item-22362 Podio API addItem call in a nodejs module. Here is the code:
var _makeRequest = function(type, url, params, cb) {
var headers = {};
if(_isAuthenticated) {
headers.Authorization = 'OAuth2 ' + _access_token ;
}
console.log(url,params);
_request({method: type, url: url, json: true, form: params, headers: headers},function (error, response, body) {
if(!error && response.statusCode == 200) {
cb.call(this,body);
} else {
console.log('Error occured while launching a request to Podio: ' + error + '; body: ' + JSON.stringify (body));
}
});
}
exports.addItem = function(app_id, field_values, cb) {
_makeRequest('POST', _baseUrl + "/item/app/" + app_id + '/',{fields: {'title': 'fgdsfgdsf'}},function(response) {
cb.call(this,response);
});
It returns the following error:
{"error_propagate":false,"error_parameters":{},"error_detail":null,"error_description":"No matching operation could be found. No body was given.","error":"not_found"}
Only "title" attribute is required in the app - I checked that in Podio GUI. I also tried to remove trailing slash from the url where I post to, then a similar error occurs, but with the URL not found message in the error description.
I'm going to setup a proxy to catch a raw request, but maybe someone just sees the error in the code?
Any help is appreciated.
Nevermind on this, I found a solution. The thing is that addItem call was my first "real"-API method implementation with JSON parameters in the body. The former calls were authentication and getApp which is GET and doesn't have any parameters.
The problem is that Podio supports POST key-value pairs for authentication, but doesn't support this for all the calls, and I was trying to utilize single _makeRequest() method for all the calls, both auth and real-API ones.
Looks like I need to implement one for auth and one for all API calls.
Anyway, if someone needs a working proof of concept for addItem call on node, here it is (assuming you've got an auth token beforehand)
_request({method: 'POST', url: "https://api.podio.com/item/app/" + app_id + '/', headers: headers, body: JSON.stringify({fields: {'title': 'gdfgdsfgds'}})},function(error, response, body) {
console.log(body);
});
You should set content-type to application/json
send the body as stringfied json.
const getHeaders = async () => {
const headers = {
Accept: 'application/json',
'Content-Type': 'application/json; charset=utf-8',
};
const token = "YOUR APP TOKEN HERE";
headers.Authorization = `Bearer ${token}`;
return headers;
}
const createItem = async (data) => {
const uri = `https://api.podio.com/item/app/${APP_ID}/`;
const payload = {
fields: {
[data.FIELD_ID]: [data.FIELD_VALUE],
},
};
const response = await fetch(uri, {
method: 'POST',
headers: await getHeaders(),
body: JSON.stringify(payload),
});
const newItem = await response.json();
return newItem;
}

Resources