Compare commits

...

4 commits

Author SHA1 Message Date
powermaker450 0600f13511 Some cleanup again 2024-10-23 16:07:27 -04:00
powermaker450 e89e674aa2 Use a constant 2024-10-23 15:57:03 -04:00
powermaker450 a2279ef93c Add pardonuser command 2024-10-23 15:34:52 -04:00
powermaker450 f5b18513d2 Change updateGuild to refresh guild and make it actually work 2024-10-23 12:31:40 -04:00
11 changed files with 122 additions and 48 deletions

View file

@ -6,7 +6,7 @@
"scripts": { "scripts": {
"build": "rm -rf ./dist && tsc -p .", "build": "rm -rf ./dist && tsc -p .",
"start": "node ./dist/main.js", "start": "node ./dist/main.js",
"refresh": "node ./dist/scripts/updateGuild.js", "refresh": "node ./dist/scripts/refreshGuild.js",
"prettier": "if prettier -v >/dev/null 2>&1; then prettier . --write; else npx prettier . --write; fi", "prettier": "if prettier -v >/dev/null 2>&1; then prettier . --write; else npx prettier . --write; fi",
"test": "echo \"Error: no test specified\" && exit 1" "test": "echo \"Error: no test specified\" && exit 1"
}, },

View file

@ -29,7 +29,7 @@ const commandsData = Object.values(commands).map(command =>
command.data.toJSON() command.data.toJSON()
); );
const rest = new REST({ version: "9" }).setToken(BOT_TOKEN); export const rest = new REST({ version: "9" }).setToken(BOT_TOKEN);
export async function deployCommands({ guildId }: DeployCommandsProps) { export async function deployCommands({ guildId }: DeployCommandsProps) {
try { try {

View file

@ -30,6 +30,7 @@ import { dt } from "../main";
import { StoreMan } from "../storeman"; import { StoreMan } from "../storeman";
import getRandomColor from "../utils/getRandomColor"; import getRandomColor from "../utils/getRandomColor";
import Logger from "../utils/Logger"; import Logger from "../utils/Logger";
import { messageOpts } from "../constants";
const logger = new Logger("(/) confess"); const logger = new Logger("(/) confess");
@ -53,14 +54,14 @@ export async function execute(interaction: ChatInputCommandInteraction) {
// TODO: This all works as intended, but I'd like for it so be a reusable function // TODO: This all works as intended, but I'd like for it so be a reusable function
// instead because all of this is used in src/main.ts // instead because all of this is used in src/main.ts
const { id: guildId } = interaction.guild!; const { id: guildId } = interaction.guild!;
const { id: userId } = interaction.user; const { id: userId, displayName: userName } = interaction.user;
try { try {
// If the user is banned in this guild, don't let them post // If the user is banned in this guild, don't let them post
if (dt.isBannedByUser(guildId, userId)) { if (dt.isBannedByUser(guildId, userId)) {
return interaction.reply({ return interaction.reply({
content: "You are banned from confessions in this server!", content: "You are banned from confessions in this server!",
ephemeral: true ...messageOpts
}); });
} }
@ -69,11 +70,11 @@ export async function execute(interaction: ChatInputCommandInteraction) {
return interaction.reply({ return interaction.reply({
content: content:
"The bot hasn't been set up yet! Ask the server admins to set it up.", "The bot hasn't been set up yet! Ask the server admins to set it up.",
ephemeral: true ...messageOpts
}); });
} }
const confessChannel = dt.getGuildInfo(guildId)?.settings.confessChannel; const confessChannel = dt.getGuildInfo(guildId)!.settings.confessChannel;
const adminChannel = dt.getGuildInfo(guildId)?.settings.modChannel; const adminChannel = dt.getGuildInfo(guildId)?.settings.modChannel;
const messageContent = `"${interaction.options.getString("message")}"`; const messageContent = `"${interaction.options.getString("message")}"`;
@ -162,8 +163,8 @@ export async function execute(interaction: ChatInputCommandInteraction) {
dt.addConfession( dt.addConfession(
message, message,
messageId, messageId,
interaction.user.displayName, userName,
interaction.user.id, userId,
messageContent, messageContent,
attachment attachment
); );
@ -172,20 +173,24 @@ export async function execute(interaction: ChatInputCommandInteraction) {
// If there are 2 or more confessions, remove the previous confession's button components // If there are 2 or more confessions, remove the previous confession's button components
if (confessionsLength >= 2) { if (confessionsLength >= 2) {
await ( (BotClient.channels.cache.get(confessChannel) as TextChannel).messages
BotClient.channels.cache.get(confessChannel!) as TextChannel
).messages
.fetch( .fetch(
dt.getGuildInfo(guildId)!.confessions[confessionsLength - 2].messageId dt.getGuildInfo(guildId)!.confessions[confessionsLength - 2].messageId
) )
.then(message => { .then(message => {
message.edit({ components: [] }); message.edit({ components: [] });
})
.catch(err => {
logger.error(
"An error occured removing embeds from the previous message:",
err
);
}); });
} }
return interaction.reply({ return interaction.reply({
content: "Confession sent!", content: "Confession sent!",
ephemeral: true ...messageOpts
}); });
} catch (err) { } catch (err) {
logger.error("An error occured:", err); logger.error("An error occured:", err);

View file

@ -27,6 +27,7 @@ import { dt } from "../main";
import { BotClient } from "../bot"; import { BotClient } from "../bot";
import getRandomColor from "../utils/getRandomColor"; import getRandomColor from "../utils/getRandomColor";
import Logger from "../utils/Logger"; import Logger from "../utils/Logger";
import { messageOpts } from "../constants";
const logger = new Logger("(/) confessdel"); const logger = new Logger("(/) confessdel");
@ -46,7 +47,7 @@ export async function execute(interaction: ChatInputCommandInteraction) {
return interaction.reply({ return interaction.reply({
content: content:
"The bot hasn't been set up yet! Ask the server admins to set it up.", "The bot hasn't been set up yet! Ask the server admins to set it up.",
ephemeral: true ...messageOpts
}); });
} }
@ -84,13 +85,13 @@ export async function execute(interaction: ChatInputCommandInteraction) {
return interaction.reply({ return interaction.reply({
content: "Confession removed.", content: "Confession removed.",
ephemeral: true ...messageOpts
}); });
} catch (err) { } catch (err) {
logger.error("A confession delete error occured:", err); logger.error("A confession delete error occured:", err);
return interaction.reply({ return interaction.reply({
content: "An error occured.", content: "An error occured.",
ephemeral: true ...messageOpts
}); });
} }
} else { } else {
@ -99,18 +100,18 @@ export async function execute(interaction: ChatInputCommandInteraction) {
return result return result
? interaction.reply({ ? interaction.reply({
content: "You are not allowed to remove this confession.", content: "You are not allowed to remove this confession.",
ephemeral: true ...messageOpts
}) })
: interaction.reply({ : interaction.reply({
content: content:
"Either the confession wasn't found or you may not be allowed to remove it.", "Either the confession wasn't found or you may not be allowed to remove it.",
ephemeral: true ...messageOpts
}); });
} catch (err) { } catch (err) {
logger.error("A confession delete interaction occured:", err); logger.error("A confession delete interaction occured:", err);
return interaction.reply({ return interaction.reply({
content: "An error occured.", content: "An error occured.",
ephemeral: true ...messageOpts
}); });
} }
} }

View file

@ -28,6 +28,7 @@ import {
import { dt } from "../main"; import { dt } from "../main";
import Logger from "../utils/Logger"; import Logger from "../utils/Logger";
import { BanReason } from "../storeman"; import { BanReason } from "../storeman";
import { messageOpts } from "../constants";
const logger = new Logger("(/) confessban"); const logger = new Logger("(/) confessban");
@ -71,6 +72,17 @@ export const data = new SlashCommandBuilder()
.setMaxLength(4) .setMaxLength(4)
.setRequired(true) .setRequired(true)
) )
)
.addSubcommand(pardonuser =>
pardonuser
.setName("pardonuser")
.setDescription("Pardon a user from confessions")
.addUserOption(user =>
user
.setName("user")
.setDescription("The user to pardon")
.setRequired(true)
)
); );
export async function execute(interaction: ChatInputCommandInteraction) { export async function execute(interaction: ChatInputCommandInteraction) {
@ -84,7 +96,7 @@ export async function execute(interaction: ChatInputCommandInteraction) {
try { try {
return interaction.reply({ return interaction.reply({
content: "That user is already banned!", content: "That user is already banned!",
ephemeral: true ...messageOpts
}); });
} catch (err) { } catch (err) {
logger.error("A ban interaction error occured:", err); logger.error("A ban interaction error occured:", err);
@ -97,11 +109,11 @@ export async function execute(interaction: ChatInputCommandInteraction) {
return result return result
? interaction.reply({ ? interaction.reply({
content: "User was banned.", content: "User was banned.",
ephemeral: true ...messageOpts
}) })
: interaction.reply({ : interaction.reply({
content: "No confession with that ID was found.", content: "No confession with that ID was found.",
ephemeral: true ...messageOpts
}); });
} catch (err) { } catch (err) {
logger.error("A ban interaction error occured:", err); logger.error("A ban interaction error occured:", err);
@ -116,11 +128,11 @@ export async function execute(interaction: ChatInputCommandInteraction) {
return result return result
? interaction.reply({ ? interaction.reply({
content: "User was banned.", content: "User was banned.",
ephemeral: true ...messageOpts
}) })
: interaction.reply({ : interaction.reply({
content: "How did we get here? (An error occured.)}", content: "How did we get here? (An error occured.)}",
ephemeral: true ...messageOpts
}); });
} catch (err) { } catch (err) {
logger.error("A banuser interaction error occured:", err); logger.error("A banuser interaction error occured:", err);
@ -161,36 +173,57 @@ export async function execute(interaction: ChatInputCommandInteraction) {
try { try {
return interaction.reply({ return interaction.reply({
content: determineContent(), content: determineContent(),
ephemeral: true ...messageOpts
}); });
} catch (err) { } catch (err) {
logger.error("A banlist interaction error occured:", err); logger.error("A banlist interaction error occured:", err);
return interaction.reply({ return interaction.reply({
content: "A server-side error occurred when getting the ban list.", content: "A server-side error occurred when getting the ban list.",
ephemeral: true ...messageOpts
}); });
} }
// /confessmod pardon <id> // /confessmod pardon <id>
} else if (interaction.options.getSubcommand() === "pardon") { } else if (interaction.options.getSubcommand() === "pardon") {
const result = dt.removeBan(guildId, interaction.options.getString("id")!); const result = dt.removeBanById(
guildId,
interaction.options.getString("id")!
);
try { try {
return result return result
? interaction.reply({ ? interaction.reply({
content: "User was unbanned.", content: "User was unbanned.",
ephemeral: true ...messageOpts
}) })
: interaction.reply({ : interaction.reply({
content: "No confession with that ID was found.", content: "No confession with that ID was found.",
ephemeral: true ...messageOpts
}); });
} catch (err) { } catch (err) {
logger.error("An unban interaction error occured:", err); logger.error("An unban interaction error occured:", err);
} }
} else if (interaction.options.getSubcommand() === "pardonuser") {
const { id: userId } = interaction.options.getUser("user")!;
const result = dt.removeBanByUser(guildId, userId);
try {
return result
? interaction.reply({
content: "User was unbanned.",
...messageOpts
})
: interaction.reply({
content: "That user is not banned from confessions.",
...messageOpts
});
} catch (err) {
logger.error("An unban user interaction error occured:", err);
}
} }
return interaction.reply({ return interaction.reply({
content: "Unknown error", content: "Unknown error",
ephemeral: true ...messageOpts
}); });
} }

View file

@ -29,6 +29,7 @@ import {
} from "discord.js"; } from "discord.js";
import { dt } from "../main"; import { dt } from "../main";
import Logger from "../utils/Logger"; import Logger from "../utils/Logger";
import { messageOpts } from "../constants";
const logger = new Logger("(/) setup"); const logger = new Logger("(/) setup");
@ -44,7 +45,7 @@ export async function execute(interaction: CommandInteraction) {
if (dt.checkSetup(guildId)) { if (dt.checkSetup(guildId)) {
return interaction.reply({ return interaction.reply({
content: "This guild has already been set up!", content: "This guild has already been set up!",
ephemeral: true ...messageOpts
}); });
} }
@ -70,7 +71,7 @@ export async function execute(interaction: CommandInteraction) {
try { try {
const response = await interaction.reply({ const response = await interaction.reply({
content: `# Let's get started, ${username}!\nFirst, let's choose a channel for your confessions.`, content: `# Let's get started, ${username}!\nFirst, let's choose a channel for your confessions.`,
ephemeral: true, ...messageOpts,
components: [channelRow] components: [channelRow]
}); });
@ -101,7 +102,7 @@ export async function execute(interaction: CommandInteraction) {
const logResponse = await interaction.followUp({ const logResponse = await interaction.followUp({
content: "# Now, select a logging channel, for moderation purposes.", content: "# Now, select a logging channel, for moderation purposes.",
ephemeral: true, ...messageOpts,
components: [logChannelRow, buttonRow] components: [logChannelRow, buttonRow]
}); });
@ -159,7 +160,7 @@ export async function execute(interaction: CommandInteraction) {
!skipped && !skipped &&
interaction.followUp({ interaction.followUp({
content: "No channel selected. Please try again.", content: "No channel selected. Please try again.",
ephemeral: true, ...messageOpts,
components: [] components: []
}); });
}); });
@ -170,7 +171,7 @@ export async function execute(interaction: CommandInteraction) {
!collected.size && !collected.size &&
interaction.followUp({ interaction.followUp({
content: "No channel selected. Try again.", content: "No channel selected. Try again.",
ephemeral: true, ...messageOpts,
components: [] components: []
}); });
}); });

View file

@ -23,6 +23,7 @@ import {
} from "discord.js"; } from "discord.js";
import { deployCommands } from "../bot"; import { deployCommands } from "../bot";
import Logger from "../utils/Logger"; import Logger from "../utils/Logger";
import { messageOpts } from "../constants";
const logger = new Logger("(/) update"); const logger = new Logger("(/) update");
const minutes = 5; const minutes = 5;
@ -39,7 +40,7 @@ export async function execute(interaction: ChatInputCommandInteraction) {
if (cooldownList.has(guildId)) { if (cooldownList.has(guildId)) {
return interaction.reply({ return interaction.reply({
content: `You can only run the update command once every ${minutes} minutes.`, content: `You can only run the update command once every ${minutes} minutes.`,
ephemeral: true ...messageOpts
}); });
} }
@ -58,6 +59,6 @@ export async function execute(interaction: ChatInputCommandInteraction) {
return interaction.reply({ return interaction.reply({
content: "Commands refreshed.", content: "Commands refreshed.",
ephemeral: true ...messageOpts
}); });
} }

3
src/constants.ts Normal file
View file

@ -0,0 +1,3 @@
export const messageOpts = {
ephemeral: true
};

View file

@ -31,6 +31,7 @@ import { StoreMan } from "./storeman";
import Logger from "./utils/Logger"; import Logger from "./utils/Logger";
import getRandomColor from "./utils/getRandomColor"; import getRandomColor from "./utils/getRandomColor";
import { submit } from "./modals"; import { submit } from "./modals";
import { messageOpts } from "./constants";
export const dt = new StoreMan(StoreMan.checkFile()); export const dt = new StoreMan(StoreMan.checkFile());
const logger = new Logger("Main"); const logger = new Logger("Main");
@ -100,7 +101,7 @@ BotClient.on(Events.InteractionCreate, async interaction => {
dt.isBannedByUser(interaction.guild?.id!, interaction.user.id) dt.isBannedByUser(interaction.guild?.id!, interaction.user.id)
? interaction.reply({ ? interaction.reply({
content: "You are banned from confessions in this server!", content: "You are banned from confessions in this server!",
ephemeral: true ...messageOpts
}) })
: interaction.showModal(submit); : interaction.showModal(submit);
} }
@ -121,7 +122,7 @@ BotClient.on(Events.InteractionCreate, async interaction => {
if (dt.isBannedByUser(interaction.guild?.id!, interaction.user.id)) { if (dt.isBannedByUser(interaction.guild?.id!, interaction.user.id)) {
return interaction.reply({ return interaction.reply({
content: "You are banned from confessions in this server!", content: "You are banned from confessions in this server!",
ephemeral: true ...messageOpts
}); });
} }
@ -129,7 +130,7 @@ BotClient.on(Events.InteractionCreate, async interaction => {
return interaction.reply({ return interaction.reply({
content: content:
"The bot hasn't been set up yet! Ask the server admins to set it up.", "The bot hasn't been set up yet! Ask the server admins to set it up.",
ephemeral: true ...messageOpts
}); });
} }
@ -218,7 +219,7 @@ BotClient.on(Events.InteractionCreate, async interaction => {
return interaction.reply({ return interaction.reply({
content: "Confession sent!", content: "Confession sent!",
ephemeral: true ...messageOpts
}); });
} catch (err) { } catch (err) {
logger.error("An error occured:", err); logger.error("An error occured:", err);

View file

@ -16,22 +16,32 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import { Events } from "discord.js"; import { Events, Routes } from "discord.js";
import { BotClient, deployCommands } from "../bot"; import { BOT_ID, BotClient, deployCommands, rest } from "../bot";
if (process.argv.length < 3 || !process.argv[2]) { if (process.argv.length < 3 || !process.argv[2]) {
console.log("You need to specify the guild ID to refresh."); console.log("You need to specify the guild ID to refresh.");
process.exit(1); process.exit(1);
} }
const [, , guildId] = process.argv;
BotClient.on(Events.ClientReady, () => { BotClient.on(Events.ClientReady, () => {
try { try {
BotClient.fetchGuildPreview(process.argv[2]) rest
.then(({ id, name }) => { .put(Routes.applicationGuildCommands(BOT_ID, guildId), { body: [] })
deployCommands({ guildId: id }); .then(() => {
console.log(`Updated (/) commands for "${name}".`); console.log("Deleted (/) commands.");
deployCommands({ guildId: guildId })
.then(() => {
console.log("Successfully reloaded (/) commands.");
process.exit(0); process.exit(0);
}) })
.catch(err => {
console.log("An error occurred refreshing (/) commands:", err);
process.exit(1);
});
})
.catch(err => { .catch(err => {
console.log("An error occured refreshing (/) commands:", err); console.log("An error occured refreshing (/) commands:", err);
process.exit(1); process.exit(1);

View file

@ -302,7 +302,7 @@ export class StoreMan {
} }
// Attempts to pardon a user from a ban. If sucessfully completed, returns true, false if otherwise. // Attempts to pardon a user from a ban. If sucessfully completed, returns true, false if otherwise.
public removeBan(guildId: string, confessionId: string): boolean { public removeBanById(guildId: string, confessionId: string): boolean {
for (const guild of this.data) { for (const guild of this.data) {
if (guild.id === guildId) { if (guild.id === guildId) {
if (this.getConfession(guildId, confessionId)) { if (this.getConfession(guildId, confessionId)) {
@ -320,4 +320,23 @@ export class StoreMan {
return false; return false;
} }
public removeBanByUser(guildId: string, userId: string): boolean {
for (const guild of this.data) {
if (guild.id === guildId) {
for (const ban of guild.settings.bans) {
if (ban.method === BanReason.ByUser && ban.user === userId) {
guild.settings.bans = guild.settings.bans.filter(ban => {
return ban.user !== userId;
});
this.saveFile();
return true;
}
}
}
}
return false;
}
} }