Forge-Media/teamspeak-bot

View on GitHub
helpers/riotHelper.js

Summary

Maintainability
D
1 day
Test Coverage
/**
 * This is a thin wrapper around the Riot Games API,
 * which provides request methods and error handling
 *
 * @version 1.0
 * @type {class}
 * @param {string} botname - Name of the bot (used for logging)
 * @property {object} config - Contains config settings for your Steam Bot
 */

const fetch = require("node-fetch");

const regionList = ["BR1", "EUN1", "EUW1", "JP1", "KR", "LA1", "LA2", "NA1", "OC1", "RU", "TR1"];

class riotHelper {
    constructor(config, botname, firebaseHelper) {
        this.name = botname;
        this.config = config;
        this.db = firebaseHelper;
        this.fetchHeader = {};
        this.init();
    }

    async init() {
        if (this.config.api_key) {
            this.fetchHeader = {
                "X-Riot-Token": this.config.api_key,
            };
        } else {
            console.error(`${this.name}:`, "Riot-Games API Key missing!");
        }

        // Check connection to Riot API
        try {
            let summoner = await this.getSummoner(null, "FugiTive Legacy", "euw1");
            if (summoner.name) {
                console.info(`${this.name}:`, "Riot-API connection is Ready");
            }
        } catch (e) {
            console.error(e);
            process.exit(1);
        }
    }

    /**
     * Returns a summoner object which contains the summoners name, account ID, level and more
     *
     * @version 1.0
     *
     * @memberof riotHelper
     * @param    {String} id - (Optional) Summoner's encrypted account ID
     * @param    {String} name - Summoner's name
     * @param    {String} region - Summoner's region for api url
     * @returns {Promise.<data>} - data contains summoner as an object
     */
    async getSummoner(id, name, region) {
        if (!name && !id) {
            return new Error("No Summoner Name or ID provided");
        }

        if (!region) {
            return new Error("No region provided, try e.g. [EUW1, EUN1, NA1, JP1]");
        }

        if (!regionList.includes(region.toUpperCase())) {
            return new Error("Invalid region");
        }

        let URL = null;

        // Set correct url, based on getByName or getByID
        if (name && !id) {
            let summonerName = this.formateSummonerName(name);
            URL = `https://${region.toLowerCase()}.${this.config.summoner_api_url}/by-name/${summonerName}`;
        } else if (id) {
            URL = `https://${region.toLowerCase()}.${this.config.summoner_api_url}/by-account/${id}`;
        }

        // console.log(URL);

        // Fetch API response, check for errors and return the summoner as a object
        try {
            let response = await fetch(URL, { method: "GET", headers: this.fetchHeader });
            response = this.checkStatus(response);
            return await response.json();
        } catch (e) {
            if (e.name === "AbortError") {
                console.error("request was aborted");
                return null;
            } else {
                console.error(`Error Type: ${e.type}`);
                console.error(`Error message: ${e.message}`);
                return null;
            }
        }
    }

    /**
     * Returns a summoner's [solo/duo queue rank / flex queue rank] as an array of objects
     *
     * @version 1.0
     *
     * @memberof riotHelper
     * @param    {String} id - Summoner's encrypted account ID
     * @param    {String} region - Summoner's region for api url
     * @returns {Promise.<data>} - data contains summoner rank(s) as an object
     */
    async getSummonerLeagues(id, region) {
        if (!id && !region) {
            return new Error("No Summoner ID or region");
        }

        if (!regionList.includes(region.toUpperCase())) {
            return new Error("Invalid region");
        }

        const URL = `https://${region}.${this.config.league_api_url}/entries/by-summoner/${id}`;

        try {
            let response = await fetch(URL, { method: "GET", headers: this.fetchHeader });
            response = this.checkStatus(response);
            return await response.json();
        } catch (e) {
            if (e.name === "AbortError") {
                console.error("request was aborted");
                return null;
            } else {
                console.error(`Error Type: ${e.type}`);
                console.error(`Error message: ${e.message}`);
                return null;
            }
        }
    }

