Calling NetSuite restlet from Node - node.js

I'm trying to call a restlet from nodejs; it's a simple post with some authorization but all I get is some error :
{"error" : {"code" : "SYNTAX_ERROR", "message" : "SyntaxError: Empty JSON string (null$lib#3)."}}
Here's my code
request.post({
url: netSuiteUrl
headers: {
'Content-Type': 'application/json'
'Authorization': 'NLAuth nlauth_account=<account>, nlauth_email=<email>, nlauth_signature=<username>, nlauth_role=3'
}
content: '{"data":"test"}'
}, (error, response, body) ->
console.log(body)
)
The restlet actually receives the call and authorization is working. The same data I'm sending works fine with the following PHP code:
$opts = array(
'http' => array(
'method' => "POST",
'header' => "Authorization: NLAuth nlauth_account=<account>, nlauth_email=<email>, nlauth_signature=<signature>, nlauth_role=3\r\n" .
"Content-Type: application/json\r\n",
'content': '{"data":"test"}'
)
);
$context = stream_context_create($opts);
$file = file_get_contents($url, false, $context);
Any hint?

Which library do you use to send your request? Do you try with the module http of Node JS? It seems that your content isn't sent within the request.
See code below for example:
var postData = querystring.stringify({data:'test'});
var options = {
hostname: '<my host>',
port: 80,
path: '/<mypath>',
method: 'POST',
headers: {
'Content-Type': 'application/json'
'Authorization': 'NLAuth nlauth_account=<account>, nlauth_email=<email>, nlauth_signature=<username>, nlauth_role=3',
}
};
var req = http.request(options, function(res) {
// Handle successful request
console.log('STATUS: ' + res.statusCode);
console.log('HEADERS: ' + JSON.stringify(res.headers));
res.setEncoding('utf8');
res.on('data', function (chunk) {
console.log('BODY: ' + chunk);
});
});
// Handle errors
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
// Send data
req.write(postData);
req.end();
Hope it helps you,
Thierry

Related

NodeJS request get return me html code instead of json

I'm trying to get get a json from a get request it's work in python but in NodeJs that display me the html code source of the page
this is my code :
app.get("/well", function(request, response) {
const req = require('request');
const options = {
url: 'https://swarmmanager.francecentral.cloudapp.azure.com:3000',
method: 'GET',
headers: {
'Accept': 'application/json',
},
agentOptions: {
ca: fs.readFileSync("public/IdaktoPKIRootCA.crt")
}
};
req(options, function(err, res, body) {
console.log(body);
});
});
and this is another version but same problem:
app.get("/well", function(request, response) {
g_CnieOidcAddr = 'https://swarmmanager.francecentral.cloudapp.azure.com:3000';
const options = {
hostname: 'swarmmanager.francecentral.cloudapp.azure.com',
port: 3000,
method: 'GET',
headers: {
'Accept': 'application/json',
},
ca: fs.readFileSync("public/IdaktoPKIRootCA.crt")
};
const req = https.request(options, (res) => {
console.log('statusCode:', res.statusCode);
console.log('headers:', res.headers);
res.on('data', (d) => {
process.stdout.write(d);
});
});
req.on('error', (e) => {
console.error(e);
});
req.end();
});
i try to do it in python and it's work find that return me a json:
headers = {'Accept': 'application/json'}
r = requests.get(g_CnieOidcAddr + '/.well-known/openid-configuration', params={}, headers = headers, verify='./IdaktoPKIRootCA.crt')
print (r.text)
if anyone has an idea i'm a taker ^^ thanks for reading.
ok that work find i just forgot something at the end of the url so if you come to this page the 2 codes work find to to a request

nodejs request post large json fail

