Skip to content

Commit 84acfe9

Browse files
rainerstudiosclaude
andcommitted
Add Steam inventory test endpoint and improve error handling
Changes: - Added test endpoint GET /api/steam/inventory/test/:steamId (no auth required) - Improved error handling with detailed debug information - Added browser-like headers to Steam API requests - Better error messages for 400/401/403 responses - Created test script (test-inventory.js) for manual testing Error handling improvements: - Now shows Steam API status code and response body - Differentiates between private inventory (403) and invalid requests (400/401) - Provides actionable error messages to users Testing results: - Steam API requires specific conditions for inventory access - Some inventories may be private or require authentication - Test endpoint allows frontend testing without auth WARNING: Test endpoint exposes inventory data publicly Remove /api/steam/inventory/test/:steamId in production! 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 8b9b43a commit 84acfe9

3 files changed

Lines changed: 184 additions & 2 deletions

File tree

index.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4149,6 +4149,23 @@ app.post('/api/steam/inventory/sync', requireAuth, async (req, res) => {
41494149
}
41504150
});
41514151

4152+
// TEST ENDPOINT - Remove auth requirement for testing
4153+
// WARNING: This exposes inventory data publicly! Remove in production!
4154+
app.get('/api/steam/inventory/test/:steamId', async (req, res) => {
4155+
try {
4156+
const { steamId } = req.params;
4157+
const result = await steamInventory.getSteamInventory(steamId);
4158+
res.json(result);
4159+
} catch (error) {
4160+
winston.error('Test inventory fetch error:', error);
4161+
res.status(500).json({
4162+
success: false,
4163+
error: 'Failed to fetch inventory',
4164+
message: error.message
4165+
});
4166+
}
4167+
});
4168+
41524169
winston.info('Steam inventory endpoints loaded');
41534170

41544171

