Command Cooldown 10 second not working discord bot - node.js

I want add cooldown and write this code, but doesn't work, can you tell me where is the error? Very Thanks.
client.on('message', message => {
const helloSet = new Set();
if (helloSet.has(message.author.id)) {
const expirationTime = helloSet.get(message.author.id) + 10000; // 10000 is cooldow
let user1 = message.author;
let user = message.author;
if (message.mentions.users.first()) {
user = message.mentions.members.first().user
}
if (now < expirationTime) {
const timeLeft = (expirationTime - now) / 1000;
return message.reply(`Ожидайте ${timeLeft.toFixed(1)} перед выдачей печеньки`);
} else {
helloSet.add(message.author.id)
if (user !== user1) {
if (message.content.includes(`🍪`)) {
db.add(`${user.id}_cockie`, 1);
setTimeout(() => {
helloSet.delete(message.author.id)
}, 10000)
}}}}});

You could try this!
// First, this must be at the top level of your code, **NOT** in any event!
const talkedRecently = new Set();
Now in the command event add this:
if (talkedRecently.has(msg.author.id)) {
msg.channel.send("Wait 1 minute before getting typing this again. - " + msg.author);
} else {
// the user can type the command ... your command code goes here :)
// Adds the user to the set so that they can't talk for a minute
talkedRecently.add(msg.author.id);
setTimeout(() => {
// Removes the user from the set after a minute
talkedRecently.delete(msg.author.id);
}, 60000);
}
Source

Related

Command Cooldown 1 minute not working discord bot

Here I tried making a command cooldown so people wont be spamming and getting rich fast on my discord bot! The thing is though the code I wrote does not do what I want it to do! It just ignores talkRecently Here is my code:
var eco = require('discord-economy');
const editJsonFile = require("edit-json-file");
const prefix = '.';
const talkedRecently = new Set();
exports.run = async (client, message, args, ops) => {
if (talkedRecently.has(message.author.id)) {
message.channel.send("Wait 1 minute before getting typing this again. - " + message.author);
} else {
var job2 = ['actor/actress','astronaut','baker','barber','biologist','chef','doctor','dentist','farmer','nurse','jounalist','police officer','vet','vocalist','zoologist','waiter/waitress'];
const user = message.author.id;
var number = Math.floor(Math.random() * (500 + 1));
let check = eco.FetchBalance(user);
if(!check) {
eco.SetBalance(user, 0);
}
eco.AddToBalance(user, number)
var job = job2[Math.floor(Math.random() * job2.length)];
message.channel.send(`You have worked as a **${job}** and you have earned ${number}`);
}
talkedRecently.add(message.author.id);
setTimeout(() => {
// Removes the user from the set after a minute
talkedRecently.delete(message.author.id);
}, 60000);
}
Excluding boilerplate code
var arrayOfIntervalUsed = []
var arrOfIds = [];
client.on("message", (msg) => {
arrOfIds.push(msg.author.id)
if(arrOfIntervalUsed.indexOf(msg.author.id) === -1){
setInterval(() => {
arrOfIntervalUsed.push(msg.author.id) // so the bot isn't duplicating itself
if(arrOfIds.filter(() => {
return msg.author.id
}).length > 10){
msg.reply("Stop spamming")
arrOfIds = arrOfIds.filter(() => {
return !msg.author.id
})
}
}, 60000)
}
})
EDIT:
If you want none of the commands to work if they spam add a variable by default true which has to be true in your if statement for what command it is and in the code above below the message about stop spamming make it false but if you want it to come back on add another setInterval outside of that that a set amount of miliseconds it is restored.

I want a coin system for seating in a voice channel per 1 minute

