summaryrefslogtreecommitdiff
path: root/commands.ts
diff options
context:
space:
mode:
Diffstat (limited to 'commands.ts')
-rw-r--r--commands.ts76
1 files changed, 59 insertions, 17 deletions
diff --git a/commands.ts b/commands.ts
index f100cc7..3b72c3a 100644
--- a/commands.ts
+++ b/commands.ts
@@ -9,8 +9,10 @@ import {
SlashCommandChannelOption,
SlashCommandStringOption,
SlashCommandUserOption,
+ ChatInputCommandInteraction,
type ButtonInteraction,
- type ChatInputCommandInteraction,
+ type GuildForumTag,
+ type GuildBasedChannel,
} from "discord.js";
export let slashCommands = [
@@ -107,6 +109,8 @@ async function newCtf(interaction: ChatInputCommandInteraction) {
],
});
+ await ensureUnsolvedTag(forum);
+
let generalThread = await forum.threads.create({
name: "general",
message: {
@@ -304,32 +308,70 @@ async function handleJoinCtfButton(interaction: ButtonInteraction, forumId: stri
});
}
-async function getCtfForum(interaction: ButtonInteraction | ChatInputCommandInteraction): Promise<ForumChannel> {
- let errorMsg = "This command can only be used in a CTF forum channel.";
-
- if (!interaction.guild) {
- await interaction.reply({ content: errorMsg, flags: "Ephemeral" });
+/**
+ * Given either a forum, a thread in a forum, or an interaction from a slash command ran in a thread
+ * in a forum, returns that forum if it was created by this bot.
+ */
+export async function getCtfForum(interactionOrChannel: ChatInputCommandInteraction | GuildBasedChannel): Promise<ForumChannel> {
+ let interaction = (interactionOrChannel instanceof ChatInputCommandInteraction) ? interactionOrChannel : null;
+ async function done(): Promise<never> {
+ await interaction?.reply({ content: "This command can only be used in a CTF forum channel.", flags: "Ephemeral" });
throw "done";
}
- let channel = await interaction.guild.channels.fetch(interaction.channelId);
+ let channel: GuildBasedChannel;
+ if (interactionOrChannel instanceof ChatInputCommandInteraction) {
+ if (!interactionOrChannel.guild) throw await done();
- if (!channel) {
- await interaction.reply({ content: errorMsg, flags: "Ephemeral" });
- throw "done";
+ let ch = await interactionOrChannel.guild.channels.fetch(interactionOrChannel.channelId);
+
+ if (!ch) throw await done();
+
+ channel = ch;
+ } else {
+ channel = interactionOrChannel;
}
if (channel.type === ChannelType.GuildForum) {
return channel as ForumChannel;
}
-
- if (channel.isThread() && channel.parentId) {
- let parent = await interaction.guild.channels.fetch(channel.parentId);
- if (parent && parent.type === ChannelType.GuildForum) {
- return parent as ForumChannel;
+ if (!channel.isThread() || !channel.parentId)
+ throw await done();
+
+ let parent = await channel.guild.channels.fetch(channel.parentId);
+ if (!parent || parent.type !== ChannelType.GuildForum)
+ throw await done();
+
+ let threads = await parent.threads.fetch();
+ for (let thread of threads.threads.values()) {
+ if (thread.name !== "general" ||
+ thread.ownerId !== channel.client.user?.id ||
+ !thread.flags.has("Pinned")) {
+ continue;
}
+
+ return parent as ForumChannel;
+ }
+
+ throw await done();
+}
+
+export async function ensureUnsolvedTag(forum: ForumChannel): Promise<GuildForumTag> {
+ let currentTags = forum.availableTags ?? [];
+ let existing = currentTags.find(tag => tag.name === "unsolved");
+ if (existing) {
+ return existing;
+ }
+
+ await forum.setAvailableTags([
+ ...currentTags,
+ { name: "unsolved", moderated: false },
+ ]);
+
+ let updated = forum.availableTags?.find(tag => tag.name === "unsolved");
+ if (!updated) {
+ throw new Error(`Failed to create unsolved tag for ${forum.id}`);
}
- await interaction.reply({ content: errorMsg, flags: "Ephemeral" });
- throw "done";
+ return updated;
}