Skip to content

Commit

Permalink
Merge pull request #409 from TFNS/408-ctf-limit-crash-discord
Browse files Browse the repository at this point in the history
Change Discord interaction to select menu
  • Loading branch information
JJ-8 authored Jan 16, 2025
2 parents 559d33e + 135b614 commit f4d4910
Show file tree
Hide file tree
Showing 20 changed files with 117 additions and 112 deletions.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
2 changes: 1 addition & 1 deletion api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"@graphile/operation-hooks": "^1.0.0",
"@graphile/pg-pubsub": "4.13.0",
"axios": "^1.7.7",
"discord.js": "^14.16.3",
"discord.js": "^14.17.3",
"dotenv": "^16.4.5",
"express": "^4.21.1",
"graphile-utils": "4.13.0",
Expand Down
40 changes: 23 additions & 17 deletions api/src/discord/agile/commands/archiveCtf.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import {
ActionRowBuilder,
ApplicationCommandType,
ButtonBuilder,
ButtonInteraction,
ButtonStyle,
Client,
CommandInteraction,
PermissionFlagsBits,
StringSelectMenuBuilder,
StringSelectMenuInteraction,
StringSelectMenuOptionBuilder,
} from "discord.js";
import { Command } from "../../interfaces/command";
import {
Expand All @@ -20,10 +20,12 @@ import {
createPadWithoutLimit,
getMessagesOfCategories,
} from "../../utils/messages";
import { DiscordButtonInteraction } from "../../interfaces/interaction";
import { DiscordInputInteraction } from "../../interfaces/interaction";

const customId = "archive-ctf-interaction";

async function handleArchiveInteraction(
interaction: ButtonInteraction,
interaction: StringSelectMenuInteraction,
ctfName: string
) {
const guild = interaction.guild;
Expand Down Expand Up @@ -54,10 +56,10 @@ async function handleArchiveInteraction(
return true;
}

export const HandleArchiveCtfInteraction: DiscordButtonInteraction = {
customId: "archive-ctf-button",
handle: async (client: Client, interaction: ButtonInteraction) => {
const ctfName = interaction.customId.replace("archive-ctf-button-", "");
export const HandleArchiveCtfInteraction: DiscordInputInteraction = {
customId: customId,
handle: async (client: Client, interaction: StringSelectMenuInteraction) => {
const ctfName = interaction.values[0];
await interaction.deferUpdate();
await interaction.editReply({
content: `Archiving the CTF channels and roles for ${ctfName}`,
Expand Down Expand Up @@ -97,19 +99,23 @@ async function archiveCtfLogic(
return;
}

const buttons: ButtonBuilder[] = [];
const options: StringSelectMenuOptionBuilder[] = [];
for (let i = 0; i < ctfNames.length; i++) {
buttons.push(
new ButtonBuilder()
.setCustomId(`archive-ctf-button-${ctfNames[i]}`)
options.push(
new StringSelectMenuOptionBuilder()
.setLabel(ctfNames[i])
.setStyle(ButtonStyle.Success)
.setValue(ctfNames[i])
);
}

const actionRow = new ActionRowBuilder<ButtonBuilder>().addComponents(
buttons
);
const select = new StringSelectMenuBuilder();
select
.setCustomId(customId)
.setPlaceholder("Choose the CTF")
.addOptions(options);

const actionRow =
new ActionRowBuilder<StringSelectMenuBuilder>().addComponents(select);

await interaction.editReply({
content: "Which CTF do you want to archive?",
Expand Down
38 changes: 21 additions & 17 deletions api/src/discord/agile/commands/createCtf.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import {
ActionRowBuilder,
ApplicationCommandType,
ButtonBuilder,
ButtonInteraction,
ButtonStyle,
Client,
CommandInteraction,
PermissionFlagsBits,
StringSelectMenuBuilder,
StringSelectMenuInteraction,
StringSelectMenuOptionBuilder,
} from "discord.js";
import { Command } from "../../interfaces/command";
import {
Expand All @@ -18,13 +18,15 @@ import {
createChannelsAndRolesForCtf,
getChannelCategoriesForCtf,
} from "../channels";
import { DiscordButtonInteraction } from "../../interfaces/interaction";
import { DiscordInputInteraction } from "../../interfaces/interaction";
import { getChallengesFromDatabase } from "../../database/tasks";

export const HandleCreateCtfInteraction: DiscordButtonInteraction = {
customId: "create-ctf-button",
handle: async (client: Client, interaction: ButtonInteraction) => {
const ctfName = interaction.customId.replace("create-ctf-button-", "");
const customId = "create-ctf-interaction";

export const HandleCreateCtfInteraction: DiscordInputInteraction = {
customId: customId,
handle: async (client: Client, interaction: StringSelectMenuInteraction) => {
const ctfName = interaction.values[0];
await interaction.deferUpdate();
await interaction.editReply({
content: `Creating the CTF channels and roles for ${ctfName}`,
Expand Down Expand Up @@ -79,21 +81,23 @@ async function createCtfLogic(client: Client, interaction: CommandInteraction) {
return;
}

// Make a loop to create buttons for each CTF
const buttons: ButtonBuilder[] = [];
const options: StringSelectMenuOptionBuilder[] = [];
for (let i = 0; i < ctfNames.length; i++) {
buttons.push(
new ButtonBuilder()
.setCustomId(`create-ctf-button-${ctfNames[i]}`)
options.push(
new StringSelectMenuOptionBuilder()
.setLabel(ctfNames[i])
.setStyle(ButtonStyle.Success)
.setValue(ctfNames[i])
);
}
const select = new StringSelectMenuBuilder();
select
.setCustomId(customId)
.setPlaceholder("Choose the CTF")
.addOptions(options);

// Create the action row with the button components
const actionRow = new ActionRowBuilder<ButtonBuilder>().addComponents(
buttons
);
const actionRow =
new ActionRowBuilder<StringSelectMenuBuilder>().addComponents(select);

await interaction.editReply({
content: ctfNamesMessage,
Expand Down
38 changes: 22 additions & 16 deletions api/src/discord/agile/commands/deleteCtf.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import {
ActionRowBuilder,
ApplicationCommandType,
ButtonBuilder,
ButtonInteraction,
ButtonStyle,
Client,
CommandInteraction,
Interaction,
PermissionFlagsBits,
StringSelectMenuBuilder,
StringSelectMenuInteraction,
StringSelectMenuOptionBuilder,
} from "discord.js";
import { Command } from "../../interfaces/command";
import {
Expand All @@ -18,7 +18,9 @@ import { getChannelCategoriesForCtf } from "../channels";
import { handleDeleteCtf } from "../hooks";
import { getTaskByCtfIdAndNameFromDatabase } from "../../database/tasks";
import { discordArchiveTaskName } from "../../utils/messages";
import { DiscordButtonInteraction } from "../../interfaces/interaction";
import { DiscordInputInteraction } from "../../interfaces/interaction";

const customId = "delete-ctf-interaction";

export async function handleDeleteInteraction(
interaction: Interaction,
Expand Down Expand Up @@ -58,19 +60,23 @@ async function deleteCtfLogic(client: Client, interaction: CommandInteraction) {
return;
}

const buttons: ButtonBuilder[] = [];
const options: StringSelectMenuOptionBuilder[] = [];
for (let i = 0; i < ctfNames.length; i++) {
buttons.push(
new ButtonBuilder()
.setCustomId(`delete-ctf-button-${ctfNames[i]}`)
options.push(
new StringSelectMenuOptionBuilder()
.setLabel(ctfNames[i])
.setStyle(ButtonStyle.Success)
.setValue(ctfNames[i])
);
}

const actionRow = new ActionRowBuilder<ButtonBuilder>().addComponents(
buttons
);
const select = new StringSelectMenuBuilder();
select
.setCustomId(customId)
.setPlaceholder("Choose the CTF")
.addOptions(options);

const actionRow =
new ActionRowBuilder<StringSelectMenuBuilder>().addComponents(select);

await interaction.editReply({
content:
Expand All @@ -79,10 +85,10 @@ async function deleteCtfLogic(client: Client, interaction: CommandInteraction) {
});
}

export const HandleDeleteCtfInteraction: DiscordButtonInteraction = {
customId: "delete-ctf-button",
handle: async (client: Client, interaction: ButtonInteraction) => {
const ctfName = interaction.customId.replace("delete-ctf-button-", "");
export const HandleDeleteCtfInteraction: DiscordInputInteraction = {
customId: customId,
handle: async (client: Client, interaction: StringSelectMenuInteraction) => {
const ctfName = interaction.values[0];
await interaction.deferUpdate();
await interaction.editReply({
content: `Deleting the CTF channels and roles for ${ctfName}`,
Expand Down
9 changes: 6 additions & 3 deletions api/src/discord/interfaces/interaction.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { ButtonInteraction, Client } from "discord.js";
import { Client, StringSelectMenuInteraction } from "discord.js";

export interface DiscordButtonInteraction {
export interface DiscordInputInteraction {
customId: string;
handle: (client: Client, interaction: ButtonInteraction) => Promise<void>;
handle: (
client: Client,
interaction: StringSelectMenuInteraction
) => Promise<void>;
}
8 changes: 4 additions & 4 deletions api/src/discord/listeners/interactionCreate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,19 @@ import {
export default (client: Client): void => {
client.on("interactionCreate", async (interaction: Interaction) => {
//check if it is a button interaction
if (interaction.isButton()) {
await handleButtonInteraction(client, interaction);
if (interaction.isStringSelectMenu()) {
await handleInputInteraction(client, interaction);
} else if (interaction.isCommand() || interaction.isContextMenuCommand()) {
await handleSlashCommand(client, interaction);
}
});
};

const handleButtonInteraction = async (
const handleInputInteraction = async (
client: Client,
interaction: Interaction
): Promise<void> => {
if (!interaction.isButton()) {
if (!interaction.isStringSelectMenu()) {
return;
}
const handler = (await getChannelHandleStyleInteractions()).find((i) =>
Expand Down
4 changes: 2 additions & 2 deletions api/src/discord/utils/channelStyle.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import config from "../../config";
import { Hooks } from "../interfaces/hooks";
import { Command } from "../interfaces/command";
import { DiscordButtonInteraction } from "../interfaces/interaction";
import { DiscordInputInteraction } from "../interfaces/interaction";

const channelStyle = config.discord.channelHandleStyle;

export async function getChannelHandleStyleInteractions(): Promise<
DiscordButtonInteraction[]
DiscordInputInteraction[]
> {
switch (channelStyle) {
case "agile": {
Expand Down
Loading

0 comments on commit f4d4910

Please sign in to comment.