Add a button to submit a confession under the most recent one
This commit is contained in:
parent
a78e27e9fa
commit
1612fa8ca1
|
@ -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
|
||||||
|
|
116
src/main.ts
116
src/main.ts
|
@ -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
19
src/modals/index.ts
Normal 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
52
src/modals/submit.ts
Normal 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 };
|
Loading…
Reference in a new issue