How do I call an API in Node.Js with an API Key and a HTTPS: Request? Here's What I'm trting to do but to no avail. Also where should I put the API Key? I haven't put it here.
var options = {
host: 'demo4444447.mockable.io',
port: 80,
method: 'GET',
path: '/alexa-skill.json'
}
var req = http.request(options, res => {
res.setEncoding('utf8');
var returnData = "";
res.on('data', chunk => {
returnData = returnData + chunk;
});
res.on('end', () => {
var result = JSON.parse(returnData);
//callback(result);
this.response.speak(`The current temperature is ${result.temperature} degrees with a humidity of ${result.humidity} and a cloud cover of ${result.cloudcover}.`);
this.emit(':responseReady');
});
});
req.end();
API keys are normally sent as headers. Example:
var options = {
host: 'demo4444447.mockable.io',
port: 80,
method: 'GET',
headers: {'headername': 'headervalue'},
path: '/alexa-skill.json'
}
You'll need to know the header name though, e.g. 'x-api-key'.
Related
I'm trying to make a Discord bot that retrieves a player's stats from the Ubisoft Rainbow Six stat website. I've worked with APIs before and I know the basics of Node and making GET requests to certain URLs. I monitored the network activity for a player's profile and found the specific URL that I need to perform a request on but I get a HTTP 400 error. I'm assuming this is because I've never authenticated with the server who I am. So I read up on authentication and the like and figured that all I had to do was include in the request header my username and password for the website(at this point I should mention that the site makes you login to retrieve player's stats). I went on Postman and included my username/password for Basic Auth and OAuth2 and I still get a HTTP 400 error, so there's obviously got to be more that I'm missing. It seems that in the network activity that some of the requests include a token, which I'm assuming is some sort of session token. I'm just completely confused as to what I'm supposed to do, as I'm kind of diving head first into this but I would really appreciate it if someone could provide some resources where I could try to fill in the gaps or help me resolve the issue. Code at the moment using pure JS/Node:
//import
const https = require('https');
const http = require('http');
//https://public-ubiservices.ubi.com/v3/profiles?namesOnPlatform=pope&platformType=uplay
var username = '';
var password = '';
var req_username = '';
//get session_id
function get_session_id(username, password) {
const options = {
host: 'public-ubiservices.ubi.com',
port: 443,
path: '/v3/profiles/sessions',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Basic' + Buffer.from(username + ':' + password).toString('base64'),
'Ubi-AppId': '',
}
}
const req_session_id = https.request(options, res => {
let res_body = '';
res.on('data', data => {
res_body += data;
})
res.on('end', () => {
res_body = JSON.parse(res_body);
console.log(res_body);
})
});
req_session_id.end();
}
//retrieve player stats
function get_stats(req_username) {
const options = {
host: 'public-ubiservices.ubi.com',
port: 443,
path: `/v3/profiles?namesOnPlatform=${req_username}&platformType=uplay`,
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Basic' + Buffer.from(username + ':' + password).toString('base64'),
'Ubi-AppId': '',
}
}
const req_get_stats = https.request(options, res => {
let res_body = '';
res.on('data', data => {
res_body += data;
});
res.on('end', () => {
res_body = JSON.parse(res_body);
console.log(res_body);
});
});
req_get_stats.end();
}
get_session_id(username, password);
get_stats(req_username);
try this out:
https://www.npmjs.com/package/r6api.js
heres an example:
const R6API = require('r6api.js');
const r6api = new R6API('email', 'password');
const username = 'Daniel.Nt'
const platform = 'uplay';
const id = await r6api.getId(platform, username).then(el => el[0].userId);
const stats = await r6api.getStats(platform, id).then(el => el[0]);
console.log(`${username} has played ${stats.pvp.general.matches} matches.`);
I am currently switching from aws lambda to azure functions and try to convert my lambda function (js) to azure function (js). One of the things I need to do in my function is to send a HTTPS Post Request to a URL to get some data. That worked perfectly fine in aws lambda. However, it seems like azure functions is either not supporting this or I am doing something wrong as it never sends the request and just ends the whole function.
This is my code:
var https = require('https');
var http = require('http');
module.exports = async function (context, req) {
var http_options = {
hostname: 'somehostname',
port: 443,
path: 'somepath',
method: 'POST',
headers: {
'Content-Type': 'text/xml;charset=UTF-8',
'SOAPAction': '"https://someURL"'
}
};
var body = '';
context.log('before request');
var req = await https.request(http_options, function (res) {
res.setEncoding('utf8');
body = '';
context.log('inside request');
res.on('data', (chunk) => {
body = body + chunk;
});
context.log('in req 2');
res.on('end', () => {
var options = {
compact: false,
ignoreComment: false,
spaces: 1
};
var result = JSON.parse(body);
})
})
};
The function always prints the "before request" part, and the just terminates.
I also tried a simple http call as described in this SO question. However, same result, the function just ends.
I don't think that https.request() is an async method (doesn't return a promise-like type). What if you try removing your await keyword there?
var https = require('https');
var http = require('http');
module.exports = async function (context, req) {
var http_options = {
hostname: 'somehostname',
port: 443,
path: 'somepath',
method: 'POST',
headers: {
'Content-Type': 'text/xml;charset=UTF-8',
'SOAPAction': '"https://someURL"'
}
};
var body = '';
context.log('before request');
https.request(http_options, function (res) {
res.setEncoding('utf8');
body = '';
context.log('inside request');
res.on('data', (chunk) => {
body = body + chunk;
});
context.log('in req 2');
res.on('end', () => {
var options = {
compact: false,
ignoreComment: false,
spaces: 1
};
var result = JSON.parse(body);
});
});
};
My code currently makes a request to an external API which then responds with a JSON object. I currently log that to my console so no problems on that end. I need to reference the object externally however so I can display it on my pug page to the client.
The following external javascript file 'server2.js' is in the same location as app.js.
function DemoApiNgClient() {
var FIRST_INDEX = 0;
var DEFAULT_ENCODING = 'utf-8';
var DEFAULT_JSON_FORMAT = '\t';
var options = {
hostname: 'api.betfair.com',
port: 443,
path: '/exchange/betting/json-rpc/v1',
method: 'POST',
headers: {
'X-Application': '',
'Accept': 'application/json',
'Content-type': 'application/json',
'X-Authentication': 'emTox++='
}
}
console.log("Get horse racing event id");
// Define Horse Racing in filter object
var jsonRequest = '{"jsonrpc":"2.0","method":"SportsAPING/v1.0/' + 'listEventTypes' + '", "params": {"filter":{}}, "id": 1}'
var str = '';
var req = https.request(options, function (res) {
res.setEncoding(DEFAULT_ENCODING);
res.on('data', function (chunk) {
str += chunk;
});
res.on('end', function (chunk) {
// On resposne parse Json and check for errors
response = JSON.parse(str);
console.log('Here is our response! ' + util.inspect(response, {showHidden: false, depth: null}))
});
});
// Send Json request object
req.write(jsonRequest, DEFAULT_ENCODING);
req.end();
req.on('error', function (e) {
console.log('Problem with request: ' + e.message);
});
}
I have tried the exports module for nested functions however the res.on block isn't necessarily a function so it won't work doing it that way.
End goal is displaying the response object from the external API in pug on client side, and not being able to reference the object is my only sticky point, everything else works.
Now I have a question like this:
I created a server with node.js ,and the server have receive a ajax request.With the data received from ajax ,node.js send a post request to another server. Now I have got the data from another server and the main question is how to send the data back to ajax, I have tried many ways but it does not work.
Can somebody help me on this issue?
here is my code
====ajax request
$.ajax({
type: "POST",
url: 'http://localhost:8888', // 这里要改成服务器的地址
data: userData,
success: function (data) {
console.log(data);
}
})
====
http.createServer(function (req, res) {
if (req.url == '/') {
var data = '';
var imdata;
util.log(util.inspect(req));
util.log('Request recieved: \nmethod: ' + req.method + '\nurl: ' + req.url);
req.on('data', function (chunk) {
imdata = querystring.parse(data += chunk);//转成对象的格式
})
req.on('end', function () {
var myIm = new ServerApi('e782429e48cb99f44b9c5effe414ac72', 'b88b9f2a2f74');
myIm.createUserId(imdata, function (err, data) {
//createUesrId is a api to deal with post request
console.log(data);//the data have received from another server,and now i do not know how to return the data to ajax success function
})
})
====the api to create user id with post requeset
ServerApi.prototype.postDataHttps = function (url, data, callback) {
this.checkSumBuilder();
var urlObj = urlParser.parse(url);
var httpHeader = {
'AppKey': this.AppKey,
'Nonce': this.Nonce,
'CurTime': this.CurTime,
'CheckSum': this.CheckSum,
'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8',
'Content-Length': Buffer.byteLength(data)
};
var options = {
hostname: urlObj.hostname,
port: 80,
path: urlObj.path,
method: 'POST',
headers: httpHeader
};
var that = this;
var req = http.request(options, function (res) {
res.setEncoding('utf8');
console.log("statusCode: ", res.statusCode);
console.log("headers: ", res.headers);
res.on('data', function (chunk) {
if (Object.prototype.toString.call(callback) === '[object Function]') {
var result = JSON.parse(chunk);
callback.call(that, null, result);
return result;
}
});
});
var postData = querystring.stringify(data);
req.write(postData);
req.end(data);
req.on('error', function (err) {
if (Object.prototype.toString.call(callback) === '[object Function]') {
callback.call(that, err, null);
}
});
}
ServerApi.prototype.createUserId = function (data, callback) {
var url = 'https://api.netease.im/nimserver/user/create.action';
var postData = {
'accid': data['accid'] || '',
'name': data['name'] || '',
'props': data['props'] || '',
'icon': data['icon'] || '',
'token': data['token'] || ''
};
this.postDataHttps(url, postData, callback);
}
On your server code. The one with http.createServer(function (req, res) {...}
Notice how you got a req and res parameter?
So on event end, that is req.on('end' function... Right after the line where you got a comment saying the 'data is received from another server', you can do something like;
res.writeHead(/*HTTP_RESPONSE_CODE_FOR_AJAX_CLIENT=*/200);
res.end('Done');
to send a response back to your client with HTTP response code = 200 and the message in the HTTP body would be 'Done'. Note that, there are quite a number of things you can do with the response object, you may want to see the documentation for more information.
See:
https://nodejs.org/api/http.html#http_response_writehead_statuscode_statusmessage_headers
OR
(中文版)
http://nodeapi.ucdok.com/api/http.html#http_class_http_serverresponse_7847
Quick explanation in Chinese:
在服务器的代码req.on('end'...那里, 你可以用resobject打回给你的AJax client.
I have nodeApp. It does stuff.
At a particular time I need to communicate with an API that out there in the wild. Using the API in rest tool like Postman is straight forward:
Postman
Url:
https://epicurl
Headers:
Content-Type : application/json
Accept : application/json
x-key : secret
Body:
{
"some":"kickass"
"data":"here"
}
Sending the above in Postman I get a nice quick response! Yay for rest tools.
So their API works, now I need to make that same response in my Node.js application.
This is where things get odd...
Request Module: FAILS
var request = require('request')
...lots_of_other_stuff...
var options = {
uri: 'https://epicURL',
method: 'POST',
json: true,
headers : {
"Content-Type":"application/json",
"Accept":"application/json",
"x-key":"secretbro"
},
body : JSON.stringify(bodyModel)
};
request(options, function(error, response, body) {
if (!error) {
console.log('Body is:');
console.log(body);
} else {
console.log('Error is:');
logger.info(error);
}
cb(body); //Callback sends request back...
});
The above fails.. It throws the good'ol ECONNRESET error that we all love! Why? Who knows?
https.request() - WORKS!
var https = require("https");
https.globalAgent.options.secureProtocol = 'SSLv3_method';
var headers = {
"Content-Type":"application/json",
"Accept":"application/json",
"x-key":"nicetrybro"
}
var options = {
host: 'www.l33turls.com',
port:443,
path: "/sweetpathsofjebus",
method: 'POST',
headers: headers
};
var req = https.request(options, function(res) {
res.setEncoding('utf-8');
var responseString = '';
res.on('data', function(data) {
responseString += data;
});
res.on('end', function() {
var resultObject = responseString;
//Call the callback function to get this response object back to the router.
cb(resultObject);
});
});
req.on('error', function(e) {
console.log(e);
});
req.write(bodyString);
req.end();
But then I notice...
If i leave this line of code in place when using the Request Module it then works...
var https = require("https");
https.globalAgent.options.secureProtocol = 'SSLv3_method';
Is this documented somewhere and I am missing it? Anyone explain this to me?