@meibot/unofficial-valorant-api
Version:
Library for the Unofficial VALORANT API by api.henrikdev.xyz
519 lines • 24.1 kB
JavaScript
import axios from "axios";
/**
* Base API endpoint
*/
const baseUrl = "https://api.henrikdev.xyz/valorant";
export default class {
token;
/**
* Images for every Rank
* @remarks
* You must call {@link initUtils} before using this!
*/
rankImages;
/**
* Images for every Valorant map
* @remarks
* You must call {@link initUtils} before using this!
*/
mapImages;
/**
* Create a new instance of the main API. All API calls are in this class
* @example
* Create a new instance
* ```js
* import _VAPI from "unofficial-valorant-api"
* const VAPI = new _VAPI("my super secret token")
* ```
* @param token - (optional) The token, if you have one. Get one from the Discord server ({@link https://discord.gg/wXNMnqzvAD})
*/
constructor(token) {
this.token = token;
}
/**
* Creates {@link default.rankImages} and {@link default.mapImages} by pulling the images from {@link https://valorant-api.com}
* @remarks
* Must be called before using {@link default.rankImages} and {@link default.mapImages}
*/
async initUtils() {
const mapsReq = (await axios({ url: "https://valorant-api.com/v1/maps" }).catch(() => null))?.data?.data;
if (mapsReq) {
this.mapImages = {};
mapsReq.forEach((map) => (this.mapImages[map.displayName] = {
splash: map.splash,
minimap: map.displayIcon,
landscape: map.listViewIcon,
}));
}
const tiersReq = (await axios({ url: "https://valorant-api.com/v1/competitivetiers" }).catch(() => null))?.data?.data;
if (tiersReq) {
const capitalize = (string) => string.charAt(0).toUpperCase() + string.slice(1);
this.rankImages = {};
tiersReq[tiersReq.length - 1].tiers.forEach((rank) => (this.rankImages[capitalize(rank.tierName.toLowerCase())] = {
large: rank.largeIcon,
small: rank.smallIcon,
triangleUp: rank.rankTriangleUpIcon,
triangleDown: rank.rankTriangleDownIcon,
}));
}
}
/**
* @internal
* Parses the body of an axios response
*/
parseBody(body) {
if (body.errors)
return body.errors;
return body.status ? body.data : body;
}
/**
* @internal
* Main function to fetch from the API
* @typeParam dataType - The type of the response
* @param url - URl to fetch. Appended to the base url and automatically encoded
* @param searchParams - Any extra search params. Empty values will be filtered out
* @param config - Override the default axios config with custom params
* @returns Formatted response
*/
async fetch(url, searchParams, config = {}) {
// Format search params into `?something=like&this`
const queryParams = searchParams
? Object.keys(searchParams).reduce((acc, cur) => {
const value = searchParams[cur];
if (value === null || value === undefined)
return acc;
return acc === "" ? `?${cur}=${value}` : acc + `&${cur}=${value}`;
}, "")
: "";
// Main request
const req = await axios({
url: encodeURI(`${baseUrl}/${url}${queryParams}`),
responseType: "json",
headers: this.token
? { Authorization: this.token, "User-Agent": "unofficial-valorant-api/node.js/fuckinghell" }
: { "User-Agent": "unofficial-valorant-api/node.js/fuckinghell" },
...config,
}).catch(error => error);
// Formatting response
return {
status: req.response ? req.response.status : req.status,
data: req.response ? null : !req.config.headers["Content-Type"] ? this.parseBody(req.data) : req.data,
rateLimits: {
used: Number(req.response ? req.response.headers["x-ratelimit-limit"] : req.headers["x-ratelimit-limit"]),
remaining: Number(req.response ? req.response.headers["x-ratelimit-remaining"] : req.headers["x-ratelimit-remaining"]),
reset: Number(req.response ? req.response.headers["x-ratelimit-reset"] : req.headers["x-ratelimit-reset"]),
},
error: req.response ? this.parseBody(req.response.data) : null,
};
}
/**
* @internal
* Make sure each key has a non empty value
* @param input - Object to check for non empty values
* @throws TypeError - Only if there is a empty value to a key
*/
async validateArgs(input) {
Object.keys(input).forEach(key => {
if (input[key] === null || input[key] === undefined)
throw new TypeError(`Missing parameter: "${key}"`);
});
}
/**
* Get an image of a valorant crosshair by its code
* @example
* Load and write a crosshair to crosshair.png
* ```js
* import { writeFileSync } from "fs"
*
* const crosshair = await default.getCrosshair("0;s;1;P;c;5;o;1;d;1;z;3;0b;0;1b;0;S;c;4;o;1")
* writeFileSync("crosshair.png", crosshair.data)
* ```
* @param args.code - Valorant crosshair code
* @param args.size - (optional) Image size (default: `1024`)
* @returns The image of the crosshair as a {@link https://nodejs.org/api/buffer.html Buffer}
*/
async getCrosshair({ code, size }) {
this.validateArgs({ code });
return this.fetch("v1/crosshair/generate", { id: code, size }, {
responseType: "arraybuffer",
});
}
/**
* Get all announcements from the valorant website of a country
* @param args.countryCode - Country code of website
* @returns List of announcements from the valorant website
*/
async getAnnouncements({ countryCode, }) {
this.validateArgs({ countryCode });
return this.fetch(`v1/website/${countryCode}`);
}
/**
* Get all announcements from the valorant website of a country
* @param args.countryCode - Country code of website
* @returns List of announcements from the valorant website
* @depreciated Use {@link default.getAnnouncements} instead
*/
async getWebsite({ countryCode, category, }) {
this.validateArgs({ countryCode });
return this.fetch(`v1/website/${countryCode}`, { category });
}
/**
* Get information about valorant in a region, such as the client version, branch, and server version
* @param args.region - Region of valorant to get info about
* @returns Information about a regions valorant
*/
async getVersion({ region }) {
this.validateArgs({ region });
return this.fetch(`v1/version/${region}`);
}
/**
* Get all of the featured items in the current valorant store
* @returns Featured items in the current valorant store
*/
async getFeaturedItems({ version } = {}) {
return this.fetch(`${version || "v2"}/store-featured`);
}
/**
* Get a list of all the prices of every skin in the game
* @returns List of skin prices
*/
async getOffers({ version } = {}) {
return this.fetch(`${version || "v2"}/store-offers`);
}
/**
* Will get information about the current maintenances and incidents about a region
* @param args.region - Region to get info about
* @returns Info about undergoing maintenances and incidents in a region of valorant
*/
async getStatus({ region }) {
this.validateArgs({ region });
return this.fetch(`v1/status/${region}`);
}
/**
* Gets raw data for a match from the valorant API. (Not formatted, use only if you know what you are doing)
* @see {@link default.getMatch} for an easier response to use
* @param args.matchID - The match ID to get details about
* @param args.region - Region of the match
* @param args.queries - Extra queries. See {@link https://github.com/techchrism/valorant-api-docs/blob/trunk/docs/PVP%20Endpoints/GET%20MatchDetails_FetchMatchDetails.md documentation}
* @returns Information about the match
*/
async getRawMatchDetails({ matchID, region, queries }) {
this.validateArgs({ matchID, region });
return await this.fetch("v1/raw", null, {
data: { type: "matchdetails", value: matchID, region, ...queries },
method: "POST",
});
}
/**
* Gets raw data for a players match history from the valorant API. (Not formatted, use only if you know what you are doing)
* @see {@link default.getMatches} for an easier response to use
* @param args.puuid - The match ID to get details about
* @param args.region - Region of the player
* @param args.queries - Extra queries. See {@link https://github.com/techchrism/valorant-api-docs/blob/trunk/docs/PVP%20Endpoints/GET%20MatchHistory_FetchMatchHistory.md documentation}
* @returns Information about the players match history
*/
async getRawMatchHistory({ puuid, region, queries }) {
this.validateArgs({ puuid, region });
return await this.fetch("v1/raw", null, {
data: { type: "matchhistory", value: puuid, region, ...queries },
method: "POST",
});
}
/**
* Gets raw data for a players competitive updates (rr changes) from the valorant API. **(Not formatted, use only if you know what you are doing)**
* @see {@link default.getMMRHistory} for an easier response to use
* @param args.puuid - The match ID to get details about
* @param args.region - Region of the player
* @param args.queries - Extra queries. See {@link https://github.com/techchrism/valorant-api-docs/blob/trunk/docs/PVP%20Endpoints/GET%20MMR_FetchCompetitiveUpdates.md documentation}
* @returns Information about the players rr history
*/
async getRawCompetitiveUpdates({ puuid, region, queries }) {
this.validateArgs({ puuid, region });
return await this.fetch("v1/raw", null, {
data: { type: "mmr", value: puuid, region, ...queries },
method: "POST",
});
}
/**
* Gets raw data for a players mmr from the valorant API. **(Not formatted, use only if you know what you are doing)**
* @see {@link default.getMMR} for an easier response to use
* @param args.puuid - The match ID to get details about
* @param args.region - Region of the player
* @param args.queries - Extra queries. See {@link https://github.com/techchrism/valorant-api-docs/blob/trunk/docs/PVP%20Endpoints/GET%20MMR_FetchPlayer.md documentation}
* @returns Information about the players mmr
*/
async getRawMMR({ puuid, region, queries }) {
this.validateArgs({ puuid, region });
return await this.fetch("v1/raw", null, {
data: { type: "competitiveupdates", value: puuid, region, ...queries },
method: "POST",
});
}
/**
* Gets raw data from the valorant API. **(Not formatted, use only if you know what you are doing)**
* @param args.type - Type of data to return
* @param args.value - A players puuid if type is `mmr` or `competitiveupdates`, else a match id
* @param args.region - Region of the player or match
* @param args.queries
* @returns Either match details, a users patch history, a users mmr, or a users past rr changes
* @depreciated Use {@link default.getRawCompetitiveUpdates} {@link default.getRawMatchDetails} {@link default.getRawMatchHistory} {@link default.getRawMMR} instead
*/
async getRawData({ type, value, region, queries, }) {
this.validateArgs({ type, value, region });
return await this.fetch("v1/raw", null, {
data: { type, value, region, ...queries },
method: "POST",
});
}
/**
* Get a list of rr changes of a player by their Riot ID
* @param args.name - The Riot ID username of the player
* @param args.tag - The Riot tag username of the player
* @param args.region - The players region
* @return List of rr changes (recent competitive games)
*/
async getMMRHistory({ name, tag, region }) {
this.validateArgs({ name, tag, region });
return this.fetch(`v1/mmr-history/${region}/${name}/${tag}`);
}
/**
* Get a list of rr changes of a player by their PUUID
* @param args.puuid - The PUUID of the player
* @param args.region - The players region
* @return List of rr changes (recent competitive games)
*/
async getMMRHistoryByPUUID({ puuid, region }) {
this.validateArgs({ puuid, region });
return this.fetch(`v1/by-puuid/mmr-history/${region}/${puuid}`);
}
/**
* Get information about a match
* @param args.matchID - The matchs ID
* @returns Information about the match
*/
async getMatch({ matchID }) {
this.validateArgs({ matchID });
return this.fetch(`v2/match/${matchID}`);
}
/**
* Get the leaderboard of a region
* @remarks
* In order for player filtering to work, they must be Immortal or higher
* @param args.region - Region to get leaderboard from
* @param args.version - Can be `v1` or `v2`. Note: V2 does not support filters!
* @param args.start - (optional) Get 1000 leaderboard players starting from the given start value
* @param args.end - (optional) Limit the amount of leaderboard players returned
* @param args.riotID - (optional) Search for a specific player by their Riot ID
* @param args.riotID.name - The Riot IDs username
* @param args.riotID.tag - The Riot IDs tag
* @param args.puuid - (optional) Search for a specific player by their PUUID
* @param args.season - (optional) Get leaderboard from a specific season
* @returns Descending order of the highest ranked players. (Immortal and up)
* @throws TypeError - If both a riotID and puuid are supplied
*/
async getLeaderboard({ version, region, start, end, riotID, puuid, season, }) {
if (version === "v1") {
if (riotID && puuid)
throw new TypeError("Too many parameters: You can't search for a Riot ID and puuid at the same time, please decide between Riot ID and puuid");
}
else {
if (start || end)
throw new TypeError("Can't use start/end filters when using V2!");
}
this.validateArgs({ region });
return this.fetch(`${version || "v2"}/leaderboard/${region}`, { start, end, name: riotID?.name, tag: riotID?.tag, puuid, season });
}
/**
* Get all translations for every character, skin, map, ability, spray, charm, player card, player title, and more in the game
* @param args.locale - If this is set, instead of all translations, it will return just translations for this language
*/
async getTranslations({ locale } = {}) {
return this.fetch("v1/content", { locale });
}
/**
* Get all translations for every character, skin, map, ability, spray, charm, player card, player title, and more in the game
* @param args.locale - If this is set, instead of all translations, it will return just translations for this language
* @depreciated Use the new {@link default.getTranslations} instead
*/
async getContent({ locale } = {}) {
return this.fetch("v1/content", { locale });
}
/**
* Gets general info about a players rank by their Riot ID
* @remarks
* **Returns:**
* - Current rank and info about their rank
* - RR change on their last game
* - Their PUUID
* - Their peak rank from every season
* @param args.name - The Riot ID username of the player
* @param args.tag - The Riot ID tag of the player
* @param args.region - The region of the player
* @param args.seasonFilter - (optional) Filter results based on episode and act
* @param args.version - (optional) Change endpoint version
* @param args.filter - (optional) Same as seasonFilter. Only here for backwards compatibility
* @returns Information about a players mmr/rank
* @throws TypeError - If both filter and seasonFilter are set
*/
async getMMR({ name, tag, region, seasonFilter, version, }) {
if (version === "v1")
console.warn("v1 is outdated, please migrate to v2!");
this.validateArgs({ name, tag, region });
return this.fetch(`${version || "v2"}/mmr/${region}/${name}/${tag}`, { season: seasonFilter });
}
/**
* Gets general info about a players rank by their PUUID
* @remarks
* **Returns:**
* - Current rank and info about their rank
* - RR change on their last game
* - Their PUUID
* - Their peak rank from every season
* @param args.puuid - The PUUID of the player
* @param args.region - The region of the player
* @param args.seasonFilter - (optional) Filter results based on episode and act
* @param args.version - (optional) Change endpoint version
* @param args.filter - (optional) Same as seasonFilter. Only here for backwards compatibility
* @returns Information about a players mmr/rank
* @throws TypeError - If both filter and seasonFilter are set
*/
async getMMRByPUUID({ puuid, region, seasonFilter, version, }) {
if (version === "v1")
console.warn("v1 is outdated, please migrate to v2!");
this.validateArgs({ puuid, region });
return this.fetch(`${version || "v2"}/by-puuid/mmr/${region}/${puuid}`, { season: seasonFilter });
}
/**
* Gets the most recent 5 matches by a players Riot ID
* @remarks
* **Returns:**
* - Info about most recent 5 matches including:
* - Metadata info about the match such as length, time, map, score, etc
* - Information about every player including their PUUID, Riot ID, kills, ability usage, etc
* - Information about every round in the match such as plant/defuse info, etc
* - Information about every kill in the game including killer, victim, assist, etc
* @param args.name - The Riot ID username of the player
* @param args.tag - The Riot ID tag of the player
* @param args.region - The region of the player
* @param args.gamemodeFilter - Filter results based on gamemode
* @param args.mapFilter - Filter results based on map
* @param args.size - Return a specific amount of matches (1-10)
* @returns Info about a players last 5 matches
* @throws TypeError - Only if the size parameter is set and not between 1-10
*/
async getMatches({ name, tag, region, gamemodeFilter, mapFilter, size, }) {
this.validateArgs({ name, tag, region });
if (size && (size > 10 || size < 1))
throw new TypeError("Invalid size parameter. Size must be between 1-10!");
return this.fetch(`v3/matches/${region}/${name}/${tag}`, { mode: gamemodeFilter, map: mapFilter, size });
}
/**
* Gets the most recent 5 matches by a players PUUID
* @remarks
* **Returns:**
* - Info about most recent 5 matches including:
* - Metadata info about the match such as length, time, map, score, etc
* - Information about every player including their PUUID, Riot ID, kills, ability usage, etc
* - Information about every round in the match such as plant/defuse info, etc
* - Information about every kill in the game including killer, victim, assist, etc
* @param args.puuid - The PUUID username of the player
* @param args.region - The region of the player
* @param args.gamemodeFilter - Filter results based on gamemode
* @param args.mapFilter - Filter results based on map
* @param args.size - Return a specific amount of matches (1-10)
* @returns Info about a players last 5 matches
* @throws TypeError - Only if the size parameter is set and not between 1-10
*/
async getMatchesByPUUID({ puuid, region, gamemodeFilter, mapFilter, size, }) {
this.validateArgs({ name: puuid, region });
if (size && (size > 10 || size < 1))
throw new TypeError("Invalid size parameter. Size must be between 1-10!");
return this.fetch(`v3/by-puuid/matches/${region}/${puuid}`, { mode: gamemodeFilter, map: mapFilter, size });
}
/**
* Get general information about a player from their Riot ID
* @remarks
* **Returns:**
* - Their PUUID
* - Their region
* - Their account level
* - Their current card
* @param args.name - The Riot ID username of the player
* @param args.tag - The Riot ID tag of the player
* @param args.force - Force data update?
* @return General information on a players profile
*/
async getAccount({ name, tag, force }) {
this.validateArgs({ name, tag });
return this.fetch(`v1/account/${name}/${tag}`, { force });
}
/**
* Get general information about a player from their Riot ID
* @remarks
* **Returns:**
* - Their PUUID
* - Their region
* - Their account level
* - Their current card
* @param args.puuid The PUUID of the player
* @param args.force Force data update?
* @return General information on a players profile
*/
async getAccountByPUUID({ puuid, force }) {
this.validateArgs({ puuid });
return this.fetch(`v1/by-puuid/account/${puuid}`, { force });
}
/**
* Get all matches fetched matches from a player
* @remarks
* **Returns:**
* - The most important metadata
* - The most important stats
* - The team results
* @param args.name - The Riot ID username of the player
* @param args.tag - The Riot ID tag of the player
* @param args.region - The region of the player
* @param args.gamemodeFilter - Filter results based on gamemode
* @param args.mapFilter - Filter results based on map
* @param args.page - Return a specific page of all matches (can only be used with the "size" params)
* @param args.size - Return a specific amount of matches (can only be used with the "page" params)
* @return All fetched matches from a player
*/
async getLifetimeMatches({ name, tag, region, gamemodeFilter, mapFilter, page, size, }) {
this.validateArgs({ name, tag, region });
return this.fetch(`v1/lifetime/matches/${region}/${name}/${tag}:`, { mode: gamemodeFilter, map: mapFilter, page, size });
}
/**
* Get all matches fetched matches from a player
* @remarks
* **Returns:**
* - The most important metadata
* - The most important stats
* - The team results
* @param args.puuid The PUUID of the player
* @param args.region - The region of the player
* @param args.gamemodeFilter - Filter results based on gamemode
* @param args.mapFilter - Filter results based on map
* @param args.page - Return a specific page of all matches (can only be used with the "size" params)
* @param args.size - Return a specific amount of matches (can only be used with the "page" params)
* @return All fetched matches from a player
*/
async getLifetimeMatchesByPUUID({ puuid, region, gamemodeFilter, mapFilter, page, size, }) {
this.validateArgs({ puuid, region });
return this.fetch(`v1/by-puuid/lifetime/matches/${region}/${puuid}`, { gamemodeFilter, mapFilter, page, size });
}
/**
* Get esports schedule data
* @remarks
* **Returns:**
* - All scheduled esport games
* - Games from: https://valorantesports.com/schedule
* @param args.region - Filter for schedules games in this region
* @param args.league - Filter for schedules games in this league
* @return All scheduled esport games
*/
async getEsportsSchedule({ region, league }) {
return this.fetch("v1/esports/schedule", { region, league });
}
}
//# sourceMappingURL=vapi.js.map