    /**
     * Checks if a user with passed 'summoner name' exists in the firebase database already or not
     *
     * @version 1.0
     * @memberof riotHelper
     * @param    {String} name - Summoner name
     * @param    {Object} invoker - (Optional) Teamspeak user who made request
     * @returns {Promise.<boolean>}
     */
    async isRegisteredBySummonerName(summonerName) {
        // Summoner name comes in pre-formated, from getSummoner()
        // let summonerName = this.formateSummonerName(name);
        let userRef = this.db.collection("riot-users").where("summoner_name", "==", summonerName);
        try {
            let getDoc = await userRef.get();
            if (getDoc.empty) {
                return false; // Not registered
            } else {
                return true; // Is registered
            }
        } catch (e) {
            console.error("Error checking for database entry: ", e.message);
        }
    }

    /**
     * Checks if a user with passed 'ts_uid' exists in firebase database already or not
     *
     * @version 1.0
     * @memberof riotHelper
     * @param    {String} ts_uid - A Teamspeak 3 user's unique ID (Should be the invokers ID)
     * @param    {Object} invoker - (Optional) Teamspeak user who made request
     * @returns {Promise.<boolean>}
     */
    async isRegisteredByUid(ts_uid) {
        let userRef = this.db.collection("riot-users").where("ts_uid", "==", ts_uid);
        try {
            let getDoc = await userRef.get();
            if (getDoc.empty) {
                return false; // Not Registered
            } else {
                return true; // Is registered
            }
        } catch (e) {
            console.error("Error checking for database entry: ", e.message);
        }
    }

    /**
     * Retrieve a registered user from the firebase database by Teamspeak UID
     *
     * @version 1.0
     * @memberof riotHelper
     * @param    {String} ts_uid - A Teamspeak 3 user's unique ID (Should be the invokers ID)
     * @returns {Promise.<data>}
     */
    async getRegisterdUserByUid(ts_uid) {
        let userRef = this.db.collection("riot-users").where("ts_uid", "==", ts_uid);
        try {
            let getDoc = await userRef.get();
            if (getDoc.empty) {
                return null;
            } else {
                return getDoc.docs[0];
            }
        } catch (e) {
            console.error("Error getting database entry: ", e.message);
        }
    }

    /**
     * Retrieve all registered users from the firebase database
     *
     * @version 1.0
     * @memberof riotHelper
     * @returns {Promise.<data>}
     */
    async getAllRegisterdUsers() {
        let dbRef = this.db.collection("riot-users");

        try {
            let getDb = await dbRef.get();
            if (getDb.empty) {
                console.log("Database empty!");
                return null;
            } else {
                return getDb.docs;
            }
        } catch (e) {
            console.log("Error getting database entries: ", e.message);
        }
    }

    /**
     * Registers a new user into the firebase database
     *
     * @version 1.0
     * @memberof riotHelper
     * @param    {Object} client - A client object which follows the database collection schema
     * @returns {Promise.<>}
     */
    async registerUser(client) {
        let refData = this.db.collection("riot-users").doc(client.id);
        try {
            await refData.set(client.data);
        } catch (e) {
            return e.message;
        }
    }

    /**
     * Deregisters an existing user from the firebase database
     *
     * @version 1.0
     * @memberof riotHelper
     * @param    {String} id - Summoner's encrypted account ID
     * @returns {Promise.<boolean>}
     */
    async deregisterUser(id) {
        let userRef = this.db.collection("riot-users").doc(id);
        try {
            await userRef.delete();
        } catch (e) {
            return e.message;
        }
    }

    /**
     * Checks the status of an http API request response, returns the response if 200 OK, else throws a details error message
     *
     * @version 1.0
     *
     * @memberof riotHelper
     * @param    {Object} res - API response prior to json(ifiying)
     * @returns {Object} - response if 200 OK
     */
    checkStatus(res) {
        if (res.ok) {
            if (res.status >= 200 && res.status < 300) {
                return res;
            } else {
                throw new fetch.FetchError(res.statusText, res.status);
            }
        } else {
            throw new fetch.FetchError(res.statusText, res.status);
        }
    }

    /**
     * Formats summoner name to lowercase and removes all spaces
     *
     * @version 1.0
     *
     * @memberof riotHelper
     * @param    {String} name - Summoner name
     * @returns {String} - Formated Summoner name
     */
    formateSummonerName(name) {
        let formatedName = name.toLowerCase();
        formatedName = formatedName.trim();
        return formatedName.replace(/\s/g, "");
    }
}

module.exports = riotHelper;