Jump to content
McKay Development

All Activity

This stream auto-updates

  1. Past hour
  2. 407 means your proxy is rejecting your connection. You're either using the wrong credentials or you have things configured wrong.
  3. Today
  4. Trades containing CS2 items are not returned by the WebAPI when using an API key. You need to use an access token instead. You can get one using steam-session, and you provide it like this: https://api.steampowered.com/IEconService/GetTradeStatus/v1/?tradeid=123456&access_token=eyAid...
  5. Yesterday
  6. this is the middleware of my route when ai copy console.logged proxy and pasting in new loginsession it works but when im running the code with this : `http://${ListWithGeo.login}:${ListWithGeo.password}@${ListWithGeo.PROXY_GETEWAY_HOST}:${ListWithGeo.PROXY_GETEWAY_PORT}` IT GIVES PROXY AUTH ERROR 407 I DONT UNDERSTAND WHAT IM DOIN WRONG PLS SOMEONE HELP ME!!!!!!!!!!!!!!!!!!!!!!! // proxyMiddleware.js const net = require('net'); const { HttpsProxyAgent } = require('https-proxy-agent'); const axios = require('axios') const geoip = require('geoip-lite') const fs = require('fs').promises; const path = require('path'); const jwt = require('jsonwebtoken'); const GEO_FILE_PATH = path.join(__dirname, 'geo.json'); const PROXY_API_KEY = 'APIKEY'; const PROXY_BASE_URL = `https://proxy-seller.com/personal/api/v1/${PROXY_API_KEY}`; const PROXY_GATEWAY_HOST = 'res.proxy-seller.com'; const PROXY_GATEWAY_PORT = 10000; const JWT_SECRET = 'SECRET'; module.exports = async function proxyMiddleware(req, res, next) { try { const token = req.cookies.auth; if (token) { const decoded = jwt.verify(token, JWT_SECRET); const proxy = decoded.proxy console.log('Decoded Proxy:',proxy) req.proxy = proxy return next(); // No token, continue to route } console.log('starting generation of proxy for new ip') //(req.headers['x-forwarded-for'] || req.socket.remoteAddress || '').split(',')[0].trim(); const userIp = (req.headers['x-forwarded-for'] || req.socket.remoteAddress || '').split(',')[0].trim().split(':')[3]; const geo = geoip.lookup(userIp); console.log(geo); console.log('geo.city : ',geo.city) console.log('geo.country: ',geo.country) const ListWithGeo = await getProxyUrl(geo.country, geo.city, userIp) console.log('gotproxyfrommiddle:',ListWithGeo) req.proxy = ListWithGeo // If IPv6 localhost like ::1, ignore if (!userIp || userIp.startsWith('::1') || userIp === '127.0.0.1') { req.proxyConfig = { proxyAgent: null }; return next(); } next(); } catch (err) { console.error('Proxy middleware error:', err); req.proxyConfig = { proxyAgent: null }; next(); } }; async function getProxyUrl(countryCodeOrName, city, ip) { const MY_AUTHORIZED_IP = ip; console.log('pfuncIP :',ip) const geoDataArray = await readGeoJson(); const countryObj = findCountry(geoDataArray, countryCodeOrName); const targetCityObj = findCity(countryObj, city); if (!targetCityObj.isps?.length) { throw new Error(`No ISPs found for city "${city}" in geo.json`); } const isp = targetCityObj.isps[0]; const credentials = await requestProxy(countryObj.code, targetCityObj.region, targetCityObj.name, isp, MY_AUTHORIZED_IP); const login = encodeURIComponent(credentials.login); const password = encodeURIComponent(credentials.password); const test_proxy = `http://${login}:${password}@${PROXY_GATEWAY_HOST}:${PROXY_GATEWAY_PORT}`; //return`https://${login}:${password}@${PROXY_GATEWAY_HOST}:${PROXY_GATEWAY_PORT}`; return test_proxy; } async function readGeoJson() { try { const content = await fs.readFile(GEO_FILE_PATH, 'utf8'); const data = JSON.parse(content); if (!Array.isArray(data)) throw new Error('geo.json must be an array'); return data; } catch (err) { throw new Error(`Failed to read geo.json: ${err.message}`); } } function findCountry(geoArray, search) { const lowered = search.toLowerCase(); const country = geoArray.find(c => (c.name && c.name.toLowerCase() === lowered) || (c.code && c.code.toLowerCase() === lowered) ); if (!country) throw new Error(`Country "${search}" not found in geo.json`); return country; } function findCity(countryObj, cityName) { // Сначала ищем точно нужный город for (const region of countryObj.regions) { const foundCity = region.cities.find(c => c.name.toLowerCase() === cityName.toLowerCase()); if (foundCity && foundCity.isps?.length) return { ...foundCity, region: region.name }; } for (const region of countryObj.regions) { const cityWithIsps = region.cities.find(c => c.isps?.length); if (cityWithIsps) return { ...cityWithIsps, region: region.name }; } throw new Error(`No city with ISPs found in country "${countryObj.name}"`); } async function requestProxy(countryCode, region, city, isp, authorizedIp) { // <-- Добавлен authorizedIp try { const postData = { title: `API Test with IP Binding: ${Date.now()}`, geo: { country: countryCode, region, city, provider: isp }, rotation: 0, export: { ext: 'login:password@ip:port', ports: 1 }, ip: authorizedIp }; console.log("3. Requesting credentials with IP BINDING:", postData); const res = await axios.post(`${PROXY_BASE_URL}/resident/list`, postData); if (res.data.status !== 'success' || !res.data.data?.login) { const errMsg = res.data.errors ? JSON.stringify(res.data.errors) : 'Invalid API response'; throw new Error(`Proxy creation failed: ${errMsg}`); } return { login: res.data.data.login, password: res.data.data.password }; } catch (err) { if (err.response) console.error('API error details:', err.response.data); throw new Error(`Failed to request proxy: ${err.message}`); } } /************************************************* AND THIS IS MY ROUTE *************************************************\ const express = require('express'); const router = express.Router(); const SteamUser = require('steam-user') const { LoginSession, EAuthTokenPlatformType } = require('steam-session'); const SteamCommunity = require('steamcommunity'); const community = new SteamCommunity(); const QRCode = require('qrcode'); const https = require('https'); const geoip = require('geoip-lite') const activeSessions = new Map(); const client = new SteamUser() const jwt = require('jsonwebtoken'); const { v4: uuidv4 } = require('uuid'); // დავამატეთ UUID გენერატორი const { HttpsProxyAgent } = require('https-proxy-agent'); const axios = require('axios') const fs = require('fs').promises; const path = require('path'); const GEO_FILE_PATH = path.join(__dirname, 'geo.json'); const PROXY_API_KEY = 'KEY'; const PROXY_BASE_URL = `https://proxy-seller.com/personal/api/v1/${PROXY_API_KEY}`; const PROXY_GATEWAY_HOST = 'res.proxy-seller.com'; const PROXY_GATEWAY_PORT = 10000; const JWT_SECRET = 'SECRET'; router.use(proxyMiddleware); router.post('/', async (req, res) => { let proxyUrl = req.proxy; try { const userIp = (req.headers['x-forwarded-for'] || req.socket.remoteAddress || '').split(',')[0].trim().split(':')[3]; const geo = geoip.lookup(userIp); console.log(geo); const ListWithGeo = await getProxyUrl(geo.country, geo.city, userIp) console.log('listeith:',ListWithGeo) const session = new LoginSession(EAuthTokenPlatformType.WebBrowser, { httpProxy:`http://${ListWithGeo.login}:${ListWithGeo.password}@${ListWithGeo.PROXY_GATEWAY_HOST}:${ListWithGeo.PROXY_GATEWAY_PORT}` }); const startResult = await session.startWithQR(); const qrImageUrl = await QRCode.toDataURL(startResult.qrChallengeUrl); const sessionId = uuidv4(); activeSessions.set(sessionId, session); const token = jwt.sign( { proxy:req.proxy, sessionId: sessionId // დავამატეთ sessionId ტოკენში }, 'KEY', { expiresIn: '30d' } ); res.cookie('auth', token, { httpOnly: true, secure: true, sameSite: 'none', path: '/', maxAge: 86400000 }); res.status(200).json({ success: true, message: 'qr generated', qrImageUrl, sessionId // დავაბრუნეთ sessionId კლიენტს }); } catch(error) { console.log('QR REFRESH ERROR:', error); res.status(500).json({ success: false, error: error.message }); } }); // SSE Endpoint for real-time updates router.get('/events/:sessionId', (req, res) => { const { sessionId } = req.params; const session = activeSessions.get(sessionId); if (!session) { return res.status(404).json({ success: false, error: 'Session not found' }); } // SSE headers res.setHeader('Content-Type', 'text/event-stream'); res.setHeader('Cache-Control', 'no-cache'); res.setHeader('Connection', 'keep-alive'); res.setHeader('Access-Control-Allow-Origin', '*'); // Send initial connection confirmation res.write(`event: connected\ndata: ${JSON.stringify({ message: "SSE connection established" })}\n\n`); // Event handlers session.on('remoteInteraction', () => { res.write(`event: scanned\ndata: ${JSON.stringify({ message: "QR scanned! Waiting for approval..." })}\n\n`); }); session.on('authenticated', async () => { try { const cookies = await session.getWebCookies(); const inventory = await loginWithCookies(cookies); res.write(`event: authenticated\ndata: ${JSON.stringify({ message: "Login successful!", cookies, inventory })}\n\n`); activeSessions.delete(sessionId); // Cleanup res.end(); } catch (error) { res.write(`event: error\ndata: ${JSON.stringify({ error: "Failed to get inventory", details: error.message })}\n\n`); res.end(); activeSessions.delete(sessionId); } }); session.on('timeout', () => { res.write(`event: timeout\ndata: ${JSON.stringify({ message: "Session timed out." })}\n\n`); activeSessions.delete(sessionId); res.end(); }); session.on('error', (err) => { res.write(`event: error\ndata: ${JSON.stringify({ error: err.message })}\n\n`); activeSessions.delete(sessionId); res.end(); }); // Handle client disconnect req.on('close', () => { if (session && !session.isAuthenticated) { session.cancelLoginAttempt(); activeSessions.delete(sessionId); } }); }); module.exports = router; // Game configurations const GAMES = { CS2: { appid: 730, contextid: 2 }, DOTA2: { appid: 570, contextid: 2 }, RUST: { appid: 252490, contextid: 2 }, TF2: { appid: 440, contextid: 2 } }; async function loginWithCookies(cookies) { try { // Set cookies and get SteamID community.setCookies(cookies); const steamID = community.steamID.getSteamID64(); // Load all inventories in parallel const inventoryPromises = Object.entries(GAMES).map(async ([gameName, config]) => { try { const inventory = await getInventory(steamID, config.appid, config.contextid); return { game: gameName, items: processInventoryItems(inventory) }; } catch (error) { console.error(`Failed to load ${gameName} inventory:`, error); return { game: gameName, items: [], error: error.message }; } }); // Wait for all inventories to load const gameInventories = await Promise.all(inventoryPromises); // Convert to object format { CS2: [...], DOTA2: [...], ... } const inventories = {}; gameInventories.forEach(result => { inventories[result.game] = result.items; }); return { steamID, inventories }; } catch (error) { console.error('Error in loginWithCookies:', error); throw error; } } function getInventory(steamID, appid, contextid) { return new Promise((resolve, reject) => { community.getUserInventoryContents( steamID, appid, contextid, true, // tradable only (err, inventory) => { if (err) return reject(err); resolve(inventory); } ); }); } function processInventoryItems(inventory) { return inventory.map(item => ({ assetid: item.assetid, name: item.market_hash_name, icon: item.icon_url, icon_large: item.icon_url_large, tradable: item.tradable, marketable: item.marketable, type: item.type, amount: item.amount })); } module.exports = router async function getProxyUrl(countryCodeOrName, city, ip) { const MY_AUTHORIZED_IP = ip; console.log('pfuncIP :',ip) const geoDataArray = await readGeoJson(); const countryObj = findCountry(geoDataArray, countryCodeOrName); const targetCityObj = findCity(countryObj, city); if (!targetCityObj.isps?.length) { throw new Error(`No ISPs found for city "${city}" in geo.json`); } const isp = targetCityObj.isps[0]; const credentials = await requestProxy(countryObj.code, targetCityObj.region, targetCityObj.name, isp, MY_AUTHORIZED_IP); const login = encodeURIComponent(credentials.login); const password = encodeURIComponent(credentials.password); const test_proxy = `http://${login}:${password}@${PROXY_GATEWAY_HOST}:${PROXY_GATEWAY_PORT}`; //return`https://${login}:${password}@${PROXY_GATEWAY_HOST}:${PROXY_GATEWAY_PORT}`; return {login,password,PROXY_GATEWAY_HOST, PROXY_GATEWAY_PORT}; } async function readGeoJson() { try { const content = await fs.readFile(GEO_FILE_PATH, 'utf8'); const data = JSON.parse(content); if (!Array.isArray(data)) throw new Error('geo.json must be an array'); return data; } catch (err) { throw new Error(`Failed to read geo.json: ${err.message}`); } } function findCountry(geoArray, search) { const lowered = search.toLowerCase(); const country = geoArray.find(c => (c.name && c.name.toLowerCase() === lowered) || (c.code && c.code.toLowerCase() === lowered) ); if (!country) throw new Error(`Country "${search}" not found in geo.json`); return country; } function findCity(countryObj, cityName) { // Сначала ищем точно нужный город for (const region of countryObj.regions) { const foundCity = region.cities.find(c => c.name.toLowerCase() === cityName.toLowerCase()); if (foundCity && foundCity.isps?.length) return { ...foundCity, region: region.name }; } for (const region of countryObj.regions) { const cityWithIsps = region.cities.find(c => c.isps?.length); if (cityWithIsps) return { ...cityWithIsps, region: region.name }; } throw new Error(`No city with ISPs found in country "${countryObj.name}"`); } async function requestProxy(countryCode, region, city, isp, authorizedIp) { // <-- Добавлен authorizedIp try { const postData = { title: `API Test with IP Binding: ${Date.now()}`, geo: { country: countryCode, region, city, provider: isp }, rotation: 0, export: { ext: 'login:password@ip:port', ports: 1 }, // --- ДОБАВЬТЕ ПАРАМЕТР ПРИВЯЗКИ IP ИЗ ДОКУМЕНТАЦИИ --- // Наиболее вероятное название - 'ip'. // Если не сработает, ищите в документации 'bind_ip', 'auth_ip' и т.п. ip: authorizedIp // --------------------------------------------------------- }; console.log("3. Requesting credentials with IP BINDING:", postData); const res = await axios.post(`${PROXY_BASE_URL}/resident/list`, postData); if (res.data.status !== 'success' || !res.data.data?.login) { const errMsg = res.data.errors ? JSON.stringify(res.data.errors) : 'Invalid API response'; throw new Error(`Proxy creation failed: ${errMsg}`); } return { login: res.data.data.login, password: res.data.data.password }; } catch (err) { if (err.response) console.error('API error details:', err.response.data); throw new Error(`Failed to request proxy: ${err.message}`); } } // Example usage: // const cookies = [...]; // Get these from your authentication flow // loginWithCookies(cookies) // .then(data => console.log('Inventory data:', data)) // .catch(err => console.error('Failed:', err));
  7. Hello, the websession is never emitted when logged in with refresh token. Only loggedOn is emitted. const SteamUser = require("steam-user"); const client = new SteamUser(); client.logOn({ refreshToken: "YOUR_REFRESH_TOKEN" }); client.on("loggedOn", () => { console.log("Logged in"); }); client.on("webSession", (sessionID, cookies) => { console.log("Web session fired!", sessionID, cookies); }); client.on("error", (err) => console.error(err));
  8. Hello, how can I see when my Steam market ban will end using this library or another one? Additionally, I couldn’t find any functions to view hidden items or see when their bans will end. Are those functions missing in doctormckay’s libraries as well?
  9. Last week
  10. why does the IEconService/GetTradeStatus/v1 method return an empty response? I tried using the developer access key from both the account that sent the items and the bot that received the items. And the response is still empty. Tradeid used the one that was given by offer.send when creating the trade. https://api.steampowered.com/IEconService/GetTradeStatus/v1/?key=CAFBBC72E27B49776xxx1xxF9792643E&tradeid=8345025797 https://api.steampowered.com/IEconService/GetTradeStatus/v1/?key=CAFBBC72E27B49776xxx1xxF9792643E&tradeid=8345025797&get_descriptions=true&language=en_us
  11. thanx. this method fixed this problem
  12. same issue on newest version node:internal/buffer:86 throw new ERR_BUFFER_OUT_OF_BOUNDS(); ^ RangeError [ERR_BUFFER_OUT_OF_BOUNDS]: Attempt to access memory outside buffer bounds at boundsError (node:internal/buffer:86:11) at Buffer.readUInt32LE (node:internal/buffer:222:5) at TCPConnection._readMessage (C:\Users\PC\Desktop\checler\node_modules\steam-user\components\connection_protocols\tcp.js:194:33) at Socket.emit (node:events:518:28) at emitReadable_ (node:internal/streams/readable:834:12) at onEofChunk (node:internal/streams/readable:812:5) at readableAddChunkPushByteMode (node:internal/streams/readable:466:5) at Readable.push (node:internal/streams/readable:392:5) at TCP.onStreamRead (node:internal/stream_base_commons:231:12) { code: 'ERR_BUFFER_OUT_OF_BOUNDS' }
  13. Hey doc! I’m using steam-session to make qr code authentication on my testing website for login in on the bot account and when I’m running the script on local host it’s going well but when I’m deploing this application and I’m trying login through QR code in steam mobile app it shows that I’m logging in from a different place and the app is not allowing me to log in so can someone help me with this? Pls<3
  14. Have you acknowledged the modal about trade protection? You need to do that or call acknowledgeTradeProtection in node-steamcommunity once per account to be able to trade.
  15. Earlier
  16. if (response.statusCode != 200) { if (response.statusCode == 401) { this.manager._notifySessionExpired(new Error("HTTP error 401")); Helpers.makeAnError(new Error("Not Logged In"), callback); return; } console.log(response.statusCode); console.log(callback); console.log(body); Helpers.makeAnError(new Error("HTTP error " + response.statusCode), callback, body); return; } 500 [Function (anonymous)] { strError: 'An error occurred. Please see your Trade Offers page on Steam for information about changes to trading.' } This in send method from tradeoffer.js. const SteamUser = require('steam-user'); const SteamCommunity = require('steamcommunity'); const TradeOfferManager = require('steam-tradeoffer-manager'); // const community = new SteamCommunity(); const steamID = SteamCommunity.SteamID; //===================INIT STEAM USER======================== const client = new SteamUser(); //===================INIT TRADE OFFER MANAGER======================== const manager = new TradeOfferManager({ steam: client, domain: 'domain.com', language: 'en' }); client.logOn({ accountName: botConfig.username, password: botConfig.password, twoFactorCode: require('steam-totp').getAuthCode(botConfig.sharedSecret) }); client.on('loggedOn', () => { console.log(`Bot ${botConfig.username} logged in`); const personaName = client.steamID.getSteamID64(); console.log(`Bot persona name: ${personaName}`); }); client.on('webSession', (sessionid, cookies) => { manager.setCookies(cookies, err => { if (err) { console.error(`Failed to set cookies for bot ${botConfig.username}:`, err); process.exit(1); } community.setCookies(cookies); community.startConfirmationChecker(30000, botConfig.sharedSecret); console.log(`Bot ${botConfig.username} ready to trade`); }); bot.manager.getUserInventoryContents(userSteamId, appid, contextid, true, (err, inventory) => { if (err) { console.log("Failed to get client user inventory:", err); return; } if (inventory.length === 0) { console.log("client user inventory is empty."); return; } console.log(`take first item`); const firstItem = inventory[0]; const offer = bot.manager.createOffer(userTradeUrl); //example https://steamcommunity.com/tradeoffer/new/?partner=xxx141&token=xxfacGs offer.addTheirItem({ appid: appid, contextid: contextid, assetid: firstItem.assetid }); offer.send((err, status) => { if (err) { console.error("Failed to send offer:", err); console.error("Steam response:", err.cause || err.response || err.body); return res.status(500).json({ success: false, message: 'Error sending trade offer', error: err.message }); } console.log("Trade offer sent successfully! Status:", status); }); }); Failed to send offer: Error: An error occurred. Please see your Trade Offers page on Steam for information about changes to trading. Both accounts meet the requirements. All authorizations are successful. I can go to tradeurl and send a trade manually. The only message I get after sending is that the trade will be delayed until 15 days due to not using steam guard for a long time (something like that). steam response all err./ empty for this error what is my mistake
  17. It's based on whether Steam reports if you have a wallet or not. I believe it becomes true the first time you fund your wallet (and thus set a currency for it).
  18. The hasWallet property in the wallet data returns either true or false, but what is this value based on? Is hasWallet always false for limited accounts and always true for non-limited accounts?
  19. I feel stupid for not trying that out from the beginning! Thanks for quick response.
  20. Just add 2FA the same way you would if you had a phone number. The code gets sent to your email instead of your phone.
  21. I was going through this suggestion you made of using node-steamcommunity but it looks like steam account needs to have a phone number verified before that process can be followed. In steam mobile app, I noticed that you can get steam guard working even without adding any phone number. I believe same process is followed by Steam Desktop Authenticator as well. Is there some option available in node-steamcommunity as well? Am I missing something here? I tested adding steam guard without phone number on a new account using ipad, if that matters.
  22. Hello, I have searched all over the internet, but couldn't figure out anything. Is anyone familiar with what `player_xp_bonus_flags` maps to? I got a `16` field value on my account, so I assume that would relate to my account currently having weekly XP boost available, but I'm not sure at all. Thanks for any replies
  23. https://github.com/DoctorMcKay/node-steamcommunity/wiki/CSteamUser#commentmessage-callback
  24. Is comment posting available in the module?
  25. A trade that's reversed during Trade Protection will go to status 12 in GetTradeHistory and GetTradeStatus.
  26. A previous offer's corresponding tradeid couldn't be found in the trade history API because the previously saved time_updated value was not the latest—it had changed. By using the updated time_updated value, the corresponding tradeid can be found in the trade history.
  27. In GetTradeStatus, even if a trade is rolled back midway, it still returns a success status (3). It has been observed that when using the start_after_time parameter in the GetTradeHistory API, there are still cases where the corresponding tradeid is not returned—approximately 1 out of every 20 trades. Therefore, it’s still necessary to paginate through the results to locate it.
  28. Or you could just use GetTradeStatus which takes a tradeid as input?
  29. Retrieve time_updated from the Trade Offer API First, use the Steam Trade Offer API to get the time_updated field of the target trade. For example: https://api.steampowered.com/IEconService/GetTradeOffer/v1/?tradeofferid=8301957547&access_token=xx.xx.xx { "response": { "offer": { "tradeofferid": "8301957547", "tradeid": "807950398061201297", "time_updated": 1753501576, ... } } } Use time_updated as the start_after_time parameter to query the Trade History API Next, pass the time_updated value as the start_after_time parameter when calling the Trade History API: GET https://api.steampowered.com/IEconService/GetTradeHistory/v1/?max_trades=1&start_after_time=1753501576&access_token=xxx.xxx.xxx The API response will include the trade information starting from that timestamp: { "response": { "more": true, "trades": [ { "tradeid": "807950398061201297", "time_init": 1753501576, ... }, ... ] } } This method allows you to accurately locate a trade in the trade history using the time_updated value, which is useful for tracking or further processing.
  1. Load more activity
×
×
  • Create New...