Fix a bunch of linter errors
diff --git a/src/Unfinished/all.ts b/src/Unfinished/all.ts
index 51be5cb..453a467 100644
--- a/src/Unfinished/all.ts
+++ b/src/Unfinished/all.ts
@@ -1,5 +1,11 @@
import { LoadingEmbed } from "./../utils/defaultEmbeds.js";
-import Discord, { CommandInteraction, GuildMember, MessageActionRow, MessageButton, MessageSelectMenu } from "discord.js";
+import Discord, {
+ CommandInteraction,
+ GuildMember,
+ MessageActionRow,
+ MessageButton,
+ MessageSelectMenu
+} from "discord.js";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import { WrappedCheck } from "jshaiku";
import EmojiEmbed from "../utils/generateEmojiEmbed.js";
@@ -17,13 +23,23 @@
data: object;
checkFunction: (member) => boolean;
inverted = false;
- constructor(name: (data) => string | string, data: object, check: (member) => boolean) {
- if (typeof name === "function") { this.name = name(data);
- } else { this.name = name; }
+ constructor(
+ name: (data) => string | string,
+ data: object,
+ check: (member) => boolean
+ ) {
+ if (typeof name === "function") {
+ this.name = name(data);
+ } else {
+ this.name = name;
+ }
this.data = data;
this.checkFunction = check;
}
- flip() { this.inverted = true; return this; }
+ flip() {
+ this.inverted = true;
+ return this;
+ }
check(member) {
if (this.inverted) return !this.checkFunction(member);
else return this.checkFunction(member);
@@ -35,51 +51,130 @@
render: "Member",
has: {
render: "has",
- role: (role) => ( new Filter((data) => `Member has role <@&${data.role}>`, {role: role, type: Discord.Role, render: "role"}, (member) => { return member.roles.cache.has(role);}))
+ role: (role) =>
+ new Filter(
+ (data) => `Member has role <@&${data.role}>`,
+ { role: role, type: Discord.Role, render: "role" },
+ (member) => {
+ return member.roles.cache.has(role);
+ }
+ )
},
joined: {
render: "joined",
- before: (date) => ( new Filter((_data) => `Joined server before <t:${Math.round(date.getTime() / 1000)}:D>`, {date: date, type: Date, render: "before"}, (member) => {
- return member.joinedTimestamp < date.getTime();
- }))
+ before: (date) =>
+ new Filter(
+ (_data) =>
+ `Joined server before <t:${Math.round(
+ date.getTime() / 1000
+ )}:D>`,
+ { date: date, type: Date, render: "before" },
+ (member) => {
+ return member.joinedTimestamp < date.getTime();
+ }
+ )
},
nickname: {
render: "Nickname",
- set: () => ( new Filter((_data) => "Member has a nickname set\"", {render: "set"}, (member) => { return member.nickname !== null;})),
- includes: (name) => ( new Filter((_data) => `Nickname includes "${name}"`, {nickname: name, type: String, render: "includes"}, (member) => {
- return member.displayName.includes(name);})),
- startsWith: (name) => ( new Filter((_data) => `Nickname starts with "${name}"`, {nickname: name, type: String, render: "starts with"}, (member) => {
- return member.displayName.startsWith(name);})),
- endsWith: (name) => ( new Filter((_data) => `Nickname ends with "${name}"`, {nickname: name, type: String, render: "ends with"}, (member) => {
- return member.displayName.endsWith(name);}))
+ set: () =>
+ new Filter(
+ (_data) => 'Member has a nickname set"',
+ { render: "set" },
+ (member) => {
+ return member.nickname !== null;
+ }
+ ),
+ includes: (name) =>
+ new Filter(
+ (_data) => `Nickname includes "${name}"`,
+ { nickname: name, type: String, render: "includes" },
+ (member) => {
+ return member.displayName.includes(name);
+ }
+ ),
+ startsWith: (name) =>
+ new Filter(
+ (_data) => `Nickname starts with "${name}"`,
+ { nickname: name, type: String, render: "starts with" },
+ (member) => {
+ return member.displayName.startsWith(name);
+ }
+ ),
+ endsWith: (name) =>
+ new Filter(
+ (_data) => `Nickname ends with "${name}"`,
+ { nickname: name, type: String, render: "ends with" },
+ (member) => {
+ return member.displayName.endsWith(name);
+ }
+ )
}
},
account: {
render: "Account",
created: {
render: "created",
- before: (date) => ( new Filter((_data) => `Account created before <t:${Math.round(date.getTime() / 1000)}:D>`, {date: date, type: Date, render: "before"}, (member) => {
- return member.user.createdTimestamp < date.getTime();
- }))
+ before: (date) =>
+ new Filter(
+ (_data) =>
+ `Account created before <t:${Math.round(
+ date.getTime() / 1000
+ )}:D>`,
+ { date: date, type: Date, render: "before" },
+ (member) => {
+ return member.user.createdTimestamp < date.getTime();
+ }
+ )
},
is: {
render: "is",
- human: () => ( new Filter((_data) => "Member is a human", {human: true, render: "human"}, (member) => { return !member.bot; }))
+ human: () =>
+ new Filter(
+ (_data) => "Member is a human",
+ { human: true, render: "human" },
+ (member) => {
+ return !member.bot;
+ }
+ )
},
username: {
render: "Username",
- includes: (name) => ( new Filter((_data) => `Nickname includes "${name}"`, {nickname: name, type: String, render: "includes"}, (member) => {
- return member.user.name.includes(name);})),
- startsWith: (name) => ( new Filter((_data) => `Nickname starts with "${name}"`, {nickname: name, type: String, render: "starts with"}, (member) => {
- return member.user.name.startsWith(name);})),
- endsWith: (name) => ( new Filter((_data) => `Nickname ends with "${name}"`, {nickname: name, type: String, render: "ends with"}, (member) => {
- return member.user.name.endsWith(name);}))
+ includes: (name) =>
+ new Filter(
+ (_data) => `Nickname includes "${name}"`,
+ { nickname: name, type: String, render: "includes" },
+ (member) => {
+ return member.user.name.includes(name);
+ }
+ ),
+ startsWith: (name) =>
+ new Filter(
+ (_data) => `Nickname starts with "${name}"`,
+ { nickname: name, type: String, render: "starts with" },
+ (member) => {
+ return member.user.name.startsWith(name);
+ }
+ ),
+ endsWith: (name) =>
+ new Filter(
+ (_data) => `Nickname ends with "${name}"`,
+ { nickname: name, type: String, render: "ends with" },
+ (member) => {
+ return member.user.name.endsWith(name);
+ }
+ )
}
}
};
-const callback = async (interaction: CommandInteraction): Promise<void | unknown> => {
- await interaction.reply({embeds: LoadingEmbed, ephemeral: true, fetchReply: true});
+const callback = async (
+ interaction: CommandInteraction
+): Promise<void | unknown> => {
+ await interaction.reply({
+ embeds: LoadingEmbed,
+ ephemeral: true,
+ fetchReply: true
+ });
const filters: Filter[] = [
filterList.member.has.role("959901346000154674"),
filterList.member.nickname.startsWith("Pinea"),
@@ -91,65 +186,122 @@
const affected = [];
const members = interaction.guild.members.cache;
if (all) {
- members.forEach(member => {
+ members.forEach((member) => {
let applies = true;
- filters.forEach(filter => { if (!filter.check(member)) { applies = false; } });
- if (applies) { affected.push(member); }
+ filters.forEach((filter) => {
+ if (!filter.check(member)) {
+ applies = false;
+ }
+ });
+ if (applies) {
+ affected.push(member);
+ }
});
} else {
- members.forEach(member => {
+ members.forEach((member) => {
let applies = false;
- filters.forEach(filter => { if (filter.check(member)) { applies = true; } });
- if (applies) { affected.push(member); }
+ filters.forEach((filter) => {
+ if (filter.check(member)) {
+ applies = true;
+ }
+ });
+ if (applies) {
+ affected.push(member);
+ }
});
}
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Role all")
- .setDescription((all ? "All of the following must be true:" : "Any of the following must be true") + "\n" +
- filters.map((f) => {
- count ++;
- return (count === 1 ? getEmojiByName("ICONS.FILTER") : (all ? "**and** " : "**or** ")) +
- (f.inverted ? "**not** " : "") + `${f.name}`;
- }).join("\n") + "\n\n" + `This will affect ${addPlural(affected.length, "member")}`)
- .setEmoji("GUILD.ROLES.CREATE")
- .setStatus("Success")
- ], components: [
- new MessageActionRow().addComponents([new MessageSelectMenu().setOptions(filters.map((f, index) => ({
- label: (f.inverted ? "(Not) " : "") + f.name,
- value: index.toString()
- }))).setMinValues(1).setMaxValues(filters.length).setCustomId("select").setPlaceholder("Remove a filter")]),
- new MessageActionRow().addComponents([
- new MessageButton()
- .setLabel("Apply")
- .setStyle("PRIMARY")
- .setCustomId("apply")
- .setEmoji(client.emojis.cache.get(getEmojiByName("CONTROL.TICK", "id")))
- .setDisabled(affected.length === 0),
- new MessageButton()
- .setLabel("Add filter")
- .setStyle("PRIMARY")
- .setCustomId("add")
- .setEmoji(client.emojis.cache.get(getEmojiByName("ICONS.FILTER", "id")))
- .setDisabled(filters.length >= 25)
- ])
- ]});
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Role all")
+ .setDescription(
+ (all
+ ? "All of the following must be true:"
+ : "Any of the following must be true") +
+ "\n" +
+ filters
+ .map((f) => {
+ count++;
+ return (
+ (count === 1
+ ? getEmojiByName("ICONS.FILTER")
+ : all
+ ? "**and** "
+ : "**or** ") +
+ (f.inverted ? "**not** " : "") +
+ `${f.name}`
+ );
+ })
+ .join("\n") +
+ "\n\n" +
+ `This will affect ${addPlural(
+ affected.length,
+ "member"
+ )}`
+ )
+ .setEmoji("GUILD.ROLES.CREATE")
+ .setStatus("Success")
+ ],
+ components: [
+ new MessageActionRow().addComponents([
+ new MessageSelectMenu()
+ .setOptions(
+ filters.map((f, index) => ({
+ label: (f.inverted ? "(Not) " : "") + f.name,
+ value: index.toString()
+ }))
+ )
+ .setMinValues(1)
+ .setMaxValues(filters.length)
+ .setCustomId("select")
+ .setPlaceholder("Remove a filter")
+ ]),
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setLabel("Apply")
+ .setStyle("PRIMARY")
+ .setCustomId("apply")
+ .setEmoji(
+ client.emojis.cache.get(
+ getEmojiByName("CONTROL.TICK", "id")
+ )
+ )
+ .setDisabled(affected.length === 0),
+ new MessageButton()
+ .setLabel("Add filter")
+ .setStyle("PRIMARY")
+ .setCustomId("add")
+ .setEmoji(
+ client.emojis.cache.get(
+ getEmojiByName("ICONS.FILTER", "id")
+ )
+ )
+ .setDisabled(filters.length >= 25)
+ ])
+ ]
+ });
break;
}
return;
};
-const check = async (interaction: CommandInteraction, _defaultCheck: WrappedCheck) => {
- const member = (interaction.member as GuildMember);
- const me = (interaction.guild.me as GuildMember);
- if (!me.permissions.has("MANAGE_ROLES")) throw "I do not have the *Manage Roles* permission";
+const check = async (
+ interaction: CommandInteraction,
+ _defaultCheck: WrappedCheck
+) => {
+ const member = interaction.member as GuildMember;
+ const me = interaction.guild.me!;
+ if (!me.permissions.has("MANAGE_ROLES"))
+ throw "I do not have the *Manage Roles* permission";
// Allow the owner to role anyone
if (member.id === interaction.guild.ownerId) return true;
// Check if the user has manage_roles permission
- if (! member.permissions.has("MANAGE_ROLES")) throw "You do not have the *Manage Roles* permission";
+ if (!member.permissions.has("MANAGE_ROLES"))
+ throw "You do not have the *Manage Roles* permission";
// Allow role
return true;
};
export { command };
export { callback };
-export { check };
\ No newline at end of file
+export { check };
diff --git a/src/Unfinished/categorisationTest.ts b/src/Unfinished/categorisationTest.ts
index 4ba582d..e4346d6 100644
--- a/src/Unfinished/categorisationTest.ts
+++ b/src/Unfinished/categorisationTest.ts
@@ -1,5 +1,11 @@
import { LoadingEmbed } from "../utils/defaultEmbeds.js";
-import { CommandInteraction, GuildChannel, MessageActionRow, MessageButton, MessageSelectMenu } from "discord.js";
+import {
+ CommandInteraction,
+ GuildChannel,
+ MessageActionRow,
+ MessageButton,
+ MessageSelectMenu
+} from "discord.js";
import { SlashCommandBuilder } from "@discordjs/builders";
import { WrappedCheck } from "jshaiku";
import EmojiEmbed from "../utils/generateEmojiEmbed.js";
@@ -11,10 +17,14 @@
.setName("categorise")
.setDescription("Categorises your servers channels");
-const callback = async (interaction: CommandInteraction): Promise<void | unknown> => {
- const channels = interaction.guild.channels.cache.filter(c => c.type !== "GUILD_CATEGORY");
+const callback = async (
+ interaction: CommandInteraction
+): Promise<void | unknown> => {
+ const channels = interaction.guild.channels.cache.filter(
+ (c) => c.type !== "GUILD_CATEGORY"
+ );
const categorised = {};
- await interaction.reply({embeds: LoadingEmbed, ephemeral: true});
+ await interaction.reply({ embeds: LoadingEmbed, ephemeral: true });
const predicted = {};
const types = {
general: ["general", "muted", "main", "topic", "discuss"],
@@ -41,58 +51,110 @@
for (const c of channels) {
// convert channel to a channel if its a string
let channel: string | GuildChannel;
- if (typeof c === "string") channel = interaction.guild.channels.cache.get(channel as string).id;
+ if (typeof c === "string")
+ channel = interaction.guild.channels.cache.get(
+ channel as string
+ ).id;
else channel = (c[0] as unknown as GuildChannel).id;
console.log(channel);
if (!predicted[channel]) predicted[channel] = [];
- m = await interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Categorise")
- .setDescription(`Select all types that apply to <#${channel}>.\n\n` +
- `${addPlural(predicted[channel].length, "Suggestion")}: ${predicted[channel].join(", ")}`)
- .setEmoji("CHANNEL.CATEGORY.CREATE")
- .setStatus("Success")
- ], components: [
- new MessageActionRow().addComponents([new MessageSelectMenu()
- .setCustomId("selected")
- .setMaxValues(Object.keys(types).length)
- .setMinValues(1)
- .setPlaceholder("Select all types that apply to this channel")
- .setOptions(Object.keys(types).map(type => ({label: type, value: type})))
- ]),
- new MessageActionRow().addComponents([
- new MessageButton().setLabel("Accept Suggestion").setCustomId("accept").setStyle("SUCCESS").setDisabled(predicted[channel].length === 0)
- .setEmoji(client.emojis.cache.get(getEmojiByName("ICONS.TICK", "id"))),
- new MessageButton().setLabel("Use \"Other\"").setCustomId("reject").setStyle("SECONDARY")
- .setEmoji(client.emojis.cache.get(getEmojiByName("ICONS.CROSS", "id")))
- ])
- ]});
+ m = await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Categorise")
+ .setDescription(
+ `Select all types that apply to <#${channel}>.\n\n` +
+ `${addPlural(
+ predicted[channel].length,
+ "Suggestion"
+ )}: ${predicted[channel].join(", ")}`
+ )
+ .setEmoji("CHANNEL.CATEGORY.CREATE")
+ .setStatus("Success")
+ ],
+ components: [
+ new MessageActionRow().addComponents([
+ new MessageSelectMenu()
+ .setCustomId("selected")
+ .setMaxValues(Object.keys(types).length)
+ .setMinValues(1)
+ .setPlaceholder(
+ "Select all types that apply to this channel"
+ )
+ .setOptions(
+ Object.keys(types).map((type) => ({
+ label: type,
+ value: type
+ }))
+ )
+ ]),
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setLabel("Accept Suggestion")
+ .setCustomId("accept")
+ .setStyle("SUCCESS")
+ .setDisabled(predicted[channel].length === 0)
+ .setEmoji(
+ client.emojis.cache.get(
+ getEmojiByName("ICONS.TICK", "id")
+ )
+ ),
+ new MessageButton()
+ .setLabel('Use "Other"')
+ .setCustomId("reject")
+ .setStyle("SECONDARY")
+ .setEmoji(
+ client.emojis.cache.get(
+ getEmojiByName("ICONS.CROSS", "id")
+ )
+ )
+ ])
+ ]
+ });
let i;
try {
i = await m.awaitMessageComponent({ time: 300000 });
} catch (e) {
- return await interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Categorise")
- .setEmoji("CHANNEL.CATEGORY.DELETE")
- .setStatus("Danger")
- .setDescription(`Select all types that apply to <#${channel}>.\n\n` +
- `${addPlural(predicted[channel].length, "Suggestion")}: ${predicted[channel].join(", ")}`)
- .setFooter({text: "Message timed out"})
- ]});
+ return await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Categorise")
+ .setEmoji("CHANNEL.CATEGORY.DELETE")
+ .setStatus("Danger")
+ .setDescription(
+ `Select all types that apply to <#${channel}>.\n\n` +
+ `${addPlural(
+ predicted[channel].length,
+ "Suggestion"
+ )}: ${predicted[channel].join(", ")}`
+ )
+ .setFooter({ text: "Message timed out" })
+ ]
+ });
}
i.deferUpdate();
let selected;
- if (i.customId === "select") { selected = i.values; }
- if (i.customId === "accept") { selected = predicted[channel]; }
- if (i.customId === "reject") { selected = ["other"]; }
+ if (i.customId === "select") {
+ selected = i.values;
+ }
+ if (i.customId === "accept") {
+ selected = predicted[channel];
+ }
+ if (i.customId === "reject") {
+ selected = ["other"];
+ }
categorised[channel] = selected;
}
console.log(categorised);
};
-const check = (_interaction: CommandInteraction, _defaultCheck: WrappedCheck) => {
+const check = (
+ _interaction: CommandInteraction,
+ _defaultCheck: WrappedCheck
+) => {
return true;
};
export { command };
export { callback };
-export { check };
\ No newline at end of file
+export { check };
diff --git a/src/actions/createModActionTicket.ts b/src/actions/createModActionTicket.ts
index 1d3406d..41f949c 100644
--- a/src/actions/createModActionTicket.ts
+++ b/src/actions/createModActionTicket.ts
@@ -3,14 +3,35 @@
import getEmojiByName from "../utils/getEmojiByName.js";
import client from "../utils/client.js";
-export async function create(guild: Discord.Guild, member: Discord.User, createdBy: Discord.User, reason: string, customReason?: string) {
+export async function create(
+ guild: Discord.Guild,
+ member: Discord.User,
+ createdBy: Discord.User,
+ reason: string,
+ customReason?: string
+) {
const config = await client.database.guilds.read(guild.id);
- const { log, NucleusColors, entry, renderUser, renderChannel, renderDelta } = client.logger;
- const overwrites = [{
- id: member,
- allow: ["VIEW_CHANNEL", "SEND_MESSAGES", "ATTACH_FILES", "ADD_REACTIONS", "READ_MESSAGE_HISTORY"],
- type: "member"
- }] as Discord.OverwriteResolvable[];
+ const {
+ log,
+ NucleusColors,
+ entry,
+ renderUser,
+ renderChannel,
+ renderDelta
+ } = client.logger;
+ const overwrites = [
+ {
+ id: member,
+ allow: [
+ "VIEW_CHANNEL",
+ "SEND_MESSAGES",
+ "ATTACH_FILES",
+ "ADD_REACTIONS",
+ "READ_MESSAGE_HISTORY"
+ ],
+ type: "member"
+ }
+ ] as Discord.OverwriteResolvable[];
overwrites.push({
id: guild.roles.everyone,
deny: ["VIEW_CHANNEL"],
@@ -19,7 +40,13 @@
if (config.tickets.supportRole !== null) {
overwrites.push({
id: guild.roles.cache.get(config.tickets.supportRole),
- allow: ["VIEW_CHANNEL", "SEND_MESSAGES", "ATTACH_FILES", "ADD_REACTIONS", "READ_MESSAGE_HISTORY"],
+ allow: [
+ "VIEW_CHANNEL",
+ "SEND_MESSAGES",
+ "ATTACH_FILES",
+ "ADD_REACTIONS",
+ "READ_MESSAGE_HISTORY"
+ ],
type: "role"
});
}
@@ -31,40 +58,59 @@
topic: `${member.id} Active`,
parent: config.tickets.category,
nsfw: false,
- permissionOverwrites: (overwrites as Discord.OverwriteResolvable[]),
+ permissionOverwrites: overwrites as Discord.OverwriteResolvable[],
reason: "Creating ticket"
});
} catch (e) {
return null;
}
try {
- await c.send(
- {
- content: (`<@${member.id}>` + (config.tickets.supportRole !== null ? ` • <@&${config.tickets.supportRole}>` : "")),
- allowedMentions: {
- users: [member.id],
- roles: (config.tickets.supportRole !== null ? [config.tickets.supportRole] : [])
- }
+ await c.send({
+ content:
+ `<@${member.id}>` +
+ (config.tickets.supportRole !== null
+ ? ` • <@&${config.tickets.supportRole}>`
+ : ""),
+ allowedMentions: {
+ users: [member.id],
+ roles:
+ config.tickets.supportRole !== null
+ ? [config.tickets.supportRole]
+ : []
}
- );
- await c.send({ embeds: [new EmojiEmbed()
- .setTitle("New Ticket")
- .setDescription(
- "Ticket created by a Moderator\n" +
- `**Support type:** ${customReason ? customReason : "Appeal submission"}\n` + (reason !== null ? `**Reason:**\n> ${reason}\n` : "") +
- `**Ticket ID:** \`${c.id}\`\n` +
- "Type `/ticket close` to close this ticket."
- )
- .setStatus("Success")
- .setEmoji("GUILD.TICKET.OPEN")
- ], components: [new MessageActionRow().addComponents([new MessageButton()
- .setLabel("Close")
- .setStyle("DANGER")
- .setCustomId("closeticket")
- .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
- ])]});
+ });
+ await c.send({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("New Ticket")
+ .setDescription(
+ "Ticket created by a Moderator\n" +
+ `**Support type:** ${
+ customReason
+ ? customReason
+ : "Appeal submission"
+ }\n` +
+ (reason !== null
+ ? `**Reason:**\n> ${reason}\n`
+ : "") +
+ `**Ticket ID:** \`${c.id}\`\n` +
+ "Type `/ticket close` to close this ticket."
+ )
+ .setStatus("Success")
+ .setEmoji("GUILD.TICKET.OPEN")
+ ],
+ components: [
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setLabel("Close")
+ .setStyle("DANGER")
+ .setCustomId("closeticket")
+ .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
+ ])
+ ]
+ });
const data = {
- meta:{
+ meta: {
type: "ticketCreate",
displayName: "Ticket Created",
calculateType: "ticketUpdate",
@@ -75,7 +121,10 @@
list: {
ticketFor: entry(member.id, renderUser(member)),
createdBy: entry(createdBy.id, renderUser(createdBy)),
- created: entry(new Date().getTime(), renderDelta(new Date().getTime())),
+ created: entry(
+ new Date().getTime(),
+ renderDelta(new Date().getTime())
+ ),
ticketChannel: entry(c.id, renderChannel(c))
},
hidden: {
@@ -83,11 +132,14 @@
}
};
log(data);
- } catch (e) { console.log(e); return null; }
+ } catch (e) {
+ console.log(e);
+ return null;
+ }
return c.id;
}
export async function areTicketsEnabled(guild: string) {
const config = await client.database.guilds.read(guild);
return config.tickets.enabled;
-}
\ No newline at end of file
+}
diff --git a/src/actions/roleMenu.ts b/src/actions/roleMenu.ts
index 9a8e80a..dc224e8 100644
--- a/src/actions/roleMenu.ts
+++ b/src/actions/roleMenu.ts
@@ -7,30 +7,47 @@
export async function callback(interaction) {
const config = await client.database.guilds.read(interaction.guild.id);
- if (!config.roleMenu.enabled) return await interaction.reply({embeds: [new EmojiEmbed()
- .setTitle("Roles")
- .setDescription("Self roles are currently disabled. Please contact a staff member or try again later.")
- .setStatus("Danger")
- .setEmoji("CONTROL.BLOCKCROSS")
- ], ephemeral: true});
- if (config.roleMenu.options.length === 0) return await interaction.reply({embeds: [new EmojiEmbed()
- .setTitle("Roles")
- .setDescription("There are no roles available. Please contact a staff member or try again later.")
- .setStatus("Danger")
- .setEmoji("CONTROL.BLOCKCROSS")
- ], ephemeral: true});
- await interaction.reply({embeds: LoadingEmbed, ephemeral: true});
+ if (!config.roleMenu.enabled)
+ return await interaction.reply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Roles")
+ .setDescription(
+ "Self roles are currently disabled. Please contact a staff member or try again later."
+ )
+ .setStatus("Danger")
+ .setEmoji("CONTROL.BLOCKCROSS")
+ ],
+ ephemeral: true
+ });
+ if (config.roleMenu.options.length === 0)
+ return await interaction.reply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Roles")
+ .setDescription(
+ "There are no roles available. Please contact a staff member or try again later."
+ )
+ .setStatus("Danger")
+ .setEmoji("CONTROL.BLOCKCROSS")
+ ],
+ ephemeral: true
+ });
+ await interaction.reply({ embeds: LoadingEmbed, ephemeral: true });
let m;
if (config.roleMenu.allowWebUI) {
let code = "";
let length = 5;
let itt = 0;
- const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+ const chars =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
let valid = false;
while (!valid) {
itt += 1;
code = "";
- for (let i = 0; i < length; i++) { code += chars.charAt(Math.floor(Math.random() * chars.length)); }
+ for (let i = 0; i < length; i++) {
+ code += chars.charAt(Math.floor(Math.random() * chars.length));
+ }
if (code in client.roleMenu) continue;
if (itt > 1000) {
itt = 0;
@@ -42,7 +59,7 @@
client.roleMenu[code] = {
guild: interaction.guild.id,
guildName: interaction.guild.name,
- guildIcon: interaction.guild.iconURL({format: "png"}),
+ guildIcon: interaction.guild.iconURL({ format: "png" }),
user: interaction.member.user.id,
username: interaction.member.user.username,
data: config.roleMenu.options,
@@ -50,31 +67,44 @@
};
let up = true;
try {
- const status = await fetch(client.config.baseUrl).then(res => res.status);
+ const status = await fetch(client.config.baseUrl).then(
+ (res) => res.status
+ );
if (status !== 200) up = false;
- } catch { up = false; }
+ } catch {
+ up = false;
+ }
m = await interaction.editReply({
- embeds: [new EmojiEmbed()
- .setTitle("Roles")
- .setDescription("Select how to choose your roles")
- .setStatus("Success")
- .setEmoji("GUILD.GREEN")
- ], components: [new MessageActionRow().addComponents([
- new MessageButton()
- .setLabel("Online")
- .setStyle("LINK")
- .setDisabled(!up)
- .setURL(`${client.config.baseUrl}nucleus/rolemenu?code=${code}`),
- new MessageButton()
- .setLabel("Manual")
- .setStyle("PRIMARY")
- .setCustomId("manual")
- ])]
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Roles")
+ .setDescription("Select how to choose your roles")
+ .setStatus("Success")
+ .setEmoji("GUILD.GREEN")
+ ],
+ components: [
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setLabel("Online")
+ .setStyle("LINK")
+ .setDisabled(!up)
+ .setURL(
+ `${client.config.baseUrl}nucleus/rolemenu?code=${code}`
+ ),
+ new MessageButton()
+ .setLabel("Manual")
+ .setStyle("PRIMARY")
+ .setCustomId("manual")
+ ])
+ ]
});
}
let component;
- try { component = await m.awaitMessageComponent({time: 300000});
- } catch (e) { return; }
+ try {
+ component = await m.awaitMessageComponent({ time: 300000 });
+ } catch (e) {
+ return;
+ }
component.deferUpdate();
let rolesToAdd = [];
for (let i = 0; i < config.roleMenu.options.length; i++) {
@@ -84,36 +114,66 @@
new EmojiEmbed()
.setTitle("Roles")
.setEmoji("GUILD.GREEN")
- .setDescription(`**${object.name}**` + (object.description ? `\n${object.description}` : "") +
- `\n\nSelect ${object.min}` + (object.min !== object.max ? ` to ${object.max}` : "") + ` role${object.max === 1 ? "" : "s"} to add.`)
+ .setDescription(
+ `**${object.name}**` +
+ (object.description
+ ? `\n${object.description}`
+ : "") +
+ `\n\nSelect ${object.min}` +
+ (object.min !== object.max
+ ? ` to ${object.max}`
+ : "") +
+ ` role${object.max === 1 ? "" : "s"} to add.`
+ )
.setStatus("Success")
- .setFooter({text: `Step ${i + 1}/${config.roleMenu.options.length}`})
+ .setFooter({
+ text: `Step ${i + 1}/${config.roleMenu.options.length}`
+ })
],
components: [
+ new MessageActionRow().addComponents(
+ [
+ new MessageButton()
+ .setLabel("Cancel")
+ .setStyle("DANGER")
+ .setCustomId("cancel")
+ .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
+ ].concat(
+ object.min === 0
+ ? [
+ new MessageButton()
+ .setLabel("Skip")
+ .setStyle("SECONDARY")
+ .setCustomId("skip")
+ .setEmoji(
+ getEmojiByName("CONTROL.RIGHT", "id")
+ )
+ ]
+ : []
+ )
+ )
+ ].concat([
new MessageActionRow().addComponents([
- new MessageButton()
- .setLabel("Cancel")
- .setStyle("DANGER")
- .setCustomId("cancel")
- .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
- ].concat(object.min === 0 ? [
- new MessageButton()
- .setLabel("Skip")
- .setStyle("SECONDARY")
- .setCustomId("skip")
- .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
- ] : []))
- ].concat([new MessageActionRow().addComponents([new MessageSelectMenu()
- .setPlaceholder(`${object.name}`)
- .setCustomId("rolemenu")
- .setMinValues(object.min)
- .setMaxValues(object.max)
- .setOptions(object.options.map(o => { return {label: o.name, description: o.description, value: o.role}; }))
- ])])
+ new MessageSelectMenu()
+ .setPlaceholder(`${object.name}`)
+ .setCustomId("rolemenu")
+ .setMinValues(object.min)
+ .setMaxValues(object.max)
+ .setOptions(
+ object.options.map((o) => {
+ return {
+ label: o.name,
+ description: o.description,
+ value: o.role
+ };
+ })
+ )
+ ])
+ ])
});
let component;
try {
- component = await m.awaitMessageComponent({time: 300000});
+ component = await m.awaitMessageComponent({ time: 300000 });
} catch (e) {
return;
}
@@ -121,34 +181,54 @@
if (component.customId === "rolemenu") {
rolesToAdd = rolesToAdd.concat(component.values);
} else if (component.customId === "cancel") {
- return await interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Roles")
- .setDescription("Cancelled. No changes were made.")
- .setStatus("Danger")
- .setEmoji("GUILD.RED")
- ], components: []});
+ return await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Roles")
+ .setDescription("Cancelled. No changes were made.")
+ .setStatus("Danger")
+ .setEmoji("GUILD.RED")
+ ],
+ components: []
+ });
}
}
- let rolesToRemove = config.roleMenu.options.map(o => o.options.map(o => o.role)).flat();
- const memberRoles = interaction.member.roles.cache.map(r => r.id);
- rolesToRemove = rolesToRemove.filter(r => memberRoles.includes(r)).filter(r => !rolesToAdd.includes(r));
- rolesToAdd = rolesToAdd.filter(r => !memberRoles.includes(r));
+ let rolesToRemove = config.roleMenu.options
+ .map((o) => o.options.map((o) => o.role))
+ .flat();
+ const memberRoles = interaction.member.roles.cache.map((r) => r.id);
+ rolesToRemove = rolesToRemove
+ .filter((r) => memberRoles.includes(r))
+ .filter((r) => !rolesToAdd.includes(r));
+ rolesToAdd = rolesToAdd.filter((r) => !memberRoles.includes(r));
try {
await interaction.member.roles.remove(rolesToRemove);
await interaction.member.roles.add(rolesToAdd);
} catch (e) {
- return await interaction.reply({embeds: [new EmojiEmbed()
- .setTitle("Roles")
- .setDescription("Something went wrong and your roles were not added. Please contact a staff member or try again later.")
- .setStatus("Danger")
- .setEmoji("GUILD.RED")
- ], components: []});
+ return await interaction.reply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Roles")
+ .setDescription(
+ "Something went wrong and your roles were not added. Please contact a staff member or try again later."
+ )
+ .setStatus("Danger")
+ .setEmoji("GUILD.RED")
+ ],
+ components: []
+ });
}
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Roles")
- .setDescription("Roles have been added. You may close this message.")
- .setStatus("Success")
- .setEmoji("GUILD.GREEN")
- ], components: []});
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Roles")
+ .setDescription(
+ "Roles have been added. You may close this message."
+ )
+ .setStatus("Success")
+ .setEmoji("GUILD.GREEN")
+ ],
+ components: []
+ });
return;
}
diff --git a/src/actions/tickets/create.ts b/src/actions/tickets/create.ts
index f724728..ca5147a 100644
--- a/src/actions/tickets/create.ts
+++ b/src/actions/tickets/create.ts
@@ -6,50 +6,84 @@
function capitalize(s: string) {
s = s.replace(/([A-Z])/g, " $1");
- return s.length < 3 ? s.toUpperCase() : s[0].toUpperCase() + s.slice(1).toLowerCase();
+ return s.length < 3
+ ? s.toUpperCase()
+ : s[0].toUpperCase() + s.slice(1).toLowerCase();
}
export default async function (interaction) {
- const { log, NucleusColors, entry, renderUser, renderChannel, renderDelta } = client.logger;
+ const {
+ log,
+ NucleusColors,
+ entry,
+ renderUser,
+ renderChannel,
+ renderDelta
+ } = client.logger;
const config = await client.database.guilds.read(interaction.guild.id);
if (!config.tickets.enabled || !config.tickets.category) {
- return await interaction.reply({embeds: [new EmojiEmbed()
- .setTitle("Tickets are disabled")
- .setDescription("Please enable tickets in the configuration to use this command.")
- .setFooter({text: interaction.member.permissions.has("MANAGE_GUILD") ? "You can enable it by running /settings tickets" : ""})
- .setStatus("Danger")
- .setEmoji("CONTROL.BLOCKCROSS")
- ], ephemeral: true});
+ return await interaction.reply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Tickets are disabled")
+ .setDescription(
+ "Please enable tickets in the configuration to use this command."
+ )
+ .setFooter({
+ text: interaction.member.permissions.has("MANAGE_GUILD")
+ ? "You can enable it by running /settings tickets"
+ : ""
+ })
+ .setStatus("Danger")
+ .setEmoji("CONTROL.BLOCKCROSS")
+ ],
+ ephemeral: true
+ });
}
- const category = interaction.guild.channels.cache.get(config.tickets.category) as Discord.CategoryChannel;
+ const category = interaction.guild.channels.cache.get(
+ config.tickets.category
+ ) as Discord.CategoryChannel;
let count = 0;
- category.children.forEach(element => {
+ category.children.forEach((element) => {
if (!(element.type === "GUILD_TEXT")) return;
- if ((element as Discord.TextChannel).topic.includes(`${interaction.member.user.id}`)) {
+ if (
+ (element as Discord.TextChannel).topic.includes(
+ `${interaction.member.user.id}`
+ )
+ ) {
if ((element as Discord.TextChannel).topic.endsWith("Active")) {
count++;
}
}
});
if (count >= config.tickets.maxTickets) {
- return await interaction.reply({embeds: [new EmojiEmbed()
- .setTitle("Create Ticket")
- .setDescription(`You have reached the maximum amount of tickets (${config.tickets.maxTickets}). Please close one of your active tickets before creating a new one.`)
- .setStatus("Danger")
- .setEmoji("CONTROL.BLOCKCROSS")
- ], ephemeral: true});
+ return await interaction.reply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Create Ticket")
+ .setDescription(
+ `You have reached the maximum amount of tickets (${config.tickets.maxTickets}). Please close one of your active tickets before creating a new one.`
+ )
+ .setStatus("Danger")
+ .setEmoji("CONTROL.BLOCKCROSS")
+ ],
+ ephemeral: true
+ });
}
let ticketTypes;
let custom = false;
- if (config.tickets.customTypes && config.tickets.useCustom) { ticketTypes = config.tickets.customTypes; custom = true; }
- else if (config.tickets.types) ticketTypes = toHexArray(config.tickets.types, tickets);
+ if (config.tickets.customTypes && config.tickets.useCustom) {
+ ticketTypes = config.tickets.customTypes;
+ custom = true;
+ } else if (config.tickets.types)
+ ticketTypes = toHexArray(config.tickets.types, tickets);
else ticketTypes = [];
let chosenType;
let splitFormattedTicketTypes = [];
if (ticketTypes.length > 0) {
let formattedTicketTypes = [];
- formattedTicketTypes = ticketTypes.map(type => {
+ formattedTicketTypes = ticketTypes.map((type) => {
if (custom) {
return new MessageButton()
.setLabel(type)
@@ -60,28 +94,43 @@
.setLabel(capitalize(type))
.setStyle("PRIMARY")
.setCustomId(type)
- .setEmoji(getEmojiByName(("TICKETS." + type.toString().toUpperCase()), "id"));
+ .setEmoji(
+ getEmojiByName(
+ "TICKETS." + type.toString().toUpperCase(),
+ "id"
+ )
+ );
}
});
for (let i = 0; i < formattedTicketTypes.length; i += 5) {
- splitFormattedTicketTypes.push(new MessageActionRow().addComponents(formattedTicketTypes.slice(i, i + 5)));
+ splitFormattedTicketTypes.push(
+ new MessageActionRow().addComponents(
+ formattedTicketTypes.slice(i, i + 5)
+ )
+ );
}
- const m = await interaction.reply({embeds: [new EmojiEmbed()
- .setTitle("Create Ticket")
- .setDescription("Select a ticket type")
- .setStatus("Success")
- .setEmoji("GUILD.TICKET.OPEN")
- ], ephemeral: true, fetchReply: true, components: splitFormattedTicketTypes});
+ const m = await interaction.reply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Create Ticket")
+ .setDescription("Select a ticket type")
+ .setStatus("Success")
+ .setEmoji("GUILD.TICKET.OPEN")
+ ],
+ ephemeral: true,
+ fetchReply: true,
+ components: splitFormattedTicketTypes
+ });
let component;
try {
- component = await m.awaitMessageComponent({time: 300000});
+ component = await m.awaitMessageComponent({ time: 300000 });
} catch (e) {
return;
}
chosenType = component.customId;
splitFormattedTicketTypes = [];
formattedTicketTypes = [];
- formattedTicketTypes = ticketTypes.map(type => {
+ formattedTicketTypes = ticketTypes.map((type) => {
if (custom) {
return new MessageButton()
.setLabel(type)
@@ -93,31 +142,57 @@
.setLabel(capitalize(type))
.setStyle(chosenType === type ? "SUCCESS" : "SECONDARY")
.setCustomId(type)
- .setEmoji(getEmojiByName(("TICKETS." + type.toString().toUpperCase()), "id"))
+ .setEmoji(
+ getEmojiByName(
+ "TICKETS." + type.toString().toUpperCase(),
+ "id"
+ )
+ )
.setDisabled(true);
}
});
for (let i = 0; i < formattedTicketTypes.length; i += 5) {
- splitFormattedTicketTypes.push(new MessageActionRow().addComponents(formattedTicketTypes.slice(i, i + 5)));
+ splitFormattedTicketTypes.push(
+ new MessageActionRow().addComponents(
+ formattedTicketTypes.slice(i, i + 5)
+ )
+ );
}
- component.update({embeds: [new EmojiEmbed()
- .setTitle("Create Ticket")
- .setDescription("Select a ticket type")
- .setStatus("Success")
- .setEmoji("GUILD.TICKET.OPEN")
- ], components: splitFormattedTicketTypes});
+ component.update({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Create Ticket")
+ .setDescription("Select a ticket type")
+ .setStatus("Success")
+ .setEmoji("GUILD.TICKET.OPEN")
+ ],
+ components: splitFormattedTicketTypes
+ });
} else {
chosenType = null;
- await interaction.reply({embeds: [new EmojiEmbed()
- .setTitle("Create Ticket")
- .setEmoji("GUILD.TICKET.OPEN")
- ], ephemeral: true, components: splitFormattedTicketTypes});
+ await interaction.reply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Create Ticket")
+ .setEmoji("GUILD.TICKET.OPEN")
+ ],
+ ephemeral: true,
+ components: splitFormattedTicketTypes
+ });
}
- const overwrites = [{
- id: interaction.member,
- allow: ["VIEW_CHANNEL", "SEND_MESSAGES", "ATTACH_FILES", "ADD_REACTIONS", "READ_MESSAGE_HISTORY"],
- type: "member"
- }] as Discord.OverwriteResolvable[];
+ const overwrites = [
+ {
+ id: interaction.member,
+ allow: [
+ "VIEW_CHANNEL",
+ "SEND_MESSAGES",
+ "ATTACH_FILES",
+ "ADD_REACTIONS",
+ "READ_MESSAGE_HISTORY"
+ ],
+ type: "member"
+ }
+ ] as Discord.OverwriteResolvable[];
overwrites.push({
id: interaction.guild.roles.everyone,
deny: ["VIEW_CHANNEL"],
@@ -126,60 +201,93 @@
if (config.tickets.supportRole !== null) {
overwrites.push({
id: interaction.guild.roles.cache.get(config.tickets.supportRole),
- allow: ["VIEW_CHANNEL", "SEND_MESSAGES", "ATTACH_FILES", "ADD_REACTIONS", "READ_MESSAGE_HISTORY"],
+ allow: [
+ "VIEW_CHANNEL",
+ "SEND_MESSAGES",
+ "ATTACH_FILES",
+ "ADD_REACTIONS",
+ "READ_MESSAGE_HISTORY"
+ ],
type: "role"
});
}
let c;
try {
- c = await interaction.guild.channels.create(interaction.member.user.username, {
- type: "GUILD_TEXT",
- topic: `${interaction.member.user.id} Active`,
- parent: config.tickets.category,
- nsfw: false,
- permissionOverwrites: (overwrites as Discord.OverwriteResolvable[]),
- reason: "Creating ticket"
- });
- } catch (e) {
- return await interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Create Ticket")
- .setDescription("Failed to create ticket")
- .setStatus("Danger")
- .setEmoji("CONTROL.BLOCKCROSS")
- ]});
- }
- try {
- await c.send(
+ c = await interaction.guild.channels.create(
+ interaction.member.user.username,
{
- content: (`<@${interaction.member.user.id}>` + (config.tickets.supportRole !== null ? ` • <@&${config.tickets.supportRole}>` : "")),
- allowedMentions: {
- users: [(interaction.member as Discord.GuildMember).id],
- roles: (config.tickets.supportRole !== null ? [config.tickets.supportRole] : [])
- }
+ type: "GUILD_TEXT",
+ topic: `${interaction.member.user.id} Active`,
+ parent: config.tickets.category,
+ nsfw: false,
+ permissionOverwrites:
+ overwrites as Discord.OverwriteResolvable[],
+ reason: "Creating ticket"
}
);
- let content = interaction.options ? interaction.options.getString("message") || "" : "";
+ } catch (e) {
+ return await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Create Ticket")
+ .setDescription("Failed to create ticket")
+ .setStatus("Danger")
+ .setEmoji("CONTROL.BLOCKCROSS")
+ ]
+ });
+ }
+ try {
+ await c.send({
+ content:
+ `<@${interaction.member.user.id}>` +
+ (config.tickets.supportRole !== null
+ ? ` • <@&${config.tickets.supportRole}>`
+ : ""),
+ allowedMentions: {
+ users: [(interaction.member as Discord.GuildMember).id],
+ roles:
+ config.tickets.supportRole !== null
+ ? [config.tickets.supportRole]
+ : []
+ }
+ });
+ let content = interaction.options
+ ? interaction.options.getString("message") || ""
+ : "";
if (content) content = `**Message:**\n> ${content}\n`;
- const emoji = custom ? "" : getEmojiByName("TICKETS." + chosenType.toUpperCase());
- await c.send({ embeds: [new EmojiEmbed()
- .setTitle("New Ticket")
- .setDescription(
- `Ticket created by <@${interaction.member.user.id}>\n` +
- `**Support type:** ${chosenType !== null ? (emoji) + " " + capitalize(chosenType) : "General"}\n` +
- `**Ticket ID:** \`${c.id}\`\n${content}\n` +
- "Type `/ticket close` to close this ticket."
- )
- .setStatus("Success")
- .setEmoji("GUILD.TICKET.OPEN")
- ], components: [new MessageActionRow().addComponents([new MessageButton()
- .setLabel("Close")
- .setStyle("DANGER")
- .setCustomId("closeticket")
- .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
- ])]});
+ const emoji = custom
+ ? ""
+ : getEmojiByName("TICKETS." + chosenType.toUpperCase());
+ await c.send({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("New Ticket")
+ .setDescription(
+ `Ticket created by <@${interaction.member.user.id}>\n` +
+ `**Support type:** ${
+ chosenType !== null
+ ? emoji + " " + capitalize(chosenType)
+ : "General"
+ }\n` +
+ `**Ticket ID:** \`${c.id}\`\n${content}\n` +
+ "Type `/ticket close` to close this ticket."
+ )
+ .setStatus("Success")
+ .setEmoji("GUILD.TICKET.OPEN")
+ ],
+ components: [
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setLabel("Close")
+ .setStyle("DANGER")
+ .setCustomId("closeticket")
+ .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
+ ])
+ ]
+ });
const data = {
- meta:{
+ meta: {
type: "ticketCreate",
displayName: "Ticket Created",
calculateType: "ticketUpdate",
@@ -188,8 +296,14 @@
timestamp: new Date().getTime()
},
list: {
- ticketFor: entry(interaction.member.user.id, renderUser(interaction.member.user)),
- created: entry(new Date().getTime(), renderDelta(new Date().getTime())),
+ ticketFor: entry(
+ interaction.member.user.id,
+ renderUser(interaction.member.user)
+ ),
+ created: entry(
+ new Date().getTime(),
+ renderDelta(new Date().getTime())
+ ),
ticketChannel: entry(c.id, renderChannel(c))
},
hidden: {
@@ -197,11 +311,19 @@
}
};
log(data);
- } catch (e) { console.log(e);}
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Create Ticket")
- .setDescription(`Ticket created. You can view it here: <#${c.id}>`)
- .setStatus("Success")
- .setEmoji("GUILD.TICKET.OPEN")
- ], components: splitFormattedTicketTypes});
-}
\ No newline at end of file
+ } catch (e) {
+ console.log(e);
+ }
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Create Ticket")
+ .setDescription(
+ `Ticket created. You can view it here: <#${c.id}>`
+ )
+ .setStatus("Success")
+ .setEmoji("GUILD.TICKET.OPEN")
+ ],
+ components: splitFormattedTicketTypes
+ });
+}
diff --git a/src/actions/tickets/delete.ts b/src/actions/tickets/delete.ts
index e5c017f..6509c03 100644
--- a/src/actions/tickets/delete.ts
+++ b/src/actions/tickets/delete.ts
@@ -4,31 +4,53 @@
import getEmojiByName from "../../utils/getEmojiByName.js";
export default async function (interaction) {
- const { log, NucleusColors, entry, renderUser, renderChannel, renderDelta } = client.logger;
+ const {
+ log,
+ NucleusColors,
+ entry,
+ renderUser,
+ renderChannel,
+ renderDelta
+ } = client.logger;
const config = await client.database.guilds.read(interaction.guild.id);
let thread = false;
if (interaction.channel instanceof Discord.ThreadChannel) thread = true;
const threadChannel = interaction.channel as Discord.ThreadChannel;
- const channel = (interaction.channel as Discord.TextChannel);
- if (!channel.parent || config.tickets.category !== channel.parent.id || (thread ? (threadChannel.parent.parent.id !== config.tickets.category) : false)) {
- return interaction.reply({embeds: [new EmojiEmbed()
- .setTitle("Deleting Ticket...")
- .setDescription("This ticket is not in your tickets category, so cannot be deleted. You cannot run close in a thread.")
- .setStatus("Danger")
- .setEmoji("CONTROL.BLOCKCROSS")
- ], ephemeral: true});
+ const channel = interaction.channel as Discord.TextChannel;
+ if (
+ !channel.parent ||
+ config.tickets.category !== channel.parent.id ||
+ (thread
+ ? threadChannel.parent.parent.id !== config.tickets.category
+ : false)
+ ) {
+ return interaction.reply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Deleting Ticket...")
+ .setDescription(
+ "This ticket is not in your tickets category, so cannot be deleted. You cannot run close in a thread."
+ )
+ .setStatus("Danger")
+ .setEmoji("CONTROL.BLOCKCROSS")
+ ],
+ ephemeral: true
+ });
}
const status = channel.topic.split(" ")[1];
if (status === "Archived") {
- await interaction.reply({embeds: [new EmojiEmbed()
- .setTitle("Delete Ticket")
- .setDescription("Your ticket is being deleted...")
- .setStatus("Danger")
- .setEmoji("GUILD.TICKET.CLOSE")
- ]});
+ await interaction.reply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Delete Ticket")
+ .setDescription("Your ticket is being deleted...")
+ .setStatus("Danger")
+ .setEmoji("GUILD.TICKET.CLOSE")
+ ]
+ });
const data = {
- meta:{
+ meta: {
type: "ticketDeleted",
displayName: "Ticket Deleted",
calculateType: "ticketUpdate",
@@ -37,9 +59,24 @@
timestamp: new Date().getTime()
},
list: {
- ticketFor: entry(channel.topic.split(" ")[0], renderUser((await interaction.guild.members.fetch(channel.topic.split(" ")[0])).user)),
- deletedBy: entry(interaction.member.user.id, renderUser(interaction.member.user)),
- deleted: entry(new Date().getTime(), renderDelta(new Date().getTime()))
+ ticketFor: entry(
+ channel.topic.split(" ")[0],
+ renderUser(
+ (
+ await interaction.guild.members.fetch(
+ channel.topic.split(" ")[0]
+ )
+ ).user
+ )
+ ),
+ deletedBy: entry(
+ interaction.member.user.id,
+ renderUser(interaction.member.user)
+ ),
+ deleted: entry(
+ new Date().getTime(),
+ renderDelta(new Date().getTime())
+ )
},
hidden: {
guild: interaction.guild.id
@@ -49,12 +86,15 @@
interaction.channel.delete();
return;
} else if (status === "Active") {
- await interaction.reply({embeds: [new EmojiEmbed()
- .setTitle("Close Ticket")
- .setDescription("Your ticket is being closed...")
- .setStatus("Warning")
- .setEmoji("GUILD.TICKET.ARCHIVED")
- ]});
+ await interaction.reply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Close Ticket")
+ .setDescription("Your ticket is being closed...")
+ .setStatus("Warning")
+ .setEmoji("GUILD.TICKET.ARCHIVED")
+ ]
+ });
const overwrites = [
{
id: channel.topic.split(" ")[0],
@@ -69,15 +109,23 @@
] as Discord.OverwriteResolvable[];
if (config.tickets.supportRole !== null) {
overwrites.push({
- id: interaction.guild.roles.cache.get(config.tickets.supportRole),
- allow: ["VIEW_CHANNEL", "SEND_MESSAGES", "ATTACH_FILES", "ADD_REACTIONS", "READ_MESSAGE_HISTORY"],
+ id: interaction.guild.roles.cache.get(
+ config.tickets.supportRole
+ ),
+ allow: [
+ "VIEW_CHANNEL",
+ "SEND_MESSAGES",
+ "ATTACH_FILES",
+ "ADD_REACTIONS",
+ "READ_MESSAGE_HISTORY"
+ ],
type: "role"
});
}
- channel.edit({permissionOverwrites: overwrites});
+ channel.edit({ permissionOverwrites: overwrites });
channel.setTopic(`${channel.topic.split(" ")[0]} Archived`);
const data = {
- meta:{
+ meta: {
type: "ticketClosed",
displayName: "Ticket Closed",
calculateType: "ticketUpdate",
@@ -86,9 +134,24 @@
timestamp: new Date().getTime()
},
list: {
- ticketFor: entry(channel.topic.split(" ")[0], renderUser((await interaction.guild.members.fetch(channel.topic.split(" ")[0])).user)),
- closedBy: entry(interaction.member.user.id, renderUser(interaction.member.user)),
- closed: entry(new Date().getTime(), renderDelta(new Date().getTime())),
+ ticketFor: entry(
+ channel.topic.split(" ")[0],
+ renderUser(
+ (
+ await interaction.guild.members.fetch(
+ channel.topic.split(" ")[0]
+ )
+ ).user
+ )
+ ),
+ closedBy: entry(
+ interaction.member.user.id,
+ renderUser(interaction.member.user)
+ ),
+ closed: entry(
+ new Date().getTime(),
+ renderDelta(new Date().getTime())
+ ),
ticketChannel: entry(channel.id, renderChannel(channel))
},
hidden: {
@@ -96,26 +159,43 @@
}
};
log(data);
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Close Ticket")
- .setDescription("This ticket has been closed.\nType `/ticket close` again to delete it.\n\nNote: Check `/privacy` for details about transcripts.")
- .setStatus("Warning")
- .setEmoji("GUILD.TICKET.ARCHIVED")
- ], components: [
- new MessageActionRow().addComponents([
- new MessageButton()
- .setLabel("Delete")
- .setStyle("DANGER")
- .setCustomId("closeticket")
- .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
- ].concat(client.database.premium.hasPremium(interaction.guild.id) ? [
- new MessageButton()
- .setLabel("Create Transcript and Delete")
- .setStyle("PRIMARY")
- .setCustomId("createtranscript")
- .setEmoji(getEmojiByName("CONTROL.DOWNLOAD", "id"))
- ] : []))
- ]});
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Close Ticket")
+ .setDescription(
+ "This ticket has been closed.\nType `/ticket close` again to delete it.\n\nNote: Check `/privacy` for details about transcripts."
+ )
+ .setStatus("Warning")
+ .setEmoji("GUILD.TICKET.ARCHIVED")
+ ],
+ components: [
+ new MessageActionRow().addComponents(
+ [
+ new MessageButton()
+ .setLabel("Delete")
+ .setStyle("DANGER")
+ .setCustomId("closeticket")
+ .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
+ ].concat(
+ client.database.premium.hasPremium(interaction.guild.id)
+ ? [
+ new MessageButton()
+ .setLabel("Create Transcript and Delete")
+ .setStyle("PRIMARY")
+ .setCustomId("createtranscript")
+ .setEmoji(
+ getEmojiByName(
+ "CONTROL.DOWNLOAD",
+ "id"
+ )
+ )
+ ]
+ : []
+ )
+ )
+ ]
+ });
return;
}
}
@@ -127,19 +207,22 @@
if (!tickets) return;
const ticketChannels = tickets.children;
let deleted = 0;
- ticketChannels.forEach(element => {
+ ticketChannels.forEach((element) => {
if (element.type !== "GUILD_TEXT") return;
if (element.topic.split(" ")[0] === member) {
try {
element.delete();
- } catch { /* Errors if the channel does not exist (deleted already) */ }
+ } catch {
+ /* Errors if the channel does not exist (deleted already) */
+ }
deleted++;
}
});
if (deleted) {
- const { log, NucleusColors, entry, renderUser, renderDelta } = member.client.logger;
+ const { log, NucleusColors, entry, renderUser, renderDelta } =
+ member.client.logger;
const data = {
- meta:{
+ meta: {
type: "ticketPurge",
displayName: "Tickets Purged",
calculateType: "ticketUpdate",
@@ -150,7 +233,10 @@
list: {
ticketFor: entry(member, renderUser(member)),
deletedBy: entry(null, "Member left server"),
- deleted: entry(new Date().getTime(), renderDelta(new Date().getTime())),
+ deleted: entry(
+ new Date().getTime(),
+ renderDelta(new Date().getTime())
+ ),
ticketsDeleted: deleted
},
hidden: {
@@ -161,4 +247,4 @@
}
}
-export { purgeByUser };
\ No newline at end of file
+export { purgeByUser };
diff --git a/src/api/index.ts b/src/api/index.ts
index b94bbe0..2c4baba 100644
--- a/src/api/index.ts
+++ b/src/api/index.ts
@@ -4,7 +4,6 @@
import EmojiEmbed from "../utils/generateEmojiEmbed.js";
import structuredClone from "@ungap/structured-clone";
-
const jsonParser = bodyParser.json();
const app = express();
const port = 10000;
@@ -19,26 +18,36 @@
const secret = req.body.secret;
if (secret === client.config.verifySecret) {
const guild = await client.guilds.fetch(client.verify[code].gID);
- if (!guild) { return res.status(404); }
+ if (!guild) {
+ return res.status(404);
+ }
const member = await guild.members.fetch(client.verify[code].uID);
- if (!member) { return res.status(404); }
- if (member.roles.cache.has(client.verify[code].rID)) { return res.status(200); }
+ if (!member) {
+ return res.status(404);
+ }
+ if (member.roles.cache.has(client.verify[code].rID)) {
+ return res.status(200);
+ }
await member.roles.add(client.verify[code].rID);
const interaction = client.verify[code].interaction;
if (interaction) {
- interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Verify")
- .setDescription("Verification complete")
- .setStatus("Success")
- .setEmoji("MEMBER.JOIN")
- ], components: []});
+ interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Verify")
+ .setDescription("Verification complete")
+ .setStatus("Success")
+ .setEmoji("MEMBER.JOIN")
+ ],
+ components: []
+ });
}
delete client.verify[code];
const { log, NucleusColors, entry, renderUser } = client.logger;
try {
const data = {
- meta:{
+ meta: {
type: "memberVerify",
displayName: "Member Verified",
calculateType: "guildMemberVerify",
@@ -70,14 +79,21 @@
try {
const interaction = client.verify[code].interaction;
if (interaction) {
- interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Verify")
- .setDescription("Verify was opened in another tab or window, please complete the CAPTCHA there to continue")
- .setStatus("Success")
- .setEmoji("MEMBER.JOIN")
- ]});
+ interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Verify")
+ .setDescription(
+ "Verify was opened in another tab or window, please complete the CAPTCHA there to continue"
+ )
+ .setStatus("Success")
+ .setEmoji("MEMBER.JOIN")
+ ]
+ });
}
- } catch { return res.sendStatus(410); }
+ } catch {
+ return res.sendStatus(410);
+ }
const data = structuredClone(client.verify[code]);
delete data.interaction;
return res.status(200).send(data);
@@ -89,10 +105,18 @@
const code = req.params.code;
const secret = req.body.secret;
if (secret === client.config.verifySecret) {
- const guild = await client.guilds.fetch(client.roleMenu[code].guild);
- if (!guild) { return res.status(404); }
- const member = await guild.members.fetch(client.roleMenu[code].user);
- if (!member) { return res.status(404); }
+ const guild = await client.guilds.fetch(
+ client.roleMenu[code].guild
+ );
+ if (!guild) {
+ return res.status(404);
+ }
+ const member = await guild.members.fetch(
+ client.roleMenu[code].user
+ );
+ if (!member) {
+ return res.status(404);
+ }
res.sendStatus(200);
} else {
res.sendStatus(403);
@@ -105,14 +129,22 @@
try {
const interaction = client.roleMenu[code].interaction;
if (interaction) {
- interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Roles")
- .setDescription("The role menu was opened in another tab or window, please select your roles there to continue")
- .setStatus("Success")
- .setEmoji("GUILD.GREEN")
- ], components: []});
+ interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Roles")
+ .setDescription(
+ "The role menu was opened in another tab or window, please select your roles there to continue"
+ )
+ .setStatus("Success")
+ .setEmoji("GUILD.GREEN")
+ ],
+ components: []
+ });
}
- } catch { return res.sendStatus(410); }
+ } catch {
+ return res.sendStatus(410);
+ }
const data = structuredClone(client.roleMenu[code]);
delete data.interaction;
console.log(data);
@@ -124,4 +156,4 @@
app.listen(port);
};
-export default runServer;
\ No newline at end of file
+export default runServer;
diff --git a/src/commands/help.ts b/src/commands/help.ts
index 900f24c..921318e 100644
--- a/src/commands/help.ts
+++ b/src/commands/help.ts
@@ -10,10 +10,13 @@
interaction.reply("hel p"); // TODO: FINISH THIS FOR RELEASE
};
-const check = (_interaction: CommandInteraction, _defaultCheck: WrappedCheck) => {
+const check = (
+ _interaction: CommandInteraction,
+ _defaultCheck: WrappedCheck
+) => {
return true;
};
export { command };
export { callback };
-export { check };
\ No newline at end of file
+export { check };
diff --git a/src/commands/mod/_meta.ts b/src/commands/mod/_meta.ts
index c2a76a9..7bdd813 100644
--- a/src/commands/mod/_meta.ts
+++ b/src/commands/mod/_meta.ts
@@ -1,4 +1,4 @@
const name = "mod";
const description = "Perform moderator actions";
-export { name, description };
\ No newline at end of file
+export { name, description };
diff --git a/src/commands/mod/ban.ts b/src/commands/mod/ban.ts
index a55dcfa..4560c8b 100644
--- a/src/commands/mod/ban.ts
+++ b/src/commands/mod/ban.ts
@@ -1,4 +1,9 @@
-import { CommandInteraction, GuildMember, MessageActionRow, MessageButton } from "discord.js";
+import {
+ CommandInteraction,
+ GuildMember,
+ MessageActionRow,
+ MessageButton
+} from "discord.js";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import confirmationMessage from "../../utils/confirmationMessage.js";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
@@ -10,8 +15,20 @@
builder
.setName("ban")
.setDescription("Bans a user from the server")
- .addUserOption(option => option.setName("user").setDescription("The user to ban").setRequired(true))
- .addNumberOption(option => option.setName("delete").setDescription("The days of messages to delete | Default: 0").setMinValue(0).setMaxValue(7).setRequired(false));
+ .addUserOption((option) =>
+ option
+ .setName("user")
+ .setDescription("The user to ban")
+ .setRequired(true)
+ )
+ .addNumberOption((option) =>
+ option
+ .setName("delete")
+ .setDescription("The days of messages to delete | Default: 0")
+ .setMinValue(0)
+ .setMaxValue(7)
+ .setRequired(false)
+ );
const callback = async (interaction: CommandInteraction): Promise<void> => {
const { renderUser } = client.logger;
@@ -23,13 +40,25 @@
confirmation = await new confirmationMessage(interaction)
.setEmoji("PUNISH.BAN.RED")
.setTitle("Ban")
- .setDescription(keyValueList({
- "user": renderUser(interaction.options.getUser("user")),
- "reason": reason ? ("\n> " + ((reason ?? "").replaceAll("\n", "\n> "))) : "*No reason provided*"
- })
- + `The user **will${notify ? "" : " not"}** be notified\n`
- + `${addPlurals(interaction.options.getInteger("delete") ? interaction.options.getInteger("delete") : 0, "day")} of messages will be deleted\n\n`
- + `Are you sure you want to ban <@!${(interaction.options.getMember("user") as GuildMember).id}>?`)
+ .setDescription(
+ keyValueList({
+ user: renderUser(interaction.options.getUser("user")),
+ reason: reason
+ ? "\n> " + (reason ?? "").replaceAll("\n", "\n> ")
+ : "*No reason provided*"
+ }) +
+ `The user **will${notify ? "" : " not"}** be notified\n` +
+ `${addPlurals(
+ interaction.options.getInteger("delete")
+ ? interaction.options.getInteger("delete")
+ : 0,
+ "day"
+ )} of messages will be deleted\n\n` +
+ `Are you sure you want to ban <@!${
+ (interaction.options.getMember("user") as GuildMember)
+ .id
+ }>?`
+ )
.setColor("Danger")
.addReasonButton(reason ?? "")
.send(reason !== null);
@@ -37,7 +66,8 @@
if (confirmation.cancelled) return;
if (confirmation.success) break;
if (confirmation.newReason) reason = confirmation.newReason;
- if (confirmation.components) notify = confirmation.components.notify.active;
+ if (confirmation.components)
+ notify = confirmation.components.notify.active;
}
if (confirmation.success) {
let dmd = false;
@@ -45,31 +75,52 @@
const config = await client.database.guilds.read(interaction.guild.id);
try {
if (notify) {
- dm = await (interaction.options.getMember("user") as GuildMember).send({
- embeds: [new EmojiEmbed()
- .setEmoji("PUNISH.BAN.RED")
- .setTitle("Banned")
- .setDescription(`You have been banned in ${interaction.guild.name}` +
- (reason ? ` for:\n> ${reason}` : "."))
- .setStatus("Danger")
+ dm = await (
+ interaction.options.getMember("user") as GuildMember
+ ).send({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("PUNISH.BAN.RED")
+ .setTitle("Banned")
+ .setDescription(
+ `You have been banned in ${interaction.guild.name}` +
+ (reason ? ` for:\n> ${reason}` : ".")
+ )
+ .setStatus("Danger")
],
- components: [new MessageActionRow().addComponents(config.moderation.ban.text ? [new MessageButton()
- .setStyle("LINK")
- .setLabel(config.moderation.ban.text)
- .setURL(config.moderation.ban.link)
- ] : [])]
+ components: [
+ new MessageActionRow().addComponents(
+ config.moderation.ban.text
+ ? [
+ new MessageButton()
+ .setStyle("LINK")
+ .setLabel(config.moderation.ban.text)
+ .setURL(config.moderation.ban.link)
+ ]
+ : []
+ )
+ ]
});
dmd = true;
}
- } catch { dmd = false; }
+ } catch {
+ dmd = false;
+ }
try {
- const member = (interaction.options.getMember("user") as GuildMember);
+ const member = interaction.options.getMember("user") as GuildMember;
member.ban({
days: Number(interaction.options.getNumber("delete") ?? 0),
reason: reason ?? "No reason provided"
});
- await client.database.history.create("ban", interaction.guild.id, member.user, interaction.user, reason);
- const { log, NucleusColors, entry, renderUser, renderDelta } = client.logger;
+ await client.database.history.create(
+ "ban",
+ interaction.guild.id,
+ member.user,
+ interaction.user,
+ reason
+ );
+ const { log, NucleusColors, entry, renderUser, renderDelta } =
+ client.logger;
const data = {
meta: {
type: "memberBan",
@@ -82,10 +133,22 @@
list: {
memberId: entry(member.user.id, `\`${member.user.id}\``),
name: entry(member.user.id, renderUser(member.user)),
- banned: entry(new Date().getTime(), renderDelta(new Date().getTime())),
- bannedBy: entry(interaction.user.id, renderUser(interaction.user)),
- reason: entry(reason, reason ? `\n> ${reason}` : "*No reason provided.*"),
- accountCreated: entry(member.user.createdAt, renderDelta(member.user.createdAt)),
+ banned: entry(
+ new Date().getTime(),
+ renderDelta(new Date().getTime())
+ ),
+ bannedBy: entry(
+ interaction.user.id,
+ renderUser(interaction.user)
+ ),
+ reason: entry(
+ reason,
+ reason ? `\n> ${reason}` : "*No reason provided.*"
+ ),
+ accountCreated: entry(
+ member.user.createdAt,
+ renderDelta(member.user.createdAt)
+ ),
serverMemberCount: interaction.guild.memberCount
},
hidden: {
@@ -94,56 +157,79 @@
};
log(data);
} catch {
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("PUNISH.BAN.RED")
- .setTitle("Ban")
- .setDescription("Something went wrong and the user was not banned")
- .setStatus("Danger")
- ], components: []});
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("PUNISH.BAN.RED")
+ .setTitle("Ban")
+ .setDescription(
+ "Something went wrong and the user was not banned"
+ )
+ .setStatus("Danger")
+ ],
+ components: []
+ });
if (dmd) await dm.delete();
return;
}
- const failed = (dmd === false && notify);
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji(`PUNISH.BAN.${failed ? "YELLOW" : "GREEN"}`)
- .setTitle("Ban")
- .setDescription("The member was banned" + (failed ? ", but could not be notified" : ""))
- .setStatus(failed ? "Warning" : "Success")
- ], components: []});
+ const failed = !dmd && notify;
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji(`PUNISH.BAN.${failed ? "YELLOW" : "GREEN"}`)
+ .setTitle("Ban")
+ .setDescription(
+ "The member was banned" +
+ (failed ? ", but could not be notified" : "")
+ )
+ .setStatus(failed ? "Warning" : "Success")
+ ],
+ components: []
+ });
} else {
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("PUNISH.BAN.GREEN")
- .setTitle("Ban")
- .setDescription("No changes were made")
- .setStatus("Success")
- ], components: []});
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("PUNISH.BAN.GREEN")
+ .setTitle("Ban")
+ .setDescription("No changes were made")
+ .setStatus("Success")
+ ],
+ components: []
+ });
}
};
const check = (interaction: CommandInteraction) => {
- const member = (interaction.member as GuildMember);
- const me = (interaction.guild.me as GuildMember);
- const apply = (interaction.options.getMember("user") as GuildMember);
- if (member === null || me === null || apply === null) throw "That member is not in the server";
+ const member = interaction.member as GuildMember;
+ const me = interaction.guild.me!;
+ const apply = interaction.options.getMember("user") as GuildMember;
+ if (member === null || me === null || apply === null)
+ throw "That member is not in the server";
const memberPos = member.roles ? member.roles.highest.position : 0;
const mePos = me.roles ? me.roles.highest.position : 0;
const applyPos = apply.roles ? apply.roles.highest.position : 0;
// Do not allow banning the owner
- if (member.id === interaction.guild.ownerId) throw "You cannot ban the owner of the server";
+ if (member.id === interaction.guild.ownerId)
+ throw "You cannot ban the owner of the server";
// Check if Nucleus can ban the member
- if (! (mePos > applyPos)) throw "I do not have a role higher than that member";
+ if (!(mePos > applyPos))
+ throw "I do not have a role higher than that member";
// Check if Nucleus has permission to ban
- if (! me.permissions.has("BAN_MEMBERS")) throw "I do not have the *Ban Members* permission";
+ if (!me.permissions.has("BAN_MEMBERS"))
+ throw "I do not have the *Ban Members* permission";
// Do not allow banning Nucleus
if (member.id === interaction.guild.me.id) throw "I cannot ban myself";
// Allow the owner to ban anyone
if (member.id === interaction.guild.ownerId) return true;
// Check if the user has ban_members permission
- if (! member.permissions.has("BAN_MEMBERS")) throw "You do not have the *Ban Members* permission";
+ if (!member.permissions.has("BAN_MEMBERS"))
+ throw "You do not have the *Ban Members* permission";
// Check if the user is below on the role list
- if (! (memberPos > applyPos)) throw "You do not have a role higher than that member";
+ if (!(memberPos > applyPos))
+ throw "You do not have a role higher than that member";
// Allow ban
return true;
};
-export { command, callback, check };
\ No newline at end of file
+export { command, callback, check };
diff --git a/src/commands/mod/info.ts b/src/commands/mod/info.ts
index 68b3ce7..86a4c4a 100644
--- a/src/commands/mod/info.ts
+++ b/src/commands/mod/info.ts
@@ -1,5 +1,11 @@
import { HistorySchema } from "../../utils/database";
-import Discord, { CommandInteraction, GuildMember, MessageActionRow, MessageButton, TextInputComponent } from "discord.js";
+import Discord, {
+ CommandInteraction,
+ GuildMember,
+ MessageActionRow,
+ MessageButton,
+ TextInputComponent
+} from "discord.js";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import getEmojiByName from "../../utils/getEmojiByName.js";
@@ -11,51 +17,88 @@
builder
.setName("info")
.setDescription("Shows moderator information about a user")
- .addUserOption(option => option.setName("user").setDescription("The user to get information about").setRequired(true));
+ .addUserOption((option) =>
+ option
+ .setName("user")
+ .setDescription("The user to get information about")
+ .setRequired(true)
+ );
const types = {
- "warn": {emoji: "PUNISH.WARN.YELLOW", text: "Warned"},
- "mute": {emoji: "PUNISH.MUTE.YELLOW", text: "Muted"},
- "unmute": {emoji: "PUNISH.MUTE.GREEN", text: "Unmuted"},
- "join": {emoji: "MEMBER.JOIN", text: "Joined"},
- "leave": {emoji: "MEMBER.LEAVE", text: "Left"},
- "kick": {emoji: "MEMBER.KICK", text: "Kicked"},
- "softban": {emoji: "PUNISH.SOFTBAN", text: "Softbanned"},
- "ban": {emoji: "MEMBER.BAN", text: "Banned"},
- "unban": {emoji: "MEMBER.UNBAN", text: "Unbanned"},
- "purge": {emoji: "PUNISH.CLEARHISTORY", text: "Messages cleared"},
- "nickname": {emoji: "PUNISH.NICKNAME.YELLOW", text: "Nickname changed"}
+ warn: { emoji: "PUNISH.WARN.YELLOW", text: "Warned" },
+ mute: { emoji: "PUNISH.MUTE.YELLOW", text: "Muted" },
+ unmute: { emoji: "PUNISH.MUTE.GREEN", text: "Unmuted" },
+ join: { emoji: "MEMBER.JOIN", text: "Joined" },
+ leave: { emoji: "MEMBER.LEAVE", text: "Left" },
+ kick: { emoji: "MEMBER.KICK", text: "Kicked" },
+ softban: { emoji: "PUNISH.SOFTBAN", text: "Softbanned" },
+ ban: { emoji: "MEMBER.BAN", text: "Banned" },
+ unban: { emoji: "MEMBER.UNBAN", text: "Unbanned" },
+ purge: { emoji: "PUNISH.CLEARHISTORY", text: "Messages cleared" },
+ nickname: { emoji: "PUNISH.NICKNAME.YELLOW", text: "Nickname changed" }
};
function historyToString(history: HistorySchema) {
let s = `${getEmojiByName(types[history.type].emoji)} ${
- history.amount ? (history.amount + " ") : ""
- }${
- types[history.type].text
- } on <t:${Math.round(history.occurredAt.getTime() / 1000)}:F>`;
- if (history.moderator) { s += ` by <@${history.moderator}>`; }
- if (history.reason) { s += `\n**Reason:**\n> ${history.reason}`; }
- if (history.before) { s += `\n**Before:**\n> ${history.before}`; }
- if (history.after) { s += `\n**After:**\n> ${history.after}`; }
+ history.amount ? history.amount + " " : ""
+ }${types[history.type].text} on <t:${Math.round(
+ history.occurredAt.getTime() / 1000
+ )}:F>`;
+ if (history.moderator) {
+ s += ` by <@${history.moderator}>`;
+ }
+ if (history.reason) {
+ s += `\n**Reason:**\n> ${history.reason}`;
+ }
+ if (history.before) {
+ s += `\n**Before:**\n> ${history.before}`;
+ }
+ if (history.after) {
+ s += `\n**After:**\n> ${history.after}`;
+ }
return s + "\n";
}
-
class TimelineSection {
name: string;
- content: {data: HistorySchema, rendered: string}[] = [];
+ content: { data: HistorySchema; rendered: string }[] = [];
- addContent = (content: {data: HistorySchema, rendered: string}) => { this.content.push(content); return this; };
- contentLength = () => { return this.content.reduce((acc, cur) => acc + cur.rendered.length, 0); };
+ addContent = (content: { data: HistorySchema; rendered: string }) => {
+ this.content.push(content);
+ return this;
+ };
+ contentLength = () => {
+ return this.content.reduce((acc, cur) => acc + cur.rendered.length, 0);
+ };
generateName = () => {
- const first = Math.round(this.content[0].data.occurredAt.getTime() / 1000);
- const last = Math.round(this.content[this.content.length - 1].data.occurredAt.getTime() / 1000);
- if (first === last) { return this.name = `<t:${first}:F>`; }
- return this.name = `<t:${first}:F> - <t:${last}:F>`;
+ const first = Math.round(
+ this.content[0].data.occurredAt.getTime() / 1000
+ );
+ const last = Math.round(
+ this.content[this.content.length - 1].data.occurredAt.getTime() /
+ 1000
+ );
+ if (first === last) {
+ return (this.name = `<t:${first}:F>`);
+ }
+ return (this.name = `<t:${first}:F> - <t:${last}:F>`);
};
}
-const monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
+const monthNames = [
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December"
+];
async function showHistory(member, interaction: CommandInteraction) {
let currentYear = new Date().getFullYear();
@@ -66,41 +109,72 @@
let openFilterPane = false;
while (true) {
if (refresh) {
- history = await client.database.history.read(member.guild.id, member.id, currentYear);
- history = history.sort((a, b) => b.occurredAt.getTime() - a.occurredAt.getTime()).reverse();
+ history = await client.database.history.read(
+ member.guild.id,
+ member.id,
+ currentYear
+ );
+ history = history
+ .sort((a, b) => b.occurredAt.getTime() - a.occurredAt.getTime())
+ .reverse();
if (openFilterPane) {
let tempFilteredTypes = filteredTypes;
- if (filteredTypes.length === 0) { tempFilteredTypes = Object.keys(types); }
- history = history.filter(h => tempFilteredTypes.includes(h.type));
+ if (filteredTypes.length === 0) {
+ tempFilteredTypes = Object.keys(types);
+ }
+ history = history.filter((h) =>
+ tempFilteredTypes.includes(h.type)
+ );
}
refresh = false;
}
const groups: TimelineSection[] = [];
if (history.length > 0) {
current = new TimelineSection();
- history.forEach(event => {
- if (current.contentLength() + historyToString(event).length > 2000 || current.content.length === 5) {
+ history.forEach((event) => {
+ if (
+ current.contentLength() + historyToString(event).length >
+ 2000 ||
+ current.content.length === 5
+ ) {
groups.push(current);
current.generateName();
current = new TimelineSection();
}
- current.addContent({data: event, rendered: historyToString(event)});
+ current.addContent({
+ data: event,
+ rendered: historyToString(event)
+ });
});
current.generateName();
groups.push(current);
- if (pageIndex === null) { pageIndex = groups.length - 1; }
+ if (pageIndex === null) {
+ pageIndex = groups.length - 1;
+ }
}
const components = (
- openFilterPane ? [
- new MessageActionRow().addComponents([new Discord.MessageSelectMenu().setOptions(
- Object.entries(types).map(([key, value]) => ({
- label: value.text,
- value: key,
- default: filteredTypes.includes(key),
- emoji: client.emojis.resolve(getEmojiByName(value.emoji, "id"))
- }))
- ).setMinValues(1).setMaxValues(Object.keys(types).length).setCustomId("filter").setPlaceholder("Select at least one event")])
- ] : []).concat([
+ openFilterPane
+ ? [
+ new MessageActionRow().addComponents([
+ new Discord.MessageSelectMenu()
+ .setOptions(
+ Object.entries(types).map(([key, value]) => ({
+ label: value.text,
+ value: key,
+ default: filteredTypes.includes(key),
+ emoji: client.emojis.resolve(
+ getEmojiByName(value.emoji, "id")
+ )
+ }))
+ )
+ .setMinValues(1)
+ .setMaxValues(Object.keys(types).length)
+ .setCustomId("filter")
+ .setPlaceholder("Select at least one event")
+ ])
+ ]
+ : []
+ ).concat([
new MessageActionRow().addComponents([
new MessageButton()
.setCustomId("prevYear")
@@ -119,14 +193,18 @@
.setCustomId("nextPage")
.setLabel("Next page")
.setStyle("PRIMARY")
- .setDisabled(pageIndex >= groups.length - 1 && currentYear === new Date().getFullYear()),
+ .setDisabled(
+ pageIndex >= groups.length - 1 &&
+ currentYear === new Date().getFullYear()
+ ),
new MessageButton()
.setCustomId("nextYear")
.setLabel((currentYear + 1).toString())
.setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
.setStyle("SECONDARY")
.setDisabled(currentYear === new Date().getFullYear())
- ]), new MessageActionRow().addComponents([
+ ]),
+ new MessageActionRow().addComponents([
new MessageButton()
.setLabel("Mod notes")
.setCustomId("modNotes")
@@ -139,40 +217,82 @@
.setEmoji(getEmojiByName("ICONS.FILTER", "id"))
])
]);
- const end = "\n\nJanuary " + currentYear.toString() + pageIndicator(
- Math.max(groups.length, 1),
- groups.length === 0 ? 1 : pageIndex
- ) + (currentYear === new Date().getFullYear() ? monthNames[new Date().getMonth()] : "December"
- ) + " " + currentYear.toString();
+ const end =
+ "\n\nJanuary " +
+ currentYear.toString() +
+ pageIndicator(
+ Math.max(groups.length, 1),
+ groups.length === 0 ? 1 : pageIndex
+ ) +
+ (currentYear === new Date().getFullYear()
+ ? monthNames[new Date().getMonth()]
+ : "December") +
+ " " +
+ currentYear.toString();
if (groups.length > 0) {
const toRender = groups[Math.min(pageIndex, groups.length - 1)];
- m = await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("MEMBER.JOIN")
- .setTitle("Moderation history for " + member.user.username)
- .setDescription(`**${toRender.name}**\n\n` + toRender.content.map(c => c.rendered).join("\n") + end)
- .setStatus("Success")
- .setFooter({text: (openFilterPane && filteredTypes.length) ? "Filters are currently enabled" : ""})
- ], components: components});
+ m = await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("MEMBER.JOIN")
+ .setTitle(
+ "Moderation history for " + member.user.username
+ )
+ .setDescription(
+ `**${toRender.name}**\n\n` +
+ toRender.content
+ .map((c) => c.rendered)
+ .join("\n") +
+ end
+ )
+ .setStatus("Success")
+ .setFooter({
+ text:
+ openFilterPane && filteredTypes.length
+ ? "Filters are currently enabled"
+ : ""
+ })
+ ],
+ components: components
+ });
} else {
- m = await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("MEMBER.JOIN")
- .setTitle("Moderation history for " + member.user.username)
- .setDescription(`**${currentYear}**\n\n*No events*` + "\n\n" + end)
- .setStatus("Success")
- .setFooter({text: (openFilterPane && filteredTypes.length) ? "Filters are currently enabled" : ""})
- ], components: components});
+ m = await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("MEMBER.JOIN")
+ .setTitle(
+ "Moderation history for " + member.user.username
+ )
+ .setDescription(
+ `**${currentYear}**\n\n*No events*` + "\n\n" + end
+ )
+ .setStatus("Success")
+ .setFooter({
+ text:
+ openFilterPane && filteredTypes.length
+ ? "Filters are currently enabled"
+ : ""
+ })
+ ],
+ components: components
+ });
}
let i;
try {
i = await m.awaitMessageComponent({ time: 300000 });
} catch (e) {
- interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("MEMBER.JOIN")
- .setTitle("Moderation history for " + member.user.username)
- .setDescription(m.embeds[0].description)
- .setStatus("Danger")
- .setFooter({text: "Message timed out"})
- ]});
+ interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("MEMBER.JOIN")
+ .setTitle(
+ "Moderation history for " + member.user.username
+ )
+ .setDescription(m.embeds[0].description)
+ .setStatus("Danger")
+ .setFooter({ text: "Message timed out" })
+ ]
+ });
return 0;
}
i.deferUpdate();
@@ -181,103 +301,170 @@
pageIndex = null;
refresh = true;
}
- if (i.customId === "prevYear") { currentYear--; pageIndex = null; refresh = true; }
- if (i.customId === "nextYear") { currentYear++; pageIndex = null; refresh = true; }
+ if (i.customId === "prevYear") {
+ currentYear--;
+ pageIndex = null;
+ refresh = true;
+ }
+ if (i.customId === "nextYear") {
+ currentYear++;
+ pageIndex = null;
+ refresh = true;
+ }
if (i.customId === "prevPage") {
pageIndex--;
- if (pageIndex < 0) { pageIndex = null; currentYear--; refresh = true; }
+ if (pageIndex < 0) {
+ pageIndex = null;
+ currentYear--;
+ refresh = true;
+ }
}
if (i.customId === "nextPage") {
pageIndex++;
- if (pageIndex >= groups.length) { pageIndex = 0; currentYear++; refresh = true; }
+ if (pageIndex >= groups.length) {
+ pageIndex = 0;
+ currentYear++;
+ refresh = true;
+ }
}
- if (i.customId === "today") { currentYear = new Date().getFullYear(); pageIndex = null; refresh = true; }
- if (i.customId === "modNotes") { return 1; }
- if (i.customId === "openFilter") { openFilterPane = !openFilterPane; refresh = true; }
+ if (i.customId === "today") {
+ currentYear = new Date().getFullYear();
+ pageIndex = null;
+ refresh = true;
+ }
+ if (i.customId === "modNotes") {
+ return 1;
+ }
+ if (i.customId === "openFilter") {
+ openFilterPane = !openFilterPane;
+ refresh = true;
+ }
}
}
-
-const callback = async (interaction: CommandInteraction): Promise<void | unknown> => {
+const callback = async (
+ interaction: CommandInteraction
+): Promise<void | unknown> => {
let m;
- const member = (interaction.options.getMember("user")) as Discord.GuildMember;
- await interaction.reply({embeds: [new EmojiEmbed()
- .setEmoji("NUCLEUS.LOADING")
- .setTitle("Downloading Data")
- .setStatus("Danger")
- ], ephemeral: true, fetchReply: true});
+ const member = interaction.options.getMember("user") as Discord.GuildMember;
+ await interaction.reply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("NUCLEUS.LOADING")
+ .setTitle("Downloading Data")
+ .setStatus("Danger")
+ ],
+ ephemeral: true,
+ fetchReply: true
+ });
let note;
let firstLoad = true;
while (true) {
note = await client.database.notes.read(member.guild.id, member.id);
- if (firstLoad && !note) { await showHistory(member, interaction); }
+ if (firstLoad && !note) {
+ await showHistory(member, interaction);
+ }
firstLoad = false;
- m = await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("MEMBER.JOIN")
- .setTitle("Mod notes for " + member.user.username)
- .setDescription(note ? note : "*No note set*")
- .setStatus("Success")
- ], components: [new MessageActionRow().addComponents([
- new MessageButton()
- .setLabel(`${note ? "Modify" : "Create"} note`)
- .setStyle("PRIMARY")
- .setCustomId("modify")
- .setEmoji(getEmojiByName("ICONS.EDIT", "id")),
- new MessageButton()
- .setLabel("View moderation history")
- .setStyle("PRIMARY")
- .setCustomId("history")
- .setEmoji(getEmojiByName("ICONS.HISTORY", "id"))
- ])]});
+ m = await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("MEMBER.JOIN")
+ .setTitle("Mod notes for " + member.user.username)
+ .setDescription(note ? note : "*No note set*")
+ .setStatus("Success")
+ ],
+ components: [
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setLabel(`${note ? "Modify" : "Create"} note`)
+ .setStyle("PRIMARY")
+ .setCustomId("modify")
+ .setEmoji(getEmojiByName("ICONS.EDIT", "id")),
+ new MessageButton()
+ .setLabel("View moderation history")
+ .setStyle("PRIMARY")
+ .setCustomId("history")
+ .setEmoji(getEmojiByName("ICONS.HISTORY", "id"))
+ ])
+ ]
+ });
let i;
try {
i = await m.awaitMessageComponent({ time: 300000 });
- } catch (e) { return; }
+ } catch (e) {
+ return;
+ }
if (i.customId === "modify") {
- await i.showModal(new Discord.Modal().setCustomId("modal").setTitle("Editing moderator note").addComponents(
- new MessageActionRow<TextInputComponent>().addComponents(new TextInputComponent()
- .setCustomId("note")
- .setLabel("Note")
- .setMaxLength(4000)
- .setRequired(false)
- .setStyle("PARAGRAPH")
- .setValue(note ? note : "")
- )
- ));
+ await i.showModal(
+ new Discord.Modal()
+ .setCustomId("modal")
+ .setTitle("Editing moderator note")
+ .addComponents(
+ new MessageActionRow<TextInputComponent>().addComponents(
+ new TextInputComponent()
+ .setCustomId("note")
+ .setLabel("Note")
+ .setMaxLength(4000)
+ .setRequired(false)
+ .setStyle("PARAGRAPH")
+ .setValue(note ? note : "")
+ )
+ )
+ );
await interaction.editReply({
- embeds: [new EmojiEmbed()
- .setTitle("Mod notes for " + member.user.username)
- .setDescription("Modal opened. If you can't see it, click back and try again.")
- .setStatus("Success")
- .setEmoji("GUILD.TICKET.OPEN")
- ], components: [new MessageActionRow().addComponents([new MessageButton()
- .setLabel("Back")
- .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
- .setStyle("PRIMARY")
- .setCustomId("back")
- ])]
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Mod notes for " + member.user.username)
+ .setDescription(
+ "Modal opened. If you can't see it, click back and try again."
+ )
+ .setStatus("Success")
+ .setEmoji("GUILD.TICKET.OPEN")
+ ],
+ components: [
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setLabel("Back")
+ .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
+ .setStyle("PRIMARY")
+ .setCustomId("back")
+ ])
+ ]
});
let out;
try {
- out = await modalInteractionCollector(m, (m) => m.channel.id === interaction.channel.id, (m) => m.customId === "modify");
- } catch (e) { continue; }
+ out = await modalInteractionCollector(
+ m,
+ (m) => m.channel.id === interaction.channel.id,
+ (m) => m.customId === "modify"
+ );
+ } catch (e) {
+ continue;
+ }
if (out.fields) {
const toAdd = out.fields.getTextInputValue("note") || null;
- await client.database.notes.create(member.guild.id, member.id, toAdd);
- } else { continue; }
+ await client.database.notes.create(
+ member.guild.id,
+ member.id,
+ toAdd
+ );
+ } else {
+ continue;
+ }
} else if (i.customId === "history") {
i.deferUpdate();
- if (!await showHistory(member, interaction) ) return;
+ if (!(await showHistory(member, interaction))) return;
}
}
};
const check = (interaction: CommandInteraction) => {
- const member = (interaction.member as GuildMember);
- if (! member.permissions.has("MODERATE_MEMBERS")) throw "You do not have the *Moderate Members* permission";
+ const member = interaction.member as GuildMember;
+ if (!member.permissions.has("MODERATE_MEMBERS"))
+ throw "You do not have the *Moderate Members* permission";
return true;
};
export { command };
export { callback };
-export { check };
\ No newline at end of file
+export { check };
diff --git a/src/commands/mod/kick.ts b/src/commands/mod/kick.ts
index 23785c3..59c2f81 100644
--- a/src/commands/mod/kick.ts
+++ b/src/commands/mod/kick.ts
@@ -1,4 +1,9 @@
-import { CommandInteraction, GuildMember, MessageActionRow, MessageButton } from "discord.js";
+import {
+ CommandInteraction,
+ GuildMember,
+ MessageActionRow,
+ MessageButton
+} from "discord.js";
import humanizeDuration from "humanize-duration";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import confirmationMessage from "../../utils/confirmationMessage.js";
@@ -10,9 +15,16 @@
builder
.setName("kick")
.setDescription("Kicks a user from the server")
- .addUserOption(option => option.setName("user").setDescription("The user to kick").setRequired(true));
+ .addUserOption((option) =>
+ option
+ .setName("user")
+ .setDescription("The user to kick")
+ .setRequired(true)
+ );
-const callback = async (interaction: CommandInteraction): Promise<void | unknown> => {
+const callback = async (
+ interaction: CommandInteraction
+): Promise<void | unknown> => {
const { renderUser } = client.logger;
// TODO:[Modals] Replace this with a modal
let reason = null;
@@ -22,12 +34,19 @@
confirmation = await new confirmationMessage(interaction)
.setEmoji("PUNISH.KICK.RED")
.setTitle("Kick")
- .setDescription(keyValueList({
- "user": renderUser(interaction.options.getUser("user")),
- "reason": reason ? ("\n> " + ((reason ?? "").replaceAll("\n", "\n> "))) : "*No reason provided*"
- })
- + `The user **will${notify ? "" : " not"}** be notified\n\n`
- + `Are you sure you want to kick <@!${(interaction.options.getMember("user") as GuildMember).id}>?`)
+ .setDescription(
+ keyValueList({
+ user: renderUser(interaction.options.getUser("user")),
+ reason: reason
+ ? "\n> " + (reason ?? "").replaceAll("\n", "\n> ")
+ : "*No reason provided*"
+ }) +
+ `The user **will${notify ? "" : " not"}** be notified\n\n` +
+ `Are you sure you want to kick <@!${
+ (interaction.options.getMember("user") as GuildMember)
+ .id
+ }>?`
+ )
.setColor("Danger")
.addReasonButton(reason ?? "")
.send(reason !== null);
@@ -45,28 +64,51 @@
const config = await client.database.guilds.read(interaction.guild.id);
try {
if (notify) {
- dm = await (interaction.options.getMember("user") as GuildMember).send({
- embeds: [new EmojiEmbed()
- .setEmoji("PUNISH.KICK.RED")
- .setTitle("Kicked")
- .setDescription(`You have been kicked in ${interaction.guild.name}` +
- (reason ? ` for:\n> ${reason}` : "."))
- .setStatus("Danger")
+ dm = await (
+ interaction.options.getMember("user") as GuildMember
+ ).send({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("PUNISH.KICK.RED")
+ .setTitle("Kicked")
+ .setDescription(
+ `You have been kicked in ${interaction.guild.name}` +
+ (reason ? ` for:\n> ${reason}` : ".")
+ )
+ .setStatus("Danger")
],
- components: [new MessageActionRow().addComponents(config.moderation.kick.text ? [new MessageButton()
- .setStyle("LINK")
- .setLabel(config.moderation.kick.text)
- .setURL(config.moderation.kick.link)
- ] : [])]
+ components: [
+ new MessageActionRow().addComponents(
+ config.moderation.kick.text
+ ? [
+ new MessageButton()
+ .setStyle("LINK")
+ .setLabel(config.moderation.kick.text)
+ .setURL(config.moderation.kick.link)
+ ]
+ : []
+ )
+ ]
});
dmd = true;
}
- } catch { dmd = false; }
+ } catch {
+ dmd = false;
+ }
try {
- (interaction.options.getMember("user") as GuildMember).kick(reason ?? "No reason provided.");
- const member = (interaction.options.getMember("user") as GuildMember);
- await client.database.history.create("kick", interaction.guild.id, member.user, interaction.user, reason);
- const { log, NucleusColors, entry, renderUser, renderDelta } = client.logger;
+ (interaction.options.getMember("user") as GuildMember).kick(
+ reason ?? "No reason provided."
+ );
+ const member = interaction.options.getMember("user") as GuildMember;
+ await client.database.history.create(
+ "kick",
+ interaction.guild.id,
+ member.user,
+ interaction.user,
+ reason
+ );
+ const { log, NucleusColors, entry, renderUser, renderDelta } =
+ client.logger;
const data = {
meta: {
type: "memberKick",
@@ -79,12 +121,35 @@
list: {
memberId: entry(member.id, `\`${member.id}\``),
name: entry(member.id, renderUser(member.user)),
- joined: entry(member.joinedAt, renderDelta(member.joinedAt)),
- kicked: entry(new Date().getTime(), renderDelta(new Date().getTime())),
- kickedBy: entry(interaction.user.id, renderUser(interaction.user)),
- reason: entry(reason, reason ? `\n> ${reason}` : "*No reason provided.*"),
- timeInServer: entry(new Date().getTime() - member.joinedTimestamp, humanizeDuration(new Date().getTime() - member.joinedTimestamp, { round: true })),
- accountCreated: entry(member.user.createdAt, renderDelta(member.user.createdAt)),
+ joined: entry(
+ member.joinedAt,
+ renderDelta(member.joinedAt)
+ ),
+ kicked: entry(
+ new Date().getTime(),
+ renderDelta(new Date().getTime())
+ ),
+ kickedBy: entry(
+ interaction.user.id,
+ renderUser(interaction.user)
+ ),
+ reason: entry(
+ reason,
+ reason ? `\n> ${reason}` : "*No reason provided.*"
+ ),
+ timeInServer: entry(
+ new Date().getTime() - member.joinedTimestamp,
+ humanizeDuration(
+ new Date().getTime() - member.joinedTimestamp,
+ {
+ round: true
+ }
+ )
+ ),
+ accountCreated: entry(
+ member.user.createdAt,
+ renderDelta(member.user.createdAt)
+ ),
serverMemberCount: member.guild.memberCount
},
hidden: {
@@ -93,56 +158,79 @@
};
log(data);
} catch {
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("PUNISH.KICK.RED")
- .setTitle("Kick")
- .setDescription("Something went wrong and the user was not kicked")
- .setStatus("Danger")
- ], components: []});
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("PUNISH.KICK.RED")
+ .setTitle("Kick")
+ .setDescription(
+ "Something went wrong and the user was not kicked"
+ )
+ .setStatus("Danger")
+ ],
+ components: []
+ });
if (dmd) await dm.delete();
return;
}
- const failed = (dmd === false && notify);
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji(`PUNISH.KICK.${failed ? "YELLOW" : "GREEN"}`)
- .setTitle("Kick")
- .setDescription("The member was kicked" + (failed ? ", but could not be notified" : ""))
- .setStatus(failed ? "Warning" : "Success")
- ], components: []});
+ const failed = !dmd && notify;
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji(`PUNISH.KICK.${failed ? "YELLOW" : "GREEN"}`)
+ .setTitle("Kick")
+ .setDescription(
+ "The member was kicked" +
+ (failed ? ", but could not be notified" : "")
+ )
+ .setStatus(failed ? "Warning" : "Success")
+ ],
+ components: []
+ });
} else {
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("PUNISH.KICK.GREEN")
- .setTitle("Kick")
- .setDescription("No changes were made")
- .setStatus("Success")
- ], components: []});
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("PUNISH.KICK.GREEN")
+ .setTitle("Kick")
+ .setDescription("No changes were made")
+ .setStatus("Success")
+ ],
+ components: []
+ });
}
};
const check = (interaction: CommandInteraction) => {
- const member = (interaction.member as GuildMember);
- const me = (interaction.guild.me as GuildMember);
- const apply = (interaction.options.getMember("user") as GuildMember);
- if (member === null || me === null || apply === null) throw "That member is not in the server";
+ const member = interaction.member as GuildMember;
+ const me = interaction.guild.me!;
+ const apply = interaction.options.getMember("user") as GuildMember;
+ if (member === null || me === null || apply === null)
+ throw "That member is not in the server";
const memberPos = member.roles ? member.roles.highest.position : 0;
const mePos = me.roles ? me.roles.highest.position : 0;
const applyPos = apply.roles ? apply.roles.highest.position : 0;
// Do not allow kicking the owner
- if (member.id === interaction.guild.ownerId) throw "You cannot kick the owner of the server";
+ if (member.id === interaction.guild.ownerId)
+ throw "You cannot kick the owner of the server";
// Check if Nucleus can kick the member
- if (! (mePos > applyPos)) throw "I do not have a role higher than that member";
+ if (!(mePos > applyPos))
+ throw "I do not have a role higher than that member";
// Check if Nucleus has permission to kick
- if (! me.permissions.has("KICK_MEMBERS")) throw "I do not have the *Kick Members* permission";
+ if (!me.permissions.has("KICK_MEMBERS"))
+ throw "I do not have the *Kick Members* permission";
// Do not allow kicking Nucleus
if (member.id === interaction.guild.me.id) throw "I cannot kick myself";
// Allow the owner to kick anyone
if (member.id === interaction.guild.ownerId) return true;
// Check if the user has kick_members permission
- if (! member.permissions.has("KICK_MEMBERS")) throw "You do not have the *Kick Members* permission";
+ if (!member.permissions.has("KICK_MEMBERS"))
+ throw "You do not have the *Kick Members* permission";
// Check if the user is below on the role list
- if (! (memberPos > applyPos)) throw "You do not have a role higher than that member";
+ if (!(memberPos > applyPos))
+ throw "You do not have a role higher than that member";
// Allow kick
return true;
};
-export { command, callback, check };
\ No newline at end of file
+export { command, callback, check };
diff --git a/src/commands/mod/mute.ts b/src/commands/mod/mute.ts
index 1e9a812..5be6f43 100644
--- a/src/commands/mod/mute.ts
+++ b/src/commands/mod/mute.ts
@@ -1,5 +1,11 @@
import { LoadingEmbed } from "./../../utils/defaultEmbeds.js";
-import Discord, { CommandInteraction, GuildMember, Message, MessageActionRow, MessageButton } from "discord.js";
+import Discord, {
+ CommandInteraction,
+ GuildMember,
+ Message,
+ MessageActionRow,
+ MessageButton
+} from "discord.js";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import getEmojiByName from "../../utils/getEmojiByName.js";
@@ -7,20 +13,69 @@
import keyValueList from "../../utils/generateKeyValueList.js";
import humanizeDuration from "humanize-duration";
import client from "../../utils/client.js";
-import { areTicketsEnabled, create } from "../../actions/createModActionTicket.js";
+import {
+ areTicketsEnabled,
+ create
+} from "../../actions/createModActionTicket.js";
const command = (builder: SlashCommandSubcommandBuilder) =>
builder
.setName("mute")
- .setDescription("Mutes a member, stopping them from talking in the server")
- .addUserOption(option => option.setName("user").setDescription("The user to mute").setRequired(true))
- .addIntegerOption(option => option.setName("days").setDescription("The number of days to mute the user for | Default: 0").setMinValue(0).setMaxValue(27).setRequired(false))
- .addIntegerOption(option => option.setName("hours").setDescription("The number of hours to mute the user for | Default: 0").setMinValue(0).setMaxValue(23).setRequired(false))
- .addIntegerOption(option => option.setName("minutes").setDescription("The number of minutes to mute the user for | Default: 0").setMinValue(0).setMaxValue(59).setRequired(false))
- .addIntegerOption(option => option.setName("seconds").setDescription("The number of seconds to mute the user for | Default: 0").setMinValue(0).setMaxValue(59).setRequired(false));
+ .setDescription(
+ "Mutes a member, stopping them from talking in the server"
+ )
+ .addUserOption((option) =>
+ option
+ .setName("user")
+ .setDescription("The user to mute")
+ .setRequired(true)
+ )
+ .addIntegerOption((option) =>
+ option
+ .setName("days")
+ .setDescription(
+ "The number of days to mute the user for | Default: 0"
+ )
+ .setMinValue(0)
+ .setMaxValue(27)
+ .setRequired(false)
+ )
+ .addIntegerOption((option) =>
+ option
+ .setName("hours")
+ .setDescription(
+ "The number of hours to mute the user for | Default: 0"
+ )
+ .setMinValue(0)
+ .setMaxValue(23)
+ .setRequired(false)
+ )
+ .addIntegerOption((option) =>
+ option
+ .setName("minutes")
+ .setDescription(
+ "The number of minutes to mute the user for | Default: 0"
+ )
+ .setMinValue(0)
+ .setMaxValue(59)
+ .setRequired(false)
+ )
+ .addIntegerOption((option) =>
+ option
+ .setName("seconds")
+ .setDescription(
+ "The number of seconds to mute the user for | Default: 0"
+ )
+ .setMinValue(0)
+ .setMaxValue(59)
+ .setRequired(false)
+ );
-const callback = async (interaction: CommandInteraction): Promise<void | unknown> => {
- const { log, NucleusColors, renderUser, entry, renderDelta } = client.logger;
+const callback = async (
+ interaction: CommandInteraction
+): Promise<void | unknown> => {
+ const { log, NucleusColors, renderUser, entry, renderDelta } =
+ client.logger;
const user = interaction.options.getMember("user") as GuildMember;
const time = {
days: interaction.options.getInteger("days") || 0,
@@ -29,85 +84,136 @@
seconds: interaction.options.getInteger("seconds") || 0
};
const config = await client.database.guilds.read(interaction.guild.id);
- let serverSettingsDescription = (config.moderation.mute.timeout ? "given a timeout" : "");
- if (config.moderation.mute.role) serverSettingsDescription += (serverSettingsDescription ? " and " : "") + `given the <@&${config.moderation.mute.role}> role`;
+ let serverSettingsDescription = config.moderation.mute.timeout
+ ? "given a timeout"
+ : "";
+ if (config.moderation.mute.role)
+ serverSettingsDescription +=
+ (serverSettingsDescription ? " and " : "") +
+ `given the <@&${config.moderation.mute.role}> role`;
- let muteTime = (time.days * 24 * 60 * 60) + (time.hours * 60 * 60) + (time.minutes * 60) + time.seconds;
+ let muteTime =
+ time.days * 24 * 60 * 60 +
+ time.hours * 60 * 60 +
+ time.minutes * 60 +
+ time.seconds;
if (muteTime === 0) {
- const m = await interaction.reply({embeds: [
- new EmojiEmbed()
- .setEmoji("PUNISH.MUTE.GREEN")
- .setTitle("Mute")
- .setDescription("How long should the user be muted")
- .setStatus("Success")
- ], components: [
- new MessageActionRow().addComponents([
- new Discord.MessageButton()
- .setCustomId("1m")
- .setLabel("1 Minute")
- .setStyle("SECONDARY"),
- new Discord.MessageButton()
- .setCustomId("10m")
- .setLabel("10 Minutes")
- .setStyle("SECONDARY"),
- new Discord.MessageButton()
- .setCustomId("30m")
- .setLabel("30 Minutes")
- .setStyle("SECONDARY"),
- new Discord.MessageButton()
- .setCustomId("1h")
- .setLabel("1 Hour")
- .setStyle("SECONDARY")
- ]),
- new MessageActionRow().addComponents([
- new Discord.MessageButton()
- .setCustomId("6h")
- .setLabel("6 Hours")
- .setStyle("SECONDARY"),
- new Discord.MessageButton()
- .setCustomId("12h")
- .setLabel("12 Hours")
- .setStyle("SECONDARY"),
- new Discord.MessageButton()
- .setCustomId("1d")
- .setLabel("1 Day")
- .setStyle("SECONDARY"),
- new Discord.MessageButton()
- .setCustomId("1w")
- .setLabel("1 Week")
- .setStyle("SECONDARY")
- ]),
- new MessageActionRow().addComponents([
- new Discord.MessageButton()
- .setCustomId("cancel")
- .setLabel("Cancel")
- .setStyle("DANGER")
- .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
- ])
- ], ephemeral: true, fetchReply: true}) as Message;
+ const m = (await interaction.reply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("PUNISH.MUTE.GREEN")
+ .setTitle("Mute")
+ .setDescription("How long should the user be muted")
+ .setStatus("Success")
+ ],
+ components: [
+ new MessageActionRow().addComponents([
+ new Discord.MessageButton()
+ .setCustomId("1m")
+ .setLabel("1 Minute")
+ .setStyle("SECONDARY"),
+ new Discord.MessageButton()
+ .setCustomId("10m")
+ .setLabel("10 Minutes")
+ .setStyle("SECONDARY"),
+ new Discord.MessageButton()
+ .setCustomId("30m")
+ .setLabel("30 Minutes")
+ .setStyle("SECONDARY"),
+ new Discord.MessageButton()
+ .setCustomId("1h")
+ .setLabel("1 Hour")
+ .setStyle("SECONDARY")
+ ]),
+ new MessageActionRow().addComponents([
+ new Discord.MessageButton()
+ .setCustomId("6h")
+ .setLabel("6 Hours")
+ .setStyle("SECONDARY"),
+ new Discord.MessageButton()
+ .setCustomId("12h")
+ .setLabel("12 Hours")
+ .setStyle("SECONDARY"),
+ new Discord.MessageButton()
+ .setCustomId("1d")
+ .setLabel("1 Day")
+ .setStyle("SECONDARY"),
+ new Discord.MessageButton()
+ .setCustomId("1w")
+ .setLabel("1 Week")
+ .setStyle("SECONDARY")
+ ]),
+ new MessageActionRow().addComponents([
+ new Discord.MessageButton()
+ .setCustomId("cancel")
+ .setLabel("Cancel")
+ .setStyle("DANGER")
+ .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
+ ])
+ ],
+ ephemeral: true,
+ fetchReply: true
+ })) as Message;
let component;
try {
- component = await m.awaitMessageComponent({filter: (m) => m.user.id === interaction.user.id, time: 300000});
- } catch { return; }
+ component = await m.awaitMessageComponent({
+ filter: (m) => m.user.id === interaction.user.id,
+ time: 300000
+ });
+ } catch {
+ return;
+ }
component.deferUpdate();
- if (component.customId === "cancel") return interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("PUNISH.MUTE.RED")
- .setTitle("Mute")
- .setDescription("Mute cancelled")
- .setStatus("Danger")
- ]});
+ if (component.customId === "cancel")
+ return interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("PUNISH.MUTE.RED")
+ .setTitle("Mute")
+ .setDescription("Mute cancelled")
+ .setStatus("Danger")
+ ]
+ });
switch (component.customId) {
- case "1m": { muteTime = 60; break; }
- case "10m": { muteTime = 60 * 10; break; }
- case "30m": { muteTime = 60 * 30; break; }
- case "1h": { muteTime = 60 * 60; break; }
- case "6h": { muteTime = 60 * 60 * 6; break; }
- case "12h": { muteTime = 60 * 60 * 12; break; }
- case "1d": { muteTime = 60 * 60 * 24; break; }
- case "1w": { muteTime = 60 * 60 * 24 * 7; break; }
+ case "1m": {
+ muteTime = 60;
+ break;
+ }
+ case "10m": {
+ muteTime = 60 * 10;
+ break;
+ }
+ case "30m": {
+ muteTime = 60 * 30;
+ break;
+ }
+ case "1h": {
+ muteTime = 60 * 60;
+ break;
+ }
+ case "6h": {
+ muteTime = 60 * 60 * 6;
+ break;
+ }
+ case "12h": {
+ muteTime = 60 * 60 * 12;
+ break;
+ }
+ case "1d": {
+ muteTime = 60 * 60 * 24;
+ break;
+ }
+ case "1w": {
+ muteTime = 60 * 60 * 24 * 7;
+ break;
+ }
}
} else {
- await interaction.reply({embeds: LoadingEmbed, ephemeral: true, fetchReply: true});
+ await interaction.reply({
+ embeds: LoadingEmbed,
+ ephemeral: true,
+ fetchReply: true
+ });
}
// TODO:[Modals] Replace this with a modal
let reason = null;
@@ -118,20 +224,47 @@
confirmation = await new confirmationMessage(interaction)
.setEmoji("PUNISH.MUTE.RED")
.setTitle("Mute")
- .setDescription(keyValueList({
- "user": renderUser(user.user),
- "time": `${humanizeDuration(muteTime * 1000, {round: true})}`,
- "reason": reason ? ("\n> " + ((reason ?? "").replaceAll("\n", "\n> "))) : "*No reason provided*"
- })
- + "The user will be " + serverSettingsDescription + "\n"
- + `The user **will${notify ? "" : " not"}** be notified\n\n`
- + `Are you sure you want to mute <@!${user.id}>?`)
+ .setDescription(
+ keyValueList({
+ user: renderUser(user.user),
+ time: `${humanizeDuration(muteTime * 1000, {
+ round: true
+ })}`,
+ reason: reason
+ ? "\n> " + (reason ?? "").replaceAll("\n", "\n> ")
+ : "*No reason provided*"
+ }) +
+ "The user will be " +
+ serverSettingsDescription +
+ "\n" +
+ `The user **will${notify ? "" : " not"}** be notified\n\n` +
+ `Are you sure you want to mute <@!${user.id}>?`
+ )
.setColor("Danger")
.addCustomBoolean(
- "appeal", "Create appeal ticket", !(await areTicketsEnabled(interaction.guild.id)),
- async () => await create(interaction.guild, interaction.options.getUser("user"), interaction.user, reason),
- "An appeal ticket will be created when Confirm is clicked", "CONTROL.TICKET", createAppealTicket)
- .addCustomBoolean("notify", "Notify user", false, null, null, "ICONS.NOTIFY." + (notify ? "ON" : "OFF" ), notify)
+ "appeal",
+ "Create appeal ticket",
+ !(await areTicketsEnabled(interaction.guild.id)),
+ async () =>
+ await create(
+ interaction.guild,
+ interaction.options.getUser("user"),
+ interaction.user,
+ reason
+ ),
+ "An appeal ticket will be created when Confirm is clicked",
+ "CONTROL.TICKET",
+ createAppealTicket
+ )
+ .addCustomBoolean(
+ "notify",
+ "Notify user",
+ false,
+ null,
+ null,
+ "ICONS.NOTIFY." + (notify ? "ON" : "OFF"),
+ notify
+ )
.addReasonButton(reason ?? "")
.send(true);
reason = reason ?? "";
@@ -150,69 +283,135 @@
try {
if (notify) {
dm = await user.send({
- embeds: [new EmojiEmbed()
- .setEmoji("PUNISH.MUTE.RED")
- .setTitle("Muted")
- .setDescription(`You have been muted in ${interaction.guild.name}` +
- (reason ? ` for:\n> ${reason}` : ".\n\n" +
- `You will be unmuted at: <t:${Math.round((new Date).getTime() / 1000) + muteTime}:D> at <t:${Math.round((new Date).getTime() / 1000) + muteTime}:T> (<t:${Math.round((new Date).getTime() / 1000) + muteTime}:R>)`) +
- (confirmation.components.appeal.response ? `You can appeal this here: <#${confirmation.components.appeal.response}>` : ""))
- .setStatus("Danger")
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("PUNISH.MUTE.RED")
+ .setTitle("Muted")
+ .setDescription(
+ `You have been muted in ${interaction.guild.name}` +
+ (reason
+ ? ` for:\n> ${reason}`
+ : ".\n\n" +
+ `You will be unmuted at: <t:${
+ Math.round(
+ new Date().getTime() / 1000
+ ) + muteTime
+ }:D> at <t:${
+ Math.round(
+ new Date().getTime() / 1000
+ ) + muteTime
+ }:T> (<t:${
+ Math.round(
+ new Date().getTime() / 1000
+ ) + muteTime
+ }:R>)`) +
+ (confirmation.components.appeal.response
+ ? `You can appeal this here: <#${confirmation.components.appeal.response}>`
+ : "")
+ )
+ .setStatus("Danger")
],
- components: [new MessageActionRow().addComponents(config.moderation.mute.text ? [new MessageButton()
- .setStyle("LINK")
- .setLabel(config.moderation.mute.text)
- .setURL(config.moderation.mute.link)
- ] : [])]
+ components: [
+ new MessageActionRow().addComponents(
+ config.moderation.mute.text
+ ? [
+ new MessageButton()
+ .setStyle("LINK")
+ .setLabel(config.moderation.mute.text)
+ .setURL(config.moderation.mute.link)
+ ]
+ : []
+ )
+ ]
});
dmd = true;
}
- } catch { dmd = false; }
+ } catch {
+ dmd = false;
+ }
const member = user;
let errors = 0;
try {
if (config.moderation.mute.timeout) {
- await member.timeout(muteTime * 1000, reason || "No reason provided");
+ await member.timeout(
+ muteTime * 1000,
+ reason || "No reason provided"
+ );
if (config.moderation.mute.role !== null) {
await member.roles.add(config.moderation.mute.role);
- await client.database.eventScheduler.schedule("naturalUnmute", new Date().getTime() + muteTime * 1000, {
- guild: interaction.guild.id,
- user: user.id,
- expires: new Date().getTime() + muteTime * 1000
- });
+ await client.database.eventScheduler.schedule(
+ "naturalUnmute",
+ new Date().getTime() + muteTime * 1000,
+ {
+ guild: interaction.guild.id,
+ user: user.id,
+ expires: new Date().getTime() + muteTime * 1000
+ }
+ );
}
}
- } catch { errors++; }
+ } catch {
+ errors++;
+ }
try {
if (config.moderation.mute.role !== null) {
await member.roles.add(config.moderation.mute.role);
- await client.database.eventScheduler.schedule("unmuteRole", new Date().getTime() + muteTime * 1000, {
- guild: interaction.guild.id,
- user: user.id,
- role: config.moderation.mute.role
- });
+ await client.database.eventScheduler.schedule(
+ "unmuteRole",
+ new Date().getTime() + muteTime * 1000,
+ {
+ guild: interaction.guild.id,
+ user: user.id,
+ role: config.moderation.mute.role
+ }
+ );
}
- } catch (e){ console.log(e); errors++; }
+ } catch (e) {
+ console.log(e);
+ errors++;
+ }
if (errors === 2) {
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("PUNISH.MUTE.RED")
- .setTitle("Mute")
- .setDescription("Something went wrong and the user was not muted")
- .setStatus("Danger")
- ], components: []}); // TODO: make this clearer
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("PUNISH.MUTE.RED")
+ .setTitle("Mute")
+ .setDescription(
+ "Something went wrong and the user was not muted"
+ )
+ .setStatus("Danger")
+ ],
+ components: []
+ }); // TODO: make this clearer
if (dmd) await dm.delete();
return;
}
- await client.database.history.create("mute", interaction.guild.id, member.user, interaction.user, reason);
- const failed = (dmd === false && notify);
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji(`PUNISH.MUTE.${failed ? "YELLOW" : "GREEN"}`)
- .setTitle("Mute")
- .setDescription("The member was muted" + (failed ? ", but could not be notified" : "") + (confirmation.components.appeal.response ? ` and an appeal ticket was opened in <#${confirmation.components.appeal.response}>` : ""))
- .setStatus(failed ? "Warning" : "Success")
- ], components: []});
+ await client.database.history.create(
+ "mute",
+ interaction.guild.id,
+ member.user,
+ interaction.user,
+ reason
+ );
+ const failed = !dmd && notify;
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji(`PUNISH.MUTE.${failed ? "YELLOW" : "GREEN"}`)
+ .setTitle("Mute")
+ .setDescription(
+ "The member was muted" +
+ (failed ? ", but could not be notified" : "") +
+ (confirmation.components.appeal.response
+ ? ` and an appeal ticket was opened in <#${confirmation.components.appeal.response}>`
+ : "")
+ )
+ .setStatus(failed ? "Warning" : "Success")
+ ],
+ components: []
+ });
const data = {
- meta:{
+ meta: {
type: "memberMute",
displayName: "Member Muted",
calculateType: "guildMemberPunish",
@@ -223,9 +422,18 @@
list: {
memberId: entry(member.user.id, `\`${member.user.id}\``),
name: entry(member.user.id, renderUser(member.user)),
- mutedUntil: entry(new Date().getTime() + muteTime * 1000, renderDelta(new Date().getTime() + muteTime * 1000)),
- muted: entry(new Date().getTime(), renderDelta(new Date().getTime() - 1000)),
- mutedBy: entry(interaction.member.user.id, renderUser(interaction.member.user)),
+ mutedUntil: entry(
+ new Date().getTime() + muteTime * 1000,
+ renderDelta(new Date().getTime() + muteTime * 1000)
+ ),
+ muted: entry(
+ new Date().getTime(),
+ renderDelta(new Date().getTime() - 1000)
+ ),
+ mutedBy: entry(
+ interaction.member.user.id,
+ renderUser(interaction.member.user)
+ ),
reason: entry(reason, reason ? reason : "*No reason provided*")
},
hidden: {
@@ -234,39 +442,49 @@
};
log(data);
} else {
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("PUNISH.MUTE.GREEN")
- .setTitle("Mute")
- .setDescription("No changes were made")
- .setStatus("Success")
- ], components: []});
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("PUNISH.MUTE.GREEN")
+ .setTitle("Mute")
+ .setDescription("No changes were made")
+ .setStatus("Success")
+ ],
+ components: []
+ });
}
};
const check = (interaction: CommandInteraction) => {
- const member = (interaction.member as GuildMember);
- const me = (interaction.guild.me as GuildMember);
- const apply = (interaction.options.getMember("user") as GuildMember);
- if (member === null || me === null || apply === null) throw "That member is not in the server";
+ const member = interaction.member as GuildMember;
+ const me = interaction.guild.me!;
+ const apply = interaction.options.getMember("user") as GuildMember;
+ if (member === null || me === null || apply === null)
+ throw "That member is not in the server";
const memberPos = member.roles ? member.roles.highest.position : 0;
const mePos = me.roles ? me.roles.highest.position : 0;
const applyPos = apply.roles ? apply.roles.highest.position : 0;
// Do not allow muting the owner
- if (member.id === interaction.guild.ownerId) throw "You cannot mute the owner of the server";
+ if (member.id === interaction.guild.ownerId)
+ throw "You cannot mute the owner of the server";
// Check if Nucleus can mute the member
- if (! (mePos > applyPos)) throw "I do not have a role higher than that member";
+ if (!(mePos > applyPos))
+ throw "I do not have a role higher than that member";
// Check if Nucleus has permission to mute
- if (! me.permissions.has("MODERATE_MEMBERS")) throw "I do not have the *Moderate Members* permission";
+ if (!me.permissions.has("MODERATE_MEMBERS"))
+ throw "I do not have the *Moderate Members* permission";
// Do not allow muting Nucleus
if (member.id === me.id) throw "I cannot mute myself";
// Allow the owner to mute anyone
if (member.id === interaction.guild.ownerId) return true;
// Check if the user has moderate_members permission
- if (! member.permissions.has("MODERATE_MEMBERS")) throw "You do not have the *Moderate Members* permission";
+ if (!member.permissions.has("MODERATE_MEMBERS"))
+ throw "You do not have the *Moderate Members* permission";
// Check if the user is below on the role list
- if (! (memberPos > applyPos)) throw "You do not have a role higher than that member";
+ if (!(memberPos > applyPos))
+ throw "You do not have a role higher than that member";
// Allow mute
return true;
};
-export { command, callback, check };
\ No newline at end of file
+export { command, callback, check };
diff --git a/src/commands/mod/nick.ts b/src/commands/mod/nick.ts
index 06fab47..c3d6b33 100644
--- a/src/commands/mod/nick.ts
+++ b/src/commands/mod/nick.ts
@@ -9,10 +9,22 @@
builder
.setName("nick")
.setDescription("Changes a users nickname")
- .addUserOption(option => option.setName("user").setDescription("The user to change").setRequired(true))
- .addStringOption(option => option.setName("name").setDescription("The name to set | Leave blank to clear").setRequired(false));
+ .addUserOption((option) =>
+ option
+ .setName("user")
+ .setDescription("The user to change")
+ .setRequired(true)
+ )
+ .addStringOption((option) =>
+ option
+ .setName("name")
+ .setDescription("The name to set | Leave blank to clear")
+ .setRequired(false)
+ );
-const callback = async (interaction: CommandInteraction): Promise<void | unknown> => {
+const callback = async (
+ interaction: CommandInteraction
+): Promise<void | unknown> => {
const { renderUser } = client.logger;
// TODO:[Modals] Replace this with a modal
let notify = true;
@@ -21,14 +33,35 @@
confirmation = await new confirmationMessage(interaction)
.setEmoji("PUNISH.NICKNAME.RED")
.setTitle("Nickname")
- .setDescription(keyValueList({
- "user": renderUser(interaction.options.getUser("user")),
- "new nickname": `${interaction.options.getString("name") ? interaction.options.getString("name") : "*No nickname*"}`
- })
- + `The user **will${notify ? "" : " not"}** be notified\n\n`
- + `Are you sure you want to ${interaction.options.getString("name") ? "change" : "clear"} <@!${(interaction.options.getMember("user") as GuildMember).id}>'s nickname?`)
+ .setDescription(
+ keyValueList({
+ user: renderUser(interaction.options.getUser("user")),
+ "new nickname": `${
+ interaction.options.getString("name")
+ ? interaction.options.getString("name")
+ : "*No nickname*"
+ }`
+ }) +
+ `The user **will${notify ? "" : " not"}** be notified\n\n` +
+ `Are you sure you want to ${
+ interaction.options.getString("name")
+ ? "change"
+ : "clear"
+ } <@!${
+ (interaction.options.getMember("user") as GuildMember)
+ .id
+ }>'s nickname?`
+ )
.setColor("Danger")
- .addCustomBoolean("notify", "Notify user", false, null, null, "ICONS.NOTIFY." + (notify ? "ON" : "OFF" ), notify)
+ .addCustomBoolean(
+ "notify",
+ "Notify user",
+ false,
+ null,
+ null,
+ "ICONS.NOTIFY." + (notify ? "ON" : "OFF"),
+ notify
+ )
.send(interaction.options.getString("name") !== null);
if (confirmation.cancelled) return;
if (confirmation.success) break;
@@ -41,28 +74,53 @@
let dm;
try {
if (notify) {
- dm = await (interaction.options.getMember("user") as GuildMember).send({
- embeds: [new EmojiEmbed()
- .setEmoji("PUNISH.NICKNAME.RED")
- .setTitle("Nickname changed")
- .setDescription(`Your nickname was ${interaction.options.getString("name") ? "changed" : "cleared"} in ${interaction.guild.name}.` +
- (interaction.options.getString("name") ? ` it is now: ${interaction.options.getString("name")}` : "") + "\n\n" +
- (confirmation.components.appeal.response ? `You can appeal this here: <#${confirmation.components.appeal.response}>` : ""))
- .setStatus("Danger")
+ dm = await (
+ interaction.options.getMember("user") as GuildMember
+ ).send({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("PUNISH.NICKNAME.RED")
+ .setTitle("Nickname changed")
+ .setDescription(
+ `Your nickname was ${
+ interaction.options.getString("name")
+ ? "changed"
+ : "cleared"
+ } in ${interaction.guild.name}.` +
+ (interaction.options.getString("name")
+ ? ` it is now: ${interaction.options.getString(
+ "name"
+ )}`
+ : "") +
+ "\n\n" +
+ (confirmation.components.appeal.response
+ ? `You can appeal this here: <#${confirmation.components.appeal.response}>`
+ : "")
+ )
+ .setStatus("Danger")
]
});
dmd = true;
}
- } catch { dmd = false; }
+ } catch {
+ dmd = false;
+ }
try {
- const member = (interaction.options.getMember("user") as GuildMember);
+ const member = interaction.options.getMember("user") as GuildMember;
const before = member.nickname;
const nickname = interaction.options.getString("name");
member.setNickname(nickname ?? null, "Nucleus Nickname command");
await client.database.history.create(
- "nickname", interaction.guild.id, member.user, interaction.user,
- null, before, nickname);
- const { log, NucleusColors, entry, renderUser, renderDelta } = client.logger;
+ "nickname",
+ interaction.guild.id,
+ member.user,
+ interaction.user,
+ null,
+ before,
+ nickname
+ );
+ const { log, NucleusColors, entry, renderUser, renderDelta } =
+ client.logger;
const data = {
meta: {
type: "memberUpdate",
@@ -76,8 +134,14 @@
memberId: entry(member.id, `\`${member.id}\``),
before: entry(before, before ? before : "*None*"),
after: entry(nickname, nickname ? nickname : "*None*"),
- updated: entry(new Date().getTime(), renderDelta(new Date().getTime())),
- updatedBy: entry(interaction.user.id, renderUser(interaction.user))
+ updated: entry(
+ new Date().getTime(),
+ renderDelta(new Date().getTime())
+ ),
+ updatedBy: entry(
+ interaction.user.id,
+ renderUser(interaction.user)
+ )
},
hidden: {
guild: interaction.guild.id
@@ -85,56 +149,82 @@
};
log(data);
} catch {
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("PUNISH.NICKNAME.RED")
- .setTitle("Nickname")
- .setDescription("Something went wrong and the users nickname could not be changed.")
- .setStatus("Danger")
- ], components: []});
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("PUNISH.NICKNAME.RED")
+ .setTitle("Nickname")
+ .setDescription(
+ "Something went wrong and the users nickname could not be changed."
+ )
+ .setStatus("Danger")
+ ],
+ components: []
+ });
if (dmd) await dm.delete();
return;
}
- const failed = (dmd === false && notify);
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji(`PUNISH.NICKNAME.${failed ? "YELLOW" : "GREEN"}`)
- .setTitle("Nickname")
- .setDescription("The members nickname was changed" + (failed ? ", but was not notified" : "") + (confirmation.components.appeal.response ? ` and an appeal ticket was opened in <#${confirmation.components.appeal.response}>` : ""))
- .setStatus(failed ? "Warning" : "Success")
- ], components: []});
+ const failed = !dmd && notify;
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji(`PUNISH.NICKNAME.${failed ? "YELLOW" : "GREEN"}`)
+ .setTitle("Nickname")
+ .setDescription(
+ "The members nickname was changed" +
+ (failed ? ", but was not notified" : "") +
+ (confirmation.components.appeal.response
+ ? ` and an appeal ticket was opened in <#${confirmation.components.appeal.response}>`
+ : "")
+ )
+ .setStatus(failed ? "Warning" : "Success")
+ ],
+ components: []
+ });
} else {
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("PUNISH.NICKNAME.GREEN")
- .setTitle("Nickname")
- .setDescription("No changes were made")
- .setStatus("Success")
- ], components: []});
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("PUNISH.NICKNAME.GREEN")
+ .setTitle("Nickname")
+ .setDescription("No changes were made")
+ .setStatus("Success")
+ ],
+ components: []
+ });
}
};
const check = (interaction: CommandInteraction) => {
- const member = (interaction.member as GuildMember);
- const me = (interaction.guild.me as GuildMember);
- const apply = (interaction.options.getMember("user") as GuildMember);
- if (member === null || me === null || apply === null) throw "That member is not in the server";
+ const member = interaction.member as GuildMember;
+ const me = interaction.guild.me!;
+ const apply = interaction.options.getMember("user") as GuildMember;
+ if (member === null || me === null || apply === null)
+ throw "That member is not in the server";
const memberPos = member.roles ? member.roles.highest.position : 0;
const mePos = me.roles ? me.roles.highest.position : 0;
const applyPos = apply.roles ? apply.roles.highest.position : 0;
// Do not allow any changing of the owner
- if (member.id === interaction.guild.ownerId) throw "You cannot change the owner's nickname";
+ if (member.id === interaction.guild.ownerId)
+ throw "You cannot change the owner's nickname";
// Check if Nucleus can change the nickname
- if (! (mePos > applyPos)) throw "I do not have a role higher than that member";
+ if (!(mePos > applyPos))
+ throw "I do not have a role higher than that member";
// Check if Nucleus has permission to change the nickname
- if (! me.permissions.has("MANAGE_NICKNAMES")) throw "I do not have the *Manage Nicknames* permission";
+ if (!me.permissions.has("MANAGE_NICKNAMES"))
+ throw "I do not have the *Manage Nicknames* permission";
// Allow the owner to change anyone's nickname
if (member.id === interaction.guild.ownerId) return true;
// Check if the user has manage_nicknames permission
- if (! member.permissions.has("MANAGE_NICKNAMES")) throw "You do not have the *Manage Nicknames* permission";
+ if (!member.permissions.has("MANAGE_NICKNAMES"))
+ throw "You do not have the *Manage Nicknames* permission";
// Allow changing your own nickname
if (member === apply) return true;
// Check if the user is below on the role list
- if (! (memberPos > applyPos)) throw "You do not have a role higher than that member";
+ if (!(memberPos > applyPos))
+ throw "You do not have a role higher than that member";
// Allow change
return true;
};
-export { command, callback, check };
\ No newline at end of file
+export { command, callback, check };
diff --git a/src/commands/mod/purge.ts b/src/commands/mod/purge.ts
index c554ee7..b78c423 100644
--- a/src/commands/mod/purge.ts
+++ b/src/commands/mod/purge.ts
@@ -1,4 +1,9 @@
-import Discord, { CommandInteraction, GuildChannel, GuildMember, TextChannel } from "discord.js";
+import Discord, {
+ CommandInteraction,
+ GuildChannel,
+ GuildMember,
+ TextChannel
+} from "discord.js";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import confirmationMessage from "../../utils/confirmationMessage.js";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
@@ -10,19 +15,41 @@
builder
.setName("purge")
.setDescription("Bulk deletes messages in a channel")
- .addIntegerOption(option => option
- .setName("amount")
- .setDescription("The amount of messages to delete")
- .setRequired(false)
- .setMinValue(1)
- .setMaxValue(100))
- .addUserOption(option => option.setName("user").setDescription("The user to purge messages from").setRequired(false))
- .addStringOption(option => option.setName("reason").setDescription("The reason for the purge").setRequired(false));
+ .addIntegerOption((option) =>
+ option
+ .setName("amount")
+ .setDescription("The amount of messages to delete")
+ .setRequired(false)
+ .setMinValue(1)
+ .setMaxValue(100)
+ )
+ .addUserOption((option) =>
+ option
+ .setName("user")
+ .setDescription("The user to purge messages from")
+ .setRequired(false)
+ )
+ .addStringOption((option) =>
+ option
+ .setName("reason")
+ .setDescription("The reason for the purge")
+ .setRequired(false)
+ );
-const callback = async (interaction: CommandInteraction): Promise<void | unknown> => {
- const user = interaction.options.getMember("user") as GuildMember ?? null;
- const channel = (interaction.channel as GuildChannel);
- if (!(["GUILD_TEXT", "GUILD_NEWS", "GUILD_NEWS_THREAD", "GUILD_PUBLIC_THREAD", "GUILD_PRIVATE_THREAD"].includes(channel.type.toString()))) {
+const callback = async (
+ interaction: CommandInteraction
+): Promise<void | unknown> => {
+ const user = (interaction.options.getMember("user") as GuildMember) ?? null;
+ const channel = interaction.channel as GuildChannel;
+ if (
+ ![
+ "GUILD_TEXT",
+ "GUILD_NEWS",
+ "GUILD_NEWS_THREAD",
+ "GUILD_PUBLIC_THREAD",
+ "GUILD_PRIVATE_THREAD"
+ ].includes(channel.type.toString())
+ ) {
return await interaction.reply({
embeds: [
new EmojiEmbed()
@@ -36,7 +63,7 @@
});
}
// TODO:[Modals] Replace this with a modal
- if ( !interaction.options.getInteger("amount") ) {
+ if (!interaction.options.getInteger("amount")) {
await interaction.reply({
embeds: [
new EmojiEmbed()
@@ -51,12 +78,14 @@
});
let deleted = [] as Discord.Message[];
while (true) {
- const m = await interaction.editReply({
+ const m = (await interaction.editReply({
embeds: [
new EmojiEmbed()
.setEmoji("CHANNEL.PURGE.RED")
.setTitle("Purge")
- .setDescription("Select how many messages to delete. You can continue clicking until all messages are cleared.")
+ .setDescription(
+ "Select how many messages to delete. You can continue clicking until all messages are cleared."
+ )
.setStatus("Danger")
],
components: [
@@ -96,40 +125,64 @@
.setEmoji(getEmojiByName("CONTROL.TICK", "id"))
])
]
- }) as Discord.Message;
+ })) as Discord.Message;
let component;
try {
- component = m.awaitMessageComponent({filter: (m) => m.user.id === interaction.user.id, time: 300000});
- } catch (e) { break; }
+ component = m.awaitMessageComponent({
+ filter: (m) => m.user.id === interaction.user.id,
+ time: 300000
+ });
+ } catch (e) {
+ break;
+ }
component.deferUpdate();
if (component.customId === "done") break;
let amount;
- try { amount = parseInt(component.customId); } catch { break; }
+ try {
+ amount = parseInt(component.customId);
+ } catch {
+ break;
+ }
let messages;
- await (interaction.channel as TextChannel).messages.fetch({limit: amount}).then(async (ms) => {
- if (user) {
- ms = ms.filter(m => m.author.id === user.id);
- }
- messages = await (channel as TextChannel).bulkDelete(ms, true);
- });
+ await (interaction.channel as TextChannel).messages
+ .fetch({ limit: amount })
+ .then(async (ms) => {
+ if (user) {
+ ms = ms.filter((m) => m.author.id === user.id);
+ }
+ messages = await (channel as TextChannel).bulkDelete(
+ ms,
+ true
+ );
+ });
if (messages) {
- deleted = deleted.concat(messages.map(m => m));
+ deleted = deleted.concat(messages.map((m) => m));
}
}
- if (deleted.length === 0) return await interaction.editReply({
- embeds: [
- new EmojiEmbed()
- .setEmoji("CHANNEL.PURGE.RED")
- .setTitle("Purge")
- .setDescription("No messages were deleted")
- .setStatus("Danger")
- ],
- components: []
- });
+ if (deleted.length === 0)
+ return await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("CHANNEL.PURGE.RED")
+ .setTitle("Purge")
+ .setDescription("No messages were deleted")
+ .setStatus("Danger")
+ ],
+ components: []
+ });
if (user) {
- await client.database.history.create("purge", interaction.guild.id, user, interaction.options.getString("reason"), null, null, deleted.length);
+ await client.database.history.create(
+ "purge",
+ interaction.guild.id,
+ user,
+ interaction.options.getString("reason"),
+ null,
+ null,
+ deleted.length
+ );
}
- const { log, NucleusColors, entry, renderUser, renderChannel } = client.logger;
+ const { log, NucleusColors, entry, renderUser, renderChannel } =
+ client.logger;
const data = {
meta: {
type: "channelPurge",
@@ -140,9 +193,18 @@
timestamp: new Date().getTime()
},
list: {
- memberId: entry(interaction.user.id, `\`${interaction.user.id}\``),
- purgedBy: entry(interaction.user.id, renderUser(interaction.user)),
- channel: entry(interaction.channel.id, renderChannel(interaction.channel)),
+ memberId: entry(
+ interaction.user.id,
+ `\`${interaction.user.id}\``
+ ),
+ purgedBy: entry(
+ interaction.user.id,
+ renderUser(interaction.user)
+ ),
+ channel: entry(
+ interaction.channel.id,
+ renderChannel(interaction.channel)
+ ),
messagesCleared: entry(deleted.length, deleted.length)
},
hidden: {
@@ -151,10 +213,16 @@
};
log(data);
let out = "";
- deleted.reverse().forEach(message => {
- out += `${message.author.username}#${message.author.discriminator} (${message.author.id}) [${new Date(message.createdTimestamp).toISOString()}]\n`;
+ deleted.reverse().forEach((message) => {
+ out += `${message.author.username}#${
+ message.author.discriminator
+ } (${message.author.id}) [${new Date(
+ message.createdTimestamp
+ ).toISOString()}]\n`;
const lines = message.content.split("\n");
- lines.forEach(line => {out += `> ${line}\n`;});
+ lines.forEach((line) => {
+ out += `> ${line}\n`;
+ });
out += "\n\n";
});
const attachmentObject = {
@@ -162,47 +230,73 @@
name: `purge-${channel.id}-${Date.now()}.txt`,
description: "Purge log"
};
- const m = await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("CHANNEL.PURGE.GREEN")
- .setTitle("Purge")
- .setDescription("Messages cleared")
- .setStatus("Success")
- ], components: [new Discord.MessageActionRow().addComponents([
- new Discord.MessageButton()
- .setCustomId("download")
- .setLabel("Download transcript")
- .setStyle("SUCCESS")
- .setEmoji(getEmojiByName("CONTROL.DOWNLOAD", "id"))
- ])]}) as Discord.Message;
+ const m = (await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("CHANNEL.PURGE.GREEN")
+ .setTitle("Purge")
+ .setDescription("Messages cleared")
+ .setStatus("Success")
+ ],
+ components: [
+ new Discord.MessageActionRow().addComponents([
+ new Discord.MessageButton()
+ .setCustomId("download")
+ .setLabel("Download transcript")
+ .setStyle("SUCCESS")
+ .setEmoji(getEmojiByName("CONTROL.DOWNLOAD", "id"))
+ ])
+ ]
+ })) as Discord.Message;
let component;
try {
- component = await m.awaitMessageComponent({filter: (m) => m.user.id === interaction.user.id, time: 300000});
- } catch { return; }
+ component = await m.awaitMessageComponent({
+ filter: (m) => m.user.id === interaction.user.id,
+ time: 300000
+ });
+ } catch {
+ return;
+ }
if (component && component.customId === "download") {
- interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("CHANNEL.PURGE.GREEN")
- .setTitle("Purge")
- .setDescription("Uploaded")
- .setStatus("Success")
- ], components: [], files: [attachmentObject]});
+ interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("CHANNEL.PURGE.GREEN")
+ .setTitle("Purge")
+ .setDescription("Uploaded")
+ .setStatus("Success")
+ ],
+ components: [],
+ files: [attachmentObject]
+ });
} else {
- interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("CHANNEL.PURGE.GREEN")
- .setTitle("Purge")
- .setDescription("Messages cleared")
- .setStatus("Success")
- ], components: []});
+ interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("CHANNEL.PURGE.GREEN")
+ .setTitle("Purge")
+ .setDescription("Messages cleared")
+ .setStatus("Success")
+ ],
+ components: []
+ });
}
return;
} else {
const confirmation = await new confirmationMessage(interaction)
.setEmoji("CHANNEL.PURGE.RED")
.setTitle("Purge")
- .setDescription(keyValueList({
- "channel": `<#${channel.id}>`,
- "amount": interaction.options.getInteger("amount").toString(),
- "reason": `\n> ${interaction.options.getString("reason") ? interaction.options.getString("reason") : "*No reason provided*"}`
- }))
+ .setDescription(
+ keyValueList({
+ channel: `<#${channel.id}>`,
+ amount: interaction.options.getInteger("amount").toString(),
+ reason: `\n> ${
+ interaction.options.getString("reason")
+ ? interaction.options.getString("reason")
+ : "*No reason provided*"
+ }`
+ })
+ )
.setColor("Danger")
.send();
if (confirmation.cancelled) return;
@@ -210,25 +304,57 @@
let messages;
try {
if (!user) {
- const toDelete = await (interaction.channel as TextChannel).messages.fetch({limit: interaction.options.getInteger("amount")});
- messages = await (channel as TextChannel).bulkDelete(toDelete, true);
+ const toDelete = await (
+ interaction.channel as TextChannel
+ ).messages.fetch({
+ limit: interaction.options.getInteger("amount")
+ });
+ messages = await (channel as TextChannel).bulkDelete(
+ toDelete,
+ true
+ );
} else {
- const toDelete = (await (await (interaction.channel as TextChannel).messages.fetch({limit: 100}))
- .filter(m => m.author.id === user.id)).first(interaction.options.getInteger("amount"));
- messages = await (channel as TextChannel).bulkDelete(toDelete, true);
+ const toDelete = (
+ await (
+ await (
+ interaction.channel as TextChannel
+ ).messages.fetch({
+ limit: 100
+ })
+ ).filter((m) => m.author.id === user.id)
+ ).first(interaction.options.getInteger("amount"));
+ messages = await (channel as TextChannel).bulkDelete(
+ toDelete,
+ true
+ );
}
- } catch(e) {
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("CHANNEL.PURGE.RED")
- .setTitle("Purge")
- .setDescription("Something went wrong and no messages were deleted")
- .setStatus("Danger")
- ], components: []});
+ } catch (e) {
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("CHANNEL.PURGE.RED")
+ .setTitle("Purge")
+ .setDescription(
+ "Something went wrong and no messages were deleted"
+ )
+ .setStatus("Danger")
+ ],
+ components: []
+ });
}
if (user) {
- await client.database.history.create("purge", interaction.guild.id, user, interaction.options.getString("reason"), null, null, messages.size);
+ await client.database.history.create(
+ "purge",
+ interaction.guild.id,
+ user,
+ interaction.options.getString("reason"),
+ null,
+ null,
+ messages.size
+ );
}
- const { log, NucleusColors, entry, renderUser, renderChannel } = client.logger;
+ const { log, NucleusColors, entry, renderUser, renderChannel } =
+ client.logger;
const data = {
meta: {
type: "channelPurge",
@@ -239,9 +365,18 @@
timestamp: new Date().getTime()
},
list: {
- memberId: entry(interaction.user.id, `\`${interaction.user.id}\``),
- purgedBy: entry(interaction.user.id, renderUser(interaction.user)),
- channel: entry(interaction.channel.id, renderChannel(interaction.channel)),
+ memberId: entry(
+ interaction.user.id,
+ `\`${interaction.user.id}\``
+ ),
+ purgedBy: entry(
+ interaction.user.id,
+ renderUser(interaction.user)
+ ),
+ channel: entry(
+ interaction.channel.id,
+ renderChannel(interaction.channel)
+ ),
messagesCleared: entry(messages.size, messages.size)
},
hidden: {
@@ -250,10 +385,16 @@
};
log(data);
let out = "";
- messages.reverse().forEach(message => {
- out += `${message.author.username}#${message.author.discriminator} (${message.author.id}) [${new Date(message.createdTimestamp).toISOString()}]\n`;
+ messages.reverse().forEach((message) => {
+ out += `${message.author.username}#${
+ message.author.discriminator
+ } (${message.author.id}) [${new Date(
+ message.createdTimestamp
+ ).toISOString()}]\n`;
const lines = message.content.split("\n");
- lines.forEach(line => {out += `> ${line}\n`;});
+ lines.forEach((line) => {
+ out += `> ${line}\n`;
+ });
out += "\n\n";
});
const attachmentObject = {
@@ -261,59 +402,85 @@
name: `purge-${channel.id}-${Date.now()}.txt`,
description: "Purge log"
};
- const m = await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("CHANNEL.PURGE.GREEN")
- .setTitle("Purge")
- .setDescription("Messages cleared")
- .setStatus("Success")
- ], components: [new Discord.MessageActionRow().addComponents([
- new Discord.MessageButton()
- .setCustomId("download")
- .setLabel("Download transcript")
- .setStyle("SUCCESS")
- .setEmoji(getEmojiByName("CONTROL.DOWNLOAD", "id"))
- ])]}) as Discord.Message;
+ const m = (await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("CHANNEL.PURGE.GREEN")
+ .setTitle("Purge")
+ .setDescription("Messages cleared")
+ .setStatus("Success")
+ ],
+ components: [
+ new Discord.MessageActionRow().addComponents([
+ new Discord.MessageButton()
+ .setCustomId("download")
+ .setLabel("Download transcript")
+ .setStyle("SUCCESS")
+ .setEmoji(getEmojiByName("CONTROL.DOWNLOAD", "id"))
+ ])
+ ]
+ })) as Discord.Message;
let component;
try {
- component = await m.awaitMessageComponent({filter: (m) => m.user.id === interaction.user.id, time: 300000});
- } catch { return; }
+ component = await m.awaitMessageComponent({
+ filter: (m) => m.user.id === interaction.user.id,
+ time: 300000
+ });
+ } catch {
+ return;
+ }
if (component && component.customId === "download") {
- interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("CHANNEL.PURGE.GREEN")
- .setTitle("Purge")
- .setDescription("Transcript uploaded above")
- .setStatus("Success")
- ], components: [], files: [attachmentObject]});
+ interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("CHANNEL.PURGE.GREEN")
+ .setTitle("Purge")
+ .setDescription("Transcript uploaded above")
+ .setStatus("Success")
+ ],
+ components: [],
+ files: [attachmentObject]
+ });
} else {
- interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("CHANNEL.PURGE.GREEN")
- .setTitle("Purge")
- .setDescription("Messages cleared")
- .setStatus("Success")
- ], components: []});
+ interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("CHANNEL.PURGE.GREEN")
+ .setTitle("Purge")
+ .setDescription("Messages cleared")
+ .setStatus("Success")
+ ],
+ components: []
+ });
}
} else {
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("CHANNEL.PURGE.GREEN")
- .setTitle("Purge")
- .setDescription("No changes were made")
- .setStatus("Success")
- ], components: []});
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("CHANNEL.PURGE.GREEN")
+ .setTitle("Purge")
+ .setDescription("No changes were made")
+ .setStatus("Success")
+ ],
+ components: []
+ });
}
}
};
const check = (interaction: CommandInteraction) => {
- const member = (interaction.member as GuildMember);
- const me = (interaction.guild.me as GuildMember);
+ const member = interaction.member as GuildMember;
+ const me = interaction.guild.me!;
// Check if nucleus has the manage_messages permission
- if (! me.permissions.has("MANAGE_MESSAGES")) throw "I do not have the *Manage Messages* permission";
+ if (!me.permissions.has("MANAGE_MESSAGES"))
+ throw "I do not have the *Manage Messages* permission";
// Allow the owner to purge
if (member.id === interaction.guild.ownerId) return true;
// Check if the user has manage_messages permission
- if (! member.permissions.has("MANAGE_MESSAGES")) throw "You do not have the *Manage Messages* permission";
+ if (!member.permissions.has("MANAGE_MESSAGES"))
+ throw "You do not have the *Manage Messages* permission";
// Allow purge
return true;
};
-export { command, callback, check };
\ No newline at end of file
+export { command, callback, check };
diff --git a/src/commands/mod/slowmode.ts b/src/commands/mod/slowmode.ts
index 7e8b8a2..1a06db1 100644
--- a/src/commands/mod/slowmode.ts
+++ b/src/commands/mod/slowmode.ts
@@ -5,29 +5,51 @@
import confirmationMessage from "../../utils/confirmationMessage.js";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
-
const command = (builder: SlashCommandSubcommandBuilder) =>
builder
.setName("slowmode")
.setDescription("Manages slowmode in a channel")
- .addStringOption(option => option.setName("time").setDescription("The delay between messages").setRequired(false).addChoices([
- ["Off", "0"],
- ["5 seconds", "5"], ["10 seconds", "10"], ["15 seconds", "15"], ["30 seconds", "30"],
- ["1 minute", "60"], ["2 minutes", "120"], ["5 minutes", "300"], ["10 minutes", "600"],
- ["15 minutes", "900"], ["30 minutes", "1800"],
- ["1 hour", "3600"], ["2 hours", "7200"], ["6 hours", "21600"]
- ]));
+ .addStringOption((option) =>
+ option
+ .setName("time")
+ .setDescription("The delay between messages")
+ .setRequired(false)
+ .addChoices([
+ ["Off", "0"],
+ ["5 seconds", "5"],
+ ["10 seconds", "10"],
+ ["15 seconds", "15"],
+ ["30 seconds", "30"],
+ ["1 minute", "60"],
+ ["2 minutes", "120"],
+ ["5 minutes", "300"],
+ ["10 minutes", "600"],
+ ["15 minutes", "900"],
+ ["30 minutes", "1800"],
+ ["1 hour", "3600"],
+ ["2 hours", "7200"],
+ ["6 hours", "21600"]
+ ])
+ );
const callback = async (interaction: CommandInteraction): Promise<void> => {
let time = parseInt(interaction.options.getString("time") ?? "0");
- if (time === 0 && (interaction.channel as TextChannel).rateLimitPerUser === 0) { time = 10; }
+ if (
+ time === 0 &&
+ (interaction.channel as TextChannel).rateLimitPerUser === 0
+ ) {
+ time = 10;
+ }
const confirmation = await new confirmationMessage(interaction)
.setEmoji("CHANNEL.SLOWMODE.OFF")
.setTitle("Slowmode")
- .setDescription(keyValueList({
- "time": time ? humanizeDuration(time * 1000, { round: true }) : "No delay"
- })
- + "Are you sure you want to set the slowmode in this channel?")
+ .setDescription(
+ keyValueList({
+ time: time
+ ? humanizeDuration(time * 1000, { round: true })
+ : "No delay"
+ }) + "Are you sure you want to set the slowmode in this channel?"
+ )
.setColor("Danger")
.send();
if (confirmation.cancelled) return;
@@ -35,37 +57,53 @@
try {
(interaction.channel as TextChannel).setRateLimitPerUser(time);
} catch (e) {
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("CHANNEL.SLOWMODE.OFF")
- .setTitle("Slowmode")
- .setDescription("Something went wrong while setting the slowmode")
- .setStatus("Danger")
- ], components: []});
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("CHANNEL.SLOWMODE.OFF")
+ .setTitle("Slowmode")
+ .setDescription(
+ "Something went wrong while setting the slowmode"
+ )
+ .setStatus("Danger")
+ ],
+ components: []
+ });
}
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("CHANNEL.SLOWMODE.ON")
- .setTitle("Slowmode")
- .setDescription("The channel slowmode was set successfully")
- .setStatus("Success")
- ], components: []});
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("CHANNEL.SLOWMODE.ON")
+ .setTitle("Slowmode")
+ .setDescription("The channel slowmode was set successfully")
+ .setStatus("Success")
+ ],
+ components: []
+ });
} else {
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("CHANNEL.SLOWMODE.ON")
- .setTitle("Slowmode")
- .setDescription("No changes were made")
- .setStatus("Success")
- ], components: []});
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("CHANNEL.SLOWMODE.ON")
+ .setTitle("Slowmode")
+ .setDescription("No changes were made")
+ .setStatus("Success")
+ ],
+ components: []
+ });
}
};
const check = (interaction: CommandInteraction) => {
- const member = (interaction.member as GuildMember);
+ const member = interaction.member as GuildMember;
// Check if Nucleus can set the slowmode
- if (! interaction.guild.me.permissions.has("MANAGE_CHANNELS")) throw "I do not have the *Manage Channels* permission";
+ if (!interaction.guild.me.permissions.has("MANAGE_CHANNELS"))
+ throw "I do not have the *Manage Channels* permission";
// Check if the user has manage_channel permission
- if (! member.permissions.has("MANAGE_CHANNELS")) throw "You do not have the *Manage Channels* permission";
+ if (!member.permissions.has("MANAGE_CHANNELS"))
+ throw "You do not have the *Manage Channels* permission";
// Allow slowmode
return true;
};
-export { command, callback, check };
\ No newline at end of file
+export { command, callback, check };
diff --git a/src/commands/mod/softban.ts b/src/commands/mod/softban.ts
index d0dc9bb..f3c475e 100644
--- a/src/commands/mod/softban.ts
+++ b/src/commands/mod/softban.ts
@@ -1,4 +1,9 @@
-import { CommandInteraction, GuildMember, MessageActionRow, MessageButton } from "discord.js";
+import {
+ CommandInteraction,
+ GuildMember,
+ MessageActionRow,
+ MessageButton
+} from "discord.js";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import confirmationMessage from "../../utils/confirmationMessage.js";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
@@ -10,10 +15,24 @@
builder
.setName("softban")
.setDescription("Kicks a user and deletes their messages")
- .addUserOption(option => option.setName("user").setDescription("The user to softban").setRequired(true))
- .addIntegerOption(option => option.setName("delete").setDescription("The days of messages to delete | Default: 0").setMinValue(0).setMaxValue(7).setRequired(false));
+ .addUserOption((option) =>
+ option
+ .setName("user")
+ .setDescription("The user to softban")
+ .setRequired(true)
+ )
+ .addIntegerOption((option) =>
+ option
+ .setName("delete")
+ .setDescription("The days of messages to delete | Default: 0")
+ .setMinValue(0)
+ .setMaxValue(7)
+ .setRequired(false)
+ );
-const callback = async (interaction: CommandInteraction): Promise<void | unknown> => {
+const callback = async (
+ interaction: CommandInteraction
+): Promise<void | unknown> => {
const { renderUser } = client.logger;
// TODO:[Modals] Replace this with a modal
let reason = null;
@@ -23,15 +42,35 @@
const confirmation = await new confirmationMessage(interaction)
.setEmoji("PUNISH.BAN.RED")
.setTitle("Softban")
- .setDescription(keyValueList({
- "user": renderUser(interaction.options.getUser("user")),
- "reason": reason ? ("\n> " + ((reason ?? "").replaceAll("\n", "\n> "))) : "*No reason provided*"
- })
- + `The user **will${notify ? "" : " not"}** be notified\n`
- + `${addPlural(interaction.options.getInteger("delete") ? interaction.options.getInteger("delete") : 0, "day")} of messages will be deleted\n\n`
- + `Are you sure you want to softban <@!${(interaction.options.getMember("user") as GuildMember).id}>?`)
+ .setDescription(
+ keyValueList({
+ user: renderUser(interaction.options.getUser("user")),
+ reason: reason
+ ? "\n> " + (reason ?? "").replaceAll("\n", "\n> ")
+ : "*No reason provided*"
+ }) +
+ `The user **will${notify ? "" : " not"}** be notified\n` +
+ `${addPlural(
+ interaction.options.getInteger("delete")
+ ? interaction.options.getInteger("delete")
+ : 0,
+ "day"
+ )} of messages will be deleted\n\n` +
+ `Are you sure you want to softban <@!${
+ (interaction.options.getMember("user") as GuildMember)
+ .id
+ }>?`
+ )
.setColor("Danger")
- .addCustomBoolean("notify", "Notify user", false, null, null, "ICONS.NOTIFY." + (notify ? "ON" : "OFF" ), notify)
+ .addCustomBoolean(
+ "notify",
+ "Notify user",
+ false,
+ null,
+ null,
+ "ICONS.NOTIFY." + (notify ? "ON" : "OFF"),
+ notify
+ )
.addReasonButton(reason ?? "")
.send(reason !== null);
reason = reason ?? "";
@@ -47,24 +86,38 @@
const config = await client.database.guilds.read(interaction.guild.id);
try {
if (notify) {
- await (interaction.options.getMember("user") as GuildMember).send({
- embeds: [new EmojiEmbed()
- .setEmoji("PUNISH.BAN.RED")
- .setTitle("Softbanned")
- .setDescription(`You have been softbanned from ${interaction.guild.name}` +
- (reason ? ` for:\n> ${reason}` : "."))
- .setStatus("Danger")
+ await (
+ interaction.options.getMember("user") as GuildMember
+ ).send({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("PUNISH.BAN.RED")
+ .setTitle("Softbanned")
+ .setDescription(
+ `You have been softbanned from ${interaction.guild.name}` +
+ (reason ? ` for:\n> ${reason}` : ".")
+ )
+ .setStatus("Danger")
],
- components: [new MessageActionRow().addComponents(config.moderation.ban.text ? [new MessageButton()
- .setStyle("LINK")
- .setLabel(config.moderation.ban.text)
- .setURL(config.moderation.ban.link)
- ] : [])]
+ components: [
+ new MessageActionRow().addComponents(
+ config.moderation.ban.text
+ ? [
+ new MessageButton()
+ .setStyle("LINK")
+ .setLabel(config.moderation.ban.text)
+ .setURL(config.moderation.ban.link)
+ ]
+ : []
+ )
+ ]
});
dmd = true;
}
- } catch { dmd = false;}
- const member = (interaction.options.getMember("user") as GuildMember);
+ } catch {
+ dmd = false;
+ }
+ const member = interaction.options.getMember("user") as GuildMember;
try {
await member.ban({
days: Number(interaction.options.getInteger("delete") ?? 0),
@@ -72,55 +125,83 @@
});
await interaction.guild.members.unban(member, "Softban");
} catch {
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("PUNISH.BAN.RED")
- .setTitle("Softban")
- .setDescription("Something went wrong and the user was not softbanned")
- .setStatus("Danger")
- ], components: []});
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("PUNISH.BAN.RED")
+ .setTitle("Softban")
+ .setDescription(
+ "Something went wrong and the user was not softbanned"
+ )
+ .setStatus("Danger")
+ ],
+ components: []
+ });
}
- await client.database.history.create("softban", interaction.guild.id, member.user, reason);
- const failed = (dmd === false && notify);
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji(`PUNISH.BAN.${failed ? "YELLOW" : "GREEN"}`)
- .setTitle("Softban")
- .setDescription("The member was softbanned" + (failed ? ", but could not be notified" : ""))
- .setStatus(failed ? "Warning" : "Success")
- ], components: []});
+ await client.database.history.create(
+ "softban",
+ interaction.guild.id,
+ member.user,
+ reason
+ );
+ const failed = !dmd && notify;
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji(`PUNISH.BAN.${failed ? "YELLOW" : "GREEN"}`)
+ .setTitle("Softban")
+ .setDescription(
+ "The member was softbanned" +
+ (failed ? ", but could not be notified" : "")
+ )
+ .setStatus(failed ? "Warning" : "Success")
+ ],
+ components: []
+ });
} else {
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("PUNISH.BAN.GREEN")
- .setTitle("Softban")
- .setDescription("No changes were made")
- .setStatus("Success")
- ], components: []});
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("PUNISH.BAN.GREEN")
+ .setTitle("Softban")
+ .setDescription("No changes were made")
+ .setStatus("Success")
+ ],
+ components: []
+ });
}
};
const check = (interaction: CommandInteraction) => {
- const member = (interaction.member as GuildMember);
- const me = (interaction.guild.me as GuildMember);
- const apply = (interaction.options.getMember("user") as GuildMember);
- if (member === null || me === null || apply === null) throw "That member is not in the server";
+ const member = interaction.member as GuildMember;
+ const me = interaction.guild.me!;
+ const apply = interaction.options.getMember("user") as GuildMember;
+ if (member === null || me === null || apply === null)
+ throw "That member is not in the server";
const memberPos = member.roles ? member.roles.highest.position : 0;
const mePos = me.roles ? me.roles.highest.position : 0;
const applyPos = apply.roles ? apply.roles.highest.position : 0;
// Do not allow softbanning the owner
- if (member.id === interaction.guild.ownerId) throw "You cannot softban the owner of the server";
+ if (member.id === interaction.guild.ownerId)
+ throw "You cannot softban the owner of the server";
// Check if Nucleus can ban the member
- if (! (mePos > applyPos)) throw "I do not have a role higher than that member";
+ if (!(mePos > applyPos))
+ throw "I do not have a role higher than that member";
// Check if Nucleus has permission to ban
- if (!me.permissions.has("BAN_MEMBERS")) throw "I do not have the *Ban Members* permission";
+ if (!me.permissions.has("BAN_MEMBERS"))
+ throw "I do not have the *Ban Members* permission";
// Do not allow softbanning Nucleus
if (member.id === me.id) throw "I cannot softban myself";
// Allow the owner to softban anyone
if (member.id === interaction.guild.ownerId) return true;
// Check if the user has ban_members permission
- if (! member.permissions.has("BAN_MEMBERS")) throw "You do not have the *Ban Members* permission";
+ if (!member.permissions.has("BAN_MEMBERS"))
+ throw "You do not have the *Ban Members* permission";
// Check if the user is below on the role list
- if (! (memberPos > applyPos)) throw "You do not have a role higher than that member";
+ if (!(memberPos > applyPos))
+ throw "You do not have a role higher than that member";
// Allow softban
return true;
};
-export { command, callback, check };
\ No newline at end of file
+export { command, callback, check };
diff --git a/src/commands/mod/unban.ts b/src/commands/mod/unban.ts
index 88301eb..06fe647 100644
--- a/src/commands/mod/unban.ts
+++ b/src/commands/mod/unban.ts
@@ -9,39 +9,68 @@
builder
.setName("unban")
.setDescription("Unbans a user")
- .addStringOption(option => option.setName("user").setDescription("The user to unban (Username or ID)").setRequired(true));
+ .addStringOption((option) =>
+ option
+ .setName("user")
+ .setDescription("The user to unban (Username or ID)")
+ .setRequired(true)
+ );
-const callback = async (interaction: CommandInteraction): Promise<void | unknown> => {
+const callback = async (
+ interaction: CommandInteraction
+): Promise<void | unknown> => {
const bans = await interaction.guild.bans.fetch();
const user = interaction.options.getString("user");
- let resolved = bans.find(ban => ban.user.id === user);
- if (!resolved) resolved = bans.find(ban => ban.user.username.toLowerCase() === user.toLowerCase());
- if (!resolved) resolved = bans.find(ban => ban.user.tag.toLowerCase() === user.toLowerCase());
+ let resolved = bans.find((ban) => ban.user.id === user);
+ if (!resolved)
+ resolved = bans.find(
+ (ban) => ban.user.username.toLowerCase() === user.toLowerCase()
+ );
+ if (!resolved)
+ resolved = bans.find(
+ (ban) => ban.user.tag.toLowerCase() === user.toLowerCase()
+ );
if (!resolved) {
- return interaction.reply({embeds: [new EmojiEmbed()
- .setTitle("Unban")
- .setDescription(`Could not find any user called \`${user}\``)
- .setEmoji("PUNISH.UNBAN.RED")
- .setStatus("Danger")
- ], ephemeral: true});
+ return interaction.reply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Unban")
+ .setDescription(
+ `Could not find any user called \`${user}\``
+ )
+ .setEmoji("PUNISH.UNBAN.RED")
+ .setStatus("Danger")
+ ],
+ ephemeral: true
+ });
}
// TODO:[Modals] Replace this with a modal
const confirmation = await new confirmationMessage(interaction)
.setEmoji("PUNISH.UNBAN.RED")
.setTitle("Unban")
- .setDescription(keyValueList({
- "user": `${resolved.user.username} [<@${resolved.user.id}>]`
- })
- + `Are you sure you want to unban <@${resolved.user.id}>?`)
+ .setDescription(
+ keyValueList({
+ user: `${resolved.user.username} [<@${resolved.user.id}>]`
+ }) + `Are you sure you want to unban <@${resolved.user.id}>?`
+ )
.setColor("Danger")
.send();
if (confirmation.cancelled) return;
if (confirmation.success) {
try {
- await interaction.guild.members.unban(resolved.user as User, "Unban");
- const member = (resolved.user as User);
- await client.database.history.create("unban", interaction.guild.id, member, interaction.user);
- const { log, NucleusColors, entry, renderUser, renderDelta } = client.logger;
+ await interaction.guild.members.unban(
+ resolved.user as User,
+ "Unban"
+ );
+ const member = resolved.user as User;
+ await client.database.history.create(
+ "unban",
+ interaction.guild.id,
+ member,
+ interaction.user
+ );
+ const { log, NucleusColors, entry, renderUser, renderDelta } =
+ client.logger;
const data = {
meta: {
type: "memberUnban",
@@ -54,9 +83,18 @@
list: {
memberId: entry(member.id, `\`${member.id}\``),
name: entry(member.id, renderUser(member)),
- unbanned: entry(new Date().getTime(), renderDelta(new Date().getTime())),
- unbannedBy: entry(interaction.user.id, renderUser(interaction.user)),
- accountCreated: entry(member.createdAt, renderDelta(member.createdAt))
+ unbanned: entry(
+ new Date().getTime(),
+ renderDelta(new Date().getTime())
+ ),
+ unbannedBy: entry(
+ interaction.user.id,
+ renderUser(interaction.user)
+ ),
+ accountCreated: entry(
+ member.createdAt,
+ renderDelta(member.createdAt)
+ )
},
hidden: {
guild: interaction.guild.id
@@ -64,40 +102,56 @@
};
log(data);
} catch {
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("PUNISH.UNBAN.RED")
- .setTitle("Unban")
- .setDescription("Something went wrong and the user was not unbanned")
- .setStatus("Danger")
- ], components: []});
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("PUNISH.UNBAN.RED")
+ .setTitle("Unban")
+ .setDescription(
+ "Something went wrong and the user was not unbanned"
+ )
+ .setStatus("Danger")
+ ],
+ components: []
+ });
}
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("PUNISH.UNBAN.GREEN")
- .setTitle("Unban")
- .setDescription("The member was unbanned")
- .setStatus("Success")
- ], components: []});
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("PUNISH.UNBAN.GREEN")
+ .setTitle("Unban")
+ .setDescription("The member was unbanned")
+ .setStatus("Success")
+ ],
+ components: []
+ });
} else {
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("PUNISH.UNBAN.GREEN")
- .setTitle("Unban")
- .setDescription("No changes were made")
- .setStatus("Success")
- ], components: []});
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("PUNISH.UNBAN.GREEN")
+ .setTitle("Unban")
+ .setDescription("No changes were made")
+ .setStatus("Success")
+ ],
+ components: []
+ });
}
};
const check = (interaction: CommandInteraction) => {
- const member = (interaction.member as GuildMember);
- const me = (interaction.guild.me as GuildMember);
+ const member = interaction.member as GuildMember;
+ const me = interaction.guild.me!;
// Check if Nucleus can unban members
- if (! me.permissions.has("BAN_MEMBERS")) throw "I do not have the *Ban Members* permission";
+ if (!me.permissions.has("BAN_MEMBERS"))
+ throw "I do not have the *Ban Members* permission";
// Allow the owner to unban anyone
if (member.id === interaction.guild.ownerId) return true;
// Check if the user has ban_members permission
- if (! member.permissions.has("BAN_MEMBERS")) throw "You do not have the *Ban Members* permission";
+ if (!member.permissions.has("BAN_MEMBERS"))
+ throw "You do not have the *Ban Members* permission";
// Allow unban
return true;
};
-export { command, callback, check };
\ No newline at end of file
+export { command, callback, check };
diff --git a/src/commands/mod/unmute.ts b/src/commands/mod/unmute.ts
index d4e0d75..f625461 100644
--- a/src/commands/mod/unmute.ts
+++ b/src/commands/mod/unmute.ts
@@ -9,24 +9,37 @@
builder
.setName("unmute")
.setDescription("Unmutes a user")
- .addUserOption(option => option.setName("user").setDescription("The user to unmute").setRequired(true));
+ .addUserOption((option) =>
+ option
+ .setName("user")
+ .setDescription("The user to unmute")
+ .setRequired(true)
+ );
-const callback = async (interaction: CommandInteraction): Promise<void | unknown> => {
- const { log, NucleusColors, renderUser, entry, renderDelta } = client.logger;
+const callback = async (
+ interaction: CommandInteraction
+): Promise<void | unknown> => {
+ const { log, NucleusColors, renderUser, entry, renderDelta } =
+ client.logger;
// TODO:[Modals] Replace this with a modal
let reason = null;
let notify = false;
let confirmation;
while (true) {
- confirmation = await new confirmationMessage(interaction)
+ confirmation = await new confirmationMessage(interaction)
.setEmoji("PUNISH.MUTE.RED")
.setTitle("Unmute")
- .setDescription(keyValueList({
- "user": renderUser(interaction.options.getUser("user")),
- "reason": `\n> ${reason ? reason : "*No reason provided*"}`
- })
- + `The user **will${notify ? "" : " not"}** be notified\n\n`
- + `Are you sure you want to unmute <@!${(interaction.options.getMember("user") as GuildMember).id}>?`)
+ .setDescription(
+ keyValueList({
+ user: renderUser(interaction.options.getUser("user")),
+ reason: `\n> ${reason ? reason : "*No reason provided*"}`
+ }) +
+ `The user **will${notify ? "" : " not"}** be notified\n\n` +
+ `Are you sure you want to unmute <@!${
+ (interaction.options.getMember("user") as GuildMember)
+ .id
+ }>?`
+ )
.setColor("Danger")
.addReasonButton(reason ?? "")
.send(reason !== null);
@@ -42,32 +55,53 @@
let dm;
try {
if (notify) {
- dm = await (interaction.options.getMember("user") as GuildMember).send({
- embeds: [new EmojiEmbed()
- .setEmoji("PUNISH.MUTE.GREEN")
- .setTitle("Unmuted")
- .setDescription(`You have been unmuted in ${interaction.guild.name}` +
- (reason ? ` for:\n> ${reason}` : " with no reason provided."))
- .setStatus("Success")
+ dm = await (
+ interaction.options.getMember("user") as GuildMember
+ ).send({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("PUNISH.MUTE.GREEN")
+ .setTitle("Unmuted")
+ .setDescription(
+ `You have been unmuted in ${interaction.guild.name}` +
+ (reason
+ ? ` for:\n> ${reason}`
+ : " with no reason provided.")
+ )
+ .setStatus("Success")
]
});
dmd = true;
}
- } catch { dmd = false; }
- const member = (interaction.options.getMember("user") as GuildMember);
+ } catch {
+ dmd = false;
+ }
+ const member = interaction.options.getMember("user") as GuildMember;
try {
member.timeout(0, reason || "No reason provided");
} catch {
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("PUNISH.MUTE.RED")
- .setTitle("Unmute")
- .setDescription("Something went wrong and the user was not unmuted")
- .setStatus("Danger")
- ], components: []});
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("PUNISH.MUTE.RED")
+ .setTitle("Unmute")
+ .setDescription(
+ "Something went wrong and the user was not unmuted"
+ )
+ .setStatus("Danger")
+ ],
+ components: []
+ });
if (dmd) await dm.delete();
return;
}
- await client.database.history.create("unmute", interaction.guild.id, (interaction.options.getMember("user") as GuildMember).user, interaction.user, reason);
+ await client.database.history.create(
+ "unmute",
+ interaction.guild.id,
+ (interaction.options.getMember("user") as GuildMember).user,
+ interaction.user,
+ reason
+ );
const data = {
meta: {
type: "memberUnmute",
@@ -80,53 +114,76 @@
list: {
memberId: entry(member.user.id, `\`${member.user.id}\``),
name: entry(member.user.id, renderUser(member.user)),
- unmuted: entry(new Date().getTime(), renderDelta(new Date().getTime())),
- unmutedBy: entry(interaction.user.id, renderUser(interaction.user))
+ unmuted: entry(
+ new Date().getTime(),
+ renderDelta(new Date().getTime())
+ ),
+ unmutedBy: entry(
+ interaction.user.id,
+ renderUser(interaction.user)
+ )
},
hidden: {
guild: interaction.guild.id
}
};
log(data);
- const failed = (dmd === false && notify);
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji(`PUNISH.MUTE.${failed ? "YELLOW" : "GREEN"}`)
- .setTitle("Unmute")
- .setDescription("The member was unmuted" + (failed ? ", but could not be notified" : ""))
- .setStatus(failed ? "Warning" : "Success")
- ], components: []});
+ const failed = !dmd && notify;
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji(`PUNISH.MUTE.${failed ? "YELLOW" : "GREEN"}`)
+ .setTitle("Unmute")
+ .setDescription(
+ "The member was unmuted" +
+ (failed ? ", but could not be notified" : "")
+ )
+ .setStatus(failed ? "Warning" : "Success")
+ ],
+ components: []
+ });
} else {
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("PUNISH.MUTE.GREEN")
- .setTitle("Unmute")
- .setDescription("No changes were made")
- .setStatus("Success")
- ], components: []});
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("PUNISH.MUTE.GREEN")
+ .setTitle("Unmute")
+ .setDescription("No changes were made")
+ .setStatus("Success")
+ ],
+ components: []
+ });
}
};
const check = (interaction: CommandInteraction) => {
- const member = (interaction.member as GuildMember);
- const me = (interaction.guild.me as GuildMember);
- const apply = (interaction.options.getMember("user") as GuildMember);
- if (member === null || me === null || apply === null) throw "That member is not in the server";
+ const member = interaction.member as GuildMember;
+ const me = interaction.guild.me!;
+ const apply = interaction.options.getMember("user") as GuildMember;
+ if (member === null || me === null || apply === null)
+ throw "That member is not in the server";
const memberPos = member.roles ? member.roles.highest.position : 0;
const mePos = me.roles ? me.roles.highest.position : 0;
const applyPos = apply.roles ? apply.roles.highest.position : 0;
// Do not allow unmuting the owner
- if (member.id === interaction.guild.ownerId) throw "You cannot unmute the owner of the server";
+ if (member.id === interaction.guild.ownerId)
+ throw "You cannot unmute the owner of the server";
// Check if Nucleus can unmute the member
- if (! (mePos > applyPos)) throw "I do not have a role higher than that member";
+ if (!(mePos > applyPos))
+ throw "I do not have a role higher than that member";
// Check if Nucleus has permission to unmute
- if (! me.permissions.has("MODERATE_MEMBERS")) throw "I do not have the *Moderate Members* permission";
+ if (!me.permissions.has("MODERATE_MEMBERS"))
+ throw "I do not have the *Moderate Members* permission";
// Allow the owner to unmute anyone
if (member.id === interaction.guild.ownerId) return true;
// Check if the user has moderate_members permission
- if (! member.permissions.has("MODERATE_MEMBERS")) throw "You do not have the *Moderate Members* permission";
+ if (!member.permissions.has("MODERATE_MEMBERS"))
+ throw "You do not have the *Moderate Members* permission";
// Check if the user is below on the role list
- if (! (memberPos > applyPos)) throw "You do not have a role higher than that member";
+ if (!(memberPos > applyPos))
+ throw "You do not have a role higher than that member";
// Allow unmute
return true;
};
-export { command, callback, check };
\ No newline at end of file
+export { command, callback, check };
diff --git a/src/commands/mod/viewas.ts b/src/commands/mod/viewas.ts
index ca52787..f0b2047 100644
--- a/src/commands/mod/viewas.ts
+++ b/src/commands/mod/viewas.ts
@@ -1,4 +1,11 @@
-import Discord, { CategoryChannel, CommandInteraction, GuildMember, MessageActionRow, MessageButton, MessageSelectMenu } from "discord.js";
+import Discord, {
+ CategoryChannel,
+ CommandInteraction,
+ GuildMember,
+ MessageActionRow,
+ MessageButton,
+ MessageSelectMenu
+} from "discord.js";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import getEmojiByName from "../../utils/getEmojiByName.js";
@@ -8,97 +15,189 @@
builder
.setName("viewas")
.setDescription("View the server as a specific member")
- .addUserOption(option => option.setName("member").setDescription("The member to view as").setRequired(true));
+ .addUserOption((option) =>
+ option
+ .setName("member")
+ .setDescription("The member to view as")
+ .setRequired(true)
+ );
const callback = async (interaction: CommandInteraction): Promise<void> => {
let channels = [];
let m;
- interaction.guild.channels.cache.forEach(channel => {
- if (!channel.parent && channel.type !== "GUILD_CATEGORY") channels.push(channel);
+ interaction.guild.channels.cache.forEach((channel) => {
+ if (!channel.parent && channel.type !== "GUILD_CATEGORY")
+ channels.push(channel);
});
channels = [channels];
- channels = channels.concat(interaction.guild.channels.cache
- .filter(c => c.type === "GUILD_CATEGORY")
- .map(c => (c as CategoryChannel).children.map(c => c))
+ channels = channels.concat(
+ interaction.guild.channels.cache
+ .filter((c) => c.type === "GUILD_CATEGORY")
+ .map((c) => (c as CategoryChannel).children.map((c) => c))
);
const autoSortBelow = ["GUILD_VOICE", "GUILD_STAGE_VOICE"];
- channels = channels.map(c => c.sort((a, b) => {
- if (autoSortBelow.includes(a.type) && autoSortBelow.includes(b.type)) return a.position - b.position;
- if (autoSortBelow.includes(a.type)) return 1;
- if (autoSortBelow.includes(b.type)) return -1;
- return a.position - b.position;
- }));
+ channels = channels.map((c) =>
+ c.sort((a, b) => {
+ if (
+ autoSortBelow.includes(a.type) &&
+ autoSortBelow.includes(b.type)
+ )
+ return a.position - b.position;
+ if (autoSortBelow.includes(a.type)) return 1;
+ if (autoSortBelow.includes(b.type)) return -1;
+ return a.position - b.position;
+ })
+ );
// Sort all arrays by the position of the first channels parent position
channels = channels.sort((a, b) => {
if (!a[0].parent) return -1;
if (!b[0].parent) return 1;
return a[0].parent.position - b[0].parent.position;
});
- const member = interaction.options.getMember("member") as Discord.GuildMember;
- m = await interaction.reply({embeds: [new EmojiEmbed()
- .setEmoji("MEMBER.JOIN")
- .setTitle("Viewing as " + member.displayName)
- .setStatus("Success")
- ], ephemeral: true, fetchReply: true});
+ const member = interaction.options.getMember(
+ "member"
+ ) as Discord.GuildMember;
+ m = await interaction.reply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("MEMBER.JOIN")
+ .setTitle("Viewing as " + member.displayName)
+ .setStatus("Success")
+ ],
+ ephemeral: true,
+ fetchReply: true
+ });
let page = 0;
while (true) {
- m = await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("MEMBER.JOIN")
- .setTitle("Viewing as " + member.displayName)
- .setStatus("Success")
- .setDescription(
- `**${channels[page][0].parent ? channels[page][0].parent.name : "Uncategorised"}**` + "\n" +
- channels[page].map(c => {
- let channelType = c.type;
- if (interaction.guild.rulesChannelId === c.id) channelType = "RULES";
- else if ("nsfw" in c && c.nsfw) channelType += "_NSFW";
- return c.permissionsFor(member).has("VIEW_CHANNEL") ? (
- `${getEmojiByName("ICONS.CHANNEL." + channelType)} ${c.name}\n` + (() => {
- if ("threads" in c && c.threads.cache.size > 0) {
- return c.threads.cache.map(t => ` ${
- getEmojiByName("ICONS.CHANNEL.THREAD_PIPE") + " " +
- getEmojiByName("ICONS.CHANNEL.THREAD_CHANNEL")} ${t.name}`).join("\n") + "\n";
- }return "";
- })()) : "";
- }).join("") + "\n" + pageIndicator(channels.length, page)
- )
- ], components: [
- new MessageActionRow().addComponents([new MessageSelectMenu().setOptions(channels.map((c, index) => ({
- label: c[0].parent ? c[0].parent.name : "Uncategorised",
- value: index.toString(),
- default: page === index
- }))).setCustomId("select").setMaxValues(1).setMinValues(1).setPlaceholder("Select a category")]),
- new MessageActionRow().addComponents([
- new MessageButton()
- .setLabel(page === 0 ? "" : (channels[page - 1][0].parent ? channels[page - 1][0].parent.name : "Uncategorised"))
- .setDisabled(page === 0)
- .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
- .setStyle("PRIMARY")
- .setCustomId("previous"),
- new MessageButton()
- .setLabel(page === channels.length - 1 ? "" : (channels[page + 1][0].parent ? channels[page + 1][0].parent.name : "Uncategorised"))
- .setDisabled(page === channels.length - 1)
- .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
- .setStyle("PRIMARY")
- .setCustomId("next")
- ])
- ]});
+ m = await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("MEMBER.JOIN")
+ .setTitle("Viewing as " + member.displayName)
+ .setStatus("Success")
+ .setDescription(
+ `**${
+ channels[page][0].parent
+ ? channels[page][0].parent.name
+ : "Uncategorised"
+ }**` +
+ "\n" +
+ channels[page]
+ .map((c) => {
+ let channelType = c.type;
+ if (
+ interaction.guild.rulesChannelId ===
+ c.id
+ )
+ channelType = "RULES";
+ else if ("nsfw" in c && c.nsfw)
+ channelType += "_NSFW";
+ return c
+ .permissionsFor(member)
+ .has("VIEW_CHANNEL")
+ ? `${getEmojiByName(
+ "ICONS.CHANNEL." + channelType
+ )} ${c.name}\n` +
+ (() => {
+ if (
+ "threads" in c &&
+ c.threads.cache.size > 0
+ ) {
+ return (
+ c.threads.cache
+ .map(
+ (t) =>
+ ` ${
+ getEmojiByName(
+ "ICONS.CHANNEL.THREAD_PIPE"
+ ) +
+ " " +
+ getEmojiByName(
+ "ICONS.CHANNEL.THREAD_CHANNEL"
+ )
+ } ${
+ t.name
+ }`
+ )
+ .join("\n") + "\n"
+ );
+ }
+ return "";
+ })()
+ : "";
+ })
+ .join("") +
+ "\n" +
+ pageIndicator(channels.length, page)
+ )
+ ],
+ components: [
+ new MessageActionRow().addComponents([
+ new MessageSelectMenu()
+ .setOptions(
+ channels.map((c, index) => ({
+ label: c[0].parent
+ ? c[0].parent.name
+ : "Uncategorised",
+ value: index.toString(),
+ default: page === index
+ }))
+ )
+ .setCustomId("select")
+ .setMaxValues(1)
+ .setMinValues(1)
+ .setPlaceholder("Select a category")
+ ]),
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setLabel(
+ page === 0
+ ? ""
+ : channels[page - 1][0].parent
+ ? channels[page - 1][0].parent.name
+ : "Uncategorised"
+ )
+ .setDisabled(page === 0)
+ .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
+ .setStyle("PRIMARY")
+ .setCustomId("previous"),
+ new MessageButton()
+ .setLabel(
+ page === channels.length - 1
+ ? ""
+ : channels[page + 1][0].parent
+ ? channels[page + 1][0].parent.name
+ : "Uncategorised"
+ )
+ .setDisabled(page === channels.length - 1)
+ .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
+ .setStyle("PRIMARY")
+ .setCustomId("next")
+ ])
+ ]
+ });
let i;
try {
i = await m.awaitMessageComponent({ time: 300000 });
- } catch (e) { return; }
+ } catch (e) {
+ return;
+ }
i.deferUpdate();
- if (i.customId === "next") { page++; }
- else if (i.customId === "previous") { page--; }
- else if (i.customId === "select") { page = parseInt(i.values[0]); }
+ if (i.customId === "next") {
+ page++;
+ } else if (i.customId === "previous") {
+ page--;
+ } else if (i.customId === "select") {
+ page = parseInt(i.values[0]);
+ }
}
};
-
const check = (interaction: CommandInteraction) => {
- const member = (interaction.member as GuildMember);
- if (! member.permissions.has("MANAGE_ROLES")) throw "You do not have the *Manage Roles* permission";
+ const member = interaction.member as GuildMember;
+ if (!member.permissions.has("MANAGE_ROLES"))
+ throw "You do not have the *Manage Roles* permission";
return true;
};
-export { command, callback, check };
\ No newline at end of file
+export { command, callback, check };
diff --git a/src/commands/mod/warn.ts b/src/commands/mod/warn.ts
index 34ad3c3..91c876e 100644
--- a/src/commands/mod/warn.ts
+++ b/src/commands/mod/warn.ts
@@ -1,18 +1,33 @@
-import Discord, { CommandInteraction, GuildMember, MessageActionRow, MessageButton } from "discord.js";
+import Discord, {
+ CommandInteraction,
+ GuildMember,
+ MessageActionRow,
+ MessageButton
+} from "discord.js";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import confirmationMessage from "../../utils/confirmationMessage.js";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import keyValueList from "../../utils/generateKeyValueList.js";
-import { create, areTicketsEnabled } from "../../actions/createModActionTicket.js";
+import {
+ create,
+ areTicketsEnabled
+} from "../../actions/createModActionTicket.js";
import client from "../../utils/client.js";
const command = (builder: SlashCommandSubcommandBuilder) =>
builder
.setName("warn")
.setDescription("Warns a user")
- .addUserOption(option => option.setName("user").setDescription("The user to warn").setRequired(true));
+ .addUserOption((option) =>
+ option
+ .setName("user")
+ .setDescription("The user to warn")
+ .setRequired(true)
+ );
-const callback = async (interaction: CommandInteraction): Promise<void | unknown> => {
+const callback = async (
+ interaction: CommandInteraction
+): Promise<void | unknown> => {
const { log, NucleusColors, renderUser, entry } = client.logger;
// TODO:[Modals] Replace this with a modal
let reason = null;
@@ -23,18 +38,44 @@
confirmation = await new confirmationMessage(interaction)
.setEmoji("PUNISH.WARN.RED")
.setTitle("Warn")
- .setDescription(keyValueList({
- "user": renderUser(interaction.options.getUser("user")),
- "reason": reason ? ("\n> " + ((reason ?? "").replaceAll("\n", "\n> "))) : "*No reason provided*"
- })
- + `The user **will${notify ? "" : " not"}** be notified\n\n`
- + `Are you sure you want to warn <@!${(interaction.options.getMember("user") as GuildMember).id}>?`)
+ .setDescription(
+ keyValueList({
+ user: renderUser(interaction.options.getUser("user")),
+ reason: reason
+ ? "\n> " + (reason ?? "").replaceAll("\n", "\n> ")
+ : "*No reason provided*"
+ }) +
+ `The user **will${notify ? "" : " not"}** be notified\n\n` +
+ `Are you sure you want to warn <@!${
+ (interaction.options.getMember("user") as GuildMember)
+ .id
+ }>?`
+ )
.setColor("Danger")
.addCustomBoolean(
- "appeal", "Create appeal ticket", !(await areTicketsEnabled(interaction.guild.id)),
- async () => await create(interaction.guild, interaction.options.getUser("user"), interaction.user, reason),
- "An appeal ticket will be created when Confirm is clicked", "CONTROL.TICKET", createAppealTicket)
- .addCustomBoolean("notify", "Notify user", false, null, null, "ICONS.NOTIFY." + (notify ? "ON" : "OFF" ), notify)
+ "appeal",
+ "Create appeal ticket",
+ !(await areTicketsEnabled(interaction.guild.id)),
+ async () =>
+ await create(
+ interaction.guild,
+ interaction.options.getUser("user"),
+ interaction.user,
+ reason
+ ),
+ "An appeal ticket will be created when Confirm is clicked",
+ "CONTROL.TICKET",
+ createAppealTicket
+ )
+ .addCustomBoolean(
+ "notify",
+ "Notify user",
+ false,
+ null,
+ null,
+ "ICONS.NOTIFY." + (notify ? "ON" : "OFF"),
+ notify
+ )
.addReasonButton(reason ?? "")
.send(reason !== null);
reason = reason ?? "";
@@ -50,31 +91,51 @@
let dmd = false;
try {
if (notify) {
- const config = await client.database.guilds.read(interaction.guild.id);
- await (interaction.options.getMember("user") as GuildMember).send({
- embeds: [new EmojiEmbed()
- .setEmoji("PUNISH.WARN.RED")
- .setTitle("Warned")
- .setDescription(`You have been warned in ${interaction.guild.name}` +
- (reason ? ` for:\n> ${reason}` : ".") + "\n\n" +
- (confirmation.components.appeal.response ? `You can appeal this here ticket: <#${confirmation.components.appeal.response}>` : ""))
- .setStatus("Danger")
- .setFooter({
- text: config.moderation.warn.text ? "The button below is set by the server admins. Do not enter any passwords or other account details on the linked site." : "",
- iconURL: "https://cdn.discordapp.com/emojis/952295894370369587.webp?size=128&quality=lossless"
- })
+ const config = await client.database.guilds.read(
+ interaction.guild.id
+ );
+ await (
+ interaction.options.getMember("user") as GuildMember
+ ).send({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("PUNISH.WARN.RED")
+ .setTitle("Warned")
+ .setDescription(
+ `You have been warned in ${interaction.guild.name}` +
+ (reason ? ` for:\n> ${reason}` : ".") +
+ "\n\n" +
+ (confirmation.components.appeal.response
+ ? `You can appeal this here ticket: <#${confirmation.components.appeal.response}>`
+ : "")
+ )
+ .setStatus("Danger")
+ .setFooter({
+ text: config.moderation.warn.text
+ ? "The button below is set by the server admins. Do not enter any passwords or other account details on the linked site."
+ : "",
+ iconURL:
+ "https://cdn.discordapp.com/emojis/952295894370369587.webp?size=128&quality=lossless"
+ })
],
- components: config.moderation.warn.text ? [new MessageActionRow().addComponents([new MessageButton()
- .setStyle("LINK")
- .setLabel(config.moderation.warn.text)
- .setURL(config.moderation.warn.link)
- ])] : []
+ components: config.moderation.warn.text
+ ? [
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setStyle("LINK")
+ .setLabel(config.moderation.warn.text)
+ .setURL(config.moderation.warn.link)
+ ])
+ ]
+ : []
});
dmd = true;
}
- } catch { dmd = false; }
+ } catch {
+ dmd = false;
+ }
const data = {
- meta:{
+ meta: {
type: "memberWarn",
displayName: "Member warned",
calculateType: "guildMemberPunish",
@@ -83,8 +144,18 @@
timestamp: new Date().getTime()
},
list: {
- user: entry((interaction.options.getMember("user") as GuildMember).user.id, renderUser((interaction.options.getMember("user") as GuildMember).user)),
- warnedBy: entry(interaction.member.user.id, renderUser(interaction.member.user)),
+ user: entry(
+ (interaction.options.getMember("user") as GuildMember).user
+ .id,
+ renderUser(
+ (interaction.options.getMember("user") as GuildMember)
+ .user
+ )
+ ),
+ warnedBy: entry(
+ interaction.member.user.id,
+ renderUser(interaction.member.user)
+ ),
reason: reason ? `\n> ${reason}` : "No reason provided"
},
hidden: {
@@ -92,28 +163,47 @@
}
};
await client.database.history.create(
- "warn", interaction.guild.id,
+ "warn",
+ interaction.guild.id,
(interaction.options.getMember("user") as GuildMember).user,
- interaction.user, reason
+ interaction.user,
+ reason
);
log(data);
- const failed = (dmd === false && notify);
+ const failed = !dmd && notify;
if (!failed) {
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("PUNISH.WARN.GREEN")
- .setTitle("Warn")
- .setDescription("The user was warned" + (confirmation.components.appeal.response ? ` and an appeal ticket was opened in <#${confirmation.components.appeal.response}>` : ""))
- .setStatus("Success")
- ], components: []});
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("PUNISH.WARN.GREEN")
+ .setTitle("Warn")
+ .setDescription(
+ "The user was warned" +
+ (confirmation.components.appeal.response
+ ? ` and an appeal ticket was opened in <#${confirmation.components.appeal.response}>`
+ : "")
+ )
+ .setStatus("Success")
+ ],
+ components: []
+ });
} else {
- const canSeeChannel = (interaction.options.getMember("user") as GuildMember).permissionsIn(interaction.channel as Discord.TextChannel).has("VIEW_CHANNEL");
- const m = await interaction.editReply({
- embeds: [new EmojiEmbed()
- .setEmoji("PUNISH.WARN.RED")
- .setTitle("Warn")
- .setDescription("The user's DMs are not open\n\nWhat would you like to do?")
- .setStatus("Danger")
- ], components: [
+ const canSeeChannel = (
+ interaction.options.getMember("user") as GuildMember
+ )
+ .permissionsIn(interaction.channel as Discord.TextChannel)
+ .has("VIEW_CHANNEL");
+ const m = (await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("PUNISH.WARN.RED")
+ .setTitle("Warn")
+ .setDescription(
+ "The user's DMs are not open\n\nWhat would you like to do?"
+ )
+ .setStatus("Danger")
+ ],
+ components: [
new MessageActionRow().addComponents([
new Discord.MessageButton()
.setCustomId("log")
@@ -130,76 +220,131 @@
.setStyle(canSeeChannel ? "SECONDARY" : "PRIMARY")
])
]
- }) as Discord.Message;
+ })) as Discord.Message;
let component;
try {
- component = await m.awaitMessageComponent({filter: (m) => m.user.id === interaction.user.id, time: 300000});
+ component = await m.awaitMessageComponent({
+ filter: (m) => m.user.id === interaction.user.id,
+ time: 300000
+ });
} catch (e) {
- return await interaction.editReply({embeds: [new EmojiEmbed()
+ return await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("PUNISH.WARN.GREEN")
+ .setTitle("Warn")
+ .setDescription("No changes were made")
+ .setStatus("Success")
+ ],
+ components: []
+ });
+ }
+ if (component.customId === "here") {
+ await interaction.channel.send({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("PUNISH.WARN.RED")
+ .setTitle("Warn")
+ .setDescription(
+ "You have been warned" +
+ (reason ? ` for:\n> ${reason}` : ".")
+ )
+ .setStatus("Danger")
+ ],
+ content: `<@!${
+ (interaction.options.getMember("user") as GuildMember)
+ .id
+ }>`,
+ allowedMentions: {
+ users: [
+ (
+ interaction.options.getMember(
+ "user"
+ ) as GuildMember
+ ).id
+ ]
+ }
+ });
+ return await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("PUNISH.WARN.GREEN")
+ .setTitle("Warn")
+ .setDescription(
+ "The user was warned" +
+ (confirmation.response
+ ? ` and an appeal ticket was opened in <#${confirmation.response}>`
+ : "")
+ )
+ .setStatus("Success")
+ ],
+ components: []
+ });
+ } else if (component.customId === "log") {
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("PUNISH.WARN.GREEN")
+ .setTitle("Warn")
+ .setDescription("The warn was logged")
+ .setStatus("Success")
+ ],
+ components: []
+ });
+ } else if (component.customId === "ticket") {
+ const ticketChannel = await create(
+ interaction.guild,
+ interaction.options.getUser("user"),
+ interaction.user,
+ reason,
+ "Warn Notification"
+ );
+ if (ticketChannel === null) {
+ return await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("PUNISH.WARN.RED")
+ .setTitle("Warn")
+ .setDescription("A ticket could not be created")
+ .setStatus("Danger")
+ ],
+ components: []
+ });
+ }
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("PUNISH.WARN.GREEN")
+ .setTitle("Warn")
+ .setDescription(
+ `A ticket was created in <#${ticketChannel}>`
+ )
+ .setStatus("Success")
+ ],
+ components: []
+ });
+ }
+ }
+ } else {
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
.setEmoji("PUNISH.WARN.GREEN")
.setTitle("Warn")
.setDescription("No changes were made")
.setStatus("Success")
- ], components: []});
- }
- if ( component.customId === "here" ) {
- await interaction.channel.send({
- embeds: [new EmojiEmbed()
- .setEmoji("PUNISH.WARN.RED")
- .setTitle("Warn")
- .setDescription("You have been warned" +
- (reason ? ` for:\n> ${reason}` : "."))
- .setStatus("Danger")
- ],
- content: `<@!${(interaction.options.getMember("user") as GuildMember).id}>`,
- allowedMentions: {users: [(interaction.options.getMember("user") as GuildMember).id]}
- });
- return await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("PUNISH.WARN.GREEN")
- .setTitle("Warn")
- .setDescription("The user was warned" + (confirmation.response ? ` and an appeal ticket was opened in <#${confirmation.response}>` : ""))
- .setStatus("Success")
- ], components: []});
- } else if (component.customId === "log") {
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("PUNISH.WARN.GREEN")
- .setTitle("Warn")
- .setDescription("The warn was logged")
- .setStatus("Success")
- ], components: []});
- } else if (component.customId === "ticket") {
- const ticketChannel = await create(interaction.guild, interaction.options.getUser("user"), interaction.user, reason, "Warn Notification");
- if (ticketChannel === null) {
- return await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("PUNISH.WARN.RED")
- .setTitle("Warn")
- .setDescription("A ticket could not be created")
- .setStatus("Danger")
- ], components: []});
- }
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("PUNISH.WARN.GREEN")
- .setTitle("Warn")
- .setDescription(`A ticket was created in <#${ticketChannel}>`)
- .setStatus("Success")
- ], components: []});
- }
- }
- } else {
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("PUNISH.WARN.GREEN")
- .setTitle("Warn")
- .setDescription("No changes were made")
- .setStatus("Success")
- ], components: []});
+ ],
+ components: []
+ });
}
};
const check = (interaction: CommandInteraction) => {
- const member = (interaction.member as GuildMember);
- const me = (interaction.guild.me as GuildMember);
- const apply = (interaction.options.getMember("user") as GuildMember);
- if (member === null || me === null || apply === null) throw "That member is not in the server";
+ const member = interaction.member as GuildMember;
+ const me = interaction.guild.me!;
+ const apply = interaction.options.getMember("user") as GuildMember;
+ if (member === null || me === null || apply === null)
+ throw "That member is not in the server";
const memberPos = member.roles ? member.roles.highest.position : 0;
const applyPos = apply.roles ? apply.roles.highest.position : 0;
// Do not allow warning bots
@@ -207,11 +352,13 @@
// Allow the owner to warn anyone
if (member.id === interaction.guild.ownerId) return true;
// Check if the user has moderate_members permission
- if (! member.permissions.has("MODERATE_MEMBERS")) throw "You do not have the *Moderate Members* permission";
+ if (!member.permissions.has("MODERATE_MEMBERS"))
+ throw "You do not have the *Moderate Members* permission";
// Check if the user is below on the role list
- if (! (memberPos > applyPos)) throw "You do not have a role higher than that member";
+ if (!(memberPos > applyPos))
+ throw "You do not have a role higher than that member";
// Allow warn
return true;
};
-export { command, callback, check };
\ No newline at end of file
+export { command, callback, check };
diff --git a/src/commands/nucleus/_meta.ts b/src/commands/nucleus/_meta.ts
index df978ba..a79a596 100644
--- a/src/commands/nucleus/_meta.ts
+++ b/src/commands/nucleus/_meta.ts
@@ -1,4 +1,4 @@
const name = "nucleus";
const description = "Commands relating to Nucleus itself";
-export { name, description };
\ No newline at end of file
+export { name, description };
diff --git a/src/commands/nucleus/guide.ts b/src/commands/nucleus/guide.ts
index 3141f9f..b9df446 100644
--- a/src/commands/nucleus/guide.ts
+++ b/src/commands/nucleus/guide.ts
@@ -6,7 +6,6 @@
.setName("guide")
.setDescription("Shows the welcome guide for the bot");
-
const callback = async (interaction) => {
guide(interaction.guild, interaction);
};
diff --git a/src/commands/nucleus/invite.ts b/src/commands/nucleus/invite.ts
index ebc3c34..8ae8c1a 100644
--- a/src/commands/nucleus/invite.ts
+++ b/src/commands/nucleus/invite.ts
@@ -1,24 +1,38 @@
-import { CommandInteraction, MessageActionRow, MessageButton } from "discord.js";
+import {
+ CommandInteraction,
+ MessageActionRow,
+ MessageButton
+} from "discord.js";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import client from "../../utils/client.js";
const command = (builder: SlashCommandSubcommandBuilder) =>
- builder
- .setName("invite")
- .setDescription("Invites Nucleus to your server");
+ builder.setName("invite").setDescription("Invites Nucleus to your server");
const callback = async (interaction: CommandInteraction): Promise<void> => {
- interaction.reply({embeds: [new EmojiEmbed()
- .setTitle("Invite")
- .setDescription("You can invite Nucleus to your server by clicking the button below")
- .setEmoji("NUCLEUS.LOGO")
- .setStatus("Danger")
- ], components: [new MessageActionRow().addComponents([new MessageButton()
- .setLabel("Invite")
- .setStyle("LINK")
- .setURL(`https://discord.com/api/oauth2/authorize?client_id=${client.user.id}&permissions=295157886134&scope=bot%20applications.commands`)
- ])], ephemeral: true});
+ interaction.reply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Invite")
+ .setDescription(
+ "You can invite Nucleus to your server by clicking the button below"
+ )
+ .setEmoji("NUCLEUS.LOGO")
+ .setStatus("Danger")
+ ],
+ components: [
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setLabel("Invite")
+ .setStyle("LINK")
+ .setURL(
+ `https://discord.com/api/oauth2/authorize?client_id=${client.user.id}&permissions=295157886134&scope=bot%20applications.commands`
+ )
+ ])
+ ],
+ ephemeral: true
+ });
};
const check = () => {
@@ -27,4 +41,4 @@
export { command };
export { callback };
-export { check };
\ No newline at end of file
+export { check };
diff --git a/src/commands/nucleus/ping.ts b/src/commands/nucleus/ping.ts
index 91e8363..105cda5 100644
--- a/src/commands/nucleus/ping.ts
+++ b/src/commands/nucleus/ping.ts
@@ -5,26 +5,29 @@
import client from "../../utils/client.js";
const command = (builder: SlashCommandSubcommandBuilder) =>
- builder
- .setName("ping")
- .setDescription("Gets the bot's ping time");
+ builder.setName("ping").setDescription("Gets the bot's ping time");
const callback = async (interaction: CommandInteraction): Promise<void> => {
// WEBSOCKET | Nucleus -> Discord
// EDITING | Nucleus -> discord -> nucleus | edit time / 2
const initial = new Date().getTime();
- await interaction.reply({embeds: LoadingEmbed, ephemeral: true});
+ await interaction.reply({ embeds: LoadingEmbed, ephemeral: true });
const ping = new Date().getTime() - initial;
- interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Ping")
- .setDescription(
- `**Ping:** \`${ping}ms\`\n` +
- `**To Discord:** \`${client.ws.ping}ms\`\n` +
- `**From Expected:** \`±${Math.abs((ping / 2) - client.ws.ping)}ms\``
- )
- .setEmoji("CHANNEL.SLOWMODE.OFF")
- .setStatus("Danger")
- ]});
+ interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Ping")
+ .setDescription(
+ `**Ping:** \`${ping}ms\`\n` +
+ `**To Discord:** \`${client.ws.ping}ms\`\n` +
+ `**From Expected:** \`±${Math.abs(
+ ping / 2 - client.ws.ping
+ )}ms\``
+ )
+ .setEmoji("CHANNEL.SLOWMODE.OFF")
+ .setStatus("Danger")
+ ]
+ });
};
const check = () => {
@@ -33,4 +36,4 @@
export { command };
export { callback };
-export { check };
\ No newline at end of file
+export { check };
diff --git a/src/commands/nucleus/premium.ts b/src/commands/nucleus/premium.ts
index 9ad2c16..83ba327 100644
--- a/src/commands/nucleus/premium.ts
+++ b/src/commands/nucleus/premium.ts
@@ -8,17 +8,21 @@
.setDescription("Information about Nucleus Premium");
const callback = async (interaction: CommandInteraction): Promise<void> => {
- interaction.reply({embeds: [new EmojiEmbed()
- .setTitle("Premium")
- .setDescription(
- "*Nucleus Premium is currently not available.*\n\n" +
- "Premium allows your server to get access to extra features, for a fixed price per month.\nThis includes:\n" +
- "- Attachment logs - Stores attachments so they can be viewed after a message is deleted.\n" +
- "- Ticket Transcripts - Gives a link to view the history of a ticket after it has been closed.\n"
- )
- .setEmoji("NUCLEUS.LOGO")
- .setStatus("Danger")
- ], ephemeral: true});
+ interaction.reply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Premium")
+ .setDescription(
+ "*Nucleus Premium is currently not available.*\n\n" +
+ "Premium allows your server to get access to extra features, for a fixed price per month.\nThis includes:\n" +
+ "- Attachment logs - Stores attachments so they can be viewed after a message is deleted.\n" +
+ "- Ticket Transcripts - Gives a link to view the history of a ticket after it has been closed.\n"
+ )
+ .setEmoji("NUCLEUS.LOGO")
+ .setStatus("Danger")
+ ],
+ ephemeral: true
+ });
};
const check = () => {
@@ -27,4 +31,4 @@
export { command };
export { callback };
-export { check };
\ No newline at end of file
+export { check };
diff --git a/src/commands/nucleus/stats.ts b/src/commands/nucleus/stats.ts
index 2558997..68eeaa9 100644
--- a/src/commands/nucleus/stats.ts
+++ b/src/commands/nucleus/stats.ts
@@ -4,22 +4,21 @@
import client from "../../utils/client.js";
const command = (builder: SlashCommandSubcommandBuilder) =>
- builder
- .setName("stats")
- .setDescription("Gets the bot's stats");
+ builder.setName("stats").setDescription("Gets the bot's stats");
const callback = async (interaction: CommandInteraction): Promise<void> => {
interaction.reply({
- embeds: [new EmojiEmbed()
- .setTitle("Stats")
- .setDescription(
- `**Servers:** ${client.guilds.cache.size}\n` +
- `**Ping:** \`${client.ws.ping*2}ms\``
- )
- .setStatus("Success")
- .setEmoji("GUILD.GRAPHS")
-
- ], ephemeral: true
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Stats")
+ .setDescription(
+ `**Servers:** ${client.guilds.cache.size}\n` +
+ `**Ping:** \`${client.ws.ping * 2}ms\``
+ )
+ .setStatus("Success")
+ .setEmoji("GUILD.GRAPHS")
+ ],
+ ephemeral: true
});
};
@@ -29,4 +28,4 @@
export { command };
export { callback };
-export { check };
\ No newline at end of file
+export { check };
diff --git a/src/commands/nucleus/suggest.ts b/src/commands/nucleus/suggest.ts
index a6657d8..0f40501 100644
--- a/src/commands/nucleus/suggest.ts
+++ b/src/commands/nucleus/suggest.ts
@@ -9,7 +9,12 @@
builder
.setName("suggest")
.setDescription("Sends a suggestion to the developers")
- .addStringOption(option => option.setName("suggestion").setDescription("The suggestion to send").setRequired(true));
+ .addStringOption((option) =>
+ option
+ .setName("suggestion")
+ .setDescription("The suggestion to send")
+ .setRequired(true)
+ );
const callback = async (interaction: CommandInteraction): Promise<void> => {
const { renderUser } = client.logger;
@@ -17,42 +22,63 @@
const confirmation = await new confirmationMessage(interaction)
.setEmoji("ICONS.OPP.ADD")
.setTitle("Suggest")
- .setDescription(`**Suggestion:**\n> ${suggestion}\n`
- + "Your username and ID will also be sent with your suggestion.\n\nAre you sure you want to send this suggestion?")
+ .setDescription(
+ `**Suggestion:**\n> ${suggestion}\n` +
+ "Your username and ID will also be sent with your suggestion.\n\nAre you sure you want to send this suggestion?"
+ )
.setColor("Danger")
.setInverted(true)
.send();
if (confirmation.cancelled) return;
if (confirmation.success) {
- await (client.channels.cache.get("955161206459600976") as Discord.TextChannel).send({
+ await (
+ client.channels.cache.get(
+ "955161206459600976"
+ ) as Discord.TextChannel
+ ).send({
embeds: [
new EmojiEmbed()
.setTitle("Suggestion")
- .setDescription(`**From:** ${renderUser(interaction.member.user)}\n**Suggestion:**\n> ${suggestion}`)
+ .setDescription(
+ `**From:** ${renderUser(
+ interaction.member.user
+ )}\n**Suggestion:**\n> ${suggestion}`
+ )
.setStatus("Danger")
.setEmoji("NUCLEUS.LOGO")
]
});
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("ICONS.ADD")
- .setTitle("Suggest")
- .setDescription("Your suggestion was sent successfully")
- .setStatus("Success")
- ], components: []});
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("ICONS.ADD")
+ .setTitle("Suggest")
+ .setDescription("Your suggestion was sent successfully")
+ .setStatus("Success")
+ ],
+ components: []
+ });
} else {
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("ICONS.OPP.ADD")
- .setTitle("Suggest")
- .setDescription("No changes were made")
- .setStatus("Danger")
- ], components: []});
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("ICONS.OPP.ADD")
+ .setTitle("Suggest")
+ .setDescription("No changes were made")
+ .setStatus("Danger")
+ ],
+ components: []
+ });
}
};
-const check = (_interaction: CommandInteraction, _defaultCheck: WrappedCheck) => {
+const check = (
+ _interaction: CommandInteraction,
+ _defaultCheck: WrappedCheck
+) => {
return true;
};
export { command };
export { callback };
-export { check };
\ No newline at end of file
+export { check };
diff --git a/src/commands/privacy.ts b/src/commands/privacy.ts
index 8fb6b40..3c36ea1 100644
--- a/src/commands/privacy.ts
+++ b/src/commands/privacy.ts
@@ -1,5 +1,9 @@
import { LoadingEmbed } from "./../utils/defaultEmbeds.js";
-import Discord, { CommandInteraction, MessageActionRow, MessageButton } from "discord.js";
+import Discord, {
+ CommandInteraction,
+ MessageActionRow,
+ MessageButton
+} from "discord.js";
import { SelectMenuOption, SlashCommandBuilder } from "@discordjs/builders";
import { WrappedCheck } from "jshaiku";
import EmojiEmbed from "../utils/generateEmojiEmbed.js";
@@ -10,7 +14,9 @@
const command = new SlashCommandBuilder()
.setName("privacy")
- .setDescription("Information and options for you and your server's settings");
+ .setDescription(
+ "Information and options for you and your server's settings"
+ );
class Embed {
embed: Discord.MessageEmbed;
@@ -18,61 +24,111 @@
description = "";
pageId = 0;
components?: MessageActionRow[] = [];
- setEmbed(embed: Discord.MessageEmbed) { this.embed = embed; return this; }
- setTitle(title: string) { this.title = title; return this; }
- setDescription(description: string) { this.description = description; return this; }
- setPageId(pageId: number) { this.pageId = pageId; return this; }
- setComponents(components: MessageActionRow[]) { this.components = components; return this; }
+ setEmbed(embed: Discord.MessageEmbed) {
+ this.embed = embed;
+ return this;
+ }
+ setTitle(title: string) {
+ this.title = title;
+ return this;
+ }
+ setDescription(description: string) {
+ this.description = description;
+ return this;
+ }
+ setPageId(pageId: number) {
+ this.pageId = pageId;
+ return this;
+ }
+ setComponents(components: MessageActionRow[]) {
+ this.components = components;
+ return this;
+ }
}
const callback = async (interaction: CommandInteraction): Promise<void> => {
const pages = [
new Embed()
- .setEmbed(new EmojiEmbed()
- .setTitle("Nucleus Privacy")
- .setDescription(
- "Nucleus is a bot that naturally needs to store data about servers.\n" +
- "We are entirely [open source](https://github.com/ClicksMinutePer/Nucleus), so you can check exactly what we store, and how it works.\n\n" +
- "If you are a server administrator, you can view the options page in the dropdown under this message.\n\n" +
- "Any questions about Nucleus, how it works and data stored can be asked in [our server](https://discord.gg/bPaNnxe)."
- )
- .setEmoji("NUCLEUS.LOGO")
- .setStatus("Danger")
- ).setTitle("Welcome").setDescription("General privacy information").setPageId(0),
- new Embed()
- .setEmbed(new EmojiEmbed()
- .setTitle("Scanners")
- .setDescription(
- "Nucleus uses [unscan](https://unscan.co) to scan links, images and files for malware and other threats.\n" +
- "This service's [privacy policy](https://unscan.co/policies) is public, and they \"do not store or sell your data.\""
- )
- .setEmoji("NUCLEUS.LOGO")
- .setStatus("Danger")
- ).setTitle("Scanners").setDescription("About Unscan").setPageId(1),
- new Embed()
- .setEmbed(new EmojiEmbed()
- .setTitle("Link scanning and Transcripts")
- .setDescription(
- "**Facebook** - Facebook trackers include data such as your date of birth, and guess your age if not entered, your preferences, who you interact with and more.\n" +
- "**AMP** - AMP is a technology that allows websites to be served by Google. This means Google can store and track data, and are pushing this to as many pages as possible.\n\n" +
- "Transcripts allow you to store all messages sent in a channel. This could be an issue in some cases, as they are hosted on [Pastebin](https://pastebin.com), so a leaked link could show all messages sent in the channel.\n"
- )
- .setEmoji("NUCLEUS.LOGO")
- .setStatus("Danger")
- ).setTitle("Link scanning and Transcripts").setDescription("Regarding Facebook and AMP filter types, and ticket transcripts").setPageId(2)
- ].concat((interaction.member as Discord.GuildMember).permissions.has("ADMINISTRATOR") ? [new Embed()
- .setEmbed(new EmojiEmbed()
- .setTitle("Options")
- .setDescription(
- "Below are buttons for controlling this servers privacy settings"
+ .setEmbed(
+ new EmojiEmbed()
+ .setTitle("Nucleus Privacy")
+ .setDescription(
+ "Nucleus is a bot that naturally needs to store data about servers.\n" +
+ "We are entirely [open source](https://github.com/ClicksMinutePer/Nucleus), so you can check exactly what we store, and how it works.\n\n" +
+ "If you are a server administrator, you can view the options page in the dropdown under this message.\n\n" +
+ "Any questions about Nucleus, how it works and data stored can be asked in [our server](https://discord.gg/bPaNnxe)."
+ )
+ .setEmoji("NUCLEUS.LOGO")
+ .setStatus("Danger")
)
- .setEmoji("NUCLEUS.LOGO")
- .setStatus("Danger")
- ).setTitle("Options").setDescription("Options").setPageId(3).setComponents([new MessageActionRow().addComponents([
- new MessageButton().setLabel("Clear all data").setCustomId("clear-all-data").setStyle("DANGER")
- ])])
- ] : []);
- const m = await interaction.reply({embeds: LoadingEmbed, fetchReply: true, ephemeral: true});
+ .setTitle("Welcome")
+ .setDescription("General privacy information")
+ .setPageId(0),
+ new Embed()
+ .setEmbed(
+ new EmojiEmbed()
+ .setTitle("Scanners")
+ .setDescription(
+ "Nucleus uses [unscan](https://unscan.co) to scan links, images and files for malware and other threats.\n" +
+ 'This service\'s [privacy policy](https://unscan.co/policies) is public, and they "do not store or sell your data."'
+ )
+ .setEmoji("NUCLEUS.LOGO")
+ .setStatus("Danger")
+ )
+ .setTitle("Scanners")
+ .setDescription("About Unscan")
+ .setPageId(1),
+ new Embed()
+ .setEmbed(
+ new EmojiEmbed()
+ .setTitle("Link scanning and Transcripts")
+ .setDescription(
+ "**Facebook** - Facebook trackers include data such as your date of birth, and guess your age if not entered, your preferences, who you interact with and more.\n" +
+ "**AMP** - AMP is a technology that allows websites to be served by Google. This means Google can store and track data, and are pushing this to as many pages as possible.\n\n" +
+ "Transcripts allow you to store all messages sent in a channel. This could be an issue in some cases, as they are hosted on [Pastebin](https://pastebin.com), so a leaked link could show all messages sent in the channel.\n"
+ )
+ .setEmoji("NUCLEUS.LOGO")
+ .setStatus("Danger")
+ )
+ .setTitle("Link scanning and Transcripts")
+ .setDescription(
+ "Regarding Facebook and AMP filter types, and ticket transcripts"
+ )
+ .setPageId(2)
+ ].concat(
+ (interaction.member as Discord.GuildMember).permissions.has(
+ "ADMINISTRATOR"
+ )
+ ? [
+ new Embed()
+ .setEmbed(
+ new EmojiEmbed()
+ .setTitle("Options")
+ .setDescription(
+ "Below are buttons for controlling this servers privacy settings"
+ )
+ .setEmoji("NUCLEUS.LOGO")
+ .setStatus("Danger")
+ )
+ .setTitle("Options")
+ .setDescription("Options")
+ .setPageId(3)
+ .setComponents([
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setLabel("Clear all data")
+ .setCustomId("clear-all-data")
+ .setStyle("DANGER")
+ ])
+ ])
+ ]
+ : []
+ );
+ const m = await interaction.reply({
+ embeds: LoadingEmbed,
+ fetchReply: true,
+ ephemeral: true
+ });
let page = 0;
let selectPaneOpen = false;
@@ -83,37 +139,59 @@
if (selectPaneOpen) {
const options = [];
- pages.forEach(embed => {
- options.push(new SelectMenuOption({
- label: embed.title,
- value: embed.pageId.toString(),
- description: embed.description || ""
- }));
+ pages.forEach((embed) => {
+ options.push(
+ new SelectMenuOption({
+ label: embed.title,
+ value: embed.pageId.toString(),
+ description: embed.description || ""
+ })
+ );
});
- selectPane = [new MessageActionRow().addComponents([
- new Discord.MessageSelectMenu()
- .addOptions(options)
- .setCustomId("page")
- .setMaxValues(1)
- .setPlaceholder("Choose a page...")
- ])];
+ selectPane = [
+ new MessageActionRow().addComponents([
+ new Discord.MessageSelectMenu()
+ .addOptions(options)
+ .setCustomId("page")
+ .setMaxValues(1)
+ .setPlaceholder("Choose a page...")
+ ])
+ ];
}
- const components = selectPane.concat([new MessageActionRow().addComponents([
- new MessageButton().setCustomId("left").setEmoji(getEmojiByName("CONTROL.LEFT", "id")).setStyle("SECONDARY").setDisabled(page === 0),
- new MessageButton().setCustomId("select").setEmoji(getEmojiByName("CONTROL.MENU", "id")).setStyle(selectPaneOpen ? "PRIMARY" : "SECONDARY").setDisabled(false),
- new MessageButton().setCustomId("right").setEmoji(getEmojiByName("CONTROL.RIGHT", "id")).setStyle("SECONDARY").setDisabled(page === pages.length - 1)
- ])]);
+ const components = selectPane.concat([
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setCustomId("left")
+ .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
+ .setStyle("SECONDARY")
+ .setDisabled(page === 0),
+ new MessageButton()
+ .setCustomId("select")
+ .setEmoji(getEmojiByName("CONTROL.MENU", "id"))
+ .setStyle(selectPaneOpen ? "PRIMARY" : "SECONDARY")
+ .setDisabled(false),
+ new MessageButton()
+ .setCustomId("right")
+ .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
+ .setStyle("SECONDARY")
+ .setDisabled(page === pages.length - 1)
+ ])
+ ]);
const em = new Discord.MessageEmbed(pages[page].embed);
- em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page));
- em.setFooter({text: nextFooter ?? ""});
+ em.setDescription(
+ em.description + "\n\n" + createPageIndicator(pages.length, page)
+ );
+ em.setFooter({ text: nextFooter ?? "" });
await interaction.editReply({
embeds: [em],
components: components.concat(pages[page].components)
});
let i;
try {
- i = await m.awaitMessageComponent({time: 300000});
- } catch(e) { break; }
+ i = await m.awaitMessageComponent({ time: 300000 });
+ } catch (e) {
+ break;
+ }
nextFooter = null;
i.deferUpdate();
if (i.component.customId === "left") {
@@ -133,11 +211,13 @@
.setTitle("Clear All Data")
.setDescription(
"Are you sure you want to delete all data on this server? This includes your settings and all punishment histories.\n\n" +
- "**This cannot be undone.**"
+ "**This cannot be undone.**"
)
.setColor("Danger")
.send(true);
- if (confirmation.cancelled) { break; }
+ if (confirmation.cancelled) {
+ break;
+ }
if (confirmation.success) {
client.database.guilds.delete(interaction.guild.id);
client.database.history.delete(interaction.guild.id);
@@ -149,25 +229,34 @@
}
} else {
const em = new Discord.MessageEmbed(pages[page].embed);
- em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page));
- em.setFooter({text: "Message closed"});
- interaction.editReply({embeds: [em], components: []});
+ em.setDescription(
+ em.description +
+ "\n\n" +
+ createPageIndicator(pages.length, page)
+ );
+ em.setFooter({ text: "Message closed" });
+ interaction.editReply({ embeds: [em], components: [] });
return;
}
}
const em = new Discord.MessageEmbed(pages[page].embed);
- em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page));
- em.setFooter({text: "Message timed out"});
+ em.setDescription(
+ em.description + "\n\n" + createPageIndicator(pages.length, page)
+ );
+ em.setFooter({ text: "Message timed out" });
await interaction.editReply({
embeds: [em],
components: []
});
};
-const check = (_interaction: CommandInteraction, _defaultCheck: WrappedCheck) => {
+const check = (
+ _interaction: CommandInteraction,
+ _defaultCheck: WrappedCheck
+) => {
return true;
};
export { command };
export { callback };
-export { check };
\ No newline at end of file
+export { check };
diff --git a/src/commands/role/_meta.ts b/src/commands/role/_meta.ts
index 408576f..c5936c9 100644
--- a/src/commands/role/_meta.ts
+++ b/src/commands/role/_meta.ts
@@ -1,4 +1,4 @@
const name = "role";
const description = "Change roles for users";
-export { name, description };
\ No newline at end of file
+export { name, description };
diff --git a/src/commands/role/user.ts b/src/commands/role/user.ts
index b54ee1e..2557b4b 100644
--- a/src/commands/role/user.ts
+++ b/src/commands/role/user.ts
@@ -10,25 +10,49 @@
builder
.setName("user")
.setDescription("Gives or removes a role from someone")
- .addUserOption(option => option.setName("user").setDescription("The member to give or remove the role from").setRequired(true))
- .addRoleOption(option => option.setName("role").setDescription("The role to give or remove").setRequired(true))
- .addStringOption(option => option.setName("action").setDescription("The action to perform").setRequired(true).addChoices([
- ["Add", "give"],
- ["Remove", "remove"]
- ]));
+ .addUserOption((option) =>
+ option
+ .setName("user")
+ .setDescription("The member to give or remove the role from")
+ .setRequired(true)
+ )
+ .addRoleOption((option) =>
+ option
+ .setName("role")
+ .setDescription("The role to give or remove")
+ .setRequired(true)
+ )
+ .addStringOption((option) =>
+ option
+ .setName("action")
+ .setDescription("The action to perform")
+ .setRequired(true)
+ .addChoices([
+ ["Add", "give"],
+ ["Remove", "remove"]
+ ])
+ );
-
-const callback = async (interaction: CommandInteraction): Promise<void | unknown> => {
+const callback = async (
+ interaction: CommandInteraction
+): Promise<void | unknown> => {
const { renderUser, renderRole } = client.logger;
const action = interaction.options.getString("action");
// TODO:[Modals] Replace this with a modal
const confirmation = await new confirmationMessage(interaction)
.setEmoji("GUILD.ROLES.DELETE")
.setTitle("Role")
- .setDescription(keyValueList({
- "user": renderUser(interaction.options.getUser("user")),
- "role": renderRole(interaction.options.getRole("role"))
- }) + `\nAre you sure you want to ${action === "give" ? "give the role to" : "remove the role from"} ${interaction.options.getUser("user")}?`)
+ .setDescription(
+ keyValueList({
+ user: renderUser(interaction.options.getUser("user")),
+ role: renderRole(interaction.options.getRole("role"))
+ }) +
+ `\nAre you sure you want to ${
+ action === "give"
+ ? "give the role to"
+ : "remove the role from"
+ } ${interaction.options.getUser("user")}?`
+ )
.setColor("Danger")
.send();
if (confirmation.cancelled) return;
@@ -42,44 +66,68 @@
member.roles.remove(role);
}
} catch (e) {
- return await interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Role")
- .setDescription("Something went wrong and the role could not be added")
- .setStatus("Danger")
- .setEmoji("CONTROL.BLOCKCROSS")
- ], components: []});
+ return await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Role")
+ .setDescription(
+ "Something went wrong and the role could not be added"
+ )
+ .setStatus("Danger")
+ .setEmoji("CONTROL.BLOCKCROSS")
+ ],
+ components: []
+ });
}
- return await interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Role")
- .setDescription(`The role has been ${action === "give" ? "given" : "removed"} successfully`)
- .setStatus("Success")
- .setEmoji("GUILD.ROLES.CREATE")
- ], components: []});
+ return await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Role")
+ .setDescription(
+ `The role has been ${
+ action === "give" ? "given" : "removed"
+ } successfully`
+ )
+ .setStatus("Success")
+ .setEmoji("GUILD.ROLES.CREATE")
+ ],
+ components: []
+ });
} else {
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("GUILD.ROLES.CREATE")
- .setTitle("Role")
- .setDescription("No changes were made.")
- .setStatus("Danger")
- ], components: []});
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("GUILD.ROLES.CREATE")
+ .setTitle("Role")
+ .setDescription("No changes were made.")
+ .setStatus("Danger")
+ ],
+ components: []
+ });
}
};
-const check = (interaction: CommandInteraction, _defaultCheck: WrappedCheck) => {
- const member = (interaction.member as GuildMember);
- const me = (interaction.guild.me as GuildMember);
- const apply = (interaction.options.getMember("user") as GuildMember);
- if (member === null || me === null || apply === null) throw "That member is not in the server";
+const check = (
+ interaction: CommandInteraction,
+ _defaultCheck: WrappedCheck
+) => {
+ const member = interaction.member as GuildMember;
+ const me = interaction.guild.me!;
+ const apply = interaction.options.getMember("user") as GuildMember;
+ if (member === null || me === null || apply === null)
+ throw "That member is not in the server";
// Check if Nucleus has permission to role
- if (!me.permissions.has("MANAGE_ROLES")) throw "I do not have the *Manage Roles* permission";
+ if (!me.permissions.has("MANAGE_ROLES"))
+ throw "I do not have the *Manage Roles* permission";
// Allow the owner to role anyone
if (member.id === interaction.guild.ownerId) return true;
// Check if the user has manage_roles permission
- if (! member.permissions.has("MANAGE_ROLES")) throw "You do not have the *Manage Roles* permission";
+ if (!member.permissions.has("MANAGE_ROLES"))
+ throw "You do not have the *Manage Roles* permission";
// Allow role
return true;
};
export { command };
export { callback };
-export { check };
\ No newline at end of file
+export { check };
diff --git a/src/commands/rolemenu.ts b/src/commands/rolemenu.ts
index dd3cb34..8566966 100644
--- a/src/commands/rolemenu.ts
+++ b/src/commands/rolemenu.ts
@@ -11,7 +11,10 @@
await roleMenu(interaction);
};
-const check = (_interaction: CommandInteraction, _defaultCheck: WrappedCheck) => {
+const check = (
+ _interaction: CommandInteraction,
+ _defaultCheck: WrappedCheck
+) => {
return true;
};
diff --git a/src/commands/server/_meta.ts b/src/commands/server/_meta.ts
index 379aac6..5c0ba48 100644
--- a/src/commands/server/_meta.ts
+++ b/src/commands/server/_meta.ts
@@ -1,4 +1,4 @@
const name = "server";
const description = "Commands for the server";
-export { name, description };
\ No newline at end of file
+export { name, description };
diff --git a/src/commands/server/about.ts b/src/commands/server/about.ts
index c0a2ede..0a1cc6f 100644
--- a/src/commands/server/about.ts
+++ b/src/commands/server/about.ts
@@ -3,48 +3,84 @@
import { WrappedCheck } from "jshaiku";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import getEmojiByName from "../../utils/getEmojiByName.js";
-import generateKeyValueList, { toCapitals } from "../../utils/generateKeyValueList.js";
+import generateKeyValueList, {
+ toCapitals
+} from "../../utils/generateKeyValueList.js";
import client from "../../utils/client.js";
-const command = (builder: SlashCommandSubcommandBuilder) => builder
- .setName("about")
- .setDescription("Shows info about the server");
+const command = (builder: SlashCommandSubcommandBuilder) =>
+ builder.setName("about").setDescription("Shows info about the server");
const callback = async (interaction: CommandInteraction): Promise<void> => {
- const guild = interaction.guild as Guild;
+ const guild = interaction.guild!;
const { renderUser, renderDelta } = client.logger;
- interaction.reply({embeds: [new EmojiEmbed()
- .setTitle("Server Info")
- .setStatus("Success")
- .setEmoji("GUILD.GREEN")
- .setDescription(
- generateKeyValueList({
- "name": guild.name,
- "id": `\`${guild.id}\``,
- "owner": `${renderUser((await guild.fetchOwner()).user)}`,
- "created": `${renderDelta(guild.createdTimestamp)}`,
- "emojis": `${guild.emojis.cache.size}` + (guild.emojis.cache.size > 1 ? `\n> ${
- guild.emojis.cache.first(10).map((emoji) => `<${emoji.animated ? "a" : ""}:${emoji.name}:${emoji.id}>`).join(" ")
- }` +
- (guild.emojis.cache.size > 10 ? ` and ${guild.emojis.cache.size - 10} more` : "") : ""),
- "icon": `[Discord](${guild.iconURL()})`,
- "2 factor authentication": `${guild.mfaLevel === "NONE" ? `${getEmojiByName("CONTROL.CROSS")} No` : `${getEmojiByName("CONTROL.TICK")} Yes`}`,
- "verification level": `${toCapitals(guild.verificationLevel)}`,
- "explicit content filter": `${toCapitals(guild.explicitContentFilter.toString().replace(/_/, " " ))}`,
- "nitro boost level": `${guild.premiumTier !== "NONE" ? guild.premiumTier.toString()[-1] : "0"}`,
- "channels": `${guild.channels.cache.size}`,
- "roles": `${guild.roles.cache.size}`,
- "members": `${guild.memberCount}`
- })
- )
- .setThumbnail(guild.iconURL({dynamic: true}))
- ], ephemeral: true});
+ interaction.reply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Server Info")
+ .setStatus("Success")
+ .setEmoji("GUILD.GREEN")
+ .setDescription(
+ generateKeyValueList({
+ name: guild.name,
+ id: `\`${guild.id}\``,
+ owner: `${renderUser((await guild.fetchOwner()).user)}`,
+ created: `${renderDelta(guild.createdTimestamp)}`,
+ emojis:
+ `${guild.emojis.cache.size}` +
+ (guild.emojis.cache.size > 1
+ ? `\n> ${guild.emojis.cache
+ .first(10)
+ .map(
+ (emoji) =>
+ `<${emoji.animated ? "a" : ""}:${
+ emoji.name
+ }:${emoji.id}>`
+ )
+ .join(" ")}` +
+ (guild.emojis.cache.size > 10
+ ? ` and ${
+ guild.emojis.cache.size - 10
+ } more`
+ : "")
+ : ""),
+ icon: `[Discord](${guild.iconURL()})`,
+ "2 factor authentication": `${
+ guild.mfaLevel === "NONE"
+ ? `${getEmojiByName("CONTROL.CROSS")} No`
+ : `${getEmojiByName("CONTROL.TICK")} Yes`
+ }`,
+ "verification level": `${toCapitals(
+ guild.verificationLevel
+ )}`,
+ "explicit content filter": `${toCapitals(
+ guild.explicitContentFilter
+ .toString()
+ .replace(/_/, " ")
+ )}`,
+ "nitro boost level": `${
+ guild.premiumTier !== "NONE"
+ ? guild.premiumTier.toString()[-1]
+ : "0"
+ }`,
+ channels: `${guild.channels.cache.size}`,
+ roles: `${guild.roles.cache.size}`,
+ members: `${guild.memberCount}`
+ })
+ )
+ .setThumbnail(guild.iconURL({ dynamic: true }))
+ ],
+ ephemeral: true
+ });
};
-const check = (_interaction: CommandInteraction, _defaultCheck: WrappedCheck) => {
+const check = (
+ _interaction: CommandInteraction,
+ _defaultCheck: WrappedCheck
+) => {
return true;
};
export { command };
export { callback };
-export { check };
\ No newline at end of file
+export { check };
diff --git a/src/commands/settings/_meta.ts b/src/commands/settings/_meta.ts
index 63d726e..1241322 100644
--- a/src/commands/settings/_meta.ts
+++ b/src/commands/settings/_meta.ts
@@ -1,4 +1,4 @@
const name = "settings";
const description = "Change bot settings";
-export { name, description };
\ No newline at end of file
+export { name, description };
diff --git a/src/commands/settings/commands.ts b/src/commands/settings/commands.ts
index 845e001..13cfa89 100644
--- a/src/commands/settings/commands.ts
+++ b/src/commands/settings/commands.ts
@@ -1,5 +1,10 @@
import { LoadingEmbed } from "./../../utils/defaultEmbeds.js";
-import Discord, { CommandInteraction, MessageActionRow, MessageButton, TextInputComponent } from "discord.js";
+import Discord, {
+ CommandInteraction,
+ MessageActionRow,
+ MessageButton,
+ TextInputComponent
+} from "discord.js";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import getEmojiByName from "../../utils/getEmojiByName.js";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
@@ -12,133 +17,257 @@
const command = (builder: SlashCommandSubcommandBuilder) =>
builder
.setName("commands")
- .setDescription("Links and text shown to a user after a moderator action is performed")
- .addRoleOption(o => o.setName("role").setDescription("The role given when a member is muted"));
+ .setDescription(
+ "Links and text shown to a user after a moderator action is performed"
+ )
+ .addRoleOption((o) =>
+ o
+ .setName("role")
+ .setDescription("The role given when a member is muted")
+ );
-const callback = async (interaction: CommandInteraction): Promise<void | unknown> => {
- await interaction.reply({embeds: LoadingEmbed, ephemeral: true, fetchReply: true});
+const callback = async (
+ interaction: CommandInteraction
+): Promise<void | unknown> => {
+ await interaction.reply({
+ embeds: LoadingEmbed,
+ ephemeral: true,
+ fetchReply: true
+ });
let m;
let clicked = "";
if (interaction.options.getRole("role")) {
const confirmation = await new confirmationMessage(interaction)
.setEmoji("GUILD.ROLES.DELETE")
.setTitle("Moderation Commands")
- .setDescription(keyValueList({
- role: `<@&${interaction.options.getRole("role").id}>`
- }))
+ .setDescription(
+ keyValueList({
+ role: `<@&${interaction.options.getRole("role").id}>`
+ })
+ )
.setColor("Danger")
.send(true);
- if (confirmation.cancelled) return await interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Moderation Commands")
- .setDescription("No changes were made")
- .setStatus("Success")
- .setEmoji("GUILD.ROLES.CREATE")
- ]});
+ if (confirmation.cancelled)
+ return await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Moderation Commands")
+ .setDescription("No changes were made")
+ .setStatus("Success")
+ .setEmoji("GUILD.ROLES.CREATE")
+ ]
+ });
if (confirmation.success) {
- await client.database.guilds.write(interaction.guild.id, {["moderation.mute.role"]: interaction.options.getRole("role").id});
+ await client.database.guilds.write(interaction.guild.id, {
+ ["moderation.mute.role"]: interaction.options.getRole("role").id
+ });
}
}
while (true) {
const config = await client.database.guilds.read(interaction.guild.id);
const moderation = config.getKey("moderation");
- m = await interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Moderation Commands")
- .setEmoji("PUNISH.BAN.GREEN")
- .setStatus("Success")
- .setDescription(
- "These links are shown below the message sent in a user's DM when they are punished.\n\n" +
- "**Mute Role:** " + (moderation.mute.role ? `<@&${moderation.mute.role}>` : "*None set*")
- )
- ], components: [new MessageActionRow().addComponents([
- new MessageButton().setLabel("Warn").setEmoji(getEmojiByName("PUNISH.WARN.YELLOW", "id")).setCustomId("warn").setStyle("SECONDARY"),
- new MessageButton().setLabel("Mute").setEmoji(getEmojiByName("PUNISH.MUTE.YELLOW", "id")).setCustomId("mute").setStyle("SECONDARY"),
- new MessageButton().setLabel("Nickname").setEmoji(getEmojiByName("PUNISH.NICKNAME.GREEN", "id")).setCustomId("nickname").setStyle("SECONDARY")
- ]), new MessageActionRow().addComponents([
- new MessageButton().setLabel("Kick").setEmoji(getEmojiByName("PUNISH.KICK.RED", "id")).setCustomId("kick").setStyle("SECONDARY"),
- new MessageButton().setLabel("Softban").setEmoji(getEmojiByName("PUNISH.BAN.YELLOW", "id")).setCustomId("softban").setStyle("SECONDARY"),
- new MessageButton().setLabel("Ban").setEmoji(getEmojiByName("PUNISH.BAN.RED", "id")).setCustomId("ban").setStyle("SECONDARY")
- ]), new MessageActionRow().addComponents([
- new MessageButton().setLabel(
- clicked === "clearMuteRole" ? "Click again to confirm" : "Clear mute role"
- ).setEmoji(getEmojiByName("CONTROL.CROSS", "id")).setCustomId("clearMuteRole").setStyle("DANGER").setDisabled(!moderation.mute.role),
- new MessageButton()
- .setCustomId("timeout")
- .setLabel("Mute timeout " + (moderation.mute.timeout ? "Enabled" : "Disabled"))
- .setStyle(moderation.mute.timeout ? "SUCCESS" : "DANGER")
- .setEmoji(getEmojiByName("CONTROL." + (moderation.mute.timeout ? "TICK" : "CROSS"), "id"))
- ])]});
+ m = await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Moderation Commands")
+ .setEmoji("PUNISH.BAN.GREEN")
+ .setStatus("Success")
+ .setDescription(
+ "These links are shown below the message sent in a user's DM when they are punished.\n\n" +
+ "**Mute Role:** " +
+ (moderation.mute.role
+ ? `<@&${moderation.mute.role}>`
+ : "*None set*")
+ )
+ ],
+ components: [
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setLabel("Warn")
+ .setEmoji(getEmojiByName("PUNISH.WARN.YELLOW", "id"))
+ .setCustomId("warn")
+ .setStyle("SECONDARY"),
+ new MessageButton()
+ .setLabel("Mute")
+ .setEmoji(getEmojiByName("PUNISH.MUTE.YELLOW", "id"))
+ .setCustomId("mute")
+ .setStyle("SECONDARY"),
+ new MessageButton()
+ .setLabel("Nickname")
+ .setEmoji(getEmojiByName("PUNISH.NICKNAME.GREEN", "id"))
+ .setCustomId("nickname")
+ .setStyle("SECONDARY")
+ ]),
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setLabel("Kick")
+ .setEmoji(getEmojiByName("PUNISH.KICK.RED", "id"))
+ .setCustomId("kick")
+ .setStyle("SECONDARY"),
+ new MessageButton()
+ .setLabel("Softban")
+ .setEmoji(getEmojiByName("PUNISH.BAN.YELLOW", "id"))
+ .setCustomId("softban")
+ .setStyle("SECONDARY"),
+ new MessageButton()
+ .setLabel("Ban")
+ .setEmoji(getEmojiByName("PUNISH.BAN.RED", "id"))
+ .setCustomId("ban")
+ .setStyle("SECONDARY")
+ ]),
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setLabel(
+ clicked === "clearMuteRole"
+ ? "Click again to confirm"
+ : "Clear mute role"
+ )
+ .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
+ .setCustomId("clearMuteRole")
+ .setStyle("DANGER")
+ .setDisabled(!moderation.mute.role),
+ new MessageButton()
+ .setCustomId("timeout")
+ .setLabel(
+ "Mute timeout " +
+ (moderation.mute.timeout
+ ? "Enabled"
+ : "Disabled")
+ )
+ .setStyle(
+ moderation.mute.timeout ? "SUCCESS" : "DANGER"
+ )
+ .setEmoji(
+ getEmojiByName(
+ "CONTROL." +
+ (moderation.mute.timeout
+ ? "TICK"
+ : "CROSS"),
+ "id"
+ )
+ )
+ ])
+ ]
+ });
let i;
try {
i = await m.awaitMessageComponent({ time: 300000 });
- } catch (e) { return; }
- let chosen = moderation[i.customId] ?? {text: null, url: null};
+ } catch (e) {
+ return;
+ }
+ let chosen = moderation[i.customId] ?? { text: null, url: null };
if (i.component.customId === "clearMuteRole") {
i.deferUpdate();
if (clicked === "clearMuteRole") {
- await client.database.guilds.write(interaction.guild.id, {"moderation.mute.role": null });
- } else { clicked = "clearMuteRole"; }
+ await client.database.guilds.write(interaction.guild.id, {
+ "moderation.mute.role": null
+ });
+ } else {
+ clicked = "clearMuteRole";
+ }
continue;
- } else { clicked = ""; }
+ } else {
+ clicked = "";
+ }
if (i.component.customId === "timeout") {
await i.deferUpdate();
- await client.database.guilds.write(interaction.guild.id, {"moderation.mute.timeout": !moderation.mute.timeout } );
+ await client.database.guilds.write(interaction.guild.id, {
+ "moderation.mute.timeout": !moderation.mute.timeout
+ });
continue;
} else if (i.customId) {
- await i.showModal(new Discord.Modal().setCustomId("modal").setTitle(`Options for ${i.customId}`).addComponents(
- new MessageActionRow<TextInputComponent>().addComponents(new TextInputComponent()
- .setCustomId("name")
- .setLabel("Button text")
- .setMaxLength(100)
- .setRequired(false)
- .setStyle("SHORT")
- .setValue(chosen.text ?? "")
- ),
- new MessageActionRow<TextInputComponent>().addComponents(new TextInputComponent()
- .setCustomId("url")
- .setLabel("URL - Type {id} to insert the user's ID")
- .setMaxLength(2000)
- .setRequired(false)
- .setStyle("SHORT")
- .setValue(chosen.link ?? "")
- )
- ));
+ await i.showModal(
+ new Discord.Modal()
+ .setCustomId("modal")
+ .setTitle(`Options for ${i.customId}`)
+ .addComponents(
+ new MessageActionRow<TextInputComponent>().addComponents(
+ new TextInputComponent()
+ .setCustomId("name")
+ .setLabel("Button text")
+ .setMaxLength(100)
+ .setRequired(false)
+ .setStyle("SHORT")
+ .setValue(chosen.text ?? "")
+ ),
+ new MessageActionRow<TextInputComponent>().addComponents(
+ new TextInputComponent()
+ .setCustomId("url")
+ .setLabel(
+ "URL - Type {id} to insert the user's ID"
+ )
+ .setMaxLength(2000)
+ .setRequired(false)
+ .setStyle("SHORT")
+ .setValue(chosen.link ?? "")
+ )
+ )
+ );
await interaction.editReply({
- embeds: [new EmojiEmbed()
- .setTitle("Moderation Links")
- .setDescription("Modal opened. If you can't see it, click back and try again.")
- .setStatus("Success")
- .setEmoji("GUILD.TICKET.OPEN")
- ], components: [new MessageActionRow().addComponents([new MessageButton()
- .setLabel("Back")
- .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
- .setStyle("PRIMARY")
- .setCustomId("back")
- ])]
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Moderation Links")
+ .setDescription(
+ "Modal opened. If you can't see it, click back and try again."
+ )
+ .setStatus("Success")
+ .setEmoji("GUILD.TICKET.OPEN")
+ ],
+ components: [
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setLabel("Back")
+ .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
+ .setStyle("PRIMARY")
+ .setCustomId("back")
+ ])
+ ]
});
let out;
try {
- out = await modalInteractionCollector(m, (m) => m.channel.id === interaction.channel.id, (_) => true);
- } catch (e) { continue; }
+ out = await modalInteractionCollector(
+ m,
+ (m) => m.channel.id === interaction.channel.id,
+ (_) => true
+ );
+ } catch (e) {
+ continue;
+ }
if (out.fields) {
const buttonText = out.fields.getTextInputValue("name");
- const buttonLink = out.fields.getTextInputValue("url").replace(/{id}/gi, "{id}");
+ const buttonLink = out.fields
+ .getTextInputValue("url")
+ .replace(/{id}/gi, "{id}");
const current = chosen;
- if (current.text !== buttonText || current.link !== buttonLink) {
+ if (
+ current.text !== buttonText ||
+ current.link !== buttonLink
+ ) {
chosen = { text: buttonText, link: buttonLink };
- await client.database.guilds.write(interaction.guild.id, { ["moderation." + i.customId]: { text: buttonText, link: buttonLink }});
+ await client.database.guilds.write(interaction.guild.id, {
+ ["moderation." + i.customId]: {
+ text: buttonText,
+ link: buttonLink
+ }
+ });
}
- } else { continue; }
+ } else {
+ continue;
+ }
}
}
};
-
-const check = (interaction: CommandInteraction, _defaultCheck: WrappedCheck) => {
- const member = (interaction.member as Discord.GuildMember);
- if (!member.permissions.has("MANAGE_GUILD")) throw "You must have the *Manage Server* permission to use this command";
+const check = (
+ interaction: CommandInteraction,
+ _defaultCheck: WrappedCheck
+) => {
+ const member = interaction.member as Discord.GuildMember;
+ if (!member.permissions.has("MANAGE_GUILD"))
+ throw "You must have the *Manage Server* permission to use this command";
return true;
};
export { command };
export { callback };
-export { check };
\ No newline at end of file
+export { check };
diff --git a/src/commands/settings/filters.ts b/src/commands/settings/filters.ts
index 7ee5b8d..3b0988e 100644
--- a/src/commands/settings/filters.ts
+++ b/src/commands/settings/filters.ts
@@ -2,20 +2,19 @@
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
const command = (builder: SlashCommandSubcommandBuilder) =>
- builder
- .setName("filter")
- .setDescription("Setting for message filters");
+ builder.setName("filter").setDescription("Setting for message filters");
const callback = async (_interaction: CommandInteraction): Promise<void> => {
console.log("Filters");
};
const check = (interaction: CommandInteraction) => {
- const member = (interaction.member as Discord.GuildMember);
- if (!member.permissions.has("MANAGE_MESSAGES")) throw "You must have the *Manage Messages* permission to use this command";
+ const member = interaction.member as Discord.GuildMember;
+ if (!member.permissions.has("MANAGE_MESSAGES"))
+ throw "You must have the *Manage Messages* permission to use this command";
return true;
};
export { command };
export { callback };
-export { check };
\ No newline at end of file
+export { check };
diff --git a/src/commands/settings/logs/_meta.ts b/src/commands/settings/logs/_meta.ts
index f46987f..fadff33 100644
--- a/src/commands/settings/logs/_meta.ts
+++ b/src/commands/settings/logs/_meta.ts
@@ -1,4 +1,4 @@
const name = "logs";
const description = "Settings for logging";
-export { name, description };
\ No newline at end of file
+export { name, description };
diff --git a/src/commands/settings/logs/attachment.ts b/src/commands/settings/logs/attachment.ts
index cb96567..f37bd1a 100644
--- a/src/commands/settings/logs/attachment.ts
+++ b/src/commands/settings/logs/attachment.ts
@@ -1,6 +1,10 @@
import { LoadingEmbed } from "./../../../utils/defaultEmbeds.js";
import { ChannelType } from "discord-api-types";
-import Discord, { CommandInteraction, MessageActionRow, MessageButton } from "discord.js";
+import Discord, {
+ CommandInteraction,
+ MessageActionRow,
+ MessageButton
+} from "discord.js";
import EmojiEmbed from "../../../utils/generateEmojiEmbed.js";
import confirmationMessage from "../../../utils/confirmationMessage.js";
import getEmojiByName from "../../../utils/getEmojiByName.js";
@@ -12,39 +16,59 @@
builder
.setName("attachments")
.setDescription("Where attachments should be logged to (Premium only)")
- .addChannelOption(option => option.setName("channel").setDescription("The channel to log attachments in").addChannelTypes([
- ChannelType.GuildNews, ChannelType.GuildText
- ]).setRequired(false));
+ .addChannelOption((option) =>
+ option
+ .setName("channel")
+ .setDescription("The channel to log attachments in")
+ .addChannelTypes([ChannelType.GuildNews, ChannelType.GuildText])
+ .setRequired(false)
+ );
-const callback = async (interaction: CommandInteraction): Promise<void | unknown> => {
- const m = await interaction.reply({embeds: LoadingEmbed, ephemeral: true, fetchReply: true}) as Discord.Message;
+const callback = async (
+ interaction: CommandInteraction
+): Promise<void | unknown> => {
+ const m = (await interaction.reply({
+ embeds: LoadingEmbed,
+ ephemeral: true,
+ fetchReply: true
+ })) as Discord.Message;
if (interaction.options.getChannel("channel")) {
let channel;
try {
channel = interaction.options.getChannel("channel");
} catch {
- return await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("CHANNEL.TEXT.DELETE")
- .setTitle("Attachment Log Channel")
- .setDescription("The channel you provided is not a valid channel")
- .setStatus("Danger")
- ]});
+ return await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("CHANNEL.TEXT.DELETE")
+ .setTitle("Attachment Log Channel")
+ .setDescription(
+ "The channel you provided is not a valid channel"
+ )
+ .setStatus("Danger")
+ ]
+ });
}
channel = channel as Discord.TextChannel;
if (channel.guild.id !== interaction.guild.id) {
- return interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Attachment Log Channel")
- .setDescription("You must choose a channel in this server")
- .setStatus("Danger")
- .setEmoji("CHANNEL.TEXT.DELETE")
- ]});
+ return interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Attachment Log Channel")
+ .setDescription(
+ "You must choose a channel in this server"
+ )
+ .setStatus("Danger")
+ .setEmoji("CHANNEL.TEXT.DELETE")
+ ]
+ });
}
const confirmation = await new confirmationMessage(interaction)
.setEmoji("CHANNEL.TEXT.EDIT")
.setTitle("Attachment Log Channel")
.setDescription(
"This will be the channel all attachments will be sent to.\n\n" +
- `Are you sure you want to set the attachment log channel to <#${channel.id}>?`
+ `Are you sure you want to set the attachment log channel to <#${channel.id}>?`
)
.setColor("Warning")
.setInverted(true)
@@ -52,10 +76,13 @@
if (confirmation.cancelled) return;
if (confirmation.success) {
try {
- await client.database.guilds.write(interaction.guild.id, {"logging.attachments.channel": channel.id});
- const { log, NucleusColors, entry, renderUser, renderChannel } = client.logger;
+ await client.database.guilds.write(interaction.guild.id, {
+ "logging.attachments.channel": channel.id
+ });
+ const { log, NucleusColors, entry, renderUser, renderChannel } =
+ client.logger;
const data = {
- meta:{
+ meta: {
type: "attachmentChannelUpdate",
displayName: "Attachment Log Channel Updated",
calculateType: "nucleusSettingsUpdated",
@@ -64,8 +91,14 @@
timestamp: new Date().getTime()
},
list: {
- memberId: entry(interaction.user.id, `\`${interaction.user.id}\``),
- changedBy: entry(interaction.user.id, renderUser(interaction.user)),
+ memberId: entry(
+ interaction.user.id,
+ `\`${interaction.user.id}\``
+ ),
+ changedBy: entry(
+ interaction.user.id,
+ renderUser(interaction.user)
+ ),
channel: entry(channel.id, renderChannel(channel))
},
hidden: {
@@ -74,75 +107,124 @@
};
log(data);
} catch (e) {
- return interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Attachment Log Channel")
- .setDescription("Something went wrong and the attachment log channel could not be set")
- .setStatus("Danger")
- .setEmoji("CHANNEL.TEXT.DELETE")
- ], components: []});
+ return interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Attachment Log Channel")
+ .setDescription(
+ "Something went wrong and the attachment log channel could not be set"
+ )
+ .setStatus("Danger")
+ .setEmoji("CHANNEL.TEXT.DELETE")
+ ],
+ components: []
+ });
}
} else {
- return interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Attachment Log Channel")
- .setDescription("No changes were made")
- .setStatus("Success")
- .setEmoji("CHANNEL.TEXT.CREATE")
- ], components: []});
+ return interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Attachment Log Channel")
+ .setDescription("No changes were made")
+ .setStatus("Success")
+ .setEmoji("CHANNEL.TEXT.CREATE")
+ ],
+ components: []
+ });
}
}
let clicks = 0;
const data = await client.database.guilds.read(interaction.guild.id);
let channel = data.logging.staff.channel;
while (true) {
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Attachment Log Channel")
- .setDescription(
- channel ? `Your attachment log channel is currently set to <#${channel}>` : "This server does not have an attachment log channel" +
- (client.database.premium.hasPremium(interaction.guild.id) ? "" : "\n\nThis server does not have premium, so this feature is disabled")
- )
- .setStatus("Success")
- .setEmoji("CHANNEL.TEXT.CREATE")
- ], components: [new MessageActionRow().addComponents([new MessageButton()
- .setCustomId("clear")
- .setLabel(clicks ? "Click again to confirm" : "Reset channel")
- .setEmoji(getEmojiByName(clicks ? "TICKETS.ISSUE" : "CONTROL.CROSS", "id"))
- .setStyle("DANGER")
- .setDisabled(!channel)
- ])]});
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Attachment Log Channel")
+ .setDescription(
+ channel
+ ? `Your attachment log channel is currently set to <#${channel}>`
+ : "This server does not have an attachment log channel" +
+ (client.database.premium.hasPremium(
+ interaction.guild.id
+ )
+ ? ""
+ : "\n\nThis server does not have premium, so this feature is disabled")
+ )
+ .setStatus("Success")
+ .setEmoji("CHANNEL.TEXT.CREATE")
+ ],
+ components: [
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setCustomId("clear")
+ .setLabel(
+ clicks ? "Click again to confirm" : "Reset channel"
+ )
+ .setEmoji(
+ getEmojiByName(
+ clicks ? "TICKETS.ISSUE" : "CONTROL.CROSS",
+ "id"
+ )
+ )
+ .setStyle("DANGER")
+ .setDisabled(!channel)
+ ])
+ ]
+ });
let i;
try {
- i = await m.awaitMessageComponent({time: 300000});
- } catch(e) { break; }
+ i = await m.awaitMessageComponent({ time: 300000 });
+ } catch (e) {
+ break;
+ }
i.deferUpdate();
if (i.component.customId === "clear") {
clicks += 1;
if (clicks === 2) {
clicks = 0;
- await client.database.guilds.write(interaction.guild.id, null, ["logging.announcements.channel"]);
+ await client.database.guilds.write(interaction.guild.id, null, [
+ "logging.announcements.channel"
+ ]);
channel = undefined;
}
} else {
break;
}
}
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Attachment Log Channel")
- .setDescription(channel ? `Your attachment log channel is currently set to <#${channel}>` : "This server does not have an attachment log channel")
- .setStatus("Success")
- .setEmoji("CHANNEL.TEXT.CREATE")
- .setFooter({text: "Message closed"})
- ], components: [new MessageActionRow().addComponents([new MessageButton()
- .setCustomId("clear")
- .setLabel("Clear")
- .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
- .setStyle("SECONDARY")
- .setDisabled(true)
- ])]});
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Attachment Log Channel")
+ .setDescription(
+ channel
+ ? `Your attachment log channel is currently set to <#${channel}>`
+ : "This server does not have an attachment log channel"
+ )
+ .setStatus("Success")
+ .setEmoji("CHANNEL.TEXT.CREATE")
+ .setFooter({ text: "Message closed" })
+ ],
+ components: [
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setCustomId("clear")
+ .setLabel("Clear")
+ .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
+ .setStyle("SECONDARY")
+ .setDisabled(true)
+ ])
+ ]
+ });
};
-const check = (interaction: CommandInteraction, _defaultCheck: WrappedCheck) => {
- const member = (interaction.member as Discord.GuildMember);
- if (!member.permissions.has("MANAGE_GUILD")) throw "You must have the *Manage Server* permission to use this command";
+const check = (
+ interaction: CommandInteraction,
+ _defaultCheck: WrappedCheck
+) => {
+ const member = interaction.member as Discord.GuildMember;
+ if (!member.permissions.has("MANAGE_GUILD"))
+ throw "You must have the *Manage Server* permission to use this command";
return true;
};
diff --git a/src/commands/settings/logs/channel.ts b/src/commands/settings/logs/channel.ts
index 4d4a392..00d2411 100644
--- a/src/commands/settings/logs/channel.ts
+++ b/src/commands/settings/logs/channel.ts
@@ -1,6 +1,10 @@
import { LoadingEmbed } from "./../../../utils/defaultEmbeds.js";
import { ChannelType } from "discord-api-types";
-import Discord, { CommandInteraction, MessageActionRow, MessageButton } from "discord.js";
+import Discord, {
+ CommandInteraction,
+ MessageActionRow,
+ MessageButton
+} from "discord.js";
import EmojiEmbed from "../../../utils/generateEmojiEmbed.js";
import confirmationMessage from "../../../utils/confirmationMessage.js";
import getEmojiByName from "../../../utils/getEmojiByName.js";
@@ -12,47 +16,71 @@
builder
.setName("channel")
.setDescription("Sets or shows the log channel")
- .addChannelOption(option => option.setName("channel").setDescription("The channel to set the log channel to").addChannelTypes([
- ChannelType.GuildNews, ChannelType.GuildText
- ]));
+ .addChannelOption((option) =>
+ option
+ .setName("channel")
+ .setDescription("The channel to set the log channel to")
+ .addChannelTypes([ChannelType.GuildNews, ChannelType.GuildText])
+ );
-const callback = async (interaction: CommandInteraction): Promise<void | unknown> => {
- const m = await interaction.reply({embeds: LoadingEmbed, ephemeral: true, fetchReply: true}) as Discord.Message;
+const callback = async (
+ interaction: CommandInteraction
+): Promise<void | unknown> => {
+ const m = (await interaction.reply({
+ embeds: LoadingEmbed,
+ ephemeral: true,
+ fetchReply: true
+ })) as Discord.Message;
if (interaction.options.getChannel("channel")) {
let channel;
try {
channel = interaction.options.getChannel("channel");
} catch {
- return await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("CHANNEL.TEXT.DELETE")
- .setTitle("Log Channel")
- .setDescription("The channel you provided is not a valid channel")
- .setStatus("Danger")
- ]});
+ return await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("CHANNEL.TEXT.DELETE")
+ .setTitle("Log Channel")
+ .setDescription(
+ "The channel you provided is not a valid channel"
+ )
+ .setStatus("Danger")
+ ]
+ });
}
channel = channel as Discord.TextChannel;
if (channel.guild.id !== interaction.guild.id) {
- return interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Log Channel")
- .setDescription("You must choose a channel in this server")
- .setStatus("Danger")
- .setEmoji("CHANNEL.TEXT.DELETE")
- ]});
+ return interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Log Channel")
+ .setDescription(
+ "You must choose a channel in this server"
+ )
+ .setStatus("Danger")
+ .setEmoji("CHANNEL.TEXT.DELETE")
+ ]
+ });
}
const confirmation = await new confirmationMessage(interaction)
.setEmoji("CHANNEL.TEXT.EDIT")
.setTitle("Log Channel")
- .setDescription(`Are you sure you want to set the log channel to <#${channel.id}>?`)
+ .setDescription(
+ `Are you sure you want to set the log channel to <#${channel.id}>?`
+ )
.setColor("Warning")
.setInverted(true)
.send(true);
if (confirmation.cancelled) return;
if (confirmation.success) {
try {
- await client.database.guilds.write(interaction.guild.id, {"logging.logs.channel": channel.id});
- const { log, NucleusColors, entry, renderUser, renderChannel } = client.logger;
+ await client.database.guilds.write(interaction.guild.id, {
+ "logging.logs.channel": channel.id
+ });
+ const { log, NucleusColors, entry, renderUser, renderChannel } =
+ client.logger;
const data = {
- meta:{
+ meta: {
type: "logChannelUpdate",
displayName: "Log Channel Changed",
calculateType: "nucleusSettingsUpdated",
@@ -61,8 +89,14 @@
timestamp: new Date().getTime()
},
list: {
- memberId: entry(interaction.user.id, `\`${interaction.user.id}\``),
- changedBy: entry(interaction.user.id, renderUser(interaction.user)),
+ memberId: entry(
+ interaction.user.id,
+ `\`${interaction.user.id}\``
+ ),
+ changedBy: entry(
+ interaction.user.id,
+ renderUser(interaction.user)
+ ),
channel: entry(channel.id, renderChannel(channel))
},
hidden: {
@@ -72,72 +106,119 @@
log(data);
} catch (e) {
console.log(e);
- return interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Log Channel")
- .setDescription("Something went wrong and the log channel could not be set")
- .setStatus("Danger")
- .setEmoji("CHANNEL.TEXT.DELETE")
- ], components: []});
+ return interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Log Channel")
+ .setDescription(
+ "Something went wrong and the log channel could not be set"
+ )
+ .setStatus("Danger")
+ .setEmoji("CHANNEL.TEXT.DELETE")
+ ],
+ components: []
+ });
}
} else {
- return interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Log Channel")
- .setDescription("No changes were made")
- .setStatus("Success")
- .setEmoji("CHANNEL.TEXT.CREATE")
- ], components: []});
+ return interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Log Channel")
+ .setDescription("No changes were made")
+ .setStatus("Success")
+ .setEmoji("CHANNEL.TEXT.CREATE")
+ ],
+ components: []
+ });
}
}
let clicks = 0;
const data = await client.database.guilds.read(interaction.guild.id);
let channel = data.logging.logs.channel;
while (true) {
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Log channel")
- .setDescription(channel ? `Your log channel is currently set to <#${channel}>` : "This server does not have a log channel")
- .setStatus("Success")
- .setEmoji("CHANNEL.TEXT.CREATE")
- ], components: [new MessageActionRow().addComponents([new MessageButton()
- .setCustomId("clear")
- .setLabel(clicks ? "Click again to confirm" : "Reset channel")
- .setEmoji(getEmojiByName(clicks ? "TICKETS.ISSUE" : "CONTROL.CROSS", "id"))
- .setStyle("DANGER")
- .setDisabled(!channel)
- ])]});
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Log channel")
+ .setDescription(
+ channel
+ ? `Your log channel is currently set to <#${channel}>`
+ : "This server does not have a log channel"
+ )
+ .setStatus("Success")
+ .setEmoji("CHANNEL.TEXT.CREATE")
+ ],
+ components: [
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setCustomId("clear")
+ .setLabel(
+ clicks ? "Click again to confirm" : "Reset channel"
+ )
+ .setEmoji(
+ getEmojiByName(
+ clicks ? "TICKETS.ISSUE" : "CONTROL.CROSS",
+ "id"
+ )
+ )
+ .setStyle("DANGER")
+ .setDisabled(!channel)
+ ])
+ ]
+ });
let i;
try {
- i = await m.awaitMessageComponent({time: 300000});
- } catch(e) { break; }
+ i = await m.awaitMessageComponent({ time: 300000 });
+ } catch (e) {
+ break;
+ }
i.deferUpdate();
if (i.component.customId === "clear") {
clicks += 1;
if (clicks === 2) {
clicks = 0;
- await client.database.guilds.write(interaction.guild.id, null, ["logging.logs.channel"]);
+ await client.database.guilds.write(interaction.guild.id, null, [
+ "logging.logs.channel"
+ ]);
channel = undefined;
}
} else {
break;
}
}
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Log channel")
- .setDescription(channel ? `Your log channel is currently set to <#${channel}>` : "This server does not have a log channel")
- .setStatus("Success")
- .setEmoji("CHANNEL.TEXT.CREATE")
- .setFooter({text: "Message closed"})
- ], components: [new MessageActionRow().addComponents([new MessageButton()
- .setCustomId("clear")
- .setLabel("Clear")
- .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
- .setStyle("SECONDARY")
- .setDisabled(true)
- ])]});
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Log channel")
+ .setDescription(
+ channel
+ ? `Your log channel is currently set to <#${channel}>`
+ : "This server does not have a log channel"
+ )
+ .setStatus("Success")
+ .setEmoji("CHANNEL.TEXT.CREATE")
+ .setFooter({ text: "Message closed" })
+ ],
+ components: [
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setCustomId("clear")
+ .setLabel("Clear")
+ .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
+ .setStyle("SECONDARY")
+ .setDisabled(true)
+ ])
+ ]
+ });
};
-const check = (interaction: CommandInteraction, _defaultCheck: WrappedCheck) => {
- const member = (interaction.member as Discord.GuildMember);
- if (!member.permissions.has("MANAGE_GUILD")) throw "You must have the *Manage Server* permission to use this command";
+const check = (
+ interaction: CommandInteraction,
+ _defaultCheck: WrappedCheck
+) => {
+ const member = interaction.member as Discord.GuildMember;
+ if (!member.permissions.has("MANAGE_GUILD"))
+ throw "You must have the *Manage Server* permission to use this command";
return true;
};
diff --git a/src/commands/settings/logs/events.ts b/src/commands/settings/logs/events.ts
index 110c70e..a1edcaf 100644
--- a/src/commands/settings/logs/events.ts
+++ b/src/commands/settings/logs/events.ts
@@ -1,33 +1,37 @@
import { LoadingEmbed } from "./../../../utils/defaultEmbeds.js";
-import Discord, { CommandInteraction, MessageActionRow, MessageButton, MessageSelectMenu } from "discord.js";
+import Discord, {
+ CommandInteraction,
+ MessageActionRow,
+ MessageButton,
+ MessageSelectMenu
+} from "discord.js";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import { WrappedCheck } from "jshaiku";
import EmojiEmbed from "../../../utils/generateEmojiEmbed.js";
import client from "../../../utils/client.js";
import { toHexArray, toHexInteger } from "../../../utils/calculate.js";
-
const logs = {
- "channelUpdate": "Channels created, deleted or modified",
- "emojiUpdate": "Server emojis modified",
- "stickerUpdate": "Server stickers modified",
- "guildUpdate": "Server settings updated",
- "guildMemberUpdate": "Member updated (i.e. nickname)",
- "guildMemberPunish": "Members punished (i.e. muted, banned, kicked)",
- "guildRoleUpdate": "Role settings changed",
- "guildInviteUpdate": "Server invite created or deleted",
- "messageUpdate": "Message edited",
- "messageDelete": "Message deleted",
- "messageDeleteBulk": "Messages purged",
- "messageReactionUpdate": "Message reactions cleared",
- "messageMassPing": "Message pings multiple members at once",
- "messageAnnounce": "Message published in announcement channel",
- "threadUpdate": "Thread created or deleted",
- "webhookUpdate": "Webhooks created or deleted",
- "guildMemberVerify": "Member runs verify",
- "autoModeratorDeleted": "Messages auto deleted by Nucleus",
- "nucleusSettingsUpdated": "Nucleus' settings updated by a moderator",
- "ticketUpdate": "Tickets created or deleted"
+ channelUpdate: "Channels created, deleted or modified",
+ emojiUpdate: "Server emojis modified",
+ stickerUpdate: "Server stickers modified",
+ guildUpdate: "Server settings updated",
+ guildMemberUpdate: "Member updated (i.e. nickname)",
+ guildMemberPunish: "Members punished (i.e. muted, banned, kicked)",
+ guildRoleUpdate: "Role settings changed",
+ guildInviteUpdate: "Server invite created or deleted",
+ messageUpdate: "Message edited",
+ messageDelete: "Message deleted",
+ messageDeleteBulk: "Messages purged",
+ messageReactionUpdate: "Message reactions cleared",
+ messageMassPing: "Message pings multiple members at once",
+ messageAnnounce: "Message published in announcement channel",
+ threadUpdate: "Thread created or deleted",
+ webhookUpdate: "Webhooks created or deleted",
+ guildMemberVerify: "Member runs verify",
+ autoModeratorDeleted: "Messages auto deleted by Nucleus",
+ nucleusSettingsUpdated: "Nucleus' settings updated by a moderator",
+ ticketUpdate: "Tickets created or deleted"
};
const command = (builder: SlashCommandSubcommandBuilder) =>
@@ -36,39 +40,52 @@
.setDescription("Sets what events should be logged");
const callback = async (interaction: CommandInteraction): Promise<void> => {
- await interaction.reply({embeds: LoadingEmbed, fetchReply: true, ephemeral: true});
+ await interaction.reply({
+ embeds: LoadingEmbed,
+ fetchReply: true,
+ ephemeral: true
+ });
let m;
while (true) {
const config = await client.database.guilds.read(interaction.guild.id);
const converted = toHexArray(config.logging.logs.toLog);
- m = await interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Logging Events")
- .setDescription("Below are the events being logged in the server. You can toggle them on and off in the dropdown")
- .setStatus("Success")
- .setEmoji("CHANNEL.TEXT.CREATE")
- ], components: [
- new MessageActionRow().addComponents([new MessageSelectMenu()
- .setPlaceholder("Set events to log")
- .setMaxValues(Object.keys(logs).length)
- .setCustomId("logs")
- .setMinValues(0)
- .setOptions(Object.keys(logs).map((e, i) => ({
- label: logs[e],
- value: i.toString(),
- default: converted.includes(e)
- })))
- ]),
- new MessageActionRow().addComponents([
- new MessageButton()
- .setLabel("Select all")
- .setStyle("PRIMARY")
- .setCustomId("all"),
- new MessageButton()
- .setLabel("Select none")
- .setStyle("DANGER")
- .setCustomId("none")
- ])
- ]});
+ m = await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Logging Events")
+ .setDescription(
+ "Below are the events being logged in the server. You can toggle them on and off in the dropdown"
+ )
+ .setStatus("Success")
+ .setEmoji("CHANNEL.TEXT.CREATE")
+ ],
+ components: [
+ new MessageActionRow().addComponents([
+ new MessageSelectMenu()
+ .setPlaceholder("Set events to log")
+ .setMaxValues(Object.keys(logs).length)
+ .setCustomId("logs")
+ .setMinValues(0)
+ .setOptions(
+ Object.keys(logs).map((e, i) => ({
+ label: logs[e],
+ value: i.toString(),
+ default: converted.includes(e)
+ }))
+ )
+ ]),
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setLabel("Select all")
+ .setStyle("PRIMARY")
+ .setCustomId("all"),
+ new MessageButton()
+ .setLabel("Select none")
+ .setStyle("DANGER")
+ .setCustomId("none")
+ ])
+ ]
+ });
let i;
try {
i = await m.awaitMessageComponent({ time: 300000 });
@@ -78,33 +95,50 @@
i.deferUpdate();
if (i.customId === "logs") {
const selected = i.values;
- const newLogs = toHexInteger(selected.map(e => Object.keys(logs)[parseInt(e)]));
- await client.database.guilds.write(interaction.guild.id, {"logging.logs.toLog": newLogs});
+ const newLogs = toHexInteger(
+ selected.map((e) => Object.keys(logs)[parseInt(e)])
+ );
+ await client.database.guilds.write(interaction.guild.id, {
+ "logging.logs.toLog": newLogs
+ });
} else if (i.customId === "all") {
- const newLogs = toHexInteger(Object.keys(logs).map(e => e));
- await client.database.guilds.write(interaction.guild.id, {"logging.logs.toLog": newLogs});
+ const newLogs = toHexInteger(Object.keys(logs).map((e) => e));
+ await client.database.guilds.write(interaction.guild.id, {
+ "logging.logs.toLog": newLogs
+ });
} else if (i.customId === "none") {
- await client.database.guilds.write(interaction.guild.id, {"logging.logs.toLog": 0});
+ await client.database.guilds.write(interaction.guild.id, {
+ "logging.logs.toLog": 0
+ });
} else {
break;
}
}
- m = await interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Logging Events")
- .setDescription("Below are the events being logged in the server. You can toggle them on and off in the dropdown")
- .setFooter({text: "Message timed out"})
- .setStatus("Success")
- .setEmoji("CHANNEL.TEXT.CREATE")
- ]});
+ m = await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Logging Events")
+ .setDescription(
+ "Below are the events being logged in the server. You can toggle them on and off in the dropdown"
+ )
+ .setFooter({ text: "Message timed out" })
+ .setStatus("Success")
+ .setEmoji("CHANNEL.TEXT.CREATE")
+ ]
+ });
return;
};
-const check = (interaction: CommandInteraction, _defaultCheck: WrappedCheck) => {
- const member = (interaction.member as Discord.GuildMember);
- if (!member.permissions.has("MANAGE_GUILD")) throw "You must have the *Manage Server* permission to use this command";
+const check = (
+ interaction: CommandInteraction,
+ _defaultCheck: WrappedCheck
+) => {
+ const member = interaction.member as Discord.GuildMember;
+ if (!member.permissions.has("MANAGE_GUILD"))
+ throw "You must have the *Manage Server* permission to use this command";
return true;
};
export { command };
export { callback };
-export { check };
\ No newline at end of file
+export { check };
diff --git a/src/commands/settings/logs/staff.ts b/src/commands/settings/logs/staff.ts
index 2f0c819..718d13b 100644
--- a/src/commands/settings/logs/staff.ts
+++ b/src/commands/settings/logs/staff.ts
@@ -1,12 +1,16 @@
import { LoadingEmbed } from "./../../../utils/defaultEmbeds.js";
import { ChannelType } from "discord-api-types";
-import Discord, { CommandInteraction, MessageActionRow, MessageButton } from "discord.js";
+import Discord, {
+ CommandInteraction,
+ MessageActionRow,
+ MessageButton
+} from "discord.js";
import EmojiEmbed from "../../../utils/generateEmojiEmbed.js";
import confirmationMessage from "../../../utils/confirmationMessage.js";
import getEmojiByName from "../../../utils/getEmojiByName.js";
import type { SlashCommandSubcommandBuilder } from "@discordjs/builders";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
-// @ts-ignore
+// @ts-expect-error
import type { WrappedCheck } from "jshaiku";
import client from "../../../utils/client.js";
@@ -14,40 +18,62 @@
builder
.setName("staff")
.setDescription("Settings for the staff notifications channel")
- .addChannelOption(option => option.setName("channel").setDescription("The channel to set the staff notifications channel to").addChannelTypes([
- ChannelType.GuildNews, ChannelType.GuildText
- ]).setRequired(false));
+ .addChannelOption((option) =>
+ option
+ .setName("channel")
+ .setDescription(
+ "The channel to set the staff notifications channel to"
+ )
+ .addChannelTypes([ChannelType.GuildNews, ChannelType.GuildText])
+ .setRequired(false)
+ );
-const callback = async (interaction: CommandInteraction): Promise<unknown | void> => {
+const callback = async (
+ interaction: CommandInteraction
+): Promise<unknown | void> => {
if (!interaction.guild) return;
- const m = await interaction.reply({embeds: LoadingEmbed, ephemeral: true, fetchReply: true}) as Discord.Message<boolean>;
+ const m = (await interaction.reply({
+ embeds: LoadingEmbed,
+ ephemeral: true,
+ fetchReply: true
+ })) as Discord.Message;
if (interaction.options.getChannel("channel")) {
let channel;
try {
channel = interaction.options.getChannel("channel");
} catch {
- return await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("CHANNEL.TEXT.DELETE")
- .setTitle("Staff Notifications Channel")
- .setDescription("The channel you provided is not a valid channel")
- .setStatus("Danger")
- ]});
+ return await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("CHANNEL.TEXT.DELETE")
+ .setTitle("Staff Notifications Channel")
+ .setDescription(
+ "The channel you provided is not a valid channel"
+ )
+ .setStatus("Danger")
+ ]
+ });
}
channel = channel as Discord.TextChannel;
if (channel.guild.id !== interaction.guild.id) {
- return interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Staff Notifications Channel")
- .setDescription("You must choose a channel in this server")
- .setStatus("Danger")
- .setEmoji("CHANNEL.TEXT.DELETE")
- ]});
+ return interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Staff Notifications Channel")
+ .setDescription(
+ "You must choose a channel in this server"
+ )
+ .setStatus("Danger")
+ .setEmoji("CHANNEL.TEXT.DELETE")
+ ]
+ });
}
const confirmation = await new confirmationMessage(interaction)
.setEmoji("CHANNEL.TEXT.EDIT")
.setTitle("Staff Notifications Channel")
.setDescription(
"This will be the channel all notifications, updates, user reports etc. will be sent to.\n\n" +
- `Are you sure you want to set the staff notifications channel to <#${channel.id}>?`
+ `Are you sure you want to set the staff notifications channel to <#${channel.id}>?`
)
.setColor("Warning")
.setInverted(true)
@@ -55,10 +81,13 @@
if (confirmation.cancelled) return;
if (confirmation.success) {
try {
- await client.database.guilds.write(interaction.guild.id, {"logging.staff.channel": channel.id});
- const { log, NucleusColors, entry, renderUser, renderChannel } = client.logger;
+ await client.database.guilds.write(interaction.guild.id, {
+ "logging.staff.channel": channel.id
+ });
+ const { log, NucleusColors, entry, renderUser, renderChannel } =
+ client.logger;
const data = {
- meta:{
+ meta: {
type: "staffChannelUpdate",
displayName: "Staff Notifications Channel Updated",
calculateType: "nucleusSettingsUpdated",
@@ -67,8 +96,14 @@
timestamp: new Date().getTime()
},
list: {
- memberId: entry(interaction.user.id, `\`${interaction.user.id}\``),
- changedBy: entry(interaction.user.id, renderUser(interaction.user)),
+ memberId: entry(
+ interaction.user.id,
+ `\`${interaction.user.id}\``
+ ),
+ changedBy: entry(
+ interaction.user.id,
+ renderUser(interaction.user)
+ ),
channel: entry(channel.id, renderChannel(channel))
},
hidden: {
@@ -77,72 +112,119 @@
};
log(data);
} catch (e) {
- return interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Staff Notifications Channel")
- .setDescription("Something went wrong and the staff notifications channel could not be set")
- .setStatus("Danger")
- .setEmoji("CHANNEL.TEXT.DELETE")
- ], components: []});
+ return interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Staff Notifications Channel")
+ .setDescription(
+ "Something went wrong and the staff notifications channel could not be set"
+ )
+ .setStatus("Danger")
+ .setEmoji("CHANNEL.TEXT.DELETE")
+ ],
+ components: []
+ });
}
} else {
- return interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Staff Notifications Channel")
- .setDescription("No changes were made")
- .setStatus("Success")
- .setEmoji("CHANNEL.TEXT.CREATE")
- ], components: []});
+ return interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Staff Notifications Channel")
+ .setDescription("No changes were made")
+ .setStatus("Success")
+ .setEmoji("CHANNEL.TEXT.CREATE")
+ ],
+ components: []
+ });
}
}
let clicks = 0;
const data = await client.database.guilds.read(interaction.guild.id);
let channel = data.logging.staff.channel;
while (true) {
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Staff Notifications channel")
- .setDescription(channel ? `Your staff notifications channel is currently set to <#${channel}>` : "This server does not have a staff notifications channel")
- .setStatus("Success")
- .setEmoji("CHANNEL.TEXT.CREATE")
- ], components: [new MessageActionRow().addComponents([new MessageButton()
- .setCustomId("clear")
- .setLabel(clicks ? "Click again to confirm" : "Reset channel")
- .setEmoji(getEmojiByName(clicks ? "TICKETS.ISSUE" : "CONTROL.CROSS", "id"))
- .setStyle("DANGER")
- .setDisabled(!channel)
- ])]});
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Staff Notifications channel")
+ .setDescription(
+ channel
+ ? `Your staff notifications channel is currently set to <#${channel}>`
+ : "This server does not have a staff notifications channel"
+ )
+ .setStatus("Success")
+ .setEmoji("CHANNEL.TEXT.CREATE")
+ ],
+ components: [
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setCustomId("clear")
+ .setLabel(
+ clicks ? "Click again to confirm" : "Reset channel"
+ )
+ .setEmoji(
+ getEmojiByName(
+ clicks ? "TICKETS.ISSUE" : "CONTROL.CROSS",
+ "id"
+ )
+ )
+ .setStyle("DANGER")
+ .setDisabled(!channel)
+ ])
+ ]
+ });
let i;
try {
- i = await m.awaitMessageComponent({time: 300000});
- } catch(e) { break; }
+ i = await m.awaitMessageComponent({ time: 300000 });
+ } catch (e) {
+ break;
+ }
i.deferUpdate();
if ((i.component as MessageButton).customId === "clear") {
clicks += 1;
if (clicks === 2) {
clicks = 0;
- await client.database.guilds.write(interaction.guild.id, null, ["logging.staff.channel"]);
+ await client.database.guilds.write(interaction.guild.id, null, [
+ "logging.staff.channel"
+ ]);
channel = undefined;
}
} else {
break;
}
}
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Staff Notifications channel")
- .setDescription(channel ? `Your staff notifications channel is currently set to <#${channel}>` : "This server does not have a staff notifications channel")
- .setStatus("Success")
- .setEmoji("CHANNEL.TEXT.CREATE")
- .setFooter({text: "Message closed"})
- ], components: [new MessageActionRow().addComponents([new MessageButton()
- .setCustomId("clear")
- .setLabel("Clear")
- .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
- .setStyle("SECONDARY")
- .setDisabled(true)
- ])]});
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Staff Notifications channel")
+ .setDescription(
+ channel
+ ? `Your staff notifications channel is currently set to <#${channel}>`
+ : "This server does not have a staff notifications channel"
+ )
+ .setStatus("Success")
+ .setEmoji("CHANNEL.TEXT.CREATE")
+ .setFooter({ text: "Message closed" })
+ ],
+ components: [
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setCustomId("clear")
+ .setLabel("Clear")
+ .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
+ .setStyle("SECONDARY")
+ .setDisabled(true)
+ ])
+ ]
+ });
};
-const check = (interaction: CommandInteraction, _defaultCheck: WrappedCheck) => {
- const member = (interaction.member as Discord.GuildMember);
- if (!member.permissions.has("MANAGE_GUILD")) throw "You must have the *Manage Server* permission to use this command";
+const check = (
+ interaction: CommandInteraction,
+ _defaultCheck: WrappedCheck
+) => {
+ const member = interaction.member as Discord.GuildMember;
+ if (!member.permissions.has("MANAGE_GUILD"))
+ throw "You must have the *Manage Server* permission to use this command";
return true;
};
diff --git a/src/commands/settings/rolemenu.ts b/src/commands/settings/rolemenu.ts
index 9a4ceb0..beb2f35 100644
--- a/src/commands/settings/rolemenu.ts
+++ b/src/commands/settings/rolemenu.ts
@@ -5,20 +5,28 @@
const command = (builder: SlashCommandSubcommandBuilder) =>
builder
.setName("rolemenu")
- .setDescription("rolemenu")// TODO
- .addRoleOption(option => option.setName("role").setDescription("The role to give after verifying")); // FIXME FOR FUCK SAKE
+ .setDescription("rolemenu") // TODO
+ .addRoleOption((option) =>
+ option
+ .setName("role")
+ .setDescription("The role to give after verifying")
+ ); // FIXME FOR FUCK SAKE
const callback = async (interaction: CommandInteraction): Promise<void> => {
console.log("we changed the charger again because fuck you");
await interaction.reply("You're mum");
};
-const check = (interaction: CommandInteraction, _defaultCheck: WrappedCheck) => {
- const member = (interaction.member as Discord.GuildMember);
- if (!member.permissions.has("MANAGE_ROLES")) throw "You must have the *Manage Roles* permission to use this command";
+const check = (
+ interaction: CommandInteraction,
+ _defaultCheck: WrappedCheck
+) => {
+ const member = interaction.member as Discord.GuildMember;
+ if (!member.permissions.has("MANAGE_ROLES"))
+ throw "You must have the *Manage Roles* permission to use this command";
return true;
};
export { command };
export { callback };
-export { check };
\ No newline at end of file
+export { check };
diff --git a/src/commands/settings/stats.ts b/src/commands/settings/stats.ts
index 5a1affd..507e506 100644
--- a/src/commands/settings/stats.ts
+++ b/src/commands/settings/stats.ts
@@ -1,62 +1,112 @@
import { LoadingEmbed } from "./../../utils/defaultEmbeds.js";
-import Discord, { CommandInteraction, Message, MessageActionRow, MessageSelectMenu } from "discord.js";
+import Discord, {
+ CommandInteraction,
+ Message,
+ MessageActionRow,
+ MessageSelectMenu
+} from "discord.js";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import confirmationMessage from "../../utils/confirmationMessage.js";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import { WrappedCheck } from "jshaiku";
import client from "../../utils/client.js";
import convertCurlyBracketString from "../../utils/convertCurlyBracketString.js";
-import {callback as statsChannelAddCallback} from "../../reflex/statsChannelUpdate.js";
+import { callback as statsChannelAddCallback } from "../../reflex/statsChannelUpdate.js";
import singleNotify from "../../utils/singleNotify.js";
const command = (builder: SlashCommandSubcommandBuilder) =>
builder
.setName("stats")
- .setDescription("Controls channels which update when someone joins or leaves the server")
- .addChannelOption(option => option.setName("channel").setDescription("The channel to modify"))
- .addStringOption(option => option.setName("name").setDescription("The new channel name | Enter any text or use the extra variables like {memberCount}").setAutocomplete(true));
+ .setDescription(
+ "Controls channels which update when someone joins or leaves the server"
+ )
+ .addChannelOption((option) =>
+ option.setName("channel").setDescription("The channel to modify")
+ )
+ .addStringOption((option) =>
+ option
+ .setName("name")
+ .setDescription(
+ "The new channel name | Enter any text or use the extra variables like {memberCount}"
+ )
+ .setAutocomplete(true)
+ );
-const callback = async (interaction: CommandInteraction): Promise<void | unknown> => {
+const callback = async (
+ interaction: CommandInteraction
+): Promise<void | unknown> => {
singleNotify("statsChannelDeleted", interaction.guild.id, true);
- const m = await interaction.reply({embeds: LoadingEmbed, ephemeral: true, fetchReply: true}) as Message;
+ const m = (await interaction.reply({
+ embeds: LoadingEmbed,
+ ephemeral: true,
+ fetchReply: true
+ })) as Message;
let config = await client.database.guilds.read(interaction.guild.id);
if (interaction.options.getString("name")) {
let channel;
if (Object.keys(config.getKey("stats")).length >= 25) {
- return await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("CHANNEL.TEXT.DELETE")
- .setTitle("Stats Channel")
- .setDescription("You can only have 25 stats channels in a server")
- .setStatus("Danger")
- ]});
+ return await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("CHANNEL.TEXT.DELETE")
+ .setTitle("Stats Channel")
+ .setDescription(
+ "You can only have 25 stats channels in a server"
+ )
+ .setStatus("Danger")
+ ]
+ });
}
try {
channel = interaction.options.getChannel("channel");
} catch {
- return await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("CHANNEL.TEXT.DELETE")
- .setTitle("Stats Channel")
- .setDescription("The channel you provided is not a valid channel")
- .setStatus("Danger")
- ]});
+ return await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("CHANNEL.TEXT.DELETE")
+ .setTitle("Stats Channel")
+ .setDescription(
+ "The channel you provided is not a valid channel"
+ )
+ .setStatus("Danger")
+ ]
+ });
}
channel = channel as Discord.TextChannel;
if (channel.guild.id !== interaction.guild.id) {
- return interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Stats Channel")
- .setDescription("You must choose a channel in this server")
- .setStatus("Danger")
- .setEmoji("CHANNEL.TEXT.DELETE")
- ]});
+ return interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Stats Channel")
+ .setDescription(
+ "You must choose a channel in this server"
+ )
+ .setStatus("Danger")
+ .setEmoji("CHANNEL.TEXT.DELETE")
+ ]
+ });
}
- let newName = await convertCurlyBracketString(interaction.options.getString("name"), null, null, interaction.guild.name, interaction.guild.members);
+ let newName = await convertCurlyBracketString(
+ interaction.options.getString("name"),
+ null,
+ null,
+ interaction.guild.name,
+ interaction.guild.members
+ );
if (interaction.options.getChannel("channel").type === "GUILD_TEXT") {
newName = newName.toLowerCase().replace(/[\s]/g, "-");
}
const confirmation = await new confirmationMessage(interaction)
.setEmoji("CHANNEL.TEXT.EDIT")
.setTitle("Stats Channel")
- .setDescription(`Are you sure you want to set <#${channel.id}> to a stats channel?\n\n*Preview: ${newName.replace(/^ +| $/g, "")}*`)
+ .setDescription(
+ `Are you sure you want to set <#${
+ channel.id
+ }> to a stats channel?\n\n*Preview: ${newName.replace(
+ /^ +| $/g,
+ ""
+ )}*`
+ )
.setColor("Warning")
.setInverted(true)
.send(true);
@@ -65,10 +115,13 @@
try {
const name = interaction.options.getString("name");
const channel = interaction.options.getChannel("channel");
- await client.database.guilds.write(interaction.guild.id, {[`stats.${channel.id}`]: {name: name, enabled: true}});
- const { log, NucleusColors, entry, renderUser, renderChannel } = client.logger;
+ await client.database.guilds.write(interaction.guild.id, {
+ [`stats.${channel.id}`]: { name: name, enabled: true }
+ });
+ const { log, NucleusColors, entry, renderUser, renderChannel } =
+ client.logger;
const data = {
- meta:{
+ meta: {
type: "statsChannelUpdate",
displayName: "Stats Channel Updated",
calculateType: "nucleusSettingsUpdated",
@@ -77,10 +130,19 @@
timestamp: new Date().getTime()
},
list: {
- memberId: entry(interaction.user.id, `\`${interaction.user.id}\``),
- changedBy: entry(interaction.user.id, renderUser(interaction.user)),
+ memberId: entry(
+ interaction.user.id,
+ `\`${interaction.user.id}\``
+ ),
+ changedBy: entry(
+ interaction.user.id,
+ renderUser(interaction.user)
+ ),
channel: entry(channel.id, renderChannel(channel)),
- name: entry(interaction.options.getString("name"), `\`${interaction.options.getString("name")}\``)
+ name: entry(
+ interaction.options.getString("name"),
+ `\`${interaction.options.getString("name")}\``
+ )
},
hidden: {
guild: interaction.guild.id
@@ -89,20 +151,30 @@
log(data);
} catch (e) {
console.log(e);
- return interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Stats Channel")
- .setDescription("Something went wrong and the stats channel could not be set")
- .setStatus("Danger")
- .setEmoji("CHANNEL.TEXT.DELETE")
- ], components: []});
+ return interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Stats Channel")
+ .setDescription(
+ "Something went wrong and the stats channel could not be set"
+ )
+ .setStatus("Danger")
+ .setEmoji("CHANNEL.TEXT.DELETE")
+ ],
+ components: []
+ });
}
} else {
- return interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Stats Channel")
- .setDescription("No changes were made")
- .setStatus("Success")
- .setEmoji("CHANNEL.TEXT.CREATE")
- ], components: []});
+ return interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Stats Channel")
+ .setDescription("No changes were made")
+ .setStatus("Success")
+ .setEmoji("CHANNEL.TEXT.CREATE")
+ ],
+ components: []
+ });
}
await statsChannelAddCallback(client, interaction.member);
}
@@ -113,41 +185,83 @@
.setCustomId("remove")
.setMinValues(1)
.setMaxValues(Math.max(1, Object.keys(stats).length));
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Stats Channel")
- .setDescription("The following channels update when someone joins or leaves the server. You can select a channel to remove it from the list.")
- .setStatus("Success")
- .setEmoji("CHANNEL.TEXT.CREATE")
- ], components: [
- new MessageActionRow().addComponents(Object.keys(stats).length ? [
- selectMenu.setPlaceholder("Select a stats channel to remove, stopping it updating").addOptions(Object.keys(stats).map(key => ({
- label: interaction.guild.channels.cache.get(key).name,
- value: key,
- description: `${stats[key].name}`
- })))
- ] : [selectMenu.setPlaceholder("The server has no stats channels").setDisabled(true).setOptions([
- {label: "*Placeholder*", value: "placeholder", description: "No stats channels"}
- ])])
- ]});
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Stats Channel")
+ .setDescription(
+ "The following channels update when someone joins or leaves the server. You can select a channel to remove it from the list."
+ )
+ .setStatus("Success")
+ .setEmoji("CHANNEL.TEXT.CREATE")
+ ],
+ components: [
+ new MessageActionRow().addComponents(
+ Object.keys(stats).length
+ ? [
+ selectMenu
+ .setPlaceholder(
+ "Select a stats channel to remove, stopping it updating"
+ )
+ .addOptions(
+ Object.keys(stats).map((key) => ({
+ label: interaction.guild.channels.cache.get(
+ key
+ ).name,
+ value: key,
+ description: `${stats[key].name}`
+ }))
+ )
+ ]
+ : [
+ selectMenu
+ .setPlaceholder(
+ "The server has no stats channels"
+ )
+ .setDisabled(true)
+ .setOptions([
+ {
+ label: "*Placeholder*",
+ value: "placeholder",
+ description: "No stats channels"
+ }
+ ])
+ ]
+ )
+ ]
+ });
let i;
try {
i = await m.awaitMessageComponent({ time: 300000 });
- } catch (e) { break; }
+ } catch (e) {
+ break;
+ }
i.deferUpdate();
if (i.customId === "remove") {
const toRemove = i.values;
- await client.database.guilds.write(interaction.guild.id, null, toRemove.map(k => `stats.${k}`));
+ await client.database.guilds.write(
+ interaction.guild.id,
+ null,
+ toRemove.map((k) => `stats.${k}`)
+ );
}
}
- await interaction.editReply({embeds: [(m.embeds[0] as Discord.MessageEmbed).setFooter({text: "Message closed"})], components: []});
+ await interaction.editReply({
+ embeds: [m.embeds[0]!.setFooter({ text: "Message closed" })],
+ components: []
+ });
};
-const check = (interaction: CommandInteraction, _defaultCheck: WrappedCheck) => {
- const member = (interaction.member as Discord.GuildMember);
- if (!member.permissions.has("MANAGE_CHANNELS")) throw "You must have the *Manage Channels* permission to use this command";
+const check = (
+ interaction: CommandInteraction,
+ _defaultCheck: WrappedCheck
+) => {
+ const member = interaction.member as Discord.GuildMember;
+ if (!member.permissions.has("MANAGE_CHANNELS"))
+ throw "You must have the *Manage Channels* permission to use this command";
return true;
};
export { command };
export { callback };
-export { check };
\ No newline at end of file
+export { check };
diff --git a/src/commands/settings/tickets.ts b/src/commands/settings/tickets.ts
index f9df71c..5e5cbe7 100644
--- a/src/commands/settings/tickets.ts
+++ b/src/commands/settings/tickets.ts
@@ -2,103 +2,198 @@
import getEmojiByName from "../../utils/getEmojiByName.js";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import confirmationMessage from "../../utils/confirmationMessage.js";
-import Discord, { CommandInteraction, GuildChannel, Message, MessageActionRow, MessageActionRowComponent, MessageButton, MessageComponentInteraction, MessageSelectMenu, Role, SelectMenuInteraction, TextInputComponent } from "discord.js";
-import { SelectMenuOption, SlashCommandSubcommandBuilder } from "@discordjs/builders";
+import Discord, {
+ CommandInteraction,
+ GuildChannel,
+ Message,
+ MessageActionRow,
+ MessageActionRowComponent,
+ MessageButton,
+ MessageComponentInteraction,
+ MessageSelectMenu,
+ Role,
+ SelectMenuInteraction,
+ TextInputComponent
+} from "discord.js";
+import {
+ SelectMenuOption,
+ SlashCommandSubcommandBuilder
+} from "@discordjs/builders";
import { ChannelType } from "discord-api-types";
import client from "../../utils/client.js";
-import { toHexInteger, toHexArray, tickets as ticketTypes } from "../../utils/calculate.js";
+import {
+ toHexInteger,
+ toHexArray,
+ tickets as ticketTypes
+} from "../../utils/calculate.js";
import { capitalize } from "../../utils/generateKeyValueList.js";
import { modalInteractionCollector } from "../../utils/dualCollector.js";
-import {GuildConfig} from "../../utils/database.js";
+import { GuildConfig } from "../../utils/database.js";
-const command = (builder: SlashCommandSubcommandBuilder) => builder
- .setName("tickets")
- .setDescription("Shows settings for tickets | Use no arguments to manage custom types")
- .addStringOption(option => option.setName("enabled").setDescription("If users should be able to create tickets").setRequired(false)
- .addChoices([["Yes", "yes"], ["No", "no"]]))
- .addChannelOption(option => option.setName("category").setDescription("The category where tickets are created").addChannelType(ChannelType.GuildCategory).setRequired(false))
- .addNumberOption(option => option.setName("maxticketsperuser").setDescription("The maximum amount of tickets a user can create | Default: 5").setRequired(false).setMinValue(1))
- .addRoleOption(option => option.setName("supportrole").setDescription("This role will have view access to all tickets and will be pinged when a ticket is created").setRequired(false));
+const command = (builder: SlashCommandSubcommandBuilder) =>
+ builder
+ .setName("tickets")
+ .setDescription(
+ "Shows settings for tickets | Use no arguments to manage custom types"
+ )
+ .addStringOption((option) =>
+ option
+ .setName("enabled")
+ .setDescription("If users should be able to create tickets")
+ .setRequired(false)
+ .addChoices([
+ ["Yes", "yes"],
+ ["No", "no"]
+ ])
+ )
+ .addChannelOption((option) =>
+ option
+ .setName("category")
+ .setDescription("The category where tickets are created")
+ .addChannelType(ChannelType.GuildCategory)
+ .setRequired(false)
+ )
+ .addNumberOption((option) =>
+ option
+ .setName("maxticketsperuser")
+ .setDescription(
+ "The maximum amount of tickets a user can create | Default: 5"
+ )
+ .setRequired(false)
+ .setMinValue(1)
+ )
+ .addRoleOption((option) =>
+ option
+ .setName("supportrole")
+ .setDescription(
+ "This role will have view access to all tickets and will be pinged when a ticket is created"
+ )
+ .setRequired(false)
+ );
-const callback = async (interaction: CommandInteraction): Promise<void | unknown> => {
- let m = await interaction.reply({embeds: LoadingEmbed, ephemeral: true, fetchReply: true}) as Message;
+const callback = async (
+ interaction: CommandInteraction
+): Promise<void | unknown> => {
+ let m = (await interaction.reply({
+ embeds: LoadingEmbed,
+ ephemeral: true,
+ fetchReply: true
+ })) as Message;
const options = {
enabled: interaction.options.getString("enabled") as string | boolean,
category: interaction.options.getChannel("category"),
maxtickets: interaction.options.getNumber("maxticketsperuser"),
supportping: interaction.options.getRole("supportrole")
};
- if (options.enabled !== null || options.category || options.maxtickets || options.supportping) {
+ if (
+ options.enabled !== null ||
+ options.category ||
+ options.maxtickets ||
+ options.supportping
+ ) {
options.enabled = options.enabled === "yes" ? true : false;
if (options.category) {
let channel: GuildChannel;
try {
- channel = await interaction.guild.channels.fetch(options.category.id);
+ channel = await interaction.guild.channels.fetch(
+ options.category.id
+ );
} catch {
return await interaction.editReply({
- embeds: [new EmojiEmbed()
- .setEmoji("CHANNEL.TEXT.DELETE")
- .setTitle("Tickets > Category")
- .setDescription("The channel you provided is not a valid category")
- .setStatus("Danger")
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("CHANNEL.TEXT.DELETE")
+ .setTitle("Tickets > Category")
+ .setDescription(
+ "The channel you provided is not a valid category"
+ )
+ .setStatus("Danger")
]
});
}
channel = channel as Discord.CategoryChannel;
- if (channel.guild.id !== interaction.guild.id) return interaction.editReply({
- embeds: [new EmojiEmbed()
- .setTitle("Tickets > Category")
- .setDescription("You must choose a category in this server")
- .setStatus("Danger")
- .setEmoji("CHANNEL.TEXT.DELETE")
- ]
- });
+ if (channel.guild.id !== interaction.guild.id)
+ return interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Tickets > Category")
+ .setDescription(
+ "You must choose a category in this server"
+ )
+ .setStatus("Danger")
+ .setEmoji("CHANNEL.TEXT.DELETE")
+ ]
+ });
}
if (options.maxtickets) {
- if (options.maxtickets < 1) return interaction.editReply({
- embeds: [new EmojiEmbed()
- .setTitle("Tickets > Max Tickets")
- .setDescription("You must choose a number greater than 0")
- .setStatus("Danger")
- .setEmoji("CHANNEL.TEXT.DELETE")
- ]
- });
+ if (options.maxtickets < 1)
+ return interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Tickets > Max Tickets")
+ .setDescription(
+ "You must choose a number greater than 0"
+ )
+ .setStatus("Danger")
+ .setEmoji("CHANNEL.TEXT.DELETE")
+ ]
+ });
}
let role: Role;
if (options.supportping) {
try {
- role = await interaction.guild.roles.fetch(options.supportping.id);
+ role = await interaction.guild.roles.fetch(
+ options.supportping.id
+ );
} catch {
return await interaction.editReply({
- embeds: [new EmojiEmbed()
- .setEmoji("GUILD.ROLE.DELETE")
- .setTitle("Tickets > Support Ping")
- .setDescription("The role you provided is not a valid role")
- .setStatus("Danger")
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("GUILD.ROLE.DELETE")
+ .setTitle("Tickets > Support Ping")
+ .setDescription(
+ "The role you provided is not a valid role"
+ )
+ .setStatus("Danger")
]
});
}
role = role as Discord.Role;
- if (role.guild.id !== interaction.guild.id) return interaction.editReply({
- embeds: [new EmojiEmbed()
- .setTitle("Tickets > Support Ping")
- .setDescription("You must choose a role in this server")
- .setStatus("Danger")
- .setEmoji("GUILD.ROLE.DELETE")
- ]
- });
+ if (role.guild.id !== interaction.guild.id)
+ return interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Tickets > Support Ping")
+ .setDescription(
+ "You must choose a role in this server"
+ )
+ .setStatus("Danger")
+ .setEmoji("GUILD.ROLE.DELETE")
+ ]
+ });
}
const confirmation = await new confirmationMessage(interaction)
.setEmoji("GUILD.TICKET.ARCHIVED")
.setTitle("Tickets")
.setDescription(
- (options.category ? `**Category:** ${options.category.name}\n` : "") +
- (options.maxtickets ? `**Max Tickets:** ${options.maxtickets}\n` : "") +
- (options.supportping ? `**Support Ping:** ${options.supportping.name}\n` : "") +
- (options.enabled !== null ? `**Enabled:** ${options.enabled ? `${getEmojiByName("CONTROL.TICK")} Yes` : `${getEmojiByName("CONTROL.CROSS")} No`
- }\n` : "") +
- "\nAre you sure you want to apply these settings?"
+ (options.category
+ ? `**Category:** ${options.category.name}\n`
+ : "") +
+ (options.maxtickets
+ ? `**Max Tickets:** ${options.maxtickets}\n`
+ : "") +
+ (options.supportping
+ ? `**Support Ping:** ${options.supportping.name}\n`
+ : "") +
+ (options.enabled !== null
+ ? `**Enabled:** ${
+ options.enabled
+ ? `${getEmojiByName("CONTROL.TICK")} Yes`
+ : `${getEmojiByName("CONTROL.CROSS")} No`
+ }\n`
+ : "") +
+ "\nAre you sure you want to apply these settings?"
)
.setColor("Warning")
.setInverted(true)
@@ -106,35 +201,51 @@
if (confirmation.cancelled) return;
if (confirmation.success) {
const toUpdate = {};
- if (options.enabled !== null) toUpdate["tickets.enabled"] = options.enabled;
- if (options.category) toUpdate["tickets.category"] = options.category.id;
- if (options.maxtickets) toUpdate["tickets.maxTickets"] = options.maxtickets;
- if (options.supportping) toUpdate["tickets.supportRole"] = options.supportping.id;
+ if (options.enabled !== null)
+ toUpdate["tickets.enabled"] = options.enabled;
+ if (options.category)
+ toUpdate["tickets.category"] = options.category.id;
+ if (options.maxtickets)
+ toUpdate["tickets.maxTickets"] = options.maxtickets;
+ if (options.supportping)
+ toUpdate["tickets.supportRole"] = options.supportping.id;
try {
- await client.database.guilds.write(interaction.guild.id, toUpdate);
+ await client.database.guilds.write(
+ interaction.guild.id,
+ toUpdate
+ );
} catch (e) {
return interaction.editReply({
- embeds: [new EmojiEmbed()
- .setTitle("Tickets")
- .setDescription("Something went wrong and the staff notifications channel could not be set")
- .setStatus("Danger")
- .setEmoji("GUILD.TICKET.DELETE")
- ], components: []
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Tickets")
+ .setDescription(
+ "Something went wrong and the staff notifications channel could not be set"
+ )
+ .setStatus("Danger")
+ .setEmoji("GUILD.TICKET.DELETE")
+ ],
+ components: []
});
}
} else {
return interaction.editReply({
- embeds: [new EmojiEmbed()
- .setTitle("Tickets")
- .setDescription("No changes were made")
- .setStatus("Success")
- .setEmoji("GUILD.TICKET.OPEN")
- ], components: []
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Tickets")
+ .setDescription("No changes were made")
+ .setStatus("Success")
+ .setEmoji("GUILD.TICKET.OPEN")
+ ],
+ components: []
});
}
}
let data = await client.database.guilds.read(interaction.guild.id);
- data.tickets.customTypes = (data.tickets.customTypes || []).filter((value: string, index: number, array: string[]) => array.indexOf(value) === index);
+ data.tickets.customTypes = (data.tickets.customTypes || []).filter(
+ (value: string, index: number, array: string[]) =>
+ array.indexOf(value) === index
+ );
let lastClicked = "";
let embed: EmojiEmbed;
data = {
@@ -150,235 +261,449 @@
embed = new EmojiEmbed()
.setTitle("Tickets")
.setDescription(
- `${data.enabled ? "" : getEmojiByName("TICKETS.REPORT")} **Enabled:** ${data.enabled ? `${getEmojiByName("CONTROL.TICK")} Yes` : `${getEmojiByName("CONTROL.CROSS")} No`}\n` +
- `${data.category ? "" : getEmojiByName("TICKETS.REPORT")} **Category:** ${data.category ? `<#${data.category}>` : "*None set*"}\n` +
- `**Max Tickets:** ${data.maxTickets ? data.maxTickets : "*No limit*"}\n` +
- `**Support Ping:** ${data.supportRole ? `<@&${data.supportRole}>` : "*None set*"}\n\n` +
- ((data.useCustom && data.customTypes === null) ? `${getEmojiByName("TICKETS.REPORT")} ` : "") +
- `${data.useCustom ? "Custom" : "Default"} types in use` + "\n\n" +
- `${getEmojiByName("TICKETS.REPORT")} *Indicates a setting stopping tickets from being used*`
+ `${
+ data.enabled ? "" : getEmojiByName("TICKETS.REPORT")
+ } **Enabled:** ${
+ data.enabled
+ ? `${getEmojiByName("CONTROL.TICK")} Yes`
+ : `${getEmojiByName("CONTROL.CROSS")} No`
+ }\n` +
+ `${
+ data.category ? "" : getEmojiByName("TICKETS.REPORT")
+ } **Category:** ${
+ data.category ? `<#${data.category}>` : "*None set*"
+ }\n` +
+ `**Max Tickets:** ${
+ data.maxTickets ? data.maxTickets : "*No limit*"
+ }\n` +
+ `**Support Ping:** ${
+ data.supportRole
+ ? `<@&${data.supportRole}>`
+ : "*None set*"
+ }\n\n` +
+ (data.useCustom && data.customTypes === null
+ ? `${getEmojiByName("TICKETS.REPORT")} `
+ : "") +
+ `${data.useCustom ? "Custom" : "Default"} types in use` +
+ "\n\n" +
+ `${getEmojiByName(
+ "TICKETS.REPORT"
+ )} *Indicates a setting stopping tickets from being used*`
)
.setStatus("Success")
.setEmoji("GUILD.TICKET.OPEN");
- m = await interaction.editReply({
- embeds: [embed], components: [new MessageActionRow().addComponents([
- new MessageButton()
- .setLabel("Tickets " + (data.enabled ? "enabled" : "disabled"))
- .setEmoji(getEmojiByName("CONTROL." + (data.enabled ? "TICK" : "CROSS"), "id"))
- .setStyle(data.enabled ? "SUCCESS" : "DANGER")
- .setCustomId("enabled"),
- new MessageButton()
- .setLabel(lastClicked === "cat" ? "Click again to confirm" : "Clear category")
- .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
- .setStyle("DANGER")
- .setCustomId("clearCategory")
- .setDisabled(data.category === null),
- new MessageButton()
- .setLabel(lastClicked === "max" ? "Click again to confirm" : "Reset max tickets")
- .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
- .setStyle("DANGER")
- .setCustomId("clearMaxTickets")
- .setDisabled(data.maxTickets === 5),
- new MessageButton()
- .setLabel(lastClicked === "sup" ? "Click again to confirm" : "Clear support ping")
- .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
- .setStyle("DANGER")
- .setCustomId("clearSupportPing")
- .setDisabled(data.supportRole === null)
- ]), new MessageActionRow().addComponents([
- new MessageButton()
- .setLabel("Manage types")
- .setEmoji(getEmojiByName("TICKETS.OTHER", "id"))
- .setStyle("SECONDARY")
- .setCustomId("manageTypes"),
- new MessageButton()
- .setLabel("Add create ticket button")
- .setEmoji(getEmojiByName("TICKETS.SUGGESTION", "id"))
- .setStyle("PRIMARY")
- .setCustomId("send")
- ])]
- }) as Message;
+ m = (await interaction.editReply({
+ embeds: [embed],
+ components: [
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setLabel(
+ "Tickets " + (data.enabled ? "enabled" : "disabled")
+ )
+ .setEmoji(
+ getEmojiByName(
+ "CONTROL." + (data.enabled ? "TICK" : "CROSS"),
+ "id"
+ )
+ )
+ .setStyle(data.enabled ? "SUCCESS" : "DANGER")
+ .setCustomId("enabled"),
+ new MessageButton()
+ .setLabel(
+ lastClicked === "cat"
+ ? "Click again to confirm"
+ : "Clear category"
+ )
+ .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
+ .setStyle("DANGER")
+ .setCustomId("clearCategory")
+ .setDisabled(data.category === null),
+ new MessageButton()
+ .setLabel(
+ lastClicked === "max"
+ ? "Click again to confirm"
+ : "Reset max tickets"
+ )
+ .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
+ .setStyle("DANGER")
+ .setCustomId("clearMaxTickets")
+ .setDisabled(data.maxTickets === 5),
+ new MessageButton()
+ .setLabel(
+ lastClicked === "sup"
+ ? "Click again to confirm"
+ : "Clear support ping"
+ )
+ .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
+ .setStyle("DANGER")
+ .setCustomId("clearSupportPing")
+ .setDisabled(data.supportRole === null)
+ ]),
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setLabel("Manage types")
+ .setEmoji(getEmojiByName("TICKETS.OTHER", "id"))
+ .setStyle("SECONDARY")
+ .setCustomId("manageTypes"),
+ new MessageButton()
+ .setLabel("Add create ticket button")
+ .setEmoji(getEmojiByName("TICKETS.SUGGESTION", "id"))
+ .setStyle("PRIMARY")
+ .setCustomId("send")
+ ])
+ ]
+ })) as Message;
let i: MessageComponentInteraction;
try {
i = await m.awaitMessageComponent({ time: 300000 });
- } catch (e) { break; }
+ } catch (e) {
+ break;
+ }
i.deferUpdate();
- if ((i.component as MessageActionRowComponent).customId === "clearCategory") {
+ if (
+ (i.component as MessageActionRowComponent).customId ===
+ "clearCategory"
+ ) {
if (lastClicked === "cat") {
lastClicked = "";
- await client.database.guilds.write(interaction.guild.id, null, ["tickets.category"]);
+ await client.database.guilds.write(interaction.guild.id, null, [
+ "tickets.category"
+ ]);
data.category = undefined;
} else lastClicked = "cat";
- } else if ((i.component as MessageActionRowComponent).customId === "clearMaxTickets") {
+ } else if (
+ (i.component as MessageActionRowComponent).customId ===
+ "clearMaxTickets"
+ ) {
if (lastClicked === "max") {
lastClicked = "";
- await client.database.guilds.write(interaction.guild.id, null, ["tickets.maxTickets"]);
+ await client.database.guilds.write(interaction.guild.id, null, [
+ "tickets.maxTickets"
+ ]);
data.maxTickets = 5;
} else lastClicked = "max";
- } else if ((i.component as MessageActionRowComponent).customId === "clearSupportPing") {
+ } else if (
+ (i.component as MessageActionRowComponent).customId ===
+ "clearSupportPing"
+ ) {
if (lastClicked === "sup") {
lastClicked = "";
- await client.database.guilds.write(interaction.guild.id, null, ["tickets.supportRole"]);
+ await client.database.guilds.write(interaction.guild.id, null, [
+ "tickets.supportRole"
+ ]);
data.supportRole = undefined;
} else lastClicked = "sup";
- } else if ((i.component as MessageActionRowComponent).customId === "send") {
+ } else if (
+ (i.component as MessageActionRowComponent).customId === "send"
+ ) {
const ticketMessages = [
- {label: "Create ticket", description: "Click the button below to create a ticket"},
- {label: "Issues, questions or feedback?", description: "Click below to open a ticket and get help from our staff team"},
- {label: "Contact Us", description: "Click the button below to speak to us privately"}
+ {
+ label: "Create ticket",
+ description: "Click the button below to create a ticket"
+ },
+ {
+ label: "Issues, questions or feedback?",
+ description:
+ "Click below to open a ticket and get help from our staff team"
+ },
+ {
+ label: "Contact Us",
+ description:
+ "Click the button below to speak to us privately"
+ }
];
while (true) {
const enabled = data.enabled && data.category !== null;
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Ticket Button")
- .setDescription("Select a message template to send in this channel")
- .setFooter({text: enabled ? "" : "Tickets are not set up correctly so the button may not work for users. Check the main menu to find which options must be set."})
- .setStatus(enabled ? "Success" : "Warning")
- .setEmoji("GUILD.ROLES.CREATE")
- ], components: [
- new MessageActionRow().addComponents([
- new MessageSelectMenu().setOptions(ticketMessages.map((t: {label: string, description: string, value?: string}, index) => {
- t.value = index.toString(); return t as {value: string, label: string, description: string};
- })).setCustomId("template").setMaxValues(1).setMinValues(1).setPlaceholder("Select a message template")
- ]),
- new MessageActionRow().addComponents([
- new MessageButton()
- .setCustomId("back")
- .setLabel("Back")
- .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
- .setStyle("DANGER"),
- new MessageButton()
- .setCustomId("blank")
- .setLabel("Empty")
- .setStyle("SECONDARY"),
- new MessageButton()
- .setCustomId("custom")
- .setLabel("Custom")
- .setEmoji(getEmojiByName("TICKETS.OTHER", "id"))
- .setStyle("PRIMARY")
- ])
- ]});
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Ticket Button")
+ .setDescription(
+ "Select a message template to send in this channel"
+ )
+ .setFooter({
+ text: enabled
+ ? ""
+ : "Tickets are not set up correctly so the button may not work for users. Check the main menu to find which options must be set."
+ })
+ .setStatus(enabled ? "Success" : "Warning")
+ .setEmoji("GUILD.ROLES.CREATE")
+ ],
+ components: [
+ new MessageActionRow().addComponents([
+ new MessageSelectMenu()
+ .setOptions(
+ ticketMessages.map(
+ (
+ t: {
+ label: string;
+ description: string;
+ value?: string;
+ },
+ index
+ ) => {
+ t.value = index.toString();
+ return t as {
+ value: string;
+ label: string;
+ description: string;
+ };
+ }
+ )
+ )
+ .setCustomId("template")
+ .setMaxValues(1)
+ .setMinValues(1)
+ .setPlaceholder("Select a message template")
+ ]),
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setCustomId("back")
+ .setLabel("Back")
+ .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
+ .setStyle("DANGER"),
+ new MessageButton()
+ .setCustomId("blank")
+ .setLabel("Empty")
+ .setStyle("SECONDARY"),
+ new MessageButton()
+ .setCustomId("custom")
+ .setLabel("Custom")
+ .setEmoji(getEmojiByName("TICKETS.OTHER", "id"))
+ .setStyle("PRIMARY")
+ ])
+ ]
+ });
let i: MessageComponentInteraction;
try {
- i = await m.awaitMessageComponent({time: 300000});
- } catch(e) { break; }
- if ((i.component as MessageActionRowComponent).customId === "template") {
- i.deferUpdate();
- await interaction.channel.send({embeds: [new EmojiEmbed()
- .setTitle(ticketMessages[parseInt((i as SelectMenuInteraction).values[0])].label)
- .setDescription(ticketMessages[parseInt((i as SelectMenuInteraction).values[0])].description)
- .setStatus("Success")
- .setEmoji("GUILD.TICKET.OPEN")
- ], components: [new MessageActionRow().addComponents([new MessageButton()
- .setLabel("Create Ticket")
- .setEmoji(getEmojiByName("CONTROL.TICK", "id"))
- .setStyle("SUCCESS")
- .setCustomId("createticket")
- ])]});
+ i = await m.awaitMessageComponent({ time: 300000 });
+ } catch (e) {
break;
- } else if ((i.component as MessageActionRowComponent).customId === "blank") {
+ }
+ if (
+ (i.component as MessageActionRowComponent).customId ===
+ "template"
+ ) {
i.deferUpdate();
- await interaction.channel.send({components: [new MessageActionRow().addComponents([new MessageButton()
- .setLabel("Create Ticket")
- .setEmoji(getEmojiByName("TICKETS.SUGGESTION", "id"))
- .setStyle("SUCCESS")
- .setCustomId("createticket")
- ])]});
+ await interaction.channel.send({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle(
+ ticketMessages[
+ parseInt(
+ (i as SelectMenuInteraction)
+ .values[0]
+ )
+ ].label
+ )
+ .setDescription(
+ ticketMessages[
+ parseInt(
+ (i as SelectMenuInteraction)
+ .values[0]
+ )
+ ].description
+ )
+ .setStatus("Success")
+ .setEmoji("GUILD.TICKET.OPEN")
+ ],
+ components: [
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setLabel("Create Ticket")
+ .setEmoji(
+ getEmojiByName("CONTROL.TICK", "id")
+ )
+ .setStyle("SUCCESS")
+ .setCustomId("createticket")
+ ])
+ ]
+ });
break;
- } else if ((i.component as MessageActionRowComponent).customId === "custom") {
- await i.showModal(new Discord.Modal().setCustomId("modal").setTitle("Enter embed details").addComponents(
- new MessageActionRow<TextInputComponent>().addComponents(new TextInputComponent()
- .setCustomId("title")
- .setLabel("Title")
- .setMaxLength(256)
- .setRequired(true)
- .setStyle("SHORT")
- ),
- new MessageActionRow<TextInputComponent>().addComponents(new TextInputComponent()
- .setCustomId("description")
- .setLabel("Description")
- .setMaxLength(4000)
- .setRequired(true)
- .setStyle("PARAGRAPH")
- )
- ));
+ } else if (
+ (i.component as MessageActionRowComponent).customId ===
+ "blank"
+ ) {
+ i.deferUpdate();
+ await interaction.channel.send({
+ components: [
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setLabel("Create Ticket")
+ .setEmoji(
+ getEmojiByName(
+ "TICKETS.SUGGESTION",
+ "id"
+ )
+ )
+ .setStyle("SUCCESS")
+ .setCustomId("createticket")
+ ])
+ ]
+ });
+ break;
+ } else if (
+ (i.component as MessageActionRowComponent).customId ===
+ "custom"
+ ) {
+ await i.showModal(
+ new Discord.Modal()
+ .setCustomId("modal")
+ .setTitle("Enter embed details")
+ .addComponents(
+ new MessageActionRow<TextInputComponent>().addComponents(
+ new TextInputComponent()
+ .setCustomId("title")
+ .setLabel("Title")
+ .setMaxLength(256)
+ .setRequired(true)
+ .setStyle("SHORT")
+ ),
+ new MessageActionRow<TextInputComponent>().addComponents(
+ new TextInputComponent()
+ .setCustomId("description")
+ .setLabel("Description")
+ .setMaxLength(4000)
+ .setRequired(true)
+ .setStyle("PARAGRAPH")
+ )
+ )
+ );
await interaction.editReply({
- embeds: [new EmojiEmbed()
- .setTitle("Ticket Button")
- .setDescription("Modal opened. If you can't see it, click back and try again.")
- .setStatus("Success")
- .setEmoji("GUILD.TICKET.OPEN")
- ], components: [new MessageActionRow().addComponents([new MessageButton()
- .setLabel("Back")
- .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
- .setStyle("PRIMARY")
- .setCustomId("back")
- ])]
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Ticket Button")
+ .setDescription(
+ "Modal opened. If you can't see it, click back and try again."
+ )
+ .setStatus("Success")
+ .setEmoji("GUILD.TICKET.OPEN")
+ ],
+ components: [
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setLabel("Back")
+ .setEmoji(
+ getEmojiByName("CONTROL.LEFT", "id")
+ )
+ .setStyle("PRIMARY")
+ .setCustomId("back")
+ ])
+ ]
});
let out;
try {
- out = await modalInteractionCollector(m, (m) => m.channel.id === interaction.channel.id, (m) => m.customId === "modify");
- } catch (e) { break; }
+ out = await modalInteractionCollector(
+ m,
+ (m) => m.channel.id === interaction.channel.id,
+ (m) => m.customId === "modify"
+ );
+ } catch (e) {
+ break;
+ }
if (out.fields) {
const title = out.fields.getTextInputValue("title");
- const description = out.fields.getTextInputValue("description");
- await interaction.channel.send({embeds: [new EmojiEmbed()
- .setTitle(title)
- .setDescription(description)
- .setStatus("Success")
- .setEmoji("GUILD.TICKET.OPEN")
- ], components: [new MessageActionRow().addComponents([new MessageButton()
- .setLabel("Create Ticket")
- .setEmoji(getEmojiByName("TICKETS.SUGGESTION", "id"))
- .setStyle("SUCCESS")
- .setCustomId("createticket")
- ])]});
+ const description =
+ out.fields.getTextInputValue("description");
+ await interaction.channel.send({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle(title)
+ .setDescription(description)
+ .setStatus("Success")
+ .setEmoji("GUILD.TICKET.OPEN")
+ ],
+ components: [
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setLabel("Create Ticket")
+ .setEmoji(
+ getEmojiByName(
+ "TICKETS.SUGGESTION",
+ "id"
+ )
+ )
+ .setStyle("SUCCESS")
+ .setCustomId("createticket")
+ ])
+ ]
+ });
break;
- } else { continue; }
+ } else {
+ continue;
+ }
}
}
- } else if ((i.component as MessageActionRowComponent).customId === "enabled") {
- await client.database.guilds.write(interaction.guild.id, { "tickets.enabled": !data.enabled });
+ } else if (
+ (i.component as MessageActionRowComponent).customId === "enabled"
+ ) {
+ await client.database.guilds.write(interaction.guild.id, {
+ "tickets.enabled": !data.enabled
+ });
data.enabled = !data.enabled;
- } else if ((i.component as MessageActionRowComponent).customId === "manageTypes") {
+ } else if (
+ (i.component as MessageActionRowComponent).customId ===
+ "manageTypes"
+ ) {
data = await manageTypes(interaction, data, m as Message);
} else {
break;
}
}
- await interaction.editReply({ embeds: [embed.setFooter({ text: "Message closed" })], components: [] });
+ await interaction.editReply({
+ embeds: [embed.setFooter({ text: "Message closed" })],
+ components: []
+ });
};
-async function manageTypes(interaction: CommandInteraction, data: GuildConfig["tickets"], m: Message) {
+async function manageTypes(
+ interaction: CommandInteraction,
+ data: GuildConfig["tickets"],
+ m: Message
+) {
while (true) {
if (data.useCustom) {
const customTypes = data.customTypes;
await interaction.editReply({
- embeds: [new EmojiEmbed()
- .setTitle("Tickets > Types")
- .setDescription(
- "**Custom types enabled**\n\n" +
- "**Types in use:**\n" + ((customTypes !== null) ?
- (customTypes.map((t) => `> ${t}`).join("\n")) :
- "*None set*"
- ) + "\n\n" + (customTypes === null ?
- `${getEmojiByName("TICKETS.REPORT")} Having no types will disable tickets. Please add at least 1 type or use default types` : ""
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Tickets > Types")
+ .setDescription(
+ "**Custom types enabled**\n\n" +
+ "**Types in use:**\n" +
+ (customTypes !== null
+ ? customTypes
+ .map((t) => `> ${t}`)
+ .join("\n")
+ : "*None set*") +
+ "\n\n" +
+ (customTypes === null
+ ? `${getEmojiByName(
+ "TICKETS.REPORT"
+ )} Having no types will disable tickets. Please add at least 1 type or use default types`
+ : "")
)
- )
- .setStatus("Success")
- .setEmoji("GUILD.TICKET.OPEN")
- ], components: (customTypes ? [
- new MessageActionRow().addComponents([new Discord.MessageSelectMenu()
- .setCustomId("removeTypes")
- .setPlaceholder("Select types to remove")
- .setMaxValues(customTypes.length)
- .setMinValues(1)
- .addOptions(customTypes.map((t) => ({
- label: t,
- value: t
- })))
- ])
- ] : []).concat([
+ .setStatus("Success")
+ .setEmoji("GUILD.TICKET.OPEN")
+ ],
+ components: (customTypes
+ ? [
+ new MessageActionRow().addComponents([
+ new Discord.MessageSelectMenu()
+ .setCustomId("removeTypes")
+ .setPlaceholder("Select types to remove")
+ .setMaxValues(customTypes.length)
+ .setMinValues(1)
+ .addOptions(
+ customTypes.map((t) => ({
+ label: t,
+ value: t
+ }))
+ )
+ ])
+ ]
+ : []
+ ).concat([
new MessageActionRow().addComponents([
new MessageButton()
.setLabel("Back")
@@ -387,10 +712,14 @@
.setCustomId("back"),
new MessageButton()
.setLabel("Add new type")
- .setEmoji(getEmojiByName("TICKETS.SUGGESTION", "id"))
+ .setEmoji(
+ getEmojiByName("TICKETS.SUGGESTION", "id")
+ )
.setStyle("PRIMARY")
.setCustomId("addType")
- .setDisabled(customTypes !== null && customTypes.length >= 25),
+ .setDisabled(
+ customTypes !== null && customTypes.length >= 25
+ ),
new MessageButton()
.setLabel("Switch to default types")
.setStyle("SECONDARY")
@@ -401,13 +730,20 @@
} else {
const inUse = toHexArray(data.types, ticketTypes);
const options = [];
- ticketTypes.forEach(type => {
- options.push(new SelectMenuOption({
- label: capitalize(type),
- value: type,
- emoji: client.emojis.cache.get(getEmojiByName(`TICKETS.${type.toUpperCase()}`, "id")),
- default: inUse.includes(type)
- }));
+ ticketTypes.forEach((type) => {
+ options.push(
+ new SelectMenuOption({
+ label: capitalize(type),
+ value: type,
+ emoji: client.emojis.cache.get(
+ getEmojiByName(
+ `TICKETS.${type.toUpperCase()}`,
+ "id"
+ )
+ ),
+ default: inUse.includes(type)
+ })
+ );
});
const selectPane = new MessageActionRow().addComponents([
new Discord.MessageSelectMenu()
@@ -418,16 +754,25 @@
.setPlaceholder("Select types to use")
]);
await interaction.editReply({
- embeds: [new EmojiEmbed()
- .setTitle("Tickets > Types")
- .setDescription(
- "**Default types enabled**\n\n" +
- "**Types in use:**\n" +
- (inUse.map((t) => `> ${getEmojiByName("TICKETS." + t.toUpperCase())} ${capitalize(t)}`).join("\n"))
- )
- .setStatus("Success")
- .setEmoji("GUILD.TICKET.OPEN")
- ], components: [
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Tickets > Types")
+ .setDescription(
+ "**Default types enabled**\n\n" +
+ "**Types in use:**\n" +
+ inUse
+ .map(
+ (t) =>
+ `> ${getEmojiByName(
+ "TICKETS." + t.toUpperCase()
+ )} ${capitalize(t)}`
+ )
+ .join("\n")
+ )
+ .setStatus("Success")
+ .setEmoji("GUILD.TICKET.OPEN")
+ ],
+ components: [
selectPane,
new MessageActionRow().addComponents([
new MessageButton()
@@ -446,11 +791,15 @@
let i;
try {
i = await m.awaitMessageComponent({ time: 300000 });
- } catch (e) { break; }
+ } catch (e) {
+ break;
+ }
if (i.component.customId === "types") {
i.deferUpdate();
const types = toHexInteger(i.values, ticketTypes);
- await client.database.guilds.write(interaction.guild.id, { "tickets.types": types });
+ await client.database.guilds.write(interaction.guild.id, {
+ "tickets.types": types
+ });
data.types = types;
} else if (i.component.customId === "removeTypes") {
i.deferUpdate();
@@ -459,57 +808,96 @@
if (customTypes) {
customTypes = customTypes.filter((t) => !types.includes(t));
customTypes = customTypes.length > 0 ? customTypes : null;
- await client.database.guilds.write(interaction.guild.id, { "tickets.customTypes": customTypes });
+ await client.database.guilds.write(interaction.guild.id, {
+ "tickets.customTypes": customTypes
+ });
data.customTypes = customTypes;
}
} else if (i.component.customId === "addType") {
- await i.showModal(new Discord.Modal().setCustomId("modal").setTitle("Enter a name for the new type").addComponents(
- new MessageActionRow<TextInputComponent>().addComponents(new TextInputComponent()
- .setCustomId("type")
- .setLabel("Name")
- .setMaxLength(100)
- .setMinLength(1)
- .setPlaceholder("E.g. \"Server Idea\"")
- .setRequired(true)
- .setStyle("SHORT")
- )
- ));
+ await i.showModal(
+ new Discord.Modal()
+ .setCustomId("modal")
+ .setTitle("Enter a name for the new type")
+ .addComponents(
+ new MessageActionRow<TextInputComponent>().addComponents(
+ new TextInputComponent()
+ .setCustomId("type")
+ .setLabel("Name")
+ .setMaxLength(100)
+ .setMinLength(1)
+ .setPlaceholder('E.g. "Server Idea"')
+ .setRequired(true)
+ .setStyle("SHORT")
+ )
+ )
+ );
await interaction.editReply({
- embeds: [new EmojiEmbed()
- .setTitle("Tickets > Types")
- .setDescription("Modal opened. If you can't see it, click back and try again.")
- .setStatus("Success")
- .setEmoji("GUILD.TICKET.OPEN")
- ], components: [new MessageActionRow().addComponents([new MessageButton()
- .setLabel("Back")
- .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
- .setStyle("PRIMARY")
- .setCustomId("back")
- ])]
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Tickets > Types")
+ .setDescription(
+ "Modal opened. If you can't see it, click back and try again."
+ )
+ .setStatus("Success")
+ .setEmoji("GUILD.TICKET.OPEN")
+ ],
+ components: [
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setLabel("Back")
+ .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
+ .setStyle("PRIMARY")
+ .setCustomId("back")
+ ])
+ ]
});
let out;
try {
- out = await modalInteractionCollector(m, (m) => m.channel.id === interaction.channel.id, (m) => m.customId === "addType");
- } catch (e) { continue; }
+ out = await modalInteractionCollector(
+ m,
+ (m) => m.channel.id === interaction.channel.id,
+ (m) => m.customId === "addType"
+ );
+ } catch (e) {
+ continue;
+ }
if (out.fields) {
let toAdd = out.fields.getTextInputValue("type");
- if (!toAdd) { continue; }
+ if (!toAdd) {
+ continue;
+ }
toAdd = toAdd.substring(0, 80);
try {
- await client.database.guilds.append(interaction.guild.id, "tickets.customTypes", toAdd);
- } catch { continue; }
+ await client.database.guilds.append(
+ interaction.guild.id,
+ "tickets.customTypes",
+ toAdd
+ );
+ } catch {
+ continue;
+ }
data.customTypes = data.customTypes || [];
if (!data.customTypes.includes(toAdd)) {
data.customTypes.push(toAdd);
}
- } else { continue; }
+ } else {
+ continue;
+ }
} else if (i.component.customId === "switchToDefault") {
i.deferUpdate();
- await client.database.guilds.write(interaction.guild.id, { "tickets.useCustom": false }, []);
+ await client.database.guilds.write(
+ interaction.guild.id,
+ { "tickets.useCustom": false },
+ []
+ );
data.useCustom = false;
} else if (i.component.customId === "switchToCustom") {
i.deferUpdate();
- await client.database.guilds.write(interaction.guild.id, { "tickets.useCustom": true }, []);
+ await client.database.guilds.write(
+ interaction.guild.id,
+ { "tickets.useCustom": true },
+ []
+ );
data.useCustom = true;
} else {
i.deferUpdate();
@@ -519,10 +907,10 @@
return data;
}
-
const check = (interaction: CommandInteraction) => {
- const member = (interaction.member as Discord.GuildMember);
- if (!member.permissions.has("MANAGE_GUILD")) throw "You must have the *Manage Server* permission to use this command";
+ const member = interaction.member as Discord.GuildMember;
+ if (!member.permissions.has("MANAGE_GUILD"))
+ throw "You must have the *Manage Server* permission to use this command";
return true;
};
diff --git a/src/commands/settings/verify.ts b/src/commands/settings/verify.ts
index 4efd68c..e0af802 100644
--- a/src/commands/settings/verify.ts
+++ b/src/commands/settings/verify.ts
@@ -1,5 +1,17 @@
import { LoadingEmbed } from "./../../utils/defaultEmbeds.js";
-import Discord, { CommandInteraction, Message, MessageActionRow, MessageActionRowComponent, MessageButton, MessageComponentInteraction, MessageEmbed, MessageSelectMenu, Role, SelectMenuInteraction, TextInputComponent } from "discord.js";
+import Discord, {
+ CommandInteraction,
+ Message,
+ MessageActionRow,
+ MessageActionRowComponent,
+ MessageButton,
+ MessageComponentInteraction,
+ MessageEmbed,
+ MessageSelectMenu,
+ Role,
+ SelectMenuInteraction,
+ TextInputComponent
+} from "discord.js";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import confirmationMessage from "../../utils/confirmationMessage.js";
import getEmojiByName from "../../utils/getEmojiByName.js";
@@ -11,45 +23,70 @@
builder
.setName("verify")
.setDescription("Manage the role given after typing /verify")
- .addRoleOption(option => option.setName("role").setDescription("The role to give after verifying").setRequired(false));
+ .addRoleOption((option) =>
+ option
+ .setName("role")
+ .setDescription("The role to give after verifying")
+ .setRequired(false)
+ );
-const callback = async (interaction: CommandInteraction): Promise<void | unknown> => {
- const m = await interaction.reply({embeds: LoadingEmbed, ephemeral: true, fetchReply: true}) as Message;
+const callback = async (
+ interaction: CommandInteraction
+): Promise<void | unknown> => {
+ const m = (await interaction.reply({
+ embeds: LoadingEmbed,
+ ephemeral: true,
+ fetchReply: true
+ })) as Message;
if (interaction.options.getRole("role")) {
let role: Role;
try {
role = interaction.options.getRole("role") as Role;
} catch {
- return await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("GUILD.ROLES.DELETE")
- .setTitle("Verify Role")
- .setDescription("The role you provided is not a valid role")
- .setStatus("Danger")
- ]});
+ return await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("GUILD.ROLES.DELETE")
+ .setTitle("Verify Role")
+ .setDescription(
+ "The role you provided is not a valid role"
+ )
+ .setStatus("Danger")
+ ]
+ });
}
role = role as Discord.Role;
if (role.guild.id !== interaction.guild.id) {
- return interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Verify Role")
- .setDescription("You must choose a role in this server")
- .setStatus("Danger")
- .setEmoji("GUILD.ROLES.DELETE")
- ]});
+ return interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Verify Role")
+ .setDescription("You must choose a role in this server")
+ .setStatus("Danger")
+ .setEmoji("GUILD.ROLES.DELETE")
+ ]
+ });
}
const confirmation = await new confirmationMessage(interaction)
.setEmoji("GUILD.ROLES.EDIT")
.setTitle("Verify Role")
- .setDescription(`Are you sure you want to set the verify role to <@&${role.id}>?`)
+ .setDescription(
+ `Are you sure you want to set the verify role to <@&${role.id}>?`
+ )
.setColor("Warning")
.setInverted(true)
.send(true);
if (confirmation.cancelled) return;
if (confirmation.success) {
try {
- await client.database.guilds.write(interaction.guild.id, {"verify.role": role.id, "verify.enabled": true});
- const { log, NucleusColors, entry, renderUser, renderRole } = client.logger;
+ await client.database.guilds.write(interaction.guild.id, {
+ "verify.role": role.id,
+ "verify.enabled": true
+ });
+ const { log, NucleusColors, entry, renderUser, renderRole } =
+ client.logger;
const data = {
- meta:{
+ meta: {
type: "verifyRoleChanged",
displayName: "Verify Role Changed",
calculateType: "nucleusSettingsUpdated",
@@ -58,8 +95,14 @@
timestamp: new Date().getTime()
},
list: {
- memberId: entry(interaction.user.id, `\`${interaction.user.id}\``),
- changedBy: entry(interaction.user.id, renderUser(interaction.user)),
+ memberId: entry(
+ interaction.user.id,
+ `\`${interaction.user.id}\``
+ ),
+ changedBy: entry(
+ interaction.user.id,
+ renderUser(interaction.user)
+ ),
role: entry(role.id, renderRole(role))
},
hidden: {
@@ -69,169 +112,319 @@
log(data);
} catch (e) {
console.log(e);
- return interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Verify Role")
- .setDescription("Something went wrong while setting the verify role")
- .setStatus("Danger")
- .setEmoji("GUILD.ROLES.DELETE")
- ], components: []});
+ return interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Verify Role")
+ .setDescription(
+ "Something went wrong while setting the verify role"
+ )
+ .setStatus("Danger")
+ .setEmoji("GUILD.ROLES.DELETE")
+ ],
+ components: []
+ });
}
} else {
- return interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Verify Role")
- .setDescription("No changes were made")
- .setStatus("Success")
- .setEmoji("GUILD.ROLES.CREATE")
- ], components: []});
+ return interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Verify Role")
+ .setDescription("No changes were made")
+ .setStatus("Success")
+ .setEmoji("GUILD.ROLES.CREATE")
+ ],
+ components: []
+ });
}
}
let clicks = 0;
const data = await client.database.guilds.read(interaction.guild.id);
let role = data.verify.role;
while (true) {
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Verify Role")
- .setDescription(role ? `Your verify role is currently set to <@&${role}>` : "You have not set a verify role")
- .setStatus("Success")
- .setEmoji("GUILD.ROLES.CREATE")
- ], components: [new MessageActionRow().addComponents([
- new MessageButton()
- .setCustomId("clear")
- .setLabel(clicks ? "Click again to confirm" : "Reset role")
- .setEmoji(getEmojiByName(clicks ? "TICKETS.ISSUE" : "CONTROL.CROSS", "id"))
- .setStyle("DANGER")
- .setDisabled(!role),
- new MessageButton()
- .setCustomId("send")
- .setLabel("Add verify button")
- .setEmoji(getEmojiByName("TICKETS.SUGGESTION", "id"))
- .setStyle("PRIMARY")
- ])]});
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Verify Role")
+ .setDescription(
+ role
+ ? `Your verify role is currently set to <@&${role}>`
+ : "You have not set a verify role"
+ )
+ .setStatus("Success")
+ .setEmoji("GUILD.ROLES.CREATE")
+ ],
+ components: [
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setCustomId("clear")
+ .setLabel(
+ clicks ? "Click again to confirm" : "Reset role"
+ )
+ .setEmoji(
+ getEmojiByName(
+ clicks ? "TICKETS.ISSUE" : "CONTROL.CROSS",
+ "id"
+ )
+ )
+ .setStyle("DANGER")
+ .setDisabled(!role),
+ new MessageButton()
+ .setCustomId("send")
+ .setLabel("Add verify button")
+ .setEmoji(getEmojiByName("TICKETS.SUGGESTION", "id"))
+ .setStyle("PRIMARY")
+ ])
+ ]
+ });
let i: MessageComponentInteraction;
try {
- i = await m.awaitMessageComponent({time: 300000});
- } catch(e) { break; }
+ i = await m.awaitMessageComponent({ time: 300000 });
+ } catch (e) {
+ break;
+ }
i.deferUpdate();
if ((i.component as MessageActionRowComponent).customId === "clear") {
clicks += 1;
if (clicks === 2) {
clicks = 0;
- await client.database.guilds.write(interaction.guild.id, null, ["verify.role", "verify.enabled"]);
+ await client.database.guilds.write(interaction.guild.id, null, [
+ "verify.role",
+ "verify.enabled"
+ ]);
role = undefined;
}
- } else if ((i.component as MessageActionRowComponent).customId === "send") {
+ } else if (
+ (i.component as MessageActionRowComponent).customId === "send"
+ ) {
const verifyMessages = [
- {label: "Verify", description: "Click the button below to get verified"},
- {label: "Get verified", description: "To get access to the rest of the server, click the button below"},
- {label: "Ready to verify?", description: "Click the button below to verify yourself"}
+ {
+ label: "Verify",
+ description: "Click the button below to get verified"
+ },
+ {
+ label: "Get verified",
+ description:
+ "To get access to the rest of the server, click the button below"
+ },
+ {
+ label: "Ready to verify?",
+ description: "Click the button below to verify yourself"
+ }
];
while (true) {
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Verify Button")
- .setDescription("Select a message template to send in this channel")
- .setFooter({text: role ? "" : "You do no have a verify role set so the button will not work."})
- .setStatus(role ? "Success" : "Warning")
- .setEmoji("GUILD.ROLES.CREATE")
- ], components: [
- new MessageActionRow().addComponents([
- new MessageSelectMenu().setOptions(verifyMessages.map((t: {label: string, description: string, value?: string}, index) => {
- t.value = index.toString(); return t as {value: string, label: string, description: string};
- })).setCustomId("template").setMaxValues(1).setMinValues(1).setPlaceholder("Select a message template")
- ]),
- new MessageActionRow().addComponents([
- new MessageButton()
- .setCustomId("back")
- .setLabel("Back")
- .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
- .setStyle("DANGER"),
- new MessageButton()
- .setCustomId("blank")
- .setLabel("Empty")
- .setStyle("SECONDARY"),
- new MessageButton()
- .setCustomId("custom")
- .setLabel("Custom")
- .setEmoji(getEmojiByName("TICKETS.OTHER", "id"))
- .setStyle("PRIMARY")
- ])
- ]});
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Verify Button")
+ .setDescription(
+ "Select a message template to send in this channel"
+ )
+ .setFooter({
+ text: role
+ ? ""
+ : "You do no have a verify role set so the button will not work."
+ })
+ .setStatus(role ? "Success" : "Warning")
+ .setEmoji("GUILD.ROLES.CREATE")
+ ],
+ components: [
+ new MessageActionRow().addComponents([
+ new MessageSelectMenu()
+ .setOptions(
+ verifyMessages.map(
+ (
+ t: {
+ label: string;
+ description: string;
+ value?: string;
+ },
+ index
+ ) => {
+ t.value = index.toString();
+ return t as {
+ value: string;
+ label: string;
+ description: string;
+ };
+ }
+ )
+ )
+ .setCustomId("template")
+ .setMaxValues(1)
+ .setMinValues(1)
+ .setPlaceholder("Select a message template")
+ ]),
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setCustomId("back")
+ .setLabel("Back")
+ .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
+ .setStyle("DANGER"),
+ new MessageButton()
+ .setCustomId("blank")
+ .setLabel("Empty")
+ .setStyle("SECONDARY"),
+ new MessageButton()
+ .setCustomId("custom")
+ .setLabel("Custom")
+ .setEmoji(getEmojiByName("TICKETS.OTHER", "id"))
+ .setStyle("PRIMARY")
+ ])
+ ]
+ });
let i: MessageComponentInteraction;
try {
- i = await m.awaitMessageComponent({time: 300000});
- } catch(e) { break; }
- if ((i.component as MessageActionRowComponent).customId === "template") {
- i.deferUpdate();
- await interaction.channel.send({embeds: [new EmojiEmbed()
- .setTitle(verifyMessages[parseInt((i as SelectMenuInteraction).values[0])].label)
- .setDescription(verifyMessages[parseInt((i as SelectMenuInteraction).values[0])].description)
- .setStatus("Success")
- .setEmoji("CONTROL.BLOCKTICK")
- ], components: [new MessageActionRow().addComponents([new MessageButton()
- .setLabel("Verify")
- .setEmoji(getEmojiByName("CONTROL.TICK", "id"))
- .setStyle("SUCCESS")
- .setCustomId("verifybutton")
- ])]});
+ i = await m.awaitMessageComponent({ time: 300000 });
+ } catch (e) {
break;
- } else if ((i.component as MessageActionRowComponent).customId === "blank") {
+ }
+ if (
+ (i.component as MessageActionRowComponent).customId ===
+ "template"
+ ) {
i.deferUpdate();
- await interaction.channel.send({components: [new MessageActionRow().addComponents([new MessageButton()
- .setLabel("Verify")
- .setEmoji(getEmojiByName("CONTROL.TICK", "id"))
- .setStyle("SUCCESS")
- .setCustomId("verifybutton")
- ])]});
+ await interaction.channel.send({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle(
+ verifyMessages[
+ parseInt(
+ (i as SelectMenuInteraction)
+ .values[0]
+ )
+ ].label
+ )
+ .setDescription(
+ verifyMessages[
+ parseInt(
+ (i as SelectMenuInteraction)
+ .values[0]
+ )
+ ].description
+ )
+ .setStatus("Success")
+ .setEmoji("CONTROL.BLOCKTICK")
+ ],
+ components: [
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setLabel("Verify")
+ .setEmoji(
+ getEmojiByName("CONTROL.TICK", "id")
+ )
+ .setStyle("SUCCESS")
+ .setCustomId("verifybutton")
+ ])
+ ]
+ });
break;
- } else if ((i.component as MessageActionRowComponent).customId === "custom") {
- await i.showModal(new Discord.Modal().setCustomId("modal").setTitle("Enter embed details").addComponents(
- new MessageActionRow<TextInputComponent>().addComponents(new TextInputComponent()
- .setCustomId("title")
- .setLabel("Title")
- .setMaxLength(256)
- .setRequired(true)
- .setStyle("SHORT")
- ),
- new MessageActionRow<TextInputComponent>().addComponents(new TextInputComponent()
- .setCustomId("description")
- .setLabel("Description")
- .setMaxLength(4000)
- .setRequired(true)
- .setStyle("PARAGRAPH")
- )
- ));
+ } else if (
+ (i.component as MessageActionRowComponent).customId ===
+ "blank"
+ ) {
+ i.deferUpdate();
+ await interaction.channel.send({
+ components: [
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setLabel("Verify")
+ .setEmoji(
+ getEmojiByName("CONTROL.TICK", "id")
+ )
+ .setStyle("SUCCESS")
+ .setCustomId("verifybutton")
+ ])
+ ]
+ });
+ break;
+ } else if (
+ (i.component as MessageActionRowComponent).customId ===
+ "custom"
+ ) {
+ await i.showModal(
+ new Discord.Modal()
+ .setCustomId("modal")
+ .setTitle("Enter embed details")
+ .addComponents(
+ new MessageActionRow<TextInputComponent>().addComponents(
+ new TextInputComponent()
+ .setCustomId("title")
+ .setLabel("Title")
+ .setMaxLength(256)
+ .setRequired(true)
+ .setStyle("SHORT")
+ ),
+ new MessageActionRow<TextInputComponent>().addComponents(
+ new TextInputComponent()
+ .setCustomId("description")
+ .setLabel("Description")
+ .setMaxLength(4000)
+ .setRequired(true)
+ .setStyle("PARAGRAPH")
+ )
+ )
+ );
await interaction.editReply({
- embeds: [new EmojiEmbed()
- .setTitle("Verify Button")
- .setDescription("Modal opened. If you can't see it, click back and try again.")
- .setStatus("Success")
- .setEmoji("GUILD.TICKET.OPEN")
- ], components: [new MessageActionRow().addComponents([new MessageButton()
- .setLabel("Back")
- .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
- .setStyle("PRIMARY")
- .setCustomId("back")
- ])]
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Verify Button")
+ .setDescription(
+ "Modal opened. If you can't see it, click back and try again."
+ )
+ .setStatus("Success")
+ .setEmoji("GUILD.TICKET.OPEN")
+ ],
+ components: [
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setLabel("Back")
+ .setEmoji(
+ getEmojiByName("CONTROL.LEFT", "id")
+ )
+ .setStyle("PRIMARY")
+ .setCustomId("back")
+ ])
+ ]
});
let out;
try {
- out = await modalInteractionCollector(m, (m) => m.channel.id === interaction.channel.id, (m) => m.customId === "modify");
- } catch (e) { break; }
+ out = await modalInteractionCollector(
+ m,
+ (m) => m.channel.id === interaction.channel.id,
+ (m) => m.customId === "modify"
+ );
+ } catch (e) {
+ break;
+ }
if (out.fields) {
const title = out.fields.getTextInputValue("title");
- const description = out.fields.getTextInputValue("description");
- await interaction.channel.send({embeds: [new EmojiEmbed()
- .setTitle(title)
- .setDescription(description)
- .setStatus("Success")
- .setEmoji("CONTROL.BLOCKTICK")
- ], components: [new MessageActionRow().addComponents([new MessageButton()
- .setLabel("Verify")
- .setEmoji(getEmojiByName("CONTROL.TICK", "id"))
- .setStyle("SUCCESS")
- .setCustomId("verifybutton")
- ])]});
+ const description =
+ out.fields.getTextInputValue("description");
+ await interaction.channel.send({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle(title)
+ .setDescription(description)
+ .setStatus("Success")
+ .setEmoji("CONTROL.BLOCKTICK")
+ ],
+ components: [
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setLabel("Verify")
+ .setEmoji(
+ getEmojiByName("CONTROL.TICK", "id")
+ )
+ .setStyle("SUCCESS")
+ .setCustomId("verifybutton")
+ ])
+ ]
+ });
break;
- } else { continue; }
+ } else {
+ continue;
+ }
}
}
} else {
@@ -239,12 +432,16 @@
break;
}
}
- await interaction.editReply({embeds: [(m.embeds[0] as MessageEmbed).setFooter({text: "Message closed"})], components: []});
+ await interaction.editReply({
+ embeds: [m.embeds[0]!.setFooter({ text: "Message closed" })],
+ components: []
+ });
};
const check = (interaction: CommandInteraction) => {
- const member = (interaction.member as Discord.GuildMember);
- if (!member.permissions.has("MANAGE_GUILD")) throw "You must have the *Manage Server* permission to use this command";
+ const member = interaction.member as Discord.GuildMember;
+ if (!member.permissions.has("MANAGE_GUILD"))
+ throw "You must have the *Manage Server* permission to use this command";
return true;
};
diff --git a/src/commands/settings/welcome.ts b/src/commands/settings/welcome.ts
index f22f409..3eb0ec5 100644
--- a/src/commands/settings/welcome.ts
+++ b/src/commands/settings/welcome.ts
@@ -1,5 +1,13 @@
import { LoadingEmbed } from "./../../utils/defaultEmbeds.js";
-import Discord, { Channel, CommandInteraction, Message, MessageActionRow, MessageButton, MessageComponentInteraction, Role } from "discord.js";
+import Discord, {
+ Channel,
+ CommandInteraction,
+ Message,
+ MessageActionRow,
+ MessageButton,
+ MessageComponentInteraction,
+ Role
+} from "discord.js";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import client from "../../utils/client.js";
@@ -11,19 +19,52 @@
const command = (builder: SlashCommandSubcommandBuilder) =>
builder
.setName("welcome")
- .setDescription("Messages and roles sent or given when someone joins the server")
- .addStringOption(option => option.setName("message").setDescription("The message to send when someone joins the server").setAutocomplete(true))
- .addRoleOption(option => option.setName("role").setDescription("The role given when someone joins the server"))
- .addRoleOption(option => option.setName("ping").setDescription("The role pinged when someone joins the server"))
- .addChannelOption(option => option.setName("channel").setDescription("The channel the welcome message should be sent to").addChannelTypes([
- ChannelType.GuildText, ChannelType.GuildNews
- ]));
+ .setDescription(
+ "Messages and roles sent or given when someone joins the server"
+ )
+ .addStringOption((option) =>
+ option
+ .setName("message")
+ .setDescription(
+ "The message to send when someone joins the server"
+ )
+ .setAutocomplete(true)
+ )
+ .addRoleOption((option) =>
+ option
+ .setName("role")
+ .setDescription("The role given when someone joins the server")
+ )
+ .addRoleOption((option) =>
+ option
+ .setName("ping")
+ .setDescription("The role pinged when someone joins the server")
+ )
+ .addChannelOption((option) =>
+ option
+ .setName("channel")
+ .setDescription(
+ "The channel the welcome message should be sent to"
+ )
+ .addChannelTypes([ChannelType.GuildText, ChannelType.GuildNews])
+ );
-const callback = async (interaction: CommandInteraction): Promise<void | unknown> => {
- const { renderRole, renderChannel, log, NucleusColors, entry, renderUser } = client.logger;
- await interaction.reply({embeds: LoadingEmbed, fetchReply: true, ephemeral: true});
+const callback = async (
+ interaction: CommandInteraction
+): Promise<void | unknown> => {
+ const { renderRole, renderChannel, log, NucleusColors, entry, renderUser } =
+ client.logger;
+ await interaction.reply({
+ embeds: LoadingEmbed,
+ fetchReply: true,
+ ephemeral: true
+ });
let m: Message;
- if (interaction.options.getRole("role") || interaction.options.getChannel("channel") || interaction.options.getString("message")) {
+ if (
+ interaction.options.getRole("role") ||
+ interaction.options.getChannel("channel") ||
+ interaction.options.getString("message")
+ ) {
let role: Role;
let ping: Role;
const message = interaction.options.getString("message");
@@ -31,32 +72,42 @@
role = interaction.options.getRole("role") as Role;
ping = interaction.options.getRole("ping") as Role;
} catch {
- return await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("GUILD.ROLES.DELETE")
- .setTitle("Welcome Events")
- .setDescription("The role you provided is not a valid role")
- .setStatus("Danger")
- ]});
+ return await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("GUILD.ROLES.DELETE")
+ .setTitle("Welcome Events")
+ .setDescription(
+ "The role you provided is not a valid role"
+ )
+ .setStatus("Danger")
+ ]
+ });
}
let channel: Channel;
try {
channel = interaction.options.getChannel("channel") as Channel;
} catch {
- return await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("GUILD.ROLES.DELETE")
- .setTitle("Welcome Events")
- .setDescription("The channel you provided is not a valid channel")
- .setStatus("Danger")
- ]});
+ return await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("GUILD.ROLES.DELETE")
+ .setTitle("Welcome Events")
+ .setDescription(
+ "The channel you provided is not a valid channel"
+ )
+ .setStatus("Danger")
+ ]
+ });
}
role = role as Discord.Role;
ping = ping as Discord.Role;
channel = channel as Discord.TextChannel;
const options = {};
- if (role) options["role"] = renderRole(role);
- if (ping) options["ping"] = renderRole(ping);
- if (channel) options["channel"] = renderChannel(channel);
- if (message) options["message"] = "\n> " + message;
+ if (role) options.role = renderRole(role);
+ if (ping) options.ping = renderRole(ping);
+ if (channel) options.channel = renderChannel(channel);
+ if (message) options.message = "\n> " + message;
const confirmation = await new confirmationMessage(interaction)
.setEmoji("GUILD.ROLES.EDIT")
.setTitle("Welcome Events")
@@ -72,17 +123,27 @@
if (ping) toChange["welcome.ping"] = ping.id;
if (channel) toChange["welcome.channel"] = channel.id;
if (message) toChange["welcome.message"] = message;
- await client.database.guilds.write(interaction.guild.id, toChange);
+ await client.database.guilds.write(
+ interaction.guild.id,
+ toChange
+ );
const list = {
- memberId: entry(interaction.user.id, `\`${interaction.user.id}\``),
- changedBy: entry(interaction.user.id, renderUser(interaction.user))
+ memberId: entry(
+ interaction.user.id,
+ `\`${interaction.user.id}\``
+ ),
+ changedBy: entry(
+ interaction.user.id,
+ renderUser(interaction.user)
+ )
};
- if (role) list["role"] = entry(role.id, renderRole(role));
- if (ping) list["ping"] = entry(ping.id, renderRole(ping));
- if (channel) list["channel"] = entry(channel.id, renderChannel(channel.id));
- if (message) list["message"] = entry(message, `\`${message}\``);
+ if (role) list.role = entry(role.id, renderRole(role));
+ if (ping) list.ping = entry(ping.id, renderRole(ping));
+ if (channel)
+ list.channel = entry(channel.id, renderChannel(channel.id));
+ if (message) list.message = entry(message, `\`${message}\``);
const data = {
- meta:{
+ meta: {
type: "welcomeSettingsUpdated",
displayName: "Welcome Settings Changed",
calculateType: "nucleusSettingsUpdated",
@@ -98,68 +159,128 @@
log(data);
} catch (e) {
console.log(e);
- return interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Welcome Events")
- .setDescription("Something went wrong while updating welcome settings")
- .setStatus("Danger")
- .setEmoji("GUILD.ROLES.DELETE")
- ], components: []});
+ return interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Welcome Events")
+ .setDescription(
+ "Something went wrong while updating welcome settings"
+ )
+ .setStatus("Danger")
+ .setEmoji("GUILD.ROLES.DELETE")
+ ],
+ components: []
+ });
}
} else {
- return interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Welcome Events")
- .setDescription("No changes were made")
- .setStatus("Success")
- .setEmoji("GUILD.ROLES.CREATE")
- ], components: []});
+ return interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Welcome Events")
+ .setDescription("No changes were made")
+ .setStatus("Success")
+ .setEmoji("GUILD.ROLES.CREATE")
+ ],
+ components: []
+ });
}
}
let lastClicked = null;
while (true) {
const config = await client.database.guilds.read(interaction.guild.id);
- m = await interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Welcome Events")
- .setDescription(
- `**Message:** ${config.welcome.message ? `\n> ${config.welcome.message}` : "*None set*"}\n` +
- `**Role:** ${config.welcome.role ? renderRole(await interaction.guild.roles.fetch(config.welcome.role)) : "*None set*"}\n` +
- `**Ping:** ${config.welcome.ping ? renderRole(await interaction.guild.roles.fetch(config.welcome.ping)) : "*None set*"}\n` +
- `**Channel:** ${config.welcome.channel ? (config.welcome.channel == "dm" ? "DM" : renderChannel(await interaction.guild.channels.fetch(config.welcome.channel))) : "*None set*"}`
- )
- .setStatus("Success")
- .setEmoji("CHANNEL.TEXT.CREATE")
- ], components: [
- new MessageActionRow().addComponents([
- new MessageButton()
- .setLabel(lastClicked == "clear-message" ? "Click again to confirm" : "Clear Message")
- .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
- .setCustomId("clear-message")
- .setDisabled(!config.welcome.message)
- .setStyle("DANGER"),
- new MessageButton()
- .setLabel(lastClicked == "clear-role" ? "Click again to confirm" : "Clear Role")
- .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
- .setCustomId("clear-role")
- .setDisabled(!config.welcome.role)
- .setStyle("DANGER"),
- new MessageButton()
- .setLabel(lastClicked == "clear-ping" ? "Click again to confirm" : "Clear Ping")
- .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
- .setCustomId("clear-ping")
- .setDisabled(!config.welcome.ping)
- .setStyle("DANGER"),
- new MessageButton()
- .setLabel(lastClicked == "clear-channel" ? "Click again to confirm" : "Clear Channel")
- .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
- .setCustomId("clear-channel")
- .setDisabled(!config.welcome.channel)
- .setStyle("DANGER"),
- new MessageButton()
- .setLabel("Set Channel to DM")
- .setCustomId("set-channel-dm")
- .setDisabled(config.welcome.channel == "dm")
- .setStyle("SECONDARY")
- ])
- ]}) as Message;
+ m = (await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Welcome Events")
+ .setDescription(
+ `**Message:** ${
+ config.welcome.message
+ ? `\n> ${config.welcome.message}`
+ : "*None set*"
+ }\n` +
+ `**Role:** ${
+ config.welcome.role
+ ? renderRole(
+ await interaction.guild.roles.fetch(
+ config.welcome.role
+ )
+ )
+ : "*None set*"
+ }\n` +
+ `**Ping:** ${
+ config.welcome.ping
+ ? renderRole(
+ await interaction.guild.roles.fetch(
+ config.welcome.ping
+ )
+ )
+ : "*None set*"
+ }\n` +
+ `**Channel:** ${
+ config.welcome.channel
+ ? config.welcome.channel == "dm"
+ ? "DM"
+ : renderChannel(
+ await interaction.guild.channels.fetch(
+ config.welcome.channel
+ )
+ )
+ : "*None set*"
+ }`
+ )
+ .setStatus("Success")
+ .setEmoji("CHANNEL.TEXT.CREATE")
+ ],
+ components: [
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setLabel(
+ lastClicked == "clear-message"
+ ? "Click again to confirm"
+ : "Clear Message"
+ )
+ .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
+ .setCustomId("clear-message")
+ .setDisabled(!config.welcome.message)
+ .setStyle("DANGER"),
+ new MessageButton()
+ .setLabel(
+ lastClicked == "clear-role"
+ ? "Click again to confirm"
+ : "Clear Role"
+ )
+ .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
+ .setCustomId("clear-role")
+ .setDisabled(!config.welcome.role)
+ .setStyle("DANGER"),
+ new MessageButton()
+ .setLabel(
+ lastClicked == "clear-ping"
+ ? "Click again to confirm"
+ : "Clear Ping"
+ )
+ .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
+ .setCustomId("clear-ping")
+ .setDisabled(!config.welcome.ping)
+ .setStyle("DANGER"),
+ new MessageButton()
+ .setLabel(
+ lastClicked == "clear-channel"
+ ? "Click again to confirm"
+ : "Clear Channel"
+ )
+ .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
+ .setCustomId("clear-channel")
+ .setDisabled(!config.welcome.channel)
+ .setStyle("DANGER"),
+ new MessageButton()
+ .setLabel("Set Channel to DM")
+ .setCustomId("set-channel-dm")
+ .setDisabled(config.welcome.channel == "dm")
+ .setStyle("SECONDARY")
+ ])
+ ]
+ })) as Message;
let i: MessageComponentInteraction;
try {
i = await m.awaitMessageComponent({ time: 300000 });
@@ -169,35 +290,57 @@
i.deferUpdate();
if (i.customId == "clear-message") {
if (lastClicked == "clear-message") {
- await client.database.guilds.write(interaction.guild.id, {"welcome.message": null});
+ await client.database.guilds.write(interaction.guild.id, {
+ "welcome.message": null
+ });
lastClicked = null;
- } else { lastClicked = "clear-message"; }
+ } else {
+ lastClicked = "clear-message";
+ }
} else if (i.customId == "clear-role") {
if (lastClicked == "clear-role") {
- await client.database.guilds.write(interaction.guild.id, {"welcome.role": null});
+ await client.database.guilds.write(interaction.guild.id, {
+ "welcome.role": null
+ });
lastClicked = null;
- } else { lastClicked = "clear-role"; }
+ } else {
+ lastClicked = "clear-role";
+ }
} else if (i.customId == "clear-ping") {
if (lastClicked == "clear-ping") {
- await client.database.guilds.write(interaction.guild.id, {"welcome.ping": null});
+ await client.database.guilds.write(interaction.guild.id, {
+ "welcome.ping": null
+ });
lastClicked = null;
- } else { lastClicked = "clear-ping"; }
+ } else {
+ lastClicked = "clear-ping";
+ }
} else if (i.customId == "clear-channel") {
if (lastClicked == "clear-channel") {
- await client.database.guilds.write(interaction.guild.id, {"welcome.channel": null});
+ await client.database.guilds.write(interaction.guild.id, {
+ "welcome.channel": null
+ });
lastClicked = null;
- } else { lastClicked = "clear-channel"; }
+ } else {
+ lastClicked = "clear-channel";
+ }
} else if (i.customId == "set-channel-dm") {
- await client.database.guilds.write(interaction.guild.id, {"welcome.channel": "dm"});
+ await client.database.guilds.write(interaction.guild.id, {
+ "welcome.channel": "dm"
+ });
lastClicked = null;
}
}
- await interaction.editReply({embeds: [m.embeds[0].setFooter({text: "Message closed"})], components: []});
+ await interaction.editReply({
+ embeds: [m.embeds[0].setFooter({ text: "Message closed" })],
+ components: []
+ });
};
const check = (interaction: CommandInteraction) => {
- const member = (interaction.member as Discord.GuildMember);
- if (!member.permissions.has("MANAGE_GUILD")) throw "You must have the *Manage Server* permission to use this command";
+ const member = interaction.member as Discord.GuildMember;
+ if (!member.permissions.has("MANAGE_GUILD"))
+ throw "You must have the *Manage Server* permission to use this command";
return true;
};
diff --git a/src/commands/tag.ts b/src/commands/tag.ts
index adaf2cc..34c3152 100644
--- a/src/commands/tag.ts
+++ b/src/commands/tag.ts
@@ -1,4 +1,9 @@
-import { AutocompleteInteraction, CommandInteraction, MessageActionRow, MessageButton } from "discord.js";
+import {
+ AutocompleteInteraction,
+ CommandInteraction,
+ MessageActionRow,
+ MessageButton
+} from "discord.js";
import { SlashCommandBuilder } from "@discordjs/builders";
import client from "../utils/client.js";
import EmojiEmbed from "../utils/generateEmojiEmbed.js";
@@ -6,45 +11,68 @@
const command = new SlashCommandBuilder()
.setName("tag")
.setDescription("Get and manage the servers tags")
- .addStringOption(o => o.setName("tag").setDescription("The tag to get").setAutocomplete(true).setRequired(true));
+ .addStringOption((o) =>
+ o
+ .setName("tag")
+ .setDescription("The tag to get")
+ .setAutocomplete(true)
+ .setRequired(true)
+ );
const callback = async (interaction: CommandInteraction): Promise<void> => {
const config = await client.database.guilds.read(interaction.guild.id);
const tags = config.getKey("tags");
const tag = tags[interaction.options.getString("tag")];
if (!tag) {
- return await interaction.reply({embeds: [new EmojiEmbed()
- .setTitle("Tag")
- .setDescription(`Tag \`${interaction.options.getString("tag")}\` does not exist`)
- .setEmoji("PUNISH.NICKNAME.RED")
- .setStatus("Danger")
- ], ephemeral: true});
+ return await interaction.reply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Tag")
+ .setDescription(
+ `Tag \`${interaction.options.getString(
+ "tag"
+ )}\` does not exist`
+ )
+ .setEmoji("PUNISH.NICKNAME.RED")
+ .setStatus("Danger")
+ ],
+ ephemeral: true
+ });
}
let url = "";
let components = [];
if (tag.match(/^(http|https):\/\/[^ "]+$/)) {
url = tag;
- components = [new MessageActionRow().addComponents([new MessageButton()
- .setLabel("Open")
- .setURL(url)
- .setStyle("LINK")
- ])];
+ components = [
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setLabel("Open")
+ .setURL(url)
+ .setStyle("LINK")
+ ])
+ ];
}
- return await interaction.reply({embeds: [new EmojiEmbed()
- .setTitle(interaction.options.getString("tag"))
- .setDescription(tag)
- .setEmoji("PUNISH.NICKNAME.GREEN")
- .setStatus("Success")
- .setImage(url)
- ], components: components, ephemeral: true});
-
+ return await interaction.reply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle(interaction.options.getString("tag"))
+ .setDescription(tag)
+ .setEmoji("PUNISH.NICKNAME.GREEN")
+ .setStatus("Success")
+ .setImage(url)
+ ],
+ components: components,
+ ephemeral: true
+ });
};
const check = () => {
return true;
};
-const autocomplete = async (interaction: AutocompleteInteraction): Promise<string[]> => {
+const autocomplete = async (
+ interaction: AutocompleteInteraction
+): Promise<string[]> => {
if (!interaction.guild) return [];
const config = await client.database.guilds.read(interaction.guild.id);
const tags = Object.keys(config.getKey("tags"));
diff --git a/src/commands/tags/_meta.ts b/src/commands/tags/_meta.ts
index 8c07682..2ce5318 100644
--- a/src/commands/tags/_meta.ts
+++ b/src/commands/tags/_meta.ts
@@ -1,4 +1,4 @@
const name = "tags";
const description = "manage server tags";
-export { name, description };
\ No newline at end of file
+export { name, description };
diff --git a/src/commands/tags/create.ts b/src/commands/tags/create.ts
index 4aaa49d..5d6621b 100644
--- a/src/commands/tags/create.ts
+++ b/src/commands/tags/create.ts
@@ -9,76 +9,132 @@
builder
.setName("create")
.setDescription("Creates a tag")
- .addStringOption(o => o.setName("name").setRequired(true).setDescription("The name of the tag"))
- .addStringOption(o => o.setName("value").setRequired(true).setDescription("The value of the tag, shown after running /tag name"));
+ .addStringOption((o) =>
+ o
+ .setName("name")
+ .setRequired(true)
+ .setDescription("The name of the tag")
+ )
+ .addStringOption((o) =>
+ o
+ .setName("value")
+ .setRequired(true)
+ .setDescription(
+ "The value of the tag, shown after running /tag name"
+ )
+ );
-const callback = async (interaction: CommandInteraction): Promise<void | unknown> => {
+const callback = async (
+ interaction: CommandInteraction
+): Promise<void | unknown> => {
const name = interaction.options.getString("name");
const value = interaction.options.getString("value");
- if (name.length > 100) return await interaction.reply({embeds: [new EmojiEmbed()
- .setTitle("Tag Create")
- .setDescription("Tag names cannot be longer than 100 characters")
- .setStatus("Danger")
- .setEmoji("PUNISH.NICKNAME.RED")
- ], ephemeral: true});
- if (value.length > 1000) return await interaction.reply({embeds: [new EmojiEmbed()
- .setTitle("Tag Create")
- .setDescription("Tag values cannot be longer than 1000 characters")
- .setStatus("Danger")
- .setEmoji("PUNISH.NICKNAME.RED")
- ], ephemeral: true});
+ if (name.length > 100)
+ return await interaction.reply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Tag Create")
+ .setDescription(
+ "Tag names cannot be longer than 100 characters"
+ )
+ .setStatus("Danger")
+ .setEmoji("PUNISH.NICKNAME.RED")
+ ],
+ ephemeral: true
+ });
+ if (value.length > 1000)
+ return await interaction.reply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Tag Create")
+ .setDescription(
+ "Tag values cannot be longer than 1000 characters"
+ )
+ .setStatus("Danger")
+ .setEmoji("PUNISH.NICKNAME.RED")
+ ],
+ ephemeral: true
+ });
const data = await client.database.guilds.read(interaction.guild.id);
- if (data.tags.length >= 100) return await interaction.reply({embeds: [new EmojiEmbed()
- .setTitle("Tag Create")
- .setDescription("You cannot have more than 100 tags")
- .setStatus("Danger")
- .setEmoji("PUNISH.NICKNAME.RED")
- ], ephemeral: true});
- if (data.tags[name]) return await interaction.reply({embeds: [new EmojiEmbed()
- .setTitle("Tag Create")
- .setDescription("That tag already exists")
- .setStatus("Danger")
- .setEmoji("PUNISH.NICKNAME.RED")
- ], ephemeral: true});
+ if (data.tags.length >= 100)
+ return await interaction.reply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Tag Create")
+ .setDescription("You cannot have more than 100 tags")
+ .setStatus("Danger")
+ .setEmoji("PUNISH.NICKNAME.RED")
+ ],
+ ephemeral: true
+ });
+ if (data.tags[name])
+ return await interaction.reply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Tag Create")
+ .setDescription("That tag already exists")
+ .setStatus("Danger")
+ .setEmoji("PUNISH.NICKNAME.RED")
+ ],
+ ephemeral: true
+ });
const confirmation = await new confirmationMessage(interaction)
.setEmoji("PUNISH.NICKNAME.YELLOW")
.setTitle("Tag create")
- .setDescription(keyValueList({
- "name": `${name}`,
- "value": `\n> ${value}`
- })
- + "\nAre you sure you want to create this tag?")
+ .setDescription(
+ keyValueList({
+ name: `${name}`,
+ value: `\n> ${value}`
+ }) + "\nAre you sure you want to create this tag?"
+ )
.setColor("Warning")
.setInverted(true)
.send();
if (confirmation.cancelled) return;
- if (!confirmation) return await interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Tag Create")
- .setDescription("No changes were made")
- .setStatus("Success")
- .setEmoji("PUNISH.NICKNAME.GREEN")
- ]});
+ if (!confirmation)
+ return await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Tag Create")
+ .setDescription("No changes were made")
+ .setStatus("Success")
+ .setEmoji("PUNISH.NICKNAME.GREEN")
+ ]
+ });
try {
- await client.database.guilds.write(interaction.guild.id, {[`tags.${name}`]: value});
+ await client.database.guilds.write(interaction.guild.id, {
+ [`tags.${name}`]: value
+ });
} catch (e) {
- return await interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Tag Create")
- .setDescription("Something went wrong and the tag was not created")
- .setStatus("Danger")
- .setEmoji("PUNISH.NICKNAME.RED")
- ], components: []});
+ return await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Tag Create")
+ .setDescription(
+ "Something went wrong and the tag was not created"
+ )
+ .setStatus("Danger")
+ .setEmoji("PUNISH.NICKNAME.RED")
+ ],
+ components: []
+ });
}
- return await interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Tag Create")
- .setDescription("Tag created")
- .setStatus("Success")
- .setEmoji("PUNISH.NICKNAME.GREEN")
- ], components: []});
+ return await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Tag Create")
+ .setDescription("Tag created")
+ .setStatus("Success")
+ .setEmoji("PUNISH.NICKNAME.GREEN")
+ ],
+ components: []
+ });
};
const check = (interaction: CommandInteraction) => {
- const member = (interaction.member as Discord.GuildMember);
- if (!member.permissions.has("MANAGE_MESSAGES")) throw "You must have the *Manage Messages* permission to use this command";
+ const member = interaction.member as Discord.GuildMember;
+ if (!member.permissions.has("MANAGE_MESSAGES"))
+ throw "You must have the *Manage Messages* permission to use this command";
return true;
};
diff --git a/src/commands/tags/delete.ts b/src/commands/tags/delete.ts
index 3509dcc..4d1a1aa 100644
--- a/src/commands/tags/delete.ts
+++ b/src/commands/tags/delete.ts
@@ -9,57 +9,87 @@
builder
.setName("delete")
.setDescription("Deletes a tag")
- .addStringOption(o => o.setName("name").setRequired(true).setDescription("The name of the tag"));
+ .addStringOption((o) =>
+ o
+ .setName("name")
+ .setRequired(true)
+ .setDescription("The name of the tag")
+ );
-const callback = async (interaction: CommandInteraction): Promise<void | unknown> => {
+const callback = async (
+ interaction: CommandInteraction
+): Promise<void | unknown> => {
const name = interaction.options.getString("name");
const data = await client.database.guilds.read(interaction.guild.id);
- if (!data.tags[name]) return await interaction.reply({embeds: [new EmojiEmbed()
- .setTitle("Tags")
- .setDescription("That tag does not exist")
- .setStatus("Danger")
- .setEmoji("PUNISH.NICKNAME.RED")
- ], ephemeral: true});
+ if (!data.tags[name])
+ return await interaction.reply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Tags")
+ .setDescription("That tag does not exist")
+ .setStatus("Danger")
+ .setEmoji("PUNISH.NICKNAME.RED")
+ ],
+ ephemeral: true
+ });
const confirmation = await new confirmationMessage(interaction)
.setEmoji("PUNISH.NICKNAME.YELLOW")
.setTitle("Tag Delete")
- .setDescription(keyValueList({
- "name": `${name}`,
- "value": `\n> ${data.tags[name]}`
- })
- + "\nAre you sure you want to delete this tag?")
+ .setDescription(
+ keyValueList({
+ name: `${name}`,
+ value: `\n> ${data.tags[name]}`
+ }) + "\nAre you sure you want to delete this tag?"
+ )
.setColor("Warning")
.setInverted(true)
.send();
if (confirmation.cancelled) return;
- if (!confirmation) return await interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Tag Delete")
- .setDescription("No changes were made")
- .setStatus("Success")
- .setEmoji("PUNISH.NICKNAME.GREEN")
- ]});
+ if (!confirmation)
+ return await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Tag Delete")
+ .setDescription("No changes were made")
+ .setStatus("Success")
+ .setEmoji("PUNISH.NICKNAME.GREEN")
+ ]
+ });
try {
- await client.database.guilds.write(interaction.guild.id, null, ["tags." + name]);
+ await client.database.guilds.write(interaction.guild.id, null, [
+ "tags." + name
+ ]);
} catch (e) {
console.log(e);
- return await interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Tag Delete")
- .setDescription("Something went wrong and the tag was not deleted")
- .setStatus("Danger")
- .setEmoji("PUNISH.NICKNAME.RED")
- ], components: []});
+ return await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Tag Delete")
+ .setDescription(
+ "Something went wrong and the tag was not deleted"
+ )
+ .setStatus("Danger")
+ .setEmoji("PUNISH.NICKNAME.RED")
+ ],
+ components: []
+ });
}
- return await interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Tag Delete")
- .setDescription("Tag deleted")
- .setStatus("Success")
- .setEmoji("PUNISH.NICKNAME.GREEN")
- ], components: []});
+ return await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Tag Delete")
+ .setDescription("Tag deleted")
+ .setStatus("Success")
+ .setEmoji("PUNISH.NICKNAME.GREEN")
+ ],
+ components: []
+ });
};
const check = (interaction: CommandInteraction) => {
- const member = (interaction.member as Discord.GuildMember);
- if (!member.permissions.has("MANAGE_MESSAGES")) throw "You must have the *Manage Messages* permission to use this command";
+ const member = interaction.member as Discord.GuildMember;
+ if (!member.permissions.has("MANAGE_MESSAGES"))
+ throw "You must have the *Manage Messages* permission to use this command";
return true;
};
diff --git a/src/commands/tags/edit.ts b/src/commands/tags/edit.ts
index b9cdddf..192a2d4 100644
--- a/src/commands/tags/edit.ts
+++ b/src/commands/tags/edit.ts
@@ -9,63 +9,112 @@
builder
.setName("edit")
.setDescription("Edits or renames a tag")
- .addStringOption(o => o.setName("name").setRequired(true).setDescription("The tag to edit"))
- .addStringOption(o => o.setName("value").setRequired(false).setDescription("The new value of the tag / Rename"))
- .addStringOption(o => o.setName("newname").setRequired(false).setDescription("The new name of the tag / Edit"));
+ .addStringOption((o) =>
+ o
+ .setName("name")
+ .setRequired(true)
+ .setDescription("The tag to edit")
+ )
+ .addStringOption((o) =>
+ o
+ .setName("value")
+ .setRequired(false)
+ .setDescription("The new value of the tag / Rename")
+ )
+ .addStringOption((o) =>
+ o
+ .setName("newname")
+ .setRequired(false)
+ .setDescription("The new name of the tag / Edit")
+ );
const callback = async (interaction: CommandInteraction): Promise<void> => {
const name = interaction.options.getString("name");
const value = interaction.options.getString("value") || "";
const newname = interaction.options.getString("newname") || "";
- if (!newname && !value) return await interaction.reply({embeds: [new EmojiEmbed()
- .setTitle("Tag Edit")
- .setDescription("You must specify a value or a new name")
- .setStatus("Danger")
- .setEmoji("PUNISH.NICKNAME.RED")
- ], ephemeral: true});
- if (newname.length > 100) return await interaction.reply({embeds: [new EmojiEmbed()
- .setTitle("Tag Edit")
- .setDescription("Tag names cannot be longer than 100 characters")
- .setStatus("Danger")
- .setEmoji("PUNISH.NICKNAME.RED")
- ], ephemeral: true});
- if (value.length > 2000) return await interaction.reply({embeds: [new EmojiEmbed()
- .setTitle("Tag Edit")
- .setDescription("Tag values cannot be longer than 2000 characters")
- .setStatus("Danger")
- .setEmoji("PUNISH.NICKNAME.RED")
- ], ephemeral: true});
+ if (!newname && !value)
+ return await interaction.reply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Tag Edit")
+ .setDescription("You must specify a value or a new name")
+ .setStatus("Danger")
+ .setEmoji("PUNISH.NICKNAME.RED")
+ ],
+ ephemeral: true
+ });
+ if (newname.length > 100)
+ return await interaction.reply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Tag Edit")
+ .setDescription(
+ "Tag names cannot be longer than 100 characters"
+ )
+ .setStatus("Danger")
+ .setEmoji("PUNISH.NICKNAME.RED")
+ ],
+ ephemeral: true
+ });
+ if (value.length > 2000)
+ return await interaction.reply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Tag Edit")
+ .setDescription(
+ "Tag values cannot be longer than 2000 characters"
+ )
+ .setStatus("Danger")
+ .setEmoji("PUNISH.NICKNAME.RED")
+ ],
+ ephemeral: true
+ });
const data = await client.database.guilds.read(interaction.guild.id);
- if (!data.tags[name]) return await interaction.reply({embeds: [new EmojiEmbed()
- .setTitle("Tag Edit")
- .setDescription("That tag does not exist")
- .setStatus("Danger")
- .setEmoji("PUNISH.NICKNAME.RED")
- ], ephemeral: true});
- if (newname && newname !== name && data.tags[newname]) return await interaction.reply({embeds: [new EmojiEmbed()
- .setTitle("Tag Edit")
- .setDescription("A tag with that name already exists")
- .setStatus("Danger")
- .setEmoji("PUNISH.NICKNAME.RED")
- ], ephemeral: true});
+ if (!data.tags[name])
+ return await interaction.reply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Tag Edit")
+ .setDescription("That tag does not exist")
+ .setStatus("Danger")
+ .setEmoji("PUNISH.NICKNAME.RED")
+ ],
+ ephemeral: true
+ });
+ if (newname && newname !== name && data.tags[newname])
+ return await interaction.reply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Tag Edit")
+ .setDescription("A tag with that name already exists")
+ .setStatus("Danger")
+ .setEmoji("PUNISH.NICKNAME.RED")
+ ],
+ ephemeral: true
+ });
const confirmation = await new confirmationMessage(interaction)
.setEmoji("PUNISH.NICKNAME.YELLOW")
.setTitle("Tag Edit")
- .setDescription(keyValueList({
- "name": `${name}` + (newname ? ` -> ${newname}` : ""),
- "value": `\n> ${value ? value : data.tags[name]}`
- })
- + "\nAre you sure you want to edit this tag?")
+ .setDescription(
+ keyValueList({
+ name: `${name}` + (newname ? ` -> ${newname}` : ""),
+ value: `\n> ${value ? value : data.tags[name]}`
+ }) + "\nAre you sure you want to edit this tag?"
+ )
.setColor("Warning")
.setInverted(true)
.send();
if (confirmation.cancelled) return;
- if (!confirmation) return await interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Tag Edit")
- .setDescription("No changes were made")
- .setStatus("Success")
- .setEmoji("PUNISH.NICKNAME.GREEN")
- ]});
+ if (!confirmation)
+ return await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Tag Edit")
+ .setDescription("No changes were made")
+ .setStatus("Success")
+ .setEmoji("PUNISH.NICKNAME.GREEN")
+ ]
+ });
try {
const toSet = {};
const toUnset = [];
@@ -74,26 +123,41 @@
toUnset.push(`tags.${name}`);
toSet[`tags.${newname}`] = data.tags[name];
}
- await client.database.guilds.write(interaction.guild.id, toSet === {} ? null : toSet, toUnset);
+ await client.database.guilds.write(
+ interaction.guild.id,
+ toSet === {} ? null : toSet,
+ toUnset
+ );
} catch (e) {
- return await interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Tag Edit")
- .setDescription("Something went wrong and the tag was not edited")
- .setStatus("Danger")
- .setEmoji("PUNISH.NICKNAME.RED")
- ], components: []});
+ return await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Tag Edit")
+ .setDescription(
+ "Something went wrong and the tag was not edited"
+ )
+ .setStatus("Danger")
+ .setEmoji("PUNISH.NICKNAME.RED")
+ ],
+ components: []
+ });
}
- return await interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Tags")
- .setDescription("Tag edited successfully")
- .setStatus("Success")
- .setEmoji("PUNISH.NICKNAME.GREEN")
- ], components: []});
+ return await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Tags")
+ .setDescription("Tag edited successfully")
+ .setStatus("Success")
+ .setEmoji("PUNISH.NICKNAME.GREEN")
+ ],
+ components: []
+ });
};
const check = (interaction: CommandInteraction) => {
- const member = (interaction.member as Discord.GuildMember);
- if (!member.permissions.has("MANAGE_MESSAGES")) throw "You must have the *Manage Messages* permission to use this command";
+ const member = interaction.member as Discord.GuildMember;
+ if (!member.permissions.has("MANAGE_MESSAGES"))
+ throw "You must have the *Manage Messages* permission to use this command";
return true;
};
diff --git a/src/commands/tags/list.ts b/src/commands/tags/list.ts
index 1a6c22c..070aa8b 100644
--- a/src/commands/tags/list.ts
+++ b/src/commands/tags/list.ts
@@ -1,5 +1,13 @@
import { LoadingEmbed } from "./../../utils/defaultEmbeds.js";
-import Discord, { CommandInteraction, Message, MessageActionRow, MessageActionRowComponent, MessageButton, MessageComponentInteraction, SelectMenuInteraction } from "discord.js";
+import Discord, {
+ CommandInteraction,
+ Message,
+ MessageActionRow,
+ MessageActionRowComponent,
+ MessageButton,
+ MessageComponentInteraction,
+ SelectMenuInteraction
+} from "discord.js";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import client from "../../utils/client.js";
@@ -7,22 +15,31 @@
import getEmojiByName from "../../utils/getEmojiByName.js";
import createPageIndicator from "../../utils/createPageIndicator.js";
-
class Embed {
embed: Discord.MessageEmbed;
title: string;
description = "";
pageId = 0;
- setEmbed(embed: Discord.MessageEmbed) { this.embed = embed; return this; }
- setTitle(title: string) { this.title = title; return this; }
- setDescription(description: string) { this.description = description; return this; }
- setPageId(pageId: number) { this.pageId = pageId; return this; }
+ setEmbed(embed: Discord.MessageEmbed) {
+ this.embed = embed;
+ return this;
+ }
+ setTitle(title: string) {
+ this.title = title;
+ return this;
+ }
+ setDescription(description: string) {
+ this.description = description;
+ return this;
+ }
+ setPageId(pageId: number) {
+ this.pageId = pageId;
+ return this;
+ }
}
const command = (builder: SlashCommandSubcommandBuilder) =>
- builder
- .setName("list")
- .setDescription("Lists all tags in the server");
+ builder.setName("list").setDescription("Lists all tags in the server");
const callback = async (interaction: CommandInteraction): Promise<void> => {
const data = await client.database.guilds.read(interaction.guild.id);
@@ -44,15 +61,24 @@
const pages = [];
for (const string of strings) {
- pages.push(new Embed()
- .setEmbed(new EmojiEmbed()
- .setTitle("Tags")
- .setDescription(string)
- .setEmoji("PUNISH.NICKNAME.GREEN")
- .setStatus("Success")
- ).setTitle(`Page ${pages.length + 1}`).setPageId(pages.length));
+ pages.push(
+ new Embed()
+ .setEmbed(
+ new EmojiEmbed()
+ .setTitle("Tags")
+ .setDescription(string)
+ .setEmoji("PUNISH.NICKNAME.GREEN")
+ .setStatus("Success")
+ )
+ .setTitle(`Page ${pages.length + 1}`)
+ .setPageId(pages.length)
+ );
}
- const m = await interaction.reply({embeds: LoadingEmbed, fetchReply: true, ephemeral: true}) as Message;
+ const m = (await interaction.reply({
+ embeds: LoadingEmbed,
+ fetchReply: true,
+ ephemeral: true
+ })) as Message;
let page = 0;
let selectPaneOpen = false;
while (true) {
@@ -60,72 +86,150 @@
if (selectPaneOpen) {
const options = [];
- pages.forEach(embed => {
- options.push(new SelectMenuOption({
- label: embed.title,
- value: embed.pageId.toString(),
- description: embed.description || ""
- }));
+ pages.forEach((embed) => {
+ options.push(
+ new SelectMenuOption({
+ label: embed.title,
+ value: embed.pageId.toString(),
+ description: embed.description || ""
+ })
+ );
});
- selectPane = [new MessageActionRow().addComponents([
- new Discord.MessageSelectMenu()
- .addOptions(options)
- .setCustomId("page")
- .setMaxValues(1)
- .setPlaceholder("Choose a page...")
- ])];
+ selectPane = [
+ new MessageActionRow().addComponents([
+ new Discord.MessageSelectMenu()
+ .addOptions(options)
+ .setCustomId("page")
+ .setMaxValues(1)
+ .setPlaceholder("Choose a page...")
+ ])
+ ];
}
const em = new Discord.MessageEmbed(pages[page].embed);
- em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page));
+ em.setDescription(
+ em.description + "\n\n" + createPageIndicator(pages.length, page)
+ );
await interaction.editReply({
embeds: [em],
- components: selectPane.concat([new MessageActionRow().addComponents([
- new MessageButton().setCustomId("left").setEmoji(getEmojiByName("CONTROL.LEFT", "id")).setStyle("SECONDARY").setDisabled(page === 0),
- new MessageButton().setCustomId("select").setEmoji(getEmojiByName("CONTROL.MENU", "id")).setStyle(selectPaneOpen ? "PRIMARY" : "SECONDARY").setDisabled(false),
- new MessageButton().setCustomId("right").setEmoji(getEmojiByName("CONTROL.RIGHT", "id")).setStyle("SECONDARY").setDisabled(page === pages.length - 1),
- new MessageButton().setCustomId("close").setEmoji(getEmojiByName("CONTROL.CROSS", "id")).setStyle("DANGER")
- ])])
+ components: selectPane.concat([
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setCustomId("left")
+ .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
+ .setStyle("SECONDARY")
+ .setDisabled(page === 0),
+ new MessageButton()
+ .setCustomId("select")
+ .setEmoji(getEmojiByName("CONTROL.MENU", "id"))
+ .setStyle(selectPaneOpen ? "PRIMARY" : "SECONDARY")
+ .setDisabled(false),
+ new MessageButton()
+ .setCustomId("right")
+ .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
+ .setStyle("SECONDARY")
+ .setDisabled(page === pages.length - 1),
+ new MessageButton()
+ .setCustomId("close")
+ .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
+ .setStyle("DANGER")
+ ])
+ ])
});
let i: MessageComponentInteraction;
try {
- i = await m.awaitMessageComponent({time: 300000 });
- } catch (e) { break; }
+ i = await m.awaitMessageComponent({ time: 300000 });
+ } catch (e) {
+ break;
+ }
i.deferUpdate();
if ((i.component as MessageActionRowComponent).customId === "left") {
if (page > 0) page--;
selectPaneOpen = false;
- } else if ((i.component as MessageActionRowComponent).customId === "right") {
+ } else if (
+ (i.component as MessageActionRowComponent).customId === "right"
+ ) {
if (page < pages.length - 1) page++;
selectPaneOpen = false;
- } else if ((i.component as MessageActionRowComponent).customId === "select") {
+ } else if (
+ (i.component as MessageActionRowComponent).customId === "select"
+ ) {
selectPaneOpen = !selectPaneOpen;
- } else if ((i.component as MessageActionRowComponent).customId === "page") {
+ } else if (
+ (i.component as MessageActionRowComponent).customId === "page"
+ ) {
page = parseInt((i as SelectMenuInteraction).values[0]);
selectPaneOpen = false;
} else {
const em = new Discord.MessageEmbed(pages[page].embed);
- em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page) + " | Message closed");
+ em.setDescription(
+ em.description +
+ "\n\n" +
+ createPageIndicator(pages.length, page) +
+ " | Message closed"
+ );
await interaction.editReply({
- embeds: [em], components: [new MessageActionRow().addComponents([
- new MessageButton().setCustomId("left").setEmoji(getEmojiByName("CONTROL.LEFT", "id")).setStyle("SECONDARY").setDisabled(true),
- new MessageButton().setCustomId("select").setEmoji(getEmojiByName("CONTROL.MENU", "id")).setStyle(selectPaneOpen ? "PRIMARY" : "SECONDARY").setDisabled(true),
- new MessageButton().setCustomId("right").setEmoji(getEmojiByName("CONTROL.RIGHT", "id")).setStyle("SECONDARY").setDisabled(true),
- new MessageButton().setCustomId("close").setEmoji(getEmojiByName("CONTROL.CROSS", "id")).setStyle("DANGER").setDisabled(true)
- ])]
+ embeds: [em],
+ components: [
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setCustomId("left")
+ .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
+ .setStyle("SECONDARY")
+ .setDisabled(true),
+ new MessageButton()
+ .setCustomId("select")
+ .setEmoji(getEmojiByName("CONTROL.MENU", "id"))
+ .setStyle(selectPaneOpen ? "PRIMARY" : "SECONDARY")
+ .setDisabled(true),
+ new MessageButton()
+ .setCustomId("right")
+ .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
+ .setStyle("SECONDARY")
+ .setDisabled(true),
+ new MessageButton()
+ .setCustomId("close")
+ .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
+ .setStyle("DANGER")
+ .setDisabled(true)
+ ])
+ ]
});
return;
}
}
const em = new Discord.MessageEmbed(pages[page].embed);
- em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page) + " | Message timed out");
+ em.setDescription(
+ em.description +
+ "\n\n" +
+ createPageIndicator(pages.length, page) +
+ " | Message timed out"
+ );
await interaction.editReply({
embeds: [em],
- components: [new MessageActionRow().addComponents([
- new MessageButton().setCustomId("left").setEmoji(getEmojiByName("CONTROL.LEFT", "id")).setStyle("SECONDARY").setDisabled(true),
- new MessageButton().setCustomId("select").setEmoji(getEmojiByName("CONTROL.MENU", "id")).setStyle("SECONDARY").setDisabled(true),
- new MessageButton().setCustomId("right").setEmoji(getEmojiByName("CONTROL.RIGHT", "id")).setStyle("SECONDARY").setDisabled(true),
- new MessageButton().setCustomId("close").setEmoji(getEmojiByName("CONTROL.CROSS", "id")).setStyle("DANGER").setDisabled(true)
- ])]
+ components: [
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setCustomId("left")
+ .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
+ .setStyle("SECONDARY")
+ .setDisabled(true),
+ new MessageButton()
+ .setCustomId("select")
+ .setEmoji(getEmojiByName("CONTROL.MENU", "id"))
+ .setStyle("SECONDARY")
+ .setDisabled(true),
+ new MessageButton()
+ .setCustomId("right")
+ .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
+ .setStyle("SECONDARY")
+ .setDisabled(true),
+ new MessageButton()
+ .setCustomId("close")
+ .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
+ .setStyle("DANGER")
+ .setDisabled(true)
+ ])
+ ]
});
};
diff --git a/src/commands/ticket/_meta.ts b/src/commands/ticket/_meta.ts
index 8c21466..e484928 100644
--- a/src/commands/ticket/_meta.ts
+++ b/src/commands/ticket/_meta.ts
@@ -1,4 +1,4 @@
const name = "ticket";
const description = "Manage modmail tickets";
-export { name, description };
\ No newline at end of file
+export { name, description };
diff --git a/src/commands/ticket/close.ts b/src/commands/ticket/close.ts
index ed27abc..71044dd 100644
--- a/src/commands/ticket/close.ts
+++ b/src/commands/ticket/close.ts
@@ -3,9 +3,7 @@
import close from "../../actions/tickets/delete.js";
const command = (builder: SlashCommandSubcommandBuilder) =>
- builder
- .setName("close")
- .setDescription("Closes a ticket");
+ builder.setName("close").setDescription("Closes a ticket");
const callback = async (interaction: CommandInteraction): Promise<void> => {
await close(interaction);
diff --git a/src/commands/ticket/create.ts b/src/commands/ticket/create.ts
index 55962d7..10ec842 100644
--- a/src/commands/ticket/create.ts
+++ b/src/commands/ticket/create.ts
@@ -6,7 +6,12 @@
builder
.setName("create")
.setDescription("Creates a new modmail ticket")
- .addStringOption(option => option.setName("message").setDescription("The content of the ticket").setRequired(false));
+ .addStringOption((option) =>
+ option
+ .setName("message")
+ .setDescription("The content of the ticket")
+ .setRequired(false)
+ );
const callback = async (interaction: CommandInteraction): Promise<void> => {
await create(interaction);
diff --git a/src/commands/user/_meta.ts b/src/commands/user/_meta.ts
index 6c14052..8677d79 100644
--- a/src/commands/user/_meta.ts
+++ b/src/commands/user/_meta.ts
@@ -1,4 +1,4 @@
const name = "user";
const description = "Commands for user info";
-export { name, description };
\ No newline at end of file
+export { name, description };
diff --git a/src/commands/user/about.ts b/src/commands/user/about.ts
index ede84b3..5f096ae 100644
--- a/src/commands/user/about.ts
+++ b/src/commands/user/about.ts
@@ -1,6 +1,18 @@
import { LoadingEmbed } from "./../../utils/defaultEmbeds.js";
-import Discord, { CommandInteraction, GuildMember, Message, MessageActionRow, MessageActionRowComponent, MessageButton, MessageComponentInteraction, SelectMenuInteraction } from "discord.js";
-import { SelectMenuOption, SlashCommandSubcommandBuilder } from "@discordjs/builders";
+import Discord, {
+ CommandInteraction,
+ GuildMember,
+ Message,
+ MessageActionRow,
+ MessageActionRowComponent,
+ MessageButton,
+ MessageComponentInteraction,
+ SelectMenuInteraction
+} from "discord.js";
+import {
+ SelectMenuOption,
+ SlashCommandSubcommandBuilder
+} from "@discordjs/builders";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import getEmojiByName from "../../utils/getEmojiByName.js";
import generateKeyValueList from "../../utils/generateKeyValueList.js";
@@ -11,218 +23,320 @@
builder
.setName("about")
.setDescription("Shows info about a user")
- .addUserOption(option => option.setName("user").setDescription("The user to get info about | Default: Yourself"));
-
+ .addUserOption((option) =>
+ option
+ .setName("user")
+ .setDescription(
+ "The user to get info about | Default: Yourself"
+ )
+ );
class Embed {
embed: Discord.MessageEmbed;
title: string;
description = "";
pageId = 0;
- setEmbed(embed: Discord.MessageEmbed) { this.embed = embed; return this; }
- setTitle(title: string) { this.title = title; return this; }
- setDescription(description: string) { this.description = description; return this; }
- setPageId(pageId: number) { this.pageId = pageId; return this; }
+ setEmbed(embed: Discord.MessageEmbed) {
+ this.embed = embed;
+ return this;
+ }
+ setTitle(title: string) {
+ this.title = title;
+ return this;
+ }
+ setDescription(description: string) {
+ this.description = description;
+ return this;
+ }
+ setPageId(pageId: number) {
+ this.pageId = pageId;
+ return this;
+ }
}
-
const callback = async (interaction: CommandInteraction): Promise<void> => {
const { renderUser, renderDelta } = client.logger;
- const member = (interaction.options.getMember("user") || interaction.member) as Discord.GuildMember;
+ const member = (interaction.options.getMember("user") ||
+ interaction.member) as Discord.GuildMember;
const flags: string[] = [];
- if ([
- "438733159748599813", // Pinea
- "317731855317336067", // Mini
- "261900651230003201", // Coded
- "511655498676699136" // Zan
- ].includes(member.user.id)) { flags.push("NUCLEUSDEVELOPER"); }
- if ((await client.guilds.cache.get("684492926528651336")?.members.fetch())?.filter((m: GuildMember) => m.roles.cache.has("760896837866749972"))?.map((m: GuildMember) => m.id).includes(member.user.id)) { flags.push("CLICKSDEVELOPER"); }
- member.user.flags.toArray().map(flag => {
+ if (
+ [
+ "438733159748599813", // Pinea
+ "317731855317336067", // Mini
+ "261900651230003201", // Coded
+ "511655498676699136" // Zan
+ ].includes(member.user.id)
+ ) {
+ flags.push("NUCLEUSDEVELOPER");
+ }
+ if (
+ (await client.guilds.cache.get("684492926528651336")?.members.fetch())
+ ?.filter((m: GuildMember) =>
+ m.roles.cache.has("760896837866749972")
+ )
+ ?.map((m: GuildMember) => m.id)
+ .includes(member.user.id)
+ ) {
+ flags.push("CLICKSDEVELOPER");
+ }
+ member.user.flags.toArray().map((flag) => {
flags.push(flag.toString());
});
- if (member.user.bot === true) { flags.push("BOT"); }
+ if (member.user.bot) {
+ flags.push("BOT");
+ }
// Check if they are boosting the server
- if (member.premiumSince) { flags.push("BOOSTER"); }
+ if (member.premiumSince) {
+ flags.push("BOOSTER");
+ }
const nameReplacements = {
- "NUCLEUSDEVELOPER": "**Nucleus Developer**",
- "CLICKSDEVELOPER": "Clicks Developer",
- "HOUSE_BRAVERY": "Hypesquad Bravery",
- "HOUSE_BRILLIANCE": "Hypesquad Brilliance",
- "HOUSE_BALANCE": "Hypesquad Balance",
- "HYPESQUAD_EVENTS": "Hypesquad Events",
- "EARLY_SUPPORTER": "Early Supporter",
- "BUGHUNTER_LEVEL_1": "Bug Hunter Level 1",
- "BUGHUNTER_LEVEL_2": "Bug Hunter Level 2",
- "PARTNERED_SERVER_OWNER": "Partnered Server Owner",
- "DISCORD_EMPLOYEE": "Discord Staff",
- "EARLY_VERIFIED_BOT_DEVELOPER": "Verified Bot Developer",
- "BOT": "Bot",
- "BOOSTER": "Server Booster"
+ NUCLEUSDEVELOPER: "**Nucleus Developer**",
+ CLICKSDEVELOPER: "Clicks Developer",
+ HOUSE_BRAVERY: "Hypesquad Bravery",
+ HOUSE_BRILLIANCE: "Hypesquad Brilliance",
+ HOUSE_BALANCE: "Hypesquad Balance",
+ HYPESQUAD_EVENTS: "Hypesquad Events",
+ EARLY_SUPPORTER: "Early Supporter",
+ BUGHUNTER_LEVEL_1: "Bug Hunter Level 1",
+ BUGHUNTER_LEVEL_2: "Bug Hunter Level 2",
+ PARTNERED_SERVER_OWNER: "Partnered Server Owner",
+ DISCORD_EMPLOYEE: "Discord Staff",
+ EARLY_VERIFIED_BOT_DEVELOPER: "Verified Bot Developer",
+ BOT: "Bot",
+ BOOSTER: "Server Booster"
};
const members = await interaction.guild.members.fetch();
const membersArray = [...members.values()];
membersArray.sort((a, b) => a.joinedTimestamp - b.joinedTimestamp);
- const joinPos = membersArray.findIndex(m => m.id === member.user.id);
+ const joinPos = membersArray.findIndex((m) => m.id === member.user.id);
- const roles = member.roles.cache.filter(r => r.id !== interaction.guild.id).sort();
+ const roles = member.roles.cache
+ .filter((r) => r.id !== interaction.guild.id)
+ .sort();
let s = "";
let count = 0;
let ended = false;
- roles.map(item => {
+ roles.map((item) => {
if (ended) return;
const string = `<@&${item.id}>, `;
- if(s.length + string.length > 1000) {
+ if (s.length + string.length > 1000) {
ended = true;
s += `and ${roles.size - count} more`;
return;
}
- count ++;
+ count++;
s += string;
});
- if(s.length > 0 && !ended) s = s.slice(0, -2);
+ if (s.length > 0 && !ended) s = s.slice(0, -2);
let perms = "";
const permsArray = {
- "ADMINISTRATOR": "Administrator",
- "MANAGE_GUILD": "Manage Server",
- "MANAGE_ROLES": "Manage Roles",
- "MANAGE_CHANNELS": "Manage Channels",
- "KICK_MEMBERS": "Kick Members",
- "BAN_MEMBERS": "Ban Members",
- "MODERATE_MEMBERS": "Moderate Members",
- "MANAGE_NICKNAMES": "Manage Nicknames",
- "MANAGE_WEBHOOKS": "Manage Webhooks",
- "MANAGE_MESSAGES": "Manage Messages",
- "VIEW_AUDIT_LOG": "View Audit Log",
- "MENTION_EVERYONE": "Mention Everyone"
+ ADMINISTRATOR: "Administrator",
+ MANAGE_GUILD: "Manage Server",
+ MANAGE_ROLES: "Manage Roles",
+ MANAGE_CHANNELS: "Manage Channels",
+ KICK_MEMBERS: "Kick Members",
+ BAN_MEMBERS: "Ban Members",
+ MODERATE_MEMBERS: "Moderate Members",
+ MANAGE_NICKNAMES: "Manage Nicknames",
+ MANAGE_WEBHOOKS: "Manage Webhooks",
+ MANAGE_MESSAGES: "Manage Messages",
+ VIEW_AUDIT_LOG: "View Audit Log",
+ MENTION_EVERYONE: "Mention Everyone"
};
- Object.keys(permsArray).map(perm => {
- const hasPerm = member.permissions.has(perm as Discord.PermissionString);
- perms += `${getEmojiByName("CONTROL." + (hasPerm ? "TICK" : "CROSS"))} ${permsArray[perm]}\n`;
+ Object.keys(permsArray).map((perm) => {
+ const hasPerm = member.permissions.has(
+ perm as Discord.PermissionString
+ );
+ perms += `${getEmojiByName(
+ "CONTROL." + (hasPerm ? "TICK" : "CROSS")
+ )} ${permsArray[perm]}\n`;
});
let selectPaneOpen = false;
const embeds = [
new Embed()
- .setEmbed(new EmojiEmbed()
- .setTitle("User Info: General")
- .setStatus("Success")
- .setEmoji("MEMBER.JOIN")
- .setDescription(
- flags.map(flag => {
- if (nameReplacements[flag]) {
- return getEmojiByName(`BADGES.${flag}`) + " " + nameReplacements[flag];
- }
- }).join("\n") + "\n\n" +
- generateKeyValueList({
- "member": renderUser(member.user),
- "nickname": member.nickname || "*None set*",
- "id": `\`${member.id}\``,
- "joined the server": renderDelta(member.joinedTimestamp),
- "joined discord": renderDelta(member.user.createdTimestamp),
- "boost status": member.premiumSince ? `Started boosting ${renderDelta(member.premiumSinceTimestamp)}` : "*Not boosting*",
- "join position": `${joinPos + 1}`
- })
- )
- .setThumbnail(member.user.displayAvatarURL({dynamic: true}))
- .setImage((await member.user.fetch()).bannerURL({format: "gif"}))
- ).setTitle("General").setDescription("General information about the user").setPageId(0),
+ .setEmbed(
+ new EmojiEmbed()
+ .setTitle("User Info: General")
+ .setStatus("Success")
+ .setEmoji("MEMBER.JOIN")
+ .setDescription(
+ flags
+ .map((flag) => {
+ if (nameReplacements[flag]) {
+ return (
+ getEmojiByName(`BADGES.${flag}`) +
+ " " +
+ nameReplacements[flag]
+ );
+ }
+ })
+ .join("\n") +
+ "\n\n" +
+ generateKeyValueList({
+ member: renderUser(member.user),
+ nickname: member.nickname || "*None set*",
+ id: `\`${member.id}\``,
+ "joined the server": renderDelta(
+ member.joinedTimestamp
+ ),
+ "joined discord": renderDelta(
+ member.user.createdTimestamp
+ ),
+ "boost status": member.premiumSince
+ ? `Started boosting ${renderDelta(
+ member.premiumSinceTimestamp
+ )}`
+ : "*Not boosting*",
+ "join position": `${joinPos + 1}`
+ })
+ )
+ .setThumbnail(
+ member.user.displayAvatarURL({ dynamic: true })
+ )
+ .setImage(
+ (await member.user.fetch()).bannerURL({ format: "gif" })
+ )
+ )
+ .setTitle("General")
+ .setDescription("General information about the user")
+ .setPageId(0),
new Embed()
- .setEmbed(new EmojiEmbed()
- .setTitle("User Info: Roles")
- .setStatus("Success")
- .setEmoji("GUILD.ROLES.CREATE")
- .setDescription(
- generateKeyValueList({
- "member": renderUser(member.user),
- "id": `\`${member.id}\``,
- "roles": `${member.roles.cache.size - 1}`
- }) + "\n" +
- (s.length > 0 ? s : "*None*") + "\n"
- )
- .setThumbnail(member.user.displayAvatarURL({dynamic: true}))
- ).setTitle("Roles").setDescription("Roles the user has").setPageId(1),
+ .setEmbed(
+ new EmojiEmbed()
+ .setTitle("User Info: Roles")
+ .setStatus("Success")
+ .setEmoji("GUILD.ROLES.CREATE")
+ .setDescription(
+ generateKeyValueList({
+ member: renderUser(member.user),
+ id: `\`${member.id}\``,
+ roles: `${member.roles.cache.size - 1}`
+ }) +
+ "\n" +
+ (s.length > 0 ? s : "*None*") +
+ "\n"
+ )
+ .setThumbnail(
+ member.user.displayAvatarURL({ dynamic: true })
+ )
+ )
+ .setTitle("Roles")
+ .setDescription("Roles the user has")
+ .setPageId(1),
new Embed()
- .setEmbed(new EmojiEmbed()
- .setTitle("User Info: Key Permissions")
- .setStatus("Success")
- .setEmoji("GUILD.ROLES.CREATE")
- .setDescription(
- generateKeyValueList({
- "member": renderUser(member.user),
- "id": `\`${member.id}\``
- }) + "\n" + perms
- )
- .setThumbnail(member.user.displayAvatarURL({dynamic: true}))
- ).setTitle("Key Permissions").setDescription("Key permissions the user has").setPageId(2)
+ .setEmbed(
+ new EmojiEmbed()
+ .setTitle("User Info: Key Permissions")
+ .setStatus("Success")
+ .setEmoji("GUILD.ROLES.CREATE")
+ .setDescription(
+ generateKeyValueList({
+ member: renderUser(member.user),
+ id: `\`${member.id}\``
+ }) +
+ "\n" +
+ perms
+ )
+ .setThumbnail(
+ member.user.displayAvatarURL({ dynamic: true })
+ )
+ )
+ .setTitle("Key Permissions")
+ .setDescription("Key permissions the user has")
+ .setPageId(2)
];
- const m = await interaction.reply({embeds: LoadingEmbed, fetchReply: true, ephemeral: true}) as Message;
+ const m = (await interaction.reply({
+ embeds: LoadingEmbed,
+ fetchReply: true,
+ ephemeral: true
+ })) as Message;
let page = 0;
let breakReason = "";
while (true) {
const em = new Discord.MessageEmbed(embeds[page].embed);
- em.setDescription(em.description + "\n" + createPageIndicator(embeds.length, page));
+ em.setDescription(
+ em.description + "\n" + createPageIndicator(embeds.length, page)
+ );
let selectPane = [];
if (selectPaneOpen) {
const options = [];
- embeds.forEach(embed => {
- options.push(new SelectMenuOption({
- label: embed.title,
- value: embed.pageId.toString(),
- description: embed.description || ""
- }));
+ embeds.forEach((embed) => {
+ options.push(
+ new SelectMenuOption({
+ label: embed.title,
+ value: embed.pageId.toString(),
+ description: embed.description || ""
+ })
+ );
});
- selectPane = [new MessageActionRow().addComponents([
- new Discord.MessageSelectMenu()
- .addOptions(options)
- .setCustomId("page")
- .setMaxValues(1)
- .setPlaceholder("Choose a page...")
- ])];
+ selectPane = [
+ new MessageActionRow().addComponents([
+ new Discord.MessageSelectMenu()
+ .addOptions(options)
+ .setCustomId("page")
+ .setMaxValues(1)
+ .setPlaceholder("Choose a page...")
+ ])
+ ];
}
await interaction.editReply({
embeds: [em],
- components: selectPane.concat([new MessageActionRow().addComponents([
- new MessageButton()
- .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
- .setStyle("SECONDARY")
- .setCustomId("left")
- .setDisabled(page === 0),
- new MessageButton()
- .setEmoji(getEmojiByName("CONTROL.MENU", "id"))
- .setStyle(selectPaneOpen ? "PRIMARY" : "SECONDARY")
- .setCustomId("select")
- .setDisabled(false),
- new MessageButton()
- .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
- .setCustomId("right")
- .setStyle("SECONDARY")
- .setDisabled(page === embeds.length - 1),
- new MessageButton()
- .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
- .setCustomId("close")
- .setStyle("DANGER")
- ])])
+ components: selectPane.concat([
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
+ .setStyle("SECONDARY")
+ .setCustomId("left")
+ .setDisabled(page === 0),
+ new MessageButton()
+ .setEmoji(getEmojiByName("CONTROL.MENU", "id"))
+ .setStyle(selectPaneOpen ? "PRIMARY" : "SECONDARY")
+ .setCustomId("select")
+ .setDisabled(false),
+ new MessageButton()
+ .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
+ .setCustomId("right")
+ .setStyle("SECONDARY")
+ .setDisabled(page === embeds.length - 1),
+ new MessageButton()
+ .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
+ .setCustomId("close")
+ .setStyle("DANGER")
+ ])
+ ])
});
let i: MessageComponentInteraction;
try {
- i = await m.awaitMessageComponent({time: 300000});
- } catch { breakReason = "Message timed out"; break; }
+ i = await m.awaitMessageComponent({ time: 300000 });
+ } catch {
+ breakReason = "Message timed out";
+ break;
+ }
i.deferUpdate();
if ((i.component as MessageActionRowComponent).customId === "left") {
if (page > 0) page--;
selectPaneOpen = false;
- } else if ((i.component as MessageActionRowComponent).customId === "right") {
+ } else if (
+ (i.component as MessageActionRowComponent).customId === "right"
+ ) {
if (page < embeds.length - 1) page++;
selectPaneOpen = false;
- } else if ((i.component as MessageActionRowComponent).customId === "select") {
+ } else if (
+ (i.component as MessageActionRowComponent).customId === "select"
+ ) {
selectPaneOpen = !selectPaneOpen;
- } else if ((i.component as MessageActionRowComponent).customId === "close") {
+ } else if (
+ (i.component as MessageActionRowComponent).customId === "close"
+ ) {
breakReason = "Message closed";
break;
- } else if ((i.component as MessageActionRowComponent).customId === "page") {
+ } else if (
+ (i.component as MessageActionRowComponent).customId === "page"
+ ) {
page = parseInt((i as SelectMenuInteraction).values[0]);
selectPaneOpen = false;
} else {
@@ -231,29 +345,40 @@
}
}
const em = new Discord.MessageEmbed(embeds[page].embed);
- em.setDescription(em.description + "\n" + createPageIndicator(embeds.length, page) + " | " + breakReason);
- await interaction.editReply({embeds: [em], components: [new MessageActionRow().addComponents([
- new MessageButton()
- .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
- .setStyle("SECONDARY")
- .setCustomId("left")
- .setDisabled(true),
- new MessageButton()
- .setEmoji(getEmojiByName("CONTROL.MENU", "id"))
- .setStyle("SECONDARY")
- .setCustomId("select")
- .setDisabled(true),
- new MessageButton()
- .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
- .setCustomId("right")
- .setStyle("SECONDARY")
- .setDisabled(true),
- new MessageButton()
- .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
- .setCustomId("close")
- .setStyle("DANGER")
- .setDisabled(true)
- ])]});
+ em.setDescription(
+ em.description +
+ "\n" +
+ createPageIndicator(embeds.length, page) +
+ " | " +
+ breakReason
+ );
+ await interaction.editReply({
+ embeds: [em],
+ components: [
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
+ .setStyle("SECONDARY")
+ .setCustomId("left")
+ .setDisabled(true),
+ new MessageButton()
+ .setEmoji(getEmojiByName("CONTROL.MENU", "id"))
+ .setStyle("SECONDARY")
+ .setCustomId("select")
+ .setDisabled(true),
+ new MessageButton()
+ .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
+ .setCustomId("right")
+ .setStyle("SECONDARY")
+ .setDisabled(true),
+ new MessageButton()
+ .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
+ .setCustomId("close")
+ .setStyle("DANGER")
+ .setDisabled(true)
+ ])
+ ]
+ });
};
const check = () => {
diff --git a/src/commands/user/avatar.ts b/src/commands/user/avatar.ts
index 8f327a5..35c475f 100644
--- a/src/commands/user/avatar.ts
+++ b/src/commands/user/avatar.ts
@@ -9,29 +9,44 @@
builder
.setName("avatar")
.setDescription("Shows the avatar of a user")
- .addUserOption(option => option.setName("user").setDescription("The user to get the avatar of | Default: Yourself"));
+ .addUserOption((option) =>
+ option
+ .setName("user")
+ .setDescription(
+ "The user to get the avatar of | Default: Yourself"
+ )
+ );
const callback = async (interaction: CommandInteraction): Promise<void> => {
const { renderUser } = client.logger;
- const member = (interaction.options.getMember("user") || interaction.member) as Discord.GuildMember;
- await interaction.reply({embeds: [new EmojiEmbed()
- .setTitle("User Info")
- .setStatus("Success")
- .setEmoji("MEMBER.JOIN")
- .setDescription(
- generateKeyValueList({
- "member": renderUser(member.user),
- "url": member.user.displayAvatarURL({dynamic: true})
- })
- )
- .setImage(await member.user.displayAvatarURL({dynamic: true}))
- ], ephemeral: true, fetchReply: true});
+ const member = (interaction.options.getMember("user") ||
+ interaction.member) as Discord.GuildMember;
+ await interaction.reply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("User Info")
+ .setStatus("Success")
+ .setEmoji("MEMBER.JOIN")
+ .setDescription(
+ generateKeyValueList({
+ member: renderUser(member.user),
+ url: member.user.displayAvatarURL({ dynamic: true })
+ })
+ )
+ .setImage(await member.user.displayAvatarURL({ dynamic: true }))
+ ],
+ ephemeral: true,
+ fetchReply: true
+ });
};
-const check = (_interaction: CommandInteraction, _defaultCheck: WrappedCheck) => {
+const check = (
+ _interaction: CommandInteraction,
+ _defaultCheck: WrappedCheck
+) => {
return true;
};
export { command };
export { callback };
-export { check };
\ No newline at end of file
+export { check };
diff --git a/src/commands/user/track.ts b/src/commands/user/track.ts
index 4720032..e0e41e0 100644
--- a/src/commands/user/track.ts
+++ b/src/commands/user/track.ts
@@ -1,8 +1,17 @@
import { LoadingEmbed } from "./../../utils/defaultEmbeds.js";
-import Discord, { CommandInteraction, GuildMember, Message, MessageActionRow, MessageButton } from "discord.js";
-import { SelectMenuOption, SlashCommandSubcommandBuilder } from "@discordjs/builders";
+import Discord, {
+ CommandInteraction,
+ GuildMember,
+ Message,
+ MessageActionRow,
+ MessageButton
+} from "discord.js";
+import {
+ SelectMenuOption,
+ SlashCommandSubcommandBuilder
+} from "@discordjs/builders";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
-// @ts-ignore
+// @ts-expect-error
import { WrappedCheck } from "jshaiku";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import getEmojiByName from "../../utils/getEmojiByName.js";
@@ -13,24 +22,38 @@
builder
.setName("track")
.setDescription("Moves a user along a role track")
- .addUserOption(option => option.setName("user").setDescription("The user to manage").setRequired(true));
+ .addUserOption((option) =>
+ option
+ .setName("user")
+ .setDescription("The user to manage")
+ .setRequired(true)
+ );
-const generateFromTrack = (position: number, active: string | boolean, size: number, disabled: string | boolean) => {
+const generateFromTrack = (
+ position: number,
+ active: string | boolean,
+ size: number,
+ disabled: string | boolean
+) => {
active = active ? "ACTIVE" : "INACTIVE";
disabled = disabled ? "GREY." : "";
- if (position === 0 && size === 1) return "TRACKS.SINGLE." + disabled + active;
- if (position === size - 1) return "TRACKS.VERTICAL.BOTTOM." + disabled + active;
+ if (position === 0 && size === 1)
+ return "TRACKS.SINGLE." + disabled + active;
+ if (position === size - 1)
+ return "TRACKS.VERTICAL.BOTTOM." + disabled + active;
if (position === 0) return "TRACKS.VERTICAL.TOP." + disabled + active;
return "TRACKS.VERTICAL.MIDDLE." + disabled + active;
};
-const callback = async (interaction: CommandInteraction): Promise<void | unknown> => {
+const callback = async (
+ interaction: CommandInteraction
+): Promise<void | unknown> => {
const { renderUser } = client.logger;
const member = interaction.options.getMember("user") as GuildMember;
const guild = interaction.guild;
if (!guild) return;
const config = await client.database.guilds.read(guild.id);
- await interaction.reply({embeds: LoadingEmbed, ephemeral: true});
+ await interaction.reply({ embeds: LoadingEmbed, ephemeral: true });
let track = 0;
let generated;
const roles = await guild.roles.fetch();
@@ -38,119 +61,206 @@
let managed: boolean;
while (true) {
const data = config.tracks[track];
- if (data.manageableBy !== undefined) managed = data.manageableBy.some((element: string) => {return memberRoles.cache.has(element);});
- else managed = false;
- const dropdown = new Discord.MessageSelectMenu().addOptions(config.tracks.map((option, index) => {
- const hasRoleInTrack = option.track.some((element: string) => {return memberRoles.cache.has(element);});
- return new SelectMenuOption({
- default: index === track,
- label: option.name,
- value: index.toString(),
- description: option.track.length === 0 ? "No" : addPlural(option.track.length, "role"),
- emoji: client.emojis.resolve(getEmojiByName("TRACKS.SINGLE." + (hasRoleInTrack ? "ACTIVE" : "INACTIVE"), "id"))
+ if (data.manageableBy !== undefined)
+ managed = data.manageableBy.some((element: string) => {
+ return memberRoles.cache.has(element);
});
- })).setCustomId("select").setMaxValues(1);
+ else managed = false;
+ const dropdown = new Discord.MessageSelectMenu()
+ .addOptions(
+ config.tracks.map((option, index) => {
+ const hasRoleInTrack = option.track.some(
+ (element: string) => {
+ return memberRoles.cache.has(element);
+ }
+ );
+ return new SelectMenuOption({
+ default: index === track,
+ label: option.name,
+ value: index.toString(),
+ description:
+ option.track.length === 0
+ ? "No"
+ : addPlural(option.track.length, "role"),
+ emoji: client.emojis.resolve(
+ getEmojiByName(
+ "TRACKS.SINGLE." +
+ (hasRoleInTrack ? "ACTIVE" : "INACTIVE"),
+ "id"
+ )
+ )
+ });
+ })
+ )
+ .setCustomId("select")
+ .setMaxValues(1);
const allowed = [];
- generated = "**Track:** " + data.name + "\n" + "**Member:** " + renderUser(member.user) + "\n";
- generated += (data.nullable ? "Members do not need a role in this track" : "A role in this track is required") + "\n";
- generated += (data.retainPrevious ? "When promoted, the user keeps previous roles" : "Members will lose their current role when promoted") + "\n";
- generated += "\n" + data.track.map((role, index) => {
- const allow = (roles.get(role).position >= (interaction.member as GuildMember).roles.highest.position) && !managed;
- allowed.push(!allow);
- return getEmojiByName(generateFromTrack(
- index,
- memberRoles.cache.has(role),
- data.track.length,
- allow
- )) + " " +
- roles.get(role).name + " [<@&" + roles.get(role).id + ">]";
- }).join("\n");
+ generated =
+ "**Track:** " +
+ data.name +
+ "\n" +
+ "**Member:** " +
+ renderUser(member.user) +
+ "\n";
+ generated +=
+ (data.nullable
+ ? "Members do not need a role in this track"
+ : "A role in this track is required") + "\n";
+ generated +=
+ (data.retainPrevious
+ ? "When promoted, the user keeps previous roles"
+ : "Members will lose their current role when promoted") + "\n";
+ generated +=
+ "\n" +
+ data.track
+ .map((role, index) => {
+ const allow =
+ roles.get(role).position >=
+ (interaction.member as GuildMember).roles.highest
+ .position && !managed;
+ allowed.push(!allow);
+ return (
+ getEmojiByName(
+ generateFromTrack(
+ index,
+ memberRoles.cache.has(role),
+ data.track.length,
+ allow
+ )
+ ) +
+ " " +
+ roles.get(role).name +
+ " [<@&" +
+ roles.get(role).id +
+ ">]"
+ );
+ })
+ .join("\n");
const selected = [];
for (let i = 0; i < data.track.length; i++) {
- if (memberRoles.cache.has(data.track[i])) selected.push(data.track[i]);
+ if (memberRoles.cache.has(data.track[i]))
+ selected.push(data.track[i]);
}
const conflict = data.retainPrevious ? false : selected.length > 1;
let conflictDropdown;
let currentRoleIndex;
if (conflict) {
- generated += `\n\n${getEmojiByName(`PUNISH.WARN.${managed ? "YELLOW" : "RED"}`)} This user has ${selected.length} roles from this track. `;
+ generated += `\n\n${getEmojiByName(
+ `PUNISH.WARN.${managed ? "YELLOW" : "RED"}`
+ )} This user has ${selected.length} roles from this track. `;
conflictDropdown = [];
if (
- (roles.get(selected[0]).position < memberRoles.highest.position) || managed
+ roles.get(selected[0]).position <
+ memberRoles.highest.position ||
+ managed
) {
- generated += "In order to promote or demote this user, you must select which role the member should keep.";
- selected.forEach(role => {
- conflictDropdown.push(new SelectMenuOption({
- label: roles.get(role).name,
- value: roles.get(role).id
- }));
+ generated +=
+ "In order to promote or demote this user, you must select which role the member should keep.";
+ selected.forEach((role) => {
+ conflictDropdown.push(
+ new SelectMenuOption({
+ label: roles.get(role).name,
+ value: roles.get(role).id
+ })
+ );
});
- conflictDropdown = [new Discord.MessageSelectMenu()
- .addOptions(conflictDropdown)
- .setCustomId("conflict")
- .setMaxValues(1)
- .setPlaceholder("Select a role to keep")];
+ conflictDropdown = [
+ new Discord.MessageSelectMenu()
+ .addOptions(conflictDropdown)
+ .setCustomId("conflict")
+ .setMaxValues(1)
+ .setPlaceholder("Select a role to keep")
+ ];
} else {
- generated += "You don't have permission to manage one or more of the users roles, and therefore can't select one to keep.";
+ generated +=
+ "You don't have permission to manage one or more of the users roles, and therefore can't select one to keep.";
}
} else {
- currentRoleIndex = selected.length === 0 ? -1 : data.track.indexOf(selected[0].toString());
+ currentRoleIndex =
+ selected.length === 0
+ ? -1
+ : data.track.indexOf(selected[0].toString());
}
- const m = await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("TRACKS.ICON")
- .setTitle("Tracks")
- .setDescription(`${generated}`)
- .setStatus("Success")
- ], components: [
- new MessageActionRow().addComponents(dropdown)
- ]
- .concat(conflict && conflictDropdown.length ? [new MessageActionRow().addComponents(conflictDropdown)] : [])
- .concat([
- new MessageActionRow().addComponents([
- new MessageButton()
- .setEmoji(getEmojiByName("CONTROL.UP", "id"))
- .setLabel("Move up")
- .setCustomId("promote")
- .setStyle("SUCCESS")
- .setDisabled(conflict || currentRoleIndex === 0 || (currentRoleIndex === -1 ? false : !allowed[currentRoleIndex - 1])),
- new MessageButton()
- .setEmoji(getEmojiByName("CONTROL.DOWN", "id"))
- .setLabel("Move down")
- .setCustomId("demote")
- .setStyle("DANGER")
- .setDisabled(conflict || (
- data.nullable ? currentRoleIndex <= -1 :
- currentRoleIndex === data.track.length - 1 || currentRoleIndex <= -1
- ) || !allowed[currentRoleIndex])
+ const m = (await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setEmoji("TRACKS.ICON")
+ .setTitle("Tracks")
+ .setDescription(`${generated}`)
+ .setStatus("Success")
+ ],
+ components: [new MessageActionRow().addComponents(dropdown)]
+ .concat(
+ conflict && conflictDropdown.length
+ ? [
+ new MessageActionRow().addComponents(
+ conflictDropdown
+ )
+ ]
+ : []
+ )
+ .concat([
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setEmoji(getEmojiByName("CONTROL.UP", "id"))
+ .setLabel("Move up")
+ .setCustomId("promote")
+ .setStyle("SUCCESS")
+ .setDisabled(
+ conflict ||
+ currentRoleIndex === 0 ||
+ (currentRoleIndex === -1
+ ? false
+ : !allowed[currentRoleIndex - 1])
+ ),
+ new MessageButton()
+ .setEmoji(getEmojiByName("CONTROL.DOWN", "id"))
+ .setLabel("Move down")
+ .setCustomId("demote")
+ .setStyle("DANGER")
+ .setDisabled(
+ conflict ||
+ (data.nullable
+ ? currentRoleIndex <= -1
+ : currentRoleIndex ===
+ data.track.length - 1 ||
+ currentRoleIndex <= -1) ||
+ !allowed[currentRoleIndex]
+ )
+ ])
])
- ])
- }) as Message;
+ })) as Message;
let component;
try {
- component = await m.awaitMessageComponent({time: 300000});
+ component = await m.awaitMessageComponent({ time: 300000 });
} catch (e) {
return;
}
component.deferUpdate();
if (component.customId === "conflict") {
- const rolesToRemove = selected.filter(role => role !== component.values[0]);
+ const rolesToRemove = selected.filter(
+ (role) => role !== component.values[0]
+ );
await member.roles.remove(rolesToRemove);
} else if (component.customId === "promote") {
if (
- currentRoleIndex === -1 ? allowed[data.track.length - 1] :
- allowed[currentRoleIndex - 1] && allowed[currentRoleIndex]
+ currentRoleIndex === -1
+ ? allowed[data.track.length - 1]
+ : allowed[currentRoleIndex - 1] && allowed[currentRoleIndex]
) {
if (currentRoleIndex === -1) {
await member.roles.add(data.track[data.track.length - 1]);
} else if (currentRoleIndex < data.track.length) {
- if (!data.retainPrevious) await member.roles.remove(data.track[currentRoleIndex]);
+ if (!data.retainPrevious)
+ await member.roles.remove(data.track[currentRoleIndex]);
await member.roles.add(data.track[currentRoleIndex - 1]);
}
}
} else if (component.customId === "demote") {
- if(allowed[currentRoleIndex]) {
+ if (allowed[currentRoleIndex]) {
if (currentRoleIndex === data.track.length - 1) {
- if (data.nullable) await member.roles.remove(data.track[currentRoleIndex]);
+ if (data.nullable)
+ await member.roles.remove(data.track[currentRoleIndex]);
} else if (currentRoleIndex > -1) {
await member.roles.remove(data.track[currentRoleIndex]);
await member.roles.add(data.track[currentRoleIndex + 1]);
@@ -162,22 +272,32 @@
}
};
-const check = async (interaction: CommandInteraction, _defaultCheck: WrappedCheck) => {
- const tracks = (await client.database.guilds.read(interaction.guild.id)).tracks;
+const check = async (
+ interaction: CommandInteraction,
+ _defaultCheck: WrappedCheck
+) => {
+ const tracks = (await client.database.guilds.read(interaction.guild.id))
+ .tracks;
if (tracks.length === 0) throw "This server does not have any tracks";
- const member = (interaction.member as GuildMember);
+ const member = interaction.member as GuildMember;
// Allow the owner to promote anyone
if (member.id === interaction.guild.ownerId) return true;
// Check if the user can manage any of the tracks
let managed = false;
for (const element of tracks) {
if (!element.track.manageableBy) continue;
- if (!element.track.manageableBy.some(role => member.roles.cache.has(role))) continue;
+ if (
+ !element.track.manageableBy.some((role) =>
+ member.roles.cache.has(role)
+ )
+ )
+ continue;
managed = true;
break;
}
// Check if the user has manage_roles permission
- if (!managed && ! member.permissions.has("MANAGE_ROLES")) throw "You do not have the *Manage Roles* permission";
+ if (!managed && !member.permissions.has("MANAGE_ROLES"))
+ throw "You do not have the *Manage Roles* permission";
// Allow track
return true;
};
@@ -185,4 +305,3 @@
export { command };
export { callback };
export { check };
-
diff --git a/src/commands/verify.ts b/src/commands/verify.ts
index f7e66b8..d1a0659 100644
--- a/src/commands/verify.ts
+++ b/src/commands/verify.ts
@@ -1,7 +1,7 @@
import type { CommandInteraction } from "discord.js";
import { SlashCommandBuilder } from "@discordjs/builders";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
-// @ts-ignore
+// @ts-expect-error
import { WrappedCheck } from "jshaiku";
import verify from "../reflex/verify.js";
@@ -13,7 +13,10 @@
verify(interaction);
};
-const check = (_interaction: CommandInteraction, _defaultCheck: WrappedCheck) => {
+const check = (
+ _interaction: CommandInteraction,
+ _defaultCheck: WrappedCheck
+) => {
return true;
};
diff --git a/src/config/default.json b/src/config/default.json
index 3976812..7f2fdbd 100644
--- a/src/config/default.json
+++ b/src/config/default.json
@@ -92,4 +92,4 @@
"tracks": [],
"roleMenu": [],
"tags": {}
-}
\ No newline at end of file
+}
diff --git a/src/config/emojis.json b/src/config/emojis.json
index 49c2b27..fc90ce4 100644
--- a/src/config/emojis.json
+++ b/src/config/emojis.json
@@ -368,4 +368,4 @@
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/config/format.ts b/src/config/format.ts
index 03fbd85..3b977fb 100644
--- a/src/config/format.ts
+++ b/src/config/format.ts
@@ -1,21 +1,25 @@
import fs from "fs";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
-// @ts-ignore
+// @ts-expect-error
import * as readLine from "node:readline/promises";
const defaultDict = {
- "developmentToken": "Your development bot token (Used for testing in one server, rather than production)",
- "developmentGuildID": "Your development guild ID",
- "enableDevelopment": true,
- "token": "Your bot token",
- "managementGuildID": "Your management guild ID (Used for running management commands on the bot)",
- "owners": [],
- "verifySecret": "If using verify, enter a code here which matches the secret sent back by your website. You can use a random code if you do not have one already. (Optional)",
- "mongoUrl": "Your Mongo connection string, e.g. mongodb://127.0.0.1:27017",
- "baseUrl": "Your website where buttons such as Verify and Role menu will link to, e.g. https://example.com",
- "pastebinApiKey": "An API key for pastebin (optional)",
- "pastebinUsername": "Your pastebin username (optional)",
- "pastebinPassword": "Your pastebin password (optional)"
+ developmentToken:
+ "Your development bot token (Used for testing in one server, rather than production)",
+ developmentGuildID: "Your development guild ID",
+ enableDevelopment: true,
+ token: "Your bot token",
+ managementGuildID:
+ "Your management guild ID (Used for running management commands on the bot)",
+ owners: [],
+ verifySecret:
+ "If using verify, enter a code here which matches the secret sent back by your website. You can use a random code if you do not have one already. (Optional)",
+ mongoUrl: "Your Mongo connection string, e.g. mongodb://127.0.0.1:27017",
+ baseUrl:
+ "Your website where buttons such as Verify and Role menu will link to, e.g. https://example.com",
+ pastebinApiKey: "An API key for pastebin (optional)",
+ pastebinUsername: "Your pastebin username (optional)",
+ pastebinPassword: "Your pastebin password (optional)"
};
const readline = readLine.createInterface({
@@ -30,11 +34,14 @@
return answer.toString();
}
-
-export default async function(walkthrough = false) {
+export default async function (walkthrough = false) {
if (walkthrough) {
- console.log("\x1b[33m🛈 Entering walkthrough mode for any missing values.");
- console.log(" \x1b[2mIf you don't want to enter a value, just hit enter.\x1b[0m\n");
+ console.log(
+ "\x1b[33m🛈 Entering walkthrough mode for any missing values."
+ );
+ console.log(
+ " \x1b[2mIf you don't want to enter a value, just hit enter.\x1b[0m\n"
+ );
// let toUse = await getInput("\x1b[36m[Installing packages] Use Yarn or NPM? \x1b[0m(\x1b[32my\x1b[0m/\x1b[31mN\x1b[0m) > ");
// toUse = toUse.toLowerCase() === "y" ? "yarn install" : "npm i";
@@ -53,7 +60,9 @@
json = JSON.parse(fs.readFileSync("./src/config/main.json", "utf8"));
} catch (e) {
console.log("\x1b[31mâš No main.json found, creating one.");
- console.log(" \x1b[2mYou can edit src/config/main.json directly using template written to the file.\x1b[0m\n");
+ console.log(
+ " \x1b[2mYou can edit src/config/main.json directly using template written to the file.\x1b[0m\n"
+ );
out = false;
json = {};
}
@@ -61,36 +70,58 @@
if (!json[key]) {
if (walkthrough) {
switch (key) {
- case "enableDevelopment": {
- json[key] = (await getInput("\x1b[36mEnable development mode? This registers commands in a single server making it easier to test\x1b[0m(\x1b[32mY\x1b[0m/\x1b[31mn\x1b[0m) > ") || "Y").toLowerCase() === "y"; break;
- } case "owners": {
- let chosen = "!";
- const toWrite = [];
- while (chosen !== "") {
- chosen = await getInput("\x1b[36mEnter an owner ID \x1b[0m(\x1b[35mleave blank to finish\x1b[0m) > ");
- if (chosen !== "") { toWrite.push(chosen); }
+ case "enableDevelopment": {
+ json[key] =
+ (
+ (await getInput(
+ "\x1b[36mEnable development mode? This registers commands in a single server making it easier to test\x1b[0m(\x1b[32mY\x1b[0m/\x1b[31mn\x1b[0m) > "
+ )) || "Y"
+ ).toLowerCase() === "y";
+ break;
}
- json[key] = toWrite; break;
- } default: {
- json[key] = await getInput(`\x1b[36m${key} \x1b[0m(\x1b[35m${defaultDict[key]}\x1b[0m) > `);
+ case "owners": {
+ let chosen = "!";
+ const toWrite = [];
+ while (chosen !== "") {
+ chosen = await getInput(
+ "\x1b[36mEnter an owner ID \x1b[0m(\x1b[35mleave blank to finish\x1b[0m) > "
+ );
+ if (chosen !== "") {
+ toWrite.push(chosen);
+ }
+ }
+ json[key] = toWrite;
+ break;
+ }
+ default: {
+ json[key] = await getInput(
+ `\x1b[36m${key} \x1b[0m(\x1b[35m${defaultDict[key]}\x1b[0m) > `
+ );
+ }
}
- }
+ } else {
+ json[key] = defaultDict[key];
}
- else { json[key] = defaultDict[key]; }
}
}
- if (walkthrough && !json.mongoUrl) json.mongoUrl = "mongodb://127.0.0.1:27017";
+ if (walkthrough && !json.mongoUrl)
+ json.mongoUrl = "mongodb://127.0.0.1:27017";
if (!json.mongoUrl.endsWith("/")) json.mongoUrl += "/";
if (!json.baseUrl.endsWith("/")) json.baseUrl += "/";
let hosts;
try {
hosts = fs.readFileSync("/etc/hosts", "utf8").toString().split("\n");
} catch (e) {
- return console.log("\x1b[31mâš No /etc/hosts found. Please ensure the file exists and is readable. (Windows is not supported, Mac and Linux users should not experience this error)");
+ return console.log(
+ "\x1b[31mâš No /etc/hosts found. Please ensure the file exists and is readable. (Windows is not supported, Mac and Linux users should not experience this error)"
+ );
}
- let localhost = hosts.find(line => line.split(" ")[1] === "localhost");
- if (localhost) { localhost = localhost.split(" ")[0]; }
- else { localhost = "127.0.0.1"; }
+ let localhost = hosts.find((line) => line.split(" ")[1] === "localhost");
+ if (localhost) {
+ localhost = localhost.split(" ")[0];
+ } else {
+ localhost = "127.0.0.1";
+ }
json.mongoUrl = json.mongoUrl.replace("localhost", localhost);
json.baseUrl = json.baseUrl.replace("localhost", localhost);
diff --git a/src/events/channelCreate.ts b/src/events/channelCreate.ts
index c4c1347..7350ebd 100644
--- a/src/events/channelCreate.ts
+++ b/src/events/channelCreate.ts
@@ -1,49 +1,59 @@
export const event = "channelCreate";
export async function callback(client, channel) {
- const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = channel.client.logger;
+ const {
+ getAuditLog,
+ log,
+ NucleusColors,
+ entry,
+ renderUser,
+ renderDelta,
+ renderChannel
+ } = channel.client.logger;
const auditLog = await getAuditLog(channel.guild, "CHANNEL_CREATE");
- const audit = auditLog.entries.filter(entry => entry.target.id === channel.id).first();
+ const audit = auditLog.entries
+ .filter((entry) => entry.target.id === channel.id)
+ .first();
if (audit.executor.id === client.user.id) return;
let emoji;
let readableType;
let displayName;
switch (channel.type) {
- case "GUILD_TEXT": {
- emoji = "CHANNEL.TEXT.CREATE";
- readableType = "Text";
- displayName = "Text Channel";
- break;
- }
- case "GUILD_NEWS": {
- emoji = "CHANNEL.TEXT.CREATE";
- readableType = "Announcement";
- displayName = "Announcement Channel";
- break;
- }
- case "GUILD_VOICE": {
- emoji = "CHANNEL.VOICE.CREATE";
- readableType = "Voice";
- displayName = "Voice Channel";
- break;
- }
- case "GUILD_STAGE": {
- emoji = "CHANNEL.VOICE.CREATE";
- readableType = "Stage";
- displayName = "Stage Channel";
- break;
- }
- case "GUILD_CATEGORY": {
- emoji = "CHANNEL.CATEGORY.CREATE";
- readableType = "Category";
- displayName = "Category";
- break;
- }
- default: {
- emoji = "CHANNEL.TEXT.CREATE";
- readableType = "Channel";
- displayName = "Channel";
- }
+ case "GUILD_TEXT": {
+ emoji = "CHANNEL.TEXT.CREATE";
+ readableType = "Text";
+ displayName = "Text Channel";
+ break;
+ }
+ case "GUILD_NEWS": {
+ emoji = "CHANNEL.TEXT.CREATE";
+ readableType = "Announcement";
+ displayName = "Announcement Channel";
+ break;
+ }
+ case "GUILD_VOICE": {
+ emoji = "CHANNEL.VOICE.CREATE";
+ readableType = "Voice";
+ displayName = "Voice Channel";
+ break;
+ }
+ case "GUILD_STAGE": {
+ emoji = "CHANNEL.VOICE.CREATE";
+ readableType = "Stage";
+ displayName = "Stage Channel";
+ break;
+ }
+ case "GUILD_CATEGORY": {
+ emoji = "CHANNEL.CATEGORY.CREATE";
+ readableType = "Category";
+ displayName = "Category";
+ break;
+ }
+ default: {
+ emoji = "CHANNEL.TEXT.CREATE";
+ readableType = "Channel";
+ displayName = "Channel";
+ }
}
const data = {
meta: {
@@ -58,9 +68,15 @@
channelId: entry(channel.id, `\`${channel.id}\``),
name: entry(channel.name, renderChannel(channel)),
type: entry(channel.type, readableType),
- category: entry(channel.parent ? channel.parent.id : null, channel.parent ? channel.parent.name : "Uncategorised"),
+ category: entry(
+ channel.parent ? channel.parent.id : null,
+ channel.parent ? channel.parent.name : "Uncategorised"
+ ),
createdBy: entry(audit.executor.id, renderUser(audit.executor)),
- created: entry(channel.createdTimestamp, renderDelta(channel.createdTimestamp))
+ created: entry(
+ channel.createdTimestamp,
+ renderDelta(channel.createdTimestamp)
+ )
},
hidden: {
guild: channel.guild.id
diff --git a/src/events/channelDelete.ts b/src/events/channelDelete.ts
index c8a72a4..af55205 100644
--- a/src/events/channelDelete.ts
+++ b/src/events/channelDelete.ts
@@ -3,58 +3,77 @@
export const event = "channelDelete";
export async function callback(client, channel) {
- const { getAuditLog, log, NucleusColors, entry, renderDelta, renderUser } = channel.client.logger;
+ const { getAuditLog, log, NucleusColors, entry, renderDelta, renderUser } =
+ channel.client.logger;
const auditLog = await getAuditLog(channel.guild, "CHANNEL_DELETE");
- const audit = auditLog.entries.filter(entry => entry.target.id === channel.id).first();
+ const audit = auditLog.entries
+ .filter((entry) => entry.target.id === channel.id)
+ .first();
if (audit.executor.id === client.user.id) return;
let emoji;
let readableType;
let displayName;
switch (channel.type) {
- case "GUILD_TEXT": {
- emoji = "CHANNEL.TEXT.DELETE";
- readableType = "Text";
- displayName = "Text Channel";
- break;
- }
- case "GUILD_VOICE": {
- emoji = "CHANNEL.VOICE.DELETE";
- readableType = "Voice";
- displayName = "Voice Channel";
- break;
- }
- case "GUILD_CATEGORY": {
- emoji = "CHANNEL.CATEGORY.DELETE";
- readableType = "Category";
- displayName = "Category";
- break;
- }
- default: {
- emoji = "CHANNEL.TEXT.DELETE";
- readableType = "Channel";
- displayName = "Channel";
- }
+ case "GUILD_TEXT": {
+ emoji = "CHANNEL.TEXT.DELETE";
+ readableType = "Text";
+ displayName = "Text Channel";
+ break;
+ }
+ case "GUILD_VOICE": {
+ emoji = "CHANNEL.VOICE.DELETE";
+ readableType = "Voice";
+ displayName = "Voice Channel";
+ break;
+ }
+ case "GUILD_CATEGORY": {
+ emoji = "CHANNEL.CATEGORY.DELETE";
+ readableType = "Category";
+ displayName = "Category";
+ break;
+ }
+ default: {
+ emoji = "CHANNEL.TEXT.DELETE";
+ readableType = "Channel";
+ displayName = "Channel";
+ }
}
const list = {
channelId: entry(channel.id, `\`${channel.id}\``),
name: entry(channel.id, `${channel.name}`),
topic: null,
type: entry(channel.type, readableType),
- category: entry(channel.parent ? channel.parent.id : null, channel.parent ? channel.parent.name : "Uncategorised"),
+ category: entry(
+ channel.parent ? channel.parent.id : null,
+ channel.parent ? channel.parent.name : "Uncategorised"
+ ),
nsfw: null,
- created: entry(channel.createdTimestamp, renderDelta(channel.createdTimestamp)),
+ created: entry(
+ channel.createdTimestamp,
+ renderDelta(channel.createdTimestamp)
+ ),
deleted: entry(new Date().getTime(), renderDelta(new Date().getTime())),
deletedBy: entry(audit.executor.id, renderUser(audit.executor))
};
- if (channel.topic !== null ?? false) list.topic = entry(channel.topic, `\`\`\`\n${channel.topic.replace("`", "'")}\n\`\`\``);
+ if (channel.topic !== null ?? false)
+ list.topic = entry(
+ channel.topic,
+ `\`\`\`\n${channel.topic.replace("`", "'")}\n\`\`\``
+ );
else delete list.topic;
- if (channel.nsfw !== null ?? false) list.nsfw = entry(channel.nsfw, channel.nsfw ? `${getEmojiByName("CONTROL.TICK")} Yes` : `${getEmojiByName("CONTROL.CROSS")} No`);
+ if (channel.nsfw !== null ?? false)
+ list.nsfw = entry(
+ channel.nsfw,
+ channel.nsfw
+ ? `${getEmojiByName("CONTROL.TICK")} Yes`
+ : `${getEmojiByName("CONTROL.CROSS")} No`
+ );
else delete list.nsfw;
const data = {
- meta:{
+ meta: {
type: "channelDelete",
displayName: displayName + " Deleted",
calculateType: "channelUpdate",
diff --git a/src/events/channelUpdate.ts b/src/events/channelUpdate.ts
index 89692e8..6717661 100644
--- a/src/events/channelUpdate.ts
+++ b/src/events/channelUpdate.ts
@@ -5,118 +5,218 @@
export async function callback(client, oc, nc) {
const config = await client.memory.readGuildInfo(nc.guild.id);
- const { getAuditLog, log, NucleusColors, entry, renderDelta, renderUser, renderChannel } = client.logger;
+ const {
+ getAuditLog,
+ log,
+ NucleusColors,
+ entry,
+ renderDelta,
+ renderUser,
+ renderChannel
+ } = client.logger;
- if (nc.parent && (nc.parent.id === config.tickets.category)) return;
+ if (nc.parent && nc.parent.id === config.tickets.category) return;
const auditLog = await getAuditLog(nc.guild, "CHANNEL_UPDATE");
- const audit = auditLog.entries.filter(entry => entry.target.id === nc.id).first();
+ const audit = auditLog.entries
+ .filter((entry) => entry.target.id === nc.id)
+ .first();
if (audit.executor.id === client.user.id) return;
- let emoji:string;
- let readableType:string;
- let displayName:string ;
+ let emoji: string;
+ let readableType: string;
+ let displayName: string;
const changes = {
channelId: entry(nc.id, `\`${nc.id}\``),
channel: entry(nc.id, renderChannel(nc)),
edited: entry(new Date().getTime(), renderDelta(new Date().getTime())),
- editedBy: entry(audit.executor.id, renderUser((await nc.guild.members.fetch(audit.executor.id)).user))
+ editedBy: entry(
+ audit.executor.id,
+ renderUser((await nc.guild.members.fetch(audit.executor.id)).user)
+ )
};
- if (oc.name !== nc.name) changes["name"] = entry([oc.name, nc.name], `${oc.name} -> ${nc.name}`);
- if (oc.position !== nc.position) changes["position"] = entry([oc.position, nc.position], `${oc.position} -> ${nc.position}`);
+ if (oc.name !== nc.name)
+ changes.name = entry([oc.name, nc.name], `${oc.name} -> ${nc.name}`);
+ if (oc.position !== nc.position)
+ changes.position = entry(
+ [oc.position, nc.position],
+ `${oc.position} -> ${nc.position}`
+ );
switch (nc.type) {
- case "GUILD_TEXT": {
- emoji = "CHANNEL.TEXT.EDIT";
- readableType = "Text";
- displayName = "Text Channel";
- let oldTopic = oc.topic, newTopic = nc.topic;
- if (oldTopic) {
- if (oldTopic.length > 256) oldTopic = `\`\`\`\n${oldTopic.replace("`", "'").substring(0, 253) + "..."}\n\`\`\``;
- else oldTopic = `\`\`\`\n${oldTopic.replace("`", "'")}\n\`\`\``;
- } else { oldTopic = "None"; }
- if (newTopic) {
- if (newTopic.length > 256) newTopic = `\`\`\`\n${newTopic.replace("`", "'").substring(0, 253) + "..."}\n\`\`\``;
- else newTopic = `\`\`\`\n${newTopic.replace("`", "'")}\n\`\`\``;
- } else { newTopic = "None"; }
- const nsfw = ["", ""];
- nsfw[0] = oc.nsfw ? `${getEmojiByName("CONTROL.TICK")} Yes` : `${getEmojiByName("CONTROL.CROSS")} No`;
- nsfw[1] = nc.nsfw ? `${getEmojiByName("CONTROL.TICK")} Yes` : `${getEmojiByName("CONTROL.CROSS")} No`;
- if (oc.topic !== nc.topic) changes["description"] = entry([oc.topic, nc.topic], `\nBefore: ${oldTopic}\nAfter: ${newTopic}`);
- if (oc.nsfw !== nc.nsfw) changes["nsfw"] = entry([oc.nsfw, nc.nsfw], `${nsfw[0]} -> ${nsfw[1]}`);
- if (oc.rateLimitPerUser !== nc.rateLimitPerUser) changes["rateLimitPerUser"] = entry(
- [oc.rateLimitPerUser, nc.rateLimitPerUser],
- `${humanizeDuration(oc.rateLimitPerUser * 1000)} -> ${humanizeDuration(nc.rateLimitPerUser * 1000)}`
- );
+ case "GUILD_TEXT": {
+ emoji = "CHANNEL.TEXT.EDIT";
+ readableType = "Text";
+ displayName = "Text Channel";
+ let oldTopic = oc.topic,
+ newTopic = nc.topic;
+ if (oldTopic) {
+ if (oldTopic.length > 256)
+ oldTopic = `\`\`\`\n${
+ oldTopic.replace("`", "'").substring(0, 253) + "..."
+ }\n\`\`\``;
+ else oldTopic = `\`\`\`\n${oldTopic.replace("`", "'")}\n\`\`\``;
+ } else {
+ oldTopic = "None";
+ }
+ if (newTopic) {
+ if (newTopic.length > 256)
+ newTopic = `\`\`\`\n${
+ newTopic.replace("`", "'").substring(0, 253) + "..."
+ }\n\`\`\``;
+ else newTopic = `\`\`\`\n${newTopic.replace("`", "'")}\n\`\`\``;
+ } else {
+ newTopic = "None";
+ }
+ const nsfw = ["", ""];
+ nsfw[0] = oc.nsfw
+ ? `${getEmojiByName("CONTROL.TICK")} Yes`
+ : `${getEmojiByName("CONTROL.CROSS")} No`;
+ nsfw[1] = nc.nsfw
+ ? `${getEmojiByName("CONTROL.TICK")} Yes`
+ : `${getEmojiByName("CONTROL.CROSS")} No`;
+ if (oc.topic !== nc.topic)
+ changes.description = entry(
+ [oc.topic, nc.topic],
+ `\nBefore: ${oldTopic}\nAfter: ${newTopic}`
+ );
+ if (oc.nsfw !== nc.nsfw)
+ changes.nsfw = entry(
+ [oc.nsfw, nc.nsfw],
+ `${nsfw[0]} -> ${nsfw[1]}`
+ );
+ if (oc.rateLimitPerUser !== nc.rateLimitPerUser)
+ changes.rateLimitPerUser = entry(
+ [oc.rateLimitPerUser, nc.rateLimitPerUser],
+ `${humanizeDuration(
+ oc.rateLimitPerUser * 1000
+ )} -> ${humanizeDuration(nc.rateLimitPerUser * 1000)}`
+ );
- break;
- }
- case "GUILD_NEWS": {
- emoji = "CHANNEL.TEXT.EDIT";
- readableType = "News";
- displayName = "News Channel";
- let oldTopic = oc.topic, newTopic = nc.topic;
- if (oldTopic) {
- if (oldTopic.length > 256) oldTopic = `\`\`\`\n${oldTopic.replace("`", "'").substring(0, 253) + "..."}\n\`\`\``;
- else oldTopic = `\`\`\`\n${oldTopic.replace("`", "'")}\n\`\`\``;
- } else { oldTopic = "None"; }
- if (newTopic) {
- if (newTopic.length > 256) newTopic = `\`\`\`\n${newTopic.replace("`", "'").substring(0, 253) + "..."}\n\`\`\``;
- else newTopic = `\`\`\`\n${newTopic.replace("`", "'")}\n\`\`\``;
- } else { newTopic = "None"; }
- if (oc.nsfw !== nc.nsfw) changes["nsfw"] = entry([oc.nsfw, nc.nsfw], `${oc.nsfw ? "On" : "Off"} -> ${nc.nsfw ? "On" : "Off"}`);
- break;
- }
- case "GUILD_VOICE": {
- emoji = "CHANNEL.VOICE.EDIT";
- readableType = "Voice";
- displayName = "Voice Channel";
- if (oc.bitrate !== nc.bitrate) changes["bitrate"] = entry([oc.bitrate, nc.bitrate], `${oc.bitrate} -> ${nc.bitrate}`);
- if (oc.userLimit !== nc.userLimit) changes["maxUsers"] = entry([oc.userLimit, nc.userLimit], `${oc.userLimit ? oc.userLimit : "Unlimited"} -> ${nc.userLimit}`);
- if (oc.rtcRegion !== nc.rtcRegion) changes["region"] = entry(
- [oc.rtcRegion, nc.rtcRegion],
- `${oc.rtcRegion || "Automatic"} -> ${nc.rtcRegion || "Automatic"}`
- );
- break;
- }
- case "GUILD_STAGE": {
- emoji = "CHANNEL.VOICE.EDIT";
- readableType = "Stage";
- displayName = "Stage Channel";
- let oldTopic = oc.topic, newTopic = nc.topic;
- if (oldTopic) {
- if (oldTopic.length > 256) oldTopic = `\`\`\`\n${oldTopic.replace("`", "'").substring(0, 253) + "..."}\n\`\`\``;
- else oldTopic = `\`\`\`\n${oldTopic.replace("`", "'")}\n\`\`\``;
- } else { oldTopic = "None"; }
- if (newTopic) {
- if (newTopic.length > 256) newTopic = `\`\`\`\n${newTopic.replace("`", "'").substring(0, 253) + "..."}\n\`\`\``;
- else newTopic = `\`\`\`\n${newTopic.replace("`", "'")}\n\`\`\``;
- } else { newTopic = "None"; }
- if (oc.bitrate !== nc.bitrate) changes["bitrate"] = entry([oc.bitrate, nc.bitrate], `${oc.bitrate} -> ${nc.bitrate}`);
- if (oc.userLimit !== nc.userLimit) changes["maxUsers"] = entry([oc.userLimit, nc.userLimit], `${oc.userLimit ? oc.userLimit : "Unlimited"} -> ${nc.userLimit}`);
- if (oc.rtcRegion !== nc.rtcRegion) changes["region"] = entry(
- [oc.rtcRegion, nc.rtcRegion],
- `${oc.rtcRegion || "Automatic"} -> ${nc.rtcRegion || "Automatic"}`
- );
- break;
- }
- case "GUILD_CATEGORY": {
- emoji = "CHANNEL.CATEGORY.EDIT";
- readableType = "Category";
- displayName = "Category";
- break;
- }
- default: {
- emoji = "CHANNEL.TEXT.EDIT";
- readableType = "Channel";
- displayName = "Channel";
- }
+ break;
+ }
+ case "GUILD_NEWS": {
+ emoji = "CHANNEL.TEXT.EDIT";
+ readableType = "News";
+ displayName = "News Channel";
+ let oldTopic = oc.topic,
+ newTopic = nc.topic;
+ if (oldTopic) {
+ if (oldTopic.length > 256)
+ oldTopic = `\`\`\`\n${
+ oldTopic.replace("`", "'").substring(0, 253) + "..."
+ }\n\`\`\``;
+ else oldTopic = `\`\`\`\n${oldTopic.replace("`", "'")}\n\`\`\``;
+ } else {
+ oldTopic = "None";
+ }
+ if (newTopic) {
+ if (newTopic.length > 256)
+ newTopic = `\`\`\`\n${
+ newTopic.replace("`", "'").substring(0, 253) + "..."
+ }\n\`\`\``;
+ else newTopic = `\`\`\`\n${newTopic.replace("`", "'")}\n\`\`\``;
+ } else {
+ newTopic = "None";
+ }
+ if (oc.nsfw !== nc.nsfw)
+ changes.nsfw = entry(
+ [oc.nsfw, nc.nsfw],
+ `${oc.nsfw ? "On" : "Off"} -> ${nc.nsfw ? "On" : "Off"}`
+ );
+ break;
+ }
+ case "GUILD_VOICE": {
+ emoji = "CHANNEL.VOICE.EDIT";
+ readableType = "Voice";
+ displayName = "Voice Channel";
+ if (oc.bitrate !== nc.bitrate)
+ changes.bitrate = entry(
+ [oc.bitrate, nc.bitrate],
+ `${oc.bitrate} -> ${nc.bitrate}`
+ );
+ if (oc.userLimit !== nc.userLimit)
+ changes.maxUsers = entry(
+ [oc.userLimit, nc.userLimit],
+ `${oc.userLimit ? oc.userLimit : "Unlimited"} -> ${
+ nc.userLimit
+ }`
+ );
+ if (oc.rtcRegion !== nc.rtcRegion)
+ changes.region = entry(
+ [oc.rtcRegion, nc.rtcRegion],
+ `${oc.rtcRegion || "Automatic"} -> ${
+ nc.rtcRegion || "Automatic"
+ }`
+ );
+ break;
+ }
+ case "GUILD_STAGE": {
+ emoji = "CHANNEL.VOICE.EDIT";
+ readableType = "Stage";
+ displayName = "Stage Channel";
+ let oldTopic = oc.topic,
+ newTopic = nc.topic;
+ if (oldTopic) {
+ if (oldTopic.length > 256)
+ oldTopic = `\`\`\`\n${
+ oldTopic.replace("`", "'").substring(0, 253) + "..."
+ }\n\`\`\``;
+ else oldTopic = `\`\`\`\n${oldTopic.replace("`", "'")}\n\`\`\``;
+ } else {
+ oldTopic = "None";
+ }
+ if (newTopic) {
+ if (newTopic.length > 256)
+ newTopic = `\`\`\`\n${
+ newTopic.replace("`", "'").substring(0, 253) + "..."
+ }\n\`\`\``;
+ else newTopic = `\`\`\`\n${newTopic.replace("`", "'")}\n\`\`\``;
+ } else {
+ newTopic = "None";
+ }
+ if (oc.bitrate !== nc.bitrate)
+ changes.bitrate = entry(
+ [oc.bitrate, nc.bitrate],
+ `${oc.bitrate} -> ${nc.bitrate}`
+ );
+ if (oc.userLimit !== nc.userLimit)
+ changes.maxUsers = entry(
+ [oc.userLimit, nc.userLimit],
+ `${oc.userLimit ? oc.userLimit : "Unlimited"} -> ${
+ nc.userLimit
+ }`
+ );
+ if (oc.rtcRegion !== nc.rtcRegion)
+ changes.region = entry(
+ [oc.rtcRegion, nc.rtcRegion],
+ `${oc.rtcRegion || "Automatic"} -> ${
+ nc.rtcRegion || "Automatic"
+ }`
+ );
+ break;
+ }
+ case "GUILD_CATEGORY": {
+ emoji = "CHANNEL.CATEGORY.EDIT";
+ readableType = "Category";
+ displayName = "Category";
+ break;
+ }
+ default: {
+ emoji = "CHANNEL.TEXT.EDIT";
+ readableType = "Channel";
+ displayName = "Channel";
+ }
}
const t = oc.type.split("_")[1];
- if (oc.type !== nc.type) changes["type"] = entry([oc.type, nc.type], `${t[0] + t.splice(1).toLowerCase()} -> ${readableType}`);
+ if (oc.type !== nc.type)
+ changes.type = entry(
+ [oc.type, nc.type],
+ `${t[0] + t.splice(1).toLowerCase()} -> ${readableType}`
+ );
if (!(Object.values(changes).length - 4)) return;
const data = {
- meta:{
+ meta: {
type: "channelUpdate",
displayName: displayName + " Edited",
calculateType: "channelUpdate",
@@ -130,4 +230,4 @@
}
};
log(data);
-}
\ No newline at end of file
+}
diff --git a/src/events/commandError.ts b/src/events/commandError.ts
index 2ec6a5d..ce50122 100644
--- a/src/events/commandError.ts
+++ b/src/events/commandError.ts
@@ -4,18 +4,26 @@
export async function callback(client, interaction, error) {
if (interaction.replied || interaction.deferred) {
- await interaction.followUp({embeds: [new EmojiEmbed()
- .setTitle("Something went wrong")
- .setDescription(error.message ?? error.toString())
- .setStatus("Danger")
- .setEmoji("CONTROL.BLOCKCROSS")
- ], ephemeral: true});
+ await interaction.followUp({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Something went wrong")
+ .setDescription(error.message ?? error.toString())
+ .setStatus("Danger")
+ .setEmoji("CONTROL.BLOCKCROSS")
+ ],
+ ephemeral: true
+ });
} else {
- await interaction.reply({embeds: [new EmojiEmbed()
- .setTitle("Something went wrong")
- .setDescription(error.message ?? error.toString())
- .setStatus("Danger")
- .setEmoji("CONTROL.BLOCKCROSS")
- ], ephemeral: true});
+ await interaction.reply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Something went wrong")
+ .setDescription(error.message ?? error.toString())
+ .setStatus("Danger")
+ .setEmoji("CONTROL.BLOCKCROSS")
+ ],
+ ephemeral: true
+ });
}
}
diff --git a/src/events/emojiCreate.ts b/src/events/emojiCreate.ts
index 83a30e2..53f564c 100644
--- a/src/events/emojiCreate.ts
+++ b/src/events/emojiCreate.ts
@@ -1,9 +1,19 @@
export const event = "emojiCreate";
export async function callback(client, emoji) {
- const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderEmoji } = emoji.client.logger;
+ const {
+ getAuditLog,
+ log,
+ NucleusColors,
+ entry,
+ renderUser,
+ renderDelta,
+ renderEmoji
+ } = emoji.client.logger;
const auditLog = await getAuditLog(emoji.guild, "EMOJI_CREATE");
- const audit = auditLog.entries.filter(entry => entry.target.id === emoji.id).first();
+ const audit = auditLog.entries
+ .filter((entry) => entry.target.id === emoji.id)
+ .first();
if (audit.executor.id === client.user.id) return;
const data = {
meta: {
@@ -18,7 +28,10 @@
emojiId: entry(emoji.id, `\`${emoji.id}\``),
emoji: entry(emoji.name, renderEmoji(emoji)),
createdBy: entry(audit.executor.id, renderUser(audit.executor)),
- created: entry(emoji.createdTimestamp, renderDelta(emoji.createdTimestamp))
+ created: entry(
+ emoji.createdTimestamp,
+ renderDelta(emoji.createdTimestamp)
+ )
},
hidden: {
guild: emoji.guild.id
diff --git a/src/events/emojiDelete.ts b/src/events/emojiDelete.ts
index 5ed7a87..041b432 100644
--- a/src/events/emojiDelete.ts
+++ b/src/events/emojiDelete.ts
@@ -1,9 +1,19 @@
export const event = "emojiDelete";
export async function callback(client, emoji) {
- const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderEmoji } = emoji.client.logger;
+ const {
+ getAuditLog,
+ log,
+ NucleusColors,
+ entry,
+ renderUser,
+ renderDelta,
+ renderEmoji
+ } = emoji.client.logger;
const auditLog = await getAuditLog(emoji.guild, "EMOJI_DELETE");
- const audit = auditLog.entries.filter(entry => entry.target.id === emoji.id).first();
+ const audit = auditLog.entries
+ .filter((entry) => entry.target.id === emoji.id)
+ .first();
if (audit.executor.id === client.user.id) return;
const data = {
meta: {
@@ -18,8 +28,14 @@
emojiId: entry(emoji.id, `\`${emoji.id}\``),
emoji: entry(emoji.name, renderEmoji(emoji)),
deletedBy: entry(audit.executor.id, renderUser(audit.executor)),
- created: entry(emoji.createdTimestamp, renderDelta(emoji.createdTimestamp)),
- deleted: entry(audit.createdTimestamp, renderDelta(audit.createdTimestamp))
+ created: entry(
+ emoji.createdTimestamp,
+ renderDelta(emoji.createdTimestamp)
+ ),
+ deleted: entry(
+ audit.createdTimestamp,
+ renderDelta(audit.createdTimestamp)
+ )
},
hidden: {
guild: emoji.guild.id
diff --git a/src/events/emojiUpdate.ts b/src/events/emojiUpdate.ts
index d04c6c8..34b16de 100644
--- a/src/events/emojiUpdate.ts
+++ b/src/events/emojiUpdate.ts
@@ -1,7 +1,15 @@
export const event = "emojiUpdate";
export async function callback(client, oe, ne) {
- const { getAuditLog, log, NucleusColors, entry, renderDelta, renderUser, renderEmoji } = client.logger;
+ const {
+ getAuditLog,
+ log,
+ NucleusColors,
+ entry,
+ renderDelta,
+ renderUser,
+ renderEmoji
+ } = client.logger;
if (oe.name === ne.name) return;
const auditLog = await getAuditLog(ne.guild, "EMOJI_UPDATE");
@@ -12,11 +20,14 @@
emojiId: entry(ne.id, `\`${ne.id}\``),
emoji: entry(ne.id, renderEmoji(ne)),
edited: entry(ne.createdTimestamp, renderDelta(ne.createdTimestamp)),
- editedBy: entry(audit.executor.id, renderUser((await ne.guild.members.fetch(audit.executor.id)).user)),
+ editedBy: entry(
+ audit.executor.id,
+ renderUser((await ne.guild.members.fetch(audit.executor.id)).user)
+ ),
name: entry([oe.name, ne.name], `\`:${oe.name}:\` -> \`:${ne.name}:\``)
};
const data = {
- meta:{
+ meta: {
type: "emojiUpdate",
displayName: "Emoji Edited",
calculateType: "emojiUpdate",
@@ -30,4 +41,4 @@
}
};
log(data);
-}
\ No newline at end of file
+}
diff --git a/src/events/guildBanAdd.ts b/src/events/guildBanAdd.ts
index c5d269b..dd723d3 100644
--- a/src/events/guildBanAdd.ts
+++ b/src/events/guildBanAdd.ts
@@ -6,11 +6,20 @@
export async function callback(client, ban) {
await statsChannelRemove(client, ban.user);
purgeByUser(ban.user.id, ban.guild);
- const { log, NucleusColors, entry, renderUser, renderDelta, getAuditLog } = ban.user.client.logger;
+ const { log, NucleusColors, entry, renderUser, renderDelta, getAuditLog } =
+ ban.user.client.logger;
const auditLog = await getAuditLog(ban.guild, "MEMBER_BAN_ADD");
- const audit = auditLog.entries.filter(entry => entry.target.id === ban.user.id).first();
+ const audit = auditLog.entries
+ .filter((entry) => entry.target.id === ban.user.id)
+ .first();
if (audit.executor.id === client.user.id) return;
- await client.database.history.create("ban", ban.guild.id, ban.user, audit.executor, audit.reason);
+ await client.database.history.create(
+ "ban",
+ ban.guild.id,
+ ban.user,
+ audit.executor,
+ audit.reason
+ );
const data = {
meta: {
type: "memberBan",
@@ -23,10 +32,19 @@
list: {
memberId: entry(ban.user.id, `\`${ban.user.id}\``),
name: entry(ban.user.id, renderUser(ban.user)),
- banned: entry(new Date().getTime(), renderDelta(new Date().getTime())),
+ banned: entry(
+ new Date().getTime(),
+ renderDelta(new Date().getTime())
+ ),
bannedBy: entry(audit.executor.id, renderUser(audit.executor)),
- reason: entry(audit.reason, audit.reason ? `\n> ${audit.reason}` : "*No reason provided.*"),
- accountCreated: entry(ban.user.createdAt, renderDelta(ban.user.createdAt)),
+ reason: entry(
+ audit.reason,
+ audit.reason ? `\n> ${audit.reason}` : "*No reason provided.*"
+ ),
+ accountCreated: entry(
+ ban.user.createdAt,
+ renderDelta(ban.user.createdAt)
+ ),
serverMemberCount: ban.guild.memberCount
},
hidden: {
diff --git a/src/events/guildBanRemove.ts b/src/events/guildBanRemove.ts
index 352265f..4c2263d 100644
--- a/src/events/guildBanRemove.ts
+++ b/src/events/guildBanRemove.ts
@@ -6,11 +6,20 @@
export async function callback(client, ban) {
await statsChannelRemove(client, ban.user);
purgeByUser(ban.user.id, ban.guild);
- const { log, NucleusColors, entry, renderUser, renderDelta, getAuditLog } = ban.user.client.logger;
+ const { log, NucleusColors, entry, renderUser, renderDelta, getAuditLog } =
+ ban.user.client.logger;
const auditLog = await getAuditLog(ban.guild, "MEMBER_BAN_REMOVE");
- const audit = auditLog.entries.filter(entry => entry.target.id === ban.user.id).first();
+ const audit = auditLog.entries
+ .filter((entry) => entry.target.id === ban.user.id)
+ .first();
if (audit.executor.id === client.user.id) return;
- await client.database.history.create("unban", ban.guild.id, ban.user, audit.executor, audit.reason);
+ await client.database.history.create(
+ "unban",
+ ban.guild.id,
+ ban.user,
+ audit.executor,
+ audit.reason
+ );
const data = {
meta: {
type: "memberUnban",
@@ -23,9 +32,15 @@
list: {
memberId: entry(ban.user.id, `\`${ban.user.id}\``),
name: entry(ban.user.id, renderUser(ban.user)),
- unbanned: entry(new Date().getTime(), renderDelta(new Date().getTime())),
+ unbanned: entry(
+ new Date().getTime(),
+ renderDelta(new Date().getTime())
+ ),
unbannedBy: entry(audit.executor.id, renderUser(audit.executor)),
- accountCreated: entry(ban.user.createdAt, renderDelta(ban.user.createdAt))
+ accountCreated: entry(
+ ban.user.createdAt,
+ renderDelta(ban.user.createdAt)
+ )
},
hidden: {
guild: ban.guild.id
diff --git a/src/events/guildCreate.ts b/src/events/guildCreate.ts
index 8f8d0f5..5ae4248 100644
--- a/src/events/guildCreate.ts
+++ b/src/events/guildCreate.ts
@@ -1,6 +1,6 @@
import type { Guild } from "discord.js";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
-// @ts-ignore
+// @ts-expect-error
import type { HaikuClient } from "jshaiku";
import guide from "../reflex/guide.js";
diff --git a/src/events/guildMemberUpdate.ts b/src/events/guildMemberUpdate.ts
index a7f8c47..4cffe69 100644
--- a/src/events/guildMemberUpdate.ts
+++ b/src/events/guildMemberUpdate.ts
@@ -2,14 +2,29 @@
export async function callback(client, before, after) {
try {
- const { log, NucleusColors, entry, renderUser, renderDelta, getAuditLog } = after.client.logger;
+ const {
+ log,
+ NucleusColors,
+ entry,
+ renderUser,
+ renderDelta,
+ getAuditLog
+ } = after.client.logger;
const auditLog = await getAuditLog(after.guild, "MEMBER_UPDATE");
- const audit = auditLog.entries.filter(entry => entry.target.id === after.id).first();
+ const audit = auditLog.entries
+ .filter((entry) => entry.target.id === after.id)
+ .first();
if (audit.executor.id === client.user.id) return;
if (before.nickname !== after.nickname) {
await client.database.history.create(
- "nickname", after.guild.id, after.user, audit.executor,
- null, before.nickname || before.user.username, after.nickname || after.user.username);
+ "nickname",
+ after.guild.id,
+ after.user,
+ audit.executor,
+ null,
+ before.nickname || before.user.username,
+ after.nickname || after.user.username
+ );
const data = {
meta: {
type: "memberUpdate",
@@ -22,19 +37,41 @@
list: {
memberId: entry(after.id, `\`${after.id}\``),
name: entry(after.user.id, renderUser(after.user)),
- before: entry(before.nickname, before.nickname ? before.nickname : "*None*"),
- after: entry(after.nickname, after.nickname ? after.nickname : "*None*"),
- changed: entry(new Date().getTime(), renderDelta(new Date().getTime())),
- changedBy: entry(audit.executor.id, renderUser(audit.executor))
+ before: entry(
+ before.nickname,
+ before.nickname ? before.nickname : "*None*"
+ ),
+ after: entry(
+ after.nickname,
+ after.nickname ? after.nickname : "*None*"
+ ),
+ changed: entry(
+ new Date().getTime(),
+ renderDelta(new Date().getTime())
+ ),
+ changedBy: entry(
+ audit.executor.id,
+ renderUser(audit.executor)
+ )
},
hidden: {
guild: after.guild.id
}
};
log(data);
- } else if (before.communicationDisabledUntilTimestamp < new Date().getTime() && after.communicationDisabledUntil > new Date().getTime()) {
+ } else if (
+ before.communicationDisabledUntilTimestamp < new Date().getTime() &&
+ after.communicationDisabledUntil > new Date().getTime()
+ ) {
await client.database.history.create(
- "mute", after.guild.id, after.user, audit.executor, audit.reason, null, null, null
+ "mute",
+ after.guild.id,
+ after.user,
+ audit.executor,
+ audit.reason,
+ null,
+ null,
+ null
);
const data = {
meta: {
@@ -48,25 +85,51 @@
list: {
memberId: entry(after.id, `\`${after.id}\``),
name: entry(after.user.id, renderUser(after.user)),
- mutedUntil: entry(after.communicationDisabledUntilTimestamp, renderDelta(after.communicationDisabledUntilTimestamp)),
- muted: entry(new Date().getTime(), renderDelta(new Date().getTime())),
- mutedBy: entry(audit.executor.id, renderUser(audit.executor)),
- reason: entry(audit.reason, audit.reason ? audit.reason : "\n> *No reason provided*")
+ mutedUntil: entry(
+ after.communicationDisabledUntilTimestamp,
+ renderDelta(after.communicationDisabledUntilTimestamp)
+ ),
+ muted: entry(
+ new Date().getTime(),
+ renderDelta(new Date().getTime())
+ ),
+ mutedBy: entry(
+ audit.executor.id,
+ renderUser(audit.executor)
+ ),
+ reason: entry(
+ audit.reason,
+ audit.reason ? audit.reason : "\n> *No reason provided*"
+ )
},
hidden: {
guild: after.guild.id
}
};
log(data);
- client.database.eventScheduler.schedule("naturalUnmute", after.communicationDisabledUntil,
- {guild: after.guild.id, user: after.id, expires: after.communicationDisabledUntilTimestamp}
+ client.database.eventScheduler.schedule(
+ "naturalUnmute",
+ after.communicationDisabledUntil,
+ {
+ guild: after.guild.id,
+ user: after.id,
+ expires: after.communicationDisabledUntilTimestamp
+ }
);
} else if (
- after.communicationDisabledUntil === null && before.communicationDisabledUntilTimestamp !== null &&
+ after.communicationDisabledUntil === null &&
+ before.communicationDisabledUntilTimestamp !== null &&
new Date().getTime() >= audit.createdTimestamp
) {
await client.database.history.create(
- "unmute", after.guild.id, after.user, audit.executor, null, null, null, null
+ "unmute",
+ after.guild.id,
+ after.user,
+ audit.executor,
+ null,
+ null,
+ null,
+ null
);
const data = {
meta: {
@@ -80,15 +143,27 @@
list: {
memberId: entry(after.id, `\`${after.id}\``),
name: entry(after.user.id, renderUser(after.user)),
- unmuted: entry(new Date().getTime(), renderDelta(new Date().getTime())),
- unmutedBy: entry(audit.executor.id, renderUser(audit.executor))
+ unmuted: entry(
+ new Date().getTime(),
+ renderDelta(new Date().getTime())
+ ),
+ unmutedBy: entry(
+ audit.executor.id,
+ renderUser(audit.executor)
+ )
},
hidden: {
guild: after.guild.id
}
};
log(data);
- client.database.eventScheduler.cancel("naturalUnmute", {guild: after.guild.id, user: after.id, expires: before.communicationDisabledUntilTimestamp});
+ client.database.eventScheduler.cancel("naturalUnmute", {
+ guild: after.guild.id,
+ user: after.id,
+ expires: before.communicationDisabledUntilTimestamp
+ });
}
- } catch (e) { console.log(e); }
+ } catch (e) {
+ console.log(e);
+ }
}
diff --git a/src/events/guildUpdate.ts b/src/events/guildUpdate.ts
index 2cb1de8..2c87807 100644
--- a/src/events/guildUpdate.ts
+++ b/src/events/guildUpdate.ts
@@ -4,9 +4,12 @@
export async function callback(client, before, after) {
await statsChannelUpdate(client, after.me);
- const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta } = after.client.logger;
+ const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta } =
+ after.client.logger;
const auditLog = await getAuditLog(after, "GUILD_UPDATE");
- const audit = auditLog.entries.filter(entry => entry.target.id === after.id).first();
+ const audit = auditLog.entries
+ .filter((entry) => entry.target.id === after.id)
+ .first();
if (audit.executor.id === client.user.id) return;
const list = {};
@@ -29,18 +32,65 @@
ELEVATED: "Enabled"
};
- if (before.name !== after.name) list["name"] = entry([before.name, after.name], `${before.name} -> ${after.name}`);
- if (before.icon !== after.icon) list["icon"] = entry([before.icon, after.icon], `[Before](${before.iconURL()}) -> [After](${after.iconURL()})`);
- if (before.splash !== after.splash) list["splash"] = entry([before.splash, after.splash], `[Before](${before.splashURL()}) -> [After](${after.splashURL()})`);
- if (before.banner !== after.banner) list["banner"] = entry([before.banner, after.banner], `[Before](${before.bannerURL()}) -> [After](${after.bannerURL()})`);
- if (before.owner !== after.owner) list["owner"] = entry([before.owner, after.owner], `${renderUser(before.owner.user)} -> ${renderUser(after.owner.user)}`);
- if (before.verificationLevel !== after.verificationLevel) list["verificationLevel"] = entry([verificationLevels[before.verificationLevel], verificationLevels[after.verificationLevel]], `${verificationLevels[before.verificationLevel]} -> ${verificationLevels[after.verificationLevel]}`);
- if (before.explicitContentFilter !== after.explicitContentFilter) list["explicitContentFilter"] = entry([explicitContentFilterLevels[before.explicitContentFilter], explicitContentFilterLevels[after.explicitContentFilter]], `${explicitContentFilterLevels[before.explicitContentFilter]} -> ${explicitContentFilterLevels[after.explicitContentFilter]}`);
- if (before.mfaLevel !== after.mfaLevel) list["2 factor authentication"] = entry([MFALevels[before.mfaLevel], MFALevels[after.mfaLevel]], `${MFALevels[before.mfaLevel]} -> ${MFALevels[after.mfaLevel]}`);
+ if (before.name !== after.name)
+ list.name = entry(
+ [before.name, after.name],
+ `${before.name} -> ${after.name}`
+ );
+ if (before.icon !== after.icon)
+ list.icon = entry(
+ [before.icon, after.icon],
+ `[Before](${before.iconURL()}) -> [After](${after.iconURL()})`
+ );
+ if (before.splash !== after.splash)
+ list.splash = entry(
+ [before.splash, after.splash],
+ `[Before](${before.splashURL()}) -> [After](${after.splashURL()})`
+ );
+ if (before.banner !== after.banner)
+ list.banner = entry(
+ [before.banner, after.banner],
+ `[Before](${before.bannerURL()}) -> [After](${after.bannerURL()})`
+ );
+ if (before.owner !== after.owner)
+ list.owner = entry(
+ [before.owner, after.owner],
+ `${renderUser(before.owner.user)} -> ${renderUser(
+ after.owner.user
+ )}`
+ );
+ if (before.verificationLevel !== after.verificationLevel)
+ list.verificationLevel = entry(
+ [
+ verificationLevels[before.verificationLevel],
+ verificationLevels[after.verificationLevel]
+ ],
+ `${verificationLevels[before.verificationLevel]} -> ${
+ verificationLevels[after.verificationLevel]
+ }`
+ );
+ if (before.explicitContentFilter !== after.explicitContentFilter)
+ list.explicitContentFilter = entry(
+ [
+ explicitContentFilterLevels[before.explicitContentFilter],
+ explicitContentFilterLevels[after.explicitContentFilter]
+ ],
+ `${explicitContentFilterLevels[before.explicitContentFilter]} -> ${
+ explicitContentFilterLevels[after.explicitContentFilter]
+ }`
+ );
+ if (before.mfaLevel !== after.mfaLevel)
+ list["2 factor authentication"] = entry(
+ [MFALevels[before.mfaLevel], MFALevels[after.mfaLevel]],
+ `${MFALevels[before.mfaLevel]} -> ${MFALevels[after.mfaLevel]}`
+ );
- if (!(Object.keys(list).length)) return;
- list["updated"] = entry(new Date().getTime(), renderDelta(new Date().getTime()));
- list["updatedBy"] = entry(audit.executor.id, renderUser(audit.executor));
+ if (!Object.keys(list).length) return;
+ list.updated = entry(
+ new Date().getTime(),
+ renderDelta(new Date().getTime())
+ );
+ list.updatedBy = entry(audit.executor.id, renderUser(audit.executor));
const data = {
meta: {
type: "guildUpdate",
diff --git a/src/events/interactionCreate.ts b/src/events/interactionCreate.ts
index 08fcc77..60b90e3 100644
--- a/src/events/interactionCreate.ts
+++ b/src/events/interactionCreate.ts
@@ -8,49 +8,123 @@
export const event = "interactionCreate";
-
function getAutocomplete(typed: string, options: string[]): object[] {
- options = options.filter(option => option.length <= 100); // thanks discord. 6000 character limit on slash command inputs but only 100 for autocomplete.
- if (!typed) return options.slice(0, 25).sort().map(option => ({name: option, value: option}));
- const fuse = new Fuse(options, {useExtendedSearch: true, findAllMatches: true, minMatchCharLength: 0}).search(typed);
- return fuse.slice(0, 25).map(option => ({name: option.item, value: option.item}));
+ options = options.filter((option) => option.length <= 100); // thanks discord. 6000 character limit on slash command inputs but only 100 for autocomplete.
+ if (!typed)
+ return options
+ .slice(0, 25)
+ .sort()
+ .map((option) => ({ name: option, value: option }));
+ const fuse = new Fuse(options, {
+ useExtendedSearch: true,
+ findAllMatches: true,
+ minMatchCharLength: 0
+ }).search(typed);
+ return fuse
+ .slice(0, 25)
+ .map((option) => ({ name: option.item, value: option.item }));
}
function generateStatsChannelAutocomplete(typed) {
- const validReplacements = ["serverName", "memberCount", "memberCount:bots", "memberCount:humans"];
+ const validReplacements = [
+ "serverName",
+ "memberCount",
+ "memberCount:bots",
+ "memberCount:humans"
+ ];
const autocompletions = [];
const beforeLastOpenBracket = typed.match(/(.*){[^{}]{0,15}$/);
- if (beforeLastOpenBracket !== null) { for (const replacement of validReplacements) { autocompletions.push(`${beforeLastOpenBracket[1]} {${replacement}}`); } }
- else { for (const replacement of validReplacements) { autocompletions.push(`${typed} {${replacement}}`); } }
+ if (beforeLastOpenBracket !== null) {
+ for (const replacement of validReplacements) {
+ autocompletions.push(
+ `${beforeLastOpenBracket[1]} {${replacement}}`
+ );
+ }
+ } else {
+ for (const replacement of validReplacements) {
+ autocompletions.push(`${typed} {${replacement}}`);
+ }
+ }
return getAutocomplete(typed, autocompletions);
}
function generateWelcomeMessageAutocomplete(typed) {
- const validReplacements = ["serverName", "memberCount", "memberCount:bots", "memberCount:humans", "member:mention", "member:name"];
+ const validReplacements = [
+ "serverName",
+ "memberCount",
+ "memberCount:bots",
+ "memberCount:humans",
+ "member:mention",
+ "member:name"
+ ];
const autocompletions = [];
const beforeLastOpenBracket = typed.match(/(.*){[^{}]{0,15}$/);
- if (beforeLastOpenBracket !== null) { for (const replacement of validReplacements) { autocompletions.push(`${beforeLastOpenBracket[1]} {${replacement}}`); } }
- else { for (const replacement of validReplacements) { autocompletions.push(`${typed} {${replacement}}`); } }
+ if (beforeLastOpenBracket !== null) {
+ for (const replacement of validReplacements) {
+ autocompletions.push(
+ `${beforeLastOpenBracket[1]} {${replacement}}`
+ );
+ }
+ } else {
+ for (const replacement of validReplacements) {
+ autocompletions.push(`${typed} {${replacement}}`);
+ }
+ }
return getAutocomplete(typed, autocompletions);
}
async function interactionCreate(interaction) {
if (interaction.componentType === "BUTTON") {
switch (interaction.customId) {
- case "rolemenu": { return await roleMenu(interaction); }
- case "verifybutton": { return verify(interaction); }
- case "createticket": { return create(interaction); }
- case "closeticket": { return close(interaction); }
- case "createtranscript": { return createTranscript(interaction); }
+ case "rolemenu": {
+ return await roleMenu(interaction);
+ }
+ case "verifybutton": {
+ return verify(interaction);
+ }
+ case "createticket": {
+ return create(interaction);
+ }
+ case "closeticket": {
+ return close(interaction);
+ }
+ case "createtranscript": {
+ return createTranscript(interaction);
+ }
}
} else if (interaction.type === "APPLICATION_COMMAND_AUTOCOMPLETE") {
- switch (`${interaction.commandName} ${interaction.options.getSubcommandGroup(false)} ${interaction.options.getSubcommand(false)}`) {
- case "tag null null": { return interaction.respond(getAutocomplete(interaction.options.getString("tag"), (await tagAutocomplete(interaction)))); }
- case "settings null stats": { return interaction.respond(generateStatsChannelAutocomplete(interaction.options.getString("name"))); }
- case "settings null welcome": { return interaction.respond(generateWelcomeMessageAutocomplete(interaction.options.getString("message"))); }
+ switch (
+ `${
+ interaction.commandName
+ } ${interaction.options.getSubcommandGroup(
+ false
+ )} ${interaction.options.getSubcommand(false)}`
+ ) {
+ case "tag null null": {
+ return interaction.respond(
+ getAutocomplete(
+ interaction.options.getString("tag"),
+ await tagAutocomplete(interaction)
+ )
+ );
+ }
+ case "settings null stats": {
+ return interaction.respond(
+ generateStatsChannelAutocomplete(
+ interaction.options.getString("name")
+ )
+ );
+ }
+ case "settings null welcome": {
+ return interaction.respond(
+ generateWelcomeMessageAutocomplete(
+ interaction.options.getString("message")
+ )
+ );
+ }
}
}
}
export async function callback(client, interaction) {
await interactionCreate(interaction);
-}
\ No newline at end of file
+}
diff --git a/src/events/inviteCreate.ts b/src/events/inviteCreate.ts
index 1cbed02..5461307 100644
--- a/src/events/inviteCreate.ts
+++ b/src/events/inviteCreate.ts
@@ -2,9 +2,19 @@
export const event = "inviteCreate";
export async function callback(client, invite) {
- const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = invite.client.logger;
+ const {
+ getAuditLog,
+ log,
+ NucleusColors,
+ entry,
+ renderUser,
+ renderDelta,
+ renderChannel
+ } = invite.client.logger;
const auditLog = await getAuditLog(invite.guild, "INVITE_CREATE");
- const audit = auditLog.entries.filter(entry => entry.target.id === invite.id).first();
+ const audit = auditLog.entries
+ .filter((entry) => entry.target.id === invite.id)
+ .first();
if (audit.executor.id === client.user.id) return;
const data = {
meta: {
@@ -18,9 +28,15 @@
list: {
channel: entry(invite.channel.id, renderChannel(invite.channel)),
link: entry(invite.url, invite.url),
- expires: entry(invite.maxAge, invite.maxAge ? humanizeDuration(invite.maxAge * 1000) : "Never"),
+ expires: entry(
+ invite.maxAge,
+ invite.maxAge ? humanizeDuration(invite.maxAge * 1000) : "Never"
+ ),
createdBy: entry(audit.executor.id, renderUser(audit.executor)),
- created: entry(invite.createdTimestamp, renderDelta(invite.createdTimestamp))
+ created: entry(
+ invite.createdTimestamp,
+ renderDelta(invite.createdTimestamp)
+ )
},
hidden: {
guild: invite.guild.id
diff --git a/src/events/inviteDelete.ts b/src/events/inviteDelete.ts
index cbe4d4b..e5bf241 100644
--- a/src/events/inviteDelete.ts
+++ b/src/events/inviteDelete.ts
@@ -2,9 +2,19 @@
export const event = "inviteDelete";
export async function callback(client, invite) {
- const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = invite.client.logger;
+ const {
+ getAuditLog,
+ log,
+ NucleusColors,
+ entry,
+ renderUser,
+ renderDelta,
+ renderChannel
+ } = invite.client.logger;
const auditLog = await getAuditLog(invite.guild, "INVITE_DELETE");
- const audit = auditLog.entries.filter(entry => entry.target.id === invite.id).first();
+ const audit = auditLog.entries
+ .filter((entry) => entry.target.id === invite.id)
+ .first();
if (audit.executor.id === client.user.id) return;
const data = {
meta: {
@@ -18,9 +28,15 @@
list: {
channel: entry(invite.channel.id, renderChannel(invite.channel)),
link: entry(invite.url, invite.url),
- expires: entry(invite.maxAge, invite.maxAge ? humanizeDuration(invite.maxAge * 1000) : "Never"),
+ expires: entry(
+ invite.maxAge,
+ invite.maxAge ? humanizeDuration(invite.maxAge * 1000) : "Never"
+ ),
deletedBy: entry(audit.executor.id, renderUser(audit.executor)),
- deleted: entry(new Date().getTime(), renderDelta(new Date().getTime()))
+ deleted: entry(
+ new Date().getTime(),
+ renderDelta(new Date().getTime())
+ )
},
hidden: {
guild: invite.guild.id
diff --git a/src/events/memberJoin.ts b/src/events/memberJoin.ts
index 34545fb..ea0b24d 100644
--- a/src/events/memberJoin.ts
+++ b/src/events/memberJoin.ts
@@ -6,9 +6,16 @@
export async function callback(_, member) {
welcome(_, member);
- statsChannelAdd(_, member );
- const { log, NucleusColors, entry, renderUser, renderDelta } = member.client.logger;
- await client.database.history.create("join", member.guild.id, member.user, null, null);
+ statsChannelAdd(_, member);
+ const { log, NucleusColors, entry, renderUser, renderDelta } =
+ member.client.logger;
+ await client.database.history.create(
+ "join",
+ member.guild.id,
+ member.user,
+ null,
+ null
+ );
const data = {
meta: {
type: "memberJoin",
@@ -22,7 +29,10 @@
memberId: entry(member.id, `\`${member.id}\``),
name: entry(member.id, renderUser(member.user)),
joined: entry(member.joinedAt, renderDelta(member.joinedAt)),
- accountCreated: entry(member.user.createdAt, renderDelta(member.user.createdAt)),
+ accountCreated: entry(
+ member.user.createdAt,
+ renderDelta(member.user.createdAt)
+ ),
serverMemberCount: member.guild.memberCount
},
hidden: {
diff --git a/src/events/memberLeave.ts b/src/events/memberLeave.ts
index 842a48b..d170396 100644
--- a/src/events/memberLeave.ts
+++ b/src/events/memberLeave.ts
@@ -6,9 +6,12 @@
export async function callback(client, member) {
purgeByUser(member.id, member.guild);
await statsChannelRemove(client, member);
- const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta } = member.client.logger;
+ const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta } =
+ member.client.logger;
const auditLog = await getAuditLog(member.guild, "MEMBER_KICK");
- const audit = auditLog.entries.filter(entry => entry.target.id === member.id).first();
+ const audit = auditLog.entries
+ .filter((entry) => entry.target.id === member.id)
+ .first();
let type = "leave";
if (audit) {
if (audit.executor.id === client.user.id) return;
@@ -18,7 +21,13 @@
}
let data;
if (type === "kick") {
- await client.database.history.create("kick", member.guild.id, member.user, audit.executor, audit.reason);
+ await client.database.history.create(
+ "kick",
+ member.guild.id,
+ member.user,
+ audit.executor,
+ audit.reason
+ );
data = {
meta: {
type: "memberKick",
@@ -32,10 +41,21 @@
memberId: entry(member.id, `\`${member.id}\``),
name: entry(member.id, renderUser(member.user)),
joined: entry(member.joinedAt, renderDelta(member.joinedAt)),
- kicked: entry(new Date().getTime(), renderDelta(new Date().getTime())),
+ kicked: entry(
+ new Date().getTime(),
+ renderDelta(new Date().getTime())
+ ),
kickedBy: entry(audit.executor.id, renderUser(audit.executor)),
- reason: entry(audit.reason, audit.reason ? `\n> ${audit.reason}` : "*No reason provided.*"),
- accountCreated: entry(member.user.createdAt, renderDelta(member.user.createdAt)),
+ reason: entry(
+ audit.reason,
+ audit.reason
+ ? `\n> ${audit.reason}`
+ : "*No reason provided.*"
+ ),
+ accountCreated: entry(
+ member.user.createdAt,
+ renderDelta(member.user.createdAt)
+ ),
serverMemberCount: member.guild.memberCount
},
hidden: {
@@ -43,7 +63,13 @@
}
};
} else {
- await client.database.history.create("leave", member.guild.id, member.user, null, null);
+ await client.database.history.create(
+ "leave",
+ member.guild.id,
+ member.user,
+ null,
+ null
+ );
data = {
meta: {
type: "memberLeave",
@@ -56,9 +82,18 @@
list: {
memberId: entry(member.id, `\`${member.id}\``),
name: entry(member.id, renderUser(member.user)),
- joined: entry(member.joinedTimestamp, renderDelta(member.joinedAt)),
- left: entry(new Date().getTime(), renderDelta(new Date().getTime())),
- accountCreated: entry(member.user.createdAt, renderDelta(member.user.createdAt)),
+ joined: entry(
+ member.joinedTimestamp,
+ renderDelta(member.joinedAt)
+ ),
+ left: entry(
+ new Date().getTime(),
+ renderDelta(new Date().getTime())
+ ),
+ accountCreated: entry(
+ member.user.createdAt,
+ renderDelta(member.user.createdAt)
+ ),
serverMemberCount: member.guild.memberCount
},
hidden: {
diff --git a/src/events/messageCreate.ts b/src/events/messageCreate.ts
index bbb6a32..53de4df 100644
--- a/src/events/messageCreate.ts
+++ b/src/events/messageCreate.ts
@@ -1,24 +1,42 @@
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
-// @ts-ignore
+// @ts-expect-error
import { HaikuClient } from "jshaiku";
-import { LinkCheck, MalwareCheck, NSFWCheck, SizeCheck, TestString, TestImage } from "../reflex/scanners.js";
+import {
+ LinkCheck,
+ MalwareCheck,
+ NSFWCheck,
+ SizeCheck,
+ TestString,
+ TestImage
+} from "../reflex/scanners.js";
import logAttachment from "../premium/attachmentLogs.js";
import createLogException from "../utils/createLogException.js";
import getEmojiByName from "../utils/getEmojiByName.js";
import client from "../utils/client.js";
-import {callback as a} from "../reflex/statsChannelUpdate.js";
+import { callback as a } from "../reflex/statsChannelUpdate.js";
import type { Message } from "discord.js";
export const event = "messageCreate";
export async function callback(_client: HaikuClient, message: Message) {
- if(!message) return;
- if(!message.guild) return;
+ if (!message) return;
+ if (!message.guild) return;
if (message.author.bot) return;
if (message.channel.type === "DM") return;
- try { await a(client, await message.guild.members.fetch(message.author.id)); } catch(e) { console.log(e);}
+ try {
+ await a(client, await message.guild.members.fetch(message.author.id));
+ } catch (e) {
+ console.log(e);
+ }
- const { log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = client.logger;
+ const {
+ log,
+ NucleusColors,
+ entry,
+ renderUser,
+ renderDelta,
+ renderChannel
+ } = client.logger;
const fileNames = await logAttachment(message);
@@ -26,36 +44,61 @@
const config = await client.memory.readGuildInfo(message.guild.id);
const filter = getEmojiByName("ICONS.FILTER");
let attachmentJump = "";
- if (config.logging.attachments.saved[message.channel.id + message.id]) { attachmentJump = ` [[View attachments]](${config.logging.attachments.saved[message.channel.id + message.id]})`; }
+ if (config.logging.attachments.saved[message.channel.id + message.id]) {
+ attachmentJump = ` [[View attachments]](${
+ config.logging.attachments.saved[message.channel.id + message.id]
+ })`;
+ }
const list = {
messageId: entry(message.id, `\`${message.id}\``),
sentBy: entry(message.author.id, renderUser(message.author)),
sentIn: entry(message.channel.id, renderChannel(message.channel)),
deleted: entry(new Date().getTime(), renderDelta(new Date().getTime())),
mentions: message.mentions.users.size,
- attachments: entry(message.attachments.size, message.attachments.size + attachmentJump),
+ attachments: entry(
+ message.attachments.size,
+ message.attachments.size + attachmentJump
+ ),
repliedTo: entry(
message.reference ? message.reference.messageId : null,
- message.reference ? `[[Jump to message]](https://discord.com/channels/${message.guild.id}/${message.channel.id}/${message.reference.messageId})` : "None"
+ message.reference
+ ? `[[Jump to message]](https://discord.com/channels/${message.guild.id}/${message.channel.id}/${message.reference.messageId})`
+ : "None"
)
};
if (config.filters.invite.enabled) {
- if (!config.filters.invite.allowed.channels.includes(message.channel.id)) {
- if ((/(?:https?:\/\/)?discord(?:app)?\.(?:com\/invite|gg)\/[a-zA-Z0-9]+\/?/.test(content))) {
- createLogException(message.guild.id, message.channel.id, message.id);
+ if (
+ !config.filters.invite.allowed.channels.includes(message.channel.id)
+ ) {
+ if (
+ /(?:https?:\/\/)?discord(?:app)?\.(?:com\/invite|gg)\/[a-zA-Z0-9]+\/?/.test(
+ content
+ )
+ ) {
+ createLogException(
+ message.guild.id,
+ message.channel.id,
+ message.id
+ );
message.delete();
const data = {
meta: {
type: "messageDelete",
- displayName: "Message Deleted (Automated, Contained Invite)",
+ displayName:
+ "Message Deleted (Automated, Contained Invite)",
calculateType: "autoModeratorDeleted",
color: NucleusColors.red,
emoji: "MESSAGE.DELETE",
timestamp: new Date().getTime()
},
separate: {
- start: filter + " Contained invite\n\n" + (content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*")
+ start:
+ filter +
+ " Contained invite\n\n" +
+ (content
+ ? `**Message:**\n\`\`\`${content}\`\`\``
+ : "**Message:** *Message had no content*")
},
list: list,
hidden: {
@@ -69,15 +112,26 @@
if (fileNames.files.length > 0) {
for (const element of fileNames.files) {
- if(!message) return;
+ if (!message) return;
const url = element.url ? element.url : element.local;
if (url !== undefined) {
- if(/\.(jpg|jpeg|png|gif|gifv|webm|webp|mp4|wav|mp3|ogg)$/.test(url)) {
- if (config.filters.images.NSFW && !(
- message.channel.type === "GUILD_PUBLIC_THREAD" ? false : message.channel.nsfw
- )) {
+ if (
+ /\.(jpg|jpeg|png|gif|gifv|webm|webp|mp4|wav|mp3|ogg)$/.test(
+ url
+ )
+ ) {
+ if (
+ config.filters.images.NSFW &&
+ !(message.channel.type === "GUILD_PUBLIC_THREAD"
+ ? false
+ : message.channel.nsfw)
+ ) {
if (await NSFWCheck(url)) {
- createLogException(message.guild.id, message.channel.id, message.id);
+ createLogException(
+ message.guild.id,
+ message.channel.id,
+ message.id
+ );
await message.delete();
const data = {
meta: {
@@ -89,7 +143,12 @@
timestamp: new Date().getTime()
},
separate: {
- start: filter + " Image detected as NSFW\n\n" + (content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*")
+ start:
+ filter +
+ " Image detected as NSFW\n\n" +
+ (content
+ ? `**Message:**\n\`\`\`${content}\`\`\``
+ : "**Message:** *Message had no content*")
},
list: list,
hidden: {
@@ -101,9 +160,17 @@
}
if (config.filters.wordFilter.enabled) {
const text = await TestImage(url);
- const check = TestString(text ?? "", config.filters.wordFilter.words.loose, config.filters.wordFilter.words.strict);
- if(check !== null) {
- createLogException(message.guild.id, message.channel.id, message.id);
+ const check = TestString(
+ text ?? "",
+ config.filters.wordFilter.words.loose,
+ config.filters.wordFilter.words.strict
+ );
+ if (check !== null) {
+ createLogException(
+ message.guild.id,
+ message.channel.id,
+ message.id
+ );
await message.delete();
const data = {
meta: {
@@ -115,7 +182,12 @@
timestamp: new Date().getTime()
},
separate: {
- start: filter + " Image contained filtered word\n\n" + (content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*")
+ start:
+ filter +
+ " Image contained filtered word\n\n" +
+ (content
+ ? `**Message:**\n\`\`\`${content}\`\`\``
+ : "**Message:** *Message had no content*")
},
list: list,
hidden: {
@@ -126,9 +198,13 @@
}
}
if (config.filters.images.size) {
- if(url.match(/\.+(webp|png|jpg)$/gi)) {
- if(!await SizeCheck(element)) {
- createLogException(message.guild.id, message.channel.id, message.id);
+ if (url.match(/\.+(webp|png|jpg)$/gi)) {
+ if (!(await SizeCheck(element))) {
+ createLogException(
+ message.guild.id,
+ message.channel.id,
+ message.id
+ );
await message.delete();
const data = {
meta: {
@@ -140,7 +216,12 @@
timestamp: new Date().getTime()
},
separate: {
- start: filter + " Image was too small\n\n" + (content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*")
+ start:
+ filter +
+ " Image was too small\n\n" +
+ (content
+ ? `**Message:**\n\`\`\`${content}\`\`\``
+ : "**Message:** *Message had no content*")
},
list: list,
hidden: {
@@ -154,7 +235,11 @@
}
if (config.filters.malware) {
if (!MalwareCheck(url)) {
- createLogException(message.guild.id, message.channel.id, message.id);
+ createLogException(
+ message.guild.id,
+ message.channel.id,
+ message.id
+ );
await message.delete();
const data = {
meta: {
@@ -166,7 +251,12 @@
timestamp: new Date().getTime()
},
separate: {
- start: filter + " File detected as malware\n\n" + (content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*")
+ start:
+ filter +
+ " File detected as malware\n\n" +
+ (content
+ ? `**Message:**\n\`\`\`${content}\`\`\``
+ : "**Message:** *Message had no content*")
},
list: list,
hidden: {
@@ -179,7 +269,7 @@
}
}
}
- if(!message) return;
+ if (!message) return;
const linkDetectionTypes = await LinkCheck(message);
if (linkDetectionTypes.length > 0) {
@@ -195,7 +285,12 @@
timestamp: new Date().getTime()
},
separate: {
- start: filter + ` Link filtered as ${linkDetectionTypes[0]?.toLowerCase()}\n\n` + (content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*")
+ start:
+ filter +
+ ` Link filtered as ${linkDetectionTypes[0]?.toLowerCase()}\n\n` +
+ (content
+ ? `**Message:**\n\`\`\`${content}\`\`\``
+ : "**Message:** *Message had no content*")
},
list: list,
hidden: {
@@ -206,9 +301,17 @@
}
if (config.filters.wordFilter.enabled) {
- const check = TestString(content, config.filters.wordFilter.words.loose, config.filters.wordFilter.words.strict);
- if(check !== null) {
- createLogException(message.guild.id, message.channel.id, message.id);
+ const check = TestString(
+ content,
+ config.filters.wordFilter.words.loose,
+ config.filters.wordFilter.words.strict
+ );
+ if (check !== null) {
+ createLogException(
+ message.guild.id,
+ message.channel.id,
+ message.id
+ );
await message.delete();
const data = {
meta: {
@@ -220,7 +323,12 @@
timestamp: new Date().getTime()
},
separate: {
- start: filter + " Message contained filtered word\n\n" + (content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*")
+ start:
+ filter +
+ " Message contained filtered word\n\n" +
+ (content
+ ? `**Message:**\n\`\`\`${content}\`\`\``
+ : "**Message:** *Message had no content*")
},
list: list,
hidden: {
@@ -242,7 +350,9 @@
timestamp: new Date().getTime()
},
separate: {
- start: content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*"
+ start: content
+ ? `**Message:**\n\`\`\`${content}\`\`\``
+ : "**Message:** *Message had no content*"
},
list: list,
hidden: {
@@ -252,10 +362,14 @@
return log(data);
}
if (config.filters.pings.roles) {
- for(const roleId in message.mentions.roles) {
- if(!message) return;
+ for (const roleId in message.mentions.roles) {
+ if (!message) return;
if (!config.filters.pings.allowed.roles.includes(roleId)) {
- createLogException(message.guild.id, message.channel.id, message.id);
+ createLogException(
+ message.guild.id,
+ message.channel.id,
+ message.id
+ );
await message.delete();
const data = {
meta: {
@@ -267,7 +381,9 @@
timestamp: new Date().getTime()
},
separate: {
- start: content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*"
+ start: content
+ ? `**Message:**\n\`\`\`${content}\`\`\``
+ : "**Message:** *Message had no content*"
},
list: list,
hidden: {
@@ -278,7 +394,10 @@
}
}
}
- if (message.mentions.users.size >= config.filters.pings.mass && config.filters.pings.mass) {
+ if (
+ message.mentions.users.size >= config.filters.pings.mass &&
+ config.filters.pings.mass
+ ) {
createLogException(message.guild.id, message.channel.id, message.id);
await message.delete();
const data = {
@@ -291,7 +410,9 @@
timestamp: new Date().getTime()
},
separate: {
- start: content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*"
+ start: content
+ ? `**Message:**\n\`\`\`${content}\`\`\``
+ : "**Message:** *Message had no content*"
},
list: list,
hidden: {
diff --git a/src/events/messageDelete.ts b/src/events/messageDelete.ts
index 473fa52..4cdbdb2 100644
--- a/src/events/messageDelete.ts
+++ b/src/events/messageDelete.ts
@@ -3,10 +3,25 @@
export async function callback(client, message) {
try {
if (message.author.id === client.user.id) return;
- if (client.noLog.includes(`${message.guild.id}/${message.channel.id}/${message.id}`)) return;
- const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = message.channel.client.logger;
+ if (
+ client.noLog.includes(
+ `${message.guild.id}/${message.channel.id}/${message.id}`
+ )
+ )
+ return;
+ const {
+ getAuditLog,
+ log,
+ NucleusColors,
+ entry,
+ renderUser,
+ renderDelta,
+ renderChannel
+ } = message.channel.client.logger;
const auditLog = await getAuditLog(message.guild, "MEMBER_BAN_ADD");
- const audit = auditLog.entries.filter(entry => entry.target.id === message.author.id).first();
+ const audit = auditLog.entries
+ .filter((entry) => entry.target.id === message.author.id)
+ .first();
if (audit) {
if (audit.createdAt - 100 < new Date().getTime()) return;
}
@@ -14,10 +29,19 @@
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;
+ 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 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",
@@ -28,18 +52,28 @@
timestamp: new Date().getTime()
},
separate: {
- start: content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*"
+ 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)),
- deleted: entry(new Date().getTime(), renderDelta(new Date().getTime())),
+ sentIn: entry(
+ message.channel.id,
+ renderChannel(message.channel)
+ ),
+ deleted: entry(
+ new Date().getTime(),
+ renderDelta(new Date().getTime())
+ ),
mentions: message.mentions.users.size,
attachments: entry(attachments, attachments + attachmentJump),
repliedTo: entry(
message.reference.messageId || null,
- message.reference.messageId ? `[[Jump to message]](https://discord.com/channels/${message.guild.id}/${message.channel.id}/${message.reference.messageId})` : "None"
+ message.reference.messageId
+ ? `[[Jump to message]](https://discord.com/channels/${message.guild.id}/${message.channel.id}/${message.reference.messageId})`
+ : "None"
)
},
hidden: {
@@ -47,5 +81,7 @@
}
};
log(data);
- } catch(e) { console.log(e); }
+ } catch (e) {
+ console.log(e);
+ }
}
diff --git a/src/events/messageEdit.ts b/src/events/messageEdit.ts
index 148cdb7..c83512c 100644
--- a/src/events/messageEdit.ts
+++ b/src/events/messageEdit.ts
@@ -2,15 +2,29 @@
export async function callback(client, oldMessage, newMessage) {
if (newMessage.author.id === client.user.id) return;
- const { log, NucleusColors, entry, renderUser, renderDelta, renderNumberDelta, renderChannel } = newMessage.channel.client.logger;
+ const {
+ log,
+ NucleusColors,
+ entry,
+ renderUser,
+ renderDelta,
+ renderNumberDelta,
+ renderChannel
+ } = newMessage.channel.client.logger;
newMessage.reference = newMessage.reference || {};
let newContent = newMessage.cleanContent.replaceAll("`", "‘");
let oldContent = oldMessage.cleanContent.replaceAll("`", "‘");
let attachmentJump = "";
- const config = (await client.database.guilds.read(newMessage.guild.id)).logging.attachments.saved[newMessage.channel.id + newMessage.id];
- if (config) { attachmentJump = ` [[View attachments]](${config})`; }
+ const config = (await client.database.guilds.read(newMessage.guild.id))
+ .logging.attachments.saved[newMessage.channel.id + newMessage.id];
+ if (config) {
+ attachmentJump = ` [[View attachments]](${config})`;
+ }
if (newContent === oldContent) {
- if (!oldMessage.flags.has("CROSSPOSTED") && newMessage.flags.has("CROSSPOSTED")) {
+ if (
+ !oldMessage.flags.has("CROSSPOSTED") &&
+ newMessage.flags.has("CROSSPOSTED")
+ ) {
const data = {
meta: {
type: "messageAnnounce",
@@ -25,14 +39,35 @@
},
list: {
messageId: entry(newMessage.id, `\`${newMessage.id}\``),
- sentBy: entry(newMessage.author.id, renderUser(newMessage.author)),
- sentIn: entry(newMessage.channel.id, renderChannel(newMessage.channel)),
- sent: entry(new Date(newMessage.createdTimestamp), renderDelta(new Date(newMessage.createdTimestamp))),
- published: entry(new Date(newMessage.editedTimestamp), renderDelta(new Date(newMessage.editedTimestamp))),
- mentions: renderNumberDelta(oldMessage.mentions.users.size, newMessage.mentions.users.size),
+ sentBy: entry(
+ newMessage.author.id,
+ renderUser(newMessage.author)
+ ),
+ sentIn: entry(
+ newMessage.channel.id,
+ renderChannel(newMessage.channel)
+ ),
+ sent: entry(
+ new Date(newMessage.createdTimestamp),
+ renderDelta(new Date(newMessage.createdTimestamp))
+ ),
+ published: entry(
+ new Date(newMessage.editedTimestamp),
+ renderDelta(new Date(newMessage.editedTimestamp))
+ ),
+ mentions: renderNumberDelta(
+ oldMessage.mentions.users.size,
+ newMessage.mentions.users.size
+ ),
attachments: entry(
- renderNumberDelta(oldMessage.attachments.size, newMessage.attachments.size),
- renderNumberDelta(oldMessage.attachments.size, newMessage.attachments.size) + attachmentJump
+ renderNumberDelta(
+ oldMessage.attachments.size,
+ newMessage.attachments.size
+ ),
+ renderNumberDelta(
+ oldMessage.attachments.size,
+ newMessage.attachments.size
+ ) + attachmentJump
)
},
hidden: {
@@ -42,9 +77,13 @@
return log(data);
}
}
- if (!newMessage.editedTimestamp) { return; }
- if (newContent.length > 256) newContent = newContent.substring(0, 253) + "...";
- if (oldContent.length > 256) oldContent = oldContent.substring(0, 253) + "...";
+ if (!newMessage.editedTimestamp) {
+ return;
+ }
+ if (newContent.length > 256)
+ newContent = newContent.substring(0, 253) + "...";
+ if (oldContent.length > 256)
+ oldContent = oldContent.substring(0, 253) + "...";
const data = {
meta: {
type: "messageUpdate",
@@ -55,24 +94,49 @@
timestamp: newMessage.editedTimestamp
},
separate: {
- start: (oldContent ? `**Before:**\n\`\`\`\n${oldContent}\n\`\`\`\n` : "**Before:** *Message had no content*\n") +
- (newContent ? `**After:**\n\`\`\`\n${newContent}\n\`\`\`` : "**After:** *Message had no content*"),
+ start:
+ (oldContent
+ ? `**Before:**\n\`\`\`\n${oldContent}\n\`\`\`\n`
+ : "**Before:** *Message had no content*\n") +
+ (newContent
+ ? `**After:**\n\`\`\`\n${newContent}\n\`\`\``
+ : "**After:** *Message had no content*"),
end: `[[Jump to message]](${newMessage.url})`
},
list: {
messageId: entry(newMessage.id, `\`${newMessage.id}\``),
sentBy: entry(newMessage.author.id, renderUser(newMessage.author)),
- sentIn: entry(newMessage.channel.id, renderChannel(newMessage.channel)),
- sent: entry(new Date(newMessage.createdTimestamp), renderDelta(new Date(newMessage.createdTimestamp))),
- edited: entry(new Date(newMessage.editedTimestamp), renderDelta(new Date(newMessage.editedTimestamp))),
- mentions: renderNumberDelta(oldMessage.mentions.users.size, newMessage.mentions.users.size),
+ sentIn: entry(
+ newMessage.channel.id,
+ renderChannel(newMessage.channel)
+ ),
+ sent: entry(
+ new Date(newMessage.createdTimestamp),
+ renderDelta(new Date(newMessage.createdTimestamp))
+ ),
+ edited: entry(
+ new Date(newMessage.editedTimestamp),
+ renderDelta(new Date(newMessage.editedTimestamp))
+ ),
+ mentions: renderNumberDelta(
+ oldMessage.mentions.users.size,
+ newMessage.mentions.users.size
+ ),
attachments: entry(
- renderNumberDelta(oldMessage.attachments.size, newMessage.attachments.size),
- renderNumberDelta(oldMessage.attachments.size, newMessage.attachments.size) + attachmentJump
+ renderNumberDelta(
+ oldMessage.attachments.size,
+ newMessage.attachments.size
+ ),
+ renderNumberDelta(
+ oldMessage.attachments.size,
+ newMessage.attachments.size
+ ) + attachmentJump
),
repliedTo: entry(
newMessage.reference.messageId || null,
- newMessage.reference.messageId ? `[[Jump to message]](https://discord.com/channels/${newMessage.guild.id}/${newMessage.channel.id}/${newMessage.reference.messageId})` : "None"
+ newMessage.reference.messageId
+ ? `[[Jump to message]](https://discord.com/channels/${newMessage.guild.id}/${newMessage.channel.id}/${newMessage.reference.messageId})`
+ : "None"
)
},
hidden: {
@@ -80,4 +144,4 @@
}
};
log(data);
-}
\ No newline at end of file
+}
diff --git a/src/events/roleCreate.ts b/src/events/roleCreate.ts
index a717242..f0051a0 100644
--- a/src/events/roleCreate.ts
+++ b/src/events/roleCreate.ts
@@ -1,10 +1,20 @@
export const event = "roleCreate";
export async function callback(client, role) {
- const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderRole } = role.client.logger;
+ const {
+ getAuditLog,
+ log,
+ NucleusColors,
+ entry,
+ renderUser,
+ renderDelta,
+ renderRole
+ } = role.client.logger;
if (role.managed) return;
const auditLog = await getAuditLog(role.guild, "ROLE_CREATE");
- const audit = auditLog.entries.filter(entry => entry.target.id === role.id).first();
+ const audit = auditLog.entries
+ .filter((entry) => entry.target.id === role.id)
+ .first();
if (audit.executor.id === client.user.id) return;
const data = {
meta: {
@@ -19,7 +29,10 @@
roleId: entry(role.id, `\`${role.id}\``),
role: entry(role.name, renderRole(role)),
createdBy: entry(audit.executor.id, renderUser(audit.executor)),
- created: entry(role.createdTimestamp, renderDelta(role.createdTimestamp))
+ created: entry(
+ role.createdTimestamp,
+ renderDelta(role.createdTimestamp)
+ )
},
hidden: {
guild: role.guild.id
diff --git a/src/events/roleDelete.ts b/src/events/roleDelete.ts
index ad74584..185ea8e 100644
--- a/src/events/roleDelete.ts
+++ b/src/events/roleDelete.ts
@@ -3,10 +3,13 @@
export const event = "roleDelete";
export async function callback(client, role) {
- const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta } = role.client.logger;
+ const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta } =
+ role.client.logger;
if (role.managed) return;
const auditLog = await getAuditLog(role.guild, "ROLE_DELETE");
- const audit = auditLog.entries.filter(entry => entry.target.id === role.id).first();
+ const audit = auditLog.entries
+ .filter((entry) => entry.target.id === role.id)
+ .first();
if (audit.executor.id === client.user.id) return;
const data = {
meta: {
@@ -21,12 +24,28 @@
roleId: entry(role.id, `\`${role.id}\``),
role: entry(role.name, role.name),
color: entry(role.hexColor, `\`${role.hexColor}\``),
- showInMemberList: entry(role.hoist, role.hoist ? `${getEmojiByName("CONTROL.TICK")} Yes` : `${getEmojiByName("CONTROL.CROSS")} No`),
- mentionable: entry(role.mentionable, role.mentionable ? `${getEmojiByName("CONTROL.TICK")} Yes` : `${getEmojiByName("CONTROL.CROSS")} No`),
+ showInMemberList: entry(
+ role.hoist,
+ role.hoist
+ ? `${getEmojiByName("CONTROL.TICK")} Yes`
+ : `${getEmojiByName("CONTROL.CROSS")} No`
+ ),
+ mentionable: entry(
+ role.mentionable,
+ role.mentionable
+ ? `${getEmojiByName("CONTROL.TICK")} Yes`
+ : `${getEmojiByName("CONTROL.CROSS")} No`
+ ),
members: entry(role.members.size, `${role.members.size}`),
deletedBy: entry(audit.executor.id, renderUser(audit.executor)),
- created: entry(role.createdTimestamp, renderDelta(role.createdTimestamp)),
- deleted: entry(new Date().getTime(), renderDelta(new Date().getTime()))
+ created: entry(
+ role.createdTimestamp,
+ renderDelta(role.createdTimestamp)
+ ),
+ deleted: entry(
+ new Date().getTime(),
+ renderDelta(new Date().getTime())
+ )
},
hidden: {
guild: role.guild.id
diff --git a/src/events/roleUpdate.ts b/src/events/roleUpdate.ts
index c51a9b3..be276e5 100644
--- a/src/events/roleUpdate.ts
+++ b/src/events/roleUpdate.ts
@@ -3,7 +3,15 @@
export const event = "roleUpdate";
export async function callback(client, or, nr) {
- const { getAuditLog, log, NucleusColors, entry, renderDelta, renderUser, renderRole } = client.logger;
+ const {
+ getAuditLog,
+ log,
+ NucleusColors,
+ entry,
+ renderDelta,
+ renderUser,
+ renderRole
+ } = client.logger;
const auditLog = await getAuditLog(nr.guild, "ROLE_UPDATE");
const audit = auditLog.entries.first();
@@ -13,24 +21,52 @@
roleId: entry(nr.id, `\`${nr.id}\``),
role: entry(nr.id, renderRole(nr)),
edited: entry(new Date().getTime(), renderDelta(new Date().getTime())),
- editedBy: entry(audit.executor.id, renderUser((await nr.guild.members.fetch(audit.executor.id)).user))
+ editedBy: entry(
+ audit.executor.id,
+ renderUser((await nr.guild.members.fetch(audit.executor.id)).user)
+ )
};
const mentionable = ["", ""];
const hoist = ["", ""];
- mentionable[0] = or.mentionable ? `${getEmojiByName("CONTROL.TICK")} Yes` : `${getEmojiByName("CONTROL.CROSS")} No`;
- mentionable[1] = nr.mentionable ? `${getEmojiByName("CONTROL.TICK")} Yes` : `${getEmojiByName("CONTROL.CROSS")} No`;
- hoist[0] = or.hoist ? `${getEmojiByName("CONTROL.TICK")} Yes` : `${getEmojiByName("CONTROL.CROSS")} No`;
- hoist[1] = nr.hoist ? `${getEmojiByName("CONTROL.TICK")} Yes` : `${getEmojiByName("CONTROL.CROSS")} No`;
- if (or.name !== nr.name) changes["name"] = entry([or.name, nr.name], `${or.name} -> ${nr.name}`);
- if (or.position !== nr.position) changes["position"] = entry([or.position, nr.position], `${or.position} -> ${nr.position}`);
- if (or.hoist !== nr.hoist) changes["showInMemberList"] = entry([or.hoist, nr.hoist], `${hoist[0]} -> ${hoist[1]}`);
- if (or.mentionable !== nr.mentionable) changes["mentionable"] = entry([or.mentionable, nr.mentionable], `${mentionable[0]} -> ${mentionable[1]}`);
- if (or.hexColor !== nr.hexColor) changes["color"] = entry([or.hexColor, nr.hexColor], `\`${or.hexColor}\` -> \`${nr.hexColor}\``);
+ mentionable[0] = or.mentionable
+ ? `${getEmojiByName("CONTROL.TICK")} Yes`
+ : `${getEmojiByName("CONTROL.CROSS")} No`;
+ mentionable[1] = nr.mentionable
+ ? `${getEmojiByName("CONTROL.TICK")} Yes`
+ : `${getEmojiByName("CONTROL.CROSS")} No`;
+ hoist[0] = or.hoist
+ ? `${getEmojiByName("CONTROL.TICK")} Yes`
+ : `${getEmojiByName("CONTROL.CROSS")} No`;
+ hoist[1] = nr.hoist
+ ? `${getEmojiByName("CONTROL.TICK")} Yes`
+ : `${getEmojiByName("CONTROL.CROSS")} No`;
+ if (or.name !== nr.name)
+ changes.name = entry([or.name, nr.name], `${or.name} -> ${nr.name}`);
+ if (or.position !== nr.position)
+ changes.position = entry(
+ [or.position, nr.position],
+ `${or.position} -> ${nr.position}`
+ );
+ if (or.hoist !== nr.hoist)
+ changes.showInMemberList = entry(
+ [or.hoist, nr.hoist],
+ `${hoist[0]} -> ${hoist[1]}`
+ );
+ if (or.mentionable !== nr.mentionable)
+ changes.mentionable = entry(
+ [or.mentionable, nr.mentionable],
+ `${mentionable[0]} -> ${mentionable[1]}`
+ );
+ if (or.hexColor !== nr.hexColor)
+ changes.color = entry(
+ [or.hexColor, nr.hexColor],
+ `\`${or.hexColor}\` -> \`${nr.hexColor}\``
+ );
if (Object.keys(changes).length === 4) return;
const data = {
- meta:{
+ meta: {
type: "roleUpdate",
displayName: "Role Edited",
calculateType: "guildRoleUpdate",
@@ -44,4 +80,4 @@
}
}; // TODO: show perms changed (webpage)
log(data);
-}
\ No newline at end of file
+}
diff --git a/src/events/stickerCreate.ts b/src/events/stickerCreate.ts
index 43f2e9c..54de270 100644
--- a/src/events/stickerCreate.ts
+++ b/src/events/stickerCreate.ts
@@ -1,9 +1,12 @@
export const event = "stickerCreate";
export async function callback(client, emoji) {
- const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta } = emoji.client.logger;
+ const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta } =
+ emoji.client.logger;
const auditLog = await getAuditLog(emoji.guild, "STICKER_CREATE");
- const audit = auditLog.entries.filter(entry => entry.target.id === emoji.id).first();
+ const audit = auditLog.entries
+ .filter((entry) => entry.target.id === emoji.id)
+ .first();
if (audit.executor.id === client.user.id) return;
const data = {
meta: {
@@ -18,7 +21,10 @@
stickerId: entry(emoji.id, `\`${emoji.id}\``),
emoji: entry(emoji.name, `\`:${emoji.name}:\``),
createdBy: entry(audit.executor.id, renderUser(audit.executor)),
- created: entry(emoji.createdTimestamp, renderDelta(emoji.createdTimestamp))
+ created: entry(
+ emoji.createdTimestamp,
+ renderDelta(emoji.createdTimestamp)
+ )
},
hidden: {
guild: emoji.guild.id
diff --git a/src/events/stickerDelete.ts b/src/events/stickerDelete.ts
index 297e6b0..f390b5c 100644
--- a/src/events/stickerDelete.ts
+++ b/src/events/stickerDelete.ts
@@ -1,9 +1,12 @@
export const event = "stickerDelete";
export async function callback(client, emoji) {
- const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta } = emoji.client.logger;
+ const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta } =
+ emoji.client.logger;
const auditLog = await getAuditLog(emoji.guild, "STICKER_DELETE");
- const audit = auditLog.entries.filter(entry => entry.target.id === emoji.id).first();
+ const audit = auditLog.entries
+ .filter((entry) => entry.target.id === emoji.id)
+ .first();
if (audit.executor.id === client.user.id) return;
const data = {
meta: {
@@ -15,11 +18,17 @@
timestamp: audit.createdTimestamp
},
list: {
- stickerId:entry(emoji.id, `\`${emoji.id}\``),
+ stickerId: entry(emoji.id, `\`${emoji.id}\``),
sticker: entry(emoji.name, `\`${emoji.name}\``),
deletedBy: entry(audit.executor.id, renderUser(audit.executor)),
- created: entry(emoji.createdTimestamp, renderDelta(emoji.createdTimestamp)),
- deleted: entry(audit.createdTimestamp, renderDelta(audit.createdTimestamp))
+ created: entry(
+ emoji.createdTimestamp,
+ renderDelta(emoji.createdTimestamp)
+ ),
+ deleted: entry(
+ audit.createdTimestamp,
+ renderDelta(audit.createdTimestamp)
+ )
},
hidden: {
guild: emoji.guild.id
diff --git a/src/events/stickerUpdate.ts b/src/events/stickerUpdate.ts
index 1bb0fe6..46c4d17 100644
--- a/src/events/stickerUpdate.ts
+++ b/src/events/stickerUpdate.ts
@@ -1,7 +1,8 @@
export const event = "stickerUpdate";
export async function callback(client, oe, ne) {
- const { getAuditLog, log, NucleusColors, entry, renderDelta, renderUser } = client.logger;
+ const { getAuditLog, log, NucleusColors, entry, renderDelta, renderUser } =
+ client.logger;
if (oe.name === ne.name) return;
const auditLog = await getAuditLog(ne.guild, "EMOJI_UPDATE");
@@ -9,13 +10,16 @@
if (audit.executor.id === client.user.id) return;
const changes = {
- stickerId:entry(ne.id, `\`${ne.id}\``),
+ stickerId: entry(ne.id, `\`${ne.id}\``),
edited: entry(ne.createdTimestamp, renderDelta(ne.createdTimestamp)),
- editedBy: entry(audit.executor.id, renderUser((await ne.guild.members.fetch(audit.executor.id)).user)),
+ editedBy: entry(
+ audit.executor.id,
+ renderUser((await ne.guild.members.fetch(audit.executor.id)).user)
+ ),
name: entry([oe.name, ne.name], `\`:${oe.name}:\` -> \`:${ne.name}:\``)
};
const data = {
- meta:{
+ meta: {
type: "stickerUpdate",
displayName: "Sticker Edited",
calculateType: "stickerUpdate",
@@ -29,4 +33,4 @@
}
};
log(data);
-}
\ No newline at end of file
+}
diff --git a/src/events/threadCreate.ts b/src/events/threadCreate.ts
index d6b9e93..4fdedcb 100644
--- a/src/events/threadCreate.ts
+++ b/src/events/threadCreate.ts
@@ -2,9 +2,19 @@
export const event = "threadCreate";
export async function callback(client, thread) {
- const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = thread.client.logger;
+ const {
+ getAuditLog,
+ log,
+ NucleusColors,
+ entry,
+ renderUser,
+ renderDelta,
+ renderChannel
+ } = thread.client.logger;
const auditLog = await getAuditLog(thread.guild, "THREAD_CREATE");
- const audit = auditLog.entries.filter(entry => entry.target.id === thread.id).first();
+ const audit = auditLog.entries
+ .filter((entry) => entry.target.id === thread.id)
+ .first();
if (audit.executor.id === client.user.id) return;
const data = {
meta: {
@@ -16,13 +26,26 @@
timestamp: thread.createdTimestamp
},
list: {
- threadId:entry(thread.id, `\`${thread.id}\``),
+ threadId: entry(thread.id, `\`${thread.id}\``),
name: entry(thread.name, renderChannel(thread)),
parentChannel: entry(thread.parentId, renderChannel(thread.parent)),
- category: entry(thread.parent.parent ? thread.parent.parent.name : "None", thread.parent.parent ? renderChannel(thread.parent.parent) : "None"),
- autoArchiveDuration: entry(thread.autoArchiveDuration, humanizeDuration(thread.autoArchiveDuration * 60 * 1000, { round: true })),
+ category: entry(
+ thread.parent.parent ? thread.parent.parent.name : "None",
+ thread.parent.parent
+ ? renderChannel(thread.parent.parent)
+ : "None"
+ ),
+ autoArchiveDuration: entry(
+ thread.autoArchiveDuration,
+ humanizeDuration(thread.autoArchiveDuration * 60 * 1000, {
+ round: true
+ })
+ ),
createdBy: entry(audit.executor.id, renderUser(audit.executor)),
- created: entry(thread.createdTimestamp, renderDelta(thread.createdTimestamp))
+ created: entry(
+ thread.createdTimestamp,
+ renderDelta(thread.createdTimestamp)
+ )
},
hidden: {
guild: thread.guild.id
diff --git a/src/events/threadDelete.ts b/src/events/threadDelete.ts
index f3a59e7..0077eff 100644
--- a/src/events/threadDelete.ts
+++ b/src/events/threadDelete.ts
@@ -2,9 +2,19 @@
export const event = "threadDelete";
export async function callback(client, thread) {
- const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = thread.client.logger;
+ const {
+ getAuditLog,
+ log,
+ NucleusColors,
+ entry,
+ renderUser,
+ renderDelta,
+ renderChannel
+ } = thread.client.logger;
const auditLog = await getAuditLog(thread.guild, "THREAD_UPDATE");
- const audit = auditLog.entries.filter(entry => entry.target.id === thread.id).first();
+ const audit = auditLog.entries
+ .filter((entry) => entry.target.id === thread.id)
+ .first();
if (audit.executor.id === client.user.id) return;
const data = {
meta: {
@@ -16,15 +26,31 @@
timestamp: new Date().getTime()
},
list: {
- threadId:entry(thread.id, `\`${thread.id}\``),
+ threadId: entry(thread.id, `\`${thread.id}\``),
name: entry(thread.name, thread.name),
parentChannel: entry(thread.parentId, renderChannel(thread.parent)),
- category: entry(thread.parent.parent ? thread.parent.parent.name : "None", thread.parent.parent ? renderChannel(thread.parent.parent) : "None"),
- autoArchiveDuration: entry(thread.autoArchiveDuration, humanizeDuration(thread.autoArchiveDuration * 60 * 1000, { round: true })),
+ category: entry(
+ thread.parent.parent ? thread.parent.parent.name : "None",
+ thread.parent.parent
+ ? renderChannel(thread.parent.parent)
+ : "None"
+ ),
+ autoArchiveDuration: entry(
+ thread.autoArchiveDuration,
+ humanizeDuration(thread.autoArchiveDuration * 60 * 1000, {
+ round: true
+ })
+ ),
membersInThread: entry(thread.memberCount, thread.memberCount),
deletedBy: entry(audit.executor.id, renderUser(audit.executor)),
- created: entry(thread.createdTimestamp, renderDelta(thread.createdTimestamp)),
- deleted: entry(new Date().getTime(), renderDelta(new Date().getTime()))
+ created: entry(
+ thread.createdTimestamp,
+ renderDelta(thread.createdTimestamp)
+ ),
+ deleted: entry(
+ new Date().getTime(),
+ renderDelta(new Date().getTime())
+ )
},
hidden: {
guild: thread.guild.id
diff --git a/src/events/threadUpdate.ts b/src/events/threadUpdate.ts
index 89a721c..ff36ce0 100644
--- a/src/events/threadUpdate.ts
+++ b/src/events/threadUpdate.ts
@@ -2,27 +2,55 @@
export const event = "threadUpdate";
export async function callback(client, before, after) {
- const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = after.client.logger;
+ const {
+ getAuditLog,
+ log,
+ NucleusColors,
+ entry,
+ renderUser,
+ renderDelta,
+ renderChannel
+ } = after.client.logger;
const auditLog = await getAuditLog(after.guild, "THREAD_UPDATE");
- const audit = auditLog.entries.filter(entry => entry.target.id === after.id).first();
+ const audit = auditLog.entries
+ .filter((entry) => entry.target.id === after.id)
+ .first();
if (audit.executor.id === client.user.id) return;
const list = {
- threadId:entry(after.id, `\`${after.id}\``),
+ threadId: entry(after.id, `\`${after.id}\``),
thread: entry(after.name, renderChannel(after)),
parentChannel: entry(after.parentId, renderChannel(after.parent))
};
if (before.name !== after.name) {
- list["name"] = entry([before.name, after.name], `${before.name} -> ${after.name}`);
+ list.name = entry(
+ [before.name, after.name],
+ `${before.name} -> ${after.name}`
+ );
}
if (before.autoArchiveDuration !== after.autoArchiveDuration) {
- list["autoArchiveDuration"] = entry([before.autoArchiveDuration, after.autoArchiveDuration], `${humanizeDuration(before.autoArchiveDuration * 60 * 1000, { round: true })} -> ${humanizeDuration(after.autoArchiveDuration * 60 * 1000, { round: true })}`);
+ list.autoArchiveDuration = entry(
+ [before.autoArchiveDuration, after.autoArchiveDuration],
+ `${humanizeDuration(before.autoArchiveDuration * 60 * 1000, {
+ round: true
+ })} -> ${humanizeDuration(after.autoArchiveDuration * 60 * 1000, {
+ round: true
+ })}`
+ );
}
if (before.rateLimitPerUser !== after.rateLimitPerUser) {
- list["slowmode"] = entry([before.rateLimitPerUser, after.rateLimitPerUser], `${humanizeDuration(before.rateLimitPerUser * 1000)} -> ${humanizeDuration(after.rateLimitPerUser * 1000)}`);
+ list.slowmode = entry(
+ [before.rateLimitPerUser, after.rateLimitPerUser],
+ `${humanizeDuration(
+ before.rateLimitPerUser * 1000
+ )} -> ${humanizeDuration(after.rateLimitPerUser * 1000)}`
+ );
}
if (!(Object.keys(list).length - 3)) return;
- list["updated"] = entry(new Date().getTime(), renderDelta(new Date().getTime()));
- list["updatedBy"] = entry(audit.executor.id, renderUser(audit.executor));
+ list.updated = entry(
+ new Date().getTime(),
+ renderDelta(new Date().getTime())
+ );
+ list.updatedBy = entry(audit.executor.id, renderUser(audit.executor));
const data = {
meta: {
type: "channelUpdate",
diff --git a/src/events/webhookUpdate.ts b/src/events/webhookUpdate.ts
index a11fa63..f600247 100644
--- a/src/events/webhookUpdate.ts
+++ b/src/events/webhookUpdate.ts
@@ -1,66 +1,169 @@
import type Discord from "discord.js";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
-// @ts-ignore
+// @ts-expect-error
import type { HaikuClient } from "jshaiku";
export const event = "webhookUpdate";
-export async function callback(client: HaikuClient, channel: Discord.GuildChannel) {
+export async function callback(
+ client: HaikuClient,
+ channel: Discord.GuildChannel
+) {
try {
- const { getAuditLog, log, NucleusColors, entry, renderUser, renderChannel, renderDelta } = client.logger;
+ const {
+ getAuditLog,
+ log,
+ NucleusColors,
+ entry,
+ renderUser,
+ renderChannel,
+ renderDelta
+ } = client.logger;
let auditLogCreate = getAuditLog(channel.guild, "WEBHOOK_CREATE");
let auditLogUpdate = getAuditLog(channel.guild, "WEBHOOK_UPDATE");
let auditLogDelete = getAuditLog(channel.guild, "WEBHOOK_DELETE");
- [auditLogCreate, auditLogUpdate, auditLogDelete] = await Promise.all([auditLogCreate, auditLogUpdate, auditLogDelete]);
- const auditCreate = auditLogCreate.entries.filter(entry => entry.target.channelId === channel.id).first();
- const auditUpdate = auditLogUpdate.entries.filter(entry => entry.target.channelId === channel.id).first();
- const auditDelete = auditLogDelete.entries.filter(entry => entry.target.channelId === channel.id).first();
+ [auditLogCreate, auditLogUpdate, auditLogDelete] = await Promise.all([
+ auditLogCreate,
+ auditLogUpdate,
+ auditLogDelete
+ ]);
+ const auditCreate = auditLogCreate.entries
+ .filter((entry) => entry.target.channelId === channel.id)
+ .first();
+ const auditUpdate = auditLogUpdate.entries
+ .filter((entry) => entry.target.channelId === channel.id)
+ .first();
+ const auditDelete = auditLogDelete.entries
+ .filter((entry) => entry.target.channelId === channel.id)
+ .first();
if (!auditCreate && !auditUpdate && !auditDelete) return;
let audit = auditCreate;
let action = "Create";
- let list = {} as {created: { value: string, displayValue: string }, updated: { value: string, displayValue: string }, deleted: { value: string, displayValue: string }};
- if (auditUpdate && auditUpdate.createdTimestamp > audit.createdTimestamp) {
- const {before, after} = auditUpdate.changes.reduce(
- (acc, change) => { acc.before[change.key] = change.old; acc.after[change.key] = change.new; return acc; },
- {before: {}, after: {}}
+ let list = {} as {
+ created: { value: string; displayValue: string };
+ updated: { value: string; displayValue: string };
+ deleted: { value: string; displayValue: string };
+ };
+ if (
+ auditUpdate &&
+ auditUpdate.createdTimestamp > audit.createdTimestamp
+ ) {
+ const { before, after } = auditUpdate.changes.reduce(
+ (acc, change) => {
+ acc.before[change.key] = change.old;
+ acc.after[change.key] = change.new;
+ return acc;
+ },
+ { before: {}, after: {} }
);
- if (before.name !== after.name) list["name"] = entry([before.name, after.name], `${before.name} -> ${after.name}`);
- if (before.channel_id !== after.channel_id) list["channel"] = entry([before.channel_id, after.channel_id], renderChannel(await client.channels.fetch(before.channel_id)) + " -> " + renderChannel(await client.channels.fetch(after.channel_id)));
- if (!(Object.keys(list)).length) return;
- list.created = entry(auditUpdate.target.createdTimestamp, renderDelta(auditUpdate.target.createdTimestamp));
- list.edited = entry(after.editedTimestamp, renderDelta(new Date().getTime()));
- list.editedBy = entry(auditUpdate.executor.id, renderUser(auditUpdate.executor));
+ if (before.name !== after.name)
+ list.name = entry(
+ [before.name, after.name],
+ `${before.name} -> ${after.name}`
+ );
+ if (before.channel_id !== after.channel_id)
+ list.channel = entry(
+ [before.channel_id, after.channel_id],
+ renderChannel(
+ await client.channels.fetch(before.channel_id)
+ ) +
+ " -> " +
+ renderChannel(
+ await client.channels.fetch(after.channel_id)
+ )
+ );
+ if (!Object.keys(list).length) return;
+ list.created = entry(
+ auditUpdate.target.createdTimestamp,
+ renderDelta(auditUpdate.target.createdTimestamp)
+ );
+ list.edited = entry(
+ after.editedTimestamp,
+ renderDelta(new Date().getTime())
+ );
+ list.editedBy = entry(
+ auditUpdate.executor.id,
+ renderUser(auditUpdate.executor)
+ );
audit = auditUpdate;
action = "Update";
- } else if (auditDelete && auditDelete.createdTimestamp > audit.createdTimestamp) {
- const {before} = auditDelete.changes.reduce(
- (acc, change) => { acc.before[change.key] = change.old; acc.after[change.key] = change.new; return acc; },
- {before: {}, after: {}}
+ } else if (
+ auditDelete &&
+ auditDelete.createdTimestamp > audit.createdTimestamp
+ ) {
+ const { before } = auditDelete.changes.reduce(
+ (acc, change) => {
+ acc.before[change.key] = change.old;
+ acc.after[change.key] = change.new;
+ return acc;
+ },
+ { before: {}, after: {} }
);
list = {
name: entry(before.name, `${before.name}`),
- channel: entry(before.channel_id, renderChannel(await client.channels.fetch(before.channel_id))),
- created: entry(auditDelete.target.createdTimestamp, renderDelta(auditDelete.target.createdTimestamp)),
- deleted: entry(new Date().getTime(), renderDelta(new Date().getTime())),
- deletedBy: entry(auditDelete.executor.id, renderUser((await channel.guild.members.fetch(auditDelete.executor.id)).user))
+ channel: entry(
+ before.channel_id,
+ renderChannel(
+ await client.channels.fetch(before.channel_id)
+ )
+ ),
+ created: entry(
+ auditDelete.target.createdTimestamp,
+ renderDelta(auditDelete.target.createdTimestamp)
+ ),
+ deleted: entry(
+ new Date().getTime(),
+ renderDelta(new Date().getTime())
+ ),
+ deletedBy: entry(
+ auditDelete.executor.id,
+ renderUser(
+ (
+ await channel.guild.members.fetch(
+ auditDelete.executor.id
+ )
+ ).user
+ )
+ )
};
audit = auditDelete;
action = "Delete";
} else {
- const {before} = auditDelete.changes.reduce(
- (acc, change) => { acc.before[change.key] = change.old; acc.after[change.key] = change.new; return acc; },
- {before: {}, after: {}}
+ const { before } = auditDelete.changes.reduce(
+ (acc, change) => {
+ acc.before[change.key] = change.old;
+ acc.after[change.key] = change.new;
+ return acc;
+ },
+ { before: {}, after: {} }
);
list = {
name: entry(before.name, `${before.name}`),
- channel: entry(before.channel_id, renderChannel(await client.channels.fetch(before.channel_id))),
- createdBy: entry(auditCreate.executor.id, renderUser((await channel.guild.members.fetch(auditCreate.executor.id)).user)),
- created: entry(new Date().getTime(), renderDelta(new Date().getTime()))
+ channel: entry(
+ before.channel_id,
+ renderChannel(
+ await client.channels.fetch(before.channel_id)
+ )
+ ),
+ createdBy: entry(
+ auditCreate.executor.id,
+ renderUser(
+ (
+ await channel.guild.members.fetch(
+ auditCreate.executor.id
+ )
+ ).user
+ )
+ ),
+ created: entry(
+ new Date().getTime(),
+ renderDelta(new Date().getTime())
+ )
};
}
const cols = {
- "Create": "green",
- "Update": "yellow",
- "Delete": "red"
+ Create: "green",
+ Update: "yellow",
+ Delete: "red"
};
const data = {
meta: {
@@ -77,5 +180,7 @@
}
};
log(data);
- } catch(e) { console.log(e); }
+ } catch (e) {
+ console.log(e);
+ }
}
diff --git a/src/index.ts b/src/index.ts
index 22436e2..e66dbb3 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,4 +1,3 @@
-
import { Logger } from "./utils/log.js";
import runServer from "./api/index.js";
import Memory from "./utils/memory.js";
@@ -28,4 +27,4 @@
eventScheduler: await new EventScheduler().start()
};
-await client.login();
\ No newline at end of file
+await client.login();
diff --git a/src/premium/attachmentLogs.ts b/src/premium/attachmentLogs.ts
index 5a771bc..679627d 100644
--- a/src/premium/attachmentLogs.ts
+++ b/src/premium/attachmentLogs.ts
@@ -6,60 +6,98 @@
import addPlural from "../utils/plurals.js";
import type { Message } from "discord.js";
-
-export default async function logAttachment(message: Message): Promise<AttachmentLogSchema> {
- if (!message.guild) throw new Error("Tried to log an attachment in a non-guild message");
+export default async function logAttachment(
+ message: Message
+): Promise<AttachmentLogSchema> {
+ if (!message.guild)
+ throw new Error("Tried to log an attachment in a non-guild message");
const { renderUser, renderChannel, renderDelta } = client.logger;
const attachments = [];
for (const attachment of message.attachments.values()) {
- attachments.push({local: await saveAttachment(attachment.url), url: attachment.url, height: attachment.height, width: attachment.width, size: attachment.size});
+ attachments.push({
+ local: await saveAttachment(attachment.url),
+ url: attachment.url,
+ height: attachment.height,
+ width: attachment.width,
+ size: attachment.size
+ });
}
const links = message.content.match(/https?:\/\/\S+/gi) || [];
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), url: link, height: null, width: null});
+ if (
+ link
+ .toLowerCase()
+ .match(/\.(jpg|jpeg|png|gif|gifv|webm|webp|mp4|wav|mp3|ogg)$/gi)
+ ) {
+ attachments.push({
+ local: await saveAttachment(link),
+ url: link,
+ height: null,
+ width: null
+ });
}
}
- if (attachments.length === 0) return {files: []};
+ if (attachments.length === 0) return { files: [] };
if (client.database.premium.hasPremium(message.guild.id)) {
- const channel = (await client.database.guilds.read(message.guild.id)).logging.attachments.channel;
+ const channel = (await client.database.guilds.read(message.guild.id))
+ .logging.attachments.channel;
if (!channel) {
- singleNotify("noAttachmentLogChannel", message.guild.id, "No channel set for attachment logging", "Warning");
- return {files: attachments};
+ singleNotify(
+ "noAttachmentLogChannel",
+ message.guild.id,
+ "No channel set for attachment logging",
+ "Warning"
+ );
+ return { files: attachments };
}
const channelObj = await client.channels.fetch(channel);
if (!channelObj) {
- singleNotify("attachmentLogChannelDeleted", message.guild.id, "Attachment history channel was deleted", "Warning");
- return {files: attachments};
+ singleNotify(
+ "attachmentLogChannelDeleted",
+ message.guild.id,
+ "Attachment history channel was deleted",
+ "Warning"
+ );
+ return { files: attachments };
}
- const m = await channelObj.send({embeds: [new EmojiEmbed()
- .setTitle(`${addPlural(attachments.length, "Attachment")} Sent`)
- .setDescription(keyValueList({
- "messageId": `\`${message.id}\``,
- "sentBy": renderUser(message.author),
- "sentIn": renderChannel(message.channel),
- "sent": renderDelta(new Date(message.createdTimestamp))
- }) + `\n[[Jump to message]](${message.url})`)
- .setEmoji("ICONS.ATTACHMENT")
- .setStatus("Success")
- ], files: attachments.map(file => file.local)});
+ const m = await channelObj.send({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle(
+ `${addPlural(attachments.length, "Attachment")} Sent`
+ )
+ .setDescription(
+ keyValueList({
+ messageId: `\`${message.id}\``,
+ sentBy: renderUser(message.author),
+ sentIn: renderChannel(message.channel),
+ sent: renderDelta(
+ new Date(message.createdTimestamp)
+ )
+ }) + `\n[[Jump to message]](${message.url})`
+ )
+ .setEmoji("ICONS.ATTACHMENT")
+ .setStatus("Success")
+ ],
+ 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}
- );
- return {files: attachments, jump: m.url};
+ client.database.guilds.write(message.guild.id, {
+ [`logging.attachments.saved.${message.channel.id}${message.id}`]:
+ m.url
+ });
+ return { files: attachments, jump: m.url };
} else {
- return {files: attachments};
+ return { files: attachments };
}
}
export interface AttachmentLogSchema {
files: {
- url: string,
- local: string,
- height: number | null,
- width: number | null
- }[],
+ url: string;
+ local: string;
+ height: number | null;
+ width: number | null;
+ }[];
jump?: string;
-}
\ No newline at end of file
+}
diff --git a/src/premium/createTranscript.ts b/src/premium/createTranscript.ts
index d5d7bb8..3d7f4c6 100644
--- a/src/premium/createTranscript.ts
+++ b/src/premium/createTranscript.ts
@@ -2,86 +2,125 @@
import EmojiEmbed from "../utils/generateEmojiEmbed.js";
import getEmojiByName from "../utils/getEmojiByName.js";
import { PasteClient, Publicity, ExpireDate } from "pastebin-api";
-import config from "../config/main.json" assert {type: "json"};
+import config from "../config/main.json" assert { type: "json" };
import client from "../utils/client.js";
const pbClient = new PasteClient(config.pastebinApiKey);
export default async function (interaction) {
- const { log, NucleusColors, entry, renderUser, renderDelta } = client.logger;
+ const { log, NucleusColors, entry, renderUser, renderDelta } =
+ client.logger;
let messages = [];
let deleted = 100;
while (deleted === 100) {
let fetched;
- await (interaction.channel as TextChannel).messages.fetch({limit: 100}).then(async (ms) => {
- fetched = await (interaction.channel as TextChannel).bulkDelete(ms, true);
- });
+ await (interaction.channel as TextChannel).messages
+ .fetch({ limit: 100 })
+ .then(async (ms) => {
+ fetched = await (interaction.channel as TextChannel).bulkDelete(
+ ms,
+ true
+ );
+ });
deleted = fetched.size;
if (fetched) {
- messages = messages.concat(fetched.map(m => m));
+ messages = messages.concat(fetched.map((m) => m));
}
}
let out = "";
- messages.reverse().forEach(message => {
+ messages.reverse().forEach((message) => {
if (!message.author.bot) {
const sentDate = new Date(message.createdTimestamp);
- out += `${message.author.username}#${message.author.discriminator} (${message.author.id}) [${sentDate.toUTCString()}]\n`;
+ out += `${message.author.username}#${
+ message.author.discriminator
+ } (${message.author.id}) [${sentDate.toUTCString()}]\n`;
const lines = message.content.split("\n");
- lines.forEach(line => {out += `> ${line}\n`;});
+ lines.forEach((line) => {
+ out += `> ${line}\n`;
+ });
out += "\n\n";
}
});
- const member = interaction.channel.guild.members.cache.get(interaction.channel.topic.split(" ")[0]);
+ const member = interaction.channel.guild.members.cache.get(
+ interaction.channel.topic.split(" ")[0]
+ );
let m;
if (out !== "") {
const url = await pbClient.createPaste({
code: out,
expireDate: ExpireDate.Never,
- name: `Ticket Transcript for ${member.user.username}#${member.user.discriminator} (Created at ${new Date(interaction.channel.createdTimestamp).toDateString()})`,
+ name: `Ticket Transcript for ${member.user.username}#${
+ member.user.discriminator
+ } (Created at ${new Date(
+ interaction.channel.createdTimestamp
+ ).toDateString()})`,
publicity: Publicity.Unlisted
});
- const guildConfig = await client.database.guilds.read(interaction.guild.id);
- m = await interaction.reply({embeds: [new EmojiEmbed()
- .setTitle("Transcript")
- .setDescription("You can view the transcript using the link below. You can save the link for later" + (guildConfig.logging.logs.channel ?
- ` or find it in <#${guildConfig.logging.logs.channel}> once you press delete below. After this the channel will be deleted.`
- : "."))
- .setStatus("Success")
- .setEmoji("CONTROL.DOWNLOAD")
- ], components: [new MessageActionRow().addComponents([
- new MessageButton()
- .setLabel("View")
- .setStyle("LINK")
- .setURL(url),
- new MessageButton()
- .setLabel("Delete")
- .setStyle("DANGER")
- .setCustomId("close")
- .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
- ])], fetchReply: true});
+ const guildConfig = await client.database.guilds.read(
+ interaction.guild.id
+ );
+ m = await interaction.reply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Transcript")
+ .setDescription(
+ "You can view the transcript using the link below. You can save the link for later" +
+ (guildConfig.logging.logs.channel
+ ? ` or find it in <#${guildConfig.logging.logs.channel}> once you press delete below. After this the channel will be deleted.`
+ : ".")
+ )
+ .setStatus("Success")
+ .setEmoji("CONTROL.DOWNLOAD")
+ ],
+ components: [
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setLabel("View")
+ .setStyle("LINK")
+ .setURL(url),
+ new MessageButton()
+ .setLabel("Delete")
+ .setStyle("DANGER")
+ .setCustomId("close")
+ .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
+ ])
+ ],
+ fetchReply: true
+ });
} else {
- m = await interaction.reply({embeds: [new EmojiEmbed()
- .setTitle("Transcript")
- .setDescription("The transcript was empty, so no changes were made. To delete this ticket, press the delete button below.")
- .setStatus("Success")
- .setEmoji("CONTROL.DOWNLOAD")
- ], components: [new MessageActionRow().addComponents([
- new MessageButton()
- .setLabel("Delete")
- .setStyle("DANGER")
- .setCustomId("close")
- .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
- ])], fetchReply: true});
+ m = await interaction.reply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Transcript")
+ .setDescription(
+ "The transcript was empty, so no changes were made. To delete this ticket, press the delete button below."
+ )
+ .setStatus("Success")
+ .setEmoji("CONTROL.DOWNLOAD")
+ ],
+ components: [
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setLabel("Delete")
+ .setStyle("DANGER")
+ .setCustomId("close")
+ .setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
+ ])
+ ],
+ fetchReply: true
+ });
}
let i;
try {
i = await m.awaitMessageComponent({ time: 300000 });
i.deferUpdate();
- } catch { return; }
+ } catch {
+ return;
+ }
const data = {
- meta:{
+ meta: {
type: "ticketDeleted",
displayName: "Ticket Deleted",
calculateType: "ticketUpdate",
@@ -90,9 +129,24 @@
timestamp: new Date().getTime()
},
list: {
- ticketFor: entry(interaction.channel.topic.split(" ")[0], renderUser((await interaction.guild.members.fetch(interaction.channel.topic.split(" ")[0])).user)),
- deletedBy: entry(interaction.member.user.id, renderUser(interaction.member.user)),
- deleted: entry(new Date().getTime(), renderDelta(new Date().getTime()))
+ ticketFor: entry(
+ interaction.channel.topic.split(" ")[0],
+ renderUser(
+ (
+ await interaction.guild.members.fetch(
+ interaction.channel.topic.split(" ")[0]
+ )
+ ).user
+ )
+ ),
+ deletedBy: entry(
+ interaction.member.user.id,
+ renderUser(interaction.member.user)
+ ),
+ deleted: entry(
+ new Date().getTime(),
+ renderDelta(new Date().getTime())
+ )
},
hidden: {
guild: interaction.guild.id
@@ -101,4 +155,4 @@
log(data);
await interaction.channel.delete();
return;
-}
\ No newline at end of file
+}
diff --git a/src/reflex/guide.ts b/src/reflex/guide.ts
index 640ec13..0b09f69 100644
--- a/src/reflex/guide.ts
+++ b/src/reflex/guide.ts
@@ -10,128 +10,208 @@
title: string;
description = "";
pageId = 0;
- setEmbed(embed: Discord.MessageEmbed) { this.embed = embed; return this; }
- setTitle(title: string) { this.title = title; return this; }
- setDescription(description: string) { this.description = description; return this; }
- setPageId(pageId: number) { this.pageId = pageId; return this; }
+ setEmbed(embed: Discord.MessageEmbed) {
+ this.embed = embed;
+ return this;
+ }
+ setTitle(title: string) {
+ this.title = title;
+ return this;
+ }
+ setDescription(description: string) {
+ this.description = description;
+ return this;
+ }
+ setPageId(pageId: number) {
+ this.pageId = pageId;
+ return this;
+ }
}
export default async (guild, interaction?) => {
- let c = guild.publicUpdatesChannel ? guild.publicUpdatesChannel : guild.systemChannel;
- c = c ? c : guild.channels.cache.find(ch => ch.type === "GUILD_TEXT" && ch.permissionsFor(guild.roles.everyone).has("SEND_MESSAGES") && ch.permissionsFor(guild.me).has("EMBED_LINKS"));
+ let c = guild.publicUpdatesChannel
+ ? guild.publicUpdatesChannel
+ : guild.systemChannel;
+ c = c
+ ? c
+ : guild.channels.cache.find(
+ (ch) =>
+ ch.type === "GUILD_TEXT" &&
+ ch
+ .permissionsFor(guild.roles.everyone)
+ .has("SEND_MESSAGES") &&
+ ch.permissionsFor(guild.me).has("EMBED_LINKS")
+ );
const pages = [
new Embed()
- .setEmbed(new EmojiEmbed()
- .setTitle("Welcome to Nucleus")
- .setDescription(
- "Thanks for adding Nucleus to your server\n\n" +
- "On the next few pages you can find instructions on getting started, and commands you may want to set up\n\n" +
- "If you need support, have questions or want features, you can let us know in [Clicks](https://discord.gg/bPaNnxe)"
- )
- .setEmoji("NUCLEUS.LOGO")
- .setStatus("Danger")
- ).setTitle("Welcome").setDescription("About Nucleus").setPageId(0),
+ .setEmbed(
+ new EmojiEmbed()
+ .setTitle("Welcome to Nucleus")
+ .setDescription(
+ "Thanks for adding Nucleus to your server\n\n" +
+ "On the next few pages you can find instructions on getting started, and commands you may want to set up\n\n" +
+ "If you need support, have questions or want features, you can let us know in [Clicks](https://discord.gg/bPaNnxe)"
+ )
+ .setEmoji("NUCLEUS.LOGO")
+ .setStatus("Danger")
+ )
+ .setTitle("Welcome")
+ .setDescription("About Nucleus")
+ .setPageId(0),
new Embed()
- .setEmbed(new EmojiEmbed()
- .setTitle("Logging")
- .setDescription(
- "Nucleus can log server events and keep you informed with what content is being posted to your server.\n" +
- "We have 2 different types of logs, which each can be configured to send to a channel of your choice:\n" +
- "**General Logs:** These are events like kicks and channel changes etc.\n" +
- "**Warning Logs:** Warnings like NSFW avatars and spam etc. that may require action by a server staff member. " +
- "These go to to a separate staff notifications channel.\n\n" +
- "A general log channel can be set with `/settings log`\n" +
- "A warning log channel can be set with `/settings warnings channel`"
- )
- .setEmoji("ICONS.LOGGING")
- .setStatus("Danger")
- ).setTitle("Logging").setDescription("Logging, staff warning logs etc.").setPageId(1),
+ .setEmbed(
+ new EmojiEmbed()
+ .setTitle("Logging")
+ .setDescription(
+ "Nucleus can log server events and keep you informed with what content is being posted to your server.\n" +
+ "We have 2 different types of logs, which each can be configured to send to a channel of your choice:\n" +
+ "**General Logs:** These are events like kicks and channel changes etc.\n" +
+ "**Warning Logs:** Warnings like NSFW avatars and spam etc. that may require action by a server staff member. " +
+ "These go to to a separate staff notifications channel.\n\n" +
+ "A general log channel can be set with `/settings log`\n" +
+ "A warning log channel can be set with `/settings warnings channel`"
+ )
+ .setEmoji("ICONS.LOGGING")
+ .setStatus("Danger")
+ )
+ .setTitle("Logging")
+ .setDescription("Logging, staff warning logs etc.")
+ .setPageId(1),
new Embed()
- .setEmbed(new EmojiEmbed()
- .setTitle("Moderation")
- .setDescription(
- "Nucleus has a number of commands that can be used to moderate your server.\n" +
- "These commands are all found under `/mod`, and they include:\n" +
- `**${getEmojiByName("PUNISH.WARN.YELLOW")} Warn:** The user is warned (via DM) that they violated server rules.\n` +
- `**${getEmojiByName("PUNISH.CLEARHISTORY")} Clear:** Some messages from a user are deleted in a channel.\n` +
- `**${getEmojiByName("PUNISH.MUTE.YELLOW")} Mute:** The user is unable to send messages or join voice chats.\n` +
- `**${getEmojiByName("PUNISH.MUTE.GREEN")} Unmute:** The user is able to send messages in the server.\n` +
- `**${getEmojiByName("PUNISH.KICK.RED")} Kick:** The user is removed from the server.\n` +
- `**${getEmojiByName("PUNISH.SOFTBAN")} Softban:** Kicks the user, deleting their messages from every channel.\n` +
- `**${getEmojiByName("PUNISH.BAN.RED")} Ban:** The user is removed from the server, and they are unable to rejoin.\n` +
- `**${getEmojiByName("PUNISH.BAN.GREEN")} Unban:** The user is able to rejoin the server.`
- )
- .setEmoji("PUNISH.BAN.RED")
- .setStatus("Danger")
- ).setTitle("Moderation").setDescription("Basic moderation commands").setPageId(2),
+ .setEmbed(
+ new EmojiEmbed()
+ .setTitle("Moderation")
+ .setDescription(
+ "Nucleus has a number of commands that can be used to moderate your server.\n" +
+ "These commands are all found under `/mod`, and they include:\n" +
+ `**${getEmojiByName(
+ "PUNISH.WARN.YELLOW"
+ )} Warn:** The user is warned (via DM) that they violated server rules.\n` +
+ `**${getEmojiByName(
+ "PUNISH.CLEARHISTORY"
+ )} Clear:** Some messages from a user are deleted in a channel.\n` +
+ `**${getEmojiByName(
+ "PUNISH.MUTE.YELLOW"
+ )} Mute:** The user is unable to send messages or join voice chats.\n` +
+ `**${getEmojiByName(
+ "PUNISH.MUTE.GREEN"
+ )} Unmute:** The user is able to send messages in the server.\n` +
+ `**${getEmojiByName(
+ "PUNISH.KICK.RED"
+ )} Kick:** The user is removed from the server.\n` +
+ `**${getEmojiByName(
+ "PUNISH.SOFTBAN"
+ )} Softban:** Kicks the user, deleting their messages from every channel.\n` +
+ `**${getEmojiByName(
+ "PUNISH.BAN.RED"
+ )} Ban:** The user is removed from the server, and they are unable to rejoin.\n` +
+ `**${getEmojiByName(
+ "PUNISH.BAN.GREEN"
+ )} Unban:** The user is able to rejoin the server.`
+ )
+ .setEmoji("PUNISH.BAN.RED")
+ .setStatus("Danger")
+ )
+ .setTitle("Moderation")
+ .setDescription("Basic moderation commands")
+ .setPageId(2),
new Embed()
- .setEmbed(new EmojiEmbed()
- .setTitle("Verify")
- .setDescription(
- "Nucleus has a verification system that allows users to prove they aren't bots.\n" +
- "This is done by running `/verify` which sends a message only the user can see, giving them a link to a CAPTCHA to verify.\n" +
- "After the user complete's the CAPTCHA, they are given a role and can use the permissions accordingly.\n" +
- "You can set the role given with `/settings verify`"
- )
- .setEmoji("CONTROL.REDTICK")
- .setStatus("Danger")
- ).setTitle("Verify").setDescription("Captcha verification system").setPageId(3),
+ .setEmbed(
+ new EmojiEmbed()
+ .setTitle("Verify")
+ .setDescription(
+ "Nucleus has a verification system that allows users to prove they aren't bots.\n" +
+ "This is done by running `/verify` which sends a message only the user can see, giving them a link to a CAPTCHA to verify.\n" +
+ "After the user complete's the CAPTCHA, they are given a role and can use the permissions accordingly.\n" +
+ "You can set the role given with `/settings verify`"
+ )
+ .setEmoji("CONTROL.REDTICK")
+ .setStatus("Danger")
+ )
+ .setTitle("Verify")
+ .setDescription("Captcha verification system")
+ .setPageId(3),
new Embed()
- .setEmbed(new EmojiEmbed()
- .setTitle("Content Scanning")
- .setDescription(
- "Nucleus has a content scanning system that automatically scans links and images sent by users.\n" +
- "Nucleus can detect, delete, and punish users for sending NSFW content, or links to scam or adult sites.\n" +
- "You can set the threshold for this in `/settings automation`" // TODO
- )
- .setEmoji("MOD.IMAGES.TOOSMALL")
- .setStatus("Danger")
- ).setTitle("Content Scanning").setDescription("Content (NSFW, malware, scams) scanning").setPageId(4),
+ .setEmbed(
+ new EmojiEmbed()
+ .setTitle("Content Scanning")
+ .setDescription(
+ "Nucleus has a content scanning system that automatically scans links and images sent by users.\n" +
+ "Nucleus can detect, delete, and punish users for sending NSFW content, or links to scam or adult sites.\n" +
+ "You can set the threshold for this in `/settings automation`" // TODO
+ )
+ .setEmoji("MOD.IMAGES.TOOSMALL")
+ .setStatus("Danger")
+ )
+ .setTitle("Content Scanning")
+ .setDescription("Content (NSFW, malware, scams) scanning")
+ .setPageId(4),
new Embed()
- .setEmbed(new EmojiEmbed()
- .setTitle("Tickets")
- .setDescription(
- "Nucleus has a ticket system that allows users to create tickets and have a support team respond to them.\n" +
- "Tickets can be created with `/ticket create` and a channel is created, pinging the user and support role.\n" +
- "When the ticket is resolved, anyone can run `/ticket close` (or click the button) to close it.\n" +
- "Running `/ticket close` again will delete the ticket."
- )
- .setEmoji("GUILD.TICKET.CLOSE")
- .setStatus("Danger")
- ).setTitle("Tickets").setDescription("Ticket system").setPageId(5),
+ .setEmbed(
+ new EmojiEmbed()
+ .setTitle("Tickets")
+ .setDescription(
+ "Nucleus has a ticket system that allows users to create tickets and have a support team respond to them.\n" +
+ "Tickets can be created with `/ticket create` and a channel is created, pinging the user and support role.\n" +
+ "When the ticket is resolved, anyone can run `/ticket close` (or click the button) to close it.\n" +
+ "Running `/ticket close` again will delete the ticket."
+ )
+ .setEmoji("GUILD.TICKET.CLOSE")
+ .setStatus("Danger")
+ )
+ .setTitle("Tickets")
+ .setDescription("Ticket system")
+ .setPageId(5),
new Embed()
- .setEmbed(new EmojiEmbed()
- .setTitle("Tags")
- .setDescription(
- "Add a tag system to your server with the `/tag` and `/tags` commands.\n" +
- "To create a tag, type `/tags create <tag name> <tag content>`.\n" +
- "Tag names and content can be edited with `/tags edit`.\n" +
- "To delete a tag, type `/tags delete <tag name>`.\n" +
- "To view all tags, type `/tags list`.\n"
- )
- .setEmoji("PUNISH.NICKNAME.RED")
- .setStatus("Danger")
- ).setTitle("Tags").setDescription("Tag system").setPageId(6),
+ .setEmbed(
+ new EmojiEmbed()
+ .setTitle("Tags")
+ .setDescription(
+ "Add a tag system to your server with the `/tag` and `/tags` commands.\n" +
+ "To create a tag, type `/tags create <tag name> <tag content>`.\n" +
+ "Tag names and content can be edited with `/tags edit`.\n" +
+ "To delete a tag, type `/tags delete <tag name>`.\n" +
+ "To view all tags, type `/tags list`.\n"
+ )
+ .setEmoji("PUNISH.NICKNAME.RED")
+ .setStatus("Danger")
+ )
+ .setTitle("Tags")
+ .setDescription("Tag system")
+ .setPageId(6),
new Embed()
- .setEmbed(new EmojiEmbed()
- .setTitle("Premium")
- .setDescription(
- "In the near future, we will be releasing extra premium only features.\n" +
- "These features will include:\n\n" +
- "**Attachment logs**\n> When a message with attachments is edited or deleted, the logs will also include the images sent.\n" +
- "\nPremium is not yet available. Check `/nucleus premium` for updates on features and pricing"
- )
- .setEmoji("NUCLEUS.COMMANDS.LOCK")
- .setStatus("Danger")
- ).setTitle("Premium").setDescription("Premium features").setPageId(7)
+ .setEmbed(
+ new EmojiEmbed()
+ .setTitle("Premium")
+ .setDescription(
+ "In the near future, we will be releasing extra premium only features.\n" +
+ "These features will include:\n\n" +
+ "**Attachment logs**\n> When a message with attachments is edited or deleted, the logs will also include the images sent.\n" +
+ "\nPremium is not yet available. Check `/nucleus premium` for updates on features and pricing"
+ )
+ .setEmoji("NUCLEUS.COMMANDS.LOCK")
+ .setStatus("Danger")
+ )
+ .setTitle("Premium")
+ .setDescription("Premium features")
+ .setPageId(7)
];
let m;
- if (interaction) { m = await interaction.reply({embeds: LoadingEmbed, fetchReply: true, ephemeral: true}); }
- else { m = await c.send({embeds: LoadingEmbed }); }
+ if (interaction) {
+ m = await interaction.reply({
+ embeds: LoadingEmbed,
+ fetchReply: true,
+ ephemeral: true
+ });
+ } else {
+ m = await c.send({ embeds: LoadingEmbed });
+ }
let page = 0;
const f = async (component) => {
- return (component.member as Discord.GuildMember).permissions.has("MANAGE_GUILD");
+ return (component.member as Discord.GuildMember).permissions.has(
+ "MANAGE_GUILD"
+ );
};
let selectPaneOpen = false;
@@ -141,36 +221,62 @@
if (selectPaneOpen) {
const options = [];
- pages.forEach(embed => {
- options.push(new SelectMenuOption({
- label: embed.title,
- value: embed.pageId.toString(),
- description: embed.description || ""
- }));
+ pages.forEach((embed) => {
+ options.push(
+ new SelectMenuOption({
+ label: embed.title,
+ value: embed.pageId.toString(),
+ description: embed.description || ""
+ })
+ );
});
- selectPane = [new MessageActionRow().addComponents([
- new Discord.MessageSelectMenu()
- .addOptions(options)
- .setCustomId("page")
- .setMaxValues(1)
- .setPlaceholder("Choose a page...")
- ])];
+ selectPane = [
+ new MessageActionRow().addComponents([
+ new Discord.MessageSelectMenu()
+ .addOptions(options)
+ .setCustomId("page")
+ .setMaxValues(1)
+ .setPlaceholder("Choose a page...")
+ ])
+ ];
}
- const components = selectPane.concat([new MessageActionRow().addComponents([
- new MessageButton().setCustomId("left").setEmoji(getEmojiByName("CONTROL.LEFT", "id")).setStyle("SECONDARY").setDisabled(page === 0),
- new MessageButton().setCustomId("select").setEmoji(getEmojiByName("CONTROL.MENU", "id")).setStyle(selectPaneOpen ? "PRIMARY" : "SECONDARY").setDisabled(false),
- new MessageButton().setCustomId("right").setEmoji(getEmojiByName("CONTROL.RIGHT", "id")).setStyle("SECONDARY").setDisabled(page === pages.length - 1)
- ])]);
+ const components = selectPane.concat([
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setCustomId("left")
+ .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
+ .setStyle("SECONDARY")
+ .setDisabled(page === 0),
+ new MessageButton()
+ .setCustomId("select")
+ .setEmoji(getEmojiByName("CONTROL.MENU", "id"))
+ .setStyle(selectPaneOpen ? "PRIMARY" : "SECONDARY")
+ .setDisabled(false),
+ new MessageButton()
+ .setCustomId("right")
+ .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
+ .setStyle("SECONDARY")
+ .setDisabled(page === pages.length - 1)
+ ])
+ ]);
if (interaction) {
const em = new Discord.MessageEmbed(pages[page].embed);
- em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page));
+ em.setDescription(
+ em.description +
+ "\n\n" +
+ createPageIndicator(pages.length, page)
+ );
await interaction.editReply({
embeds: [em],
components: components
});
} else {
const em = new Discord.MessageEmbed(pages[page].embed);
- em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page));
+ em.setDescription(
+ em.description +
+ "\n\n" +
+ createPageIndicator(pages.length, page)
+ );
await m.edit({
embeds: [em],
components: components,
@@ -179,8 +285,17 @@
}
let i;
try {
- i = await m.awaitMessageComponent({filter: interaction ? () => { return true; } : f, time: 300000});
- } catch(e) { break; }
+ i = await m.awaitMessageComponent({
+ filter: interaction
+ ? () => {
+ return true;
+ }
+ : f,
+ time: 300000
+ });
+ } catch (e) {
+ break;
+ }
i.deferUpdate();
if (i.component.customId === "left") {
if (page > 0) page--;
@@ -196,13 +311,36 @@
} else {
if (interaction) {
const em = new Discord.MessageEmbed(pages[page].embed);
- em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page));
- em.setFooter({text: "Message closed"});
- interaction.editReply({embeds: [em], components: [new MessageActionRow().addComponents([
- new MessageButton().setCustomId("left").setEmoji(getEmojiByName("CONTROL.LEFT", "id")).setStyle("SECONDARY").setDisabled(true),
- new MessageButton().setCustomId("select").setEmoji(getEmojiByName("CONTROL.MENU", "id")).setStyle(selectPaneOpen ? "PRIMARY" : "SECONDARY").setDisabled(true),
- new MessageButton().setCustomId("right").setEmoji(getEmojiByName("CONTROL.RIGHT", "id")).setStyle("SECONDARY").setDisabled(true)
- ])]});
+ em.setDescription(
+ em.description +
+ "\n\n" +
+ createPageIndicator(pages.length, page)
+ );
+ em.setFooter({ text: "Message closed" });
+ interaction.editReply({
+ embeds: [em],
+ components: [
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setCustomId("left")
+ .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
+ .setStyle("SECONDARY")
+ .setDisabled(true),
+ new MessageButton()
+ .setCustomId("select")
+ .setEmoji(getEmojiByName("CONTROL.MENU", "id"))
+ .setStyle(
+ selectPaneOpen ? "PRIMARY" : "SECONDARY"
+ )
+ .setDisabled(true),
+ new MessageButton()
+ .setCustomId("right")
+ .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
+ .setStyle("SECONDARY")
+ .setDisabled(true)
+ ])
+ ]
+ });
} else {
m.delete();
}
@@ -211,25 +349,57 @@
}
if (interaction) {
const em = new Discord.MessageEmbed(pages[page].embed);
- em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page)).setFooter({text: "Message timed out"});
+ em.setDescription(
+ em.description + "\n\n" + createPageIndicator(pages.length, page)
+ ).setFooter({ text: "Message timed out" });
await interaction.editReply({
embeds: [em],
- components: [new MessageActionRow().addComponents([
- new MessageButton().setCustomId("left").setEmoji(getEmojiByName("CONTROL.LEFT", "id")).setStyle("SECONDARY").setDisabled(true),
- new MessageButton().setCustomId("select").setEmoji(getEmojiByName("CONTROL.MENU", "id")).setStyle("SECONDARY").setDisabled(true),
- new MessageButton().setCustomId("right").setEmoji(getEmojiByName("CONTROL.RIGHT", "id")).setStyle("SECONDARY").setDisabled(true)
- ])]
+ components: [
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setCustomId("left")
+ .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
+ .setStyle("SECONDARY")
+ .setDisabled(true),
+ new MessageButton()
+ .setCustomId("select")
+ .setEmoji(getEmojiByName("CONTROL.MENU", "id"))
+ .setStyle("SECONDARY")
+ .setDisabled(true),
+ new MessageButton()
+ .setCustomId("right")
+ .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
+ .setStyle("SECONDARY")
+ .setDisabled(true)
+ ])
+ ]
});
} else {
const em = new Discord.MessageEmbed(pages[page].embed);
- em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page)).setFooter({text: "Message timed out"});
+ em.setDescription(
+ em.description + "\n\n" + createPageIndicator(pages.length, page)
+ ).setFooter({ text: "Message timed out" });
await m.edit({
embeds: [em],
- components: [new MessageActionRow().addComponents([
- new MessageButton().setCustomId("left").setEmoji(getEmojiByName("CONTROL.LEFT", "id")).setStyle("SECONDARY").setDisabled(true),
- new MessageButton().setCustomId("select").setEmoji(getEmojiByName("CONTROL.MENU", "id")).setStyle("SECONDARY").setDisabled(true),
- new MessageButton().setCustomId("right").setEmoji(getEmojiByName("CONTROL.RIGHT", "id")).setStyle("SECONDARY").setDisabled(true)
- ])]
+ components: [
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setCustomId("left")
+ .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
+ .setStyle("SECONDARY")
+ .setDisabled(true),
+ new MessageButton()
+ .setCustomId("select")
+ .setEmoji(getEmojiByName("CONTROL.MENU", "id"))
+ .setStyle("SECONDARY")
+ .setDisabled(true),
+ new MessageButton()
+ .setCustomId("right")
+ .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
+ .setStyle("SECONDARY")
+ .setDisabled(true)
+ ])
+ ]
});
}
};
diff --git a/src/reflex/scanners.ts b/src/reflex/scanners.ts
index 435ce4c..162b85a 100644
--- a/src/reflex/scanners.ts
+++ b/src/reflex/scanners.ts
@@ -1,5 +1,5 @@
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
-// @ts-ignore
+// @ts-expect-error
import * as us from "unscan";
import fetch from "node-fetch";
import { writeFileSync } from "fs";
@@ -7,8 +7,12 @@
import Tesseract from "node-tesseract-ocr";
import type Discord from "discord.js";
-interface NSFWSchema { nsfw: boolean }
-interface MalwareSchema { safe: boolean }
+interface NSFWSchema {
+ nsfw: boolean;
+}
+interface MalwareSchema {
+ safe: boolean;
+}
export async function testNSFW(link: string): Promise<NSFWSchema> {
const p = await saveAttachment(link);
@@ -24,74 +28,102 @@
export async function saveAttachment(link: string): Promise<string> {
const image = (await (await fetch(link)).buffer()).toString("base64");
- const fileName = generateFileName((link.split("/").pop() as string).split(".").pop() as string);
+ const fileName = generateFileName(link.split("/").pop()!.split(".").pop()!);
writeFileSync(fileName, image, "base64");
return fileName;
}
-export async function testLink(link: string): Promise<{safe: boolean, tags: string[]}> {
- return await us.link.scan(link);
+const defaultLinkTestResult: { safe: boolean; tags: string[] } = {
+ safe: true,
+ tags: []
+};
+export async function testLink(
+ link: string
+): Promise<{ safe: boolean; tags: string[] }> {
+ const scanned: { safe?: boolean; tags?: string[] } | undefined =
+ await us.link.scan(link);
+ if (scanned === undefined) return defaultLinkTestResult;
+ return {
+ safe: scanned.safe ?? defaultLinkTestResult.safe,
+ tags: scanned.tags ?? defaultLinkTestResult.tags
+ };
}
-
const linkTypes = {
- "PHISHING": "Links designed to trick users into clicking on them.",
- "DATING": "Dating sites.",
- "TRACKERS": "Websites that store or track personal information.",
- "ADVERTISEMENTS": "Websites only for ads.",
- "FACEBOOK": "Facebook pages. (Facebook has a number of dangerous trackers. Read more on /privacy)",
- "AMP": "AMP pages. (AMP is a technology that allows websites to be served by Google. Read more on /privacy)",
+ PHISHING: "Links designed to trick users into clicking on them.",
+ DATING: "Dating sites.",
+ TRACKERS: "Websites that store or track personal information.",
+ ADVERTISEMENTS: "Websites only for ads.",
+ FACEBOOK:
+ "Facebook pages. (Facebook has a number of dangerous trackers. Read more on /privacy)",
+ AMP: "AMP pages. (AMP is a technology that allows websites to be served by Google. Read more on /privacy)",
"FACEBOOK TRACKERS": "Websites that include trackers from Facebook.",
- "IP GRABBERS": "Websites that store your IP address, which shows your approximate location.",
- "PORN": "Websites that include pornography.",
- "GAMBLING": "Gambling sites, often scams.",
- "MALWARE": "Websites which download files designed to break or slow down your device.",
- "PIRACY": "Sites which include illegally downloaded material.",
- "RANSOMWARE": "Websites which download a program that can steal your data and make you pay to get it back.",
- "REDIRECTS": "Sites like bit.ly which could redirect to a malicious site.",
- "SCAMS": "Sites which are designed to trick you into doing something.",
- "TORRENT": "Websites that download torrent files.",
- "HATE": "Websites that spread hate towards groups or individuals.",
- "JUNK": "Websites that are designed to make you waste time."
+ "IP GRABBERS":
+ "Websites that store your IP address, which shows your approximate location.",
+ PORN: "Websites that include pornography.",
+ GAMBLING: "Gambling sites, often scams.",
+ MALWARE:
+ "Websites which download files designed to break or slow down your device.",
+ PIRACY: "Sites which include illegally downloaded material.",
+ RANSOMWARE:
+ "Websites which download a program that can steal your data and make you pay to get it back.",
+ REDIRECTS: "Sites like bit.ly which could redirect to a malicious site.",
+ SCAMS: "Sites which are designed to trick you into doing something.",
+ TORRENT: "Websites that download torrent files.",
+ HATE: "Websites that spread hate towards groups or individuals.",
+ JUNK: "Websites that are designed to make you waste time."
};
export { linkTypes };
-
export async function LinkCheck(message: Discord.Message): Promise<string[]> {
- const links = message.content.match(/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/gi) ?? [];
- const detections: {tags: string[], safe: boolean}[] = [];
- const promises: Promise<void>[] = links.map(async element => {
+ const links =
+ message.content.match(
+ /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/gi
+ ) ?? [];
+ const detections: { tags: string[]; safe: boolean }[] = [];
+ const promises: Promise<void>[] = links.map(async (element) => {
let returned;
try {
- if (element.match(/https?:\/\/[a-zA-Z]+\.?discord(app)?\.(com|net)\/?/)) return; // Also matches discord.net, not enough of a bug
+ if (
+ element.match(
+ /https?:\/\/[a-zA-Z]+\.?discord(app)?\.(com|net)\/?/
+ )
+ )
+ return; // Also matches discord.net, not enough of a bug
returned = await testLink(element);
} catch {
- detections.push({tags: [], safe: true});
+ detections.push({ tags: [], safe: true });
return;
}
- if (returned) { detections.push({tags: returned.tags || [], safe: returned.safe}); }
- else { detections.push({tags: [], safe: true}); }
+ detections.push({ tags: returned.tags, safe: returned.safe });
});
await Promise.all(promises);
- const detectionsTypes = detections.map(element => {
- const type = Object.keys(linkTypes).find(type => element.tags.includes(type));
- if (type) return type;
- // if (!element.safe) return "UNSAFE"
- return undefined;
- }).filter(element => element !== undefined);
+ const detectionsTypes = detections
+ .map((element) => {
+ const type = Object.keys(linkTypes).find((type) =>
+ element.tags.includes(type)
+ );
+ if (type) return type;
+ // if (!element.safe) return "UNSAFE"
+ return undefined;
+ })
+ .filter((element) => element !== undefined);
return detectionsTypes as string[];
}
export async function NSFWCheck(element: string): Promise<boolean> {
try {
- const test = (await testNSFW(element));
+ const test = await testNSFW(element);
return test.nsfw;
} catch {
return false;
}
}
-export async function SizeCheck(element: {height: number | null, width: number | null}): Promise<boolean> {
+export async function SizeCheck(element: {
+ height: number | null;
+ width: number | null;
+}): Promise<boolean> {
if (element.height === null || element.width === null) return true;
if (element.height < 20 || element.width < 20) return false;
return true;
@@ -105,16 +137,20 @@
}
}
-export function TestString(string: string, soft: string[], strict: string[]): object | null {
- for(const word of strict || []) {
+export function TestString(
+ string: string,
+ soft: string[],
+ strict: string[]
+): object | null {
+ for (const word of strict) {
if (string.toLowerCase().includes(word)) {
- return {word: word, type: "strict"};
+ return { word: word, type: "strict" };
}
}
- for(const word of soft) {
- for(const word2 of string.match(/[a-z]+/gi) || []) {
+ for (const word of soft) {
+ for (const word2 of string.match(/[a-z]+/gi) ?? []) {
if (word2 === word) {
- return {word: word, type: "strict"};
+ return { word: word, type: "strict" };
}
}
}
@@ -122,6 +158,10 @@
}
export async function TestImage(url: string): Promise<string | null> {
- const text = await Tesseract.recognize(url, {lang: "eng", oem: 1, psm: 3});
+ const text = await Tesseract.recognize(url, {
+ lang: "eng",
+ oem: 1,
+ psm: 3
+ });
return text;
}
diff --git a/src/reflex/statsChannelUpdate.ts b/src/reflex/statsChannelUpdate.ts
index 7301a60..2dee385 100644
--- a/src/reflex/statsChannelUpdate.ts
+++ b/src/reflex/statsChannelUpdate.ts
@@ -2,7 +2,10 @@
import singleNotify from "../utils/singleNotify.js";
import client from "../utils/client.js";
-interface PropSchema { enabled: boolean, name: string }
+interface PropSchema {
+ enabled: boolean;
+ name: string;
+}
export async function callback(_, member) {
const guild = await client.guilds.fetch(member.guild.id);
@@ -11,21 +14,33 @@
if ((props as PropSchema).enabled) {
let string = (props as PropSchema).name;
if (!string) return;
- string = await convertCurlyBracketString(string, member.id, member.displayName, guild.name, guild.members);
+ string = await convertCurlyBracketString(
+ string,
+ member.id,
+ member.displayName,
+ guild.name,
+ guild.members
+ );
let fetchedChannel;
try {
fetchedChannel = await guild.channels.fetch(channel);
- } catch (e) { fetchedChannel = null; }
+ } catch (e) {
+ fetchedChannel = null;
+ }
if (!fetchedChannel) {
const deleted = config.getKey("stats")[channel];
console.log(`stats.${channel}`);
console.log(guild.id);
- await client.database.guilds.write(guild.id, null, `stats.${channel}`);
+ await client.database.guilds.write(
+ guild.id,
+ null,
+ `stats.${channel}`
+ );
return singleNotify(
"statsChannelDeleted",
guild.id,
"One or more of your stats channels have been deleted. Please use `/settings stats` if you wish to add the channel again.\n" +
- `The channels name was: ${deleted.name}`,
+ `The channels name was: ${deleted.name}`,
"Critical"
);
}
diff --git a/src/reflex/verify.ts b/src/reflex/verify.ts
index d9fab66..1737387 100644
--- a/src/reflex/verify.ts
+++ b/src/reflex/verify.ts
@@ -1,113 +1,193 @@
import { LoadingEmbed } from "./../utils/defaultEmbeds.js";
-import Discord, { GuildMember } from "discord.js";
+import Discord, { CommandInteraction, GuildMember } from "discord.js";
import EmojiEmbed from "../utils/generateEmojiEmbed.js";
import fetch from "node-fetch";
import { TestString, NSFWCheck } from "./scanners.js";
import createPageIndicator from "../utils/createPageIndicator.js";
import client from "../utils/client.js";
-function step(i) {
+function step(i: number) {
return "\n\n" + createPageIndicator(5, i);
}
-export default async function(interaction) {
+export default async function (interaction: CommandInteraction) {
const verify = client.verify;
- await interaction.reply({embeds: LoadingEmbed, ephemeral: true, fetchReply: true});
+ await interaction.reply({
+ embeds: LoadingEmbed,
+ ephemeral: true,
+ fetchReply: true
+ });
const config = await client.database.guilds.read(interaction.guild.id);
- if ((!config.verify.enabled ) || (!config.verify.role)) return interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Verify")
- .setDescription("Verify is not enabled on this server")
- .setFooter({text: interaction.member.permissions.has("MANAGE_GUILD") ? "You can enable it by running /settings verify" : ""})
- .setStatus("Danger")
- .setEmoji("CONTROL.BLOCKCROSS")
- ], ephemeral: true, fetchReply: true});
- if ((interaction.member as GuildMember).roles.cache.has(config.verify.role)) {
- return await interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Verify")
- .setDescription(`You already have the <@&${config.verify.role}> role` + step(0))
- .setStatus("Danger")
- .setEmoji("CONTROL.BLOCKCROSS")
- ]});
+ if (!config.verify.enabled || !config.verify.role)
+ return interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Verify")
+ .setDescription("Verify is not enabled on this server")
+ .setFooter({
+ text: interaction.member.permissions.has("MANAGE_GUILD")
+ ? "You can enable it by running /settings verify"
+ : ""
+ })
+ .setStatus("Danger")
+ .setEmoji("CONTROL.BLOCKCROSS")
+ ],
+ ephemeral: true,
+ fetchReply: true
+ });
+ if (
+ (interaction.member as GuildMember).roles.cache.has(config.verify.role)
+ ) {
+ return await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Verify")
+ .setDescription(
+ `You already have the <@&${config.verify.role}> role` +
+ step(0)
+ )
+ .setStatus("Danger")
+ .setEmoji("CONTROL.BLOCKCROSS")
+ ]
+ });
}
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Verify")
- .setDescription("Checking our servers are up" + step(0))
- .setStatus("Warning")
- .setEmoji("NUCLEUS.LOADING")
- ]});
- try {
- const status = await fetch(client.config.baseUrl).then(res => res.status);
- if (status !== 200) {
- return await interaction.editReply({embeds: [new EmojiEmbed()
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
.setTitle("Verify")
- .setDescription("Our servers appear to be down, please try again later" + step(0))
- .setStatus("Danger")
- .setEmoji("CONTROL.BLOCKCROSS")
- ]});
+ .setDescription("Checking our servers are up" + step(0))
+ .setStatus("Warning")
+ .setEmoji("NUCLEUS.LOADING")
+ ]
+ });
+ try {
+ const status = await fetch(client.config.baseUrl).then(
+ (res) => res.status
+ );
+ if (status !== 200) {
+ return await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Verify")
+ .setDescription(
+ "Our servers appear to be down, please try again later" +
+ step(0)
+ )
+ .setStatus("Danger")
+ .setEmoji("CONTROL.BLOCKCROSS")
+ ]
+ });
}
} catch {
- return await interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Verify")
- .setDescription("Our servers appear to be down, please try again later" + step(0))
- .setStatus("Danger")
- .setEmoji("CONTROL.BLOCKCROSS")
- ], components: [new Discord.MessageActionRow().addComponents([
- new Discord.MessageButton()
- .setLabel("Check webpage")
- .setStyle("LINK")
- .setURL(client.config.baseUrl),
- new Discord.MessageButton()
- .setLabel("Support")
- .setStyle("LINK")
- .setURL("https://discord.gg/bPaNnxe")
- ])]});
+ return await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Verify")
+ .setDescription(
+ "Our servers appear to be down, please try again later" +
+ step(0)
+ )
+ .setStatus("Danger")
+ .setEmoji("CONTROL.BLOCKCROSS")
+ ],
+ components: [
+ new Discord.MessageActionRow().addComponents([
+ new Discord.MessageButton()
+ .setLabel("Check webpage")
+ .setStyle("LINK")
+ .setURL(client.config.baseUrl),
+ new Discord.MessageButton()
+ .setLabel("Support")
+ .setStyle("LINK")
+ .setURL("https://discord.gg/bPaNnxe")
+ ])
+ ]
+ });
}
if (config.filters.images.NSFW) {
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Verify")
- .setDescription("Checking your avatar is safe for work" + step(1))
- .setStatus("Warning")
- .setEmoji("NUCLEUS.LOADING")
- ]});
- if (await NSFWCheck((interaction.member as GuildMember).user.avatarURL({format: "png"}))) {
- return await interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Verify")
- .setDescription("Your avatar was detected as NSFW, which we do not allow in this server.\nPlease contact one of our staff members if you believe this is a mistake" + step(1))
- .setStatus("Danger")
- .setEmoji("CONTROL.BLOCKCROSS")
- ]});
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Verify")
+ .setDescription(
+ "Checking your avatar is safe for work" + step(1)
+ )
+ .setStatus("Warning")
+ .setEmoji("NUCLEUS.LOADING")
+ ]
+ });
+ if (
+ await NSFWCheck(
+ (interaction.member as GuildMember).user.avatarURL({
+ format: "png"
+ })
+ )
+ ) {
+ return await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Verify")
+ .setDescription(
+ "Your avatar was detected as NSFW, which we do not allow in this server.\nPlease contact one of our staff members if you believe this is a mistake" +
+ step(1)
+ )
+ .setStatus("Danger")
+ .setEmoji("CONTROL.BLOCKCROSS")
+ ]
+ });
}
}
if (config.filters.wordFilter) {
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Verify")
- .setDescription("Checking your name is allowed" + step(2))
- .setStatus("Warning")
- .setEmoji("NUCLEUS.LOADING")
- ]});
- if (TestString((interaction.member as Discord.GuildMember).displayName, config.filters.wordFilter.words.loose, config.filters.wordFilter.words.strict) !== null) {
- return await interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Verify")
- .setDescription("Your name contained a word we do not allow in this server.\nPlease contact one of our staff members if you believe this is a mistake" + step(2))
- .setStatus("Danger")
- .setEmoji("CONTROL.BLOCKCROSS")
- ]});
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Verify")
+ .setDescription("Checking your name is allowed" + step(2))
+ .setStatus("Warning")
+ .setEmoji("NUCLEUS.LOADING")
+ ]
+ });
+ if (
+ TestString(
+ (interaction.member as Discord.GuildMember).displayName,
+ config.filters.wordFilter.words.loose,
+ config.filters.wordFilter.words.strict
+ ) !== null
+ ) {
+ return await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Verify")
+ .setDescription(
+ "Your name contained a word we do not allow in this server.\nPlease contact one of our staff members if you believe this is a mistake" +
+ step(2)
+ )
+ .setStatus("Danger")
+ .setEmoji("CONTROL.BLOCKCROSS")
+ ]
+ });
}
}
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Verify")
- .setDescription("One moment..." + step(3))
- .setStatus("Warning")
- .setEmoji("NUCLEUS.LOADING")
- ]});
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Verify")
+ .setDescription("One moment..." + step(3))
+ .setStatus("Warning")
+ .setEmoji("NUCLEUS.LOADING")
+ ]
+ });
let code = "";
let length = 5;
let itt = 0;
- const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+ const chars =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
while (true) {
itt += 1;
code = "";
- for (let i = 0; i < length; i++) { code += chars.charAt(Math.floor(Math.random() * chars.length)); }
+ for (let i = 0; i < length; i++) {
+ code += chars.charAt(Math.floor(Math.random() * chars.length));
+ }
if (code in verify) continue;
if (itt > 1000) {
itt = 0;
@@ -123,17 +203,29 @@
rName: (await interaction.guild.roles.fetch(config.verify.role)).name,
uName: interaction.member.user.username,
gName: interaction.guild.name,
- gIcon: interaction.guild.iconURL({format: "png"}),
+ gIcon: interaction.guild.iconURL({ format: "png" }),
interaction: interaction
};
- await interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Verify")
- .setDescription("Looking good!\nClick the button below to get verified" + step(4))
- .setStatus("Success")
- .setEmoji("MEMBER.JOIN")
- ], components: [new Discord.MessageActionRow().addComponents([new Discord.MessageButton()
- .setLabel("Verify")
- .setStyle("LINK")
- .setURL(`${client.config.baseUrl}nucleus/verify?code=${code}`)
- ])]});
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Verify")
+ .setDescription(
+ "Looking good!\nClick the button below to get verified" +
+ step(4)
+ )
+ .setStatus("Success")
+ .setEmoji("MEMBER.JOIN")
+ ],
+ components: [
+ new Discord.MessageActionRow().addComponents([
+ new Discord.MessageButton()
+ .setLabel("Verify")
+ .setStyle("LINK")
+ .setURL(
+ `${client.config.baseUrl}nucleus/verify?code=${code}`
+ )
+ ])
+ ]
+ });
}
diff --git a/src/reflex/welcome.ts b/src/reflex/welcome.ts
index b4bc374..4971cc9 100644
--- a/src/reflex/welcome.ts
+++ b/src/reflex/welcome.ts
@@ -10,25 +10,38 @@
if (config.welcome.channel) {
let string = config.welcome.message;
if (string) {
- string = await convertCurlyBracketString(string, member.id, member.displayName, member.guild.name, member.guild.members);
+ string = await convertCurlyBracketString(
+ string,
+ member.id,
+ member.displayName,
+ member.guild.name,
+ member.guild.members
+ );
if (config.welcome.channel === "dm") {
await member.send({
- embeds: [new EmojiEmbed()
- .setDescription(string)
- .setStatus("Success")
+ embeds: [
+ new EmojiEmbed()
+ .setDescription(string)
+ .setStatus("Success")
]
});
} else {
- const channel = await member.guild.channels.fetch(config.welcome.channel);
+ const channel = await member.guild.channels.fetch(
+ config.welcome.channel
+ );
if (channel.guild.id !== member.guild.id) return;
if (!channel) return;
try {
await channel.send({
- embeds: [new EmojiEmbed()
- .setDescription(string)
- .setStatus("Success")
+ embeds: [
+ new EmojiEmbed()
+ .setDescription(string)
+ .setStatus("Success")
],
- content: (config.welcome.ping ? `<@${config.welcome.ping}>` : "") + `<@${member.id}>`
+ content:
+ (config.welcome.ping
+ ? `<@${config.welcome.ping}>`
+ : "") + `<@${member.id}>`
});
} catch (err) {
console.error(err); // TODO: SEN
@@ -36,4 +49,4 @@
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/utils/calculate.ts b/src/utils/calculate.ts
index 9bdef3b..6d0c55f 100644
--- a/src/utils/calculate.ts
+++ b/src/utils/calculate.ts
@@ -36,7 +36,7 @@
}
let int = 0n;
- for(const perm of permissions) {
+ for (const perm of permissions) {
int += BigInt(2 ** array.indexOf(perm));
}
return int.toString(16);
@@ -47,7 +47,10 @@
array = logs;
}
const permissions = [];
- const int = (BigInt("0x" + permissionsHex)).toString(2).split("").reverse();
+ const int = BigInt("0x" + permissionsHex)
+ .toString(2)
+ .split("")
+ .reverse();
for (const index in int) {
if (int[index] === "1" && array.length > index) {
permissions.push(array[index]);
@@ -56,9 +59,4 @@
return permissions;
};
-export {
- toHexInteger,
- toHexArray,
- tickets,
- logs
-};
\ No newline at end of file
+export { toHexInteger, toHexArray, tickets, logs };
diff --git a/src/utils/client.ts b/src/utils/client.ts
index a343bcb..0ce61f1 100644
--- a/src/utils/client.ts
+++ b/src/utils/client.ts
@@ -1,9 +1,12 @@
import { HaikuClient } from "jshaiku";
import { Intents } from "discord.js";
-import config from "../config/main.json" assert {type: "json"};
+import config from "../config/main.json" assert { type: "json" };
-const client = new HaikuClient({
- intents: new Intents(32767).bitfield // This is a way of specifying all intents w/o having to type them out
-}, config);
+const client = new HaikuClient(
+ {
+ intents: new Intents(32767).bitfield // This is a way of specifying all intents w/o having to type them out
+ },
+ config
+);
-export default client;
\ No newline at end of file
+export default client;
diff --git a/src/utils/confirmationMessage.ts b/src/utils/confirmationMessage.ts
index fd58d12..728cc52 100644
--- a/src/utils/confirmationMessage.ts
+++ b/src/utils/confirmationMessage.ts
@@ -1,9 +1,14 @@
-import Discord, { CommandInteraction, MessageActionRow, MessageButton, TextInputComponent } from "discord.js";
+import Discord, {
+ CommandInteraction,
+ Message,
+ MessageActionRow,
+ MessageButton,
+ TextInputComponent
+} from "discord.js";
import { modalInteractionCollector } from "./dualCollector.js";
import EmojiEmbed from "./generateEmojiEmbed.js";
import getEmojiByName from "./getEmojiByName.js";
-
interface CustomBoolean<T> {
title: string;
disabled: boolean;
@@ -19,8 +24,8 @@
title = "";
emoji = "";
description = "";
- color = "";
- customButtons: {[index:string]: CustomBoolean<unknown>} = {};
+ color: "Danger" | "Warning" | "Success" = "Success";
+ customButtons: Record<string, CustomBoolean<unknown>> = {};
inverted = false;
reason: string | null = null;
@@ -28,21 +33,45 @@
this.interaction = interaction;
}
- setTitle(title: string) { this.title = title; return this; }
- setEmoji(emoji: string) { this.emoji = emoji; return this; }
- setDescription(description: string) { this.description = description; return this; }
- setColor(color: string) { this.color = color; return this; }
- setInverted(inverted: boolean) { this.inverted = inverted; return this; }
- addCustomBoolean(customId: string, title: string, disabled: boolean, callback: () => Promise<unknown> | null, callbackClicked: string | null, emoji?: string, initial?: boolean) { this.customButtons[customId] = {
- title: title,
- disabled: disabled,
- value: callbackClicked,
- emoji: emoji,
- active: initial ?? false,
- onClick: callback ?? (() => null),
- response: null
- };
- return this;
+ setTitle(title: string) {
+ this.title = title;
+ return this;
+ }
+ setEmoji(emoji: string) {
+ this.emoji = emoji;
+ return this;
+ }
+ setDescription(description: string) {
+ this.description = description;
+ return this;
+ }
+ setColor(color: "Danger" | "Warning" | "Success") {
+ this.color = color;
+ return this;
+ }
+ setInverted(inverted: boolean) {
+ this.inverted = inverted;
+ return this;
+ }
+ addCustomBoolean(
+ customId: string,
+ title: string,
+ disabled: boolean,
+ callback: () => Promise<unknown> = async () => null,
+ callbackClicked: string | null,
+ emoji?: string,
+ initial?: boolean
+ ) {
+ this.customButtons[customId] = {
+ title: title,
+ disabled: disabled,
+ value: callbackClicked,
+ emoji: emoji,
+ active: initial ?? false,
+ onClick: callback,
+ response: null
+ };
+ return this;
}
addReasonButton(reason: string) {
this.reason = reason;
@@ -63,50 +92,71 @@
.setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
];
Object.entries(this.customButtons).forEach(([k, v]) => {
- fullComponents.push(new Discord.MessageButton()
+ const button = new Discord.MessageButton()
.setCustomId(k)
.setLabel(v.title)
.setStyle(v.active ? "SUCCESS" : "PRIMARY")
- .setEmoji(getEmojiByName(v.emoji, "id"))
- .setDisabled(v.disabled));
+ .setDisabled(v.disabled);
+ if (v.emoji !== undefined)
+ button.setEmoji(getEmojiByName(v.emoji, "id"));
+ fullComponents.push(button);
});
- if (this.reason !== null) fullComponents.push(new Discord.MessageButton()
- .setCustomId("reason")
- .setLabel("Edit Reason")
- .setStyle("PRIMARY")
- .setEmoji(getEmojiByName("ICONS.EDIT", "id"))
- .setDisabled(false)
- );
+ if (this.reason !== null)
+ fullComponents.push(
+ new Discord.MessageButton()
+ .setCustomId("reason")
+ .setLabel("Edit Reason")
+ .setStyle("PRIMARY")
+ .setEmoji(getEmojiByName("ICONS.EDIT", "id"))
+ .setDisabled(false)
+ );
const components = [];
for (let i = 0; i < fullComponents.length; i += 5) {
- components.push(new MessageActionRow().addComponents(fullComponents.slice(i, i + 5)));
+ components.push(
+ new MessageActionRow().addComponents(
+ fullComponents.slice(i, i + 5)
+ )
+ );
}
const object = {
embeds: [
new EmojiEmbed()
.setEmoji(this.emoji)
.setTitle(this.title)
- .setDescription(this.description + "\n\n" + Object.values(this.customButtons).map(v => {
- if (v.value === null) return "";
- return v.active ? `*${v.value}*\n` : "";
- }).join(""))
+ .setDescription(
+ this.description +
+ "\n\n" +
+ Object.values(this.customButtons)
+ .map((v) => {
+ if (v.value === null) return "";
+ return v.active ? `*${v.value}*\n` : "";
+ })
+ .join("")
+ )
.setStatus(this.color)
],
components: components,
ephemeral: true,
fetchReply: true
};
- let m;
+ let m: Message;
try {
- if ( editOnly ) {
- m = await this.interaction.editReply(object);
+ if (editOnly) {
+ m = (await this.interaction.editReply(object)) as Message;
} else {
- m = await this.interaction.reply(object);
+ m = (await this.interaction.reply(
+ object
+ )) as unknown as Message;
}
- } catch { return { cancelled: true }; }
+ } catch {
+ return { cancelled: true };
+ }
let component;
try {
- component = await m.awaitMessageComponent({filter: (m) => m.user.id === this.interaction.user.id, time: 300000});
+ component = await m.awaitMessageComponent({
+ filter: (m) => m.user.id === this.interaction.user.id,
+ time: 300000
+ });
} catch (e) {
return { success: false, components: this.customButtons };
}
@@ -114,47 +164,75 @@
component.deferUpdate();
for (const v of Object.values(this.customButtons)) {
if (!v.active) continue;
- try { v.response = await v.onClick(); }
- catch (e) { console.log(e); }
+ try {
+ v.response = await v.onClick();
+ } catch (e) {
+ console.log(e);
+ }
}
return { success: true, components: this.customButtons };
} else if (component.customId === "no") {
component.deferUpdate();
return { success: false, components: this.customButtons };
} else if (component.customId === "reason") {
- await component.showModal(new Discord.Modal().setCustomId("modal").setTitle("Editing reason").addComponents(
- new MessageActionRow<TextInputComponent>().addComponents(new TextInputComponent()
- .setCustomId("reason")
- .setLabel("Reason")
- .setMaxLength(2000)
- .setRequired(false)
- .setStyle("PARAGRAPH")
- .setPlaceholder("Spammed in #general")
- .setValue(this.reason ? this.reason : "")
- )
- ));
+ await component.showModal(
+ new Discord.Modal()
+ .setCustomId("modal")
+ .setTitle("Editing reason")
+ .addComponents(
+ new MessageActionRow<TextInputComponent>().addComponents(
+ new TextInputComponent()
+ .setCustomId("reason")
+ .setLabel("Reason")
+ .setMaxLength(2000)
+ .setRequired(false)
+ .setStyle("PARAGRAPH")
+ .setPlaceholder("Spammed in #general")
+ .setValue(this.reason ? this.reason : "")
+ )
+ )
+ );
await this.interaction.editReply({
- embeds: [new EmojiEmbed()
- .setTitle(this.title)
- .setDescription("Modal opened. If you can't see it, click back and try again.")
- .setStatus(this.color)
- .setEmoji(this.emoji)
- ], components: [new MessageActionRow().addComponents([new MessageButton()
- .setLabel("Back")
- .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
- .setStyle("PRIMARY")
- .setCustomId("back")
- ])]
+ embeds: [
+ new EmojiEmbed()
+ .setTitle(this.title)
+ .setDescription(
+ "Modal opened. If you can't see it, click back and try again."
+ )
+ .setStatus(this.color)
+ .setEmoji(this.emoji)
+ ],
+ components: [
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setLabel("Back")
+ .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
+ .setStyle("PRIMARY")
+ .setCustomId("back")
+ ])
+ ]
});
let out;
try {
- out = await modalInteractionCollector(m, (m) => m.channel.id === this.interaction.channel.id, (m) => m.customId === "reason");
- } catch (e) { return {}; }
- if (out.fields) { return { newReason: out.fields.getTextInputValue("reason") ?? "" }; }
- else { return { newReason: this.reason }; }
+ out = await modalInteractionCollector(
+ m,
+ (m) => m.channel.id === this.interaction.channel.id,
+ (m) => m.customId === "reason"
+ );
+ } catch (e) {
+ return {};
+ }
+ if (out.fields) {
+ return {
+ newReason: out.fields.getTextInputValue("reason") ?? ""
+ };
+ } else {
+ return { newReason: this.reason };
+ }
} else {
component.deferUpdate();
- this.customButtons[component.customId].active = !this.customButtons[component.customId].active;
+ this.customButtons[component.customId].active =
+ !this.customButtons[component.customId].active;
return { components: this.customButtons };
}
}
diff --git a/src/utils/convertCurlyBracketString.ts b/src/utils/convertCurlyBracketString.ts
index f05076e..49a4418 100644
--- a/src/utils/convertCurlyBracketString.ts
+++ b/src/utils/convertCurlyBracketString.ts
@@ -1,13 +1,33 @@
-async function convertCurlyBracketString(str, memberID, memberName, serverName, members): Promise<string> {
+async function convertCurlyBracketString(
+ str,
+ memberID,
+ memberName,
+ serverName,
+ members
+): Promise<string> {
const memberCount = (await members.fetch()).size;
- const bots = (await members.fetch()).filter(m => m.user.bot).size;
+ const bots = (await members.fetch()).filter((m) => m.user.bot).size;
str = str
- .replace("{member:mention}", memberID ? `<@${memberID}>` : "{member:mention}")
- .replace("{member:name}", memberName ? `${memberName}` : "{member:name}")
+ .replace(
+ "{member:mention}",
+ memberID ? `<@${memberID}>` : "{member:mention}"
+ )
+ .replace(
+ "{member:name}",
+ memberName ? `${memberName}` : "{member:name}"
+ )
.replace("{serverName}", serverName ? `${serverName}` : "{serverName}")
- .replace("{memberCount}", memberCount ? `${memberCount}` : "{memberCount}")
+ .replace(
+ "{memberCount}",
+ memberCount ? `${memberCount}` : "{memberCount}"
+ )
.replace("{memberCount:bots}", bots ? `${bots}` : "{memberCount:bots}")
- .replace("{memberCount:humans}", (memberCount && bots) ? `${memberCount - bots}` : "{memberCount:humans}");
+ .replace(
+ "{memberCount:humans}",
+ memberCount && bots
+ ? `${memberCount - bots}`
+ : "{memberCount:humans}"
+ );
return str;
}
diff --git a/src/utils/createLogException.ts b/src/utils/createLogException.ts
index c62a824..7a6c492 100644
--- a/src/utils/createLogException.ts
+++ b/src/utils/createLogException.ts
@@ -3,6 +3,8 @@
export default function (guild: string, channel: string, message: string) {
client.noLog.push(`${guild}/${channel}/${message}`);
setTimeout(() => {
- client.noLog = client.noLog.filter((i) => {return i !== `${guild}/${channel}/${message}`;});
+ client.noLog = client.noLog.filter((i) => {
+ return i !== `${guild}/${channel}/${message}`;
+ });
}, 500);
-}
\ No newline at end of file
+}
diff --git a/src/utils/createPageIndicator.ts b/src/utils/createPageIndicator.ts
index fa203dc..ccf18e2 100644
--- a/src/utils/createPageIndicator.ts
+++ b/src/utils/createPageIndicator.ts
@@ -1,15 +1,23 @@
import getEmojiByName from "./getEmojiByName.js";
-function pageIndicator(amount: number, selected: number, showDetails?: boolean | true) {
+function pageIndicator(
+ amount: number,
+ selected: number,
+ showDetails?: boolean | true
+) {
let out = "";
if (amount === 1) {
- out += getEmojiByName("TRACKS.SINGLE." + (selected === 0 ? "ACTIVE" : "INACTIVE"));
+ out += getEmojiByName(
+ "TRACKS.SINGLE." + (selected === 0 ? "ACTIVE" : "INACTIVE")
+ );
} else {
for (let i = 0; i < amount; i++) {
- out += getEmojiByName("TRACKS.HORIZONTAL." +
- (i === 0 ? "LEFT" : (i === amount - 1 ? "RIGHT" : "MIDDLE")) + "." +
- (i === selected ? "ACTIVE" : "INACTIVE")
+ out += getEmojiByName(
+ "TRACKS.HORIZONTAL." +
+ (i === 0 ? "LEFT" : i === amount - 1 ? "RIGHT" : "MIDDLE") +
+ "." +
+ (i === selected ? "ACTIVE" : "INACTIVE")
);
}
}
@@ -19,4 +27,4 @@
return out;
}
-export default pageIndicator;
\ No newline at end of file
+export default pageIndicator;
diff --git a/src/utils/database.ts b/src/utils/database.ts
index cffdf04..3592c95 100644
--- a/src/utils/database.ts
+++ b/src/utils/database.ts
@@ -1,10 +1,9 @@
import type Discord from "discord.js";
import { Collection, MongoClient } from "mongodb";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
-// @ts-ignore
+// @ts-expect-error
import structuredClone from "@ungap/structured-clone";
-import config from "../config/main.json" assert {type: "json"};
-
+import config from "../config/main.json" assert { type: "json" };
const mongoClient = new MongoClient(config.mongoUrl);
await mongoClient.connect();
@@ -19,17 +18,21 @@
// eslint-disable-next-line @typescript-eslint/no-explicit-any
get(target: Record<string, any>, prop: string, receiver: any) {
let dataToReturn = data[prop];
- if (dataToReturn === null ) return Reflect.get(target, prop, receiver);
- if (typeof dataToReturn === "object" && !Array.isArray(dataToReturn)) dataToReturn = new Proxy(
- Reflect.get(target, prop, receiver),
- Entry(dataToReturn)
- );
+ if (dataToReturn === null)
+ return Reflect.get(target, prop, receiver);
+ if (
+ typeof dataToReturn === "object" &&
+ !Array.isArray(dataToReturn)
+ )
+ dataToReturn = new Proxy(
+ Reflect.get(target, prop, receiver),
+ Entry(dataToReturn)
+ );
return dataToReturn ?? Reflect.get(target, prop, receiver);
}
};
};
-
export class Guilds {
guilds: Collection<GuildConfig>;
defaultData: GuildConfig | null;
@@ -41,55 +44,89 @@
}
async setup() {
- this.defaultData = (await import("../config/default.json", { assert: { type: "json" }})).default as unknown as GuildConfig;
+ this.defaultData = (
+ await import("../config/default.json", { assert: { type: "json" } })
+ ).default as unknown as GuildConfig;
}
async read(guild: string) {
const entry = await this.guilds.findOne({ id: guild });
- return new Proxy(structuredClone(this.defaultData), Entry(entry)) as unknown as GuildConfig;
+ return new Proxy(
+ structuredClone(this.defaultData),
+ Entry(entry)
+ ) as unknown as GuildConfig;
}
- async write(guild: string, set: object | null, unset: string[] | string = []) {
+ async write(
+ guild: string,
+ set: object | null,
+ unset: string[] | string = []
+ ) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const uo: Record<string, any> = {};
if (!Array.isArray(unset)) unset = [unset];
for (const key of unset) {
uo[key] = null;
}
- const out = {$set: {}, $unset: {}};
- if (set) out["$set"] = set;
- if (unset.length) out["$unset"] = uo;
+ const out = { $set: {}, $unset: {} };
+ if (set) out.$set = set;
+ if (unset.length) out.$unset = uo;
await this.guilds.updateOne({ id: guild }, out, { upsert: true });
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
async append(guild: string, key: string, value: any) {
if (Array.isArray(value)) {
- await this.guilds.updateOne({ id: guild }, {
- $addToSet: { [key]: { $each: value } }
- }, { upsert: true });
+ await this.guilds.updateOne(
+ { id: guild },
+ {
+ $addToSet: { [key]: { $each: value } }
+ },
+ { upsert: true }
+ );
} else {
- await this.guilds.updateOne({ id: guild }, {
- $addToSet: { [key]: value }
- }, { upsert: true });
+ await this.guilds.updateOne(
+ { id: guild },
+ {
+ $addToSet: { [key]: value }
+ },
+ { upsert: true }
+ );
}
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
- async remove(guild: string, key: string, value: any, innerKey?: string | null) {
+ async remove(
+ guild: string,
+ key: string,
+ value: any,
+ innerKey?: string | null
+ ) {
console.log(Array.isArray(value));
if (innerKey) {
- await this.guilds.updateOne({ id: guild }, {
- $pull: { [key]: { [innerKey]: { $eq: value } } }
- }, { upsert: true });
+ await this.guilds.updateOne(
+ { id: guild },
+ {
+ $pull: { [key]: { [innerKey]: { $eq: value } } }
+ },
+ { upsert: true }
+ );
} else if (Array.isArray(value)) {
- await this.guilds.updateOne({ id: guild }, {
- $pullAll: { [key]: value }
- }, { upsert: true });
+ await this.guilds.updateOne(
+ { id: guild },
+ {
+ $pullAll: { [key]: value }
+ },
+ { upsert: true }
+ );
} else {
- await this.guilds.updateOne({ id: guild }, {
- $pullAll: { [key]: [value] }
- }, { upsert: true });
+ await this.guilds.updateOne(
+ { id: guild },
+ {
+ $pullAll: { [key]: [value] }
+ },
+ { upsert: true }
+ );
}
}
@@ -98,7 +135,6 @@
}
}
-
export class History {
histories: Collection<HistorySchema>;
defaultData: GuildConfig;
@@ -108,7 +144,16 @@
return this;
}
- async create(type: string, guild: string, user: Discord.User, moderator: Discord.User | null, reason: string | null, before?: null, after?: null, amount?: null) {
+ async create(
+ type: string,
+ guild: string,
+ user: Discord.User,
+ moderator: Discord.User | null,
+ reason: string | null,
+ before?: null,
+ after?: null,
+ amount?: null
+ ) {
await this.histories.insertOne({
type: type,
guild: guild,
@@ -123,14 +168,16 @@
}
async read(guild: string, user: string, year: number) {
- const entry = (await this.histories.find({
- guild: guild,
- user: user,
- occurredAt: {
- $gte: new Date(year - 1, 11, 31, 23, 59, 59),
- $lt: new Date(year + 1, 0, 1, 0, 0, 0)
- }
- }).toArray()) as HistorySchema[];
+ const entry = (await this.histories
+ .find({
+ guild: guild,
+ user: user,
+ occurredAt: {
+ $gte: new Date(year - 1, 11, 31, 23, 59, 59),
+ $lt: new Date(year + 1, 0, 1, 0, 0, 0)
+ }
+ })
+ .toArray()) as HistorySchema[];
return entry;
}
@@ -149,7 +196,11 @@
}
async create(guild: string, user: string, note: string | null) {
- await this.modNotes.updateOne({ guild: guild, user: user }, { $set: { note: note }}, { upsert: true });
+ await this.modNotes.updateOne(
+ { guild: guild, user: user },
+ { $set: { note: note } },
+ { upsert: true }
+ );
}
async read(guild: string, user: string) {
@@ -167,163 +218,165 @@
}
async hasPremium(guild: string) {
- const entry = await this.premium.findOne({ appliesTo: { $in: [guild] } });
+ const entry = await this.premium.findOne({
+ appliesTo: { $in: [guild] }
+ });
return entry !== null;
}
}
export interface GuildConfig {
- id: string,
- version: number,
+ id: string;
+ version: number;
singleEventNotifications: {
- statsChannelDeleted: boolean
- }
+ statsChannelDeleted: boolean;
+ };
filters: {
images: {
- NSFW: boolean,
- size: boolean
- },
- malware: boolean,
+ NSFW: boolean;
+ size: boolean;
+ };
+ malware: boolean;
wordFilter: {
- enabled: boolean,
+ enabled: boolean;
words: {
- strict: string[],
- loose: string[]
- },
+ strict: string[];
+ loose: string[];
+ };
allowed: {
- users: string[],
- roles: string[],
- channels: string[]
- }
- },
+ users: string[];
+ roles: string[];
+ channels: string[];
+ };
+ };
invite: {
- enabled: boolean,
- channels: string[]
- },
+ enabled: boolean;
+ channels: string[];
+ };
pings: {
- mass: number,
- everyone: boolean,
- roles: boolean,
+ mass: number;
+ everyone: boolean;
+ roles: boolean;
allowed: {
- roles: string[],
- rolesToMention: string[],
- users: string[],
- channels: string[]
- }
- }
- }
+ roles: string[];
+ rolesToMention: string[];
+ users: string[];
+ channels: string[];
+ };
+ };
+ };
welcome: {
- enabled: boolean,
+ enabled: boolean;
verificationRequired: {
- message: boolean,
- role: string | null
- },
- role: string | null,
- ping: string | null,
- channel: string | null,
- message: string | null,
- }
- stats: Record<string, {name: string, enabled: boolean}>
+ message: boolean;
+ role: string | null;
+ };
+ role: string | null;
+ ping: string | null;
+ channel: string | null;
+ message: string | null;
+ };
+ stats: Record<string, { name: string; enabled: boolean }>;
logging: {
logs: {
- enabled: boolean,
- channel: string | null,
- toLog: string | null,
- },
+ enabled: boolean;
+ channel: string | null;
+ toLog: string | null;
+ };
staff: {
- channel: string | null,
- },
+ channel: string | null;
+ };
attachments: {
- channel: string | null,
- saved: Record<string, string>
- }
- }
+ channel: string | null;
+ saved: Record<string, string>;
+ };
+ };
verify: {
- enabled: boolean,
- role: string | null,
- }
+ enabled: boolean;
+ role: string | null;
+ };
tickets: {
- enabled: boolean,
- category: string | null,
- types: string | null,
- customTypes: string[],
- useCustom: boolean,
- supportRole: string | null,
- maxTickets: number
- }
+ enabled: boolean;
+ category: string | null;
+ types: string | null;
+ customTypes: string[];
+ useCustom: boolean;
+ supportRole: string | null;
+ maxTickets: number;
+ };
moderation: {
mute: {
- timeout: boolean,
- role: string | null,
- text: string | null,
- link: string | null
- },
+ timeout: boolean;
+ role: string | null;
+ text: string | null;
+ link: string | null;
+ };
kick: {
- text: string | null,
- link: string | null
- },
+ text: string | null;
+ link: string | null;
+ };
ban: {
- text: string | null,
- link: string | null
- },
+ text: string | null;
+ link: string | null;
+ };
softban: {
- text: string | null,
- link: string | null
- },
+ text: string | null;
+ link: string | null;
+ };
warn: {
- text: string | null,
- link: string | null
- },
+ text: string | null;
+ link: string | null;
+ };
role: {
- role: string | null,
- }
- }
+ role: string | null;
+ };
+ };
tracks: {
- name: string,
- retainPrevious: boolean,
- nullable: boolean,
- track: string[],
- manageableBy: string[]
- }[]
+ name: string;
+ retainPrevious: boolean;
+ nullable: boolean;
+ track: string[];
+ manageableBy: string[];
+ }[];
roleMenu: {
- enabled: boolean,
- allowWebUI: boolean,
+ enabled: boolean;
+ allowWebUI: boolean;
options: {
- name: string,
- description: string,
- min: number,
- max: number,
+ name: string;
+ description: string;
+ min: number;
+ max: number;
options: {
- name: string,
- description: string | null,
- role: string
- }[]
- }[]
- }
- tags: Record<string, string>
+ name: string;
+ description: string | null;
+ role: string;
+ }[];
+ }[];
+ };
+ tags: Record<string, string>;
}
export interface HistorySchema {
- type: string,
- guild: string,
- user: string,
- moderator: string | null,
- reason: string,
- occurredAt: Date,
- before: string | null,
- after: string | null,
- amount: string | null
+ type: string;
+ guild: string;
+ user: string;
+ moderator: string | null;
+ reason: string;
+ occurredAt: Date;
+ before: string | null;
+ after: string | null;
+ amount: string | null;
}
export interface ModNoteSchema {
- guild: string,
- user: string,
- note: string
+ guild: string;
+ user: string;
+ note: string;
}
export interface PremiumSchema {
- user: string,
- level: number,
- expires: Date,
- appliesTo: string[]
-}
\ No newline at end of file
+ user: string;
+ level: number;
+ expires: Date;
+ appliesTo: string[];
+}
diff --git a/src/utils/defaultEmbeds.ts b/src/utils/defaultEmbeds.ts
index ce6edc1..68d8013 100644
--- a/src/utils/defaultEmbeds.ts
+++ b/src/utils/defaultEmbeds.ts
@@ -1,9 +1,9 @@
import EmojiEmbed from "./generateEmojiEmbed.js";
-export const LoadingEmbed = [new EmojiEmbed()
- .setTitle("Loading")
- .setDescription("One moment...")
- .setStatus("Danger")
- .setEmoji("NUCLEUS.LOADING")
+export const LoadingEmbed = [
+ new EmojiEmbed()
+ .setTitle("Loading")
+ .setDescription("One moment...")
+ .setStatus("Danger")
+ .setEmoji("NUCLEUS.LOADING")
];
-
diff --git a/src/utils/dualCollector.ts b/src/utils/dualCollector.ts
index 11df0ce..8c6e55c 100644
--- a/src/utils/dualCollector.ts
+++ b/src/utils/dualCollector.ts
@@ -1,18 +1,49 @@
-import Discord, { Interaction } from "discord.js";
+import Discord, {
+ Interaction,
+ Message,
+ MessageComponentInteraction
+} from "discord.js";
import client from "./client.js";
-export default async function (m, interactionFilter, messageFilter) {
+export default async function (
+ m: Message,
+ interactionFilter: (
+ i: MessageComponentInteraction
+ ) => boolean | Promise<boolean>,
+ messageFilter: (m: Message) => boolean | Promise<boolean>
+) {
let out;
try {
out = await new Promise((resolve, _reject) => {
- const mes = m.createMessageComponentCollector({filter: (m) => interactionFilter(m), time: 300000})
- .on("collect", (m) => { resolve(m); });
- const int = m.channel.createMessageCollector({filter: (m) => messageFilter(m), time: 300000})
- .then("collect", (m) => { try {m.delete();} catch (e) { client._error(e); } resolve(m); });
- mes.on("end", () => { int.stop(); });
- int.on("end", () => { mes.stop(); });
+ const mes = m
+ .createMessageComponentCollector({
+ filter: (m) => interactionFilter(m),
+ time: 300000
+ })
+ .on("collect", (m) => {
+ resolve(m);
+ });
+ const int = m.channel
+ .createMessageCollector({
+ filter: (m) => messageFilter(m),
+ time: 300000
+ })
+ .on("collect", (m) => {
+ try {
+ m.delete();
+ } catch (e) {
+ client._error(e);
+ }
+ resolve(m);
+ });
+ mes.on("end", () => {
+ int.stop();
+ });
+ int.on("end", () => {
+ mes.stop();
+ });
});
- } catch(e) {
+ } catch (e) {
console.log(e);
return null;
}
@@ -20,27 +51,43 @@
return out;
}
-export async function modalInteractionCollector(m, modalFilter, interactionFilter) {
+export async function modalInteractionCollector(
+ m: Message,
+ modalFilter: (i: Interaction) => boolean | Promise<boolean>,
+ interactionFilter: (
+ i: MessageComponentInteraction
+ ) => boolean | Promise<boolean>
+) {
let out;
try {
out = await new Promise((resolve, _reject) => {
- const int = m.createMessageComponentCollector({filter: (m: Interaction) => interactionFilter(m), time: 300000})
- .on("collect", (m: Interaction) => { resolve(m); });
- const mod = new Discord.InteractionCollector(
- client, {
- filter: (m: Interaction) => modalFilter(m),
+ const int = m
+ .createMessageComponentCollector({
+ filter: (i: MessageComponentInteraction) =>
+ interactionFilter(i),
time: 300000
})
- .on("collect", async (m: Interaction) => {
- int.stop();
- (m as Discord.ModalSubmitInteraction).deferUpdate();
- resolve((m as Discord.ModalSubmitInteraction)); });
- int.on("end", () => { mod.stop(); });
- mod.on("end", () => { int.stop(); });
+ .on("collect", (i: Interaction) => {
+ resolve(i);
+ });
+ const mod = new Discord.InteractionCollector(client, {
+ filter: (i: Interaction) => modalFilter(i),
+ time: 300000
+ }).on("collect", async (i: Interaction) => {
+ int.stop();
+ (i as Discord.ModalSubmitInteraction).deferUpdate();
+ resolve(i as Discord.ModalSubmitInteraction);
+ });
+ int.on("end", () => {
+ mod.stop();
+ });
+ mod.on("end", () => {
+ int.stop();
+ });
});
- } catch(e) {
+ } catch (e) {
console.log(e);
return null;
}
return out;
-}
\ No newline at end of file
+}
diff --git a/src/utils/eventScheduler.ts b/src/utils/eventScheduler.ts
index df46ca8..6923ede 100644
--- a/src/utils/eventScheduler.ts
+++ b/src/utils/eventScheduler.ts
@@ -2,13 +2,18 @@
import client from "./client.js";
import * as fs from "fs";
import * as path from "path";
-import config from "../config/main.json" assert {type: "json"};
+import config from "../config/main.json" assert { type: "json" };
class EventScheduler {
private agenda: Agenda;
constructor() {
- this.agenda = new Agenda({db: {address: config.mongoUrl + "Nucleus", collection: "eventScheduler"}});
+ this.agenda = new Agenda({
+ db: {
+ address: config.mongoUrl + "Nucleus",
+ collection: "eventScheduler"
+ }
+ });
this.agenda.define("unmuteRole", async (job) => {
const guild = await client.guilds.fetch(job.attrs.data.guild);
@@ -18,17 +23,31 @@
await job.remove();
});
this.agenda.define("deleteFile", async (job) => {
- fs.rm(path.resolve("dist/utils/temp", job.attrs.data.fileName), client._error);
+ fs.rm(
+ path.resolve("dist/utils/temp", job.attrs.data.fileName),
+ client._error
+ );
await job.remove();
});
this.agenda.define("naturalUnmute", async (job) => {
- const { log, NucleusColors, entry, renderUser, renderDelta } = client.logger;
+ const { log, NucleusColors, entry, renderUser, renderDelta } =
+ client.logger;
const guild = await client.guilds.fetch(job.attrs.data.guild);
const user = await guild.members.fetch(job.attrs.data.user);
if (user.communicationDisabledUntil === null) return;
- try { await client.database.history.create(
- "unmute", user.guild.id, user.user, null, null, null, null
- );} catch (e) { client._error(e); }
+ try {
+ await client.database.history.create(
+ "unmute",
+ user.guild.id,
+ user.user,
+ null,
+ null,
+ null,
+ null
+ );
+ } catch (e) {
+ client._error(e);
+ }
const data = {
meta: {
type: "memberUnmute",
@@ -41,7 +60,10 @@
list: {
memberId: entry(user.user.id, `\`${user.user.id}\``),
name: entry(user.user.id, renderUser(user.user)),
- unmuted: entry(new Date().getTime(), renderDelta(new Date().getTime())),
+ unmuted: entry(
+ new Date().getTime(),
+ renderDelta(new Date().getTime())
+ ),
unmutedBy: entry(null, "*Time out ended*")
},
hidden: {
@@ -53,7 +75,7 @@
}
async start() {
- await new Promise(resolve => this.agenda.once("ready", resolve));
+ await new Promise((resolve) => this.agenda.once("ready", resolve));
this.agenda.start();
return this;
}
@@ -65,8 +87,8 @@
// eslint-disable-next-line @typescript-eslint/no-explicit-any
cancel(name: string, data: any) {
- this.agenda.cancel({name, data});
+ this.agenda.cancel({ name, data });
}
}
-export default EventScheduler;
\ No newline at end of file
+export default EventScheduler;
diff --git a/src/utils/generateEmojiEmbed.ts b/src/utils/generateEmojiEmbed.ts
index 65e11fa..c1de60f 100644
--- a/src/utils/generateEmojiEmbed.ts
+++ b/src/utils/generateEmojiEmbed.ts
@@ -2,9 +2,9 @@
import getEmojiByName from "./getEmojiByName.js";
const colors = {
- "Danger": 0xF27878,
- "Warning": 0xF2D478,
- "Success": 0x68D49E
+ Danger: 0xf27878,
+ Warning: 0xf2d478,
+ Success: 0x68d49e
};
class EmojiEmbed extends MessageEmbed {
@@ -12,7 +12,7 @@
_emoji: string | null = null;
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
- // @ts-ignore
+ // @ts-expect-error
// This *is* meant to be an accessor rather than a property
override get title() {
if (!this._emoji) return this._title;
@@ -23,9 +23,18 @@
this._title = title;
}
- override setTitle(title: string) { this._title = title; return this; }
- setEmoji(emoji: string) { this._emoji = emoji; return this; }
- setStatus(color: "Danger" | "Warning" | "Success") { this.setColor(colors[color]); return this; }
+ override setTitle(title: string) {
+ this._title = title;
+ return this;
+ }
+ setEmoji(emoji: string) {
+ this._emoji = emoji;
+ return this;
+ }
+ setStatus(color: "Danger" | "Warning" | "Success") {
+ this.setColor(colors[color]);
+ return this;
+ }
}
-export default EmojiEmbed;
\ No newline at end of file
+export default EmojiEmbed;
diff --git a/src/utils/generateKeyValueList.ts b/src/utils/generateKeyValueList.ts
index a093ab7..a158391 100644
--- a/src/utils/generateKeyValueList.ts
+++ b/src/utils/generateKeyValueList.ts
@@ -1,22 +1,21 @@
-const forceCaps = [
- "ID",
- "NSFW",
- "URL"
-];
+const forceCaps = ["ID", "NSFW", "URL"];
export function capitalize(s: string) {
s = s.replace(/([A-Z])/g, " $1");
- s = s.split(" ").map(word => {
- return forceCaps.includes(word.toUpperCase()) ? word.toUpperCase() : (word[0] ?? "")
- .toUpperCase() + word.slice(1)
- .toLowerCase()
- .replace("discord", "Discord");
- }).join(" ");
+ s = s
+ .split(" ")
+ .map((word) => {
+ return forceCaps.includes(word.toUpperCase())
+ ? word.toUpperCase()
+ : (word[0] ?? "").toUpperCase() +
+ word.slice(1).toLowerCase().replace("discord", "Discord");
+ })
+ .join(" ");
return s;
}
export function toCapitals(s: string) {
- if (s[0] === undefined) return "";
+ if (s.startsWith(undefined)) return "";
return s[0].toUpperCase() + s.slice(1).toLowerCase();
}
@@ -28,4 +27,4 @@
return out;
}
-export default keyValueList;
\ No newline at end of file
+export default keyValueList;
diff --git a/src/utils/getEmojiByName.ts b/src/utils/getEmojiByName.ts
index c0a43cb..f953a4f 100644
--- a/src/utils/getEmojiByName.ts
+++ b/src/utils/getEmojiByName.ts
@@ -1,13 +1,13 @@
-import emojis from "../config/emojis.json" assert {type: "json"};
+import emojis from "../config/emojis.json" assert { type: "json" };
interface EmojisIndex {
[key: string]: string | EmojisIndex | EmojisIndex[];
}
function getEmojiByName(name: string, format?: string): string {
- const split = name.split(".");
+ const parts = name.split(".");
let id: string | EmojisIndex | EmojisIndex[] | undefined = emojis;
- split.forEach(part => {
+ for (const part of parts) {
if (typeof id === "string" || id === undefined) {
throw new Error(`Emoji ${name} not found`);
}
@@ -16,8 +16,11 @@
} else {
id = id[part];
}
- });
- if ( format === "id" ) {
+ }
+ if (typeof id !== "string" && id !== undefined) {
+ throw new Error(`Emoji ${name} not found`);
+ }
+ if (format === "id") {
if (id === undefined) return "0";
return id.toString();
}
diff --git a/src/utils/log.ts b/src/utils/log.ts
index f9f751e..6baa0a5 100644
--- a/src/utils/log.ts
+++ b/src/utils/log.ts
@@ -7,18 +7,17 @@
const wait = promisify(setTimeout);
-
export class Logger {
renderUser(user: Discord.User | string) {
if (typeof user === "string") return `${user} [<@${user}>]`;
return `${user.username} [<@${user.id}>]`;
}
renderTime(t: number) {
- t = Math.floor(t /= 1000);
+ t = Math.floor((t /= 1000));
return `<t:${t}:D> at <t:${t}:T>`;
}
renderDelta(t: number) {
- t = Math.floor(t /= 1000);
+ t = Math.floor((t /= 1000));
return `<t:${t}:R> (<t:${t}:D> at <t:${t}:T>)`;
}
renderNumberDelta(num1: number, num2: number) {
@@ -35,19 +34,23 @@
return `${role.name} [<@&${role.id}>]`;
}
renderEmoji(emoji: Discord.GuildEmoji) {
- return `<${emoji.animated ? "a" : ""}:${emoji.name}:${emoji.id}> [\`:${emoji.name}:\`]`;
+ return `<${emoji.animated ? "a" : ""}:${emoji.name}:${emoji.id}> [\`:${
+ emoji.name
+ }:\`]`;
}
public readonly NucleusColors = {
- red: 0xF27878,
- yellow: 0xF2D478,
- green: 0x68D49E
-
+ red: 0xf27878,
+ yellow: 0xf2d478,
+ green: 0x68d49e
};
- async getAuditLog(guild: Discord.Guild, event: Discord.GuildAuditLogsResolvable): Promise<Discord.GuildAuditLogsEntry[]>{
+ async getAuditLog(
+ guild: Discord.Guild,
+ event: Discord.GuildAuditLogsResolvable
+ ): Promise<Discord.GuildAuditLogsEntry[]> {
await wait(250);
- const auditLog = await guild.fetchAuditLogs({type: event});
+ const auditLog = await guild.fetchAuditLogs({ type: event });
return auditLog as unknown as Discord.GuildAuditLogsEntry[];
}
@@ -56,16 +59,23 @@
const config = await client.database.guilds.read(log.hidden.guild);
if (!config.logging.logs.enabled) return;
if (!(log.meta.calculateType === true)) {
- if(!toHexArray(config.logging.logs.toLog).includes(log.meta.calculateType)) return console.log("Not logging this type of event");
+ if (
+ !toHexArray(config.logging.logs.toLog).includes(
+ log.meta.calculateType
+ )
+ )
+ return console.log("Not logging this type of event");
}
if (config.logging.logs.channel) {
- const channel = await client.channels.fetch(config.logging.logs.channel) as Discord.TextChannel;
+ const channel = (await client.channels.fetch(
+ config.logging.logs.channel
+ )) as Discord.TextChannel | null;
const description: Record<string, string> = {};
- Object.entries(log.list).map(entry => {
+ Object.entries(log.list).map((entry) => {
const key: string = entry[0];
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const value: any = entry[1];
- if(value.displayValue) {
+ if (value.displayValue) {
description[key] = value.displayValue;
} else {
description[key] = value;
@@ -74,19 +84,22 @@
if (channel) {
log.separate = log.separate || {};
const embed = new Discord.MessageEmbed()
- .setTitle(`${getEmojiByName(log.meta.emoji)} ${log.meta.displayName}`)
+ .setTitle(
+ `${getEmojiByName(log.meta.emoji)} ${
+ log.meta.displayName
+ }`
+ )
.setDescription(
(log.separate.start ? log.separate.start + "\n" : "") +
- generateKeyValueList(description) +
- (log.separate.end ? "\n" + log.separate.end : "")
+ generateKeyValueList(description) +
+ (log.separate.end ? "\n" + log.separate.end : "")
)
.setTimestamp(log.meta.timestamp)
.setColor(log.meta.color);
- channel.send({embeds: [embed]});
+ channel.send({ embeds: [embed] });
}
}
}
}
-
export default {};
diff --git a/src/utils/memory.ts b/src/utils/memory.ts
index 070bd7f..a397d09 100644
--- a/src/utils/memory.ts
+++ b/src/utils/memory.ts
@@ -1,31 +1,38 @@
import client from "./client.js";
+import type { GuildConfig } from "./database.js";
+
+interface GuildData {
+ lastUpdated: number;
+ filters: GuildConfig["filters"];
+ logging: GuildConfig["logging"];
+ tickets: GuildConfig["tickets"];
+}
class Memory {
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- memory: Record<string, any>;
+ memory: Map<string, GuildData>;
constructor() {
- this.memory = {};
+ this.memory = new Map<string, GuildData>();
setInterval(() => {
- for (const guild in this.memory) {
- if (this.memory[guild].updated + 15 * 60 * 1000 < Date.now()) {
- delete this.memory[guild];
+ for (const [guild, guildData] of this.memory.entries()) {
+ if (guildData.lastUpdated + 15 * 60 * 1000 < Date.now()) {
+ this.memory.delete(guild);
}
}
}, 1000 * 60 * 30);
}
- async readGuildInfo(guild: string): Promise<object> {
- if (!this.memory[guild]) {
+ async readGuildInfo(guild: string): Promise<GuildData> {
+ if (!this.memory.has(guild)) {
const guildData = await client.database.guilds.read(guild);
- this.memory[guild] = {
+ this.memory.set(guild, {
lastUpdated: Date.now(),
filters: guildData.filters,
logging: guildData.logging,
tickets: guildData.tickets
- };
+ });
}
- return this.memory[guild];
+ return this.memory.get(guild)!;
}
}
diff --git a/src/utils/plurals.ts b/src/utils/plurals.ts
index 619ced2..9cb16a0 100644
--- a/src/utils/plurals.ts
+++ b/src/utils/plurals.ts
@@ -4,4 +4,4 @@
return `${amount} ${unit}s`;
}
-export default addPlural;
\ No newline at end of file
+export default addPlural;
diff --git a/src/utils/singleNotify.ts b/src/utils/singleNotify.ts
index 7339129..8f011e3 100644
--- a/src/utils/singleNotify.ts
+++ b/src/utils/singleNotify.ts
@@ -3,28 +3,40 @@
import { Record as ImmutableRecord } from "immutable";
const severitiesType = ImmutableRecord({
- "Critical": "Danger",
- "Warning": "Warning",
- "Info": "Success"
+ Critical: "Danger",
+ Warning: "Warning",
+ Info: "Success"
} as Record<string, "Danger" | "Warning" | "Success">);
const severities = severitiesType();
-export default async function(type: string, guild: string, message: string | true, severity: "Critical" | "Warning" | "Info" = "Info") {
+export default async function (
+ type: string,
+ guild: string,
+ message: string | true,
+ severity: "Critical" | "Warning" | "Info" = "Info"
+) {
const data = await client.database.guilds.read(guild);
if (message === true) {
- return await client.database.guilds.write(guild, {[`singleEventNotifications.${type}`]: false});
+ return await client.database.guilds.write(guild, {
+ [`singleEventNotifications.${type}`]: false
+ });
}
if (data.singleEventNotifications[type]) return;
- await client.database.guilds.write(guild, {[`singleEventNotifications.${type}`]: true});
+ await client.database.guilds.write(guild, {
+ [`singleEventNotifications.${type}`]: true
+ });
try {
const channel = await client.channels.fetch(data.logging.staff.channel);
if (!channel) return;
- await channel.send({embeds: [new EmojiEmbed()
- .setTitle(`${severity} notification`)
- .setDescription(message)
- .setStatus(severities.get(severity))
- .setEmoji("CONTROL.BLOCKCROSS")
- ]});
+ await channel.send({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle(`${severity} notification`)
+ .setDescription(message)
+ .setStatus(severities.get(severity))
+ .setEmoji("CONTROL.BLOCKCROSS")
+ ]
+ });
} catch (err) {
console.error(err);
}
diff --git a/src/utils/temp/generateFileName.ts b/src/utils/temp/generateFileName.ts
index 8a219b7..956f1d7 100644
--- a/src/utils/temp/generateFileName.ts
+++ b/src/utils/temp/generateFileName.ts
@@ -2,7 +2,7 @@
import * as crypto from "crypto";
import client from "../client.js";
import * as path from "path";
-import {fileURLToPath} from "url";
+import { fileURLToPath } from "url";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
@@ -12,6 +12,10 @@
if (fs.existsSync(`./${fileName}`)) {
fileName = generateFileName(ending);
}
- client.database.eventScheduler.schedule("deleteFile", new Date().getTime() + (60 * 1000), {fileName: `${fileName}.${ending}`});
+ client.database.eventScheduler.schedule(
+ "deleteFile",
+ new Date().getTime() + 60 * 1000,
+ { fileName: `${fileName}.${ending}` }
+ );
return path.join(__dirname, fileName + "." + ending);
}