worked on automod

pull/11/head
TheCodedProf 3 years ago
parent d5a67fb2e1
commit 4f79da1cdb

@ -1,10 +1,5 @@
{ {
"filters": { "filters": {
"images": {
"NSFW": false,
"size": false
},
"malware": false,
"wordFilter": { "wordFilter": {
"enabled": true, "enabled": true,
"words": { "words": {

@ -1,21 +0,0 @@
import type Discord from "discord.js";
import type { CommandInteraction } from "discord.js";
import type { SlashCommandSubcommandBuilder } from "discord.js";
const command = (builder: SlashCommandSubcommandBuilder) =>
builder.setName("filter").setDescription("Setting for message filters");
const callback = async (_interaction: CommandInteraction): Promise<void> => {
console.log("Filters");
};
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 };

@ -1,8 +0,0 @@
import { group } from "../../../utils/commandRegistration/slashCommandBuilder.js";
const name = "filters";
const description = "Settings for filters";
const subcommand = await group(name, description, `settings/filters`)
export { name, description, subcommand as command};

@ -364,7 +364,7 @@ const callback = async (interaction: CommandInteraction): Promise<void> => {
new ButtonBuilder() new ButtonBuilder()
.setCustomId("reorder") .setCustomId("reorder")
.setLabel("Reorder Pages") .setLabel("Reorder Pages")
.setEmoji(getEmojiByName("ICONS.SHUFFLE", "id") as APIMessageComponentEmoji) .setEmoji(getEmojiByName("ICONS.REORDER", "id") as APIMessageComponentEmoji)
.setStyle(ButtonStyle.Secondary) .setStyle(ButtonStyle.Secondary)
.setDisabled(Object.keys(currentObject).length <= 1), .setDisabled(Object.keys(currentObject).length <= 1),
new ButtonBuilder() new ButtonBuilder()

@ -1,4 +1,4 @@
import { ActionRowBuilder, APIMessageComponentEmoji, ButtonBuilder, ButtonInteraction, ButtonStyle, Collection, CommandInteraction, GuildMember, Message, ModalBuilder, ModalSubmitInteraction, Role, RoleSelectMenuBuilder, RoleSelectMenuInteraction, SlashCommandSubcommandBuilder, StringSelectMenuBuilder, StringSelectMenuInteraction, StringSelectMenuOptionBuilder, TextInputBuilder, TextInputStyle } from "discord.js"; import { ActionRowBuilder, APIMessageComponentEmoji, ButtonBuilder, ButtonInteraction, ButtonStyle, Collection, CommandInteraction, GuildMember, Message, ModalBuilder, ModalSubmitInteraction, PermissionsBitField, Role, RoleSelectMenuBuilder, RoleSelectMenuInteraction, SlashCommandSubcommandBuilder, StringSelectMenuBuilder, StringSelectMenuInteraction, StringSelectMenuOptionBuilder, TextInputBuilder, TextInputStyle } from "discord.js";
import client from "../../utils/client.js"; import client from "../../utils/client.js";
import createPageIndicator, { createVerticalTrack } from "../../utils/createPageIndicator.js"; import createPageIndicator, { createVerticalTrack } from "../../utils/createPageIndicator.js";
import { LoadingEmbed } from "../../utils/defaults.js"; import { LoadingEmbed } from "../../utils/defaults.js";
@ -7,6 +7,8 @@ import getEmojiByName from "../../utils/getEmojiByName.js";
import ellipsis from "../../utils/ellipsis.js"; import ellipsis from "../../utils/ellipsis.js";
import { modalInteractionCollector } from "../../utils/dualCollector.js"; import { modalInteractionCollector } from "../../utils/dualCollector.js";
const { renderRole } = client.logger
const command = (builder: SlashCommandSubcommandBuilder) => const command = (builder: SlashCommandSubcommandBuilder) =>
builder builder
.setName("tracks") .setName("tracks")
@ -20,6 +22,7 @@ interface ObjectSchema {
manageableBy: string[]; manageableBy: string[];
} }
const editName = async (i: ButtonInteraction, interaction: StringSelectMenuInteraction | ButtonInteraction, m: Message, current?: string) => { const editName = async (i: ButtonInteraction, interaction: StringSelectMenuInteraction | ButtonInteraction, m: Message, current?: string) => {
let name = current ?? ""; let name = current ?? "";
@ -134,6 +137,7 @@ const reorderTracks = async (interaction: ButtonInteraction, m: Message, roles:
} }
const editTrack = async (interaction: ButtonInteraction | StringSelectMenuInteraction, message: Message, roles: Collection<string, Role>, current?: ObjectSchema) => { const editTrack = async (interaction: ButtonInteraction | StringSelectMenuInteraction, message: Message, roles: Collection<string, Role>, current?: ObjectSchema) => {
const isAdmin = (interaction.member!.permissions as PermissionsBitField).has("Administrator");
if(!current) { if(!current) {
current = { current = {
name: "", name: "",
@ -143,40 +147,25 @@ const editTrack = async (interaction: ButtonInteraction | StringSelectMenuIntera
manageableBy: [] manageableBy: []
} }
} }
const buttons = new ActionRowBuilder<ButtonBuilder>()
.addComponents(
new ButtonBuilder()
.setCustomId("back")
.setLabel("Back")
.setStyle(ButtonStyle.Secondary)
.setEmoji(getEmojiByName("CONTROL.LEFT", "id") as APIMessageComponentEmoji),
new ButtonBuilder()
.setCustomId("edit")
.setLabel("Edit Name")
.setStyle(ButtonStyle.Primary)
.setEmoji(getEmojiByName("ICONS.EDIT", "id") as APIMessageComponentEmoji),
new ButtonBuilder()
.setCustomId("reorder")
.setLabel("Reorder")
.setStyle(ButtonStyle.Primary)
.setEmoji(getEmojiByName("ICONS.REORDER", "id") as APIMessageComponentEmoji),
);
const roleSelect = new ActionRowBuilder<RoleSelectMenuBuilder>() const roleSelect = new ActionRowBuilder<RoleSelectMenuBuilder>()
.addComponents( .addComponents(
new RoleSelectMenuBuilder() new RoleSelectMenuBuilder()
.setCustomId("addRole") .setCustomId("addRole")
.setPlaceholder("Select a role to add") .setPlaceholder("Select a role to add")
.setDisabled(!isAdmin)
); );
let closed = false; let closed = false;
do { do {
const editableRoles: string[] = current.track.map((r) => { const editableRoles: string[] = current.track.map((r) => {
if(!(roles.get(r)!.position >= (interaction.member as GuildMember).roles.highest.position)) return r; if(!(roles.get(r)!.position >= (interaction.member as GuildMember).roles.highest.position)) return roles.get(r)!.name;
}).filter(v => v !== undefined) as string[]; }).filter(v => v !== undefined) as string[];
const selectMenu = new ActionRowBuilder<StringSelectMenuBuilder>() const selectMenu = new ActionRowBuilder<StringSelectMenuBuilder>()
.addComponents( .addComponents(
new StringSelectMenuBuilder() new StringSelectMenuBuilder()
.setCustomId("removeRole") .setCustomId("removeRole")
.setPlaceholder("Select a role to remove") .setPlaceholder("Select a role to remove")
.setDisabled(!isAdmin)
.addOptions( .addOptions(
editableRoles.map((r, i) => { editableRoles.map((r, i) => {
return new StringSelectMenuOptionBuilder() return new StringSelectMenuOptionBuilder()
@ -185,23 +174,56 @@ const editTrack = async (interaction: ButtonInteraction | StringSelectMenuIntera
) )
) )
); );
const buttons = new ActionRowBuilder<ButtonBuilder>()
.addComponents(
new ButtonBuilder()
.setCustomId("back")
.setLabel("Back")
.setStyle(ButtonStyle.Secondary)
.setEmoji(getEmojiByName("CONTROL.LEFT", "id") as APIMessageComponentEmoji),
new ButtonBuilder()
.setCustomId("edit")
.setLabel("Edit Name")
.setStyle(ButtonStyle.Primary)
.setEmoji(getEmojiByName("ICONS.EDIT", "id") as APIMessageComponentEmoji),
new ButtonBuilder()
.setCustomId("reorder")
.setLabel("Reorder")
.setDisabled(!isAdmin)
.setStyle(ButtonStyle.Primary)
.setEmoji(getEmojiByName("ICONS.REORDER", "id") as APIMessageComponentEmoji),
new ButtonBuilder()
.setCustomId("retainPrevious")
.setLabel("Retain Previous")
.setStyle(current.retainPrevious ? ButtonStyle.Success : ButtonStyle.Danger)
.setEmoji(getEmojiByName("CONTROL." + (current.retainPrevious ? "TICK" : "CROSS"), "id") as APIMessageComponentEmoji),
new ButtonBuilder()
.setCustomId("nullable")
.setLabel(`Role ${current.nullable ? "Not " : ""}Required`)
.setStyle(current.nullable ? ButtonStyle.Success : ButtonStyle.Danger)
.setEmoji(getEmojiByName("CONTROL." + (current.nullable ? "TICK" : "CROSS"), "id") as APIMessageComponentEmoji)
);
let allowed: boolean[] = []; let allowed: boolean[] = [];
for (const role of current.track) { for (const role of current.track) {
const disabled: boolean = const disabled: boolean =
roles.get(role)!.position >= (interaction.member as GuildMember).roles.highest.position; roles.get(role)!.position >= (interaction.member as GuildMember).roles.highest.position;
allowed.push(disabled) allowed.push(disabled)
} }
const mapped = current.track.map(role => roles.find(aRole => aRole.id === role)!);
const embed = new EmojiEmbed() const embed = new EmojiEmbed()
.setTitle("Tracks") .setTitle("Tracks")
.setDescription( .setDescription(
`**Currently Editing:** ${current.name}\n\n` + `**Currently Editing:** ${current.name}\n\n` +
`${getEmojiByName} Members ${current.nullable ? "don't " : ""}need a role in this track` + `${getEmojiByName("CONTROL." + (current.nullable ? "CROSS" : "TICK"))} Members ${current.nullable ? "don't " : ""}need a role in this track\n` +
`${getEmojiByName} Members ${current.retainPrevious ? "don't " : ""}keep all roles below their current highest` + `${getEmojiByName("CONTROL." + (current.retainPrevious ? "TICK" : "CROSS"))} Members ${current.retainPrevious ? "" : "don't "}keep all roles below their current highest\n\n` +
createVerticalTrack(current.track, new Array(current.track.length).fill(false), allowed) createVerticalTrack(
mapped.map(role => renderRole(role)), new Array(current.track.length).fill(false), allowed)
) )
.setStatus("Success")
interaction.editReply({embeds: [embed], components: [buttons, roleSelect, selectMenu]}); interaction.editReply({embeds: [embed], components: [roleSelect, selectMenu, buttons]});
let out: ButtonInteraction | RoleSelectMenuInteraction | StringSelectMenuInteraction | null; let out: ButtonInteraction | RoleSelectMenuInteraction | StringSelectMenuInteraction | null;
@ -227,6 +249,13 @@ const editTrack = async (interaction: ButtonInteraction | StringSelectMenuIntera
break; break;
case "reorder": case "reorder":
current.track = (await reorderTracks(out, message, roles, current.track))!; current.track = (await reorderTracks(out, message, roles, current.track))!;
break;
case "retainPrevious":
current.retainPrevious = !current.retainPrevious;
break;
case "nullable":
current.nullable = !current.nullable;
break;
} }
} else if (out.isStringSelectMenu()) { } else if (out.isStringSelectMenu()) {
out.deferUpdate(); out.deferUpdate();
@ -258,8 +287,6 @@ const callback = async (interaction: CommandInteraction) => {
const config = await client.database.guilds.read(interaction.guild!.id); const config = await client.database.guilds.read(interaction.guild!.id);
const tracks: ObjectSchema[] = config.tracks; const tracks: ObjectSchema[] = config.tracks;
const roles = await interaction.guild!.roles.fetch(); const roles = await interaction.guild!.roles.fetch();
const memberRoles = interaction.member!.roles;
const member = interaction.member as GuildMember;
let page = 0; let page = 0;
let closed = false; let closed = false;
@ -329,10 +356,11 @@ const callback = async (interaction: CommandInteraction) => {
} else { } else {
page = Math.min(page, Object.keys(tracks).length - 1); page = Math.min(page, Object.keys(tracks).length - 1);
current = tracks[page]!; current = tracks[page]!;
const mapped = current.track.map(role => roles.find(aRole => aRole.id === role)!);
embed.setDescription(`**Currently Editing:** ${current.name}\n\n` + embed.setDescription(`**Currently Editing:** ${current.name}\n\n` +
`${getEmojiByName("CONTROL." + (current.nullable ? "CROSS" : "TICK"))} Members ${current.nullable ? "don't " : ""}need a role in this track\n` + `${getEmojiByName("CONTROL." + (current.nullable ? "CROSS" : "TICK"))} Members ${current.nullable ? "don't " : ""}need a role in this track\n` +
`${getEmojiByName("CONTROL." + (current.retainPrevious ? "TICK" : "CROSS"))} Members ${current.retainPrevious ? "" : "don't "}keep all roles below their current highest\n\n` + `${getEmojiByName("CONTROL." + (current.retainPrevious ? "TICK" : "CROSS"))} Members ${current.retainPrevious ? "" : "don't "}keep all roles below their current highest\n\n` +
createVerticalTrack(current.track, new Array(current.track.length).fill(false)) + createVerticalTrack(mapped.map(role => renderRole(role)), new Array(current.track.length).fill(false)) +
`\n${createPageIndicator(config.tracks.length, page)}` `\n${createPageIndicator(config.tracks.length, page)}`
); );
@ -372,7 +400,7 @@ const callback = async (interaction: CommandInteraction) => {
page = tracks.length - 1; page = tracks.length - 1;
break; break;
case "save": case "save":
// client.database.guilds.write(interaction.guild!.id, {"roleMenu.options": tracks}); // TODO client.database.guilds.write(interaction.guild!.id, {tracks: tracks});
modified = false; modified = false;
break; break;
} }

@ -15,12 +15,17 @@
"words": { "words": {
"strict": [], "strict": [],
"loose": [] "loose": []
},
"allowed": {
"user": [],
"roles": [],
"channels": []
} }
}, },
"invite": { "invite": {
"enabled": false, "enabled": false,
"allowed": { "allowed": {
"users": [], "user": [],
"roles": [], "roles": [],
"channels": [] "channels": []
} }
@ -28,7 +33,13 @@
"pings": { "pings": {
"mass": 5, "mass": 5,
"everyone": true, "everyone": true,
"roles": true "roles": true,
"allowed": {
"user": [],
"roles": [],
"channels": [],
"rolesToMention": []
}
} }
}, },
"welcome": { "welcome": {

@ -25,7 +25,7 @@
"ATTACHMENT": "997570687193587812", "ATTACHMENT": "997570687193587812",
"LOGGING": "999613304446144562", "LOGGING": "999613304446144562",
"SAVE": "1065722246322200586", "SAVE": "1065722246322200586",
"SHUFFLE": "1069323453909454890", "REORDER": "1069323453909454890",
"NOTIFY": { "NOTIFY": {
"ON": "1000726394579464232", "ON": "1000726394579464232",
"OFF": "1000726363495477368" "OFF": "1000726363495477368"

@ -4,61 +4,58 @@ import Discord, { AuditLogEvent, GuildAuditLogsEntry, Message, User } from "disc
export const event = "messageDelete"; export const event = "messageDelete";
export async function callback(client: NucleusClient, message: Message) { export async function callback(client: NucleusClient, message: Message) {
try { if (message.author.id === client.user!.id) return;
if (message.author.id === client.user!.id) return; if (message.author.bot) return;
if (client.noLog.includes(`${message.id}/${message.channel.id}/${message.id}`)) return; if (client.noLog.includes(`${message.id}/${message.channel.id}/${message.id}`)) return;
const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = client.logger; const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = client.logger;
const auditLog = (await getAuditLog(message.guild!, AuditLogEvent.MemberBanAdd)) const auditLog = (await getAuditLog(message.guild!, AuditLogEvent.MemberBanAdd))
.filter((entry: GuildAuditLogsEntry) => (entry.target! as User).id === message.author.id)[0]; .filter((entry: GuildAuditLogsEntry) => (entry.target! as User).id === message.author.id)[0];
if (auditLog) { if (auditLog) {
if (auditLog.createdTimestamp - 1000 < new Date().getTime()) return; if (auditLog.createdTimestamp - 1000 < new Date().getTime()) return;
}
const replyTo = message.reference;
let content = message.cleanContent;
content.replace("`", "\\`");
if (content.length > 256) content = content.substring(0, 253) + "...";
const attachments =
message.attachments.size + (
message.content.match(
/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/gi
) ?? []
).length;
let attachmentJump = "";
const config = (await client.database.guilds.read(message.guild!.id)).logging.attachments.saved[
message.channel.id + message.id
];
if (config) { attachmentJump = ` [[View attachments]](${config})`; }
const data = {
meta: {
type: "messageDelete",
displayName: "Message Deleted",
calculateType: "messageDelete",
color: NucleusColors.red,
emoji: "MESSAGE.DELETE",
timestamp: new Date().getTime()
},
separate: {
start: content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*"
},
list: {
messageId: entry(message.id, `\`${message.id}\``),
sentBy: entry(message.author.id, renderUser(message.author)),
sentIn: entry(message.channel.id, renderChannel(message.channel as Discord.GuildChannel | Discord.ThreadChannel)),
deleted: entry(new Date().getTime(), renderDelta(new Date().getTime())),
mentions: message.mentions.users.size,
attachments: entry(attachments, attachments + attachmentJump),
repliedTo: entry(
replyTo ? replyTo.messageId! : null,
replyTo ? `[[Jump to message]](https://discord.com/channels/${message.guild!.id}/${message.channel.id}/${replyTo.messageId})`
: "None"
)
},
hidden: {
guild: message.guild!.id
}
};
log(data);
} catch (e) {
console.log(e);
} }
const replyTo = message.reference;
let content = message.cleanContent;
content.replace("`", "\\`");
if (content.length > 256) content = content.substring(0, 253) + "...";
const attachments =
message.attachments.size + (
message.content.match(
/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/gi
) ?? []
).length;
let attachmentJump = "";
const config = (await client.database.guilds.read(message.guild!.id)).logging.attachments.saved[
message.channel.id + message.id
];
if (config) { attachmentJump = ` [[View attachments]](${config})`; }
const data = {
meta: {
type: "messageDelete",
displayName: "Message Deleted",
calculateType: "messageDelete",
color: NucleusColors.red,
emoji: "MESSAGE.DELETE",
timestamp: new Date().getTime()
},
separate: {
start: content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*"
},
list: {
messageId: entry(message.id, `\`${message.id}\``),
sentBy: entry(message.author.id, renderUser(message.author)),
sentIn: entry(message.channel.id, renderChannel(message.channel as Discord.GuildChannel | Discord.ThreadChannel)),
deleted: entry(new Date().getTime(), renderDelta(new Date().getTime())),
mentions: message.mentions.users.size,
attachments: entry(attachments, attachments + attachmentJump),
repliedTo: entry(
replyTo ? replyTo.messageId! : null,
replyTo ? `[[Jump to message]](https://discord.com/channels/${message.guild!.id}/${message.channel.id}/${replyTo.messageId})`
: "None"
)
},
hidden: {
guild: message.guild!.id
}
};
log(data);
} }

@ -6,6 +6,7 @@ export const event = "messageUpdate";
export async function callback(client: NucleusClient, oldMessage: Message, newMessage: Message) { export async function callback(client: NucleusClient, oldMessage: Message, newMessage: Message) {
if (newMessage.author.id === client.user!.id) return; if (newMessage.author.id === client.user!.id) return;
if (newMessage.author.bot) return;
if (!newMessage.guild) return; if (!newMessage.guild) return;
const { log, NucleusColors, entry, renderUser, renderDelta, renderNumberDelta, renderChannel } = client.logger; const { log, NucleusColors, entry, renderUser, renderDelta, renderNumberDelta, renderChannel } = client.logger;
const replyTo: MessageReference | null = newMessage.reference; const replyTo: MessageReference | null = newMessage.reference;

@ -19,4 +19,4 @@ process.on("uncaughtException", (err) => { console.error(err) });
await client.login(config.enableDevelopment ? config.developmentToken : config.token) await client.login(config.enableDevelopment ? config.developmentToken : config.token)
await recordPerformance(); await recordPerformance();

@ -13,7 +13,7 @@ export default async function logAttachment(message: Message): Promise<Attachmen
const attachments = []; const attachments = [];
for (const attachment of message.attachments.values()) { for (const attachment of message.attachments.values()) {
attachments.push({ attachments.push({
local: await saveAttachment(attachment.url), local: (await saveAttachment(attachment.url))[0],
url: attachment.url, url: attachment.url,
height: attachment.height, height: attachment.height,
width: attachment.width, width: attachment.width,
@ -24,7 +24,7 @@ export default async function logAttachment(message: Message): Promise<Attachmen
for (const link of links) { for (const link of links) {
if (link.toLowerCase().match(/\.(jpg|jpeg|png|gif|gifv|webm|webp|mp4|wav|mp3|ogg)$/gi)) { if (link.toLowerCase().match(/\.(jpg|jpeg|png|gif|gifv|webm|webp|mp4|wav|mp3|ogg)$/gi)) {
attachments.push({ attachments.push({
local: await saveAttachment(link), local: (await saveAttachment(link))[0],
url: link, url: link,
height: null, height: null,
width: null width: null
@ -70,7 +70,6 @@ export default async function logAttachment(message: Message): Promise<Attachmen
], ],
files: attachments.map((file) => file.local) files: attachments.map((file) => file.local)
}); });
// await client.database.guilds.write(interaction.guild.id, {[`tags.${name}`]: value});
client.database.guilds.write(message.guild.id, { client.database.guilds.write(message.guild.id, {
[`logging.attachments.saved.${message.channel.id}${message.id}`]: m.url [`logging.attachments.saved.${message.channel.id}${message.id}`]: m.url
}); });

Loading…
Cancel
Save