worked on automod
diff --git a/TODO.json b/TODO.json
index 4637953..90fe168 100644
--- a/TODO.json
+++ b/TODO.json
@@ -1,10 +1,5 @@
{
"filters": {
- "images": {
- "NSFW": false,
- "size": false
- },
- "malware": false,
"wordFilter": {
"enabled": true,
"words": {
diff --git a/src/commands/settings/filters.ts b/src/commands/settings/filters.ts
deleted file mode 100644
index 7636f91..0000000
--- a/src/commands/settings/filters.ts
+++ /dev/null
@@ -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 };
diff --git a/src/commands/settings/filters/_meta.ts b/src/commands/settings/filters/_meta.ts
deleted file mode 100644
index d2aff53..0000000
--- a/src/commands/settings/filters/_meta.ts
+++ /dev/null
@@ -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};
diff --git a/src/commands/settings/rolemenu.ts b/src/commands/settings/rolemenu.ts
index 9528183..90b224d 100644
--- a/src/commands/settings/rolemenu.ts
+++ b/src/commands/settings/rolemenu.ts
@@ -364,7 +364,7 @@
new ButtonBuilder()
.setCustomId("reorder")
.setLabel("Reorder Pages")
- .setEmoji(getEmojiByName("ICONS.SHUFFLE", "id") as APIMessageComponentEmoji)
+ .setEmoji(getEmojiByName("ICONS.REORDER", "id") as APIMessageComponentEmoji)
.setStyle(ButtonStyle.Secondary)
.setDisabled(Object.keys(currentObject).length <= 1),
new ButtonBuilder()
diff --git a/src/commands/settings/tracks.ts b/src/commands/settings/tracks.ts
index 782f52f..354a948 100644
--- a/src/commands/settings/tracks.ts
+++ b/src/commands/settings/tracks.ts
@@ -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 createPageIndicator, { createVerticalTrack } from "../../utils/createPageIndicator.js";
import { LoadingEmbed } from "../../utils/defaults.js";
@@ -7,6 +7,8 @@
import ellipsis from "../../utils/ellipsis.js";
import { modalInteractionCollector } from "../../utils/dualCollector.js";
+const { renderRole } = client.logger
+
const command = (builder: SlashCommandSubcommandBuilder) =>
builder
.setName("tracks")
@@ -20,6 +22,7 @@
manageableBy: string[];
}
+
const editName = async (i: ButtonInteraction, interaction: StringSelectMenuInteraction | ButtonInteraction, m: Message, current?: string) => {
let name = current ?? "";
@@ -134,6 +137,7 @@
}
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) {
current = {
name: "",
@@ -143,40 +147,25 @@
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>()
.addComponents(
new RoleSelectMenuBuilder()
.setCustomId("addRole")
.setPlaceholder("Select a role to add")
+ .setDisabled(!isAdmin)
);
let closed = false;
do {
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[];
const selectMenu = new ActionRowBuilder<StringSelectMenuBuilder>()
.addComponents(
new StringSelectMenuBuilder()
.setCustomId("removeRole")
.setPlaceholder("Select a role to remove")
+ .setDisabled(!isAdmin)
.addOptions(
editableRoles.map((r, i) => {
return new StringSelectMenuOptionBuilder()
@@ -185,23 +174,56 @@
)
)
);
+ 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[] = [];
for (const role of current.track) {
const disabled: boolean =
roles.get(role)!.position >= (interaction.member as GuildMember).roles.highest.position;
allowed.push(disabled)
}
+ const mapped = current.track.map(role => roles.find(aRole => aRole.id === role)!);
const embed = new EmojiEmbed()
.setTitle("Tracks")
.setDescription(
`**Currently Editing:** ${current.name}\n\n` +
- `${getEmojiByName} Members ${current.nullable ? "don't " : ""}need a role in this track` +
- `${getEmojiByName} Members ${current.retainPrevious ? "don't " : ""}keep all roles below their current highest` +
- createVerticalTrack(current.track, new Array(current.track.length).fill(false), allowed)
+ `${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` +
+ 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;
@@ -227,6 +249,13 @@
break;
case "reorder":
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()) {
out.deferUpdate();
@@ -258,8 +287,6 @@
const config = await client.database.guilds.read(interaction.guild!.id);
const tracks: ObjectSchema[] = config.tracks;
const roles = await interaction.guild!.roles.fetch();
- const memberRoles = interaction.member!.roles;
- const member = interaction.member as GuildMember;
let page = 0;
let closed = false;
@@ -329,10 +356,11 @@
} else {
page = Math.min(page, Object.keys(tracks).length - 1);
current = tracks[page]!;
+ const mapped = current.track.map(role => roles.find(aRole => aRole.id === role)!);
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.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)}`
);
@@ -372,7 +400,7 @@
page = tracks.length - 1;
break;
case "save":
- // client.database.guilds.write(interaction.guild!.id, {"roleMenu.options": tracks}); // TODO
+ client.database.guilds.write(interaction.guild!.id, {tracks: tracks});
modified = false;
break;
}
diff --git a/src/config/default.json b/src/config/default.json
index 8e4197c..9129765 100644
--- a/src/config/default.json
+++ b/src/config/default.json
@@ -15,12 +15,17 @@
"words": {
"strict": [],
"loose": []
+ },
+ "allowed": {
+ "user": [],
+ "roles": [],
+ "channels": []
}
},
"invite": {
"enabled": false,
"allowed": {
- "users": [],
+ "user": [],
"roles": [],
"channels": []
}
@@ -28,7 +33,13 @@
"pings": {
"mass": 5,
"everyone": true,
- "roles": true
+ "roles": true,
+ "allowed": {
+ "user": [],
+ "roles": [],
+ "channels": [],
+ "rolesToMention": []
+ }
}
},
"welcome": {
diff --git a/src/config/emojis.json b/src/config/emojis.json
index abeb52a..9ccb9fa 100644
--- a/src/config/emojis.json
+++ b/src/config/emojis.json
@@ -25,7 +25,7 @@
"ATTACHMENT": "997570687193587812",
"LOGGING": "999613304446144562",
"SAVE": "1065722246322200586",
- "SHUFFLE": "1069323453909454890",
+ "REORDER": "1069323453909454890",
"NOTIFY": {
"ON": "1000726394579464232",
"OFF": "1000726363495477368"
diff --git a/src/events/messageDelete.ts b/src/events/messageDelete.ts
index f8433fc..9563a33 100644
--- a/src/events/messageDelete.ts
+++ b/src/events/messageDelete.ts
@@ -4,61 +4,58 @@
export const event = "messageDelete";
export async function callback(client: NucleusClient, message: Message) {
- try {
- if (message.author.id === client.user!.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 auditLog = (await getAuditLog(message.guild!, AuditLogEvent.MemberBanAdd))
- .filter((entry: GuildAuditLogsEntry) => (entry.target! as User).id === message.author.id)[0];
- if (auditLog) {
- 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);
+ 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;
+ const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = client.logger;
+ const auditLog = (await getAuditLog(message.guild!, AuditLogEvent.MemberBanAdd))
+ .filter((entry: GuildAuditLogsEntry) => (entry.target! as User).id === message.author.id)[0];
+ if (auditLog) {
+ 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);
}
diff --git a/src/events/messageEdit.ts b/src/events/messageEdit.ts
index caa00f6..d491641 100644
--- a/src/events/messageEdit.ts
+++ b/src/events/messageEdit.ts
@@ -6,6 +6,7 @@
export async function callback(client: NucleusClient, oldMessage: Message, newMessage: Message) {
if (newMessage.author.id === client.user!.id) return;
+ if (newMessage.author.bot) return;
if (!newMessage.guild) return;
const { log, NucleusColors, entry, renderUser, renderDelta, renderNumberDelta, renderChannel } = client.logger;
const replyTo: MessageReference | null = newMessage.reference;
diff --git a/src/index.ts b/src/index.ts
index 306811e..a3a8d38 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -19,4 +19,4 @@
await client.login(config.enableDevelopment ? config.developmentToken : config.token)
-await recordPerformance();
\ No newline at end of file
+await recordPerformance();
diff --git a/src/premium/attachmentLogs.ts b/src/premium/attachmentLogs.ts
index 628c2ec..078587e 100644
--- a/src/premium/attachmentLogs.ts
+++ b/src/premium/attachmentLogs.ts
@@ -13,7 +13,7 @@
const attachments = [];
for (const attachment of message.attachments.values()) {
attachments.push({
- local: await saveAttachment(attachment.url),
+ local: (await saveAttachment(attachment.url))[0],
url: attachment.url,
height: attachment.height,
width: attachment.width,
@@ -24,7 +24,7 @@
for (const link of links) {
if (link.toLowerCase().match(/\.(jpg|jpeg|png|gif|gifv|webm|webp|mp4|wav|mp3|ogg)$/gi)) {
attachments.push({
- local: await saveAttachment(link),
+ local: (await saveAttachment(link))[0],
url: link,
height: null,
width: null
@@ -70,7 +70,6 @@
],
files: attachments.map((file) => file.local)
});
- // await client.database.guilds.write(interaction.guild.id, {[`tags.${name}`]: value});
client.database.guilds.write(message.guild.id, {
[`logging.attachments.saved.${message.channel.id}${message.id}`]: m.url
});