changed wording on guide and updated commandmentionbyname
diff --git a/TODO.json b/TODO.json
index 19d077c..8b211ef 100644
--- a/TODO.json
+++ b/TODO.json
@@ -22,21 +22,5 @@
"roles": true
}
},
- "tracks": [],
- "rolemenu": {
- "enabled": false,
- "allowWebUI": false,
- "options": [
- {
- "name": false,
- "description": false,
- "options": [
- {
- "name": false,
- "description": false
- }
- ]
- }
- ]
- }
+ "tracks": []
}
diff --git a/src/commands/privacy.ts b/src/commands/privacy.ts
index 6113cc3..e20bf34 100644
--- a/src/commands/privacy.ts
+++ b/src/commands/privacy.ts
@@ -22,8 +22,8 @@
.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)."
+ "If you are a server administrator, you can view the options page in the dropdown under this message.\n\n" + // TODO
+ "Any questions about Nucleus, how it works, and what data is stored can be asked in [our server](https://discord.gg/bPaNnxe)."
)
.setEmoji("NUCLEUS.LOGO")
.setStatus("Danger")
diff --git a/src/commands/settings/logs/channel.ts b/src/commands/settings/logs/channel.ts
index b9b593c..afd7735 100644
--- a/src/commands/settings/logs/channel.ts
+++ b/src/commands/settings/logs/channel.ts
@@ -9,7 +9,7 @@
const command = (builder: SlashCommandSubcommandBuilder) =>
builder
- .setName("channel")
+ .setName("general")
.setDescription("Sets or shows the log channel")
.addChannelOption((option) =>
option
diff --git a/src/commands/settings/logs/events.ts b/src/commands/settings/logs/events.ts
index 40b4607..1249d2b 100644
--- a/src/commands/settings/logs/events.ts
+++ b/src/commands/settings/logs/events.ts
@@ -31,7 +31,7 @@
const command = (builder: SlashCommandSubcommandBuilder) =>
builder.setName("events").setDescription("Sets what events should be logged");
-const callback = async (interaction: CommandInteraction): Promise<void> => {
+const callback = async (interaction: CommandInteraction): Promise<void> => { // TODO: Maybe merge this into /settings log general
await interaction.reply({
embeds: LoadingEmbed,
fetchReply: true,
diff --git a/src/commands/settings/logs/staff.ts b/src/commands/settings/logs/staff.ts
index bba6441..ba9bbba 100644
--- a/src/commands/settings/logs/staff.ts
+++ b/src/commands/settings/logs/staff.ts
@@ -9,7 +9,7 @@
const command = (builder: SlashCommandSubcommandBuilder) =>
builder
- .setName("staff")
+ .setName("warnings")
.setDescription("Settings for the staff notifications channel")
.addChannelOption((option) =>
option
diff --git a/src/reflex/guide.ts b/src/reflex/guide.ts
index 668b56d..64c4f13 100644
--- a/src/reflex/guide.ts
+++ b/src/reflex/guide.ts
@@ -1,3 +1,4 @@
+import { getCommandMentionByName } from './../utils/getCommandMentionByName.js';
import { LoadingEmbed } from "../utils/defaults.js";
import Discord, {
ActionRowBuilder,
@@ -18,32 +19,43 @@
export default async (guild: Guild, interaction?: CommandInteraction) => {
let c: GuildTextBasedChannel | null = guild.publicUpdatesChannel ? guild.publicUpdatesChannel : guild.systemChannel;
c = c
- ? c
- : (guild.channels.cache.find(
- (ch) =>
- [
- ChannelType.GuildText,
- ChannelType.GuildAnnouncement,
- ChannelType.PublicThread,
- ChannelType.PrivateThread,
- ChannelType.AnnouncementThread
- ].includes(ch.type) &&
- ch.permissionsFor(guild.roles.everyone).has("SendMessages") &&
- ch.permissionsFor(guild.members.me!).has("EmbedLinks")
- ) as GuildTextBasedChannel | undefined) ?? null;
+ ? c
+ : (guild.channels.cache.find(
+ (ch) =>
+ [
+ ChannelType.GuildText,
+ ChannelType.GuildAnnouncement,
+ ChannelType.PublicThread,
+ ChannelType.PrivateThread,
+ ChannelType.AnnouncementThread
+ ].includes(ch.type) &&
+ ch.permissionsFor(guild.roles.everyone).has("SendMessages") &&
+ ch.permissionsFor(guild.members.me!).has("EmbedLinks")
+ ) as GuildTextBasedChannel | undefined) ?? null;
if (interaction) c = interaction.channel as GuildTextBasedChannel;
if (!c) {
return;
}
+ let m: Message;
+ if (interaction) {
+ m = (await interaction.reply({
+ embeds: LoadingEmbed,
+ fetchReply: true,
+ ephemeral: true
+ })) as Message;
+ } else {
+ m = await c.send({ embeds: LoadingEmbed });
+ }
+ let page = 0;
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)"
+ "Thanks for adding Nucleus to your server!\n\n" +
+ "The next few pages will show what features Nucleus has to offer, and how to enable them.\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")
@@ -54,15 +66,17 @@
new Embed()
.setEmbed(
new EmojiEmbed()
- .setTitle("Logging")
+ .setTitle("Logs")
.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`"
+ "**General:** These are events like kicks and channel changes etc.\n" +
+ `> These are standard logs and can be set with ${await getCommandMentionByName("settings/logs/general")}\n` +
+ "**Warnings:** Warnings like NSFW avatars and spam etc. that may require action by a server staff member.\n" +
+ `> These may require special action by a moderator. You can set the channel with ${await getCommandMentionByName("settings/logs/warnings")}\n` + // TODO
+ "**Attachments:** All images sent in the server - Used to keep a record of deleted images\n" +
+ `> Sent to a separate log channel to avoid spam. This can be set with ${await getCommandMentionByName("settings/logs/attachments")}\n` +
+ `> ${getEmojiByName("NUCLEUS.PREMIUM")} Please note this feature is only available with ${await getCommandMentionByName("nucleus/premium")}`
)
.setEmoji("ICONS.LOGGING")
.setStatus("Danger")
@@ -76,27 +90,15 @@
.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.`
+ `These commands are all found under ${await getCommandMentionByName(("mod"))}, and they include:\n` +
+ `${getEmojiByName("PUNISH.WARN.YELLOW")} ${await getCommandMentionByName("mod/warn")}: The user is warned (via DM) that they violated server rules. More options given if DMs are disabled.\n` +
+ `${getEmojiByName("PUNISH.CLEARHISTORY")} ${await getCommandMentionByName("mod/purge")}: Deletes messages in a channel, giving options to only delete messages by a certain user.\n` +
+ `${getEmojiByName("PUNISH.MUTE.YELLOW")} ${await getCommandMentionByName("mod/mute")}: Stops users sending messages or joining voice chats.\n` +
+ `${getEmojiByName("PUNISH.MUTE.GREEN")} ${await getCommandMentionByName("mod/unmute")}: Allows user to send messages and join voice chats.\n` +
+ `${getEmojiByName("PUNISH.KICK.RED")} ${await getCommandMentionByName("mod/kick")}: Removes a member from the server. They will be able to rejoin.\n` +
+ `${getEmojiByName("PUNISH.SOFTBAN")} ${await getCommandMentionByName("mod/softban")}: Kicks the user, deleting their messages from every channel in a given time frame.\n` +
+ `${getEmojiByName("PUNISH.BAN.RED")} ${await getCommandMentionByName("mod/ban")}: Removes the user from the server, deleting messages from every channel and stops them from rejoining.\n` +
+ `${getEmojiByName("PUNISH.BAN.GREEN")} ${await getCommandMentionByName("mod/unban")}: Allows a member to rejoin the server after being banned.`
)
.setEmoji("PUNISH.BAN.RED")
.setStatus("Danger")
@@ -110,9 +112,9 @@
.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`"
+ `This is done by running ${await getCommandMentionByName("verify")} which sends a message only the user can see, giving them a link to a website to verify.\n` +
+ "After the user complete's the check, they are given a role, which can be set to unlock specific channels.\n" +
+ `You can set the role given with ${await getCommandMentionByName("settings/verify")}`
)
.setEmoji("CONTROL.REDTICK")
.setStatus("Danger")
@@ -126,8 +128,8 @@
.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
+ "The staff team can be notified when an NSFW image is detected, or malicious links are sent.\n" +
+ `You can check and manage what to moderate in ${await getCommandMentionByName("settings/filters")}`
)
.setEmoji("MOD.IMAGES.TOOSMALL")
.setStatus("Danger")
@@ -140,10 +142,12 @@
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."
+ "Nucleus has a ticket system which allows users to create tickets and talk to the server staff or support team.\n" +
+ `Tickets can be created by users with ${await getCommandMentionByName("ticket/create")}, or by clicking a button created by moderators.\n` +
+ `After being created, a new channel or thread is created, and the user and support team are pinged. \n` +
+ `The category or channel to create threads in can be set with ${await getCommandMentionByName("settings/tickets")}\n` +
+ `When the ticket is resolved, anyone can run ${await getCommandMentionByName("ticket/close")} (or click the button) to close it.\n` +
+ `Running ${await getCommandMentionByName("ticket/close")} again will delete the ticket.`
)
.setEmoji("GUILD.TICKET.CLOSE")
.setStatus("Danger")
@@ -156,11 +160,10 @@
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"
+ "Nucleus allows you to create tags, which allow a message to be sent when a specific tag is typed.\n" +
+ `Tags can be created with ${await getCommandMentionByName("tags/create")}, and can be edited with ${await getCommandMentionByName("tags/edit")}\n` +
+ `Tags can be deleted with ${await getCommandMentionByName("tags/delete")}, and can be listed with ${await getCommandMentionByName("tags/list")}\n` +
+ `To use a tag, you can type ${await getCommandMentionByName("tag")}, followed by the tag to send`
)
.setEmoji("PUNISH.NICKNAME.RED")
.setStatus("Danger")
@@ -173,10 +176,10 @@
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"
+ "Nucleus Premium allows you to use extra features in your server, which are useful but not essential.\n" +
+ "**No currently free commands will become premium features.**\n" +
+ "Premium features include creating ticket transcripts and attachment logs.\n\n" +
+ "Premium can be purchased in [our server](https://discord.gg/bPaNnxe) in the subscriptions page" // TODO: add a table graphic
)
.setEmoji("NUCLEUS.PREMIUM")
.setStatus("Danger")
@@ -185,17 +188,6 @@
.setDescription("Premium features")
.setPageId(7)
];
- let m: Message;
- if (interaction) {
- m = (await interaction.reply({
- embeds: LoadingEmbed,
- fetchReply: true,
- ephemeral: true
- })) as Message;
- } else {
- m = await c.send({ embeds: LoadingEmbed });
- }
- let page = 0;
const publicFilter = async (component: MessageComponentInteraction) => {
return (component.member as Discord.GuildMember).permissions.has("ManageGuild");
diff --git a/src/utils/client.ts b/src/utils/client.ts
index a199b5b..2e2baa6 100644
--- a/src/utils/client.ts
+++ b/src/utils/client.ts
@@ -1,3 +1,4 @@
+import { ApplicationCommand, ApplicationCommandResolvable, DataManager } from 'discord.js';
import Discord, { Client, Interaction, AutocompleteInteraction, GatewayIntentBits, Collection } from 'discord.js';
import { Logger } from "../utils/log.js";
import Memory from "../utils/memory.js";
@@ -23,6 +24,7 @@
eventScheduler: EventScheduler;
performanceTest: PerformanceTest;
};
+ commandList?: Discord.Collection<string, Discord.ApplicationCommand>;
preloadPage: Record<string, {command: string, argument: string}> = {}; // e.g. { channelID: { command: privacy, page: 3}}
commands: Record<string, {
command: Discord.SlashCommandBuilder |
diff --git a/src/utils/commandRegistration/register.ts b/src/utils/commandRegistration/register.ts
index abc8c39..b4c6e6e 100644
--- a/src/utils/commandRegistration/register.ts
+++ b/src/utils/commandRegistration/register.ts
@@ -208,12 +208,20 @@
const guild = await client.guilds.fetch(config.developmentGuildID);
console.log(`${colours.purple}Registering commands in ${guild!.name}${colours.none}`)
await guild.commands.set(commandList);
+ client.commandList = guild.commands.cache;
} else {
console.log(`${colours.blue}Registering commands in production mode${colours.none}`)
await client.application?.commands.set(commandList);
}
}
-
+ if (config.enableDevelopment) {
+ const guild = await client.guilds.fetch(config.developmentGuildID);
+ await guild.commands.fetch();
+ client.commandList = guild.commands.cache;
+ } else {
+ await client.application?.commands.fetch();
+ client.commandList = client.application?.commands.cache!;
+ }
await registerCommandHandler();
await registerEvents();
console.log(`${colours.green}Registered commands, events and context menus${colours.none}`)
diff --git a/src/utils/getCommandMentionByName.ts b/src/utils/getCommandMentionByName.ts
index b2b9937..e5a67c5 100644
--- a/src/utils/getCommandMentionByName.ts
+++ b/src/utils/getCommandMentionByName.ts
@@ -1,22 +1,15 @@
import type Discord from "discord.js";
import client from "./client.js";
-import config from "../config/main.json" assert { type: "json"};
export const getCommandMentionByName = async (name: string): Promise<string> => {
const split = name.replaceAll("/", " ").split(" ")
const commandName: string = split[0]!;
- let commandID: string;
const filterCommand = (command: Discord.ApplicationCommand) => command.name === commandName;
- if (config.enableDevelopment) {
- const developmentGuild = client.guilds.cache.get(config.developmentGuildID)!;
- await developmentGuild.commands.fetch();
- commandID = developmentGuild.commands.cache.filter(c => filterCommand(c)).first()!.id;
- } else {
- await client.application?.commands.fetch();
- commandID = client.application?.commands.cache.filter(c => filterCommand(c)).first()!.id!;
- }
+ const command = client.commandList!.filter(c => filterCommand(c))
+ if (command.size === 0) return `\`/${name.replaceAll("/", " ")}\``;
+ const commandID = command.first()!.id;
return `</${split.join(" ")}:${commandID}>`;
-}
\ No newline at end of file
+}