lib/steam-inventory.js

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,36 @@ async function getSteamInventory(steamId) {
2020

2121
const response = await fetch(url, {
2222
headers: {
23-
'User-Agent': 'CS2FloatChecker/1.0'
23+
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
24+
'Accept': 'application/json, text/javascript, */*; q=0.01',
25+
'Accept-Language': 'en-US,en;q=0.9',
26+
'Referer': `https://steamcommunity.com/profiles/${steamId}/inventory`,
27+
'X-Requested-With': 'XMLHttpRequest'
2428
},
2529
timeout: 30000
2630
});
2731

2832
if (!response.ok) {
33+
const errorText = await response.text().catch(() => '');
34+
2935
if (response.status === 403) {
3036
return {
3137
success: false,
3238
error: 'Inventory is private',
33-
message: 'Please set your Steam inventory to public in privacy settings'
39+
message: 'Please set your Steam inventory to public in privacy settings',
40+
debug: { status: response.status, body: errorText.substring(0, 200) }
3441
};
3542
}
43+
44+
if (response.status === 400 || response.status === 401) {
45+
return {
46+
success: false,
47+
error: 'Cannot access inventory',
48+
message: `Steam API returned ${response.status}. Inventory may be private or Steam ID invalid.`,
49+
debug: { status: response.status, statusText: response.statusText, body: errorText.substring(0, 200) }
50+
};
51+
}
52+
3653
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
3754
}
3855

test-inventory.js

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
const fetch = require('node-fetch');
2+
const steamInventory = require('./lib/steam-inventory');
3+
4+
// Test Steam Community API directly
5+
async function testSteamAPI() {
6+
console.log('=== Testing Steam Community API ===\n');
7+
8+
const testCases = [
9+
{ id: '76561198084398045', name: 'shroud (public profile)' },
10+
{ id: '76561197960287930', name: 'Gabe Newell' },
11+
{ id: '76561199094452064', name: 'Test user' }
12+
];
13+
14+
for (const test of testCases) {
15+
const url = `https://steamcommunity.com/inventory/${test.id}/730/2?l=english&count=5`;
16+
17+
console.log(`\n📦 Testing: ${test.name}`);
18+
console.log(`SteamID: ${test.id}`);
19+
20+
try {
21+
const response = await fetch(url, {
22+
headers: {
23+
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
24+
'Accept': 'application/json, text/javascript, */*; q=0.01',
25+
'Accept-Language': 'en-US,en;q=0.9',
26+
'Referer': `https://steamcommunity.com/profiles/${test.id}/inventory`,
27+
'X-Requested-With': 'XMLHttpRequest'
28+
},
29+
timeout: 10000
30+
});
31+
32+
console.log(`Status: ${response.status} ${response.statusText}`);
33+
34+
if (!response.ok) {
35+
if (response.status === 403) {
36+
console.log('❌ Inventory is private');
37+
} else {
38+
console.log(`❌ HTTP Error: ${response.status}`);
39+
}
40+
continue;
41+
}
42+
43+
const text = await response.text();
44+
let data;
45+
46+
try {
47+
data = JSON.parse(text);
48+
} catch (e) {
49+
console.log('❌ Invalid JSON response');
50+
console.log('Response preview:', text.substring(0, 100));
51+
continue;
52+
}
53+
54+
if (!data) {
55+
console.log('❌ Empty response');
56+
continue;
57+
}
58+
59+
if (data.error) {
60+
console.log(`❌ Steam API Error: ${data.error}`);
61+
continue;
62+
}
63+
64+
console.log('✅ Success!');
65+
console.log(`Total inventory items: ${data.total_inventory_count || 'N/A'}`);
66+
console.log(`Assets returned: ${data.assets ? data.assets.length : 0}`);
67+
console.log(`Descriptions: ${data.descriptions ? data.descriptions.length : 0}`);
68+
69+
if (data.assets && data.assets.length > 0) {
70+
const asset = data.assets[0];
71+
const desc = data.descriptions.find(d =>
72+
d.classid === asset.classid && d.instanceid === asset.instanceid
73+
);
74+
75+
if (desc) {
76+
console.log('\nSample item:');
77+
console.log(` Name: ${desc.market_name || desc.name}`);
78+
console.log(` Type: ${desc.type}`);
79+
console.log(` Tradable: ${desc.tradable === 1}`);
80+
console.log(` Marketable: ${desc.marketable === 1}`);
81+
}
82+
}
83+
84+
} catch (error) {
85+
console.log(`❌ Error: ${error.message}`);
86+
}
87+
88+
// Wait between requests
89+
await new Promise(resolve => setTimeout(resolve, 1000));
90+
}
91+
}
92+
93+
// Test our inventory parsing function
94+
async function testInventoryParser() {
95+
console.log('\n\n=== Testing Our Inventory Parser ===\n');
96+
97+
const steamId = '76561198084398045'; // shroud - known public inventory
98+
99+
console.log(`Fetching inventory for SteamID: ${steamId}`);
100+
101+
try {
102+
const result = await steamInventory.getSteamInventory(steamId);
103+
104+
console.log('\nParser Result:');
105+
console.log(`Success: ${result.success}`);
106+
107+
if (!result.success) {
108+
console.log(`Error: ${result.error}`);
109+
console.log(`Message: ${result.message}`);
110+
return;
111+
}
112+
113+
console.log(`Total items: ${result.total_items}`);
114+
115+
if (result.items && result.items.length > 0) {
116+
const item = result.items[0];
117+
118+
console.log('\nFirst item parsed:');
119+
console.log(JSON.stringify({
120+
assetid: item.assetid,
121+
name: item.name,
122+
market_name: item.market_name,
123+
type: item.type,
124+
wear: item.wear,
125+
wear_full: item.wear_full,
126+
is_stattrak: item.is_stattrak,
127+
tradable: item.tradable,
128+
marketable: item.marketable,
129+
rarity: item.rarity,
130+
weapon_type: item.weapon_type,
131+
image_url: item.image_url?.substring(0, 60) + '...',
132+
inspect_link: item.inspect_link ? 'Present' : 'None',
133+
defindex: item.defindex
134+
}, null, 2));
135+
}
136+
137+
} catch (error) {
138+
console.log(`❌ Parser Error: ${error.message}`);
139+
console.error(error);
140+
}
141+
}
142+
143+
// Run tests
144+
(async () => {
145+
await testSteamAPI();
146+
await testInventoryParser();
147+
console.log('\n=== Tests Complete ===\n');
148+
})();

0 commit comments

Comments
 (0)