Edit a database when mute/warn is over

So, I did a command to mute (using timeout method, no problem, it works), same for warn (simple message). For each and every sanction made by a moderator, it's stored in a SQLite database with some useful infos. Now i can have the infos stored in the db, and the message of "warn/mute executed". What i'm stuck onto is how to make a long period timeout ? Say 3 months ? I tried, on ChatGPT recommandation (so like, worst idea I could have had but who knows) to use node-cron and 'events' so that an event is emitted, and another file receive it, and launch a cron.schedule to the said date, and then it executes the code of updating the db and sending a message saying the sanction is over. (Files in next message)
2 Replies
d.js toolkit
d.js toolkit10mo ago
- What's your exact discord.js npm list discord.js and node node -v version? - Not a discord.js issue? Check out #other-js-ts. - Consider reading #how-to-get-help to improve your question! - Explain what exactly your issue is. - Post the full error stack trace, not just the top part! - Show your code! - Issue solved? Press the button!
Alzalia
Alzalia10mo ago
So far, I've tried this (emitter file):
const { SlashCommandBuilder, PermissionFlagsBits} = require('discord.js');
const Sequelize = require('sequelize');
const EventEmitter = require('events')
const eventEmitter = new EventEmitter()

module.exports = {
data: new SlashCommandBuilder()
// ... the commands options
async execute(interaction) {
//... Some code that works and isn't relevant
// Retrieve infos | prepare sanction apply to db
const case_id = await randomIdGenerator(); (//randomIdGenerator works and is set just before)
const type = interaction.options.getString('sanction');
const user_id = interaction.options.getUser('utilisateur').id;
const duration = (interaction.options.getInteger('durée') != null) ? interaction.options.getInteger('durée') : 60;
const moderator_id = interaction.user.id;
const reason = (interaction.options.getString('raison') != null) ? interaction.options.getString('raison') : "Aucune raison spécifiée";
const state = "open";

switch(type){
case "warn":
//... Warn code
case "mute":
//... Warn code
case "kick":
//... Kick code
case "ban":
//... Ban code
}


// Apply the infos to db. It works, Sanctions is set with global.Sanctions in index.js
try {
const tag = await Sanctions.create({
case_id: case_id,
type: type,
user_id: user_id,
duration: duration,
moderator_id: moderator_id,
reason: reason,
state: state,
});
eventEmitter.emit('sanctionLevée', { case_id, user_id, duration });
return interaction.reply(`Tag ${tag.case_id} added by ${tag.moderator_id} at ${tag.createdAt} to ${tag.type} ${tag.user_id} because ${tag.reason} for a time of ${tag.duration}. State : ${tag.state}`);
}
catch (error) {
if (error.name === 'SequelizeUniqueConstraintError') {
return interaction.reply('That tag already exists.');
}

return interaction.reply('Something went wrong with adding a tag. : \n'+error);
}
},
};
const { SlashCommandBuilder, PermissionFlagsBits} = require('discord.js');
const Sequelize = require('sequelize');
const EventEmitter = require('events')
const eventEmitter = new EventEmitter()

module.exports = {
data: new SlashCommandBuilder()
// ... the commands options
async execute(interaction) {
//... Some code that works and isn't relevant
// Retrieve infos | prepare sanction apply to db
const case_id = await randomIdGenerator(); (//randomIdGenerator works and is set just before)
const type = interaction.options.getString('sanction');
const user_id = interaction.options.getUser('utilisateur').id;
const duration = (interaction.options.getInteger('durée') != null) ? interaction.options.getInteger('durée') : 60;
const moderator_id = interaction.user.id;
const reason = (interaction.options.getString('raison') != null) ? interaction.options.getString('raison') : "Aucune raison spécifiée";
const state = "open";

switch(type){
case "warn":
//... Warn code
case "mute":
//... Warn code
case "kick":
//... Kick code
case "ban":
//... Ban code
}


// Apply the infos to db. It works, Sanctions is set with global.Sanctions in index.js
try {
const tag = await Sanctions.create({
case_id: case_id,
type: type,
user_id: user_id,
duration: duration,
moderator_id: moderator_id,
reason: reason,
state: state,
});
eventEmitter.emit('sanctionLevée', { case_id, user_id, duration });
return interaction.reply(`Tag ${tag.case_id} added by ${tag.moderator_id} at ${tag.createdAt} to ${tag.type} ${tag.user_id} because ${tag.reason} for a time of ${tag.duration}. State : ${tag.state}`);
}
catch (error) {
if (error.name === 'SequelizeUniqueConstraintError') {
return interaction.reply('That tag already exists.');
}

return interaction.reply('Something went wrong with adding a tag. : \n'+error);
}
},
};
And the receiver file :
const cron = require('node-cron');
const EventEmitter = require('events');
const eventEmitter = new EventEmitter();
const Sequelize = require('sequelize');
require('discord.js');

// Écouter l'événement pour la levée de la sanction
eventEmitter.on('sanctionLevée', ({ case_id, user_id, duration }) => {
try{
const maintenant = Date.now();
const tempsDeLevée = maintenant + duration; // Calculer le moment de la levée
console.log(`Bien reçu l\'emit : ${new Date(tempsDeLevée)} pour lever`);
// Planifier la levée de la sanction avec la tâche cron
cron.schedule(new Date(tempsDeLevée), () => {
client.channels.cache.get('1119652569023791126').send(`Bien enlevé le warn`);
Sanctions.update({ state: "closed" }, { where: { case_id: case_id } })
});
} catch(e) {
console.log(`**Error** :\n\n ${e}`);
client.channels.cache.get('1119652569023791126').send(`**Error** :\n\n ${e}`);
}
});
const cron = require('node-cron');
const EventEmitter = require('events');
const eventEmitter = new EventEmitter();
const Sequelize = require('sequelize');
require('discord.js');

// Écouter l'événement pour la levée de la sanction
eventEmitter.on('sanctionLevée', ({ case_id, user_id, duration }) => {
try{
const maintenant = Date.now();
const tempsDeLevée = maintenant + duration; // Calculer le moment de la levée
console.log(`Bien reçu l\'emit : ${new Date(tempsDeLevée)} pour lever`);
// Planifier la levée de la sanction avec la tâche cron
cron.schedule(new Date(tempsDeLevée), () => {
client.channels.cache.get('1119652569023791126').send(`Bien enlevé le warn`);
Sanctions.update({ state: "closed" }, { where: { case_id: case_id } })
});
} catch(e) {
console.log(`**Error** :\n\n ${e}`);
client.channels.cache.get('1119652569023791126').send(`**Error** :\n\n ${e}`);
}
});
So I just... don't know what's wrong, or what can I do. There is no error message. The database isn't changed neither, so I guess it just never receives the event ? Thank you for your help, if there is any easier way (if this is even a way)... Discord.js is 14.12.1 Node.js is 18.13.0 But that would need to analyse the database at least every minute wouldn't it ? Which would be quite resourceful ? (Unless I didn't understand what you meant, I'm quite new with javascript, and thus discord.js and node.js) yes but the bigger interval the least precise the durations. If I do it every 5 minutes for example, first on at t0. I mute someone for 5min at t1. When the test happens at t5, there is still 1 minute to go. So it passes. But then, 1 min later... nothing, you need to wait t10 for the next message. Which, I mean, can be okay, but it would be best to have it precisely set... But if you tell me there is no easy other way then nevermind I'll do it that way (thus a cronjob would be the easiest right ?) oooh, true true. Is it async ? (I don't have the right word I think but like, if I have two that will end before the end can I make two setTimeout or do I need to make them in order from nearest to furthest ?) okay perfect then, I will make that, thank you very much ! Okay I'm so sorry to bother you again, but I- I don't understand why that part doesn't work. Basically I try to access my database, well, to analyse it. Except it just... doesn't seem to know it's existence. What I don't understand is that it is used in my first warn/mute command and there is no problem at all, but here it just doesn't want to. My code :
const Sequelize = require('sequelize');
const { EmbedBuilder } = require('discord.js');

( async () => {
const now = Date.now();
const openSanctions = await Sanctions.findAll({ where : {state: "open"}});
const passedSanctions = openSanctions.map(t => ((t.createdAt + t.duration)<=now) ? t : null);

passedSanctions.forEach(element => {
salon = client.channels.cache.get('1119652569023791126')
salon.send(`Case ${element.case_id} \nElement passé à : ${new Date(element.createdAt + element.duration)}`);
});
})()
const Sequelize = require('sequelize');
const { EmbedBuilder } = require('discord.js');

( async () => {
const now = Date.now();
const openSanctions = await Sanctions.findAll({ where : {state: "open"}});
const passedSanctions = openSanctions.map(t => ((t.createdAt + t.duration)<=now) ? t : null);

passedSanctions.forEach(element => {
salon = client.channels.cache.get('1119652569023791126')
salon.send(`Case ${element.case_id} \nElement passé à : ${new Date(element.createdAt + element.duration)}`);
});
})()
The error I get :
const openSanctions = await Sanctions.findAll({ where : {state: "open"}});
^

ReferenceError: Sanctions is not defined
at /home/ubuntu/discordBot/BeeBot_SourceCode/commands/moderation/autoUnMod.js:6:27
at Object.<anonymous> (/home/ubuntu/discordBot/BeeBot_SourceCode/commands/moderation/autoUnMod.js:13:3)
at Module._compile (node:internal/modules/cjs/loader:1218:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1272:10)
at Module.load (node:internal/modules/cjs/loader:1081:32)
at Module._load (node:internal/modules/cjs/loader:922:12)
at Module.require (node:internal/modules/cjs/loader:1105:19)
at require (node:internal/modules/cjs/helpers:103:18)
at Object.<anonymous> (/home/ubuntu/discordBot/BeeBot_SourceCode/deploy-commands-expe.js:21:19)
at Module._compile (node:internal/modules/cjs/loader:1218:14)

Node.js v18.13.0
const openSanctions = await Sanctions.findAll({ where : {state: "open"}});
^

ReferenceError: Sanctions is not defined
at /home/ubuntu/discordBot/BeeBot_SourceCode/commands/moderation/autoUnMod.js:6:27
at Object.<anonymous> (/home/ubuntu/discordBot/BeeBot_SourceCode/commands/moderation/autoUnMod.js:13:3)
at Module._compile (node:internal/modules/cjs/loader:1218:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1272:10)
at Module.load (node:internal/modules/cjs/loader:1081:32)
at Module._load (node:internal/modules/cjs/loader:922:12)
at Module.require (node:internal/modules/cjs/loader:1105:19)
at require (node:internal/modules/cjs/helpers:103:18)
at Object.<anonymous> (/home/ubuntu/discordBot/BeeBot_SourceCode/deploy-commands-expe.js:21:19)
at Module._compile (node:internal/modules/cjs/loader:1218:14)

Node.js v18.13.0
I declared Sanctions globally with global.Sanctions = ... but what I really don't understand is why would it work with my warn/mute command file but not this one ? Oh ok, my bad 😅 Have a nice day, and sorry for the mistake ^^