fixed up a few commands

pull/17/head
PineaFan 3 years ago
parent 7a9ad4b176
commit 9b2ac4d68d
No known key found for this signature in database
GPG Key ID: D404018735F488C9

@ -1,3 +1,4 @@
import { getCommandMentionByName } from './../utils/getCommandMentionByName.js';
import Discord, { ActionRowBuilder, ButtonBuilder, OverwriteType, ChannelType, ButtonStyle } from "discord.js"; import Discord, { ActionRowBuilder, ButtonBuilder, OverwriteType, ChannelType, ButtonStyle } from "discord.js";
import EmojiEmbed from "../utils/generateEmojiEmbed.js"; import EmojiEmbed from "../utils/generateEmojiEmbed.js";
import getEmojiByName from "../utils/getEmojiByName.js"; import getEmojiByName from "../utils/getEmojiByName.js";
@ -62,7 +63,7 @@ export async function create(
`**Support type:** ${customReason ? customReason : "Appeal submission"}\n` + `**Support type:** ${customReason ? customReason : "Appeal submission"}\n` +
(reason !== null ? `**Reason:**\n> ${reason}\n` : "") + (reason !== null ? `**Reason:**\n> ${reason}\n` : "") +
`**Ticket ID:** \`${c.id}\`\n` + `**Ticket ID:** \`${c.id}\`\n` +
"Type `/ticket close` to close this ticket." `Type ${getCommandMentionByName("ticket/close")} to close this ticket.`
) )
.setStatus("Success") .setStatus("Success")
.setEmoji("GUILD.TICKET.OPEN") .setEmoji("GUILD.TICKET.OPEN")

@ -1,5 +1,5 @@
import { getCommandMentionByName } from '../../utils/getCommandMentionByName.js'; import { getCommandMentionByName } from '../../utils/getCommandMentionByName.js';
import Discord, { ActionRowBuilder, ButtonBuilder, ButtonInteraction, PrivateThreadChannel, TextChannel, ButtonStyle } from "discord.js"; import Discord, { ActionRowBuilder, ButtonBuilder, ButtonInteraction, PrivateThreadChannel, TextChannel, ButtonStyle, CategoryChannel } from "discord.js";
import client from "../../utils/client.js"; import client from "../../utils/client.js";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js"; import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import getEmojiByName from "../../utils/getEmojiByName.js"; import getEmojiByName from "../../utils/getEmojiByName.js";
@ -142,47 +142,60 @@ export default async function (interaction: Discord.CommandInteraction | ButtonI
async function purgeByUser(member: string, guild: string) { async function purgeByUser(member: string, guild: string) {
const config = await client.database.guilds.read(guild.id); const config = await client.database.guilds.read(guild);
const fetchedGuild = await client.guilds.fetch(guild); const fetchedGuild = await client.guilds.fetch(guild);
if (!config.tickets.category) return; if (!config.tickets.category) return;
const tickets = fetchedGuild.channels.cache.get(config.tickets.category); const tickets: CategoryChannel | TextChannel | undefined = fetchedGuild.channels.cache.get(config.tickets.category) as CategoryChannel | TextChannel | undefined;
if (!tickets) return; if (!tickets) return;
const ticketChannels = tickets.children;
let deleted = 0; let deleted = 0;
ticketChannels.forEach((element) => { if (tickets.type === Discord.ChannelType.GuildCategory) {
if (element.type !== "GUILD_TEXT") return; // For channels, the topic is the user ID, then the word Active
if (element.topic.split(" ")[0] === member) { const category = tickets as Discord.CategoryChannel;
category.children.cache.forEach((element) => {
if (!(element.type === Discord.ChannelType.GuildText)) return;
if (!(((element as Discord.TextChannel).topic ?? "").includes(member))) return;
try { try {
element.delete(); element.delete();
} catch { deleted++;
/* Errors if the channel does not exist (deleted already) */ } catch (e) {
console.error(e);
} }
deleted++; });
} } else {
}); // For threads, the name is the users name, id, then the word Active
if (deleted) { const channel = tickets as Discord.TextChannel;
const { log, NucleusColors, entry, renderUser, renderDelta } = member.client.logger; channel.threads.cache.forEach((element: Discord.ThreadChannel) => {
const data = { if (!element.name.includes(member)) return;
meta: { try {
type: "ticketPurge", element.delete();
displayName: "Tickets Purged", deleted++;
calculateType: "ticketUpdate", } catch (e) {
color: NucleusColors.red, console.error(e);
emoji: "GUILD.TICKET.DELETE",
timestamp: new Date().getTime()
},
list: {
ticketFor: entry(member, renderUser(member)),
deletedBy: entry(null, "Member left server"),
deleted: entry(new Date().getTime(), renderDelta(new Date().getTime())),
ticketsDeleted: deleted
},
hidden: {
guild: guild.id
} }
}; });
log(data);
} }
if (!deleted) return
const { log, NucleusColors, entry, renderUser, renderDelta } = client.logger;
const data = {
meta: {
type: "ticketPurge",
displayName: "Tickets Purged",
calculateType: "ticketUpdate",
color: NucleusColors.red,
emoji: "GUILD.TICKET.DELETE",
timestamp: new Date().getTime()
},
list: {
ticketFor: entry(member, renderUser(member)),
deletedBy: entry(null, "Member left server"),
deleted: entry(new Date().getTime(), renderDelta(new Date().getTime())),
ticketsDeleted: deleted
},
hidden: {
guild: guild
}
};
log(data);
} }
export { purgeByUser }; export { purgeByUser };

@ -97,7 +97,7 @@ const callback = async (interaction: CommandInteraction): Promise<void> => {
.addComponents(new ButtonBuilder() .addComponents(new ButtonBuilder()
.setStyle(ButtonStyle.Link) .setStyle(ButtonStyle.Link)
.setLabel(config.moderation.ban.text) .setLabel(config.moderation.ban.text)
.setURL(config.moderation.ban.link) .setURL(config.moderation.ban.link.replaceAll("{id}", (interaction.options.getMember("user") as GuildMember).id))
) )
) )
} }

