Get Steam Community Market price history with node.js - javascript

I'm having trouble getting the price history of an item from Steam. By looking at other questions I've managed to learn a nifty way to construct a link which indeed gives me the price history of an item, my problem is that you have to be logged in to Steam to aquire this data. How do I view this data as if I'm logged in through an http-request? I've read other threads where they talked about browser sessions and how someone in my situation should set cookies of ones session-id but I haven't managed to get it to work in node. The status code I'm getting is 400.
This is my code:
const https = require('https');
const options = {
host: 'steamcommunity.com',
path: '/market/pricehistory/?country=SE&currency=3&appid=730&market_hash_name=CS20%20Case',
method: 'GET',
headers: {
'Cookie': `steamLoginSecure=THE SESSION ID I GOT FROM WRITING
"document.cookie" IN THE DEV CONSOLE`
}
}
const req = https.request(options, res => {
console.log(res.statusCode);
console.log(res.headers);
let body = '';
res.on('data', data => {
body += data;
});
res.on('end', () => console.log(body));
}).on('error', error => console.log(error));
req.end();
I'm not sure if there's anything wrong in my code or how to go about to solve this issue I'm having. I really appreciate any help I can get.

It seems like Steam has removed the 'steamLogin' cookie, thus explaining why so many people this past year have been encountering issues when using it in their code. Instead, you want to use the 'steamLoginSecure' cookie.
First you need be logged in to https://steamcommunity.com. Second you want to find the 'steamLoginSecure' cookie and copy what it contains. For chrome that would be:
Settings > Advanced > Privacy and security > Site Settings > Cookies and site data > See all cookies and site data > steamcommunity.com > steamLoginSecure
Now copy the content of 'steamLoginSecure' and have it as a cookie in your headers.
This is the final code I ended up with:
const https = require('https');
const options = {
host: 'steamcommunity.com',
path: '/market/pricehistory/?country=SE&currency=3&appid=730&market_hash_name=CS20%20Case',
method: 'GET',
headers: {
'Cookie': 'steamLoginSecure=THE CONTENT OF "steamLoginSecure" HERE'
}
}
const req = https.request(options, res => {
console.log(res.statusCode);
console.log(res.headers);
let body = '';
res.on('data', data => {
body += data;
});
res.on('end', () => console.log(body));
}).on('error', error => console.log(error));
req.end();

Related

Batch Delete Request with Google REST api getting Bad Request error

I am trying to delete multiple files at once from my google drive using the REST API. I found this SO Question-bulk deletion Google Drive API, I have tried this solution without the npm package using fetch.
This is what I have at the moment.
const boundary = 'END_OF_PART';
const separation = `\n--'${boundary}'\n`;
const ending = `\n--'${boundary}'--`;
const requestBody = files.reduce((accum, current) => {
accum += separation +
'Content-Type: application/http\n\n' +
`DELETE https://www.googleapis.com/drive/v2/files/${current.id}
\nAuthorization: Bearer ${this.getToken()}`
return accum
}, '') + ending
const _multiPart = [];
files.forEach((file) => {
const obj = {
"Content-Type": "application/http",
body: `DELETE https://www.googleapis.com/drive/v2/files/${file.id}\n`,
};
_multiPart.push(obj);
});
const url = new URL('https://www.googleapis.com/batch/drive/v3');
const requestOptions = {
method: 'POST',
headers: {
"Content-Type": "multipart/mixed",
'Authorization' : `Bearer ${this.getToken()}`
},
body: requestBody,
multipart: _multiPart,
};
await fetch(url, requestOptions);
When I run the deletion I get the id's of the files but the end result is Error 400 bad request. Documentation is scarce for this process. What is it that I am doing wrong here and how can I fix it to get this to work?
End result that I am looking for is deleting a large amount of files from my google drive.
Can anyone point me in the right direction on this ?.
EDIT: I just tried a solution at this SO Question: Bulk delete files on Google Drive with raw XMLHttpRequest
And it did delete 100 files, but the response I got back was Code 500, Internal error.
Why am I getting this response and again why is my previous code not working at all ?
I believe your goal is as follows.
In your script, files is an array including the file IDs like ["fileId1", "fileId2",,,].
In your goal, you want to delete files with the batch requests using the array files by the fetch API of Javascript.
Your access token can be used for deleting files and you have permission for deleting those files.
In this case, how about the following sample script? In order to use the batch requests with Javascript, I have created a library. Ref In this answer, I would like to use this library.
Sample script:
<script src="https://cdn.jsdelivr.net/gh/tanaikech/BatchRequest_js#master/batchrequest_js.min.js"></script>
<script>
const accessToken = "###"; // Please set your access token.
const files = ["fileId1", "fileId2",,,]; // Please set your file IDs.
const object = {
accessToken,
batchPath: "batch/drive/v3",
requests: files.map(id => ({ method: "DELETE", endpoint: "https://www.googleapis.com/drive/v3/files/" + id })),
};
Do(object)
.then((e) => console.log(e))
.catch((err) => console.log(err));
</script>
References:
Batch requests of official document
BatchRequest_js (Author: me)

