UNPKG

doblox

Version:

Roblox and Discord integration

220 lines (190 loc) 5.19 kB
import * as axios from "axios"; import * as discord from 'discord.js'; const Axios = axios.default; type noblox = object | any; type ClientOptions = { provider: string }; const defaultClientOptions = { provider: 'bloxlink' }; type Provider = { baseURL: string, requests: number, per: number, handleData: Function }; const providers = { rover: { baseURL: 'https://verify.eryn.io/api/user/', requests: 60, per: 60 * 1000 }, bloxlink: { baseURL: 'https://api.blox.link/v1/user/', requests: 60, per: 60 * 1000, handleURL(user, userid, partial: boolean, options, doblox) { return `${this.baseURL}${userid}${options.guild && user instanceof discord.GuildMember ? `?guild=${user.guild.id}` : ''}`; }, handleData: async function(data, partial: boolean, user, options) { const id = options.guild ? data.matchingAccount || data.primaryAccount : data.primaryAccount; if (!id) return; if (partial) { return { id }; } else { return this.axios.get(`https://users.roblox.com/v1/users/${id}`) .then(res => { const data = res.data; return { username: data.name, id: data.id, description: data.description, createdAt: new Date(data.created) }; }); } }, handleError(response) { if (response.data && response.data.status == 'error') { if (response.data.error == 'This user is not linked with Bloxlink.') return undefined; else throw new Error(response.data.error); } throw response; } } }; const pify = require('pify'); const Limiter = require('limiter').RateLimiter; Limiter.prototype.asyncRemoveTokens = pify(Limiter.prototype.removeTokens); type UserResolvable = RobloxUser | discord.UserResolvable; /* * A reprensantation of a roblox user, when partial, id is the only value guaranteed. * @class RobloxUser */ class RobloxUser { username: string; id: string description: string; createdAt: Date partial: Boolean /** * @param {Object} data RobloxUser data * @param {Boolean} partial Whether its a partial */ constructor(data, partial: Boolean) { /** * Username of the user * @type {String} */ this.username = data.username; /** * ID of the user * @type {Number} */ this.id = data.id; /** * Description of the user * @type {String} */ this.description = data.description; /** * Date at which the user was created at * @type {Date} */ this.createdAt = data.createdAt; /** * Whether the data is partial * @type {Boolean} */ this.partial = partial; } } /** * A value that resolves to a discord user or roblox user * @typedef {RobloxUser | discord.UserResolvable} UserResolvable */ class UnkownUser extends ReferenceError { constructor() { super('Unkown user'); this.errno = 1; } errno: number } class InvallidPlayer extends TypeError { constructor() { super('Invallid player'); this.errno = 0; } errno: number } /** * Options for the client * @typedef {Object} ClientOptions * @property {String} provider */ /* Base client for api actions */ export class Client { noblox: noblox; client: discord.Client; options: ClientOptions; provider _RateLimit: typeof Limiter; providerAxios: axios.AxiosInstance axios: axios.AxiosInstance; /** * @param {noblox} noblox Your noblox module object, not required but kept for backwards compatibility. * @param {discord.Client} client A discord client * @param {ClientOptions} options Options for the client */ constructor(noblox: noblox | undefined, client: discord.Client, options: ClientOptions) { this.noblox = noblox; this.client = client; this.options = Object.assign({}, defaultClientOptions, options); this.provider = providers[this.options.provider]; if (!this.provider) throw new ReferenceError('No such provider'); this.providerAxios = Axios.create({ baseURL: this.provider.baseURL }); this.axios = Axios.create({}); this._RateLimit = new Limiter(); } /** * @param {discord.UserResolvable} user The discord user to get robloxUser of * @param {Boolean} partial Wether to return a partial * @param {Object} options Options to pass to the provider */ async getRobloxUser(user: discord.UserResolvable, partial: Boolean = false, options): Promise<RobloxUser | undefined> { let userid; let resolvedUser = this.client.users.resolve(user); if (!resolvedUser) { if (typeof user == 'string') { userid = user; } else { throw new UnkownUser(); } } else { userid = resolvedUser.id; }; await this._RateLimit.asyncRemoveTokens(1); return (typeof this.provider.handleURL == 'function' ? this.axios.get(this.provider.handleURL(user, userid, partial, options, this)) : this.providerAxios.get(userid)) .then(async response => { const data = response.data; if (data && data.status != 'ok') { throw response; } const userData = await this.provider.handleData.call(this, data, partial, user, options); if (!userData) return; return new RobloxUser(userData, partial); }) .catch(async (err) => { return this.provider.handleError.call(this, err.response || err); }); } }