steamid-resolver
Version:
NPM library to get steamIDs from profile or group links, the other way around and validate sharedfileIDs
319 lines (272 loc) • 14.6 kB
JavaScript
/*
* File: index.js
* Project: steamid-resolver
* Created Date: 2023-04-05 19:04:56
* Author: 3urobeat
*
* Last Modified: 2025-01-24 17:36:11
* Modified By: 3urobeat
*
* Copyright (c) 2023 - 2025 3urobeat <https://github.com/3urobeat>
*
* Licensed under the MIT license: https://opensource.org/licenses/MIT
* Permission is granted to use, copy, modify, and redistribute the work.
* Full license information available in the project LICENSE file.
*/
// Source: https://github.com/3urobeat/node-steamid-resolver
const { _parseParam } = require("./parseParam.js");
const { _parseXML } = require("./parseXML.js");
// Type definitions for full information objects
/**
* Full profile information object returned by Steam. Notes: `mostPlayedGames` had 4 elements in testing. `groups` contains full information of the first 3 groups, all following groups only have '$' and 'groupID64' populated.
* @typedef fullProfileInfoObject
* @type {{
* steamID64: [string], steamID: [string], onlineState: [string], stateMessage: [string], privacyState: [string], visibilityState: [string], avatarIcon: [string], avatarMedium: [string], avatarFull: [string], vacBanned: [string],
* tradeBanState: [string], isLimitedAccount: [string], customURL: [string], memberSince: [string], steamRating: [string], hoursPlayed2Wk: [string], headline: [string], location: [string],realname: [string], summary: [string],
* mostPlayedGames: [
* { mostPlayedGame: [
* { gameName: [string], gameLink: [string], gameIcon: [string], gameLogo: [string], gameLogoSmall: [string], hoursPlayed: [string], hoursOnRecord: [string], statsName: [string] },
* { gameName: [string], gameLink: [string], gameIcon: [string], gameLogo: [string], gameLogoSmall: [string], hoursPlayed: [string], hoursOnRecord: [string], statsName: [string] },
* { gameName: [string], gameLink: [string], gameIcon: [string], gameLogo: [string], gameLogoSmall: [string], hoursPlayed: [string], hoursOnRecord: [string], statsName: [string] },
* { gameName: [string], gameLink: [string], gameIcon: [string], gameLogo: [string], gameLogoSmall: [string], hoursPlayed: [string], hoursOnRecord: [string], statsName: [string] }
* ] }
* ],
* groups: [
* { group: array<{ "$": { isPrimary: string }, groupID64: [string], groupName: [string], groupURL: [string], headline: [string], summary: [string], avatarIcon: [string], avatarMedium: [string], avatarFull: [string], memberCount: [string], membersInChat: [string], membersInGame: [string], membersOnline: [string] }> }
* ]
* }}
*/
/**
* Full group information object returned by Steam.
* @typedef fullGroupInfoObject
* @type {{
* groupID64: [string],
* groupDetails: [
* { groupName: [string], groupURL: [string], headline: [string], summary: [string], avatarIcon: [string], avatarMedium: [string], avatarFull: [string], memberCount: [string], membersInChat: [string], membersInGame: [string], membersOnline: [string] }
* ],
* memberCount: [string], totalPages: [string], currentPage: [string], startingMember: [string], nextPageLink: [string],
* members: [
* { steamID64: array<string> }
* ]
* }}
*/
/**
* Get the custom profile url of a user as String by their steamID64 or full URL
* @param {String} steamID64 steamID64 or full URL of the user
* @param {function(string, string)} [callback] Optional: Called with `err` (String) and `customURL` (String) parameters on completion
* @return {Promise.<string>} Resolves with customURL on success or rejects with error on failure
*/
module.exports.steamID64ToCustomUrl = (steamID64, callback) => {
return new Promise((resolve, reject) => {
// Hack to support Promises & Callbacks: Resolve errors instead of rejecting them when callback is defined to prevent UnhandledPromiseRejection crash
reject = (!callback || typeof callback !== "function") ? reject : resolve;
callback = callback || (() => {});
steamID64 = _parseParam(steamID64);
_parseXML(`https://steamcommunity.com/profiles/${steamID64}`)
.then(res => {
// Check if profile is private and return an error because private profiles do not contain a customURL property
if (res.customURL && res.customURL[0]) {
resolve(res.customURL[0]);
callback(null, res.customURL[0]);
} else {
reject("Failed to resolve customURL!")
callback("Failed to resolve customURL!", null);
}
})
.catch(err => {
reject(err);
callback(err, null);
});
});
};
/**
* Get the profile name of a user as String by their steamID64 or full URL
* @param {String} steamID64 steamID64 or full URL of the user
* @param {function(string, string)} [callback] Optional: Called with `err` (String) and `profileName` (String) parameters on completion
* @return {Promise.<string>} Resolves with profile name on success or rejects with error on failure
*/
module.exports.steamID64ToProfileName = (steamID64, callback) => {
return new Promise((resolve, reject) => {
// Hack to support Promises & Callbacks: Resolve errors instead of rejecting them when callback is defined to prevent UnhandledPromiseRejection crash
reject = (!callback || typeof callback !== "function") ? reject : resolve;
callback = callback || (() => {});
steamID64 = _parseParam(steamID64);
_parseXML(`https://steamcommunity.com/profiles/${steamID64}`)
.then(res => {
resolve(res.steamID[0]);
callback(null, res.steamID[0]);
})
.catch(err => {
reject(err);
callback(err, null);
});
});
};
/**
* Get the steamID64 of a user as String by their custom profile url or full URL
* @param {String} customURL Custom ID or full URL of the user as String
* @param {function(string, string)} [callback] Optional: Called with `err` (String) and `steamID64` (String) parameters on completion
* @return {Promise.<string>} Resolves with steamID64 on success or rejects with error on failure
*/
module.exports.customUrlToSteamID64 = (customURL, callback) => {
return new Promise((resolve, reject) => {
// Hack to support Promises & Callbacks: Resolve errors instead of rejecting them when callback is defined to prevent UnhandledPromiseRejection crash
reject = (!callback || typeof callback !== "function") ? reject : resolve;
callback = callback || (() => {});
customURL = _parseParam(customURL);
_parseXML(`https://steamcommunity.com/id/${customURL}`)
.then(res => {
resolve(res.steamID64[0]);
callback(null, res.steamID64[0]);
})
.catch(err => {
reject(err);
callback(err, null);
});
});
};
/**
* Get the profile name of a user as String by their custom profile url or full URL
* @param {String} customURL Custom ID or full URL of the user as String
* @param {function(string, string)} [callback] Optional: Called with `err` (String) and `profileName` (String) parameters on completion
* @return {Promise.<string>} Resolves with profile name on success or rejects with error on failure
*/
module.exports.customUrlToProfileName = (customURL, callback) => {
return new Promise((resolve, reject) => {
// Hack to support Promises & Callbacks: Resolve errors instead of rejecting them when callback is defined to prevent UnhandledPromiseRejection crash
reject = (!callback || typeof callback !== "function") ? reject : resolve;
callback = callback || (() => {});
customURL = _parseParam(customURL);
_parseXML(`https://steamcommunity.com/id/${customURL}`)
.then(res => {
resolve(res.steamID[0]);
callback(null, res.steamID[0]);
})
.catch(err => {
reject(err);
callback(err, null);
});
});
};
/**
* Get the full information of a user as Object by their steamID64 or full URL
* @param {String} steamID64 steamID64 or full URL of the user as String
* @param {function(string, fullProfileInfoObject)} [callback] Optional: Called with `err` (String) and `info` (Object) parameters on completion
* @return {Promise.<fullProfileInfoObject>} Resolves with fullInfo object on success or rejects with error string on failure
*/
module.exports.steamID64ToFullInfo = (steamID64, callback) => {
return new Promise((resolve, reject) => {
// Hack to support Promises & Callbacks: Resolve errors instead of rejecting them when callback is defined to prevent UnhandledPromiseRejection crash
reject = (!callback || typeof callback !== "function") ? reject : resolve;
callback = callback || (() => {});
steamID64 = _parseParam(steamID64);
_parseXML(`https://steamcommunity.com/profiles/${steamID64}`)
.then(res => {
resolve(res);
callback(null, res);
})
.catch(err => {
reject(err);
callback(err, null);
});
});
};
/**
* Get the full information of a user as Object by their custom profile url or full URL
* @param {String} customURL Custom ID or full URL of the user as String
* @param {function(string, fullProfileInfoObject)} [callback] Optional: Called with `err` (String) and `info` (Object) parameters on completion
* @return {Promise.<fullProfileInfoObject>} Resolves with fullInfo object on success or rejects with error string on failure
*/
module.exports.customUrlToFullInfo = (customURL, callback) => {
return new Promise((resolve, reject) => {
// Hack to support Promises & Callbacks: Resolve errors instead of rejecting them when callback is defined to prevent UnhandledPromiseRejection crash
reject = (!callback || typeof callback !== "function") ? reject : resolve;
callback = callback || (() => {});
customURL = _parseParam(customURL);
_parseXML(`https://steamcommunity.com/id/${customURL}`)
.then(res => {
resolve(res);
callback(null, res);
})
.catch(err => {
reject(err);
callback(err, null);
});
});
};
/**
* Get the group64ID of a group as String by groupURL or full URL
* @param {String} groupURL Custom Name of the group or full URL as String
* @param {function(string, string)} [callback] Optional: Called with `err` (String) and `groupID64` (String) parameters on completion
* @returns {Promise.<string>} Resolves with groupID64 on success or rejects with error on failure
*/
module.exports.groupUrlToGroupID64 = (groupURL, callback) => {
return new Promise((resolve, reject) => {
// Hack to support Promises & Callbacks: Resolve errors instead of rejecting them when callback is defined to prevent UnhandledPromiseRejection crash
reject = (!callback || typeof callback !== "function") ? reject : resolve;
callback = callback || (() => {});
groupURL = _parseParam(groupURL);
_parseXML(`https://steamcommunity.com/groups/${groupURL}/memberslistxml`)
.then(res => {
resolve(res.groupID64[0]);
callback(null, res.groupID64[0]);
})
.catch(err => {
reject(err);
callback(err, null);
});
});
};
/**
* Get the full information of a group as Object by groupURL or full URL
* @param {String} groupURL Custom Name of the group or full URL as String
* @param {function(string, fullGroupInfoObject)} [callback] Optional: Called with `err` (String) and `info` (Object) parameters on completion
* @returns {Promise.<fullGroupInfoObject>} Resolves with fullInfo object on success or rejects with error string on failure
*/
module.exports.groupUrlToFullInfo = (groupURL, callback) => {
return new Promise((resolve, reject) => {
// Hack to support Promises & Callbacks: Resolve errors instead of rejecting them when callback is defined to prevent UnhandledPromiseRejection crash
reject = (!callback || typeof callback !== "function") ? reject : resolve;
callback = callback || (() => {});
groupURL = _parseParam(groupURL);
_parseXML(`https://steamcommunity.com/groups/${groupURL}/memberslistxml`)
.then(res => {
resolve(res);
callback(null, res);
})
.catch(err => {
reject(err);
callback(err, null);
});
});
};
/**
* Checks if the provided ID or full URL points to a valid sharedfile
* @param {String} sharedfileID Sharedfile ID or full sharedfile URL
* @param {function(string, boolean)} [callback] Optional: Called with `err` (String) and `isValid` (Boolean) parameters on completion
* @returns {Promise.<boolean>} Resolves with `isValid` boolean on success or rejects with error string on failure
*/
module.exports.isValidSharedfileID = (sharedfileID, callback) => {
return new Promise((resolve, reject) => {
// Hack to support Promises & Callbacks: Resolve errors instead of rejecting them when callback is defined to prevent UnhandledPromiseRejection crash
reject = (!callback || typeof callback !== "function") ? reject : resolve;
callback = callback || (() => {});
// Precede sharedfileID with URL if only the ID was provided
if (!sharedfileID.includes("steamcommunity.com")) sharedfileID = "https://steamcommunity.com/sharedfiles/filedetails/?id=" + sharedfileID;
try {
let output = "";
require("https").get(sharedfileID, (res) => {
res.on("data", (chunk) => output += chunk); // Append each chunk to output
res.on("end", () => {
// Check if output contains an error msg
let isInvalid = output.includes("There was a problem accessing the item") || output.includes("That item does not exist");
resolve(!isInvalid);
callback(null, !isInvalid);
});
});
} catch (err) {
reject(err);
callback(err, null);
}
});
};