cross origin for amazon lambda function from localhost in gatsby site

I have the following code which works when I run it as a local serverless function with netlify dev, but I need it to run cross origin from a dev server to the hosted server function. I put the function in a aws lambda function but I am getting a cross origin blocked error on my https:dev.website.com, I thought I have the correct headers in the return object so not sure why I am getting a cross origin error.
Any help would be great
const sanityClient = require("#sanity/client");
const client = sanityClient({
projectId: "random-id",
dataset: "production",
useCdn: true,
});
exports.lambdaHandler = async (event, context) => {
var body = JSON.parse(event.body);
//console.log(body.price_id)
try {
const checkPriceId = async (test) => {
const query = `*[_type == "products" && price_id == "${body.price_id}"]`;
const documents = await client.fetch(query, {}); // this could throw
return documents.map((document) => document.sold);
};
var ok = checkPriceId().then((test) => {
return new Promise(function (resolve, reject) {
//console.log(test) // this will log the return value from line 7
console.log(test);
resolve(test);
});
});
var bools = await ok;
// prettier-ignore
return {
statusCode: 200,
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Allow-Methods':'GET, POST, OPTION',
},
body: JSON.stringify({
sold: bools,
}),
};
} catch (err) {
return { statusCode: 500, body: err.toString() };
}
};
This is my request to the function if that helps
var fetchUrl = https://random.executue-api.aws.com/prod/sold //not exact
var fetchData = async function () {
const response = await fetch(fetchUrl, {
method: "post",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
price_id: final,
}),
})
.then(res => {
return res.json()
})
.catch(error => console.log(error))
return response
}
Update:
I tried adding cors the way suggested in the answer below, but it failed seen below so I tried manually adding the method response seen after.
I still get a cross domain error. And I have changed the domain so it is now https as well. Really stuck here.
I was looking into this more, and it seems like before it does the actual post it does a cors check at the options method, so I added in the same access control headers, and deployed but did not work. Don't quite get this.
Your headers look ok to me. (note: If you mix HTTP and HTTPS you are most likely to get a mixed content error in the client). If it is ONLY a CORS issue that you are seeing in the console in the web browser, then you might not have configured the API Gateway correctly in AWS.
In AWS, go to API Gateway and you should see something like the below:
Make sure that you enable CORS and then redeploy.
UPDATE:
Just looking at a previous implementation of a lambda function I setup with AWS. The headers I declared were as follows:
headers: {
"Content-Type" : "application/json",
"Access-Control-Allow-Origin" : "*",
"Allow" : "GET, OPTIONS, POST",
"Access-Control-Allow-Methods" : "GET, OPTIONS, POST",
"Access-Control-Allow-Headers" : "*",
"Access-Control-Allow-Credentials" : true
}
Your headers look OK to me though. However, when you created the method in the API Gateway, did you select Use Proxy Lambda Integration? (see screenshot).
Your client side fetch request looks ok. For reference mine was:
const url = 'your url';
const options = {
method: 'POST',
headers: { "Content-Type": "application/json" },
body: JSON.stringify(data),
};
fetch(url, options).then(res => res.json());
Unrelated to this issue, but its not advisable to mix Async/Await with .then promise chaining. But this isn't the issue you are having. Just something to note.
Check the values from your Integration Response / try setting them manually for both OPTIONS and POST (and if that works, make sure you are passing through the response correctly from the lambda).
Your POST action should only require the Access-Control-Allow-Origin header. The other two (Access-Control-Allow-Methods, Access-Control-Allow-Headers) belong in the OPTION action. See this writeup, and note the full example exchange for a preflighted request (in grey): https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#preflighted_requests

How can I send a cookie via node-fetch

I recently started to work with the roblox api, It's been going good so far but I can't login. I tried to set the cookie by doing apiCall.headers.set-cookie = cookie, But that doesn't seem to work. How can I solve this issue?
Would I have to get set-cookie then edit it? i.g
const cookieSet = await apiCall.headers.get("set-cookie")
cookieSet = cookie
If I made it difficult to understand, I'll try to make it more clear
How would I post a cookie to a roblox API?
My code:
if (!cookie.startsWith("_|WARNING:")) {
throw new Error("Make sure your token is correct")
}
const cookies = {
headers: {
cookie: cookie
}
}
await fetch("https://www.roblox.com", cookies)
const thing = await fetch('https://api.roblox.com/currency/balance', cookies).then(res => res.json())
console.log(thing)
Thing outputs : { errors: [ { code: 403, message: 'Forbidden' } ] }
Well turns out I had to access the cookie from the Header. I did so by doing
const apiCall = await html.func("api.roblox.com/currency/balance", {
headers: {
cookie: `.ROBLOSECURITY=${cookie}`
}
})
Thanks for those who tried to help me!