I did that the bot fixes when the user enters and leaves the voice channel, i want for each minute of sitting there a participant dripping 200 coins, i already did so with the chat. For my idea, I need "ms" and "fs" to capture a minute (60000 milliseconds) I also have a file where all the coins are chased, I want the amount per minute to go there
const Discord = require('discord.js');
const fs = require("fs");
const ms = require("ms");
const token = "my token here";
const prefix = "!";
const bot = new Discord.Client({disableEveryone: true});
let coins = require("./coins.json");
bot.on("message", message => {
if (message.author.bot) return;
if (message.channel.type === "dm") return;
if(!coins[message.author.id]) {
coins[message.author.id] = {
coins: 0
};
}
let coinAmt = Math.floor(Math.random() * 70) + 25;
let baseAmt = Math.floor(Math.random() * 15) + 12;
if(coinAmt === baseAmt){
coins[message.author.id] = {
coins: coins[message.author.id].coins + coinAmt
};
fs.writeFile("./coins.json", JSON.stringify(coins), (err) => {
if (err) console.log(err)
});
let coinEmbed = new Discord.MessageEmbed()
.setColor("RANDOM")
.addField("Excellent! 🥳", `${message.author}, \`${coinAmt}\` coins added to your balance`)
message.channel.send(coinEmbed)
}
});
bot.on('voiceStateUpdate', (oldMember, newMember) => {
console.log('enter');
if (oldMember.selfMute === true) {
console.log('muted');
}
if (newMember.selfMute === true) {
console.log('muted-2');
}
});
I will be very grateful if you help, for you it is a few minutes and for me it is of great benefit
Here's how I would solve it:
Every time a member joins a channel, you save the Date in a separate object
When they leave, you see what's the difference between the current Date and the one you saved and calculate the coins to give them
The questions are mostly about how to determine if a user has joined or left the voice chat: you can check that by seeing if either their previous or current VoiceState has a channel.
Here's an example:
let voiceStates = {}
client.on('voiceStateUpdate', (oldState, newState) => {
let { id } = oldState // This is the user's ID
if (!oldState.channel) {
// The user has joined a voice channel
voiceStates[id] = new Date()
} else if (!newState.channel) {
// The user has left the voice chat (and hasn't just switched channel)
let now = new Date()
let joined = voiceStates[id] || new Date()
// This will be the difference in milliseconds
let dateDiff = now.getTime() - joined.getTime()
if (dateDiff > 60 * 1000) {
// The user has spent more than 1 minute in voice channels
// You can now do your math and assign the coins as you wish
}
}
})

Discord.js Command Cooldown + Time Remaining

Okay so I am looking to make it so that the cooldown shows how much longer the user needs to wait until they can work again. The cool down works butI want it to show the time remainign rather than it saying you need to wait 15 mnutes before typing this command. Is it Possible?
const { RichEmbed } = require("discord.js");
const { stripIndents } = require("common-tags");
const { prefix } = require("../../botconfig.json");
const db = require('quick.db')
let bal = require("../../database/balance.json");
let works = require('../../database/works.json');
const fs = require('fs');
const talkedRecently = new Set();
//Set cooldown
module.exports = {
name: "work",
aliases: [],
category: "economy",
description: "Gets you money",
usage: "[command | alias]",
run: async (client, message, args) => {
if (talkedRecently.has(message.author.id)) {
message.channel.send("You have to wait TIME minutes before you can work again")
} else {
if(!bal[message.author.id]){
bal[message.author.id] = {
balance: 0
};
}
if(!works[message.author.id]) {
works[message.author.id] = {
work: 0
};
}
const Jwork = require('../../work.json');
const JworkR = Jwork[Math.floor(Math.random() * Jwork.length)];
var random = Math.floor(Math.random() * 20) + 3;
let curBal = bal[message.author.id].balance
bal[message.author.id].balance = curBal + random;
let curWork = works[message.author.id].work
works[message.author.id].work = curWork + 1;
fs.writeFile('././database/works.json', JSON.stringify(works, null, 2), (err) => {
if (err) console.log(err)
})
fs.writeFile('././database/balance.json', JSON.stringify(bal, null, 2), (err) => {
let embed = new RichEmbed()
.setColor("RANDOM")
.setDescription(`
**\💼 | ${message.author.username}**, ${JworkR} 💴 **${random}**
`)
message.channel.send(embed)
if (err) console.log(err)
});
// Adds the user to the set so that they can't talk for a minute
talkedRecently.add(message.author.id);
setTimeout(() => {
// Removes the user from the set after a minute
talkedRecently.delete(message.author.id);
}, 900000);
}
}
}
Unfortunately, your current system won't be any help. You'll have to store more than just the user if you want to use the timings of their cooldown.
Let's use a Map for our variable so we can have key-value pairs. This will make it easier to keep track of the information we need
// Replace talkedRecently's declaration with this...
const cooldowns = new Map();
To put a user on cooldown, use Map.set() to add the user and the time at which their cooldown should expire to cooldowns. Then, use Map.delete() when the cooldown should run out to allow the user access to the command again.
// Replace the talkedRecently.add(...) section with this...
cooldowns.set(message.author.id, Date.now() + 900000);
setTimeout(() => cooldowns.delete(message.author.id), 900000);
In order to determine the amount of time remaining on the cooldown, we have to subtract the current time from that at which it expires. However, this will give us milliseconds, rendering the value unreadable to us. A simple, easy way to convert duration into words is by using humanize-duration (moment is also an option). Finally, we can send the desired message, letting the user know how much time they have left on their cooldown.
// Put this where you require your other dependencies...
const humanizeDuration = require('humanize-duration');
// Replace the if (talkedRecently.has(...)) part with this...
const cooldown = cooldowns.get(message.author.id);
if (cooldown) {
const remaining = humanizeDuration(cooldown - Date.now());
return message.channel.send(`You have to wait ${remaining} before you can work again`)
.catch(console.error);
}

