diff --git a/extended-user-info-api/.gitignore b/extended-user-info-api/.gitignore index 2eea525..13dfa36 100644 --- a/extended-user-info-api/.gitignore +++ b/extended-user-info-api/.gitignore @@ -1 +1,2 @@ -.env \ No newline at end of file +.env +node_modules/ \ No newline at end of file diff --git a/extended-user-info-api/app.js b/extended-user-info-api/app.js index 134362d..0698da5 100644 --- a/extended-user-info-api/app.js +++ b/extended-user-info-api/app.js @@ -1,10 +1,10 @@ require('dotenv').config(); -const request = require('request'); const express = require('express'); +const axios = require('axios'); const path = require('path'); -var port = process.env.PORT || 8080; -var botToken = process.env.BOT_TOKEN; +const port = process.env.PORT || 8080; +const botToken = process.env.BOT_TOKEN; const app = express(); app.use(express.json()); @@ -17,51 +17,90 @@ app.get('/', function (req, res) { res.sendFile(path.join(__dirname, '/index.html')); }); -app.get("/:userIds", async (req, res) => { - const userIds = req.params.userIds.split(","); - const results = {}; +const userCache = {}; - const promises = userIds.map(async userId => { - const options = { - url: `https://discord.com/api/v10/users/${userId}`, - headers: { - 'Authorization': 'Bot ' + botToken - } - }; +const delay = ms => new Promise(resolve => setTimeout(resolve, ms)); - return new Promise((resolve, reject) => { - request(options, (error, response, body) => { - if (!error && response.statusCode == 200) { - var preuser = JSON.parse(body); - var user = { - "global_name": preuser.global_name, - "public_flags": preuser.public_flags, - "flags": preuser.flags, - "accent_color": preuser.accent_color, - "avatar_decoration": preuser.avatar_decoration, - "banner": preuser.banner, - "banner_color": preuser.banner_color, - }; - if (preuser.avatar_decoration == null) - user.avatar_decoration = null; - else - user.avatar_decoration = "https://cdn.discordapp.com/avatar-decorations/" + preuser.id + "/" + preuser.avatar_decoration + ".png"; - if (preuser.banner == null) - user.banner_url = null; - else - user.banner_url = "https://cdn.discordapp.com/banners/" + preuser.id + "/" + preuser.banner + ".png"; - results[userId] = user; - resolve(); - } else { - reject(response.statusCode); +async function fetchUserDataWithRetry(userId) { + let retries = 0; + let delayTime = 1000; + + while (retries < 3) { + try { + const response = await axios.get(`https://discord.com/api/v10/users/${userId}`, { + headers: { + 'Authorization': 'Bot ' + botToken } }); - }); - }); + return response.data; + } catch (error) { + if (error.response && error.response.status === 429) { + const retryAfter = error.response.headers['retry-after'] || delayTime; + console.error("Rate limited. Retrying after", retryAfter, "ms"); + await delay(retryAfter); + delayTime *= 2; + retries++; + } else { + console.error("Error fetching user data:", error); + return null; + } + } + } + return null; +} + +app.get("/:userIds", async (req, res) => { + const userIds = req.params.userIds.split(","); + var results = {}; + var preresults = {}; + try { - await Promise.all(promises); - res.send(results); - } catch (errorStatusCode) { - res.status(errorStatusCode).send("Error fetching user data."); + for (const userId of userIds) { + if (userCache[userId]) { + preresults[userId] = userCache[userId]; + } else { + const userData = await fetchUserDataWithRetry(userId); + if (userData !== null) { + userCache[userId] = userData; + preresults[userId] = userData; + } else { + preresults[userId] = { error: "User not found or API error" }; + } + } + } + console.log("Results:", preresults); + for (var preresult in preresults) { + var result = { + "global_name": preresult.global_name, + "public_flags": preresult.public_flags, + "flags": preresult.flags, + "accent_color": preresult.accent_color, + "avatar_decoration": preresult.avatar_decoration, + "banner": preresult.banner, + "banner_color": preresult.banner_color, + }; + if (preresult.avatar_decoration == null) + result.avatar_decoration = null; + else + result.avatar_decoration = "https://cdn.discordapp.com/avatar-decorations/" + preresult.id + "/" + preresult.avatar_decoration + ".png"; + if (preresult.banner == null) + result.banner_url = null; + else + result.banner_url = "https://cdn.discordapp.com/banners/" + preresult.id + "/" + preresult.banner + ".png"; + results[preresult.id] = result; + } + res.send(preresults); //should be results + } catch (error) { + console.error("Error:", error); + res.status(500).json({ error: "Internal server error" }); + } +}); + +app.use((err, req, res, next) => { + if (err) { + console.error("Error:", err); + res.status(500).json({ error: "Internal server error" }); + } else { + next(); } });