From dbb557e9d8a87728ea9f3dd20e20f1ec5c98075d Mon Sep 17 00:00:00 2001 From: TheRealCrazyfuy Date: Wed, 10 Dec 2025 21:14:10 +0100 Subject: [PATCH] add verification modal and command --- commands/verification/createverification.js | 34 ++++++++++++++ example-config.json | 3 +- index.js | 10 +++- package.json | 2 +- utils/random_generators.js | 7 +++ utils/user_verifications.js | 52 +++++++++++++++++++++ 6 files changed, 104 insertions(+), 4 deletions(-) create mode 100644 commands/verification/createverification.js create mode 100644 utils/random_generators.js create mode 100644 utils/user_verifications.js diff --git a/commands/verification/createverification.js b/commands/verification/createverification.js new file mode 100644 index 0000000..7a50fb6 --- /dev/null +++ b/commands/verification/createverification.js @@ -0,0 +1,34 @@ +const { SlashCommandBuilder, ActionRowBuilder, ButtonBuilder, MessageFlags } = require('discord.js'); + +module.exports = { + data: new SlashCommandBuilder() + .setName('createverification') + .setDescription('Create a verification message in a specified channel') + .addChannelOption(option => + option + .setName('channel') + .setDescription('The channel to create the verification message in') + .setRequired(true) + ), + async execute(interaction) { + try { + if (!interaction.member.permissions.has('ManageGuild')) { + return interaction.reply({ content: `You don't have permission to use this command `, flags: MessageFlags.Ephemeral }); + } + + const row = new ActionRowBuilder().addComponents( + new ButtonBuilder() + .setCustomId('verify_button') + .setLabel('✅ Start Verification') + .setStyle('Success'), + ); + + const channel = interaction.options.getChannel('channel') + + await channel.send({ content: 'Please click the button below to start the verification process.', components: [row] }); + } catch (error) { + console.error('Error creating verification message:', error); + await interaction.reply({ content: 'There was an error creating the verification message.', flags: MessageFlags.Ephemeral }); + } + } +} \ No newline at end of file diff --git a/example-config.json b/example-config.json index 75c3dea..7396f85 100644 --- a/example-config.json +++ b/example-config.json @@ -2,5 +2,6 @@ "token": "your-bot-token", "clientId": "client-id", "forumChannelId": 12345678910, - "solvedTagId": 12345678910 + "solvedTagId": 12345678910, + "verificationRoleId": "12345678910" } \ No newline at end of file diff --git a/index.js b/index.js index 57c3879..b6e67fe 100644 --- a/index.js +++ b/index.js @@ -1,9 +1,9 @@ const fs = require('node:fs'); const path = require('node:path'); const { Client, Collection, Events, GatewayIntentBits, MessageFlags, ChannelType, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require('discord.js'); -const { token, clientId, forumChannelId, solvedTagId } = require('./config.json'); +const { token, forumChannelId, solvedTagId } = require('./config.json'); const Fuse = require('fuse.js'); - +const { createVerificationModal, handleVerificationResponse } = require('./utils/user_verifications'); const client = new Client({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.MessageContent] }); client.commands = new Collection(); @@ -209,6 +209,12 @@ client.on(Events.InteractionCreate, async interaction => { console.error('Error closing thread:', err); await interaction.reply({ content: 'There was an error closing the thread.', flags: MessageFlags.Ephemeral }); } + } else if (interaction.isButton() && interaction.customId === 'verify_button') { + await createVerificationModal(interaction); + return; + } else if (interaction.isModalSubmit() && interaction.customId.startsWith('verification_modal_')) { + await handleVerificationResponse(interaction); + return; } }); diff --git a/package.json b/package.json index 73b3452..35dbecb 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "license": "ISC", "description": "", "dependencies": { - "discord.js": "^14.21.0", + "discord.js": "^14.25.1", "fuse.js": "^7.1.0" } } diff --git a/utils/random_generators.js b/utils/random_generators.js new file mode 100644 index 0000000..d3f6e44 --- /dev/null +++ b/utils/random_generators.js @@ -0,0 +1,7 @@ +module.exports = { + generateRandomInteger +}; + +function generateRandomInteger(min, max) { + return Math.floor(Math.random() * (max - min + 1)) + min; +} \ No newline at end of file diff --git a/utils/user_verifications.js b/utils/user_verifications.js new file mode 100644 index 0000000..4e83c8d --- /dev/null +++ b/utils/user_verifications.js @@ -0,0 +1,52 @@ +module.exports = { + createVerificationModal, + handleVerificationResponse +}; + +const { ModalBuilder, LabelBuilder, TextInputStyle, MessageFlags, TextInputBuilder } = require('discord.js'); +const { generateRandomInteger } = require('./random_generators'); +const config = require('../config.json'); + +async function createVerificationModal(interaction) { + try { + const integer1 = generateRandomInteger(1, 10); + const integer2 = generateRandomInteger(1, 10); + const correctAnswer = integer1 + integer2; + + const modal = new ModalBuilder().setCustomId(`verification_modal_${correctAnswer}`).setTitle('Let\'s get verified!'); + + const user_input = new TextInputBuilder() + .setCustomId('verification_user_response') + .setStyle(TextInputStyle.Short) + .setPlaceholder(''); + + const label_modal = new LabelBuilder() + .setLabel(`Verification Question: What is ${integer1} + ${integer2}?`) + .setDescription('This helps us verify you are not a bot.') + .setTextInputComponent(user_input); + + modal.addLabelComponents(label_modal); + + await interaction.showModal(modal); + } catch (error) { + console.error('Error during verification:', error); + await interaction.reply({ content: 'There was an error during verification.', flags: MessageFlags.Ephemeral }); + } +} + +async function handleVerificationResponse(interaction) { + try { + const userResponse = interaction.fields.getTextInputValue('verification_user_response'); + if (userResponse.trim() === interaction.customId.split('_').pop()) { + const member = await interaction.guild.members.fetch(interaction.user.id); + await member.roles.add(config.verificationRoleId); + await interaction.reply({ content: 'Verification successful! You have access to the server.', flags: MessageFlags.Ephemeral }); + } else { + await interaction.reply({ content: 'Verification failed. Please try again.', flags: MessageFlags.Ephemeral }); + } + } catch (error) { + console.error('Error processing verification modal:', error); + await interaction.reply({ content: 'There was an error processing your verification.', flags: MessageFlags.Ephemeral }); + } +} +