This question already has answers here:
message event listener not working properly
(2 answers)
Closed 1 year ago.
There's something I don't understand with discordjs. I want to make a bot which lists people when they react on a message.
It partially works, when the guy who enter the commands (or who has enter a command before) reacts to the bot's message, the message edits immediately. But when it's someone who has never entered command, it didn't update.
const Discord = require('discord.js');
const client = new Discord.Client();
var auth = require('./auth.json');
const regexTime = new RegExp('^(0[0-9]|1[0-9]|2[0-3]|[0-9])([:|h])([0-5][0-9])?$');
var messageBot = "";
var time;
var timer;
var commandeValide=false;
var date = new Date;
var heureMs;
client.on('ready', () => {
console.log(client.guilds.fetch())
});
client.on('message', msg => {
if (msg.content.substring(0,1) === '!') {
var args = msg.content.substring(1).split(' ');
var cmd = args[0];
switch(cmd){
case 'amongus':
dateGame = args[1];
time = args[2];
messageBot = '#everyone Est-ce que des personne veulent faire un Among us à '+ time + ' le '+ dateGame;
if ( dateGame != undefined && time != undefined ){
var heure = time.split('h')[0] * 3600000;
var minute = time.split('h')[1] * 60000;
var temps = heure + minute;
heureMs = date.getHours() * 3600000 + date.getMinutes() * 60000;
if(regexTime.test(time) && isDate(dateGame)){
if(temps>heureMs){
commandeValide=true;
msg.channel.send(messageBot).then(sendMessage => {
sendMessage.react('✅')
});
timer = temps - heureMs;
}
}else{
msg.reply("Veuillez rentrer une heure ou une date valide!");
commandeValide=false;
}
}else{
msg.reply("Veuillez rentrer une heure et/ou une date s'il vous plaît! (exemple: !amongus 19/04 20h)");
commandeValide=false;
}
}
}
if(commandeValide){
const filter = (reaction, user) => {
console.log(client.users.cache);
//return ['✅'].includes(reaction.emoji.name);
return reaction.emoji.name === '✅' && user.id !== msg.author.id;
};
const collector = msg.createReactionCollector(filter, { dispose: true, time: timer }); //dispose: true permet d'utiliser remove
collector.on('collect', (reaction, user) => {
reaction.users.fetch().then((user) => {
updateMessage(user.array(),msg);
});
});
collector.on('remove', (reaction, user) => {
reaction.users.fetch().then((user) => {
updateMessage(user.array(),msg);
});
});
collector.on('end', collected => {
console.log(`Collected ${collected.size} items`);
});
}
});
function updateMessage(tab, msg){
var listparticipant = "";
tab.forEach(user => {
if(user.id !== auth.server_id){
listparticipant += "- " + user.username + "\n";
}
})
msg.edit(messageBot + "\n" + listparticipant);
console.log(listparticipant);
}
client.login(auth.token);
Discord changed how much they emit events, make sure to put he proper intents on your bot and try again!
const client = new Discord.Client({
ws : {
intents: [
'GUILD_MEMBERS',
'GUILD_MESSAGES',
'GUILD_MESSAGE_REACTIONS' //<--- the intent you need to detect reactions on messages in a guild
]
}
});
Related
does anyone have time to help me with a little problem? I did this function to check the license time but it doesn't really work, does anyone have any idea?
https://cdn.discordapp.com/attachments/953617052202074132/954398145868083291/unknown.png
https://cdn.discordapp.com/attachments/953617052202074132/954398654217723914/unknown.png
exilied_client.on('message', async message => {
if (message.content.startsWith(`${prefix}time`)) {
automex = message.author;
if(message.guild == undefined) {
message.reply("Comenzile le poti da doar pe server-ul de discord");
return;
};
if(message.member.roles.cache.has(zedu_roldiscord)) {
const argomento = message.content.slice(prefix.length).split(/ +/g)
const comando = argomento.shift().toLowerCase();
var i = 1;
if(argomento[0])
{
if(message.member.roles.cache.has(zedu_roldiscord))
{
var verificaretimp = message.guild.member(message.mentions.users.first() || message.guild.members.fetch(argomento[1]))
} else {
message.delete()
message.reply(automex.username + " Ce gatu ma-tii vrei sa faci?")
return;
}
} else {
var verificaretimp = automex
}
const Verificare = `SELECT license, used, total_time FROM licenses WHERE userid = '${verificaretimp.id}';`
const autoreasd = querytxt => {
return new Promise((resolve, reject) => {
exilied_database.query(querytxt, (err, results, fields) => {
if (err) reject(err);
resolve([results, fields]);
});
});
};
const [results, fields] = await autoreasd(Verificare);
const Mappa1 = results.map(results => `${(results.used)}`);
const Mappa2 = results.map(results => `${(results.total_time)}`);
var TempoAttesa = parseInt (Mappa1, 10);
var TempoAttesa2 = parseInt (Mappa2, 10);
function ConvertireTimp(UNIX_timestamp){
var exilied_time = new Date(UNIX_timestamp * 1000);
var mesi = ['January','February','March','April','May','June','July','August','September','October','November','December'];
exilied_time.setDate(exilied_time.getDate() + TempoAttesa2);
var year = exilied_time.getFullYear();
var month = mesi[exilied_time.getMonth()];
var date = exilied_time.getDate();
var hour = exilied_time.getHours();
var min = exilied_time.getMinutes();
var sec = exilied_time.getSeconds();
var time = date + ' ' + month + ' ' + year + ' ' + hour + ":"+ min;
return time;
}
message.delete()
var convertireatimp = ConvertireTimp(TempoAttesa2)
var expirelicense = automex.send("**__Your License Expired On__**: \n" + "" + convertireatimp + " \n If Not See Date Your Key Is Expired")
} else {
automex.send("**You Dont Have A License Key**")
}
}
});```
I need to store cooldowns from users and then request them, so I can check if the user has the cooldown. But there is a problem, first example.
//DB thing
const sqlite3 = require('sqlite3').verbose();
let db = new sqlite3.Database('cooldowns.db', sqlite3.OPEN_READWRITE, (err) => {
if (err) {
return console.error(err.message);
}
console.log('Connected to the cooldowns SQlite database.');
});
function getDBCooldown(userid)
{ return new Promise((resolve, reject) => {
let sql = `SELECT Author author,
Cooldown cooldown
FROM cooldowns
WHERE Author = ?`;
let author = userid
db.get(sql, [author], (err, row) => {
const now = new Date();
const cooldown = new Date(row.cooldown);
const value = date.subtract(cooldown,now);
const days = parseInt((cooldown - now) / (1000 * 60 * 60 * 24));
const hours = parseInt(Math.abs(cooldown - now) / (1000 * 60 * 60) % 24);
const minutes = parseInt(Math.abs(cooldown.getTime() - now.getTime()) / (1000 * 60) % 60);
const seconds = parseInt(Math.abs(cooldown.getTime() - now.getTime()) / (1000) % 60);
if (err) {
return console.error(err.message);
}
const expire = days + " days " + hours + " hours " + minutes + " minutes " + seconds + " seconds "
resolve(expire)
});
}) }
client.on("messageCreate", message => {
if (message.author.bot) return;
if (message.content.indexOf(config.prefix) !== 0) return;
const args = message.content.slice(config.prefix.length).trim().split(/ +/g);
const command = args.shift().toLowerCase();
if(command === 'test') {
const dbcooldown = getDBCooldown(message.author.id)
if (dbcooldown) {
getDBCooldown(message.author.id)
.then(msg => message.reply(`Cooldown is set for you. ${msg}`))
.catch(err => console.error("Erorr getting cooldown: ", err))
return;
} //if cooldown is true, this statement will happen
createDBCooldown(message.author.id, Date.now() + cooldownTime);
// another stuff below this...
const cooldown = new Date(row.cooldown);
TypeError: Cannot read property cooldown of undefined
From what I understand and saw in several posts, issue is that cooldown is not known from the user as it does not exist in the database. Let's move on...
const sqlite3 = require('sqlite3').verbose();
let db = new sqlite3.Database('cooldowns.db', sqlite3.OPEN_READWRITE, (err) => {
if (err) {
return console.error(err.message);
}
console.log('Connected to the cooldowns SQlite database.');
});
// Check User in DB
function checkDBUser(userid) {
let sql = `SELECT Author author,
Author author
FROM cooldowns
WHERE author = ?`;
let author = userid
db.get(sql, [author], (err, row) => {
if (err) {
return console.error(err.message);
}
if (row.author == author) {
return console.log(`Author ${author} is already in database!`)
}
});
};
// Create new DB user.
function createDBUser(userid) {
let author = userid
let expires = null
let MarkForDelete = false;
db.run(`INSERT INTO cooldowns (author, cooldown, MarkForDelete) VALUES(?, ?, ?)`, [author, expires, MarkForDelete], function(err) {
if (err) {
return console.log(err.message);
}
console.log(`New user added to DB ${author}`);
});
};
//Discord Message
client.on("messageCreate", message => {
if (message.author.bot) return;
if (message.content.indexOf(config.prefix) !== 0) return;
const args = message.content.slice(config.prefix.length).trim().split(/ +/g);
const command = args.shift().toLowerCase();
if(command === 'test') {
const DBcheck = checkDBUser(message.author.id)
if (DBcheck) {
return;
}
createDBUser(message.author.id)
const cooldown = cooldowns.get(message.author.id); // this will check the cooldown
const dbcooldown = getDBCooldown(message.author.id)
if (dbcooldown) {
const remaining = humanizeDuration(cooldown - Date.now(), { round: true }, { units: ["d","h","m","s"] });
getDBCooldown(message.author.id)
.then(msg => message.reply(`Cooldown is set for you. ${msg}`))
.catch(err => console.error("Erorr getting cooldown: ", err))
return;
} //if cooldown is true, this statement will happen
createDBCooldown(message.author.id, Date.now() + cooldownTime);
if (row.author == author) {
^
TypeError: Cannot read property 'author' of undefined
Another error, because user/author is not known, if I use createDBUser(message.author.id) before the statement, it will endlessly create user in the DB, but problem is that user don't exist and statement will fail due error... Another problem is with the function getDBCooldown(userid), when I tried without checkDBuser statement and just added the user before dbcooldown statement, the bot will say the cooldown is something like -10000 days, also the user will be created in the DB XY times depending on how many times command was triggered. I don't know how to create "empty" user in DB meanwhile avoiding error const cooldown = new Date(row.cooldown); TypeError: Cannot read property cooldown of undefined, everything must be created before initialization and I feel that I'm trapped in the endless loop and there is no way out from it...
I want to record a entire conversation from Discord.JS v12. But, I'm don't really good in audio manipulation and other things like that.
I've this code :
const c = message.member.voice?.channel;
if(!c) {
// The user is not in voice channel
return message.channel.send("");
}
switch(args?.[0]?.toLowerCase()){
case 'on':
if(this.vocals.find(r => r.c === c.id && r.u === message.author.id)){
// The user have already an record launched
return message.channel.send("Vous avez déjà un enregistrement de démarré.");
}
const flux = await c.join();
const receiver = flux.receiver;
const audioChunk = this.createNewChunk((message.member.nickname || message.author.username).replace(/[^A-Za-z0-9]/g, ''));
this.vocals.push({
c: c.id,
u: message.author.id,
s: Date.now(),
r: audioChunk
});
flux.on('speaking', (user, speaking) => {
if (speaking) {
const audioStream = receiver.createStream(user, { mode: 'pcm' });
audioStream.on('data', (chunk) => audioChunk.write(chunk));
}
});
return message.channel.send("L'enregistrement a bien été lancé avec succès !")
break;
case 'off':
let f = this.vocals.find(r => r.c === c.id);
const channel = this.bot.channels.cache.get(f.c);
const members = channel.members.array();
f = this.vocals.find(r => r.c === c.id &&
(members.find(r => r.user.id === message.author.id) &&
r.u === message.author.id));
if(!f){
// The user doesnt have any record
return message.channel.send("Vous n'avez aucun enregistrement de démarré.");
}
console.log(f);
f.r.close();
return message.channel.send("L'enregistrement s'est bien terminé avec succès !", )
break;
default:
// const embed = ...
return message.channel.send(
this.help.usage.replace(/{prefix}/g, this.bot.config.prefix)
)
break;
}
And the createNewChunk function :
createNewChunk(name) {
return new wav.FileWriter(`./records/record-${name}.wav`);
}
But, when the users stop speaking in the channel, the record is stopped. Do you know how I can avoid this ?
Thanks you.
Okay, so It's really simple to do.
You have to create a audio chunck with Buffer. Then, detect when nobody is speaking. And you can push every 20ms your Buffer into the Stream.
const { Buffer } = require('buffer');
const emptyBuffer = Buffer.alloc(3840, 0); // You create a Buffer with a length of 3840, and a value to 0 (no sound).
Then, you have to put all your users into an array :
const users = [];
flux.on('speaking', (user, speaking) => {
if (speaking) {
users.push(user.id);
const audioStream = receiver.createStream(user, { mode: 'pcm' });
audioStream.on('end', () => {
users.splice(users.findIndex(r => r == user.id), 1); // Remove the users of users speaking array.
});
}
});
And THEN, you can add your buffer with no sound :
var emptyInterval = setInterval(() => {
if(users.length < 1){
audioChunk.write(emptyBuffer);
}
}, 20)
For stop the stream, stop clear the interval of emptyInterval and stop your event flux.on('speaking').
Works for nodejs v16 and more. I dont know if for nodejs v14 or lower it work.
const Discord = require('discord.js');
var connection = require('../index.js');
exports.run = (bot, message, args) => {
var id = args[0];
var nome = args[1];
var sobrenome = args[2];
let verificarId = (id) => {
return new Promise( (resolve, reject) => {
try {
connection.query(
' SELECT * FROM `vrp_users` WHERE `id` = ? ', id,
function(err, rows) {
if (err) {
reject(err)
}
if (rows.length > 0) {
resolve(true)
} else {
resolve(false)
}
}
);
} catch (err) {
reject(err);
}
});
};
let addId = (id) => {
return new Promise(async (resolve, reject) => {
// check email is exist or not
let isIdExist = await verificarId(id);
if (isIdExist) {
const embed04 = new Discord.MessageEmbed()
.setColor('#A0EE45')
.setAuthor('Tuga Academy - Whitelist', 'https://cdn.discordapp.com/attachments/793200558248165396/885579421933776956/logosemfundo96.png')
.setDescription('Mencione um **ID** que não esteja usado.')
.setTimestamp()
.setFooter(`${message.author.username}`, 'https://cdn.discordapp.com/attachments/793200558248165396/885579421933776956/logosemfundo96.png');
message.channel.bulkDelete(1);
message.author.send(embed04);
} else {
if(nome && sobrenome) {
message.member.setNickname(""+id+" | "+nome+" "+sobrenome+"");
connection.connect(function(err) {
var sql = "INSERT INTO `vrp_users`(`id`, `whitelisted`, `banned`) VALUES ('"+id+"','1','0')";
connection.query(sql,[id], function (err, result) {
const embed01 = new Discord.MessageEmbed()
.setColor('#A0EE45')
.setAuthor('Tuga Academy - Whitelist', 'https://cdn.discordapp.com/attachments/793200558248165396/885579421933776956/logosemfundo96.png')
.setDescription('ID **autorizado**.')
.setTimestamp()
.setFooter(`${message.author.username}`, 'https://cdn.discordapp.com/attachments/793200558248165396/885579421933776956/logosemfundo96.png');
message.channel.bulkDelete(1);
console.log("ID Autorizado: " + id);
message.author.send(embed01);
});
});
} else {
const embed04 = new Discord.MessageEmbed()
.setColor('#A0EE45')
.setAuthor('Tuga Academy - Whitelist', 'https://cdn.discordapp.com/attachments/793200558248165396/885579421933776956/logosemfundo96.png')
.setDescription('Mencione um **NOME** e **SOBRENOME**.')
.setTimestamp()
.setFooter(`${message.author.username}`, 'https://cdn.discordapp.com/attachments/793200558248165396/885579421933776956/logosemfundo96.png');
message.channel.bulkDelete(1);
message.author.send(embed04);
}
}
});
};
var pattern = /^([^0-9]*)$/;
if(id && id.value.match(pattern)) {
if(nome && nome.value.match(pattern)) {
if(sobrenome && sobrenome.value.match(pattern)){
addId(id);
}
}
}
}
What I want to do is: When someone types -wl "id" "name" "sobrenome" all the data goes to my MYSQL database. This is possible with the function addId(id), but I don’t want numbers in their names. Only letters. I only want to call the function addId(id) when args[1] (nome) and args[2] (sobrenome) don't have numbers.
To check if their entire name has a digit, use RegExp. This will test the entire argument (if that is what you check) for a number. This returns true if the number is found, and false if it isn’t.
const numRegex = /\d+/g
console.log(numRegex.test('This has no number'))
console.log(numRegex.test('This has 1 number'))
To use this in your code, you will need to use the following
numRegex.test(args[1])
numRegex.test(args[2])
Soo I found another way to fix the issue, I used a regex to filter na username, if it contains numbers, they will be deleted and the nickname will only have letters.
var numberPattern = /[a-zA-Z]+/;
var nome1 = args[1];
var nome2 = args[2];
var nome1f = nome1.match( numberPattern )
var nome2f = nome2.match( numberPattern )
I am trying to make a Discord.js giveaway command that send an embed, save it to the variable embedSent then collect the reactions after the TimeOut with the reactions.get() method, but I keep getting the error TypeError: embedSent.reactions.get is not a function Here is the part of my code :
var embed = new Discord.MessageEmbed();
embed.setColor(0x3333ff);
embed.setTitle("Nouveau Giveaway !");
embed.setDescription("**" + item + "**");
embed.addField(`Durée : `, ms(ms(time), {
long: true
}), true);
embed.setFooter("Réagissez à ce message avec 🎉 pour participer !");
var embedSent = await message.channel.send(embed);
embedSent.react("🎉");
setTimeout(function () {
var peopleReacted = embedSent.reactions.get("🎉").users.filter(user => user.id !== client.user.id).array()
}, time);
Ok, after almost 2 months, I finally figured it out. The full, working command (DiscordJS v12) :
if (command == "giveaway") {
// !giveaway {time s/m/d} {item}
const messageArray = message.content.split(" ");
if (!message.member.hasPermission(["ADMINISTRATOR"])) return message.channel.send("You don't have enough permissions to start a giveaway !")
var item = "";
var time;
var winnerCount;
for (var i = 1; i < args.length; i++) {
item += (args[i] + " ");
}
time = args[0];
if (!time) {
return message.channel.send(`Invalid duration provided`);
}
if (!item) {
item = "No title"
}
var embed = new Discord.MessageEmbed();
embed.setColor(0x3333ff);
embed.setTitle("New Giveaway !");
embed.setDescription("**" + item + "**");
embed.addField(`Duration : `, ms(ms(time), {
long: true
}), true);
embed.setFooter("React to this message with 🎉 to participate !");
var embedSent = await message.channel.send(embed);
embedSent.react("🎉");
setTimeout(async () => {
try{
const peopleReactedBot = await embedSent.reactions.cache.get("🎉").users.fetch();
var peopleReacted = peopleReactedBot.array().filter(u => u.id !== client.user.id);
}catch(e){
return message.channel.send(`An unknown error happened during the draw of the giveaway **${item}** : `+"`"+e+"`")
}
var winner;
if (peopleReacted.length <= 0) {
return message.channel.send(`Not enough participants to execute the draw of the giveaway **${item}** :(`);
} else {
var index = Math.floor(Math.random() * peopleReacted.length);
winner = peopleReacted[index];
}
if (!winner) {
message.channel.send(`An unknown error happened during the draw of the giveaway **${item}**`);
} else {
console.log(`Giveaway ${item} won by ${winner.toString()}`)
message.channel.send(`🎉 **${winner.toString()}** has won the giveaway **${item}** ! Congratulations ! 🎉`);
}
}, ms(time));
}
Hope it helped some !
I guess this giveaway command works for me - Discord.js V13
don't forget to have npm i ms installed if you haven't already
const { Client, Intents, CommandInteraction, ReactionUserManager } = require('discord.js');
const INTENTS = new Intents(32767); // 32767 == full intents, calculated from intent calculator
const client = new Client({
intents: INTENTS
});
const Discord = require('discord.js');
const ms = require('ms') // make sure package ms is downloaded in console, to do this, simply type: npm i ms in your terminal
// https://www.npmjs.com/package/ms
client.once("ready" , () => {
console.log("I am online!")
});
client.on('messageCreate', async message => {
const prefix = "!" // this can be any prefix you want
let args = message.content.substring(prefix.length).split(" ")
// COMMAND FORMAT: !startgiveaway {duration} {winners} {#channel} {prize}
// E.g. !startgiveaway 24h 3w #giveaways Free Discord Nitro
if ((message.content.startsWith(`${prefix}startgiveaway`))) { // this condition can be changed to any command you'd like, e.g. `${prefix}gstart`
if (message.member.roles.cache.some(role => (role.name === 'Giveaway') )) { // user must have a role named Giveaway to start giveaway
let duration = args[1];
let winnerCount = args[2];
if (!duration)
return message.channel.send('Please provide a duration for the giveaway!\nThe abbreviations for units of time are: `d (days), h (hours), m (minutes), s (seconds)`');
if (
!args[1].endsWith("d") &&
!args[1].endsWith("h") &&
!args[1].endsWith("m") &&
!args[1].endsWith("s")
)
return message.channel.send('Please provide a duration for the giveaway!\nThe abbreviations for units of time are: `d (days), h (hours), m (minutes), s (seconds)`');
if (!winnerCount) return message.channel.send('Please provide the number of winners for the giveaway! E.g. `1w`')
if (isNaN(args[2].toString().slice(0, -1)) || !args[2].endsWith("w")) // if args[2]/winnerCount is not a number (even after removing end 'w') or args[2] does not end with 'w', condition returns:
return message.channel.send('Please provide the number of winners for the giveaway! E.g. `3w`');
if ((args[2].toString().slice(0, -1)) <= 0)
return message.channel.send('The number of winners cannot be less than 1!');
let giveawayChannel = message.mentions.channels.first();
if (!giveawayChannel || !args[3]) return message.channel.send("Please provide a valid channel to start the giveaway!")
let prize = args.slice(4).join(" ");
if (!prize) return message.channel.send('Please provide a prize to start the giveaway!');
let startGiveawayEmbed = new Discord.MessageEmbed()
.setTitle("🎉 GIVEAWAY 🎉")
.setDescription(`${prize}\n\nReact with 🎉 to participate in the giveaway!\nWinners: **${winnerCount.toString().slice(0, -1)}**\nTime Remaining: **${duration}**\nHosted By: **${message.author}**`)
.setColor('#FFFFFF')
.setTimestamp(Date.now() + ms(args[1])) // Displays time at which the giveaway will end
.setFooter("Giveaway ends");
let embedGiveawayHandle = await giveawayChannel.send({embeds: [startGiveawayEmbed]})
embedGiveawayHandle.react("🎉").catch(console.error);
setTimeout(() => {
if (embedGiveawayHandle.reactions.cache.get("🎉").count <= 1) {
return giveawayChannel.send("Nobody joined the giveaway :(")
}
if (embedGiveawayHandle.reactions.cache.get("🎉").count <= winnerCount.toString().slice(0, -1)) { // this if-statement can be removed
return giveawayChannel.send("There's not enough people in the giveaway to satisfy the number of winners!")
}
let winner = embedGiveawayHandle.reactions.cache.get("🎉").users.cache.filter((users) => !users.bot).random(winnerCount.toString().slice(0, -1));
const endedEmbedGiveaway = new Discord.MessageEmbed()
.setTitle("🎉 GIVEAWAY 🎉")
.setDescription(`${prize}\n\nWinner(s): ${winner}\nHosted By: **${message.author}**\nWinners: **${winnerCount.toString().slice(0, -1)}**\nParticipants: **${embedGiveawayHandle.reactions.cache.get("🎉").count - 1}**\nDuration: **${duration}**`)
.setColor('#FFFFFF')
.setTimestamp(Date.now() + ms(args[1])) // Displays time at which the giveaway ended
.setFooter("Giveaway ended");
embedGiveawayHandle.edit({embeds:[endedEmbedGiveaway]}); // edits original giveaway message to show that the giveaway ended successfully
const congratsEmbedGiveaway = new Discord.MessageEmbed()
.setDescription(`🥳 Congratulations ${winner}! You just won **${prize}**!`)
.setColor('#FFFFFF')
giveawayChannel.send({embeds: [congratsEmbedGiveaway]}).catch(console.error);
}, ms(args[1]));
} // end "Giveaway" role condition
}
})
client.login('INSERT YOUR BOT TOKEN HERE');