import axios from 'axios'; import * as cheerio from 'cheerio'; export interface SteamWebProfile { steamId: string; personaName: string; avatar: string; profileUrl: string; } const AXIOS_CONFIG = { timeout: 10000, headers: { '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' } }; export const fetchProfileData = async (identifier: string, steamLoginSecure?: string): Promise => { let url = ''; // Clean identifier const cleanId = identifier.replace(/https?:\/\/steamcommunity\.com\/(profiles|id)\//, '').replace(/\/$/, ''); if (cleanId.match(/^\d+$/)) { url = `https://steamcommunity.com/profiles/${cleanId}?xml=1`; } else { url = `https://steamcommunity.com/id/${cleanId}?xml=1`; } const headers = { ...AXIOS_CONFIG.headers } as any; if (steamLoginSecure) { headers['Cookie'] = steamLoginSecure; } try { const response = await axios.get(url, { ...AXIOS_CONFIG, headers }); const $ = cheerio.load(response.data, { xmlMode: true }); const steamId = $('steamID64').first().text().trim(); const personaName = $('steamID').first().text().trim(); const avatarRaw = $('avatarFull').first().text().trim(); // Robustly extract the first URL if concatenated let avatar = avatarRaw; const urls = avatarRaw.match(/https?:\/\/[^\s"'<>]+/g); if (urls && urls.length > 0) { avatar = urls[0]!; } // Ensure https if (avatar && avatar.startsWith('http:')) { avatar = avatar.replace('http:', 'https:'); } const profileUrl = steamId ? `https://steamcommunity.com/profiles/${steamId}` : (cleanId.match(/^\d+$/) ? `https://steamcommunity.com/profiles/${cleanId}` : `https://steamcommunity.com/id/${cleanId}`); return { steamId: steamId || cleanId, personaName: personaName || 'Unknown', avatar: avatar || 'https://avatars.akamai.steamstatic.com/fef49e7fa7e1997310d705b2a6158ff8dc1cdfeb_full.jpg', profileUrl }; } catch (error: any) { throw new Error(`Failed to fetch profile: ${error.message}`); } }; export const scrapeBanStatus = async (profileUrl: string, steamLoginSecure?: string): Promise<{ vacBanned: boolean, gameBans: number }> => { try { const headers = { ...AXIOS_CONFIG.headers } as any; if (steamLoginSecure) { headers['Cookie'] = steamLoginSecure; } const response = await axios.get(profileUrl, { ...AXIOS_CONFIG, headers }); const $ = cheerio.load(response.data); const banText = $('.profile_ban').text().toLowerCase(); const vacBanned = banText.includes('vac ban'); const gameBansMatch = banText.match(/(\d+)\s+game\s+ban/); const gameBans = gameBansMatch ? parseInt(gameBansMatch[1]!) : 0; return { vacBanned, gameBans }; } catch (error) { return { vacBanned: false, gameBans: 0 }; } };