Website does not allow about half our users to login. Cookies issue. Ubuntu

So to be honest I am not sure how much I can share here. I saw a similar post that was solved on the users end and did not actually lead to a solution on mine. If someone wants the website for testing please let me know or if I can post it here to be simple, I will as well.
So here it goes. I cannot personally replicate the issue, which is making it hard to test and I am out of my depth as is. I have watched others with the issue and this is how we have got this far.
We run a discord community and use Auth from Discord to pull in data from our members and use that for features on the site.
That being said - No roles are the issue here. We have whittled the problem down to a cookie. The website creates a cookie, which goes away during the Auth redirect, then comes back and prevents people from loading the site. Gives a 504 Gateway error. Once I get the users to delete the cookie, they can then load the website again - however they are not logged in.
Have been beating our heads against multiple walls for the past week and we cannot get it down.
I will provide some code here - Hoping this will show some issue, but I imagine it will not. Please let me know if I can provide any more clarity.
const r = require('express').Router();
const fetch = require('node-fetch');
const btoa = require('btoa');
const FormData = require("form-data");
const { catchAsync } = require('./utils/utils.js');
const session = require('express-session');
const redir = encodeURIComponent(process.env.DISCORDCALLBACK)
r.get("/login", (req, res) => {
res.redirect(`https://discord.com/api/v6/oauth2/authorize?client_id=${process.env.CID}&response_type=code&scope=identify%20email`);
});
r.get("/logout", (req, res) => {
if(req.session.accessToken.length > 1) {
req.session.accessToken = "";
res.redirect("/");
} else {
res.redirect("/");
}
})
r.get("/callback", catchAsync(async (req, res) => {
if (!req.query.code) throw new Error("NoCodeProvided");
const code = req.query.code;
//const creds = btoa(`${process.env.CID}:${process.env.SECRET}`);
const data = new FormData()
data.append("client_id", process.env.CID);
data.append("client_secret", process.env.SECRET);
data.append("grant_type", "authorization_code");
data.append("code", code);
fetch(`https://discord.com/api/v6/oauth2/token`, {
method: "POST",
//headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: data
})
.then(res => res.json())
.then(json => {
fetch("http://discord.com/api/v6/users/#me", {
method: "POST",
headers: { "Authorization": `${json.token_type} ${json.access_token}` }
})
.then(res => res.json())
.then(user => {
req.session.accessToken = `${json.access_token}`
req.session.cookie.maxAge = 86400000;
req.session.save(err => {
if(err) return console.log(err)
res.redirect("/");
})
})
.catch(err => {
console.log(err)
})
})
.catch(err => {
console.log(err)
})
}));
//export route(s)
module.exports = r;
Okay guys - so I just wanted to update you on what happened. I am thankful for the help and sorry for the waste of time.
One of our programmers said it best: "Lesson learned. Never hardcode values."
For one of Discord's call back for member roles. We had hard coded in a Discord Member ID. This lead to an error and for some reason we still do not understand, half of us being able to get in and half out...
We changed that ID to .env file that we can handle on the Pipeline and boom. People are in.
Thanks for the help!

put request works for one api but not for another api

I tested with two apis for axios put.
for one api its working fine where as with another api it throws an error.
for one api its showing request as options eventhough I gave as put and I am seeing 403 forbidden error
for this api i am facing the issue 'http:///sports/sportsId',
I debugged but still I am not able to find the issue.
is it a back-end issue
can you tell me how to fix it, providing my code snippet below
savesports = () => {
console.log("savesports---->");
console.log(this.state.sports);
let savesports = this.state.sports;
savesports.updatedBy = 'xxx';
savesports.priceRuleDescription = "test description";
let data = {
name: "yyyy",
email: "sda#gmail.com",
phone: "2321313"
};
axios
.put("https://jsonplaceholder.typicode.com/users/1", data)
.then(r => console.log("dada", r));
console.log(JSON.stringify(savesports));
axios
.put(
'http:///sports/sportsId',
savesports
// { headers: { 'Content-Type': 'application/json' } }
)
.then(r => console.log(r))
.catch(e => console.log(e));
//this.toggleDrawer("right", false);
this.setState({ right: false });
this.setState({ snackBarOpen: true });
setTimeout(() => {
this.setState({ snackBarOpen: false });
}, 6000)
};
1. Check if URL is right
I would first check if the URL is right.
Try changing http:///sports/sportsId to http://sports/sportsId if that's actually the URL you are requesting to.
2. Avoid name confusion
Both the method name and the put data variable name are the same (savesports). I would change the put data variable name to something meaningful like
let sportsData = this.state.sports;
sportsData.updatedBy = 'xxx';
sportsData.priceRuleDescription = 'test description';
3. Check authentication
403 might also be to auth error. I would check if the endpoint requires any authentication token or headers.

Categories

Resources