Unfinished, do not pull.
This commit is contained in:
@@ -0,0 +1,219 @@
|
|||||||
|
const { EmbedBuilder, ApplicationCommandType, AttachmentBuilder } = require('discord.js');
|
||||||
|
const { dangercordcheckVerification } = require('../../functions/dangerCordUtils.js');
|
||||||
|
const { createCanvas } = require('canvas');
|
||||||
|
const cfg = require('../../config/config.js');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: 'verify',
|
||||||
|
description: 'To verify yourself.',
|
||||||
|
type: ApplicationCommandType.ChatInput,
|
||||||
|
run: async (client, interaction) => {
|
||||||
|
await interaction.deferReply({ ephemeral: true });
|
||||||
|
const guildId = interaction.guild.id;
|
||||||
|
|
||||||
|
async function generateCaptcha(count) {
|
||||||
|
// Setting up the variables for generation
|
||||||
|
var upchars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
|
var lowchars = "abcdefghijklmnopqrstuvwxyz";
|
||||||
|
var nums = "0123456789";
|
||||||
|
|
||||||
|
var captcha = "";
|
||||||
|
|
||||||
|
for (var i = 0; i < count; i++) {
|
||||||
|
var c = Math.floor(Math.random() * 3);
|
||||||
|
if (c === 0) {
|
||||||
|
captcha += upchars.charAt(Math.floor(Math.random() * upchars.length));
|
||||||
|
} else if (c === 1) {
|
||||||
|
captcha += lowchars.charAt(Math.floor(Math.random() * lowchars.length));
|
||||||
|
} else {
|
||||||
|
captcha += nums.charAt(Math.floor(Math.random() * nums.length));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return captcha;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function createCaptcha(captcha) {
|
||||||
|
const canvas = createCanvas(200, 75);
|
||||||
|
const ctx = canvas.getContext('2d');
|
||||||
|
|
||||||
|
// Background color
|
||||||
|
ctx.fillStyle = '#000000';
|
||||||
|
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||||
|
|
||||||
|
// Text
|
||||||
|
ctx.font = '30px Arial';
|
||||||
|
ctx.textBaseline = 'middle';
|
||||||
|
ctx.textAlign = 'center';
|
||||||
|
ctx.fillStyle = '#ffffff';
|
||||||
|
|
||||||
|
// Calculate spacing between characters to fit within canvas width
|
||||||
|
const charWidth = 30;
|
||||||
|
const totalWidth = captcha.length * charWidth;
|
||||||
|
const startX = (canvas.width - totalWidth) / 2;
|
||||||
|
|
||||||
|
// Draw each character with random y-offset
|
||||||
|
for (let i = 0; i < captcha.length; i++) {
|
||||||
|
const x = startX + i * charWidth + charWidth / 2; // Adjust x-position for each character
|
||||||
|
const y = 37.5 + Math.random() * 30 - 15; // Random y-offset
|
||||||
|
ctx.fillText(captcha[i], x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Adding noise
|
||||||
|
for (let i = 0; i < 50; i++) {
|
||||||
|
ctx.fillStyle = `rgba(255,255,255,${Math.random() * 0.9})`;
|
||||||
|
ctx.fillRect(Math.random() * canvas.width, Math.random() * canvas.height, 1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adding white lines
|
||||||
|
for (let i = 0; i < 30; i++) {
|
||||||
|
ctx.strokeStyle = `rgba(255,255,255,${Math.random() * 1.8})`;
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(Math.random() * canvas.width, Math.random() * canvas.height);
|
||||||
|
ctx.lineTo(Math.random() * canvas.width, Math.random() * canvas.height);
|
||||||
|
ctx.stroke();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adding blue lines
|
||||||
|
for (let i = 0; i < 30; i++) {
|
||||||
|
ctx.strokeStyle = `rgba(0, 0, 255, ${Math.random() * 0.9})`;
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(Math.random() * canvas.width, Math.random() * canvas.height);
|
||||||
|
ctx.lineTo(Math.random() * canvas.width, Math.random() * canvas.height);
|
||||||
|
ctx.stroke();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rotation
|
||||||
|
const rotation = Math.random() * 0.2 - 0.1; // Random rotation between -0.1 and 0.1 radians
|
||||||
|
ctx.translate(canvas.width / 2, canvas.height / 2);
|
||||||
|
ctx.rotate(rotation);
|
||||||
|
ctx.translate(-canvas.width / 2, -canvas.height / 2);
|
||||||
|
|
||||||
|
const buffer = canvas.toBuffer('image/png');
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (interaction.channel.id !== cfg.guilds[guildId].channelId) {
|
||||||
|
return interaction.editReply({ content: cfg.messages.wrongChannel, ephemeral: true })
|
||||||
|
}
|
||||||
|
|
||||||
|
if (await client.db.get(`settings-${guildId}.verification`) === false) {
|
||||||
|
return interaction.editReply({ content: cfg.messages.verifyDisabled, ephemeral: true })
|
||||||
|
}
|
||||||
|
|
||||||
|
if (interaction.member.roles.cache.has(cfg.guilds[guildId].roleToAdd)) {
|
||||||
|
return interaction.editReply({ content: cfg.messages.alreadyVerified, ephemeral: true })
|
||||||
|
}
|
||||||
|
|
||||||
|
let attempts = 0;
|
||||||
|
let blacklisted = false;
|
||||||
|
const maxAttempts = cfg.maxAttempts;
|
||||||
|
let validated = false; // Flag to track if user is already validated
|
||||||
|
|
||||||
|
async function verifyUser(captcha) {
|
||||||
|
attempts++;
|
||||||
|
if (attempts > maxAttempts) {
|
||||||
|
await interaction.user.send(cfg.messages.maxAttemptsExceeded);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attempts == 1) {
|
||||||
|
// Check the Dangercord API using our custom library function
|
||||||
|
await dangercordcheckVerification(interaction.user.id)
|
||||||
|
.then(result => {
|
||||||
|
console.log('Verification result:', result);
|
||||||
|
if (result === 1) {
|
||||||
|
console.log(`${interaction.user.id} is not blacklisted at dangercord, lets continue with the verification process`)
|
||||||
|
// Proceed with further actions
|
||||||
|
} else {
|
||||||
|
console.log(`${interaction.user.id} is blacklisted at dangercord, we will not continue with the verification process`);
|
||||||
|
blacklisted = true; // Set blacklisted to true
|
||||||
|
// Handle the case when user is blacklisted
|
||||||
|
interaction.editReply({
|
||||||
|
content: cfg.messages.cannotContinue,
|
||||||
|
ephemeral: true
|
||||||
|
}).then(() => {
|
||||||
|
// Stop execution here
|
||||||
|
return;
|
||||||
|
}).catch(error => {
|
||||||
|
console.error('Error:', error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Error:', error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blacklisted == true) return
|
||||||
|
|
||||||
|
const buff = await createCaptcha(captcha);
|
||||||
|
const attachment = new AttachmentBuilder(buff, { name: 'captcha.png' });
|
||||||
|
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setTitle("Captcha Verification")
|
||||||
|
.setDescription(`Please type the captcha below. You have ${cfg.captchaTimeout / 1000} seconds to respond. Attempt ${attempts}/${maxAttempts}`)
|
||||||
|
.setColor('Green')
|
||||||
|
.setImage('attachment://captcha.png')
|
||||||
|
.setTimestamp();
|
||||||
|
|
||||||
|
await interaction.user.send({
|
||||||
|
embeds: [embed], files: [attachment]
|
||||||
|
}).then(async (msg) => {
|
||||||
|
await interaction.editReply({ content: cfg.messages.toVerify, ephemeral: true });
|
||||||
|
const filter = m => !m.author.bot && m.author.id === interaction.user.id && m.channel.id === msg.channel.id;
|
||||||
|
const collector = msg.channel.createMessageCollector({
|
||||||
|
filter,
|
||||||
|
time: cfg.captchaTimeout
|
||||||
|
});
|
||||||
|
|
||||||
|
collector.on('collect', async (m) => {
|
||||||
|
//if member left the server before the verification is done
|
||||||
|
if (!interaction.guild.members.cache.has(interaction.user.id)) {
|
||||||
|
await interaction.user.send(cfg.messages.userLeft);
|
||||||
|
collector.stop();
|
||||||
|
} else {
|
||||||
|
if (m.content === captcha) {
|
||||||
|
validated = true;
|
||||||
|
await interaction.member.roles.add(cfg.guilds[guildId].roleToAdd);
|
||||||
|
await interaction.member.roles.remove(cfg.guilds[guildId].firstRole);
|
||||||
|
await interaction.user.send(cfg.messages.success);
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
// If the content doesn't match captcha
|
||||||
|
collector.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
collector.on('end', async (collected, reason) => {
|
||||||
|
if (reason === 'time' && !validated) { // Send timeout message only if not already validated
|
||||||
|
await interaction.user.send(cfg.messages.tookTooLong);
|
||||||
|
} else if (!validated) {
|
||||||
|
// Only generate a new captcha and attempt verification if attempts < maxAttempts
|
||||||
|
const newCaptcha = await generateCaptcha(cfg.captchaCount);
|
||||||
|
await verifyUser(newCaptcha);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}).catch(async (err) => {
|
||||||
|
await interaction.editReply({
|
||||||
|
content: cfg.messages.unableToDM,
|
||||||
|
ephemeral: true
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const captcha = await generateCaptcha(cfg.captchaCount);
|
||||||
|
verifyUser(captcha);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Note from Naoki:
|
||||||
|
This looks simple enough but damn.
|
||||||
|
Canvas is driving me nuts due to how hard to work with it.
|
||||||
|
Had to StackOverFlow-ed it to get it to work.
|
||||||
|
I'm not sure if this is the best way to do it but it works.
|
||||||
|
Big shoutout to StackOverFlow and the people I got the code from.
|
||||||
|
*/
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
const cron = require('node-cron');
|
||||||
|
|
||||||
|
async function cronjob() {
|
||||||
|
cron.schedule('* * * * * *', async () => {
|
||||||
|
//run every .js file in the crons folder
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
const normalizedPath = path.join(__dirname, './crons');
|
||||||
|
fs.readdirSync(normalizedPath).forEach((file) => {
|
||||||
|
require(`./crons/${file}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = cronjob;
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
const cron = require('node-cron');
|
||||||
|
const client = require('..');
|
||||||
|
const ModerationAction = require('../database/models/ModerationAction');
|
||||||
|
const ModerationUtils = require('../database/models/ModerationUtils');
|
||||||
|
|
||||||
|
cron.schedule('* * * * * *', async () => {
|
||||||
|
|
||||||
|
const guilds = await ModerationAction.find({});
|
||||||
|
|
||||||
|
for (const guild of guilds) {
|
||||||
|
const warns = await ModerationUtils.find({ guildId: guild.guildId });
|
||||||
|
|
||||||
|
//check if user is in the guild
|
||||||
|
const guild = client.guilds.cache.get(guild.guildId);
|
||||||
|
if (!guild) return;
|
||||||
|
|
||||||
|
for (const warn of warns) {
|
||||||
|
const member = guild.members.cache.get(warn.userId);
|
||||||
|
if (!member) return;
|
||||||
|
|
||||||
|
switch (warn.warns) {
|
||||||
|
case guild.firstThreshold:
|
||||||
|
member.send(guild.firstAction);
|
||||||
|
break;
|
||||||
|
case guild.secondThreshold:
|
||||||
|
member.send(guild.secondAction);
|
||||||
|
break;
|
||||||
|
case guild.thirdThreshold:
|
||||||
|
member.send(guild.thirdAction);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
const mongoose = require('mongoose');
|
||||||
|
const { mongouri } = require('../config/config.js');
|
||||||
|
|
||||||
|
async function connect() {
|
||||||
|
mongoose.connect(mongouri.replace('<password>', process.env.MONGOPASS), {
|
||||||
|
useNewUrlParser: true,
|
||||||
|
useUnifiedTopology: true,
|
||||||
|
autoIndex: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
mongoose.connection.once('open', () => {
|
||||||
|
console.log('Connection to the database has been established.');
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = connect;
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
const mongoose = require('mongoose');
|
||||||
|
|
||||||
|
const GuildSettings = new mongoose.Schema(
|
||||||
|
{
|
||||||
|
guildId: {
|
||||||
|
type: mongoose.SchemaTypes.String,
|
||||||
|
required: true,
|
||||||
|
unique: true
|
||||||
|
},
|
||||||
|
verifyEnabled: {
|
||||||
|
type: mongoose.SchemaTypes.String,
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
antiNewUserEnabled: {
|
||||||
|
type: mongoose.SchemaTypes.String,
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
module.exports = mongoose.model('GuildSettings', GuildSettings);
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
const mongoose = require('mongoose');
|
||||||
|
|
||||||
|
const ModerationAction = new mongoose.Schema(
|
||||||
|
{
|
||||||
|
guildId: {
|
||||||
|
type: mongoose.SchemaTypes.String,
|
||||||
|
required: true,
|
||||||
|
unique: true
|
||||||
|
},
|
||||||
|
firstAction: {
|
||||||
|
type: mongoose.SchemaTypes.String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
secondAction: {
|
||||||
|
type: mongoose.SchemaTypes.String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
thirdAction: {
|
||||||
|
type: mongoose.SchemaTypes.String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
firstThreshold: {
|
||||||
|
type: mongoose.SchemaTypes.Number,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
secondThreshold: {
|
||||||
|
type: mongoose.SchemaTypes.Number,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
thirdThreshold: {
|
||||||
|
type: mongoose.SchemaTypes.Number,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
module.exports = mongoose.model('ModerationAction', ModerationAction);
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
const mongoose = require('mongoose');
|
||||||
|
|
||||||
|
const ModerationUtils = new mongoose.Schema(
|
||||||
|
{
|
||||||
|
guildId: {
|
||||||
|
type: mongoose.SchemaTypes.String,
|
||||||
|
required: true,
|
||||||
|
unique: true
|
||||||
|
},
|
||||||
|
caseId: {
|
||||||
|
type: mongoose.SchemaTypes.Number,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
target: {
|
||||||
|
type: mongoose.SchemaTypes.String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
moderator: {
|
||||||
|
type: mongoose.SchemaTypes.String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
reason: {
|
||||||
|
type: mongoose.SchemaTypes.String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
duration: {
|
||||||
|
type: mongoose.SchemaTypes.String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
action: {
|
||||||
|
type: mongoose.SchemaTypes.String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
proof: {
|
||||||
|
type: mongoose.SchemaTypes.String,
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
timestamp: {
|
||||||
|
type: mongoose.SchemaTypes.String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
alreadyPunished: {
|
||||||
|
type: mongoose.SchemaTypes.Boolean,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = mongoose.model('ModerationUtils', ModerationUtils);
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
const mongoose = require('mongoose');
|
||||||
|
|
||||||
|
const NewUserAction = new mongoose.Schema(
|
||||||
|
{
|
||||||
|
guildId: {
|
||||||
|
type: mongoose.SchemaTypes.String,
|
||||||
|
required: true,
|
||||||
|
unique: true
|
||||||
|
},
|
||||||
|
action: {
|
||||||
|
type: mongoose.SchemaTypes.String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
reason: {
|
||||||
|
type: mongoose.SchemaTypes.String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
threshold: {
|
||||||
|
type: mongoose.SchemaTypes.Number,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
duration: {
|
||||||
|
type: mongoose.SchemaTypes.String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
module.exports = mongoose.model('NewUserAction', NewUserAction);
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
const mongoose = require('mongoose');
|
||||||
|
|
||||||
|
const VerifyFailAction = new mongoose.Schema(
|
||||||
|
{
|
||||||
|
guildId: {
|
||||||
|
type: mongoose.SchemaTypes.String,
|
||||||
|
required: true,
|
||||||
|
unique: true
|
||||||
|
},
|
||||||
|
action: {
|
||||||
|
type: mongoose.SchemaTypes.String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
reason: {
|
||||||
|
type: mongoose.SchemaTypes.String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
threshold: {
|
||||||
|
type: mongoose.SchemaTypes.Number,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
duration: {
|
||||||
|
type: mongoose.SchemaTypes.String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
module.exports = mongoose.model('VerifyFailAction', VerifyFailAction);
|
||||||
+20
-8
@@ -6,17 +6,29 @@ client.on('ready', () => {
|
|||||||
console.log(chalk.green(`Logged in as ${client.user.tag}!`));
|
console.log(chalk.green(`Logged in as ${client.user.tag}!`));
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
let activities = [
|
let activities = [
|
||||||
{ type: "Playing", name: "/verify" },
|
{ type: "Playing", name: "with /verify command." },
|
||||||
{ type: "Playing", name: "Securing our servers" },
|
{ type: "Playing", name: "whilst securing our servers." },
|
||||||
{ type: "Watching", name: `Watching bans...` },
|
{ type: "Watching", name: `for the shooting stars.` },
|
||||||
|
{ type: "Watching", name: `over everyone.` },
|
||||||
|
{ type: "Watching", name: `for the storm that is approaching.` },
|
||||||
|
{ type: "Listening", name: "the sound of silence." },
|
||||||
|
{ type: "Listening", name: "the sound of the rain." },
|
||||||
|
{ type: "Listening", name: "the sound of the wind." }
|
||||||
];
|
];
|
||||||
|
|
||||||
const status = activities[Math.floor(Math.random() * activities.length)];
|
const status = activities[Math.floor(Math.random() * activities.length)];
|
||||||
|
|
||||||
if (status.type === "Watching") {
|
switch (status.type) {
|
||||||
client.user.setPresence({ activities: [{ name: `${status.name}`, type: ActivityType.Watching }] });
|
case "Playing":
|
||||||
} else {
|
client.user.setPresence({ activities: [{ name: `${status.name}`, type: ActivityType.Playing }] });
|
||||||
client.user.setPresence({ activities: [{ name: `${status.name}`, type: ActivityType.Playing }] });
|
break;
|
||||||
|
case "Watching":
|
||||||
|
client.user.setPresence({ activities: [{ name: `${status.name}`, type: ActivityType.Watching }] });
|
||||||
|
break;
|
||||||
|
case "Listening":
|
||||||
|
client.user.setPresence({ activities: [{ name: `${status.name}`, type: ActivityType.Listening }] });
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}, 300000); // update every 5 mins
|
|
||||||
|
}, 30000); // update every 5 mins
|
||||||
});
|
});
|
||||||
|
|||||||
+115
-9
@@ -1,19 +1,125 @@
|
|||||||
const client = require('..');
|
const client = require('..');
|
||||||
|
const moment = require('moment');
|
||||||
|
const GuildSettings = require('../database/models/GuildSettings');
|
||||||
|
const NewUserAction = require('../database/models/NewUserAction');
|
||||||
|
const { convertActionDurationFromTimeToMs, getActionDuration, moderationUtilities } = require('./utils.js');
|
||||||
|
|
||||||
async function newUserKicker(member) {
|
async function newUserKicker(member) {
|
||||||
const guildId = member.guild.id;
|
const guildId = member.guild.id;
|
||||||
const db = await client.db.get(`settings-${guildId}`) || {};
|
const newUserAction = await NewUserAction.findOne({ guildId: guildId });
|
||||||
const threshold = db.newUserKickerThreshold;
|
const guildSettings = await GuildSettings.findOne({ guildId: guildId });
|
||||||
|
const threshold = newUserAction.threshold;
|
||||||
|
|
||||||
const accountAge = (Date.now() - member.user.createdAt) / (1000 * 60 * 60 * 24);
|
const accountAge = (Date.now() - member.user.createdAt) / (1000 * 60 * 60 * 24);
|
||||||
if (accountAge <= threshold) {
|
|
||||||
member.kick('Account age is less than the threshold.');
|
switch (guildSettings?.antiNewUserEnabled) {
|
||||||
console.log(`Account age of ${member.user.tag} is ${accountAge.toFixed(0)} day(s) which is lower than the threshold. Kicked.`);
|
case 'true': {
|
||||||
return 0; // Not allowed to continue
|
switch (accountAge) {
|
||||||
} else {
|
case accountAge <= threshold: {
|
||||||
console.log(`Account age of ${member.user.tag} is ${accountAge.toFixed(0)} day(s) which is higher than the threshold. Not kicked.`);
|
switch (newUserAction?.action) {
|
||||||
return 1; // Allowed to continue
|
case 'kick': {
|
||||||
|
await moderationUtilities(
|
||||||
|
guildId,
|
||||||
|
member.user.id,
|
||||||
|
client.user.id,
|
||||||
|
'Account age is less than the threshold.',
|
||||||
|
'kick',
|
||||||
|
null
|
||||||
|
);
|
||||||
|
member.kick('Account age is less than the threshold.');
|
||||||
|
console.log(`Account age of ${member.user.tag} is ${accountAge.toFixed(0)} day(s) which is lower than the threshold. Kicked.`);
|
||||||
|
return 0; // Not allowed to continue
|
||||||
|
}
|
||||||
|
case 'ban': {
|
||||||
|
switch (newUserAction?.duration) {
|
||||||
|
case 0: {
|
||||||
|
await moderationUtilities(
|
||||||
|
guildId,
|
||||||
|
member.user.id,
|
||||||
|
client.user.id,
|
||||||
|
'Account age is less than the threshold.',
|
||||||
|
'ban',
|
||||||
|
'Permanent'
|
||||||
|
);
|
||||||
|
member.ban({ reason: 'Account age is less than the threshold.' });
|
||||||
|
console.log(`Account age of ${member.user.tag} is ${accountAge.toFixed(0)} day(s) which is lower than the threshold. Banned.`);
|
||||||
|
return 0; // Not allowed to continue
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
await moderationUtilities(
|
||||||
|
guildId,
|
||||||
|
member.user.id,
|
||||||
|
client.user.id,
|
||||||
|
'Account age is less than the threshold.',
|
||||||
|
'ban',
|
||||||
|
await getActionDuration(newUserAction?.duration)
|
||||||
|
);
|
||||||
|
member.ban({ days: await convertActionDurationFromTimeToMs(newUserAction?.duration), reason: 'Account age is less than the threshold.' });
|
||||||
|
console.log(`Account age of ${member.user.tag} is ${accountAge.toFixed(0)} day(s) which is lower than the threshold. Banned.`);
|
||||||
|
return 0; // Not allowed to continue
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case 'timeout': {
|
||||||
|
switch (newUserAction?.duration) {
|
||||||
|
case 0: {
|
||||||
|
await moderationUtilities(
|
||||||
|
guildId,
|
||||||
|
member.user.id,
|
||||||
|
client.user.id,
|
||||||
|
'Account age is less than the threshold.',
|
||||||
|
'timeout',
|
||||||
|
await getActionDuration('5m')
|
||||||
|
);
|
||||||
|
member.timeout({ timeout: await convertActionDurationFromTimeToMs('5m'), reason: 'Account age is less than the threshold.' });
|
||||||
|
console.log(`Account age of ${member.user.tag} is ${accountAge.toFixed(0)} day(s) which is lower than the threshold. Timed out.`);
|
||||||
|
return 0; // Not allowed to continue
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
await moderationUtilities(
|
||||||
|
guildId,
|
||||||
|
member.user.id,
|
||||||
|
client.user.id,
|
||||||
|
'Account age is less than the threshold.',
|
||||||
|
'timeout',
|
||||||
|
await getActionDuration(newUserAction?.duration)
|
||||||
|
);
|
||||||
|
member.timeout({ timeout: await convertActionDurationFromTimeToMs(newUserAction?.duration), reason: 'Account age is less than the threshold.' });
|
||||||
|
console.log(`Account age of ${member.user.tag} is ${accountAge.toFixed(0)} day(s) which is lower than the threshold. Timed out.`);
|
||||||
|
return 0; // Not allowed to continue
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case 'warn': {
|
||||||
|
await moderationUtilities(
|
||||||
|
guildId,
|
||||||
|
member.user.id,
|
||||||
|
client.user.id,
|
||||||
|
newUserAction?.reason || 'Account age is less than the threshold.',
|
||||||
|
'warn',
|
||||||
|
null
|
||||||
|
);
|
||||||
|
console.log(`Account age of ${member.user.tag} is ${accountAge.toFixed(0)} day(s) which is lower than the threshold. Warned.`);
|
||||||
|
return 0; // Not allowed to continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (accountAge <= threshold) {
|
||||||
|
member.kick('Account age is less than the threshold.');
|
||||||
|
console.log(`Account age of ${member.user.tag} is ${accountAge.toFixed(0)} day(s) which is lower than the threshold. Kicked.`);
|
||||||
|
return 0; // Not allowed to continue
|
||||||
|
} else {
|
||||||
|
console.log(`Account age of ${member.user.tag} is ${accountAge.toFixed(0)} day(s) which is higher than the threshold. Not kicked.`);
|
||||||
|
return 1; // Allowed to continue
|
||||||
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|||||||
@@ -0,0 +1,122 @@
|
|||||||
|
const GuildSettings = require('../database/models/GuildSettings');
|
||||||
|
const NewUserAction = require('../database/models/NewUserAction');
|
||||||
|
const ModerationUtils = require('../database/models/ModerationUtils');
|
||||||
|
|
||||||
|
async function convertActionDurationFromTimeToMs(duration) {
|
||||||
|
if (!duration) return;
|
||||||
|
|
||||||
|
const matches = duration?.match(/^(\d+)([smhdwMy])$/);
|
||||||
|
const ms = [];
|
||||||
|
|
||||||
|
if (matches) {
|
||||||
|
const value = parseInt(matches[1]);
|
||||||
|
const unit = matches[2];
|
||||||
|
|
||||||
|
let milliseconds;
|
||||||
|
switch (unit) {
|
||||||
|
case 'ms':
|
||||||
|
milliseconds = value;
|
||||||
|
ms.push(milliseconds);
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
milliseconds = value * 1000;
|
||||||
|
ms.push(milliseconds);
|
||||||
|
break;
|
||||||
|
case 'm':
|
||||||
|
milliseconds = value * 60 * 1000;
|
||||||
|
ms.push(milliseconds);
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
milliseconds = value * 60 * 60 * 1000;
|
||||||
|
ms.push(milliseconds);
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
milliseconds = value * 24 * 60 * 60 * 1000;
|
||||||
|
ms.push(milliseconds);
|
||||||
|
break;
|
||||||
|
case 'w':
|
||||||
|
milliseconds = value * 7 * 24 * 60 * 60 * 1000;
|
||||||
|
ms.push(milliseconds);
|
||||||
|
break;
|
||||||
|
case 'M':
|
||||||
|
milliseconds = value * 30 * 24 * 60 * 60 * 1000;
|
||||||
|
ms.push(milliseconds);
|
||||||
|
break;
|
||||||
|
case 'y':
|
||||||
|
milliseconds = value * 365 * 24 * 60 * 60 * 1000;
|
||||||
|
ms.push(milliseconds);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 'Invalid duration';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const sum = ms.reduce((a, b) => a + b, 0);
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getActionDuration(duration) {
|
||||||
|
if (!duration) return;
|
||||||
|
|
||||||
|
const matches = duration?.matchAll(/(\d+)([smhdwMy])/g);
|
||||||
|
|
||||||
|
const humanizedDuration = [];
|
||||||
|
for (const match of matches) {
|
||||||
|
const value = parseInt(match[1]);
|
||||||
|
const unit = match[2];
|
||||||
|
|
||||||
|
switch (unit) {
|
||||||
|
case 'ms':
|
||||||
|
humanizedDuration.push(value + ' milliseconds');
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
humanizedDuration.push(value + ' seconds');
|
||||||
|
break;
|
||||||
|
case 'm':
|
||||||
|
humanizedDuration.push(value + ' minutes');
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
humanizedDuration.push(value + ' hours');
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
humanizedDuration.push(value + ' days');
|
||||||
|
break;
|
||||||
|
case 'w':
|
||||||
|
humanizedDuration.push(value + ' weeks');
|
||||||
|
break;
|
||||||
|
case 'M':
|
||||||
|
humanizedDuration.push(value + ' months');
|
||||||
|
break;
|
||||||
|
case 'y':
|
||||||
|
humanizedDuration.push(value + ' years');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 'Invalid duration';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return humanizedDuration.join(', and ');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async function moderationUtilities(guildId, target, moderator, reason, action, duration) {
|
||||||
|
const moderationUtils = await ModerationUtils.findOne({ guildId: guildId });
|
||||||
|
|
||||||
|
await moderationUtils.create({
|
||||||
|
guildId: guildId,
|
||||||
|
caseId: moderationUtils.caseId + 1 || 1,
|
||||||
|
target: target,
|
||||||
|
moderator: moderator,
|
||||||
|
reason: reason,
|
||||||
|
duration: duration,
|
||||||
|
action: action,
|
||||||
|
timestamp: Date.now()
|
||||||
|
});
|
||||||
|
await moderationUtils.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
convertActionDurationFromTimeToMs,
|
||||||
|
getActionDuration,
|
||||||
|
moderationUtilities
|
||||||
|
};
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
const { Client, Collection, Permissions, GatewayIntentBits, Partials } = require('discord.js');
|
const { Client, Collection, Permissions, GatewayIntentBits, Partials } = require('discord.js');
|
||||||
const { QuickDB } = require('quick.db');
|
|
||||||
require('dotenv').config();
|
require('dotenv').config();
|
||||||
|
|
||||||
const client = new Client({
|
const client = new Client({
|
||||||
@@ -17,11 +16,13 @@ const client = new Client({
|
|||||||
Partials.User,
|
Partials.User,
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
const db = new QuickDB();
|
|
||||||
|
|
||||||
module.exports = client;
|
module.exports = client;
|
||||||
|
|
||||||
client.db = db;
|
(async () => {
|
||||||
|
require('./database/connect')();
|
||||||
|
require('./cron/cronjob')();
|
||||||
|
})();
|
||||||
|
|
||||||
client.commands = new Collection();
|
client.commands = new Collection();
|
||||||
client.aliases = new Collection();
|
client.aliases = new Collection();
|
||||||
client.slashCommands = new Collection();
|
client.slashCommands = new Collection();
|
||||||
|
|||||||
@@ -21,6 +21,9 @@
|
|||||||
"discord.js": "^14.14.1",
|
"discord.js": "^14.14.1",
|
||||||
"dotenv": "^16.4.1",
|
"dotenv": "^16.4.1",
|
||||||
"fs": "^0.0.1-security",
|
"fs": "^0.0.1-security",
|
||||||
|
"moment": "^2.30.1",
|
||||||
|
"mongoose": "^6.7.0",
|
||||||
|
"node-cron": "^3.0.3",
|
||||||
"quick.db": "^9.1.7"
|
"quick.db": "^9.1.7"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+437
-92
@@ -1,5 +1,6 @@
|
|||||||
const { ApplicationCommandType, ApplicationCommandOptionType, EmbedBuilder } = require('discord.js');
|
const { ApplicationCommandType, ApplicationCommandOptionType, EmbedBuilder } = require('discord.js');
|
||||||
const cfg = require('../../config/config.js');
|
const cfg = require('../../config/config.js');
|
||||||
|
const { getActionDuration, convertActionDurationFromMsToTime, convertActionDurationFromTimeToMs } = require('../../functions/utils.js');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
name: 'settings',
|
name: 'settings',
|
||||||
@@ -7,14 +8,31 @@ module.exports = {
|
|||||||
type: ApplicationCommandType.ChatInput,
|
type: ApplicationCommandType.ChatInput,
|
||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
name: 'verification',
|
name: 'change',
|
||||||
description: 'Enable or disable, or change the settings of verification.',
|
description: 'Set the settings of the bot.',
|
||||||
type: ApplicationCommandOptionType.Subcommand,
|
type: ApplicationCommandOptionType.Subcommand,
|
||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
name: 'enable-or-disable',
|
name: 'set',
|
||||||
description: 'Enable or disable verification.',
|
description: 'The settings to change.',
|
||||||
type: ApplicationCommandOptionType.String,
|
type: ApplicationCommandOptionType.String,
|
||||||
|
required: true,
|
||||||
|
choices: [
|
||||||
|
{
|
||||||
|
name: 'Verification',
|
||||||
|
value: 'verification'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Anti New User',
|
||||||
|
value: 'anti-new-user'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'enable-or-disable',
|
||||||
|
description: 'Enable or disable the setting.',
|
||||||
|
type: ApplicationCommandOptionType.String,
|
||||||
|
required: false,
|
||||||
choices: [
|
choices: [
|
||||||
{
|
{
|
||||||
name: 'Enable',
|
name: 'Enable',
|
||||||
@@ -24,122 +42,449 @@ module.exports = {
|
|||||||
name: 'Disable',
|
name: 'Disable',
|
||||||
value: 'false'
|
value: 'false'
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
required: true
|
|
||||||
},
|
},
|
||||||
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'new-user-kicker',
|
|
||||||
description: 'Enable or disable, or change the settings of new user kicker.',
|
|
||||||
type: ApplicationCommandOptionType.Subcommand,
|
|
||||||
options: [
|
|
||||||
{
|
{
|
||||||
name: 'enable-or-disable',
|
name: 'automod-action',
|
||||||
description: 'Enable or disable new user kicker.',
|
description: 'The action to take when the threshold is reached.',
|
||||||
type: ApplicationCommandOptionType.String,
|
type: ApplicationCommandOptionType.String,
|
||||||
|
required: false,
|
||||||
choices: [
|
choices: [
|
||||||
{
|
{
|
||||||
name: 'Enable',
|
name: 'Timeout',
|
||||||
value: 'true'
|
value: 'Timeout'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Disable',
|
name: 'Warn',
|
||||||
value: 'false'
|
value: 'warn'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Kick',
|
||||||
|
value: 'kick'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Ban',
|
||||||
|
value: 'ban'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'None',
|
||||||
|
value: 'none'
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
required: true
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'threshold',
|
name: 'automod-action-reason',
|
||||||
description: 'Set the amount of days user account age to kick.',
|
description: 'The reason for the action.',
|
||||||
|
type: ApplicationCommandOptionType.String,
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'automod-action-threshold',
|
||||||
|
description: 'The threshold for the setting.',
|
||||||
type: ApplicationCommandOptionType.Integer,
|
type: ApplicationCommandOptionType.Integer,
|
||||||
required: false
|
required: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'automod-action-duration',
|
||||||
|
description: 'The duration for the action.',
|
||||||
|
type: ApplicationCommandOptionType.String,
|
||||||
|
required: false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'check',
|
name: 'check',
|
||||||
description: 'Check the current settings of the bot.',
|
description: 'Check the current settings of the bot.',
|
||||||
type: ApplicationCommandOptionType.Subcommand
|
type: ApplicationCommandOptionType.Subcommand,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'settings',
|
||||||
|
description: 'The settings to check.',
|
||||||
|
type: ApplicationCommandOptionType.String,
|
||||||
|
required: true,
|
||||||
|
choices: [
|
||||||
|
{
|
||||||
|
name: 'General',
|
||||||
|
value: 'general'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Actions',
|
||||||
|
value: 'actions'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'All',
|
||||||
|
value: 'all'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'reset',
|
name: 'reset',
|
||||||
description: 'Reset the settings of the bot.',
|
description: 'Reset the settings of the bot.',
|
||||||
type: ApplicationCommandOptionType.Subcommand
|
type: ApplicationCommandOptionType.Subcommand
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'rawcheck',
|
||||||
|
description: 'Check the raw settings of the bot.',
|
||||||
|
type: ApplicationCommandOptionType.Subcommand
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
default_member_permissions: ["Administrator"],
|
default_member_permissions: ["Administrator"],
|
||||||
run: async (client, interaction) => {
|
run: async (client, interaction) => {
|
||||||
await interaction.deferReply({ ephemeral: true });
|
await interaction.deferReply({ ephemeral: true });
|
||||||
const subcommand = interaction.options.getSubcommand();
|
const filter = {
|
||||||
const guildId = interaction.guild.id;
|
guildId: interaction.guild.id
|
||||||
const settings = await client.db.get(`settings-${guildId}`) || {};
|
|
||||||
|
|
||||||
if (subcommand === 'verification') {
|
|
||||||
const value = interaction.options.getString('enable-or-disable');
|
|
||||||
if (value === 'true') {
|
|
||||||
await client.db.set(
|
|
||||||
`settings-${guildId}.verification`,
|
|
||||||
true
|
|
||||||
)
|
|
||||||
return interaction.editReply({ content: 'Verification has been enabled.' });
|
|
||||||
} else {
|
|
||||||
await client.db.set(
|
|
||||||
`settings-${guildId}.verification`,
|
|
||||||
false
|
|
||||||
)
|
|
||||||
return interaction.editReply({ content: 'Verification has been disabled.' });
|
|
||||||
}
|
|
||||||
} else if (subcommand === 'new-user-kicker') {
|
|
||||||
const value = interaction.options.getString('enable-or-disable');
|
|
||||||
if (value === 'true') {
|
|
||||||
const threshold = interaction.options.getInteger('threshold') || 7;
|
|
||||||
await client.db.set(
|
|
||||||
`settings-${guildId}.newUserKicker`,
|
|
||||||
true
|
|
||||||
)
|
|
||||||
await client.db.set(
|
|
||||||
`settings-${guildId}.newUserKickerThreshold`,
|
|
||||||
threshold
|
|
||||||
)
|
|
||||||
return interaction.editReply({ content: `New user kicker has been enabled with a threshold of ${threshold} days.` });
|
|
||||||
} else {
|
|
||||||
await client.db.set(
|
|
||||||
`settings-${guildId}.newUserKicker`,
|
|
||||||
false
|
|
||||||
)
|
|
||||||
await client.db.delete(`settings-${guildId}.newUserKickerThreshold`);
|
|
||||||
return interaction.editReply({ content: `New user kicker has been disabled.` });
|
|
||||||
}
|
|
||||||
} else if (subcommand === 'check') {
|
|
||||||
const embed = new EmbedBuilder()
|
|
||||||
.setTitle('Bot Settings')
|
|
||||||
.setColor('Green')
|
|
||||||
.setTimestamp();
|
|
||||||
|
|
||||||
if (settings.verification === true) {
|
|
||||||
embed.addFields({ name: 'Verification', value: 'Enabled' })
|
|
||||||
} else {
|
|
||||||
embed.addFields({ name: 'Verification', value: 'Disabled' })
|
|
||||||
}
|
|
||||||
|
|
||||||
if (settings.newUserKicker === true) {
|
|
||||||
embed.addFields(
|
|
||||||
{
|
|
||||||
name: 'New User Kicker',
|
|
||||||
value: `Enabled with a threshold of ${settings.newUserKickerThreshold} days.`
|
|
||||||
}
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
embed.addFields({ name: 'New User Kicker', value: 'Disabled' })
|
|
||||||
}
|
|
||||||
|
|
||||||
return interaction.editReply({ embeds: [embed] });
|
|
||||||
} else if (subcommand === 'reset') {
|
|
||||||
await client.db.delete(`settings-${guildId}`);
|
|
||||||
return interaction.editReply({ content: 'Settings have been reset.' });
|
|
||||||
}
|
}
|
||||||
|
const subcommand = interaction.options.getSubcommand();
|
||||||
|
const settings = interaction.options.get('set')?.value;
|
||||||
|
const enableOrDisable = interaction.options.get('enable-or-disable')?.value;
|
||||||
|
const automodAction = interaction.options.get('automod-action')?.value;
|
||||||
|
const automodActionReason = interaction.options.get('automod-action-reason')?.value;
|
||||||
|
const automodActionThreshold = interaction.options.get('automod-action-threshold')?.value;
|
||||||
|
const automodActionDuration = interaction.options.get('automod-action-duration')?.value;
|
||||||
|
const checksettings = interaction.options.get('settings')?.value;
|
||||||
|
|
||||||
|
const GuildSettings = require('../../database/models/GuildSettings');
|
||||||
|
const NewUserAction = require('../../database/models/NewUserAction.js');
|
||||||
|
const VerifyFailAction = require('../../database/models/VerifyFailAction.js');
|
||||||
|
const guildSettings = await GuildSettings.findOne(filter);
|
||||||
|
const newUserAction = await NewUserAction.findOne(filter);
|
||||||
|
const verifyFailAction = await VerifyFailAction.findOne(filter);
|
||||||
|
|
||||||
|
switch (subcommand) {
|
||||||
|
case 'change':
|
||||||
|
switch (settings) {
|
||||||
|
case 'verification':
|
||||||
|
switch (automodAction) {
|
||||||
|
case undefined:
|
||||||
|
console.log('a')
|
||||||
|
switch (enableOrDisable) {
|
||||||
|
case 'true': case 'false':
|
||||||
|
console.log(enableOrDisable)
|
||||||
|
switch (guildSettings) {
|
||||||
|
case null:
|
||||||
|
const newGuildSettings = new GuildSettings({
|
||||||
|
guildId: interaction.guild.id,
|
||||||
|
verifyEnabled: enableOrDisable
|
||||||
|
});
|
||||||
|
await newGuildSettings.save();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
guildSettings.verifyEnabled = enableOrDisable;
|
||||||
|
await guildSettings.save();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'none':
|
||||||
|
console.log('b')
|
||||||
|
await VerifyFailAction.find(filter).deleteMany();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.log('c')
|
||||||
|
switch (enableOrDisable) {
|
||||||
|
case 'true': case 'false':
|
||||||
|
switch (guildSettings) {
|
||||||
|
case null:
|
||||||
|
const newGuildSettings = new GuildSettings({
|
||||||
|
guildId: interaction.guild.id,
|
||||||
|
verifyEnabled: enableOrDisable
|
||||||
|
});
|
||||||
|
await newGuildSettings.save();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
guildSettings.verifyEnabled = enableOrDisable;
|
||||||
|
await guildSettings.save();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch (verifyFailAction) {
|
||||||
|
case null:
|
||||||
|
const newVerifyFailAction = new VerifyFailAction({
|
||||||
|
guildId: interaction.guild.id,
|
||||||
|
action: automodAction,
|
||||||
|
reason: automodActionReason || 'User failed to verify.',
|
||||||
|
threshold: automodActionThreshold || 3,
|
||||||
|
duration: automodActionDuration || '7d'
|
||||||
|
});
|
||||||
|
await newVerifyFailAction.save();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
verifyFailAction.action = automodAction || verifyFailAction?.action;
|
||||||
|
verifyFailAction.reason = `${automodActionReason?.toString()}` || verifyFailAction?.reason || 'User failed to verify.';
|
||||||
|
verifyFailAction.threshold = automodActionThreshold || verifyFailAction?.threshold || 3;
|
||||||
|
verifyFailAction.duration = automodActionDuration || verifyFailAction?.duration || '7d';
|
||||||
|
await verifyFailAction.save();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'anti-new-user':
|
||||||
|
switch (automodAction) {
|
||||||
|
case undefined:
|
||||||
|
switch (enableOrDisable) {
|
||||||
|
case 'true': case 'false':
|
||||||
|
switch (guildSettings) {
|
||||||
|
case null:
|
||||||
|
const newGuildSettings = new GuildSettings({
|
||||||
|
guildId: interaction.guild.id,
|
||||||
|
antiNewUserEnabled: enableOrDisable
|
||||||
|
});
|
||||||
|
await newGuildSettings.save();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
guildSettings.antiNewUserEnabled = enableOrDisable;
|
||||||
|
await guildSettings.save();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'none':
|
||||||
|
await NewUserAction.find(filter).deleteMany();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
switch (enableOrDisable) {
|
||||||
|
case 'true': case 'false':
|
||||||
|
switch (guildSettings) {
|
||||||
|
case null:
|
||||||
|
const newGuildSettings = new GuildSettings({
|
||||||
|
guildId: interaction.guild.id,
|
||||||
|
antiNewUserEnabled: enableOrDisable
|
||||||
|
});
|
||||||
|
await newGuildSettings.save();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
guildSettings.antiNewUserEnabled = enableOrDisable;
|
||||||
|
await guildSettings.save();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch (newUserAction) {
|
||||||
|
case null:
|
||||||
|
const newNewUserAction = new NewUserAction({
|
||||||
|
guildId: interaction.guild.id,
|
||||||
|
action: automodAction,
|
||||||
|
reason: automodActionReason || 'User account age is way too low.',
|
||||||
|
threshold: automodActionThreshold || 3,
|
||||||
|
duration: automodActionDuration || '7d'
|
||||||
|
});
|
||||||
|
await newNewUserAction.save();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
newUserAction.action = automodAction || newUserAction?.action;
|
||||||
|
newUserAction.reason = `${automodActionReason?.toString()}` || newUserAction?.reason || 'User account age is way too low.';
|
||||||
|
newUserAction.threshold = automodActionThreshold || newUserAction?.threshold || 3;
|
||||||
|
newUserAction.duration = automodActionDuration || newUserAction?.duration || '7d';
|
||||||
|
await newUserAction.save();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
await interaction.editReply({ content: 'Settings have been updated.' });
|
||||||
|
break;
|
||||||
|
case 'check':
|
||||||
|
function verification() {
|
||||||
|
if (guildSettings?.verifyEnabled === 'true') {
|
||||||
|
return 'Enabled';
|
||||||
|
} else if (guildSettings?.verifyEnabled === 'false') {
|
||||||
|
return 'Disabled';
|
||||||
|
} else {
|
||||||
|
return 'Disabled';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function antiNewUser() {
|
||||||
|
if (guildSettings?.antiNewUserEnabled === 'true') {
|
||||||
|
return 'Enabled';
|
||||||
|
} else if (guildSettings?.antiNewUserEnabled === 'false') {
|
||||||
|
return 'Disabled';
|
||||||
|
} else {
|
||||||
|
return 'Disabled';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setTitle('Settings')
|
||||||
|
.addFields({
|
||||||
|
name: 'Verification',
|
||||||
|
value: `${verification()}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Anti New User',
|
||||||
|
value: `${antiNewUser()}`,
|
||||||
|
})
|
||||||
|
.setColor("Gold");
|
||||||
|
|
||||||
|
const embedd = new EmbedBuilder()
|
||||||
|
.setTitle('Settings')
|
||||||
|
.addFields({
|
||||||
|
name: 'Verification Auto Action',
|
||||||
|
value: `${verifyFailAction ? `Action: ${verifyFailAction?.action.toUpperCase()}\nReason: ${verifyFailAction?.reason}\nThreshold: ${verifyFailAction?.threshold}\nDuration: ${await getActionDuration(verifyFailAction?.duration)}` : "None"}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Anti New User Auto Action',
|
||||||
|
value: `${newUserAction ? `Action: ${newUserAction?.action.toUpperCase()}\nReason: ${newUserAction?.reason}\nThreshold: ${newUserAction?.threshold}\nDuration: ${await getActionDuration(newUserAction?.duration)}` : "None"}`,
|
||||||
|
})
|
||||||
|
.setColor("Gold");
|
||||||
|
|
||||||
|
console.log(verifyFailAction?.duration, await getActionDuration(verifyFailAction?.duration), await convertActionDurationFromTimeToMs(verifyFailAction?.duration));
|
||||||
|
console.log(newUserAction?.duration, await getActionDuration(newUserAction?.duration), await convertActionDurationFromTimeToMs(newUserAction?.duration));
|
||||||
|
|
||||||
|
switch (checksettings) {
|
||||||
|
case 'general':
|
||||||
|
await interaction.editReply({ embeds: [embed] });
|
||||||
|
break;
|
||||||
|
case 'actions':
|
||||||
|
await interaction.editReply({ embeds: [embedd] });
|
||||||
|
break;
|
||||||
|
case 'all':
|
||||||
|
await interaction.editReply({ embeds: [embed, embedd] });
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'reset':
|
||||||
|
await GuildSettings.find(filter).deleteMany();
|
||||||
|
await NewUserAction.find(filter).deleteMany();
|
||||||
|
await VerifyFailAction.find(filter).deleteMany();
|
||||||
|
await interaction.editReply({ content: 'Settings have been reset.' });
|
||||||
|
break;
|
||||||
|
case 'rawcheck':
|
||||||
|
console.log(guildSettings);
|
||||||
|
console.log(verifyFailAction);
|
||||||
|
console.log(newUserAction);
|
||||||
|
await interaction.editReply({ content: 'Check the console.' });
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (settings === 'verification') {
|
||||||
|
console.log('a')
|
||||||
|
if (automodAction === undefined) {
|
||||||
|
console.log('i')
|
||||||
|
if (enableOrDisable !== undefined) {
|
||||||
|
if (guildSettings === null) {
|
||||||
|
const newGuildSettings = new GuildSettings({
|
||||||
|
guildId: interaction.guild.id,
|
||||||
|
verifyEnabled: enableOrDisable
|
||||||
|
});
|
||||||
|
await newGuildSettings.save();
|
||||||
|
} else {
|
||||||
|
guildSettings.verifyEnabled = enableOrDisable;
|
||||||
|
await guildSettings.save();
|
||||||
|
}
|
||||||
|
} else if (enableOrDisable === undefined) {
|
||||||
|
if (verifyFailAction === null) {
|
||||||
|
const newVerifyFailAction = new VerifyFailAction({
|
||||||
|
guildId: interaction.guild.id,
|
||||||
|
action: automodAction,
|
||||||
|
reason: `${automodActionReason.toString()}` || 'No reason provided.',
|
||||||
|
threshold: automodActionThreshold || 3,
|
||||||
|
duration: automodActionDuration || 7
|
||||||
|
});
|
||||||
|
await newVerifyFailAction.save();
|
||||||
|
} else if (verifyFailAction !== null) {
|
||||||
|
verifyFailAction.action = automodAction;
|
||||||
|
verifyFailAction.reason = `${automodActionReason.toString()}` || 'No reason provided.';
|
||||||
|
verifyFailAction.threshold = automodActionThreshold || 3;
|
||||||
|
verifyFailAction.duration = automodActionDuration || 7;
|
||||||
|
await verifyFailAction.save();
|
||||||
|
} else if (verifyFailAction?.action !== 'none' && automodAction === 'none') {
|
||||||
|
await VerifyFailAction.find(filter).deleteMany();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (settings === 'anti-new-user') {
|
||||||
|
if (enableOrDisable !== undefined && automodAction === undefined) {
|
||||||
|
if (guildSettings === null) {
|
||||||
|
const newGuildSettings = new GuildSettings({
|
||||||
|
guildId: interaction.guild.id,
|
||||||
|
antiNewUserEnabled: enableOrDisable
|
||||||
|
});
|
||||||
|
await newGuildSettings.save();
|
||||||
|
} else {
|
||||||
|
guildSettings.antiNewUserEnabled = enableOrDisable;
|
||||||
|
await guildSettings.save();
|
||||||
|
}
|
||||||
|
} else if (enableOrDisable !== undefined && automodAction !== 'none') {
|
||||||
|
if (guildSettings === null) {
|
||||||
|
const newGuildSettings = new GuildSettings({
|
||||||
|
guildId: interaction.guild.id,
|
||||||
|
antiNewUserEnabled: enableOrDisable
|
||||||
|
});
|
||||||
|
await newGuildSettings.save();
|
||||||
|
} else {
|
||||||
|
guildSettings.antiNewUserEnabled = enableOrDisable;
|
||||||
|
await guildSettings.save();
|
||||||
|
}
|
||||||
|
if (newUserAction === null) {
|
||||||
|
const newNewUserAction = new NewUserAction({
|
||||||
|
guildId: interaction.guild.id,
|
||||||
|
action: automodAction,
|
||||||
|
reason: `${automodActionReason}` || 'No reason provided.',
|
||||||
|
threshold: automodActionThreshold || 3,
|
||||||
|
duration: automodActionDuration || 0
|
||||||
|
});
|
||||||
|
await newNewUserAction.save();
|
||||||
|
} else {
|
||||||
|
newUserAction.action = automodAction;
|
||||||
|
newUserAction.reason = `${automodActionReason}` || 'No reason provided.';
|
||||||
|
newUserAction.threshold = automodActionThreshold || 3;
|
||||||
|
newUserAction.duration = automodActionDuration || 0;
|
||||||
|
await newUserAction.save();
|
||||||
|
}
|
||||||
|
} else if (enableOrDisable !== undefined && automodAction === 'none') {
|
||||||
|
if (guildSettings === null) {
|
||||||
|
const newGuildSettings = new GuildSettings({
|
||||||
|
guildId: interaction.guild.id,
|
||||||
|
antiNewUserEnabled: enableOrDisable
|
||||||
|
});
|
||||||
|
await newGuildSettings.save();
|
||||||
|
} else {
|
||||||
|
guildSettings.antiNewUserEnabled = enableOrDisable;
|
||||||
|
await guildSettings.save();
|
||||||
|
}
|
||||||
|
if (newUserAction?.action !== 'none') {
|
||||||
|
await NewUserAction.find(filter).deleteMany();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await interaction.editReply({ content: 'Settings have been updated.' });
|
||||||
|
} else if (subcommand === 'check') {
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setTitle('Settings')
|
||||||
|
.addFields({
|
||||||
|
name: 'Verification',
|
||||||
|
value: `${guildSettings?.verifyEnabled ? 'Enabled' : 'Disabled'}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Verification Auto Action',
|
||||||
|
value: `${verifyFailAction ? `Action: ${verifyFailAction?.action.toUpperCase()}\nReason: ${verifyFailAction?.reason}\nThreshold: ${verifyFailAction?.threshold}\nDuration: ${verifyFailAction?.duration}` : "None"}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Anti New User',
|
||||||
|
value: `${guildSettings?.antiNewUserEnabled ? 'Enabled' : 'Disabled'}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Anti New User Auto Action',
|
||||||
|
value: `${newUserAction ? `Action: ${newUserAction?.action.toUpperCase()}\nReason: ${newUserAction?.reason}\nThreshold: ${newUserAction?.threshold}\nDuration: ${newUserAction?.duration}` : "None"}`,
|
||||||
|
})
|
||||||
|
.setColor("Gold");
|
||||||
|
await interaction.editReply({ embeds: [embed] });
|
||||||
|
} else if (subcommand === 'reset') {
|
||||||
|
await GuildSettings.find(filter).deleteMany();
|
||||||
|
await NewUserAction.find(filter).deleteMany();
|
||||||
|
await VerifyFailAction.find(filter).deleteMany();
|
||||||
|
await interaction.editReply({ content: 'Settings have been reset.' });
|
||||||
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+161
-78
@@ -1,13 +1,16 @@
|
|||||||
const { EmbedBuilder, ApplicationCommandType, AttachmentBuilder } = require('discord.js');
|
const { EmbedBuilder, ApplicationCommandType, AttachmentBuilder } = require('discord.js');
|
||||||
const { dangercordcheckVerification } = require('../../functions/dangerCordUtils.js');
|
const { dangercordcheckVerification } = require('../../functions/dangerCordUtils.js');
|
||||||
const { createCanvas } = require('canvas');
|
const { createCanvas } = require('canvas');
|
||||||
|
const GuildSettings = require('../../database/models/GuildSettings');
|
||||||
const cfg = require('../../config/config.js');
|
const cfg = require('../../config/config.js');
|
||||||
|
const { moderationUtilities } = require('../../functions/utils.js');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
name: 'verify',
|
name: 'verify',
|
||||||
description: 'To verify yourself.',
|
description: 'To verify yourself.',
|
||||||
type: ApplicationCommandType.ChatInput,
|
type: ApplicationCommandType.ChatInput,
|
||||||
run: async (client, interaction) => {
|
run: async (client, interaction) => {
|
||||||
|
const guildSettings = await GuildSettings.findOne({ guildId: interaction.guild.id });
|
||||||
await interaction.deferReply({ ephemeral: true });
|
await interaction.deferReply({ ephemeral: true });
|
||||||
const guildId = interaction.guild.id;
|
const guildId = interaction.guild.id;
|
||||||
|
|
||||||
@@ -98,7 +101,7 @@ module.exports = {
|
|||||||
return interaction.editReply({ content: cfg.messages.wrongChannel, ephemeral: true })
|
return interaction.editReply({ content: cfg.messages.wrongChannel, ephemeral: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
if (await client.db.get(`settings-${guildId}.verification`) === false) {
|
if (guildSettings?.verifyEnabled === false || !guildSettings?.verifyEnabled) {
|
||||||
return interaction.editReply({ content: cfg.messages.verifyDisabled, ephemeral: true })
|
return interaction.editReply({ content: cfg.messages.verifyDisabled, ephemeral: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,98 +116,178 @@ module.exports = {
|
|||||||
|
|
||||||
async function verifyUser(captcha) {
|
async function verifyUser(captcha) {
|
||||||
attempts++;
|
attempts++;
|
||||||
if (attempts > maxAttempts) {
|
switch (attempts) {
|
||||||
await interaction.user.send(cfg.messages.maxAttemptsExceeded);
|
case attempts > maxAttempts:
|
||||||
return;
|
await interaction.user.send(cfg.messages.maxAttemptsExceeded);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (attempts == 1) {
|
/*
|
||||||
// Check the Dangercord API using our custom library function
|
if (attempts > maxAttempts) {
|
||||||
|
await interaction.user.send(cfg.messages.maxAttemptsExceeded);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
const captcha = await generateCaptcha(cfg.captchaCount);
|
||||||
|
|
||||||
|
switch (attempts) {
|
||||||
|
case 1:
|
||||||
await dangercordcheckVerification(interaction.user.id)
|
await dangercordcheckVerification(interaction.user.id)
|
||||||
.then(result => {
|
.then(result => {
|
||||||
console.log('Verification result:', result);
|
console.log('Verification result:', result);
|
||||||
if (result === 1) {
|
switch (result) {
|
||||||
console.log(`${interaction.user.id} is not blacklisted at dangercord, lets continue with the verification process`)
|
case 1: {
|
||||||
// Proceed with further actions
|
console.log(`${interaction.user.id} is not blacklisted at dangercord, lets continue with the verification process`)
|
||||||
} else {
|
// Proceed with further actions
|
||||||
console.log(`${interaction.user.id} is blacklisted at dangercord, we will not continue with the verification process`);
|
break;
|
||||||
blacklisted = true; // Set blacklisted to true
|
}
|
||||||
// Handle the case when user is blacklisted
|
default: {
|
||||||
interaction.editReply({
|
console.log(`${interaction.user.id} is blacklisted at dangercord, we will not continue with the verification process`);
|
||||||
content: cfg.messages.cannotContinue,
|
blacklisted = true; // Set blacklisted to true
|
||||||
ephemeral: true
|
// Handle the case when user is blacklisted
|
||||||
}).then(() => {
|
interaction.editReply({
|
||||||
// Stop execution here
|
content: cfg.messages.cannotContinue,
|
||||||
return;
|
ephemeral: true
|
||||||
}).catch(error => {
|
}).then(() => {
|
||||||
console.error('Error:', error);
|
// Stop execution here
|
||||||
});
|
return;
|
||||||
|
}).catch(error => {
|
||||||
|
console.error('Error:', error);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
console.error('Error:', error);
|
console.error('Error:', error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
if (blacklisted == true) return
|
if (attempts == 1) {
|
||||||
|
// Check the Dangercord API using our custom library function
|
||||||
const buff = await createCaptcha(captcha);
|
await dangercordcheckVerification(interaction.user.id)
|
||||||
const attachment = new AttachmentBuilder(buff, { name: 'captcha.png' });
|
.then(result => {
|
||||||
|
console.log('Verification result:', result);
|
||||||
const embed = new EmbedBuilder()
|
if (result === 1) {
|
||||||
.setTitle("Captcha Verification")
|
console.log(`${interaction.user.id} is not blacklisted at dangercord, lets continue with the verification process`)
|
||||||
.setDescription(`Please type the captcha below. You have ${cfg.captchaTimeout / 1000} seconds to respond. Attempt ${attempts}/${maxAttempts}`)
|
// Proceed with further actions
|
||||||
.setColor('Green')
|
|
||||||
.setImage('attachment://captcha.png')
|
|
||||||
.setTimestamp();
|
|
||||||
|
|
||||||
await interaction.user.send({
|
|
||||||
embeds: [embed], files: [attachment]
|
|
||||||
}).then(async (msg) => {
|
|
||||||
await interaction.editReply({ content: cfg.messages.toVerify, ephemeral: true });
|
|
||||||
const filter = m => !m.author.bot && m.author.id === interaction.user.id && m.channel.id === msg.channel.id;
|
|
||||||
const collector = msg.channel.createMessageCollector({
|
|
||||||
filter,
|
|
||||||
time: cfg.captchaTimeout
|
|
||||||
});
|
|
||||||
|
|
||||||
collector.on('collect', async (m) => {
|
|
||||||
//if member left the server before the verification is done
|
|
||||||
if (!interaction.guild.members.cache.has(interaction.user.id)) {
|
|
||||||
await interaction.user.send(cfg.messages.userLeft);
|
|
||||||
collector.stop();
|
|
||||||
} else {
|
} else {
|
||||||
if (m.content === captcha) {
|
console.log(`${interaction.user.id} is blacklisted at dangercord, we will not continue with the verification process`);
|
||||||
validated = true;
|
blacklisted = true; // Set blacklisted to true
|
||||||
await interaction.member.roles.add(cfg.guilds[guildId].roleToAdd);
|
// Handle the case when user is blacklisted
|
||||||
await interaction.member.roles.remove(cfg.guilds[guildId].firstRole);
|
interaction.editReply({
|
||||||
await interaction.user.send(cfg.messages.success);
|
content: cfg.messages.cannotContinue,
|
||||||
return
|
ephemeral: true
|
||||||
} else {
|
}).then(() => {
|
||||||
// If the content doesn't match captcha
|
// Stop execution here
|
||||||
collector.stop();
|
return;
|
||||||
}
|
}).catch(error => {
|
||||||
|
console.error('Error:', error);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
.catch(error => {
|
||||||
collector.on('end', async (collected, reason) => {
|
console.error('Error:', error);
|
||||||
if (reason === 'time' && !validated) { // Send timeout message only if not already validated
|
|
||||||
await interaction.user.send(cfg.messages.tookTooLong);
|
|
||||||
} else if (!validated) {
|
|
||||||
// Only generate a new captcha and attempt verification if attempts < maxAttempts
|
|
||||||
const newCaptcha = await generateCaptcha(cfg.captchaCount);
|
|
||||||
await verifyUser(newCaptcha);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}).catch(async (err) => {
|
|
||||||
await interaction.editReply({
|
|
||||||
content: cfg.messages.unableToDM,
|
|
||||||
ephemeral: true
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (blacklisted == true) return
|
||||||
|
|
||||||
|
const buff = await createCaptcha(captcha);
|
||||||
|
const attachment = new AttachmentBuilder(buff, { name: 'captcha.png' });
|
||||||
|
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setTitle("Captcha Verification")
|
||||||
|
.setDescription(`Please type the captcha below. You have ${cfg.captchaTimeout / 1000} seconds to respond. Attempt ${attempts}/${maxAttempts}`)
|
||||||
|
.setColor('Green')
|
||||||
|
.setImage('attachment://captcha.png')
|
||||||
|
.setTimestamp();
|
||||||
|
|
||||||
|
await interaction.user.send({
|
||||||
|
embeds: [embed], files: [attachment]
|
||||||
|
}).then(async (msg) => {
|
||||||
|
await interaction.editReply({ content: cfg.messages.toVerify, ephemeral: true });
|
||||||
|
const filter = m => !m.author.bot && m.author.id === interaction.user.id && m.channel.id === msg.channel.id;
|
||||||
|
const collector = msg.channel.createMessageCollector({
|
||||||
|
filter,
|
||||||
|
time: cfg.captchaTimeout
|
||||||
|
});
|
||||||
|
|
||||||
|
collector.on('collect', async (m) => {
|
||||||
|
//if member left the server before the verification is done
|
||||||
|
switch (!interaction.guild.members.cache.has(interaction.user.id)) {
|
||||||
|
case true: {
|
||||||
|
await interaction.user.send(cfg.messages.userLeft);
|
||||||
|
collector.stop();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
switch (m.content === captcha) {
|
||||||
|
case true: {
|
||||||
|
validated = true;
|
||||||
|
await interaction.member.roles.add(cfg.guilds[guildId].roleToAdd);
|
||||||
|
await interaction.member.roles.remove(cfg.guilds[guildId].firstRole);
|
||||||
|
await interaction.user.send(cfg.messages.success);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
// If the content doesn't match captcha
|
||||||
|
collector.stop();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
/*
|
||||||
|
if (!interaction.guild.members.cache.has(interaction.user.id)) {
|
||||||
|
await interaction.user.send(cfg.messages.userLeft);
|
||||||
|
collector.stop();
|
||||||
|
} else {
|
||||||
|
if (m.content === captcha) {
|
||||||
|
validated = true;
|
||||||
|
await interaction.member.roles.add(cfg.guilds[guildId].roleToAdd);
|
||||||
|
await interaction.member.roles.remove(cfg.guilds[guildId].firstRole);
|
||||||
|
await interaction.user.send(cfg.messages.success);
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
// If the content doesn't match captcha
|
||||||
|
collector.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
collector.on('end', async (collected, reason) => {
|
||||||
|
switch (reason) {
|
||||||
|
case 'time':
|
||||||
|
switch (validated) {
|
||||||
|
case false: case null:
|
||||||
|
await interaction.user.send(cfg.messages.tookTooLong);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
if (reason === 'time' && !validated) { // Send timeout message only if not already validated
|
||||||
|
await interaction.user.send(cfg.messages.tookTooLong);
|
||||||
|
} else if (!validated) {
|
||||||
|
// Only generate a new captcha and attempt verification if attempts < maxAttempts
|
||||||
|
const newCaptcha = await generateCaptcha(cfg.captchaCount);
|
||||||
|
await verifyUser(newCaptcha);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
});
|
||||||
|
}).catch(async (err) => {
|
||||||
|
await interaction.editReply({
|
||||||
|
content: cfg.messages.unableToDM,
|
||||||
|
ephemeral: true
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
const captcha = await generateCaptcha(cfg.captchaCount);
|
|
||||||
verifyUser(captcha);
|
verifyUser(captcha);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user