GiantBomb API request getting HTML instead of JSON, Nodejs Request Module - javascript

Hey I'm trying to make a query to the giant bomb API, for some reason I am getting back a bunch of HTML/js instead of a JSON object. When I enter the query in the browser I get the JSON as expected.
var giantBombAPI = 'http://www.giantbomb.com/api';
var searchString = giantBombAPI + '/search?api_key=' + apiKey +
'&format=json' + '&query=' + searchTerms + "&resources=game";
//Make our request to the API
request.get({uri: searchString},function (err, res, body) {
jsonRes = JSON.parse(body);
});
Not sure what I'm missing. Also it worked yesterday :P.
I am plugging in "warcraft" for searchterms to test.
I am using the Nodejs request module.
Thanks.

Solved it, the API now requires a custom user agent:
request.get({uri: searchString, headers:{'user-agent' : '<CUSTOM>'}},
function (err, res, body) {
//....
}

Related

GET call, get query params from callback url

I am making a GET call with the following URL
https://auth.ebay.com/oauth2/authorize?client_id=CLIENT_ID&response_type=code&redirect_uri=REDIRECT_URI&scope=https://api.ebay.com/oauth/api_scope
This URL will redirect me to a "success.php" website from my server. With that redirection, it adds in params to the URL. For example: https://www.example.com/success.php?code=12345.
I need to get that code param from this redirection. How can I do that?
I tried to do a basic .get() call, but it doesnt seem to work..
https.get(url, (resp) => {
let data = '';
// A chunk of data has been received.
resp.on('data', (chunk) => {
data += chunk;
});
// The whole response has been received. Print out the result.
resp.on('end', () => {
console.log(JSON.parse(data).explanation);
});
}).on("error", (err) => {
console.log("Error: " + err.message);
});
I have tried other ways that I thought would work from research on here, like waiting for the redirect, etc. Nothing seems to work.
It is a query param ( seems to me you are working with an oAuth flow, reading about how these flows work would also help you work out an approach to this)
So I would capture it the following way
app.get('/callback', function (req, res) {
var code = req.query.code || null;
console.log(code);
}
where /callback is the URL you are redirected to and where you can capture the code to request the authorization token
Based on the code you already have it seems you might want the following.
var https = require('https');
var url = 'https://auth.ebay.com/oauth2/authorize?client_id=CLIENT_ID&response_type=code&redirect_uri=REDIRECT_URI&scope=https://api.ebay.com/oauth/api_scope';
https.get(url, (resp) => {
var location = new URL(resp.headers.location);
var code = location.searchParams.get('code');
console.log(code);
}).on("error", (err) => {
console.log("Error: " + err.message);
});
My answer assumes you are writing the code that is making the request while #Jordi Riera assumes you are writing code to process the request. Might you tell us which it is?

Why does Github webhooks give me circular JSON objects?

With the below code I am trying to get some basic pull request info from my Github repo, when someone submits a pull request for it. But I get this output instead:
$ node poc2.js
sha1=fef5611617bf56a36d165f73d41e527ee2c97d49
res [Circular]
req [Circular]
Since the secret hash is printed, the webhook is received. I can also verifiy this by nc -l 8080 instead of running my NodeJS app. There is will see a large json object, which is from where I got the json structure I use in the console.log's below.
Question
Can anyone figure out, why I get a "circular" json object from both req and res?
And how can I get the values I console.log?
const secret = "sdfsfsfsfwerwergdgv";
const http = require('http');
const crypto = require('crypto');
http.createServer(function (req, res) {
req.on('data', function(chunk) {
let sig = "sha1=" + crypto.createHmac('sha1', secret).update(chunk.toString()).digest('hex');
console.log(sig);
if (req.headers['x-hub-signature'] == sig) {
console.log("res %j", res);
console.log("req %j", req);
if (res.action == 'opened') {
console.log('PR for: ' + res.repository.html_url);
console.log('PR for: ' + res.repository.full_name);
console.log('PR: ' + res.pull_request.html_url);
console.log('PR title: ' + res.pull_request.title);
console.log('PR description' + res.pull_request.description);
console.log('PR by user: ' + res.pull_request.user.login);
};
}
});
res.end();
}).listen(8080);
The req is circular because it's not a JSON object, it's the Request object which includes a lot of internal machinery, some of which is circularly linked.
The actual incoming JSON document is in req.body or wherever your particular JSON body parser puts it, though in this example you don't have one yet so that's something you should fix.
Tip: You may want to use Express instead of the core Node http module, it's much more capable.

Cannot get objects' values from request body while trying to POST [Node.js, MySQL]

I am working on a management system, currently creating the POST requests for the api. I need the values of the request's body to post a new city in the database. The values are used in the stored procedure as parameters. Instead of the key's values which I entered, I am getting an "undefined" value, sometimes a "[object Object]".
I am using a MySQL server, hosted in the cloud by Google's services. Backend is made with Node.js, routing with Express. None of my attempts to fix the bug worked for me.
What I've tried so far:
-Parsing each key's value .toString() and JSON.stingfify() from the body
-Converting the body to Json/string, then back to a javascript object
-Getting the response's requests's body (res.req.body)
-Getting the body's response values in an array, then pushing the next element after it has been passed as a parameter to the stored procedure
-Using the 'request' npm extension to put the values I need when calling the POST method.
-Changed the values to be stored in the URL' parameters instead of the body.
-Sent the body's values as form-data, JSON file, HTML page
Controller method in cityController.js:
exports.city_post = (req, res, next)=>{
poolDb.getConnection(function (err, connection){
if(!err) {
const sql = 'CALL createNewCity(?,?)';
var zipReq = req.params.zip;
var nameReq = req.params.name;
var reqBody = JSON.stringify(req.res.body);
connection.query(sql,[zipReq,nameReq], (err,rows)=>{
if(!err){
return res.status(201).json({Message: 'City with name: '+nameReq+' and zip code: '+zipReq+' created successfully\n', rows});
}
else{
return res.status(404).json({errorMessage: err})
}
});
}
else{
return res.status(500).json({errorMessage: "server error: "+this.err});
}
console.log("\nZip Code: "+ zipReq +"\nName: " + nameReq); //for testing
console.log("\nrequest body: " + reqBody); //for testing
});
}
City route:
const express = require('express');
const router = express.Router();
const CityController = require('../controllers/cityController.js');
router.get('/', CityController.city_getAll);
router.get('/:cityzip', CityController.city_getbyzip);
router.post('/add', CityController.city_post);
...
module.exports = router;
Expected: Posting a new field in table city, status code (201).
Actual: Status code (404), no new insertion in the DB. body, req.body.zip & req.body.name are of value "undefined".
Screenshots:
-Terminal output: https://imgur.com/a/brqKZlP
-Postman request: https://imgur.com/a/ZfFcX8Z
Express doesn't parse post body by default (for some reason). You can try popular body-parser npm package, or collect the raw body data and parse from a string yourself if you don't want to add a whole new package. Here as express app:
app.use(function(req, res, next){
var data = "";
req.on('data', function(chunk){ data += chunk})
req.on('end', function(){
req.rawBody = data;
var json = JSON.parse(req.rawBody); // assuming valid json. ideally check content-type first
next();
});
});

Firebase Database updates slowly sometimes not at all

Good morning everyone, I have a question regarding the behavior of my firebase database.
I am populating an end point on my database user with multiple POST requests to my express server app.js from my client like so:
element.on("click", function(){
send request 1 - endpoint1
send request 2 - endpoint2
send request 3 - endpoint3
}
Then in my app.js I have handlers at the routes that use the Request package to make three seperate GET request to the Halo Waypoint API like so:
app.post(endpoint1, function(req,res){
request(HaloAPI + endpoint1, function(error, res, body){
[store data from the response body into an
object to be sent to firebase endpoint 'user']
// User's stats
database + "/user".set(dataObject)
}
}
app.post(endpoint2, function(req,res){
request(HaloAPI + endpoint2, function(error, res, body){
[store data from the response body into an
object to be sent to firebase endpoint 'user'.
This is a url for an image]
//This is a player's emblem
database + "/user/emblem".set(dataObject)
}
}
app.post(endpoint3, function(req,res){
request(HaloAPI + endpoint3, function(error, res, body){
[store data from the response body into an
object to be sent to firebase endpoint 'user'.
This is a url for an image]
//This is a player's Spartan portrait
database + "/user/spartanImage".set(dataObject)
}
}
I'm expecting the database to be updated all at the same time; however, that is not the case all the time. Usually when I click the button with the event listener attached endpoint 2 and 3 come in at the same time as the data from endpoint 1, but most of the time I only get data from only endpoint 2 or only endpoint 3. Eventually I stop getting the data from endpoint 2 and 3 all together. In fact, with this current setup I can see the endpoints user/emblem and user/spartanImage populate in the database console but then they are taken away as soon as they are added. This has been troubling me from the beginning of this project and I would really appreciate some insight from someone more experience in Firebase than myself. Below I will link my relevant code, thanks in advance for the help.
request.js is where the initial AJAX calls are made client-side:
$searchButton.on("click", function(event){
event.preventDefault();
// the value of the search field creates the request object
// it is just a user's Xbox Live Gamertag and is used for the
// the subsequent requests.
var $search = $("#searchField").val();
$.post(homeRoute + "statSearch", {search: $search}, function(data){
console.log(data)
});
firebase.database().ref().on("value", function(snapshot){
function ez(path){
return snapshot.child(path).val();
}
var dataObject = {
gamertag: ez("gamertag"),
totalKills: ez("totalKills"),
totalDeaths: ez("totalDeaths"),
totalGames: ez("totalGames")
};
console.log(dataObject)
});
$.post(homeRoute + "emblemSearch", {search: $search}, function(data){
console.log(data)
});
$.post(homeRoute + "spartanSearch", {search: $search}, function(data){
console.log(data)
});
From there we go over to app.js my express server to make GET requests to the Halo Waypoint API and send the response formatted with the data I want to firebase:
app.post("/statSearch", function(req, res){
var search = req.body.search;
var statsOptions = new Options("https://www.haloapi.com/stats/h5/servicerecords/warzone?players="+search);
request(statsOptions, function (error, response, body) {
if (error) throw new Error(error);
var body = JSON.parse(response.body)
var playerData = {
gamertag: body.Results[0].Id,
totalKills: body.Results[0].Result.WarzoneStat.TotalKills,
totalDeaths: body.Results[0].Result.WarzoneStat.TotalDeaths,
totalGames: body.Results[0].Result.WarzoneStat.TotalGamesCompleted
};
res.send(playerData)
var userRef = ref.child("user");
// sending off the data object to Firebase at the "user" endpoint
userRef.set(playerData);
});
});
//emblem
app.post("/emblemSearch", function(req, res){
var search = req.body.search;
var imgOptions = new Options('https://www.haloapi.com/profile/h5/profiles/'+search+'/emblem', '512');
request(imgOptions, function (error, response, body) {
if (error) throw new Error(error);
var imgString = response.request.uri.href;
res.send(imgString);
var emblemRef = ref.child("user/emblem");
// sending off the url to Firebase at the endpoint "user/emblem"
emblemRef.set(imgString);
});
});
//spartan image
app.post("/spartanSearch", function(req, res){
var search = req.body.search
var spartanOptions = new Options('https://www.haloapi.com/profile/h5/profiles/'+search+'/spartan', '256');
request(spartanOptions, function (error, response, body) {
if (error) throw new Error(error);
var imgString = response.request.uri.href;
res.send(imgString);
var spartanImage = ref.child("user/spartanImage");
// doing the same as emblem to this endpoint^^^^
spartanImage.set(imgString);
});
});

Node.JS Express to HTML data transfer

I am creating a login application with node.js, I seem to have ran into a knowledge deficit in the area of transferring strings from the server to html.
I posted my current code at jsfiddle.
My application verifies the credentials to the mysql table then generates a basic token that contains the username password and the ip address of the user.
In the last block of code, where the client html posts to the server, I have two segments where you see send to basic user page and send to admin page.
I have attempted to research this subject, but i get nothing pertinent to the situation. can anyone guide me in the right direction on sending the user to the admin or user page while sending the token alongside of it?
As well, how can the express server send data to the client, for example
on the page, I want the database to hold pertinant information regarding the user, like address and phone number. How can this information be transmitted from the server to the client via html?
app.post('/', urlencodedParser, function (req, res) {
var date = new Date();
con.query("SELECT * from users WHERE username=" + con.escape(req.body.username) + " AND password=" + con.escape(req.body.password), function (err, rows, fields) {
if (err) {
console.log(err);
} else {
var ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
if (rows == '' && rows == '') {
console.log('User Failed to login to the server with #'.red + con.escape(req.body.username) + ':' + con.escape(req.body.password));
res.sendFile(__dirname + '/admin/failure.html');
} else {
var isadmin = rows[0].admin;
var cryptomap = [req.body.username + ',' + req.body.password + ',' + ip];
var strcryptomap = cryptomap.toString(); // convert array to string
var token = encrypt(strcryptomap);
console.log(token + ' SENT'.red);
var backto = decrypt(token); //decr
var arr = backto.toString().split(","); // SPLITTING STRING TO SATISFY /VERIFY *************************************************
console.log(arr[0] + ' has valid token, encryption succsessful'.green);
con.query('UPDATE users SET crypto=' + con.escape(token) + 'WHERE username=' + con.escape(req.body.username), function (err, rows, fields) {
if (err) {
res.send(500);
} else {
console.log('Updated Crypto for ' + req.body.username);
if (isadmin == 0) {
// send to basic user page
res.send('USER');
} else {
//send to admin user page
res.sendto('http://google.com/?' + token);
}
}
});
}
}
});
});
To start, I'll answer the actual question you are asking.
The way I normally handle what you are trying to accomplish, is by using an ajax POST from the front end with the users credentials(https of course, never send credentials using http), have the server authenticate the user, create the token and respond to the ajax post with the token. From here, if the authentication was successful and the server responded with a token and whatever other information you wanted to get, you have a few options for storing it, I personally use cookies. After the token is stored, let the front end handle the redirect.
Having said all of that, I would definitely read up on authentication principles and the different ways your system can be attacked. I see a couple of red flags dealing with pretty basic authentication ideas/strategies.
Edit : Here is an example AJAX post to a login API endpoint that responds with a token and saves the username and token to cookies. Obviously your result data in the success function may be organized differently than mine but can be accessed in the same way. You can send whatever data you would like back in this result object and redirect accordingly
var loginData = {
username : $('#loginUsername').val(),
password : $('#loginPassword').val()
}
$.ajax({
type : "POST",
url : [your-endpoint-url],
data : loginData ,
success : function(result) {
setCookie('appUN', result.username);
setCookie('appTok', result.token);
location.href = '/dashboard';
},
error : function(result) {
location.href = '/login/Error';
}
});
function setCookie(cname, cvalue) {
var d = new Date();
d.setTime(d.getTime() + 10800000);
var expires = "expires="+d.toUTCString();
var path = "path=/";
document.cookie = cname + "=" + cvalue + "; " + expires + ";" + path;
}
To actually send the data back to the client from the server, in your API endpoint, you would do all of your logic to check the users credentials and if their credentials were valid, you could create a token and return something like
res.json({
username: username,
token: token
});
and this JSON object will be available in the success function as shown above.
If the users credentials were invalid, you could return something like
res.status(400).json({Message : "The username or password is incorrect"});
and because of the 400 status, it will be caught by the error function of your AJAX request

Categories

Resources