@ -86,7 +86,7 @@ const callback = async (interaction: CommandInteraction): Promise<unknown> => {
.addComponents(new ButtonBuilder() .addComponents(new ButtonBuilder()
.setStyle(ButtonStyle.Link) .setStyle(ButtonStyle.Link)
.setLabel(config.moderation.kick.text) .setLabel(config.moderation.kick.text)
.setURL(config.moderation.kick.link) .setURL(config.moderation.kick.link.replaceAll("{id}", (interaction.options.getMember("user") as GuildMember).id))
) )
) )
} }

@ -252,7 +252,7 @@ const callback = async (interaction: CommandInteraction): Promise<unknown> => {
.addComponents(new ButtonBuilder() .addComponents(new ButtonBuilder()
.setStyle(ButtonStyle.Link) .setStyle(ButtonStyle.Link)
.setLabel(config.moderation.mute.text) .setLabel(config.moderation.mute.text)
.setURL(config.moderation.mute.link) .setURL(config.moderation.mute.link.replaceAll("{id}", (interaction.options.getMember("user") as GuildMember).id))
) )
) )
}; };

@ -97,7 +97,7 @@ const callback = async (interaction: CommandInteraction): Promise<void> => {
.addComponents(new ButtonBuilder() .addComponents(new ButtonBuilder()
.setStyle(ButtonStyle.Link) .setStyle(ButtonStyle.Link)
.setLabel(config.moderation.softban.text) .setLabel(config.moderation.softban.text)
.setURL(config.moderation.softban.link) .setURL(config.moderation.softban.link.replaceAll("{id}", (interaction.options.getMember("user") as GuildMember).id))
) )
) )
} }

@ -99,7 +99,7 @@ const callback = async (interaction: CommandInteraction): Promise<unknown> => {
.addComponents(new ButtonBuilder() .addComponents(new ButtonBuilder()
.setStyle(ButtonStyle.Link) .setStyle(ButtonStyle.Link)
.setLabel(config.moderation.warn.text) .setLabel(config.moderation.warn.text)
.setURL(config.moderation.warn.link) .setURL(config.moderation.warn.link.replaceAll("{id}", (interaction.options.getMember("user") as GuildMember).id))
) )
) )
} }

