Node HTTP POST Request to Netatmo - javascript

I'm trying to do a http POST request to my Netatmo weatherstation's cloud using NodeJS. It really needs to be http post and not use the node's 'request' module, because I indend to use it in AWS Lambda and that module is currently not supported there.
Whatever I try, I get the dreaded {"error":"invalid_request"} with result 400.. I am at a loss as to what the problem is.
Here's my snippet:
var querystring = require('querystring');
var https = require('https');
function getNetatmoData(callback, cardTitle){
var sessionAttributes = {};
var shouldEndSession = false;
cardTitle = "Welcome";
var speechOutput ="";
var repromptText ="";
console.log("sending request to netatmo...")
var payload = querystring.stringify({
'grant_type' : 'password',
'client_id' : clientId,
'client_secret' : clientSecret,
'username' : userId,
'password' : pass,
'scope' : 'read_station'
});
var options = {
host: 'api.netatmo.net',
path: '/oauth2/token',
method: 'POST',
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': Buffer.byteLength(payload)
};
//console.log('making request with data: ',options);
var req = https.request(options, function(res) {
res.setEncoding('utf8');
console.log("statusCode: ", res.statusCode);
console.log("headers: ", res.headers);
res.on('data', function (chunk) {
console.log("body: " + chunk);
});
res.on('error', function (chunk) {
console.log('Error: '+chunk);
});
res.on('end', function() {
speechOutput = "Request successfuly processed."
console.log(speechOutput);
repromptText = ""
//callback(sessionAttributes, buildSpeechletResponse(cardTitle, speechOutput, repromptText, shouldEndSession));
});
});
req.on('error', function(e){console.log('error: '+e)});
req.write(payload);
req.end();
}
Here's Cloud9's console log:
Debugger listening on port 15454
sending request to netatmo...
statusCode: 400
headers: { server: 'nginx',
date: 'Tue, 24 Nov 2015 19:30:25 GMT',
'content-type': 'application/json',
'content-length': '27',
connection: 'close',
'cache-control': 'no-store',
'access-control-allow-origin': '*' }
body: {"error":"invalid_request"}
Request successfuly processed.

Aarrgh.. I oversaw something. Apparently, the headers need to be set in the options when making the request. It is in the headers variable that the Content-Type and Content-Length are set.
Without further adue, here is the correct working of the options variable :
var options = {
host: 'api.netatmo.net',
path: '/oauth2/token',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': Buffer.byteLength(payload)
}
};

Related

how to invoke a windows process using nodejs

I have a process running on my machine at port 8123, how can I invoke or call a windows process using nodejs..?
I tried using request
let bytes = new Buffer(xml, 'ascii')
var options = {
url: "https://" + host + ":" + port,
headers: {
'Content-Type': 'text/xml',
'Content-Length': Buffer.byteLength(bytes),
'Connection': 'keep-alive'
},
method: 'POST',
requestCert: true,
agent: false,
rejectUnauthorized: false
};
function callback(error, response, body) {
if (error) cb(error)
else cb(response)
}
request(options, callback);
but its returning with error code ECONNRESET and message assocket hang up
also tried HTTP like this
var options = {
host: '127.0.0.1',
port: port,
method: 'POST',
agent: false,
headers: {
'Content-Length': Buffer.byteLength(bytes),
'Content-Type': 'text/xml',
'Connection': 'keep-alive'
},
};
var req = http.request(options, function (res) {
res.on('data', function (chunk) {
cb('BODY: ' + chunk);
});
});
req.on('error', function (e) {
cb('problem with request: ' + e.message);
});
req.end();
this also returns the same error

How to fix unsupported_grant_type error in nodejs request to Reddit API

I am receiving an unsupported_grant_type error when making a request to Reddit to obtain an access token. I am attempting to make an app that makes API requests without user context.
I've tried moving the parameters and headers around but to no avail.
This is the code I am currently using (note that I have username = 'my client ID' and password = 'my secret key'
var request = require("request");
var auth = 'Basic ' + Buffer.from(username + ':' + password).toString('base64');
var options = { method: 'POST',
url: 'https://www.reddit.com/api/v1/access_token',
headers:
{ 'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': auth,
},
body:
JSON.stringify({grant_type: 'client_credentials',
user: username,
password: password})
};
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(response,body);
});
I did resolve this problem to this way.
I change the header 'Content-Type': 'application/x-www-form-urlencoded' for Accept: 'application/json'.
The body doesn't make it a JSON Object, I send it as a string.
options.body = 'grant_type=client_credentials'
const options = {};
options.method = 'POST';
options.headers = new Headers({
'Accept-Language': 'en_US',
Accept: 'application/json',
Authorization: auth,
});
options.body = 'grant_type=client_credentials';

How to send form data in node.js

I am able to get to the server but unable to post my form data.
How should I post the form data with the https request?
I am using form-data library for form-data, and https request for post call.
When I run the following code, I am able to reach the service, but the service gives a response saying that the form data is not submitted.
var https = require('https');
var FormData = require('form-data');
//var querystring = require('querystring');
var fs = require('fs');
var form = new FormData();
connect();
function connect() {
username = "wr";
password = "45!"
var auth = 'Basic ' + new Buffer(username + ':' + password).toString('base64');
var options = {
hostname: 'trans/sun.com',
port: 443,
path: '/transfer/upload-v1/file',
method: 'POST',
rejectUnauthorized: false,
headers: {
'Authorization': auth,
'Content-Type': 'application/json',
//'Content-Length': postData.length
}
};
form.append('deviceId', '2612');
form.append('compressionType', 'Z');
form.append('file', fs.createReadStream('/Mybugs.txt'));
var req = https.request(options, function(res) {
console.log("statusCode: ", res.statusCode);
//console.log("headers: ", res.headers);
res.setEncoding('utf8');
res.on('data', function(d) {
console.log(d)
});
});
req.write(form + '');
req.end();
req.on('error', function(e) {
console.error(e);
});
}
You never link your form to your request. Check this example provided with the form-data documentation
var http = require('http');
var request = http.request({
method: 'post',
host: 'example.org',
path: '/upload',
headers: form.getHeaders()
});
form.pipe(request);
request.on('response', function(res) {
console.log(res.statusCode);
});

