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);
|
||||
+19
-7
@@ -6,17 +6,29 @@ client.on('ready', () => {
|
||||
console.log(chalk.green(`Logged in as ${client.user.tag}!`));
|
||||
setInterval(() => {
|
||||
let activities = [
|
||||
{ type: "Playing", name: "/verify" },
|
||||
{ type: "Playing", name: "Securing our servers" },
|
||||
{ type: "Watching", name: `Watching bans...` },
|
||||
{ type: "Playing", name: "with /verify command." },
|
||||
{ type: "Playing", name: "whilst securing our servers." },
|
||||
{ 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)];
|
||||
|
||||
if (status.type === "Watching") {
|
||||
client.user.setPresence({ activities: [{ name: `${status.name}`, type: ActivityType.Watching }] });
|
||||
} else {
|
||||
switch (status.type) {
|
||||
case "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
|
||||
});
|
||||
|
||||
+108
-2
@@ -1,11 +1,116 @@
|
||||
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) {
|
||||
const guildId = member.guild.id;
|
||||
const db = await client.db.get(`settings-${guildId}`) || {};
|
||||
const threshold = db.newUserKickerThreshold;
|
||||
const newUserAction = await NewUserAction.findOne({ guildId: guildId });
|
||||
const guildSettings = await GuildSettings.findOne({ guildId: guildId });
|
||||
const threshold = newUserAction.threshold;
|
||||
|
||||
const accountAge = (Date.now() - member.user.createdAt) / (1000 * 60 * 60 * 24);
|
||||
|
||||
switch (guildSettings?.antiNewUserEnabled) {
|
||||
case 'true': {
|
||||
switch (accountAge) {
|
||||
case accountAge <= threshold: {
|
||||
switch (newUserAction?.action) {
|
||||
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.`);
|
||||
@@ -14,6 +119,7 @@ async function newUserKicker(member) {
|
||||
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 = {
|
||||
|
||||
@@ -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 { QuickDB } = require('quick.db');
|
||||
require('dotenv').config();
|
||||
|
||||
const client = new Client({
|
||||
@@ -17,11 +16,13 @@ const client = new Client({
|
||||
Partials.User,
|
||||
]
|
||||
});
|
||||
const db = new QuickDB();
|
||||
|
||||
module.exports = client;
|
||||
|
||||
client.db = db;
|
||||
(async () => {
|
||||
require('./database/connect')();
|
||||
require('./cron/cronjob')();
|
||||
})();
|
||||
|
||||
client.commands = new Collection();
|
||||
client.aliases = new Collection();
|
||||
client.slashCommands = new Collection();
|
||||
|
||||
@@ -21,6 +21,9 @@
|
||||
"discord.js": "^14.14.1",
|
||||
"dotenv": "^16.4.1",
|
||||
"fs": "^0.0.1-security",
|
||||
"moment": "^2.30.1",
|
||||
"mongoose": "^6.7.0",
|
||||
"node-cron": "^3.0.3",
|
||||
"quick.db": "^9.1.7"
|
||||
}
|
||||
}
|
||||
|
||||
+428
-83
@@ -1,5 +1,6 @@
|
||||
const { ApplicationCommandType, ApplicationCommandOptionType, EmbedBuilder } = require('discord.js');
|
||||
const cfg = require('../../config/config.js');
|
||||
const { getActionDuration, convertActionDurationFromMsToTime, convertActionDurationFromTimeToMs } = require('../../functions/utils.js');
|
||||
|
||||
module.exports = {
|
||||
name: 'settings',
|
||||
@@ -7,38 +8,31 @@ module.exports = {
|
||||
type: ApplicationCommandType.ChatInput,
|
||||
options: [
|
||||
{
|
||||
name: 'verification',
|
||||
description: 'Enable or disable, or change the settings of verification.',
|
||||
name: 'change',
|
||||
description: 'Set the settings of the bot.',
|
||||
type: ApplicationCommandOptionType.Subcommand,
|
||||
options: [
|
||||
{
|
||||
name: 'enable-or-disable',
|
||||
description: 'Enable or disable verification.',
|
||||
name: 'set',
|
||||
description: 'The settings to change.',
|
||||
type: ApplicationCommandOptionType.String,
|
||||
required: true,
|
||||
choices: [
|
||||
{
|
||||
name: 'Enable',
|
||||
value: 'true'
|
||||
name: 'Verification',
|
||||
value: 'verification'
|
||||
},
|
||||
{
|
||||
name: 'Disable',
|
||||
value: 'false'
|
||||
name: 'Anti New User',
|
||||
value: 'anti-new-user'
|
||||
}
|
||||
],
|
||||
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',
|
||||
description: 'Enable or disable new user kicker.',
|
||||
description: 'Enable or disable the setting.',
|
||||
type: ApplicationCommandOptionType.String,
|
||||
required: false,
|
||||
choices: [
|
||||
{
|
||||
name: 'Enable',
|
||||
@@ -48,98 +42,449 @@ module.exports = {
|
||||
name: 'Disable',
|
||||
value: 'false'
|
||||
}
|
||||
],
|
||||
required: true
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'threshold',
|
||||
description: 'Set the amount of days user account age to kick.',
|
||||
name: 'automod-action',
|
||||
description: 'The action to take when the threshold is reached.',
|
||||
type: ApplicationCommandOptionType.String,
|
||||
required: false,
|
||||
choices: [
|
||||
{
|
||||
name: 'Timeout',
|
||||
value: 'Timeout'
|
||||
},
|
||||
{
|
||||
name: 'Warn',
|
||||
value: 'warn'
|
||||
},
|
||||
{
|
||||
name: 'Kick',
|
||||
value: 'kick'
|
||||
},
|
||||
{
|
||||
name: 'Ban',
|
||||
value: 'ban'
|
||||
},
|
||||
{
|
||||
name: 'None',
|
||||
value: 'none'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'automod-action-reason',
|
||||
description: 'The reason for the action.',
|
||||
type: ApplicationCommandOptionType.String,
|
||||
required: false
|
||||
},
|
||||
{
|
||||
name: 'automod-action-threshold',
|
||||
description: 'The threshold for the setting.',
|
||||
type: ApplicationCommandOptionType.Integer,
|
||||
required: false
|
||||
},
|
||||
{
|
||||
name: 'automod-action-duration',
|
||||
description: 'The duration for the action.',
|
||||
type: ApplicationCommandOptionType.String,
|
||||
required: false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'check',
|
||||
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',
|
||||
description: 'Reset the settings of the bot.',
|
||||
type: ApplicationCommandOptionType.Subcommand
|
||||
},
|
||||
{
|
||||
name: 'rawcheck',
|
||||
description: 'Check the raw settings of the bot.',
|
||||
type: ApplicationCommandOptionType.Subcommand
|
||||
}
|
||||
],
|
||||
default_member_permissions: ["Administrator"],
|
||||
run: async (client, interaction) => {
|
||||
await interaction.deferReply({ ephemeral: true });
|
||||
const filter = {
|
||||
guildId: interaction.guild.id
|
||||
}
|
||||
const subcommand = interaction.options.getSubcommand();
|
||||
const guildId = interaction.guild.id;
|
||||
const settings = await client.db.get(`settings-${guildId}`) || {};
|
||||
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;
|
||||
|
||||
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.' });
|
||||
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;
|
||||
}
|
||||
} 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.` });
|
||||
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('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(
|
||||
.setTitle('Settings')
|
||||
.addFields({
|
||||
name: 'Verification',
|
||||
value: `${guildSettings?.verifyEnabled ? 'Enabled' : 'Disabled'}`,
|
||||
},
|
||||
{
|
||||
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] });
|
||||
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 client.db.delete(`settings-${guildId}`);
|
||||
return interaction.editReply({ content: 'Settings have been reset.' });
|
||||
}
|
||||
await GuildSettings.find(filter).deleteMany();
|
||||
await NewUserAction.find(filter).deleteMany();
|
||||
await VerifyFailAction.find(filter).deleteMany();
|
||||
await interaction.editReply({ content: 'Settings have been reset.' });
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,16 @@
|
||||
const { EmbedBuilder, ApplicationCommandType, AttachmentBuilder } = require('discord.js');
|
||||
const { dangercordcheckVerification } = require('../../functions/dangerCordUtils.js');
|
||||
const { createCanvas } = require('canvas');
|
||||
const GuildSettings = require('../../database/models/GuildSettings');
|
||||
const cfg = require('../../config/config.js');
|
||||
const { moderationUtilities } = require('../../functions/utils.js');
|
||||
|
||||
module.exports = {
|
||||
name: 'verify',
|
||||
description: 'To verify yourself.',
|
||||
type: ApplicationCommandType.ChatInput,
|
||||
run: async (client, interaction) => {
|
||||
const guildSettings = await GuildSettings.findOne({ guildId: interaction.guild.id });
|
||||
await interaction.deferReply({ ephemeral: true });
|
||||
const guildId = interaction.guild.id;
|
||||
|
||||
@@ -98,7 +101,7 @@ module.exports = {
|
||||
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 })
|
||||
}
|
||||
|
||||
@@ -113,11 +116,55 @@ module.exports = {
|
||||
|
||||
async function verifyUser(captcha) {
|
||||
attempts++;
|
||||
switch (attempts) {
|
||||
case attempts > maxAttempts:
|
||||
await interaction.user.send(cfg.messages.maxAttemptsExceeded);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
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)
|
||||
.then(result => {
|
||||
console.log('Verification result:', result);
|
||||
switch (result) {
|
||||
case 1: {
|
||||
console.log(`${interaction.user.id} is not blacklisted at dangercord, lets continue with the verification process`)
|
||||
// Proceed with further actions
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
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);
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error:', error);
|
||||
});
|
||||
}
|
||||
/*
|
||||
if (attempts == 1) {
|
||||
// Check the Dangercord API using our custom library function
|
||||
await dangercordcheckVerification(interaction.user.id)
|
||||
@@ -145,6 +192,7 @@ module.exports = {
|
||||
console.error('Error:', error);
|
||||
});
|
||||
}
|
||||
*/
|
||||
|
||||
if (blacklisted == true) return
|
||||
|
||||
@@ -170,6 +218,31 @@ module.exports = {
|
||||
|
||||
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();
|
||||
@@ -185,9 +258,20 @@ module.exports = {
|
||||
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) {
|
||||
@@ -195,6 +279,7 @@ module.exports = {
|
||||
const newCaptcha = await generateCaptcha(cfg.captchaCount);
|
||||
await verifyUser(newCaptcha);
|
||||
}
|
||||
*/
|
||||
});
|
||||
}).catch(async (err) => {
|
||||
await interaction.editReply({
|
||||
@@ -202,9 +287,7 @@ module.exports = {
|
||||
ephemeral: true
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const captcha = await generateCaptcha(cfg.captchaCount);
|
||||
verifyUser(captcha);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user