Added options for stats channels, moderation command buttons and fixed the updating of stats channels
diff --git a/TODO.json b/TODO.json
index d95afcb..44bb7e6 100644
--- a/TODO.json
+++ b/TODO.json
@@ -2,12 +2,7 @@
"logging": {
"logs": {
"enabled": true,
- "toLog": "3fffff",
- "ignore": {
- "users": [],
- "roles": [],
- "channels": []
- }
+ "toLog": "3fffff"
}
},
"filters": {
@@ -19,16 +14,8 @@
"wordFilter": {
"enabled": true,
"words": {
- "strict": [
- "meat",
- "noon"
- ],
+ "strict": [],
"loose": []
- },
- "allowed": {
- "users": [],
- "roles": [],
- "channels": []
}
},
"invite": {
@@ -42,51 +29,13 @@
"pings": {
"mass": 5,
"everyone": true,
- "roles": true,
- "allowed": {
- "roles": [],
- "rolesToMention": [],
- "users": [],
- "channels": []
- }
- }
- },
- "moderation": {
- "mute": {
- "timeout": true,
- "role": "934941408849186856",
- "text": null,
- "link": null
- },
- "kick": {
- "text": null,
- "link": null
- },
- "ban": {
- "text": null,
- "link": null
- },
- "softban": {
- "text": null,
- "link": null
- },
- "warn": {
- "text": "Test",
- "link": "https://google.com"
- },
- "role": {
- "role": null
+ "roles": true
}
},
"roleMenu": [],
- "stats": [],
"tracks": [],
"welcome": {
"enabled": false,
- "verificationRequired": {
- "message": null,
- "role": null
- },
"welcomeRole": null,
"channel": null,
"message": null
diff --git a/src/commands/settings/commands.ts b/src/commands/settings/commands.ts
new file mode 100644
index 0000000..df2cdb4
--- /dev/null
+++ b/src/commands/settings/commands.ts
@@ -0,0 +1,144 @@
+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";
+import { WrappedCheck } from "jshaiku";
+import client from "../../utils/client.js";
+import { modalInteractionCollector } from "../../utils/dualCollector.js";
+import confirmationMessage from "../../utils/confirmationMessage.js";
+import keyValueList from "../../utils/generateKeyValueList.js";
+
+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"))
+
+const callback = async (interaction: CommandInteraction): Promise<any> => {
+ await interaction.reply({embeds: [new EmojiEmbed()
+ .setTitle("Loading")
+ .setStatus("Danger")
+ .setEmoji("NUCLEUS.LOADING")
+ ], ephemeral: true, fetchReply: true});
+ let m;
+ let clicked = "";
+ if (interaction.options.getRole("role")) {
+ let confirmation = await new confirmationMessage(interaction)
+ .setEmoji("GUILD.ROLES.DELETE")
+ .setTitle("Moderation Commands")
+ .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.success) {
+ await client.database.guilds.write(interaction.guild.id, {["moderation.mute.role"]: interaction.options.getRole("role").id});
+ }
+ }
+ while (true) {
+ let config = await client.database.guilds.read(interaction.guild.id);
+ let 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 warned, banned, etc.\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};
+ if (i.component.customId === "clearMuteRole") {
+ if (clicked === "clearMuteRole") {
+ await client.database.guilds.write(interaction.guild.id, { moderation: { mute: { role: null } } });
+ } else { clicked = "clearMuteRole" }
+ } else { clicked = "" }
+ if (i.component.customId === "timeout") {
+ await i.deferUpdate()
+ await client.database.guilds.write(interaction.guild.id, { moderation: { mute: { timeout: !moderation.mute.timeout } } });
+ } 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 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")
+ ])]
+ });
+ let out;
+ try {
+ out = await modalInteractionCollector(m, (m) => m.channel.id == interaction.channel.id, (m) => true)
+ } catch (e) { continue }
+ if (out.fields) {
+ let buttonText = out.fields.getTextInputValue("name");
+ let buttonLink = out.fields.getTextInputValue("url").replace(/{id}/gi, "{id}");
+ let current = chosen;
+ 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 }});
+ }
+ } else { continue }
+ }
+ }
+}
+
+
+const check = (interaction: CommandInteraction, defaultCheck: WrappedCheck) => {
+ let 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
diff --git a/src/commands/settings/logs/ignore.ts b/src/commands/settings/logs/ignore.ts
deleted file mode 100644
index 59f6621..0000000
--- a/src/commands/settings/logs/ignore.ts
+++ /dev/null
@@ -1,144 +0,0 @@
-import { ChannelType } from 'discord-api-types';
-import Discord, { CommandInteraction } from "discord.js";
-import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
-import EmojiEmbed from "../../../utils/generateEmojiEmbed.js";
-import { WrappedCheck } from "jshaiku";
-import confirmationMessage from '../../../utils/confirmationMessage.js';
-import keyValueList from '../../../utils/generateKeyValueList.js';
-import client from '../../../utils/client.js';
-
-const command = (builder: SlashCommandSubcommandBuilder) =>
- builder
- .setName("ignore")
- .setDescription("Sets which users, channels and roles should be ignored")
- .addStringOption(o => o.setName("action").setDescription("Add or remove from the list").addChoices([
- ["Add", "add"], ["Remove", "remove"]
- ]).setRequired(true))
- .addChannelOption(o => o.setName("addchannel").setDescription("Add a channel that should be ignored").addChannelTypes([
- ChannelType.GuildText, ChannelType.GuildVoice, ChannelType.GuildNews, ChannelType.GuildPublicThread, ChannelType.GuildPrivateThread, ChannelType.GuildNewsThread
- ]))
- .addUserOption(o => o.setName("adduser").setDescription("Add a user that should be ignored"))
- .addRoleOption(o => o.setName("addrole").setDescription("Add a role that should be ignored"))
-
-const callback = async (interaction: CommandInteraction): Promise<any> => {
- let channel = interaction.options.getChannel("addchannel")
- let user = interaction.options.getUser("adduser")
- let role = interaction.options.getRole("addrole")
- await interaction.reply({embeds: [new EmojiEmbed()
- .setTitle("Loading")
- .setStatus("Danger")
- .setEmoji("NUCLEUS.LOADING")
- ], ephemeral: true, fetchReply: true});
- if (channel || user || role) {
- if (channel) {
- try {
- channel = interaction.guild.channels.cache.get(channel.id)
- } catch {
- return await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("CHANNEL.TEXT.DELETE")
- .setTitle("Logs > Ignore")
- .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("Logs > Ignore")
- .setDescription(`You must choose a channel in this server`)
- .setStatus("Danger")
- .setEmoji("CHANNEL.TEXT.DELETE")
- ]});
- }
- }
- if (user) {
- try {
- user = interaction.guild.members.cache.get(user.id).user
- } catch {
- return await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("USER.DELETE")
- .setTitle("Logs > Ignore")
- .setDescription("The user you provided is not a valid user")
- .setStatus("Danger")
- ]})
- }
- user = user as Discord.User
- }
- if (role) {
- try {
- role = interaction.guild.roles.cache.get(role.id)
- } catch {
- return await interaction.editReply({embeds: [new EmojiEmbed()
- .setEmoji("ROLE.DELETE")
- .setTitle("Logs > Ignore")
- .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("Logs > Ignore")
- .setDescription(`You must choose a role in this server`)
- .setStatus("Danger")
- .setEmoji("ROLE.DELETE")
- ]});
- }
- }
- let changes = {}
- if (channel) changes["channel"] = channel.id
- if (user) changes["user"] = user.id
- if (role) changes["role"] = role.id
- let confirmation = await new confirmationMessage(interaction)
- .setEmoji("NUCLEUS.COMMANDS.IGNORE")
- .setTitle("Logs > Ignore")
- .setDescription(keyValueList(changes)
- + `Are you sure you want to **${interaction.options.getString("action") == "add" ? "add" : "remove"}** these to the ignore list?`)
- .setColor("Warning")
- .send(true)
- if (confirmation.cancelled) return
- if (confirmation.success) {
- let data = client.database.guilds.read(interaction.guild.id)
- if (channel) data.logging.logs.ignore.channels.concat([channel.id])
- if (user) data.logging.logs.ignore.users.concat([user.id])
- if (role) data.logging.logs.ignore.roles.concat([role.id])
- if (interaction.options.getString("action") == "add") {
- await client.database.guilds.append(interaction.guild.id, data)
- } else {
- await client.database.guilds.remove(interaction.guild.id, data)
- }
- const { log, NucleusColors, entry, renderUser, renderChannel } = client.logger
- try {
- let data = {
- meta:{
- type: 'logIgnoreUpdated',
- displayName: 'Ignored Groups Changed',
- calculateType: 'nucleusSettingsUpdated',
- color: NucleusColors.yellow,
- emoji: "CHANNEL.TEXT.EDIT",
- timestamp: new Date().getTime()
- },
- list: {
- memberId: entry(interaction.user.id, `\`${interaction.user.id}\``),
- changedBy: entry(interaction.user.id, renderUser(interaction.user)),
- channel: entry(channel.id, renderChannel(channel)),
- },
- hidden: {
- guild: interaction.guild.id
- }
- }
- log(data);
- } catch {}
- }
- }
-}
-
-const check = (interaction: CommandInteraction, defaultCheck: WrappedCheck) => {
- let 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
diff --git a/src/commands/settings/stats/set.ts b/src/commands/settings/stats.ts
similarity index 62%
rename from src/commands/settings/stats/set.ts
rename to src/commands/settings/stats.ts
index 10c3011..3159e2d 100644
--- a/src/commands/settings/stats/set.ts
+++ b/src/commands/settings/stats.ts
@@ -1,33 +1,29 @@
import { ChannelType } from 'discord-api-types';
-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 { SlashCommandSubcommandBuilder } from "@discordjs/builders";
+import Discord, { AutocompleteInteraction, CommandInteraction, Message, MessageActionRow, MessageButton, MessageSelectMenu } from "discord.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import confirmationMessage from "../../utils/confirmationMessage.js";
+import getEmojiByName from "../../utils/getEmojiByName.js";
+import { SelectMenuOption, 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 client from "../../utils/client.js";
+import convertCurlyBracketString from '../../utils/convertCurlyBracketString.js';
+import {callback as statsChannelAddCallback} from "../../reflex/statsChannelUpdate.js";
const command = (builder: SlashCommandSubcommandBuilder) =>
builder
- .setName("set")
- .setDescription("Adds or edits a channel which will update when members join or leave")
- .addChannelOption(option => option.setName("channel").setDescription("The channel to modify").addChannelTypes([
- ChannelType.GuildNews, ChannelType.GuildText
- ]).setRequired(true))
- .addStringOption(option => option.setName("name").setDescription("The channel name").setRequired(true).setAutocomplete(true))
+ .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))
const callback = async (interaction: CommandInteraction): Promise<any> => {
- console.log(interaction.options.getString("name"))
let m;
m = await interaction.reply({embeds: [new EmojiEmbed()
.setTitle("Loading")
.setStatus("Danger")
.setEmoji("NUCLEUS.LOADING")
], ephemeral: true, fetchReply: true});
- if (interaction.options.getChannel("channel")) {
- let config = client.database.guilds.read(interaction.guild.id);
+ if (interaction.options.getString("name")) {
let channel
try {
channel = interaction.options.getChannel("channel")
@@ -106,13 +102,47 @@
], components: []});
}
await statsChannelAddCallback(client, interaction.member);
- return interaction.editReply({embeds: [new EmojiEmbed()
+ }
+ while (true) {
+ let config = await client.database.guilds.read(interaction.guild.id);
+ let stats = config.getKey("stats")
+ let selectMenu = new MessageSelectMenu()
+ .setCustomId("remove")
+ .setMinValues(1)
+ .setMaxValues(Math.max(1, Object.keys(stats).length))
+ await interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Stats Channel")
- .setDescription(`The stats channel has been set to <#${channel.id}>`)
+ .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: []});
+ ], 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 }
+ i.deferUpdate()
+ if (i.customId === "remove") {
+ let toRemove = i.values;
+ console.log(toRemove.map(k => `stats.${k}`))
+ await client.database.guilds.write(interaction.guild.id, {}, toRemove.map(k => `stats.${k}`));
+ }
}
+ 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("Danger")
+ .setEmoji("CHANNEL.TEXT.DELETE")
+ ], components: []})
}
const check = (interaction: CommandInteraction, defaultCheck: WrappedCheck) => {
@@ -123,4 +153,4 @@
export { command };
export { callback };
-export { check };
+export { check };
\ No newline at end of file
diff --git a/src/commands/settings/stats/_meta.ts b/src/commands/settings/stats/_meta.ts
deleted file mode 100644
index 7443a9e..0000000
--- a/src/commands/settings/stats/_meta.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-const name = "stats";
-const description = "Settings for stats channels";
-
-export { name, description };
\ No newline at end of file
diff --git a/src/commands/settings/stats/remove.ts b/src/commands/settings/stats/remove.ts
deleted file mode 100644
index 8e3a64a..0000000
--- a/src/commands/settings/stats/remove.ts
+++ /dev/null
@@ -1,120 +0,0 @@
-import { ChannelType } from 'discord-api-types';
-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 { SlashCommandSubcommandBuilder } from "@discordjs/builders";
-import { WrappedCheck } from "jshaiku";
-import client from "../../../utils/client.js";
-
-const command = (builder: SlashCommandSubcommandBuilder) =>
- builder
- .setName("remove")
- .setDescription("Stops updating channels when a member joins or leaves")
- .addChannelOption(option => option.setName("channel").setDescription("The channel to stop updating").addChannelTypes([
- ChannelType.GuildNews, ChannelType.GuildText
- ]).setRequired(true))
-
-const callback = async (interaction: CommandInteraction): Promise<any> => {
- let m;
- m = await interaction.reply({embeds: [new EmojiEmbed()
- .setTitle("Loading")
- .setStatus("Danger")
- .setEmoji("NUCLEUS.LOADING")
- ], ephemeral: true, fetchReply: true});
- if (interaction.options.getChannel("channel")) {
- let config = client.database.guilds.read(interaction.guild.id);
- let channel
- 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")
- ]})
- }
- 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")
- ]});
- }
- // check if the channel is not in the list
- let allow = false;
- for (let c of config.stats) { if (c.channel == channel.id) allow = true; }
- if (!allow) {
- return interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Stats Channel")
- .setDescription(`That channel is not a stats channel`)
- .setStatus("Danger")
- .setEmoji("CHANNEL.TEXT.DELETE")
- ]});
- }
- let confirmation = await new confirmationMessage(interaction)
- .setEmoji("CHANNEL.TEXT.EDIT")
- .setTitle("Stats Channel")
- .setDescription(`Are you sure you want to stop <#${channel.id}> updating?`)
- .setColor("Warning")
- .setInverted(true)
- .send(true)
- if (confirmation.cancelled) return
- if (confirmation.success) {
- try {
- let channel = interaction.options.getChannel("channel")
- await client.database.guilds.write(interaction.guild.id, {}, [`stats.${channel.id}`]);
- const { log, NucleusColors, entry, renderUser, renderChannel } = client.logger
- try {
- let data = {
- meta:{
- type: 'statsChannelUpdate',
- displayName: 'Stats Channel Removed',
- calculateType: 'nucleusSettingsUpdated',
- color: NucleusColors.red,
- emoji: "CHANNEL.TEXT.EDIT",
- timestamp: new Date().getTime()
- },
- list: {
- memberId: entry(interaction.user.id, `\`${interaction.user.id}\``),
- changedBy: entry(interaction.user.id, renderUser(interaction.user)),
- channel: entry(channel.id, renderChannel(channel)),
- },
- hidden: {
- guild: interaction.guild.id
- }
- }
- log(data);
- } catch {}
- } 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 reset`)
- .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: []});
- }
- }
-}
-
-const check = (interaction: CommandInteraction, defaultCheck: WrappedCheck) => {
- let 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 };
diff --git a/src/commands/tags/delete.ts b/src/commands/tags/delete.ts
index 74ebb25..f531e93 100644
--- a/src/commands/tags/delete.ts
+++ b/src/commands/tags/delete.ts
@@ -40,8 +40,9 @@
.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")
diff --git a/src/config/default.json b/src/config/default.json
index 2f95e94..93b571f 100644
--- a/src/config/default.json
+++ b/src/config/default.json
@@ -15,11 +15,6 @@
"words": {
"strict": [],
"loose": []
- },
- "allowed": {
- "users": [],
- "roles": [],
- "channels": []
}
},
"invite": {
@@ -33,21 +28,11 @@
"pings": {
"mass": 5,
"everyone": true,
- "roles": true,
- "allowed": {
- "roles": [],
- "rolesToMention": [],
- "users": [],
- "channels": []
- }
+ "roles": true
}
},
"welcome": {
"enabled": false,
- "verificationRequired": {
- "message": null,
- "role": null
- },
"welcomeRole": null,
"channel": null,
"message": null
@@ -57,12 +42,7 @@
"logs": {
"enabled": true,
"channel": null,
- "toLog": "3fffff",
- "ignore": {
- "users": [],
- "roles": [],
- "channels": []
- }
+ "toLog": "3fffff"
},
"staff": {
"channel": null
@@ -107,8 +87,9 @@
"text": null,
"link": null
},
- "role": {
- "role": null
+ "nickname": {
+ "text": null,
+ "link": null
}
},
"tracks": [],
diff --git a/src/config/emojis.json b/src/config/emojis.json
index 7024a73..49c2b27 100644
--- a/src/config/emojis.json
+++ b/src/config/emojis.json
@@ -144,28 +144,28 @@
"PUNISH": {
"WARN": {
"RED": "947433493384806430",
- "GREEN": "947433504076091424",
- "YELLOW": "729764054897524768"
+ "YELLOW": "729764054897524768",
+ "GREEN": "947433504076091424"
},
"KICK": {
"RED": "729764053794422896",
- "GREEN": "947428786692042764",
- "YELLOW": "947429333289562132"
+ "YELLOW": "947429333289562132",
+ "GREEN": "947428786692042764"
},
"BAN": {
"RED": "729764053861400637",
- "GREEN": "947421674364629022",
- "YELLOW": "729764053941223476"
+ "YELLOW": "729764053941223476",
+ "GREEN": "947421674364629022"
},
"UNBAN": {
- "GREEN": "729263536840114216",
+ "RED": "972511610885255259",
"YELLOW": "972511620343414794",
- "RED": "972511610885255259"
+ "GREEN": "729263536840114216"
},
"MUTE": {
"RED": "947555098974883910",
- "GREEN": "947555107980066866",
- "YELLOW": "729764053865463840"
+ "YELLOW": "729764053865463840",
+ "GREEN": "947555107980066866"
},
"SOFTBAN": "729764053941223476",
"VOICEMUTE": "729764054855450697",
diff --git a/src/events/interactionCreate.ts b/src/events/interactionCreate.ts
index 900c774..eaf4fea 100644
--- a/src/events/interactionCreate.ts
+++ b/src/events/interactionCreate.ts
@@ -38,7 +38,7 @@
} 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 stats set`: { return interaction.respond(generateStatsChannelAutocomplete(interaction.options.getString("name"))) }
+ case `settings null stats`: { return interaction.respond(generateStatsChannelAutocomplete(interaction.options.getString("name"))) }
}
}
}
diff --git a/src/events/memberJoin.ts b/src/events/memberJoin.ts
index 7bee084..109f226 100644
--- a/src/events/memberJoin.ts
+++ b/src/events/memberJoin.ts
@@ -7,6 +7,7 @@
export async function callback(_, member) {
try { welcome(_, member); } catch {}
+ try { statsChannelAdd(_, member, ); } catch {}
try {
const { log, NucleusColors, entry, renderUser, renderDelta } = member.client.logger
try { await client.database.history.create("join", member.guild.id, member.user, null, null) } catch {}
@@ -32,5 +33,4 @@
}
log(data);
} catch {}
- try { statsChannelAdd(_, member, ); } catch {}
}
diff --git a/src/reflex/statsChannelUpdate.ts b/src/reflex/statsChannelUpdate.ts
index 51d4329..7d04c8f 100644
--- a/src/reflex/statsChannelUpdate.ts
+++ b/src/reflex/statsChannelUpdate.ts
@@ -5,7 +5,6 @@
interface PropSchema { enabled: boolean, name: string }
export async function callback(_, member) {
- console.log("UPDATING STATS CHANNEL")
let guild = await client.guilds.fetch(member.guild.id)
let config = await client.database.guilds.read(guild.id);
Object.entries(config.getKey("stats")).forEach(async ([channel, props]) => {
diff --git a/src/utils/database.ts b/src/utils/database.ts
index 5b1d6d9..d24c7bf 100644
--- a/src/utils/database.ts
+++ b/src/utils/database.ts
@@ -43,12 +43,12 @@
async write(guild: string, set: object = {}, unset: string[] = []) {
let uo = {}
for (let key of unset) {
- uo[key] = "";
+ uo[key] = null;
}
- await this.guilds.updateOne({ id: guild }, {
- $unset: uo,
- $set: set
- }, { upsert: true });
+ let out = {}
+ if (set) out["$set"] = set;
+ if (unset.length) out["$unset"] = uo;
+ await this.guilds.updateOne({ id: guild }, out, { upsert: true });
}
async append(guild: string, key: string, value: any) {
@@ -63,13 +63,13 @@
}
}
- async remove(guild: string, key: string, value: any, innerKey?: string) {
+ 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 });
- }
- else if (Array.isArray(value)) {
+ } else if (Array.isArray(value)) {
await this.guilds.updateOne({ id: guild }, {
$pullAll: { [key]: value }
}, { upsert: true });