Compare commits

..

11 Commits

5 changed files with 175 additions and 31 deletions

View File

@ -19,12 +19,25 @@ export const data = new SlashCommandBuilder()
.addSubcommand((subcommand) => .addSubcommand((subcommand) =>
subcommand subcommand
.setName('register') .setName('register')
.setDescription('Registers an existing voice channel.') .setDescription('Registers an existing voice channel for custom channel creation.')
.addStringOption((option) => .addChannelOption((option) =>
option option
.setName('id')
.setRequired(true) .setRequired(true)
.setDescription('The ID to reference the voice channel to be used.') .setName('channel')
.addChannelTypes(ChannelType.GuildVoice)
.setDescription('The voice channel to be used.')
)
)
.addSubcommand((subcommand) =>
subcommand
.setName('remove')
.setDescription('Remove a voice channel from custom channel creation.')
.addChannelOption((option) =>
option
.setRequired(true)
.setName('channel')
.addChannelTypes(ChannelType.GuildVoice)
.setDescription('The voice channel to be unregistered.')
) )
); );
export async function execute(interaction) { export async function execute(interaction) {
@ -55,15 +68,13 @@ export async function execute(interaction) {
content: `Successfully created channel!`, content: `Successfully created channel!`,
ephemeral: true ephemeral: true
}); });
console.info(`[INFO] New custom VC created with ID '${channel.id}'.`);
break; break;
} }
case 'register': { case 'register': {
// Get channel id from user input // Get channel id from user input
const id = options.getString('id'); const { id } = options.getChannel('channel');
step = 'fetch';
// Try fetching channel by id
await guild.channels.fetch(id);
// Save channel data // Save channel data
step = 'save'; step = 'save';
@ -74,6 +85,35 @@ export async function execute(interaction) {
content: `Successfully registered channel!`, content: `Successfully registered channel!`,
ephemeral: true ephemeral: true
}); });
console.info(`[INFO] New custom VC registered using ID '${id}'.`);
break;
}
case 'remove': {
// Get channel id from user input
const { id } = options.getChannel('channel');
// Remove channel from guild
step = 'remove';
const count = await VoiceChannel.destroy({
where: {
id,
create: true
}
});
// Set reply based on result of deletion
let response = 'Successfully removed';
if (count === 0)
response = 'Failed to remove';
// Reply to acknowledge command
await interaction.reply({
content: `${response} channel from custom channel creation!`,
ephemeral: true
});
console.info(`[INFO] Removed custom VC with ID '${id}'.`);
break; break;
} }
} }

View File

@ -0,0 +1,11 @@
import { removeSelfRoles } from '../../../../shared.js';
import { ApplicationCommandType, ContextMenuCommandBuilder } from 'discord.js';
export const data = new ContextMenuCommandBuilder()
.setDMPermission(false)
.setName('Remove self roles')
.setType(ApplicationCommandType.Message);
export async function execute(interaction) {
const id = interaction.targetMessage.id;
await removeSelfRoles(interaction, id);
}

View File

