generated from Real-Dev-Squad/website-template
-
Notifications
You must be signed in to change notification settings - Fork 56
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #221 from Real-Dev-Squad/develop
Dev to main sync
- Loading branch information
Showing
18 changed files
with
597 additions
and
52 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import { | ||
MentionEachUserOptions, | ||
UserArray, | ||
} from "../typeDefinitions/filterUsersByRole"; | ||
import { env } from "../typeDefinitions/default.types"; | ||
import { getMembersInServer } from "../utils/getMembersInServer"; | ||
import { filterUserByRoles } from "../utils/filterUsersByRole"; | ||
import { discordTextResponse } from "../utils/discordResponse"; | ||
import { removeUsers } from "../utils/removeUsers"; | ||
|
||
export async function kickEachUser( | ||
transformedArgument: { | ||
roleToBeRemovedObj: MentionEachUserOptions; | ||
channelId: number; | ||
}, | ||
env: env, | ||
ctx: ExecutionContext | ||
) { | ||
const getMembersInServerResponse = await getMembersInServer(env); | ||
const roleId = transformedArgument.roleToBeRemovedObj.value; | ||
|
||
const usersWithMatchingRole = filterUserByRoles( | ||
getMembersInServerResponse as UserArray[], | ||
roleId | ||
); | ||
|
||
const usersText = usersWithMatchingRole | ||
.map((user) => { | ||
return user; | ||
}) | ||
.join("\n"); | ||
|
||
if (usersWithMatchingRole.length === 0) { | ||
return discordTextResponse( | ||
`We couldn't find any user(s) assigned to <@&${roleId}> role.` | ||
); | ||
} else { | ||
ctx.waitUntil( | ||
removeUsers(env, usersWithMatchingRole, transformedArgument.channelId) | ||
); | ||
const responseText = `Following users will be removed shortly ..... :\n${usersText}`; | ||
return discordTextResponse(responseText); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import { env } from "../typeDefinitions/default.types"; | ||
import JSONResponse from "../utils/JsonResponse"; | ||
import * as response from "../constants/responses"; | ||
import { verifyNodejsBackendAuthToken } from "../utils/verifyAuthToken"; | ||
import { sendTaskUpdate } from "../utils/sendTaskUpdates"; | ||
import { TaskUpdates } from "../typeDefinitions/taskUpdate"; | ||
import { IRequest } from "itty-router"; | ||
|
||
export const sendTaskUpdatesHandler = async (request: IRequest, env: env) => { | ||
const authHeader = request.headers.get("Authorization"); | ||
if (!authHeader) { | ||
return new JSONResponse(response.UNAUTHORIZED, { status: 401 }); | ||
} | ||
try { | ||
await verifyNodejsBackendAuthToken(authHeader, env); | ||
const updates: TaskUpdates = await request.json(); | ||
const { completed, planned, blockers } = updates.content; | ||
await sendTaskUpdate(completed, planned, blockers, env); | ||
return new JSONResponse( | ||
"Task update sent on Discord's tracking-updates channel." | ||
); | ||
} catch (error: any) { | ||
return new JSONResponse({ | ||
res: response.INTERNAL_SERVER_ERROR, | ||
message: error.message, | ||
status: 500, | ||
}); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
export interface TaskUpdates { | ||
content: { | ||
completed: string; | ||
planned: string; | ||
blockers: string; | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import { env } from "../typeDefinitions/default.types"; | ||
import { DISCORD_BASE_URL } from "../constants/urls"; | ||
import { | ||
parseRateLimitRemaining, | ||
parseResetAfter, | ||
} from "./batchDiscordRequests"; | ||
import { | ||
discordMessageRequest, | ||
discordMessageError, | ||
} from "../typeDefinitions/discordMessage.types"; | ||
|
||
export async function removeUsers( | ||
env: env, | ||
usersWithMatchingRole: string[], | ||
channelId: number | ||
) { | ||
const batchSize = 4; | ||
let waitTillNextAPICall = 0; | ||
|
||
try { | ||
const failedUsers: Array<string> = []; | ||
for (let i = 0; i < usersWithMatchingRole.length; i += batchSize) { | ||
const batchwiseUsers = usersWithMatchingRole.slice(i, i + batchSize); | ||
const deleteRequests = batchwiseUsers.map((mention) => { | ||
const userId = mention.replace(/<@!*/g, "").replace(/>/g, ""); | ||
const url = `${DISCORD_BASE_URL}/guilds/${env.DISCORD_GUILD_ID}/members/${userId}`; | ||
|
||
return fetch(url, { | ||
method: "DELETE", | ||
headers: { | ||
"Content-Type": "application/json", | ||
Authorization: `Bot ${env.DISCORD_TOKEN}`, | ||
}, | ||
}).then((response) => { | ||
const rateLimitRemaining = parseRateLimitRemaining(response); | ||
if (rateLimitRemaining === 0) { | ||
waitTillNextAPICall = Math.max( | ||
parseResetAfter(response), | ||
waitTillNextAPICall | ||
); | ||
} | ||
return response.json(); | ||
}) as Promise<discordMessageRequest | discordMessageError>; | ||
}); | ||
|
||
const responses = await Promise.all(deleteRequests); | ||
responses.forEach((response, i) => { | ||
if (response && "message" in response) { | ||
failedUsers.push(batchwiseUsers[i]); | ||
console.error(`Failed to remove a user`); | ||
} | ||
}); | ||
await sleep(waitTillNextAPICall * 1000); | ||
waitTillNextAPICall = 0; | ||
} | ||
|
||
if (failedUsers.length > 0) { | ||
await fetch(`${DISCORD_BASE_URL}/channels/${channelId}/messages`, { | ||
method: "POST", | ||
headers: { | ||
"Content-Type": "application/json", | ||
Authorization: `Bot ${env.DISCORD_TOKEN}`, | ||
}, | ||
body: JSON.stringify({ | ||
content: `Failed to remove ${failedUsers}.`, | ||
}), | ||
}); | ||
} | ||
} catch (error) { | ||
console.error("Error occurred while removing users:", error); | ||
} | ||
} | ||
|
||
function sleep(ms: number) { | ||
return new Promise((resolve) => setTimeout(resolve, ms)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { env } from "../typeDefinitions/default.types"; | ||
import config from "../../config/config"; | ||
|
||
export async function sendTaskUpdate( | ||
completed: string, | ||
planned: string, | ||
blockers: string, | ||
env: env | ||
): Promise<void> { | ||
const formattedString = `**Completed**: ${completed}\n\n**Planned**: ${planned}\n\n**Blockers**: ${blockers}`; | ||
const bodyObj = { | ||
content: formattedString, | ||
}; | ||
const url = config(env).TRACKING_CHANNEL_URL; | ||
try { | ||
const response = await fetch(url, { | ||
method: "POST", | ||
body: JSON.stringify(bodyObj), | ||
headers: { | ||
"Content-Type": "application/json", | ||
Authorization: `Bot ${env.DISCORD_TOKEN}`, | ||
}, | ||
}); | ||
|
||
if (!response.ok) { | ||
throw new Error( | ||
`Failed to send task update: ${response.status} - ${response.statusText}` | ||
); | ||
} | ||
} catch (error) { | ||
console.error("Error occurred while sending task update:", error); | ||
throw error; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.