@ -1,5 +1,5 @@
import { LoadingEmbed } from "../../utils/defaults.js"; import { LoadingEmbed } from "../../utils/defaults.js";
import Discord, { CommandInteraction, ActionRowBuilder, ButtonBuilder, TextInputComponent, Role, ButtonStyle, ButtonComponent, TextInputBuilder } from "discord.js"; import Discord, { CommandInteraction, ActionRowBuilder, ButtonBuilder, Role, ButtonStyle, ButtonComponent, TextInputBuilder } from "discord.js";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js"; import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import getEmojiByName from "../../utils/getEmojiByName.js"; import getEmojiByName from "../../utils/getEmojiByName.js";
import type { SlashCommandSubcommandBuilder } from "@discordjs/builders"; import type { SlashCommandSubcommandBuilder } from "@discordjs/builders";
@ -43,7 +43,7 @@ const callback = async (interaction: CommandInteraction): Promise<unknown> => {
let timedOut = false; let timedOut = false;
while (!timedOut) { while (!timedOut) {
const config = await client.database.guilds.read(interaction.guild!.id); const config = await client.database.guilds.read(interaction.guild!.id);
const moderation = config["moderation"]; const moderation = config.moderation;
m = await interaction.editReply({ m = await interaction.editReply({
embeds: [ embeds: [
new EmojiEmbed() new EmojiEmbed()
@ -117,7 +117,7 @@ const callback = async (interaction: CommandInteraction): Promise<unknown> => {
continue; continue;
} }
type modIDs = "mute" | "kick" | "ban" | "softban" | "warn" | "role"; type modIDs = "mute" | "kick" | "ban" | "softban" | "warn" | "role";
let chosen = moderation[i.customId as modIDs] ?? { text: null, url: null }; let chosen = moderation[i.customId as modIDs];
if ((i.component as ButtonComponent).customId === "clearMuteRole") { if ((i.component as ButtonComponent).customId === "clearMuteRole") {
i.deferUpdate(); i.deferUpdate();
if (clicked === "clearMuteRole") { if (clicked === "clearMuteRole") {
@ -181,31 +181,28 @@ const callback = async (interaction: CommandInteraction): Promise<unknown> => {
]) ])
] ]
}); });
let out: Discord.ModalSubmitInteraction; let out: Discord.ModalSubmitInteraction | null;
try { try {
out = await modalInteractionCollector( out = await modalInteractionCollector(
m, m,
(m) => m.channel!.id === interaction.channel!.id, (m) => m.channel!.id === interaction.channel!.id,
(_) => true (_) => true
) as Discord.ModalSubmitInteraction; ) as Discord.ModalSubmitInteraction | null;
} catch (e) { } catch (e) {
continue; continue;
} }
if ((out!).fields) { if (!out) continue
const buttonText = out.fields.getTextInputValue("name"); 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; const current = chosen;
if (current.text !== buttonText || current.link !== buttonLink) { if (current.text !== buttonText || current.link !== buttonLink) {
chosen = { text: buttonText, link: buttonLink }; chosen = { text: buttonText, link: buttonLink };
await client.database.guilds.write(interaction.guild!.id, { await client.database.guilds.write(interaction.guild!.id, {
["moderation." + i.customId]: { ["moderation." + i.customId]: {
text: buttonText, text: buttonText,
link: buttonLink link: buttonLink
} }
}); });
}
} else {
continue;
} }
} }
} }

