Add a button to submit a confession under the most recent one

This commit is contained in:
powermaker450 2024-10-13 12:28:11 -04:00
parent a78e27e9fa
commit 1612fa8ca1
4 changed files with 221 additions and 2 deletions

View file

@ -17,7 +17,11 @@
*/ */
import { import {
ActionRowBuilder,
ButtonBuilder,
ButtonStyle,
CommandInteraction, CommandInteraction,
ComponentType,
EmbedBuilder, EmbedBuilder,
SlashCommandBuilder, SlashCommandBuilder,
TextChannel TextChannel
@ -27,6 +31,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 { submit } from "../modals";
const logger = new Logger("(/) confess"); const logger = new Logger("(/) confess");
@ -41,6 +46,8 @@ export const data = new SlashCommandBuilder()
); );
export async function execute(interaction: CommandInteraction) { export async function execute(interaction: CommandInteraction) {
// TODO: This all works as intended, but I'd like for it so be a reusable function
// instead because all of this is reused in src/main.ts:56
try { try {
if (dt.isBanned(interaction.guild?.id!, interaction.user.id)) { if (dt.isBanned(interaction.guild?.id!, interaction.user.id)) {
return interaction.reply({ return interaction.reply({
@ -88,10 +95,27 @@ export async function execute(interaction: CommandInteraction) {
} }
); );
const submitConfessionButton = new ButtonBuilder()
.setCustomId("submitConfession")
.setLabel("Submit a Confession")
.setStyle(ButtonStyle.Primary);
const actionRow = new ActionRowBuilder<ButtonBuilder>()
.setComponents(submitConfessionButton);
const message = await ( const message = await (
BotClient.channels.cache.get(confessChannel!) as TextChannel BotClient.channels.cache.get(confessChannel!) as TextChannel
).send({ ).send({
embeds: [userConfessionEmbed] embeds: [userConfessionEmbed],
components: [actionRow]
});
const collector = message.createMessageComponentCollector({ componentType: ComponentType.Button });
collector.on("collect", i => {
if (i.customId === "submitConfession") {
i.showModal(submit);
}
}); });
await (BotClient.channels.cache.get(adminChannel!) as TextChannel).send({ await (BotClient.channels.cache.get(adminChannel!) as TextChannel).send({
@ -106,6 +130,16 @@ export async function execute(interaction: CommandInteraction) {
messageContent messageContent
); );
const confessionsLength = dt.getGuildInfo(interaction.guild?.id!)?.confessions.length!;
if (confessionsLength >= 2) {
await (BotClient.channels.cache.get(confessChannel!) as TextChannel).messages.fetch(
dt.getGuildInfo(interaction.guild?.id!)?.confessions[confessionsLength - 2].messageId!
).then(message => {
message.edit({ components: [] });
});
}
return interaction.reply({ return interaction.reply({
content: "Confession sent!", content: "Confession sent!",
ephemeral: true ephemeral: true

View file

@ -16,10 +16,13 @@
* 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 { ActionRowBuilder, ButtonBuilder, ButtonStyle, CacheType, ComponentType, EmbedBuilder, Events, Interaction, ModalSubmitInteraction, TextChannel, } from "discord.js";
import { BotClient, BOT_TOKEN, deployCommands } from "./bot"; import { BotClient, BOT_TOKEN, deployCommands } from "./bot";
import { commands } from "./commands"; import { commands } from "./commands";
import { StoreMan } from "./storeman"; import { StoreMan } from "./storeman";
import Logger from "./utils/Logger"; import Logger from "./utils/Logger";
import getRandomColor from "./utils/getRandomColor";
import { submit } from "./modals";
export const dt = new StoreMan(StoreMan.checkFile()); export const dt = new StoreMan(StoreMan.checkFile());
const logger = new Logger("Main"); const logger = new Logger("Main");
@ -28,16 +31,18 @@ BotClient.once("ready", client => {
logger.log(`We're ready! Logged in as ${client.user.tag}`); logger.log(`We're ready! Logged in as ${client.user.tag}`);
}); });
// Deploy the commands for a new guild
BotClient.on("guildCreate", async guild => { BotClient.on("guildCreate", async guild => {
await deployCommands({ guildId: guild.id }); await deployCommands({ guildId: guild.id });
}); });
// Delete the data for a guild after it is removed
BotClient.on("guildDelete", guild => { BotClient.on("guildDelete", guild => {
logger.log(`${guild.name} didn't want us anymore... :(`); logger.log(`${guild.name} didn't want us anymore... :(`);
dt.clearSettings(guild.id); dt.clearSettings(guild.id);
}); });
BotClient.on("interactionCreate", async interaction => { BotClient.on(Events.InteractionCreate, async interaction => {
if (!interaction.isCommand()) { if (!interaction.isCommand()) {
return; return;
} }
@ -49,4 +54,113 @@ BotClient.on("interactionCreate", async interaction => {
} }
}); });
BotClient.on(Events.InteractionCreate, async interaction => {
if (!interaction.isModalSubmit()) {
return;
}
if (interaction.customId === "submitConfession") {
const messageContent: string = interaction.fields.getTextInputValue("confessionInput");
// const attachment: string = interaction.getTextInputValue("confessionAttachment");
try {
if (dt.isBanned(interaction.guild?.id!, interaction.user.id)) {
return interaction.reply({
content: "You are banned from confessions in this server!",
ephemeral: true
});
}
if (!dt.getGuildInfo(interaction.guild?.id!)) {
return interaction.reply({
content:
"The bot hasn't been set up yet! Ask the server admins to set it up.",
ephemeral: true
});
}
const confessChannel = dt.getGuildInfo(interaction.guild?.id!)?.settings
.confessChannel;
const adminChannel = dt.getGuildInfo(interaction.guild?.id!)?.settings
.modChannel;
const color = getRandomColor();
const messageId = StoreMan.genId();
const userConfessionEmbed = new EmbedBuilder()
.setColor(color)
.setTitle(`Anonymous Confession \`${messageId}\``)
// @ts-ignore
.setDescription(messageContent);
const adminConfessionEmbed = new EmbedBuilder()
.setColor(color)
.setTitle(`Anonymous Confession \`${messageId}\``)
// @ts-ignore
.setDescription(messageContent)
.addFields(
{
name: "Author",
value: interaction.user.displayName
},
{
name: "Author ID",
value: interaction.user.id
}
);
const submitConfessionButton = new ButtonBuilder()
.setCustomId("submitConfession")
.setLabel("Submit a Confession")
.setStyle(ButtonStyle.Primary);
const actionRow = new ActionRowBuilder<ButtonBuilder>()
.setComponents(submitConfessionButton);
const message = await (
BotClient.channels.cache.get(confessChannel!) as TextChannel
).send({
embeds: [userConfessionEmbed],
components: [actionRow]
});
const collector = message.createMessageComponentCollector({ componentType: ComponentType.Button });
collector.on("collect", i => {
if (i.customId === "submitConfession") {
i.showModal(submit);
}
});
await (BotClient.channels.cache.get(adminChannel!) as TextChannel).send({
embeds: [adminConfessionEmbed]
});
dt.addConfession(
message,
messageId,
interaction.user.displayName,
interaction.user.id,
messageContent
);
const confessionsLength = dt.getGuildInfo(interaction.guild?.id!)?.confessions.length!;
if (confessionsLength >= 2) {
await (BotClient.channels.cache.get(confessChannel!) as TextChannel).messages.fetch(
dt.getGuildInfo(interaction.guild?.id!)?.confessions[confessionsLength - 2].messageId!
).then(message => {
message.edit({ components: [] });
});
}
return interaction.reply({
content: "Confession sent!",
ephemeral: true
});
} catch (err) {
logger.error("An error occured:", err);
}
}
})
BotClient.login(BOT_TOKEN); BotClient.login(BOT_TOKEN);

19
src/modals/index.ts Normal file
View file

@ -0,0 +1,19 @@
/*
* Confoss: Anonymous confessions for Discord, free as in freedom and price!
* Copyright (C) 2024 powermaker450
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
export * from "./submit";

52
src/modals/submit.ts Normal file
View file

@ -0,0 +1,52 @@
/*
* Confoss: Anonymous confessions for Discord, free as in freedom and price!
* Copyright (C) 2024 powermaker450
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {
ActionRowBuilder,
ModalActionRowComponentBuilder,
ModalBuilder,
TextInputBuilder,
TextInputStyle
} from "discord.js";
const submit = new ModalBuilder()
.setCustomId("submitConfession")
.setTitle("Submit Confession")
const confessionInput = new TextInputBuilder()
.setCustomId("confessionInput")
.setLabel("Confession")
.setRequired(true)
.setMaxLength(2000)
.setStyle(TextInputStyle.Paragraph)
// TODO: Add support for attachments
//
// const attachmentInput = new TextInputBuilder()
// .setCustomId("confessionAttachment")
// .setLabel("Attachment (optional)")
// .setRequired(false)
// .setStyle(TextInputStyle.Short)
const actionRow = new ActionRowBuilder<ModalActionRowComponentBuilder>()
.addComponents(confessionInput);
// .addComponents(confessionInput, attachmentInput);
submit.addComponents(actionRow);
export { submit };