first question here, so apologies if it turns out to be something very obvious
I am trying to call the paypal adaptive payments api via node.js and am getting a 580001 invalid request error. I can make a successfull call via curl with the below message and headers, but not through node.
any help would be much appreciated.
var API_endpoint = "svcs.sandbox.paypal.com";
var API_user = '';
var API_pass = '';
var API_sig = '';
message='requestEnvelope.errorLanguage=en_US&actionType=PAY&senderEmail=test_1320882990_per#gmail.com&receiverList.receiver(0).email=test2_1320887729_biz#gmail.com& receiverList.receiver(0).amount=100.00¤cyCode=USD&cancelUrl=http://your_cancel_url& returnUrl=http://your_return_url'
//var params = qs.parse(message);
//params = qs.stringify(params);
var req_options = {
host: API_endpoint,
method: 'POST',
path: '/AdaptivePayments/Pay',
headers: {
'Host': API_endpoint,
'Content-Type': 'application/x-www-form-urlencoded',
//'Content-Type': 'text/namevalue',
'Content-Length': message.length,
'X-PAYPAL-REQUEST-DATA-FORMAT:':'NV',
'X-PAYPAL-RESPONSE-DATA-FORMAT':'NV',
'X-PAYPAL-SECURITY-USERID':API_user,
'X-PAYPAL-SECURITY-PASSWORD':API_pass,
'X-PAYPAL-SECURITY-SIGNATURE':API_sig,
'X-PAYPAL-APPLICATION-ID':'APP-80W284485P519543T'
}
}
fs.readFile('/home/dev/.ssh/sandbox-paypal-private.pem', 'ascii', function(err, key){
fs.readFile('/home/dev/.ssh/sandbox-paypal-public.pem', 'ascii', function(err, cert){
req_options.key=key
req_options.cert=cert
var req = https.request(req_options, function(res){
console.log('STATUS: ' + res.statusCode);
console.log('HEADERS: ' + JSON.stringify(res.headers));
res.on('data', function(d){
var response = d.toString();
console.log(response)
});
});
req.write(message);
req.end();
req.on('error', function request_error(e) {
console.log(e);
});
});
});
I'm not sure if it's only a copy paste problem, but your message variable does not seem to contain properly formatted string. It has white spaces and the special characters are not encoded.
requestEnvelope.errorLanguage=en_US&actionType=PAY&senderEmail=test_1320882990_per#gmail.com&receiverList.receiver(0).email=test2_1320887729_biz#gmail.com&receiverList.receiver(0).amount=100.00¤cyCode=USD&cancelUrl=http://your_cancel_url& returnUrl=http://your_return_url'.
It should look like this:
requestEnvelope.errorLanguage=en_US&actionType=PAY&senderEmail=test_1320882990_per%40gmail.com&receiverList.receiver(0).email=test2_1320887729_biz%40gmail.com& receiverList.receiver(0).amount=100.00¤cyCode=USD&cancelUrl=http%3A%2F%2Fyour_cancel_url&returnUrl=http%3A%2F%2Fyour_return_url
There's a trailing colon in one of your header fields; Rather than:
'X-PAYPAL-REQUEST-DATA-FORMAT:'
You should have:
'X-PAYPAL-REQUEST-DATA-FORMAT'
Related
I am trying to send a simple HTTP POST request, retrieve the response body.Following is my code. I am getting
Error: Incorrect header check
inside the "zlib.gunzip" method. I am new to node.js and I appreciate any help.
;
fireRequest: function() {
var rBody = '';
var resBody = '';
var contentLength;
var options = {
'encoding' : 'utf-8'
};
rBody = fSystem.readFileSync('resources/im.json', options);
console.log('Loaded data from im.json ' + rBody);
contentLength = Buffer.byteLength(rBody, 'utf-8');
console.log('Byte length of the request body ' + contentLength);
var httpOptions = {
hostname : 'abc.com',
path : '/path',
method : 'POST',
headers : {
'Authorization' : 'Basic VHJhZasfasNWEWFScsdfsNCdXllcjE6dHJhZGVjYXJk',
'Content-Type' : 'application/json; charset=UTF=8',
// 'Accept' : '*/*',
'Accept-Encoding' : 'gzip,deflate,sdch',
'Content-Length' : contentLength
}
};
var postRequest = http.request(httpOptions, function(response) {
var chunks = '';
console.log('Response received');
console.log('STATUS: ' + response.statusCode);
console.log('HEADERS: ' + JSON.stringify(response.headers));
// response.setEncoding('utf8');
response.setEncoding(null);
response.on('data', function(res) {
chunks += res;
});
response.on('end', function() {
var encoding = response.headers['content-encoding'];
if (encoding == 'gzip') {
zlib.gunzip(chunks, function(err, decoded) {
if (err)
throw err;
console.log('Decoded data: ' + decoded);
});
}
});
});
postRequest.on('error', function(e) {
console.log('Error occured' + e);
});
postRequest.write(rBody);
postRequest.end();
}
response.on('data', ...) can accept a Buffer, not just plain strings. When concatenating you are converting to string incorrectly, and then later can't gunzip. You have 2 options:
1) Collect all the buffers in an array, and in the end event concatentate them using Buffer.concat(). Then call gunzip on the result.
2) Use .pipe() and pipe the response to a gunzip object, piping the output of that to either a file stream or a string/buffer string if you want the result in memory.
Both options (1) and (2) are discussed here: http://nickfishman.com/post/49533681471/nodejs-http-requests-with-gzip-deflate-compression
In our case we added 'accept-encoding': 'gzip,deflate' to the headers and code started working (solution credited to Arul Mani):
var httpOptions = {
hostname : 'abc.com',
path : '/path',
method : 'POST',
headers : {
...
'accept-encoding': 'gzip,deflate'
}
};
I had this error trying to loop with fs.readdirSync but there is a .Dstore file so the unzip function was applied to it.
Be careful to pass only .zip/gz
import gunzip from 'gunzip-file';
const unzipAll = async () => {
try {
const compFiles = fs.readdirSync('tmp')
await Promise.all(compFiles.map( async file => {
if(file.endsWith(".gz")){
gunzip(`tmp/${file}`, `tmp/${file.slice(0, -3)}`)
}
}));
}
catch(err) {
console.log(err)
}
}
In addition to #Nitzan Shaked's answer, this might be related to the Node.js version.
What I experienced is that https.request (OP uses http.request, but it may behave the same) already decompresses the data under the hood, so that once you accumulate the chunks into a buffer, all you're left with is to call buffer.toString() (assuming utf8 as an example). I myself experienced it in this other answer and it seems to be related to Node.js version.
I'll end up this answer with a live demo of a similar working code which may come handy for future readers (it queries StackExchange API, gets a gzip compressed chunks, and then decompress it):
It includes a code that works on 14.16.0 (current StackBlitz version) - which, as I described, already decompresses the data under the hood - but not on Node.js 15.13.0,
It includes a commented-out code that works for Node.js 15.13.0 the latter but not for 14.16.0.
In my application i need to post the dynamic data into my main page(mani page means if i run my url(localhost:3456) in browser means that will display one page na that page).How can i post that data.I have tried this but i couldn't post the data.Can anyone help me to fix the issue.
app.js
var http = require('http');
var server = http.createServer(function(req, res){
res.writeHead(200, ['Content-Type', 'text/plain']);
res.write('Hello ');
res.end('World');
});
server.listen(3456);
postdata.js
var data={"errorMsg":{"errno":34,"code":"ENOENT","path":"missingFile.txt"},"date":"2013-0402T11:50:22.167Z"}
var options = {
host: 'localhost',
port: 3456,
path: '/',
method: 'POST',
data:data,
header: {
'content-type': 'application/json',
'content-length': data.length
}
};
var http=require('http');
var req;
req = http.request(options, function(res) {
var body;
body = '';
res.on('data', function(chunk) {
body += chunk;
});
return res.on('end', function() {
console.log('body is '+body);
});
});
req.on('error', function(err) {
console.log(err);
});
req.write(data);
req.end();
Do you have express installed along with Node, if so you can set up Rest Api's which you can use them in your jQuery and bind data dynamically. Please try to look into
http://expressjs.com/
Hope this helps.
//this is a string
var jsonString = '{"errorMsg":{"errno":34,"code":"ENOENT","path":"missingFile.txt"},"date":"2013-04-03T05:29:15.521Z"}';
//this is an object
var jsonObj = {"errorMsg":{"errno":34,"code":"ENOENT","path":"missingFile.txt"},"date":"2013-04-03T05:29:15.521Z"};
note the single quotes in for string
request.write(chunk, [encoding]) requires chunk to be either Buffer or string (see: http://nodejs.org/api/http.html#http_request_write_chunk_encoding)
Two things. First:
var data={"errorMsg:{"errno":34,"code":"ENOENT","path":"missingFile.txt"},"date":"2013-0402T11:50:22.167Z"}
is missing a double-quote, so it's invalid syntax... hence why the syntax highlighting is having trouble.
Second:
req.write(data);
should be:
req.write(JSON.stringify(data));
EDIT:
Based on your comment, I think you might be asking how to read from the body of an HTTP POST request (you're question is very ambiguously worded). If so, that's already very well documented in the Node.js API. Something along the lines of:
var server = http.createServer(requestHandler);
server.listen(3456);
function requestHandler (req, res) {
req.setEncoding('utf8');
var body = '';
req.on('data', function (chunk) { body += chunk; });
req.on('end', function () {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('The body of your request was: ' + body);
});
}
If that's not what you're asking, you'll need to clarify your question. Terms like 'main page' have no meaning unless you explicitly define what they are and what the expected outcome is.
I am trying to Connect my application to foursquare and I want to display a message when a user checks in to certain places. I am trying to use their real time api https://developer.foursquare.com/overview/realtime
Everything works fine until the very end, ( when I have to send a reply post request https://developer.foursquare.com/docs/checkins/reply) I am using express and node.js. Here is what my post request looks like.
app.post('/handlepush', function(req, res) {
var checkin_id =req.param('checkin');
console.log(checkin_id);
var obj = JSON.parse(checkin_id);
var id = obj.id;
res.end('It worked!');
var token = "********************************";
var post_data = querystring.stringify({text : "awesome"});
var options = {
host: 'api.foursquare.com',
path: '/v2/checkins/' + id + '/reply?oauth_token=' + token,
port: 443,
method: 'POST'
};
var req2 = https.request(options, function(res2) {
res2.setEncoding('utf8');
res2.on('data', function (chunk) {
console.log('BODY: ' + chunk);
});
req2.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
});
req2.write(post_data);
req2.end();
});
this is the error I get, for some reason I am not able to add parameters for my post:
BODY: {"meta":{"code":400,"errorType":"other","errorDetail":"Must provide parameter text"},"response":{}}
You need to actually send your request. See: How to make an HTTP POST request in node.js?
var req2 = http.request(options, function(res2) {
res2.setEncoding('utf8');
res2.on('data', function (chunk) {
console.log('BODY: ' + chunk);
});
});
req2.end();
I'm trying to post images to Twitter using the Oauth module. Here is what I have:
It throws a 403 error, I know im doing something wrong with how I add the media to the post but Im just not sure where to go from here.
var https = require('https');
var OAuth= require('oauth').OAuth;
var keys = require('./twitterkeys');
var twitterer = new OAuth(
"https://api.twitter.com/oauth/request_token",
"https://api.twitter.com/oauth/access_token",
keys.consumerKey,
keys.consumerSecret,
"1.0",
null,
"HMAC-SHA1"
);
var params = {
status : "Tiger!",
media : [("data:" + mimeType + ";base64,") + fs.readFileSync(path,'base64')]
};
//function(url, oauth_token, oauth_token_secret, post_body, post_content_type, callback)
twitterer.post("https://upload.twitter.com/1/statuses/update_with_media.json",
keys.token, keys.secret, params, "multipart/form-data",
function (error, data, response2) {
if(error){
console.log('Error: Something is wrong.\n'+JSON.stringify(error)+'\n');
}else{
console.log('Twitter status updated.\n');
console.log(response2+'\n');
}
});
Here is what I belive im supose to be doing but I don't know how to do that in the Node.js Oauth module.
Posting image to twitter using Twitter+OAuth
Reviewing the code, it looks like there's no multipart/form-data handling at all in the node-oauth package right now. You can still use the node-oauth function to create the authorization header, but you'll have to do the multipart stuff on your own.
There are probably third-party libraries that can help out with that, but here's how I got it to work constructed by hand.
var data = fs.readFileSync(fileName);
var oauth = new OAuth(
'https://api.twitter.com/oauth/request_token',
'https://api.twitter.com/oauth/access_token',
twitterKey, twitterSecret,
'1.0', null, 'HMAC-SHA1');
var crlf = "\r\n";
var boundary = '---------------------------10102754414578508781458777923';
var separator = '--' + boundary;
var footer = crlf + separator + '--' + crlf;
var fileHeader = 'Content-Disposition: file; name="media"; filename="' + photoName + '"';
var contents = separator + crlf
+ 'Content-Disposition: form-data; name="status"' + crlf
+ crlf
+ tweet + crlf
+ separator + crlf
+ fileHeader + crlf
+ 'Content-Type: image/jpeg' + crlf
+ crlf;
var multipartBody = Buffer.concat([
new Buffer(contents),
data,
new Buffer(footer)]);
var hostname = 'upload.twitter.com';
var authorization = oauth.authHeader(
'https://upload.twitter.com/1/statuses/update_with_media.json',
accessToken, tokenSecret, 'POST');
var headers = {
'Authorization': authorization,
'Content-Type': 'multipart/form-data; boundary=' + boundary,
'Host': hostname,
'Content-Length': multipartBody.length,
'Connection': 'Keep-Alive'
};
var options = {
host: hostname,
port: 443,
path: '/1/statuses/update_with_media.json',
method: 'POST',
headers: headers
};
var request = https.request(options);
request.write(multipartBody);
request.end();
request.on('error', function (err) {
console.log('Error: Something is wrong.\n'+JSON.stringify(err)+'\n');
});
request.on('response', function (response) {
response.setEncoding('utf8');
response.on('data', function (chunk) {
console.log(chunk.toString());
});
response.on('end', function () {
console.log(response.statusCode +'\n');
});
});
I am currently fiddling around with Node.JS to try to create a package for PostageApp to be able to send emails through our API.
To start, I am using the following code to test out how Node.JS can best interface with our API, but it doesn't seem to want to pass along the API key that I have attached as part of the headers.
var http = require('http');
function onRequest(request, response) {
response.end();
}
http.createServer(onRequest).listen(8888);
console.log("Server has started.");
var options = {
host: 'api.postageapp.com',
path: '/v.1.0/get_account_info.json',
method: 'POST',
headers: { "api_key" : "MY API KEY HERE" }
};
var req = http.request(options, function(res) {
console.log('STATUS: ' + res.statusCode);
res.setEncoding('utf8');
res.on('data', function (chunk) {
console.log('BODY: ' + chunk);
});
});
req.end();
console.log("Request sent!");
I pulled this together using various examples and what not - it's not pretty, I know. However, using HTTPS, I finally got it to hit our API and get a response:
{"response":{"status":"unauthorized","message":"Invalid or inactive API key used","uid":null}}
The only conclusion I can come up with is that the API key is not getting passed along, and I would appreciate any help as to how to make that happen.
Thanks!
Here's an example of code I have used to call web APIs with a key in the header:
var api = http.createClient(80, 'api.example.org');
var request = api.request('GET', '/api/foo',
{
'host': 'api.example.org',
'accept': 'application/json',
'api-key': 'apikeygoeshere'
});
request.on('response', function (response) {});
request.end();