@ -20,7 +20,8 @@ const command = (builder: SlashCommandSubcommandBuilder) =>
.setAutocomplete(true) .setAutocomplete(true)
); );
const callback = async (interaction: CommandInteraction): Promise<unknown> => { const callback = async (interaction: CommandInteraction): Promise<unknown> => { // TODO: This command feels unintuitive. Clicking a channel in the select menu deletes it
// instead, it should give a submenu to edit the channel, enable/disable or delete it
singleNotify("statsChannelDeleted", interaction.guild!.id, true); singleNotify("statsChannelDeleted", interaction.guild!.id, true);
const m = (await interaction.reply({ const m = (await interaction.reply({
embeds: LoadingEmbed, embeds: LoadingEmbed,
@ -30,7 +31,7 @@ const callback = async (interaction: CommandInteraction): Promise<unknown> => {
let config = await client.database.guilds.read(interaction.guild!.id); let config = await client.database.guilds.read(interaction.guild!.id);
if (interaction.options.get("name")?.value as string) { if (interaction.options.get("name")?.value as string) {
let channel; let channel;
if (Object.keys(config["stats"]).length >= 25) { if (Object.keys(config.stats).length >= 25) {
return await interaction.editReply({ return await interaction.editReply({
embeds: [ embeds: [
new EmojiEmbed() new EmojiEmbed()
@ -151,7 +152,7 @@ const callback = async (interaction: CommandInteraction): Promise<unknown> => {
let timedOut = false; let timedOut = false;
while (!timedOut) { while (!timedOut) {
config = await client.database.guilds.read(interaction.guild!.id); config = await client.database.guilds.read(interaction.guild!.id);
const stats = config["stats"]; const stats = config.stats;
const selectMenu = new StringSelectMenuBuilder() const selectMenu = new StringSelectMenuBuilder()
.setCustomId("remove") .setCustomId("remove")
.setMinValues(1) .setMinValues(1)

@ -82,10 +82,6 @@
"EDIT": "951957316071223336", "EDIT": "951957316071223336",
"DELETE": "729064530981683200" "DELETE": "729064530981683200"
}, },
"STORE": {
"CREATE": "729064530709315715",
"DELETE": "729064530768035922"
},
"CATEGORY": { "CATEGORY": {
"CREATE": "787987508465238026", "CREATE": "787987508465238026",
"EDIT": "787987508565770300", "EDIT": "787987508565770300",

@ -1,5 +1,7 @@
import { import {
AuditLogEvent,
BaseGuildTextChannel, BaseGuildTextChannel,
ChannelType,
GuildAuditLogsEntry, GuildAuditLogsEntry,
GuildBasedChannel, GuildBasedChannel,
StageChannel, StageChannel,
@ -13,34 +15,47 @@ export const event = "channelDelete";
export async function callback(client: NucleusClient, channel: GuildBasedChannel) { export async function callback(client: NucleusClient, channel: GuildBasedChannel) {
const { getAuditLog, log, NucleusColors, entry, renderDelta, renderUser } = client.logger; const { getAuditLog, log, NucleusColors, entry, renderDelta, renderUser } = client.logger;
// const audit = auditLog.entries.filter((entry: GuildAuditLogsEntry) => entry.target!.id === channel.id).first();
const auditLog = await getAuditLog(channel.guild, "CHANNEL_DELETE"); const auditLog = (await getAuditLog(channel.guild, AuditLogEvent.ChannelDelete))
const audit = auditLog.entries.filter((entry: GuildAuditLogsEntry) => entry.target!.id === channel.id).first(); .filter((entry: GuildAuditLogsEntry) => (entry.target as GuildBasedChannel)!.id === channel.id)[0];
if (audit.executor.id === client.user.id) return; if (!auditLog) return;
if (auditLog.executor!.id === client.user!.id) return;
let emoji; let emoji;
let readableType; let readableType;
let displayName; let displayName;
switch (channel.type) { switch (channel.type) {
case "GUILD_TEXT": { case ChannelType.GuildText: {
emoji = "CHANNEL.TEXT.DELETE"; emoji = "CHANNEL.TEXT.DELETE";
readableType = "Text"; readableType = "Text";
displayName = "Text Channel"; displayName = "Text Channel";
break; break;
} } case ChannelType.GuildAnnouncement: {
case "GUILD_VOICE": { emoji = "CHANNEL.TEXT.DELETE";
readableType = "Announcement";
displayName = "Announcement Channel";
break;
} case ChannelType.GuildVoice: {
emoji = "CHANNEL.VOICE.DELETE"; emoji = "CHANNEL.VOICE.DELETE";
readableType = "Voice"; readableType = "Voice";
displayName = "Voice Channel"; displayName = "Voice Channel";
break; break;
} } case ChannelType.GuildCategory: {
case "GUILD_CATEGORY": {
emoji = "CHANNEL.CATEGORY.DELETE"; emoji = "CHANNEL.CATEGORY.DELETE";
readableType = "Category"; readableType = "Category";
displayName = "Category"; displayName = "Category";
break; break;
} } case ChannelType.GuildStageVoice: {
default: { emoji = "CHANNEL.VOICE.DELETE";
readableType = "Stage";
displayName = "Stage Channel";
break;
} case ChannelType.GuildForum: {
emoji = "CHANNEL.TEXT.DELETE";
readableType = "Forum";
displayName = "Forum Channel";
break;
} default: {
emoji = "CHANNEL.TEXT.DELETE"; emoji = "CHANNEL.TEXT.DELETE";
readableType = "Channel"; readableType = "Channel";
displayName = "Channel"; displayName = "Channel";
@ -66,9 +81,9 @@ export async function callback(client: NucleusClient, channel: GuildBasedChannel
channel.parent ? channel.parent.name : "Uncategorised" channel.parent ? channel.parent.name : "Uncategorised"
), ),
nsfw: null, 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())), deleted: entry(new Date().getTime(), renderDelta(new Date().getTime())),
deletedBy: entry(audit.executor.id, renderUser(audit.executor)) deletedBy: entry(auditLog.executor!.id, renderUser(auditLog.executor!))
}; };
if ((channel instanceof BaseGuildTextChannel || channel instanceof StageChannel) && channel.topic !== null) if ((channel instanceof BaseGuildTextChannel || channel instanceof StageChannel) && channel.topic !== null)
list.topic = entry(channel.topic, `\`\`\`\n${channel.topic.replace("`", "'")}\n\`\`\``); list.topic = entry(channel.topic, `\`\`\`\n${channel.topic.replace("`", "'")}\n\`\`\``);
@ -94,7 +109,7 @@ export async function callback(client: NucleusClient, channel: GuildBasedChannel
calculateType: "channelUpdate", calculateType: "channelUpdate",
color: NucleusColors.red, color: NucleusColors.red,
emoji: emoji, emoji: emoji,
timestamp: audit.createdTimestamp timestamp: auditLog.createdTimestamp
}, },
list: list, list: list,
hidden: { hidden: {

@ -1,14 +1,17 @@
import type { ButtonInteraction, ContextMenuCommandInteraction } from 'discord.js';
import type { CommandInteraction } from 'discord.js';
import type { NucleusClient } from "../utils/client.js";
import EmojiEmbed from "../utils/generateEmojiEmbed.js"; import EmojiEmbed from "../utils/generateEmojiEmbed.js";
export const event = "commandError"; export const event = "commandError";
export async function callback(client, interaction, error) { export async function callback(_: NucleusClient, interaction: CommandInteraction | ButtonInteraction | ContextMenuCommandInteraction, error: string) {
if (interaction.replied || interaction.deferred) { if (interaction.replied || interaction.deferred) {
await interaction.followUp({ await interaction.followUp({
embeds: [ embeds: [
new EmojiEmbed() new EmojiEmbed()
.setTitle("Something went wrong") .setTitle("Something went wrong")
.setDescription(error.message ?? error.toString()) .setDescription(error)
.setStatus("Danger") .setStatus("Danger")
.setEmoji("CONTROL.BLOCKCROSS") .setEmoji("CONTROL.BLOCKCROSS")
], ],
@ -19,7 +22,7 @@ export async function callback(client, interaction, error) {
embeds: [ embeds: [
new EmojiEmbed() new EmojiEmbed()
.setTitle("Something went wrong") .setTitle("Something went wrong")
.setDescription(error.message ?? error.toString()) .setDescription(error)
.setStatus("Danger") .setStatus("Danger")
.setEmoji("CONTROL.BLOCKCROSS") .setEmoji("CONTROL.BLOCKCROSS")
], ],

@ -25,7 +25,7 @@ export const Logger = {
const delta = num2 - num1; const delta = num2 - num1;
return `${num1} -> ${num2} (${delta > 0 ? "+" : ""}${delta})`; return `${num1} -> ${num2} (${delta > 0 ? "+" : ""}${delta})`;
}, },
entry(value: string | number | null, displayValue: string): { value: string | null; displayValue: string } { entry(value: string | number | boolean | null, displayValue: string): { value: string | boolean | null; displayValue: string } {
if (typeof value === "number") value = value.toString(); if (typeof value === "number") value = value.toString();
return { value: value, displayValue: displayValue }; return { value: value, displayValue: displayValue };
}, },

@ -14,5 +14,5 @@
"noImplicitReturns": false "noImplicitReturns": false
}, },
"include": ["src/**/*"], "include": ["src/**/*"],
"exclude": [] "exclude": ["src/Unfinished/**/*"]
} }

Loading…
Cancel
Save