I am trying to post large json to a http server(a grafana server actually):
here is my code:
const http = require('http')
const request = require('request')
const fs = require('fs')
const opts = {
hostname: 'myip',
port: 3000,
path: '/api/dashboards/uid/KPEiIQVWk',
method: 'GET',
timeout: 5000,
headers : {
'Authorization' : 'Bearer ********************************************',
'Accept' : 'application/json',
'Content-Type' : 'application/json'
}
}
const req = http.request(opts, res => {
console.log(`Fetch: statusCode: ${res.statusCode}`)
var origin = ''
res.on('data', d => {
origin += d
})
res.on('end', function(){
dash = JSON.parse(origin)
dash.dashboard.panels.forEach(p => {
if(p.id == 26){
fs.readFile(__dirname + '/grafana/pm/branch-graph.html','utf-8', function(err, newPanel){
if(err){
console.log(err)
}
p.content = newPanel
const fresh = JSON.stringify(dash)
const updateOptions = {
uri: 'http://myip:3000/api/dashboards/db',
method: 'post',
headers : {
'Authorization' : 'Bearer *************************',
'Accept' : 'application/json',
'Content-Type' : 'application/json',
'Content-length' : fresh.length
},
json: fresh
}
fs.writeFile('tmp.json', fresh, function(err){
if(err){
console.error(err)
}
})
request(updateOptions, function(error, response, body){
console.log(`update: statusCode=${response.statusCode}`)
console.log(`update: ${body}`)
})
})
}
})
})
})
req.on('error', error => {
console.error(error)
})
req.on('timeout', () => {
req.abort()
})
req.end()
as you can see, I first fetch a grafana dashboard's source, then make some udpate, then post it back to grafana server. but always get 400 error. The strange thing is that if I dump the json to a file and use curl to post, it will work.
curl -vH "Authorization: Bearer $TOKEN" -H "Expect:" -d #tmp.json -H "Content-Type:application/json" http://myip:3000/api/dashboards/db
the whole json is about 40000+ bytes. any hint on this? I am not very famillar with nodejs. I am just trying to write some CI scripts.
First, I don't think it's necessary to use both the http and request modules. http is a module built into nodejs, and request is an npm package.
I recommend you use the npm request package because it's easier. You can read its documentation here: https://www.npmjs.com/package/request#http-authentication
Second, the options you're passing to the request module is not formatted correctly, I think this is why it is not working. With your current code, I would console.log('POST error', error); to print out the error. The correct options for the request module is proposed below.
const options = {
url: 'https://myip:3000/api/dashboards/db',
body: fresh, // the json from the fs.read callback
auth: {
'bearer': 'bearerToken'
},
json: true // from docs: If json is true, then body must be a JSON-serializable object.
}
request.post(
options,
(err, httpResponse, body) => {
console.log(err, body);
});

HTTP Module to Request Module Translation

How to rewrite this node.js code, just using the request module not http module?
var options = {
url: 'https://dnxr7vm27d.execute-api.us-east-1.amazonaws.com/prod/GetRewardInfo',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': 'kE2xi2OgUa7jfijmsd0jQ74aJntJwUEW2EU8LUsi'
}
};
var req = http.request(options, function(res) {
console.log('Status:' + res.statusCode);
console.log('Headers: ' + JSON.stringify(res.headers));
res.on('data', function(body) {
console.log('Body:' + body);
});
});
req.write('{"x-api-key":"12345", "Content-Type":"application/json", "appId":"DEMO1","momentId":"GAME_COMPLETE","deviceType":'
Android ','
campaignId ':"DEMOCAMP1","rewardGroupId":"amz1yprime"}');
req.end();
I've done part of it:
const request = require('request');
const data = JSON.stringify({
"appId": "DEMO1",
"momentId": "GAME_COMPLETE",
"deviceType": 'Android ',
'campaignId ': "DEMOCAMP1",
"rewardGroupId": "amz1yprime"
})
const options = {
url: 'https://dnxr7vm27d.execute-api.us-east-1.amazonaws.com/prod/GetReward',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': 'kE2xi2OgUa7jfijmsd0jQ74aJntJwUEW2EU8LUsi'
},
};
request.post(options, function(err, res, body) {
console.log(body);
});
But i don't know how to send "data" and how to get a response to the request
The re-write is not drastic. It's some few simple change.
const request = require('request')
var options = {
url: 'https://dnxr7vm27d.execute-api.us-east-1.amazonaws.com/prod/GetRewardInfo',
method: 'POST',
headers: {
'Content-Type': 'application/json; charset=UTF-8',
'x-api-key': 'kE2xi2OgUa7jfijmsd0jQ74aJntJwUEW2EU8LUsi'
},
body: {
'appId': 'DEMO1',
'momentId':'GAME_COMPLETE',
'deviceType' : 'Android',
'campaignId' : 'DEMOCAMP1',
'rewardGroupId': 'amz1yprime'
},
json: true // sets body to JSON representation of value
};
request.post(options, (err, httpResponse, body) => {
if (err) console.error(err);
// httpResponse contains the full response object, httpResponse.statusCode etc
else console.log(body);
})