Unable to POST data in node.js script

I am requesting a https post method with a data but my data is not going with the request and thats why service is giving error, so how can i change my code so that it will get to the server , here is my code
var https = require('https');
var querystring = require('querystring');
connect();
function connect(){
var postData = querystring.stringify({
'application': 'QF2',
'client': 'COMMAND',
'userId': 'devicexxx',
'operation': 'at-cmd',
'payload': 'dfdfdfdf',
'messageId': '123e454567-e89b-12d3-a456-42665544'
});
var options = {
hostname: 'cus.inco.com',
port: 443,
path: '/portal/action/dev',
method: 'POST',
rejectUnauthorized: false,
headers: {
'Content-Type': 'application/json',
'Content-Length': postData.length
}
};
var req = https.request(options, function(res) {
console.log("statusCode: ", res.statusCode);
//console.log("headers: ", res.headers);
res.setEncoding('utf8');
res.on('data', function(d) {
console.log(d)
});
});
req.end();
req.on('error', function(e) {
console.error(e);
});
}
You need to write() your POST data before you end the request.
req.write(postData);
req.end();

Coinbase.com API + Secret HMAC authentication in node.js

I have read some node.js docs (crypto, https) and try to use coinbase.com API in my coin.js file to get bitcoin balance of my account. But there are still some errors. When I run this code with correct key and secret values I get: [SyntaxError: Unexpected end of input]
error parsing json.
Thank you in advance for your responses.
var async = require('async');
var http = require('http');
var https = require('https');
var crypto = require('crypto');
var key = 'some_key_from_coinbasecom';
var secret = 'some_secret_from_coinbasecom';
var nonce = String(Date.now() * 1e6);
var url = 'https://coinbase.com/api/v1/account/balance';
var message = nonce + url + ''; // if body is not empty then put here body
var signature = crypto.createHmac('sha256', secret).update(message).digest('hex');
var options = {
method: 'GET',
path: '/api/v1/account/balance',
ACCESS_KEY: key,
ACCESS_SIGNATURE: signature,
ACCESS_NONCE: nonce,
hostname: 'coinbase.com'
};
https.get(options, function(res) {
var body = '';
res.on('data', function(chunk) {body += chunk;});
res.on('end', function() {
try {
var balance_json = JSON.parse(body);
if (balance_json.error) {
console.log(balance_json.error);
return;
} else {
// Here I have expected to get my balance json data
console.log(balance_json);
}
} catch (error) {
console.log(error);
console.log("error parsing json");
}
});
res.on('error', function(e) {
console.log(e);
console.log("error syncing balance");
});
});
I have tried another implementation:
https.get(options, function(res) {
console.log("statusCode: ", res.statusCode);
console.log("headers: ", res.headers);
res.on('data', function(d) {
process.stdout.write(d);
});
}).on('error', function(e) {
console.error(e);
});
There are results of this code (I have hidden some strings by XXXXXXXXXX):
statusCode: 401
headers: { server: 'cloudflare-nginx',
date: 'Wed, 14 May 2014 17:21:09 GMT',
'content-type': 'text/html; charset=utf-8',
'transfer-encoding': 'chunked',
connection: 'keep-alive',
'set-cookie':
[ '__cfduid=deacXXXXXXXXXXXXXXXXXXXXXXXXXXXX1400088069337; expires=Mon, 23-Dec-2019 23:50:00 GMT; path=/; domain=.coinbase.com; HttpOnly',
'request_method=GET; path=/; secure' ],
'cache-control': 'no-cache, no-store, max-age=0, must-revalidate',
expires: '-1',
pragma: 'no-cache',
status: '401 Unauthorized',
'strict-transport-security': 'max-age=31536000',
vary: 'Accept-Encoding',
'www-authenticate': 'Bearer realm="Doorkeeper", error="invalid_token", error_description="The access token is invalid"',
'x-content-type-options': 'nosniff',
'x-frame-options': 'SAMEORIGIN',
'x-rack-cache': 'miss',
'x-request-id': 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
'x-runtime': '0.031708',
'x-ua-compatible': 'IE=Edge,chrome=1',
'cf-ray': 'XXXXXXXXXXXXXXXXXXXXXXXXXX-LHR' }
From https://coinbase.com/docs/api/authentication:
The ACCESS_KEY header is simply your API key.
The ACCESS_SIGNATURE header ...
... ACCESS_NONCE header in your requests ...
In http://nodejs.org/api/https.html document you can find that headers are put into specific options.headers objects
Try to set options this way:
var options = {
method: 'GET',
path: '/api/v1/account/balance',
hostname: 'coinbase.com',
headers: {
ACCESS_KEY: key,
ACCESS_SIGNATURE: signature,
ACCESS_NONCE: nonce,
}
};

Categories