From 2880283e9ac6cd9ca6a05e03a711caf0a0663c00 Mon Sep 17 00:00:00 2001 From: smyalygames Date: Sun, 15 Jan 2023 19:00:10 +0000 Subject: [PATCH] feat(arabot): add access command --- src/commands/coordinators/access.ts | 238 ++++++++++++++++++++++++++++ src/utils/devIDs.ts | 1 + src/utils/ids.ts | 1 + 3 files changed, 240 insertions(+) create mode 100644 src/commands/coordinators/access.ts diff --git a/src/commands/coordinators/access.ts b/src/commands/coordinators/access.ts new file mode 100644 index 0000000..ae47816 --- /dev/null +++ b/src/commands/coordinators/access.ts @@ -0,0 +1,238 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +/* + Animal Rights Advocates Discord Bot + Copyright (C) 2023 Anthony Berg + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +import { Command, RegisterBehavior } from '@sapphire/framework'; +import { ChannelType, TextChannel, VoiceChannel } from 'discord.js'; +import IDs from '../../utils/ids'; + +class AccessCommand extends Command { + public constructor(context: Command.Context, options: Command.Options) { + super(context, { + ...options, + name: 'access', + description: 'Manages channel permissions for ModMails, Private channels, and restricted channels', + preconditions: ['CoordinatorOnly'], + }); + } + + // Registers that this is a slash command + public override registerApplicationCommands(registry: Command.Registry) { + registry.registerChatInputCommand( + (builder) => builder + .setName(this.name) + .setDescription(this.description) + .addStringOption((option) => option.setName('permission') + .setDescription('Select permissions for the user/role') + .setRequired(true) + .addChoices( + { name: 'Add', value: 'add' }, + { name: 'Read', value: 'read' }, + { name: 'Remove', value: 'remove' }, + { name: 'Reset', value: 'reset' }, + )) + .addChannelOption((option) => option.setName('channel') + .setDescription('Channel to change these permissions on') + .setRequired(true)) + .addUserOption((option) => option.setName('user') + .setDescription('User to set these permissions for')) + .addRoleOption((option) => option.setName('role') + .setDescription('Role to set these permissions for')), + { + behaviorWhenNotIdentical: RegisterBehavior.Overwrite, + }, + ); + } + + // Command run + public async chatInputRun(interaction: Command.ChatInputCommandInteraction) { + // Get the arguments + const permission = interaction.options.getString('permission'); + const parsedChannel = interaction.options.getChannel('channel'); + const user = interaction.options.getUser('user'); + const role = interaction.options.getRole('role'); + const { guild } = interaction; + + // Checks if all the variables are of the right type + if (permission === null + || parsedChannel === null + || guild === null + || (user === null && role === null)) { + await interaction.reply({ + content: 'Error fetching slash command data!', + ephemeral: true, + fetchReply: true, + }); + return; + } + + if (user !== null && role !== null) { + await interaction.reply({ + content: 'You have entered a user and a role at the same time! Please only enter one at a time.', + ephemeral: true, + fetchReply: true, + }); + return; + } + + if (parsedChannel.type !== ChannelType.GuildText + && parsedChannel.type !== ChannelType.GuildVoice) { + await interaction.reply({ + content: 'Please only select a text or voice channel!', + ephemeral: true, + fetchReply: true, + }); + return; + } + + let channel: TextChannel | VoiceChannel | undefined; + if (parsedChannel.type === ChannelType.GuildVoice) { + channel = guild.channels.cache.get(parsedChannel.id) as VoiceChannel | undefined; + } else { + channel = guild.channels.cache.get(parsedChannel.id) as TextChannel | undefined; + } + + if (channel === undefined) { + await interaction.reply({ + content: 'Could not find channel!', + ephemeral: true, + fetchReply: true, + }); + return; + } + + if (channel.parentId !== IDs.categories.modMail + && channel.parentId !== IDs.categories.private + && channel.parentId !== IDs.categories.restricted) { + await interaction.reply({ + content: 'Channel is not in ModMail/Private/Restricted category!', + ephemeral: true, + fetchReply: true, + }); + return; + } + + let permId: string; + if (user !== null) { + if (user.id === undefined) { + await interaction.reply({ + content: 'Error getting user id!', + ephemeral: true, + fetchReply: true, + }); + return; + } + permId = user.id; + } else if (role !== null) { + permId = role.id; + } else { + await interaction.reply({ + content: 'Could not find the role to edit permissions!', + ephemeral: true, + fetchReply: true, + }); + return; + } + + if (channel.type === ChannelType.GuildVoice) { + switch (permission) { + case 'add': + await channel.permissionOverwrites.create(permId, { + ViewChannel: true, + Connect: true, + Speak: true, + SendMessages: true, + ReadMessageHistory: true, + }); + break; + case 'view': + await channel.permissionOverwrites.create(permId, { + ViewChannel: true, + Connect: true, + Speak: false, + SendMessages: false, + AddReactions: false, + ReadMessageHistory: true, + }); + break; + case 'remove': + await channel.permissionOverwrites.create(permId, { + ViewChannel: false, + Connect: false, + Speak: false, + SendMessages: false, + ReadMessageHistory: false, + }); + break; + case 'reset': + await channel.permissionOverwrites.delete(permId); + break; + default: + await interaction.reply({ + content: 'Incorrect permission option!', + ephemeral: true, + fetchReply: true, + }); + return; + } + return; + } + + switch (permission) { + case 'add': + await channel.permissionOverwrites.create(permId, { + ViewChannel: true, + SendMessages: true, + ReadMessageHistory: true, + }); + break; + case 'view': + await channel.permissionOverwrites.create(permId, { + ViewChannel: true, + SendMessages: false, + AddReactions: false, + ReadMessageHistory: true, + }); + break; + case 'remove': + await channel.permissionOverwrites.create(permId, { + ViewChannel: false, + SendMessages: false, + ReadMessageHistory: false, + }); + break; + case 'reset': + await channel.permissionOverwrites.delete(permId); + break; + default: + await interaction.reply({ + content: 'Incorrect permission option!', + ephemeral: true, + fetchReply: true, + }); + return; + } + + await interaction.reply({ + content: `Successfully updated permissions for ${channel}`, + fetchReply: true, + }); + } +} + +export default AccessCommand; diff --git a/src/utils/devIDs.ts b/src/utils/devIDs.ts index 10f5175..15bac9e 100644 --- a/src/utils/devIDs.ts +++ b/src/utils/devIDs.ts @@ -110,6 +110,7 @@ const devIDs = { verification: '999431677006860409', diversity: '999431679053660185', private: '999431679527628818', + restricted: '999431679812845654', }, }; diff --git a/src/utils/ids.ts b/src/utils/ids.ts index 486acb6..af7c3bc 100644 --- a/src/utils/ids.ts +++ b/src/utils/ids.ts @@ -113,6 +113,7 @@ let IDs = { verification: '797505409073676299', diversity: '933078380394459146', private: '992581296901599302', + restricted: '809765577236283472', }, };