@ -50,6 +50,25 @@ const registerSelfRoles = async (interaction) => {
return response; return response;
}; };
const removeSelfRoles = async (interaction, msgID) => {
const { channel } = interaction;
try {
// Try fetching message from channel
await channel.messages.fetch(msgID);
} catch (error) {
console.error(error);
// Reply to acknowledge command
await interaction.reply({
content: `Failed to fetch message!`,
ephemeral: true
});
return;
}
await removeSelfRoles(interaction, msgID);
};
export const data = new SlashCommandBuilder() export const data = new SlashCommandBuilder()
.setName('self_roles') .setName('self_roles')
.setDMPermission(false) .setDMPermission(false)
@ -92,6 +111,17 @@ export const data = new SlashCommandBuilder()
.addStringOption((option) => .addStringOption((option) =>
option.setName('emoji').setRequired(true).setDescription('The emoji to be reacted with.') option.setName('emoji').setRequired(true).setDescription('The emoji to be reacted with.')
) )
)
.addSubcommand((subcommand) =>
subcommand
.setName('remove')
.setDescription('Remove self roles from a message.')
.addStringOption((option) =>
option
.setName('id')
.setRequired(true)
.setDescription('The ID to reference the message to be removed.')
)
); );
export async function execute(interaction) { export async function execute(interaction) {
const { options } = interaction; const { options } = interaction;
@ -120,6 +150,11 @@ export async function execute(interaction) {
await addSelfRoles(interaction, msgID, role, emoji); await addSelfRoles(interaction, msgID, role, emoji);
break; break;
} }
case 'remove': {
const msgID = options.getString('id');
await removeSelfRoles(interaction, msgID);
break;
}
} }
if (createNew) { if (createNew) {

View File

@ -2,24 +2,23 @@ import { ChannelType, Events, PermissionFlagsBits } from 'discord.js';
import { VoiceChannel } from '../../database.js'; import { VoiceChannel } from '../../database.js';
const vcPermissionOverwrites = [ const vcPermissionOverwrites = [
PermissionFlagsBits.ManageRoles,
PermissionFlagsBits.ManageChannels,
PermissionFlagsBits.ViewChannel,
PermissionFlagsBits.ModerateMembers,
PermissionFlagsBits.SendMessages,
PermissionFlagsBits.SendMessagesInThreads,
PermissionFlagsBits.ManageMessages,
PermissionFlagsBits.ReadMessageHistory, PermissionFlagsBits.ReadMessageHistory,
PermissionFlagsBits.AddReactions, PermissionFlagsBits.PrioritySpeaker,
PermissionFlagsBits.Connect, PermissionFlagsBits.ManageMessages,
PermissionFlagsBits.Speak, PermissionFlagsBits.ManageChannels,
PermissionFlagsBits.MuteMembers,
PermissionFlagsBits.DeafenMembers, PermissionFlagsBits.DeafenMembers,
PermissionFlagsBits.SendMessages,
PermissionFlagsBits.ViewChannel,
PermissionFlagsBits.MuteMembers,
PermissionFlagsBits.MoveMembers, PermissionFlagsBits.MoveMembers,
PermissionFlagsBits.UseVAD PermissionFlagsBits.ManageRoles,
PermissionFlagsBits.Connect,
PermissionFlagsBits.Stream,
PermissionFlagsBits.UseVAD,
PermissionFlagsBits.Speak
]; ];
const getchannel = async (member, channels) => { const getChannel = async (member, channels) => {
// Check database for existing channel // Check database for existing channel
const ownCh = await VoiceChannel.findOne({ const ownCh = await VoiceChannel.findOne({
where: { where: {
@ -53,31 +52,68 @@ const getchannel = async (member, channels) => {
return privCh; return privCh;
}; };
const leftVoiceChat = async (state) => {
const { channel } = state;
// Isn't this always false?
if (!channel) return;
// Get active members from channel
const members = Array.from(channel.members);
if (members.length > 0) return;
// Find channel by id, return if not registered as custom
const custom = await VoiceChannel.findOne({
where: {
id: channel.id,
create: false
}
});
if (custom === null) return;
// Delete channel from guild
await channel.guild.channels.delete(channel.id);
console.info(`[INFO] Custom VC with ID '${channel.id}' was empty and got deleted.`);
};
export const name = Events.VoiceStateUpdate; export const name = Events.VoiceStateUpdate;
export async function execute(_, state) { export async function execute(oldState, newState) {
if (!state.channel) return; if (!newState.channel)
return await leftVoiceChat(oldState);
console.log(
Array.from(
newState
.channel
.permissionOverwrites
.cache
.values()
).forEach(overwrite =>
console.log(overwrite.allow.toArray())
)
);
// Find channel by id, return if not registered for customs // Find channel by id, return if not registered for customs
const createCh = await VoiceChannel.findOne({ const createCh = await VoiceChannel.findOne({
where: { where: {
id: state.channel.id, id: newState.channel.id,
create: true, create: true,
} }
}); });
if (createCh === null) return; if (createCh === null) return;
// Extract user data // Extract user data
const member = state.member; const member = newState.member;
// Extract channel data // Extract channel data
const channels = state.guild.channels; const channels = newState.guild.channels;
let step = 'create'; let step = 'create';
try { try {
const privCh = await getchannel(member, channels); const privCh = await getChannel(member, channels);
step = 'move to'; step = 'move to';
// Move user to private channel // Move user to private channel
await state.setChannel(privCh); await newState.setChannel(privCh);
console.info(`[INFO] User '${name}' created private channel with ID ${privCh.id}.`); console.info(`[INFO] User '${name}' created private channel with ID ${privCh.id}.`);
} catch (error) { } catch (error) {
console.error(error); console.error(error);

View File

@ -1,6 +1,30 @@
import { join } from 'path';
import { Op } from 'sequelize'; import { Op } from 'sequelize';
import { readdir } from 'fs/promises';
import { Message, RoleEmojiPair } from './database.js'; import { Message, RoleEmojiPair } from './database.js';
export const removeSelfRoles = async (interaction, id) => {
// Try deleting message from database
const count = await Message.destroy({
where: {
id: id
}
});
// Set reply based on result of deletion
let response = 'Successfully removed';
if (count === 0)
response = 'Failed to remove';
// Reply to acknowledge command
await interaction.reply({
content: `${response} self roles from message!`,
ephemeral: true
});
console.info(`[INFO] Removed self roles from message with ID '${id}'.`);
};
const saveMessageData = async (id, role, emoji) => { const saveMessageData = async (id, role, emoji) => {
// Try finding message // Try finding message
const msg = await Message.findOne({ where: { id } }); const msg = await Message.findOne({ where: { id } });
@ -62,8 +86,6 @@ export const addSelfRoles = async (interaction, msgID, role, emoji) => {
}); });
} }
}; };
import { join } from 'path';
import { readdir } from 'fs/promises';
const required = ['data', 'execute']; const required = ['data', 'execute'];
const optional = ['autocomplete', 'modalSubmit']; const optional = ['autocomplete', 'modalSubmit'];