import { Message } from "discord.js"; import { logUnexpectedDiscordAPIError, replyWithCleanup } from "../utilities"; import { ROLEPLAY_GUILD_ID } from "../constants"; const RACECOURSES_CATEGORY_ID = "1428169113754402836"; const RACE_PLANNER_ROLE_ID = "1428173099270148173"; export const handleVerbalGatesCommand = async ( message: Message, ): Promise => { if (message.author.bot) return false; const botMentioned = message.mentions.users.has( message.client.user?.id || "", ); if (!botMentioned) return false; if (message.guildId !== ROLEPLAY_GUILD_ID) return false; const content = message.content.toLowerCase(); const openMatch = content.match(/open\s+<#(\d+)>/); const closeMatch = content.match(/close\s+<#(\d+)>/); const toggleMatch = content.match(/toggle\s+<#(\d+)>/); const action = openMatch ? "open" : closeMatch ? "close" : toggleMatch ? "toggle" : null; const channelId = openMatch?.[1] || closeMatch?.[1] || toggleMatch?.[1]; if (!action || !channelId) return false; const application = await message.client.application?.fetch(); const ownerId = application?.owner?.id; const guildOwnerId = message.guild?.ownerId; const hasAdminPermission = message.member?.permissions.has("Administrator") ?? false; const hasOwnerPermission = message.member?.permissions.has("CreateInstantInvite") ?? false; const hasRacePlannerRole = message.member?.roles.cache.has(RACE_PLANNER_ROLE_ID); const isBotOwner = message.author.id === ownerId; const isGuildOwner = message.author.id === guildOwnerId; if ( !hasAdminPermission && !hasOwnerPermission && !hasRacePlannerRole && !isBotOwner && !isGuildOwner ) { await replyWithCleanup( message, "❌ You don't have permission to use this command. Only owners, administrators, or Race Planners can use this command.", ); return true; } const targetChannel = message.client.channels.cache.get(channelId); if ( !targetChannel || !targetChannel.isTextBased() || targetChannel.isThread() ) { await replyWithCleanup( message, "❌ Channel not found, is not a text channel, or is a thread.", ); return true; } if ( !("parentId" in targetChannel) || targetChannel.parentId !== RACECOURSES_CATEGORY_ID ) { await replyWithCleanup( message, "❌ The specified channel is not a racecourse.", ); return true; } try { // eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain const everyoneRoleId = message.guild?.roles.everyone.id!; const canCurrentlySendMessages = targetChannel.permissionsFor(everyoneRoleId)?.has("SendMessages") ?? true; const canCurrentlySendInThreads = targetChannel .permissionsFor(everyoneRoleId) ?.has("SendMessagesInThreads") ?? true; const gatesCurrentlyOpen = canCurrentlySendMessages && canCurrentlySendInThreads; let actualAction = action; if (action === "toggle") actualAction = gatesCurrentlyOpen ? "close" : "open"; if (action !== "toggle") { const requestedStateMatches = (action === "open" && gatesCurrentlyOpen) || (action === "close" && !gatesCurrentlyOpen); if (requestedStateMatches) { const channelMention = `<#${targetChannel.id}>`; const currentState = gatesCurrentlyOpen ? "open" : "closed"; await replyWithCleanup( message, `ℹ️ The gates for ${channelMention} are already ${currentState}.`, ); try { await message.react("✅"); } catch (error) { logUnexpectedDiscordAPIError(error); } return true; } } if (actualAction === "close") { await targetChannel.permissionOverwrites.edit(everyoneRoleId, { SendMessages: false, SendMessagesInThreads: false, }); } else if (actualAction === "open") { await targetChannel.permissionOverwrites.edit(everyoneRoleId, { SendMessages: true, SendMessagesInThreads: true, }); } const channelMention = `<#${targetChannel.id}>`; await replyWithCleanup( message, `✅ I've successfully ${actualAction === "close" ? "closed" : "opened"} the gates for ${channelMention}.`, ); try { await message.react("✅"); } catch (error) { logUnexpectedDiscordAPIError(error); } return true; } catch (error) { logUnexpectedDiscordAPIError(error); await replyWithCleanup( message, "❌ An error occurred while managing channel permissions.", ); return true; } };