|
1 | 1 | import { env } from "../typeDefinitions/default.types";
|
2 | 2 | import { DISCORD_BASE_URL } from "../constants/urls";
|
| 3 | +import { |
| 4 | + parseRateLimitRemaining, |
| 5 | + parseResetAfter, |
| 6 | +} from "./batchDiscordRequests"; |
3 | 7 |
|
4 |
| -export const removeUsers = async ( |
5 |
| - env: env, |
6 |
| - usersWithMatchingRole: string[] |
7 |
| -) => { |
8 |
| - const baseUrl = `${DISCORD_BASE_URL}/guilds/${env.DISCORD_GUILD_ID}/members`; |
9 |
| - // Method : DELETE /guilds/{guild.id}/members/{user.id} |
10 |
| - |
11 |
| - for (const mention of usersWithMatchingRole) { |
12 |
| - // Remove <@ and > symbols from the mention |
13 |
| - const userId = mention.replace(/<@!*/g, "").replace(/>/g, ""); |
14 |
| - const url = `${baseUrl}/${userId}`; |
15 |
| - |
16 |
| - const headers = { |
17 |
| - "Content-Type": "application/json", |
18 |
| - Authorization: `Bot ${env.DISCORD_TOKEN}`, |
19 |
| - }; |
20 |
| - |
21 |
| - try { |
22 |
| - await fetch(url, { method: "DELETE", headers }); |
23 |
| - } catch (error) { |
24 |
| - console.error(`Error removing user with ID ${userId}:`, error); |
| 8 | +export async function removeUsers(env: env, usersWithMatchingRole: string[]) { |
| 9 | + const batchSize = 4; |
| 10 | + let waitTillNextAPICall = 0; |
| 11 | + |
| 12 | + try { |
| 13 | + for (let i = 0; i < usersWithMatchingRole.length; i += batchSize) { |
| 14 | + const batchwiseUsers = usersWithMatchingRole.slice(i, i + batchSize); |
| 15 | + const deleteRequests = batchwiseUsers.map((mention) => { |
| 16 | + const userId = mention.replace(/<@!*/g, "").replace(/>/g, ""); |
| 17 | + const url = `${DISCORD_BASE_URL}/guilds/${env.DISCORD_GUILD_ID}/members/${userId}`; |
| 18 | + |
| 19 | + return fetch(url, { |
| 20 | + method: "DELETE", |
| 21 | + headers: { |
| 22 | + "Content-Type": "application/json", |
| 23 | + Authorization: `Bot ${env.DISCORD_TOKEN}`, |
| 24 | + }, |
| 25 | + }).then(async (response) => { |
| 26 | + const rateLimitRemaining = parseRateLimitRemaining(response); |
| 27 | + |
| 28 | + if (rateLimitRemaining === 0) { |
| 29 | + waitTillNextAPICall = Math.max( |
| 30 | + parseResetAfter(response), |
| 31 | + waitTillNextAPICall |
| 32 | + ); |
| 33 | + } |
| 34 | + |
| 35 | + // Check if response status is 204 (No Content) indicating success |
| 36 | + if (response.status === 204) { |
| 37 | + return { success: true }; |
| 38 | + } else { |
| 39 | + throw new Error(`Failed to remove user ${userId}.`); |
| 40 | + } |
| 41 | + }); |
| 42 | + }); |
| 43 | + |
| 44 | + // Wait for all delete requests in the batch to complete |
| 45 | + await Promise.all(deleteRequests); |
| 46 | + |
| 47 | + // Wait until the next API call is allowed based on rate limits |
| 48 | + await sleep(waitTillNextAPICall * 1000); |
| 49 | + waitTillNextAPICall = 0; |
25 | 50 | }
|
| 51 | + } catch (error) { |
| 52 | + console.error("Error occurred while removing users:", error); |
26 | 53 | }
|
27 |
| -}; |
| 54 | +} |
| 55 | + |
| 56 | +function sleep(ms: number) { |
| 57 | + return new Promise((resolve) => setTimeout(resolve, ms)); |
| 58 | +} |
0 commit comments