Values get overwritten by latest person to request the bot?

I have made a raffle ballot discord bot that allows a user to DM the bot their name and raffle entry amount. Once they have set the values they can start the entry of the raffle by DMing !enter. Once this has happend a function is called which then starts a for-loop the for loop will run based on the specified entry amount. I have also added in a delay within the for-loop due to the service to get the raffle tickets takes some time (Code is edited for SO Post due to sensitive API info)
Once this is complete it then sends a DM back to the user that had DMed the bot originally. The problem I am facing is that if multiple users DM at the same time or while it is running from the first DM the variables get overwritten by the latest person requesting the bot.
I assumed that by using a Discord.js bot each time a user DMs it creates a new instance of the script or node process?
Is it possible for the function that the bot calls once DMed to create a new process within the main node process so it doesn't get overwritten?
const Discord = require('discord.js');
const botconfig = require('./discordBotConfig.json');
const bot = new Discord.Client({disableEveryone: true});
const c = require('chalk');
// Chalk Theme
const ctx = new c.constructor({level: 2});
const error = c.red;
const waiting = c.magenta;
const success = c.green;
const discordBot = c.yellow;
// Current Raffles (API Link Later)
let activeRaffles = 'Raffle 1';
// User Parmas
let usrName = '';
let entryAmount = 0;
// Ticket
let raffleTicket = [];
let retryDelay = 3000;
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
// Enter
const enterIn = async () => {
console.log('User name', usrName);
raffleTicket.push(Math.random(0, 50));
}
// Init Raffle Entry
const raffleInit = async (entryAmount) => {
for (let i = 0; i < entryAmount; i++) {
enterIn();
await sleep(retryDelay);
}
dmUser();
}
const dmUser = () => {
// Discord Message Complete
let botCompleteMsg = new Discord.RichEmbed()
.setTitle('Finished!')
.setColor('#25E37A')
.addField('Name: ', usrName)
.addField('Tickets: ', raffleTicket)
.addField('Last Update: ', bot.user.createdAt);
bot.fetchUser(userID).then((user) => {
user.send(botCompleteMsg);
});
return; // End the application
}
// Discord Bot Setup
bot.on('ready', async () => {
console.log(discordBot(`${bot.user.username} is Online!`));
bot.user.setActivity('Entering Raffle');
});
bot.on('message', async message => {
if (message.channel.type === 'dm') {
let prefix = botconfig.prefix;
let messageArray = message.content.split(' ');
let cmd = messageArray[0];
if (cmd === `${prefix}name`) {
if (messageArray.length === 3) {
userID = message.author.id;
usrName = messageArray[1];
entryAmount = messageArray[2];
// Raffle summary
let raffleSummary = new Discord.RichEmbed()
.setTitle('Entry Summary')
.setColor('#8D06FF')
.addField('Name: ', usrName)
.addField('Entry Amount: ', entryAmount)
return message.author.send(raffleSummary), message.author.send('Type **!start** to begin entry or type **!set** again to set the entry details again.');
}
}
if (cmd === `${prefix}enter`) {
// Raffle summary
let startMessage = new Discord.RichEmbed()
.setTitle('Entering raffle!')
.setDescription('Thanks for entering! :)')
.setColor('#8D06FF')
return message.author.send(startMessage), raffleInit(entryAmount);
}
}
});
bot.login(botconfig.token);
You can store your user data in a list with classes.
var userData = [
{name: "sample#0000", entryNum: 0}
];