make a post request with in node.js application

I've a node.js service with /api/authenticate endpoint. I can call this service successfully from POSTMAN with 'username' and 'password' as input (body parameters). How do I call the same services from another node.js server?
With postman I get,
body: {name: 'xxxxxx', password: 'xxxxxx' }
headers: { 'content-type': 'application/x-www-form-urlencoded',
host: 'xx.xx.xx.xx:xxxx',
connection: 'close',
'content-length': '0' }
POST /api/authenticate 200 1.336 ms - 72
Following is another nodejs application ... which makes a successful request call but doesn't have any body parameters (username and password) when it reaches to the authentication server api.
var my_http = require('http');
app.get('/makeacall', function(req, res) {
var output = '';
var options = {
body: { name: 'xxxxxx', password: 'xxxxxx' },
method: 'POST',
host: 'xx.xx.xx.xx',
port: 'xxxx',
path: '/api/authenticate',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
};
console.log('before request');
var req = my_http.request(options, function(response) {
console.log('response is: ' + response);
console.log('Response status code: ' + response.statusCode);
response.on('data', function(chunk) {
console.log('Data ..');
output += chunk;
});
response.on('end', function(chunk) {
console.log('Whole Data ..' + output);
});
});
req.on('error', function(err) {
console.log('Error: ' + err);
});
req.end();
console.log('444');
res.send({ message: 'View record message'});
});
From this nodejs application I get empty body on the server.
body: {}
headers: { 'content-type': 'application/x-www-form-urlencoded',
host: 'xx.xx.xx.xx:xxxx',
connection: 'close',
'content-length': '0' }
POST /api/authenticate 200 1.336 ms - 72
What am I missing? Any help is appreciated.
Using stock http library of NodeJS doesn't allow you to use that syntax.
Take a look at RequestJS as a much simpler solution. It will make your life a lot easier and allow you to use the syntax you want.
This is the solution to do it with stock Node.
https://nodejs.org/api/http.html#http_http_request_options_callback
Relevant Parts:
var postData = querystring.stringify({
'msg' : 'Hello World!'
});
And then, at the end:
// write data to request body
req.write(postData);
req.end();
But use a library unless you absolutely can't.
Are you trying to get the posted data from a form/etc?
Try using express.
npm install express -save
You can get posted data from a url with the ff:
app.post('*', function(request, response){
var post = {};
if(Object.keys(request.body).length){
for(var key in request.body){
post[key] = request.body[key];
console.log(key+'=>'+post[key];
}
}
});

Updating post http request length in node.js

I'm using node.js to post a http request. the code works with if i define my post data ahead of the 'options' field, but if I initially set my post_data string to empty and update it later it doesn't pick up the new length. How would I get it to do that ? I'm looking to send multiple posts of varying lengths to the same place in a loop so need to be able to do this.
var post_data=''; //if i set my string content here rather than later on it works
var options = {
host: '127.0.0.1',
port: 8529,
path: '/_api/cursor',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': post_data.length
}
};
var req = http.request(options, function(res) {
res.setEncoding('utf8');
res.on('data', function (chunk) {
console.log('BODY: ' + chunk);
});
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
post_data = 'a variable length string goes here';//the change in length to post_data is not //recognised
req.write(post_data);
req.end();
'Content-Length': post_data.length
You ran this before setting post_data.
If you want to set post_data after creating the object, you'll need to set it manually later:
options.headers['Content-Length'] = post_data.length;
Note that you must set that before calling http.request().
Posting data is a matter of sending a query string (just like the way you would send it with an URL after the ?) as the request body.
This also requires to declare Content-Type and Content-Length values so the server knows how to interpret the data.
var querystring = require('querystring');
var data = querystring.stringify({
username: yourUsernameValue,
password: yourPasswordValue
});
var options = {
host: 'my.url',
port: 80,
path: '/login',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': data.length
}
};
var req = http.request(options, function(res) {
res.setEncoding('utf8');
res.on('data', function (chunk) {
console.log("body: " + chunk);
});
});
req.write(data);
req.end();
You need to replace:
'Content-Length': post_data.length
for:
'Content-Length': Buffer.byteLength(post_data, 'utf-8')
See https://github.com/strongloop/express/issues/1870

Resources