blob: b9f2453d6df38bd7269266260e9f32336e3a756e [file] [log] [blame]
import type Discord from "discord.js";
import { ActionRowBuilder, APIMessageComponentEmoji, ButtonBuilder, ButtonInteraction, ButtonStyle, CommandInteraction, Message, StringSelectMenuBuilder, StringSelectMenuInteraction, StringSelectMenuOptionBuilder } from "discord.js";
import type { SlashCommandSubcommandBuilder } from "discord.js";
import { LoadingEmbed } from "../../utils/defaults.js";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import client from "../../utils/client.js";
import getEmojiByName from "../../utils/getEmojiByName.js";
const command = (builder: SlashCommandSubcommandBuilder) =>
builder.setName("automod").setDescription("Setting for automatic moderation features");
const emojiFromBoolean = (bool: boolean, id?: string) => bool ? getEmojiByName("CONTROL.TICK", id) : getEmojiByName("CONTROL.CROSS", id);
const imageMenu = async (interaction: StringSelectMenuInteraction, m: Message, current: {
NSFW: boolean,
size: boolean
}): Promise<{NSFW: boolean, size: boolean}> => {
let closed = false;
do {
const options = new ActionRowBuilder<ButtonBuilder>()
.addComponents(
new ButtonBuilder()
.setCustomId("back")
.setLabel("Back")
.setStyle(ButtonStyle.Secondary)
.setEmoji(getEmojiByName("CONTROL.LEFT", "id") as APIMessageComponentEmoji),
new ButtonBuilder()
.setCustomId("nsfw")
.setLabel("NSFW")
.setStyle(current.NSFW ? ButtonStyle.Success : ButtonStyle.Danger)
.setEmoji(emojiFromBoolean(current.NSFW, "id") as APIMessageComponentEmoji),
new ButtonBuilder()
.setCustomId("size")
.setLabel("Size")
.setStyle(current.size ? ButtonStyle.Success : ButtonStyle.Danger)
.setEmoji(emojiFromBoolean(current.size, "id") as APIMessageComponentEmoji)
)
const embed = new EmojiEmbed()
.setTitle("Image Settings")
.setDescription(
`${emojiFromBoolean(current.NSFW)} **NSFW**\n` +
`${emojiFromBoolean(current.size)} **Size**\n`
)
await interaction.editReply({embeds: [embed], components: [options]});
let i: ButtonInteraction;
try {
i = await m.awaitMessageComponent({filter: (i) => interaction.user.id === i.user.id && i.message.id === m.id, time: 300000}) as ButtonInteraction;
} catch (e) {
return current;
}
await i.deferUpdate();
switch(i.customId) {
case "back":
closed = true;
break;
case "nsfw":
current.NSFW = !current.NSFW;
break;
case "size":
current.size = !current.size;
break;
}
} while(!closed);
return current;
}
const wordMenu = async (interaction: StringSelectMenuInteraction, m: Message, current: {
enabled: boolean,
words: {strict: string[], loose: string[]},
allowed: {user: string[], roles: string[], channels: string[]}
}): Promise<{
enabled: boolean,
words: {strict: string[], loose: string[]},
allowed: {user: string[], roles: string[], channels: string[]}
}> => {
}
const inviteMenu = async (interaction: StringSelectMenuInteraction, m: Message, current: {
enabled: boolean,
allowed: {user: string[], roles: string[], channels: string[]}
}): Promise<{
enabled: boolean,
allowed: {user: string[], roles: string[], channels: string[]}
}> => {
}
const mentionMenu = async (interaction: StringSelectMenuInteraction, m: Message, current: {
mass: number,
everyone: boolean,
roles: boolean,
allowed: {
roles: string[],
rolesToMention: string[],
users: string[],
channels: string[]
}
}): Promise<{
mass: number,
everyone: boolean,
roles: boolean,
allowed: {
roles: string[],
rolesToMention: string[],
users: string[],
channels: string[]
}
}> => {
}
const callback = async (interaction: CommandInteraction): Promise<void> => {
if (!interaction.guild) return;
const m = await interaction.reply({embeds: LoadingEmbed, fetchReply: true, ephemeral: true});
const config = (await client.database.guilds.read(interaction.guild.id)).filters;
let closed = false;
const button = new ActionRowBuilder<ButtonBuilder>()
.addComponents(
new ButtonBuilder()
.setCustomId("save")
.setLabel("Save")
.setStyle(ButtonStyle.Success)
)
do {
const selectMenu = new ActionRowBuilder<StringSelectMenuBuilder>()
.addComponents(
new StringSelectMenuBuilder()
.setCustomId("filter")
.setPlaceholder("Select a filter to edit")
.addOptions(
new StringSelectMenuOptionBuilder()
.setLabel("Invites")
.setDescription("Automatically delete messages containing server invites")
.setValue("invites"),
new StringSelectMenuOptionBuilder()
.setLabel("Mentions")
.setDescription("Deletes messages with excessive mentions")
.setValue("mentions"),
new StringSelectMenuOptionBuilder()
.setLabel("Words")
.setDescription("Delete messages containing filtered words")
.setValue("words"),
new StringSelectMenuOptionBuilder()
.setLabel("Malware")
.setDescription("Automatically delete files and links containing malware")
.setValue("malware"),
new StringSelectMenuOptionBuilder()
.setLabel("Images")
.setDescription("Checks performed on images (NSFW, size checking, etc.)")
.setValue("images")
)
);
const embed = new EmojiEmbed()
.setTitle("Automod Settings")
.setDescription(
`${emojiFromBoolean(config.invite.enabled)} **Invites**}\n` +
`${emojiFromBoolean(config.pings.everyone || config.pings.mass > 0 || config.pings.roles)} **Mentions**\n` +
`${emojiFromBoolean(config.wordFilter.enabled)} **Words**\n` +
`${emojiFromBoolean(config.malware)} **Malware**\n` +
`${emojiFromBoolean(config.images.NSFW || config.images.size)} **Images**}\n`
)
await interaction.editReply({embeds: [embed], components: [selectMenu, button]});
let i: StringSelectMenuInteraction | ButtonInteraction;
try {
i = await m.awaitMessageComponent({filter: (i) => i.user.id === interaction.user.id && i.message.id === m.id, time: 300000}) as StringSelectMenuInteraction | ButtonInteraction;
} catch (e) {
closed = true;
return;
}
if(!i) return;
if(i.isButton()) {
await i.deferUpdate();
await client.database.guilds.write(interaction.guild.id, {filters: config});
} else {
switch(i.values[0]) {
case "invites":
break;
case "mentions":
break;
case "words":
break;
case "malware":
await i.deferUpdate();
config.malware = !config.malware;
break;
case "images":
let next = await imageMenu(i, m, config.images);
if(next) config.images = next;
break;
}
}
} while(!closed)
};
const check = (interaction: CommandInteraction, _partial: boolean = false) => {
const member = interaction.member as Discord.GuildMember;
if (!member.permissions.has("ManageMessages"))
return "You must have the *Manage Messages* permission to use this command";
return true;
};
export { command };
export { callback };
export { check };