scf-api
Version:
An SCF API Client for NodeJS
1,400 lines (1,254 loc) • 35.6 kB
JavaScript
'use strict';
var axios = require('axios');
class APIError extends Error {
constructor(message, data){
super(message);
this.name = "SCF API Error";
this.data = data;
this.type = "APIError";
}
}
const Args = {
GET: "GET",
POST: "POST",
};
class Bridge {
/**
* @type {import('../../index').default}
*/
#client;
#section = "bridge";
constructor(client) {
this.#client = client;
}
/**
* Links a Discord account to a Hypixel account via bridge verification.
* @param {string} uuid
* @param {string} discord_id
*/
async link(discord_id, uuid) {
await this.#client.sendAPIRequest(this.#section, "link", "POST", [
{
name: "discord_id",
value: discord_id,
type: Args.POST,
},
{
name: "uuid",
value: uuid,
type: Args.POST,
},
]);
}
/**
* Returns the information about the linked user.
* @param {string|null} uuid
* @param {string|null} discord_id
*/
async getLinked(uuid = null, discord_id = null) {
let args = [];
if(uuid){
args.push({
name: "uuid",
value: uuid,
type: Args.GET,
});
}
if(discord_id){
args.push({
name: "discord_id",
value: discord_id,
type: Args.GET,
});
}
let response = await this.#client.sendAPIRequest(this.#section, "getLinked", "GET", args);
return {
uuid: response.uuid,
discord_id: response.discord_id,
};
}
/**
* Sets the status of the bridge of the token.
* @param {string} connected
* @param {string} version
*/
async setStatus(connected, version) {
await this.#client.sendAPIRequest(this.#section, "setStatus", "POST", [
{
name: "connected",
value: connected,
type: Args.POST,
},
{
name: "version",
value: version,
type: Args.POST,
},
]);
}
/**
* Returns the status of the bridge of the token.
* @param {string} scf_id
*/
async getStatus(scf_id) {
let response = await this.#client.sendAPIRequest(this.#section, "getStatus", "GET", [
{
name: "scf_id",
value: scf_id,
type: Args.GET,
},
]);
return {
connected: response.status.connected,
version: response.status.version,
timestamp: response.status.timestamp
};
}
}
class Bridgelock {
/**
* @type {import('../../index').default}
*/
#client;
#section = "bridgelock";
constructor(client) {
this.#client = client;
}
/**
* Locks a user from using Guild Bridges.
* @param {string} uuid
* @param {string} moderator_id
* @param {string} reason
*/
async add(uuid, moderator_id, reason = "") {
await this.#client.sendAPIRequest(this.#section, "add", "POST", [
{
name: "uuid",
value: uuid,
type: Args.POST,
},
{
name: "moderator_id",
value: moderator_id,
type: Args.POST,
},
{
name: "reason",
value: reason,
type: Args.POST,
},
]);
}
/**
* Checks if a player is bridge locked.
* @param {string} uuid
*/
async check(uuid) {
let response = await this.#client.sendAPIRequest(this.#section, "check", "GET", [
{
name: "uuid",
value: uuid,
type: Args.GET,
},
]);
return {
locked: response?.data?.locked ?? false,
info: {
lock_id: response?.data?.info?.lock_id ?? null,
moderator_id: response?.data?.info?.moderator ?? null,
reason: response?.data?.info?.reason ?? null,
timestamp: response?.data?.info?.timestamp ?? null,
}
};
}
/**
* Removes the restriction on using the bridges.
* @param {string} uuid
*/
async remove(uuid) {
await this.#client.sendAPIRequest(this.#section, "remove", "POST", [
{
name: "uuid",
value: uuid,
type: Args.POST,
},
]);
}
}
class Experimental {
/**
* @type {import('../../index').default}
*/
#client;
#section = "experimental";
constructor(client) {
this.#client = client;
}
/**
* AI moderation for player messages.
* @param {string} message
*/
async moderateMessage(message) {
let response = await this.#client.sendAPIRequest(this.#section, "moderateMessage", "POST", [
{
name: "message",
value: message,
type: Args.POST,
},
]);
return {
action: response.action ?? "allow",
fallback: response.fallback ?? false,
};
}
/**
* Saves the fact that the player was invited to the guild.
* @param {string} uuid
*/
async saveInvite(uuid) {
await this.#client.sendAPIRequest(this.#section, "saveInvite", "POST", [
{
name: "uuid",
value: uuid,
type: Args.POST,
},
]);
}
/**
* Checks if a player UUID was already invited to the guild.
* @param {string} uuid
*/
async wasInvited(uuid) {
let response = await this.#client.sendAPIRequest(this.#section, "wasInvited", "GET", [
{
name: "uuid",
value: uuid,
type: Args.GET,
},
]);
return response.saved ?? false;
}
}
class GTW {
/**
* @type {import('../../index').default}
*/
#client;
#section = "gtw";
constructor(client) {
this.#client = client;
}
/**
* Generates hints for a provided word.
* @param {string} word
*/
async start(word) {
let response = await this.#client.sendAPIRequest(this.#section, "start", "GET", [
{
name: "word",
value: word,
type: Args.GET,
},
]);
return {
description: response.description ?? "",
hints: response.hints ?? [],
};
}
/**
* @typedef {Object} GTWPlayer
* @property {string} discord_id
* @property {number} total
* @typedef {Object} GTWLeaderboard
* @property {GTWPlayer[]} weekly
* @property {GTWPlayer[]} overall
* @typedef {Object} GTWTop
* @property {GTWLeaderboard} score
* @property {GTWLeaderboard} rounds
*
* Returns Guess The Word leaderboards.
* @returns {Promise<GTWTop>}
*/
async getTop() {
let response = await this.#client.sendAPIRequest(this.#section, "getTop", "GET", []);
return {
score: {
weekly: response?.top?.score?.weekly ?? [],
overall: response?.top?.score?.overall ?? [],
},
rounds: {
weekly: response?.top?.rounds?.weekly ?? [],
overall: response?.top?.rounds?.overall ?? [],
}
};
}
/**
* Awards points for Guess The Word minigame.
* @param {string} discord_id
* @param {number} points
*/
async awardPoints(discord_id, points) {
let response = await this.#client.sendAPIRequest(this.#section, "awardPoints", "POST", [
{
name: "discord_id",
value: discord_id,
type: Args.POST,
},
{
name: "points",
value: points,
type: Args.POST,
},
]);
return {
game_id: response.game_id ?? null,
};
}
}
class Inactive {
/**
* @type {import('../../index').default}
*/
#client;
#section = "inactive";
constructor(client) {
this.#client = client;
}
/**
* Adds a player to the inactive list.
* @param {string} uuid
* @param {number} days
*/
async add(uuid, days) {
let response = await this.#client.sendAPIRequest(this.#section, "add", "POST", [
{
name: "uuid",
value: uuid,
type: Args.POST,
},
{
name: "days",
value: days,
type: Args.POST,
},
]);
return {
expires: response.expires ?? 0,
};
}
/**
* Removes a player from the inactive list.
* @param {string} uuid
*/
async remove(uuid) {
await this.#client.sendAPIRequest(this.#section, "remove", "POST", [
{
name: "uuid",
value: uuid,
type: Args.POST,
},
]);
}
/**
* Checks if a player is on the inactive list.
* @param {string} uuid
*/
async check(uuid) {
let response = await this.#client.sendAPIRequest(this.#section, "check", "GET", [
{
name: "uuid",
value: uuid,
type: Args.GET,
},
]);
return {
protected: response?.info?.state ?? false,
requested: response?.info?.requested ?? 0,
expired: response?.info?.expired ?? 0,
};
}
/**
* @typedef {Object} InactivePlayer
* @property {string} uuid
* @property {number} requested
* @property {number} expired
*
* Returns the list of all inactive players.
* @returns {Promise<InactivePlayer[]>}
*/
async list() {
let response = await this.#client.sendAPIRequest(this.#section, "list", "GET", []);
return response.list ?? [];
}
}
class Longpoll {
/**
* @type {import('../../index').default}
*/
#client;
#section = "longpoll";
constructor(client) {
this.#client = client;
}
/**
* Creates a longpoll request.
* @param {string} action
* @param {string} executor
* @param {object} payload
*/
async create(action, executor, payload) {
await this.#client.sendAPIRequest(this.#section, "create", "POST", [
{
name: "action",
value: action,
type: Args.POST,
},
{
name: "executor",
value: executor,
type: Args.POST,
},
{
name: "payload",
value: JSON.stringify(payload),
type: Args.POST,
},
]);
}
/**
* Removes a longpoll request.
* @param {string|number} request_id
*/
async remove(request_id) {
await this.#client.sendAPIRequest(this.#section, "remove", "POST", [
{
name: "request_id",
value: request_id,
type: Args.POST,
},
]);
}
/**
* @typedef {Object} LongpollRequest
* @property {number} rid
* @property {string} action
* @property {object} data
*
* Returns the list of longpoll requests to be handled.
* @returns {Promise<LongpollRequest[]>}
*/
async getApplicable() {
let response = await this.#client.sendAPIRequest(this.#section, "getApplicable", "GET", []);
return response.requests ?? [];
}
}
class Minigames {
/**
* @type {import('../../index').default}
*/
#client;
#section = "minigames";
constructor(client) {
this.#client = client;
}
// TODO: Implement authorizations mechanism for games
// Put hold on user's funds, and subtract/remove hold on win
// Put a hold on user's game ID, so that it doesn't
// subtract if something goes wrong, only when game is completed
// successfully.
/**
* Updates coin balance for a profile.
* @param {string} discord_id
* @param {number} amount
*/
async updateCoins(discord_id, amount) {
let negative = amount < 0;
amount = Math.abs(amount);
await this.#client.sendAPIRequest(this.#section, "updateCoins", "POST", [
{
name: "discord_id",
value: discord_id,
type: Args.POST,
},
{
name: "amount",
value: amount,
type: Args.POST,
},
{
name: "negative",
value: negative ? 1 : 0,
type: Args.POST,
},
]);
}
/**
* Resets a specific cooldown timer for a user.
* @param {string} discord_id
* @param {string} cooldown
* @param {number} time
*/
async resetCooldown(discord_id, cooldown, time) {
await this.#client.sendAPIRequest(this.#section, "resetCooldown", "POST", [
{
name: "discord_id",
value: discord_id,
type: Args.POST,
},
{
name: "cooldown",
value: cooldown,
type: Args.POST,
},
{
name: "time",
value: time,
type: Args.POST,
},
]);
}
/**
* Logs a completed minigame outcome.
* @param {string} game_id
* @param {string} discord_id
* @param {string} game
* @param {number} bet
* @param {number} outcome
*/
async logOutcome(game_id, discord_id, game, bet, outcome) {
await this.#client.sendAPIRequest(this.#section, "logOutcome", "POST", [
{
name: "game_id",
value: game_id,
type: Args.POST,
},
{
name: "discord_id",
value: discord_id,
type: Args.POST,
},
{
name: "game",
value: game,
type: Args.POST,
},
{
name: "bet",
value: bet,
type: Args.POST,
},
{
name: "outcome",
value: outcome,
type: Args.POST,
},
]);
}
/**
* @typedef {Object} MinigameCoins
* @property {number} purse
* @property {number} bank
* @property {number} total
*
* @typedef {Object} MinigameCooldowns
* @property {string} work
* @property {string} crime
* @property {string} beg
* @property {string} social
*
* @typedef {Object} MinigamePlayer
* @property {string} discord_id
* @property {MinigameCoins} coins
* @property {MinigameCooldowns} cooldowns
*
* Returns top 10 minigame players, sorted by networth.
* @returns {Promise<MinigamePlayer[]>}
*/
async getTop() {
let response = await this.#client.sendAPIRequest(this.#section, "getTop", "GET", []);
return response.top ?? [];
}
/**
*
* Returns the minigame profile for a Discord ID.
* @param {string} discord_id
* @returns {Promise<MinigamePlayer>}
*/
async getProfile(discord_id) {
let response = await this.#client.sendAPIRequest(this.#section, "getProfile", "GET", [
{
name: "discord_id",
value: discord_id,
type: Args.GET,
},
]);
return response.profile ?? {};
}
/**
* Transfers coins between bank and purse.
* @param {string} discord_id
* @param {number} amount
* @param {boolean} withdraw
*/
async bankTransfer(discord_id, amount, withdraw = false) {
await this.#client.sendAPIRequest(this.#section, "bankTransfer", "POST", [
{
name: "discord_id",
value: discord_id,
type: Args.POST,
},
{
name: "amount",
value: amount,
type: Args.POST,
},
{
name: "withdraw",
value: withdraw ? 1 : 0,
type: Args.POST,
},
]);
}
}
class Score {
/**
* @type {import('../../index').default}
*/
#client;
#section = "score";
constructor(client) {
this.#client = client;
}
/**
* @typedef {Object} ScorePlaceEntry
* @property {number} place
* @property {number} score
* @property {string} nick
*
* @typedef {Object} PlayerScore
* @property {string} uuid
* @property {number} score
* @property {string} nick
*/
/**
* Returns the score and the place of a user in the guild of the token this week.
* @param {string} uuid
* @param {boolean} overall
* @returns {Promise<ScorePlaceEntry>}
*/
async getCutoff(uuid, overall = false) {
let response = await this.#client.sendAPIRequest(this.#section, "getCutoff", "GET", [
{
name: "uuid",
value: uuid,
type: Args.GET,
},
{
name: "overall",
value: overall ? 1 : 0,
type: Args.GET,
},
]);
return {
place: response.place ?? 0,
score: response.score ?? 0,
nick: response.nick ?? "",
};
}
/**
* Returns the score and the place of a user in the guild of the token in the past 7 days.
* @param {string} uuid
* @param {boolean} overall
* @returns {Promise<ScorePlaceEntry>}
*/
async getRolling(uuid, overall = false) {
let response = await this.#client.sendAPIRequest(this.#section, "getRolling", "GET", [
{
name: "uuid",
value: uuid,
type: Args.GET,
},
{
name: "overall",
value: overall ? 1 : 0,
type: Args.GET,
},
]);
return {
place: response.place ?? 0,
score: response.score ?? 0,
nick: response.nick ?? "",
};
}
/**
* Logs the information about a sent guild message.
* @param {string} uuid
* @param {string} nick
* @param {string} guild_id
*/
async saveMessage(uuid, nick, guild_id) {
await this.#client.sendAPIRequest(this.#section, "saveMessage", "POST", [
{
name: "uuid",
value: uuid,
type: Args.POST,
},
{
name: "nick",
value: nick,
type: Args.POST,
},
{
name: "guild_id",
value: guild_id,
type: Args.POST,
},
]);
}
/**
* Returns the top players in a guild based on their score.
* @param {string|null} guild_id
* @returns {Promise<{total: number, list: PlayerScore[]}>}
*/
async getTop(guild_id = null) {
let args = [];
if (guild_id) {
args.push({
name: "guild_id",
value: guild_id,
type: Args.GET,
});
}
let response = await this.#client.sendAPIRequest(this.#section, "getTop", "GET", args);
return {
total: response.total ?? 0,
list: response.players ?? [],
};
}
/**
* This method is unreliable. Only use it when you know what you are doing!
* Returns the sum of all player entries starting from a specific period.
* @param {string} uuid
* @param {string} type
* @param {string} period_id
* @returns {Promise<{
* uuid: string,
* nick: string,
* guild_id: string,
* messages: string,
* score: string,
* last_message: string,
* }>}
*/
async getPlayerSummary(uuid, type, period_id) {
let response = await this.#client.sendAPIRequest(this.#section, "getPlayerSummary", "GET", [
{
name: "uuid",
value: uuid,
type: Args.GET,
},
{
name: "type",
value: type,
type: Args.GET,
},
{
name: "period_id",
value: period_id,
type: Args.GET,
},
]);
return response.entry ?? {};
}
/**
* This method is unreliable. Only use it when you know what you are doing!
* Returns the needed player entry.
* @param {string} uuid - The UUID of the user.
* @param {string} type - A type of a record - "hour", "day", or "week".
* @param {string} period_id - An ID of a period to get the entry for.
* @returns {Promise<{
* uuid: string,
* nick: string,
* guild_id: string,
* messages: string,
* score: string,
* last_message: string,
* }>}
*/
async getPlayerEntry(uuid, type, period_id) {
let response = await this.#client.sendAPIRequest(this.#section, "getPlayerEntry", "GET", [
{
name: "uuid",
value: uuid,
type: Args.GET,
},
{
name: "type",
value: type,
type: Args.GET,
},
{
name: "period_id",
value: period_id,
type: Args.GET,
},
]);
return response.entry ?? {};
}
}
class Server {
/**
* @type {import('../../index').default}
*/
#client;
#section = "server";
constructor(client) {
this.#client = client;
}
/**
* Blacklists user from SCF Services.
* @param {string} uuid
* @param {string|null} reason
*/
async addBlacklist(uuid, reason = null) {
await this.#client.sendAPIRequest(this.#section, "addBlacklist", "POST", [
{
name: "uuid",
value: uuid,
type: Args.POST,
},
{
name: "reason",
value: reason,
type: Args.POST,
},
]);
}
/**
* Removes user's SCF blacklist.
* @param {string} uuid
*/
async removeBlacklist(uuid) {
await this.#client.sendAPIRequest(this.#section, "removeBlacklist", "POST", [
{
name: "uuid",
value: uuid,
type: Args.POST,
},
]);
}
/**
* Checks if a player is blacklisted from SCF Services.
* @param {string} uuid
*/
async isBlacklisted(uuid) {
let response = await this.#client.sendAPIRequest(this.#section, "isBlacklisted", "GET", [
{
name: "uuid",
value: uuid,
type: Args.GET,
},
]);
return {
banned: response.banned ?? false,
reason: response.reason ?? "N/A"
};
}
/**
* Verifies user in SCF Discord.
* @param {string} discord_id
* @param {string} uuid
*/
async verify(discord_id, uuid) {
await this.#client.sendAPIRequest(this.#section, "verify", "POST", [
{
name: "discord_id",
value: discord_id,
type: Args.POST,
},
{
name: "uuid",
value: uuid,
type: Args.POST,
},
]);
}
/**
* Removes user verification status in SCF Discord.
* @param {string} uuid
*/
async unverify(uuid) {
await this.#client.sendAPIRequest(this.#section, "unverify", "POST", [
{
name: "uuid",
value: uuid,
type: Args.POST,
},
]);
}
/**
* Returns the information about the linked user.
* @param {string|null} discord_id
* @param {string|null} uuid
*/
async getVerified(discord_id = null, uuid = null) {
let args = [];
if(uuid){
args.push({
name: "uuid",
value: uuid,
type: Args.GET,
});
}
if(discord_id){
args.push({
name: "discord_id",
value: discord_id,
type: Args.GET,
});
}
let response = await this.#client.sendAPIRequest(this.#section, "getVerified", "GET", args);
return {
uuid: response.uuid,
discord_id: response.discord_id
};
}
}
class Staff {
/**
* @type {import('../../index').default}
*/
#client;
#section = "staff";
constructor(client) {
this.#client = client;
}
/**
* Creates a staff log entry.
* @param {string} actor
* @param {string} action
* @param {string} affected
* @param {string} description
* @returns {Promise<{id: string}>}
*/
async createLog(actor, action, affected = "", description = "") {
let response = await this.#client.sendAPIRequest(this.#section, "createLog", "POST", [
{
name: "actor",
value: actor,
type: Args.POST,
},
{
name: "action",
value: action,
type: Args.POST,
},
{
name: "affected",
value: affected,
type: Args.POST,
},
{
name: "description",
value: description,
type: Args.POST,
},
]);
return {
id: response.id ?? "",
};
}
/**
* Approves a staff log entry.
* @param {string} id
* @param {string} reviewer
*/
async approveLog(id, reviewer) {
await this.#client.sendAPIRequest(this.#section, "approveLog", "POST", [
{
name: "id",
value: id,
type: Args.POST,
},
{
name: "reviewer",
value: reviewer,
type: Args.POST,
},
]);
}
/**
* Denies (removes) a staff log entry.
* @param {string} id
*/
async denyLog(id) {
await this.#client.sendAPIRequest(this.#section, "denyLog", "POST", [
{
name: "id",
value: id,
type: Args.POST,
},
]);
}
/**
* @typedef {Object} StaffLog
* @property {number} action_id
* @property {string} action
* @property {string} affected
* @property {string} description
* @property {string} timestamp
* @property {string} approved_by
*
* Returns staff log entries filtered by actor.
* @param {string} actor
* @returns {Promise<StaffLog[]>}
*/
async getLogs(actor) {
let response = await this.#client.sendAPIRequest(this.#section, "getLogs", "GET", [
{
name: "actor",
value: actor,
type: Args.GET,
},
]);
return response.actions ?? [];
}
}
class Stats {
/**
* @type {import('../../index').default}
*/
#client;
#section = "stats";
constructor(client) {
this.#client = client;
}
/**
* This method is unreliable. Only use it when you know what you are doing!
* Returns guild player statistics over time.
* @returns {Promise<{
* weeks: string[],
* points: Object,
* guilds: Object
* }>}
*/
async getPlayerStats() {
let response = await this.#client.sendAPIRequest(this.#section, "getPlayerStats", "GET", [], false);
return {
weeks: response.weeks ?? [],
points: response.points ?? {},
guilds: response.guilds ?? {},
};
}
/**
* This method is unreliable. Only use it when you know what you are doing!
* Returns hourly message statistics for guilds.
* @returns {Promise<{points: Object, guilds: Object}>}
*/
async getHourlyStats() {
let response = await this.#client.sendAPIRequest(this.#section, "getHourlyStats", "GET", [], false);
return {
points: response.points ?? {},
guilds: response.guilds ?? {},
};
}
/**
* Returns weekly guild statistics.
* @returns {Promise<{weeks: string[], points: Object, guilds: Object}>}
*/
async getWeeklyStats() {
let response = await this.#client.sendAPIRequest(this.#section, "getWeeklyStats", "GET", [], false);
return {
weeks: response.weeks ?? [],
points: response.points ?? {},
guilds: response.guilds ?? {},
};
}
}
class Token {
/**
* @type {import('../../index').default}
*/
#client;
#section = "token";
constructor(client) {
this.#client = client;
}
/**
* Returns an SCF Token for the provided Discord Token.
*/
async auth(token) {
let response = await this.#client.sendAPIRequest(
this.#section,
"auth",
"POST",
[
{
name: "token",
value: token,
type: Args.POST,
},
],
false
);
return {
token: response.token,
owner: response.owner,
};
}
/**
* Issues an SCF Token for the provided SCF ID.
*/
async issue(owner) {
let response = await this.#client.sendAPIRequest(this.#section, "issue", "POST", [
{
name: "owner",
value: owner,
type: Args.POST,
},
]);
return {
token: response.token,
};
}
/**
* Returns the information about the used API token.
*/
async me() {
let response = await this.#client.sendAPIRequest(this.#section, "me", "GET", []);
return {
scf_id: response.information.scf_id,
info: {
name: response.information.name,
guild_id: response.information.guild_id,
type: response.information.type,
features: response.information.features,
bot_id: response.information.bot_id,
},
};
}
}
// Utils
class SCFAPIClient {
#provider;
#discord_token;
#scf_token;
#features = {};
// Sections
API = {
bridge: new Bridge(this),
bridgelock: new Bridgelock(this),
experimental: new Experimental(this),
gtw: new GTW(this),
inactive: new Inactive(this),
longpoll: new Longpoll(this),
minigames: new Minigames(this),
score: new Score(this),
server: new Server(this),
staff: new Staff(this),
stats: new Stats(this),
token: new Token(this),
};
/**
*
* @param {String} provider
* @param {?String} discord_token
* @param {?String} scf_token
*/
constructor(provider, discord_token = null, scf_token = null) {
this.#provider = provider;
if (!discord_token && !scf_token) {
throw new APIError("Either Discord Token or SCF Token must be provided.", {
type: "internal",
});
}
this.#discord_token = discord_token;
this.#scf_token = scf_token;
}
async sendAPIRequest(section, method, http_method, params, auth = true) {
try {
const provider = new URL(this.#provider);
provider.searchParams.append("method", `${section}.${method}`);
let config = {
method: http_method,
headers: {
"User-Agent": "SCF-API-Client",
"Content-Type": "application/json",
},
};
for (const param of params) {
if (param.type == Args.GET) {
provider.searchParams.append(param.name, param.value);
}
if (param.type == Args.POST) {
if (!config.data) config.data = {};
config.data[param.name] = param.value;
}
}
config.url = provider.href;
if (auth) {
let token = await this.getToken();
config.headers["Authorization"] = `Bearer ${token}`;
}
if (this.#features.test) {
config.params = Object.fromEntries(provider.searchParams);
this.#features.test(config);
return;
}
let response;
try {
response = await axios(config);
} catch (error) {
throw new APIError("Failed to send API request.", {
type: "request_failed",
axios: error,
});
}
if (!response?.data) {
throw new APIError("API has returned no data.", {
type: "request_failed",
axios: response,
});
}
let data = response.data;
if (data.code && !data.success) {
throw new APIError(data.message, {
type: data.code,
axios: response,
});
}
return data;
} catch (e) {
if ((e instanceof APIError) && this.#features.error) {
this.#features.error(e);
}
throw e;
}
}
async getToken() {
if (!this.#scf_token) {
await this.updateToken();
}
return this.#scf_token;
}
async updateToken() {
if (!this.#discord_token) {
throw new APIError("Discord Token is required to authorize.");
}
try {
let response = await this.API.token.auth(this.#discord_token);
this.#scf_token = response.token;
} catch (e) {
if (e?.type == "APIError") {
console.log(e);
}
}
}
testMode(callback) {
this.#features.test = callback;
}
errorHandler(callback){
this.#features.error = callback;
}
}
module.exports = SCFAPIClient;