Deleting all messages in discord.js text channel

Ok, so I searched for a while, but I couldn't find any information on how to delete all messages in a discord channel. And by all messages I mean every single message ever written in that channel. Any clues?
Try this
async () => {
let fetched;
do {
fetched = await channel.fetchMessages({limit: 100});
message.channel.bulkDelete(fetched);
}
while(fetched.size >= 2);
}
Discord does not allow bots to delete more than 100 messages, so you can't delete every message in a channel. You can delete less then 100 messages, using BulkDelete.
Example:
const Discord = require("discord.js");
const client = new Discord.Client();
const prefix = "!";
client.on("ready" () => {
console.log("Successfully logged into client.");
});
client.on("message", msg => {
if (msg.content.toLowerCase().startsWith(prefix + "clearchat")) {
async function clear() {
msg.delete();
const fetched = await msg.channel.fetchMessages({limit: 99});
msg.channel.bulkDelete(fetched);
}
clear();
}
});
client.login("BOT_TOKEN");
Note, it has to be in a async function for the await to work.
Here's my improved version that is quicker and lets you know when its done in the console but you'll have to run it for each username that you used in a channel (if you changed your username at some point):
// Turn on Developer Mode under User Settings > Appearance > Developer Mode (at the bottom)
// Then open the channel you wish to delete all of the messages (could be a DM) and click the three dots on the far right.
// Click "Copy ID" and paste that instead of LAST_MESSAGE_ID.
// Copy / paste the below script into the JavaScript console.
var before = 'LAST_MESSAGE_ID';
var your_username = ''; //your username
var your_discriminator = ''; //that 4 digit code e.g. username#1234
var foundMessages = false;
clearMessages = function(){
const authToken = document.body.appendChild(document.createElement`iframe`).contentWindow.localStorage.token.replace(/"/g, "");
const channel = window.location.href.split('/').pop();
const baseURL = `https://discordapp.com/api/channels/${channel}/messages`;
const headers = {"Authorization": authToken };
let clock = 0;
let interval = 500;
function delay(duration) {
return new Promise((resolve, reject) => {
setTimeout(() => resolve(), duration);
});
}
fetch(baseURL + '?before=' + before + '&limit=100', {headers})
.then(resp => resp.json())
.then(messages => {
return Promise.all(messages.map((message) => {
before = message.id;
foundMessages = true;
if (
message.author.username == your_username
&& message.author.discriminator == your_discriminator
) {
return delay(clock += interval).then(() => fetch(`${baseURL}/${message.id}`, {headers, method: 'DELETE'}));
}
}));
}).then(() => {
if (foundMessages) {
foundMessages = false;
clearMessages();
} else {
console.log('DONE CHECKING CHANNEL!!!')
}
});
}
clearMessages();
The previous script I found for deleting your own messages without a bot...
// Turn on Developer Mode under User Settings > Appearance > Developer Mode (at the bottom)
// Then open the channel you wish to delete all of the messages (could be a DM) and click the three dots on the far right.
// Click "Copy ID" and paste that instead of LAST_MESSAGE_ID.
// Copy / paste the below script into the JavaScript console.
// If you're in a DM you will receive a 403 error for every message the other user sent (you don't have permission to delete their messages).
var before = 'LAST_MESSAGE_ID';
clearMessages = function(){
const authToken = document.body.appendChild(document.createElement`iframe`).contentWindow.localStorage.token.replace(/"/g, "");
const channel = window.location.href.split('/').pop();
const baseURL = `https://discordapp.com/api/channels/${channel}/messages`;
const headers = {"Authorization": authToken };
let clock = 0;
let interval = 500;
function delay(duration) {
return new Promise((resolve, reject) => {
setTimeout(() => resolve(), duration);
});
}
fetch(baseURL + '?before=' + before + '&limit=100', {headers})
.then(resp => resp.json())
.then(messages => {
return Promise.all(messages.map((message) => {
before = message.id;
return delay(clock += interval).then(() => fetch(`${baseURL}/${message.id}`, {headers, method: 'DELETE'}));
}));
}).then(() => clearMessages());
}
clearMessages();
Reference: https://gist.github.com/IMcPwn/0c838a6248772c6fea1339ddad503cce
This will work on discord.js version 12.2.0
Just put this inside your client on message event
and type the command: !nuke-this-channel
Every message on channel will get wiped
then, a kim jong un meme will be posted.
if (msg.content.toLowerCase() == '!nuke-this-channel') {
async function wipe() {
var msg_size = 100;
while (msg_size == 100) {
await msg.channel.bulkDelete(100)
.then(messages => msg_size = messages.size)
.catch(console.error);
}
msg.channel.send(`<#${msg.author.id}>\n> ${msg.content}`, { files: ['http://www.quickmeme.com/img/cf/cfe8938e72eb94d41bbbe99acad77a50cb08a95e164c2b7163d50877e0f86441.jpg'] })
}
wipe()
}
This will work so long your bot has appropriate permissions.
module.exports = {
name: "clear",
description: "Clear messages from the channel.",
args: true,
usage: "<number greater than 0, less than 100>",
execute(message, args) {
const amount = parseInt(args[0]) + 1;
if (isNaN(amount)) {
return message.reply("that doesn't seem to be a valid number.");
} else if (amount <= 1 || amount > 100) {
return message.reply("you need to input a number between 1 and 99.");
}
message.channel.bulkDelete(amount, true).catch((err) => {
console.error(err);
message.channel.send(
"there was an error trying to prune messages in this channel!"
);
});
},
};
In case you didn't read the DiscordJS docs, you should have an index.js file that looks a little something like this:
const Discord = require("discord.js");
const { prefix, token } = require("./config.json");
const client = new Discord.Client();
client.commands = new Discord.Collection();
const commandFiles = fs
.readdirSync("./commands")
.filter((file) => file.endsWith(".js"));
for (const file of commandFiles) {
const command = require(`./commands/${file}`);
client.commands.set(command.name, command);
}
//client portion:
client.once("ready", () => {
console.log("Ready!");
});
client.on("message", (message) => {
if (!message.content.startsWith(prefix) || message.author.bot) return;
const args = message.content.slice(prefix.length).split(/ +/);
const commandName = args.shift().toLowerCase();
if (!client.commands.has(commandName)) return;
const command = client.commands.get(commandName);
if (command.args && !args.length) {
let reply = `You didn't provide any arguments, ${message.author}!`;
if (command.usage) {
reply += `\nThe proper usage would be: \`${prefix}${command.name} ${command.usage}\``;
}
return message.channel.send(reply);
}
try {
command.execute(message, args);
} catch (error) {
console.error(error);
message.reply("there was an error trying to execute that command!");
}
});
client.login(token);
Another approach could be cloning the channel and deleting the one with the messages you want deleted:
// Clears all messages from a channel by cloning channel and deleting old channel
async function clearAllMessagesByCloning(channel) {
// Clone channel
const newChannel = await channel.clone()
console.log(newChannel.id) // Do with this new channel ID what you want
// Delete old channel
channel.delete()
}
I prefer this method rather than the ones listed on this thread because it most likely takes less time to process and (I'm guessing) puts the Discord API under less stress. Also, channel.bulkDelete() is only able to delete messages that are newer than two weeks, which means you won't be able to delete every channel message in case your channel has messages that are older than two weeks.
The possible downside is the channel changing id. In case you rely on storing ids in a database or such, don't forget to update those documents with the id of the newly cloned channel!
Here's #Kiyokodyele answer but with some changes from #user8690818 answer.
(async () => {
let deleted;
do {
deleted = await channel.bulkDelete(100);
} while (deleted.size != 0);
})();

Resources