I have been working on updating my current command cooldown, when upadting my message.js file the cooldown does not show.
This is the current code in the command cooldown file
const botconfig = require("../../botconfig.json");
const fs = require("fs")
const Discord = require('discord.js')
const cooldowns = new Map()
module.exports = async (bot, message) => {
if(message.author.bot || message.channel.type === "dm") return;
let prefixes = JSON.parse(fs.readFileSync("././prefixes.json", "utf8"))
if(!prefixes[message.guild.id]){
prefixes[message.guild.id] = {
prefixes: botconfig.prefix
};
}
let prefix = prefixes[message.guild.id].prefixes;
let args = message.content.slice(prefix.length).trim().split(/ +/g);
let cmd = args.shift().toLowerCase();
if(!message.content.startsWith(prefix)) return;
let commandfile = bot.commands.get(cmd) || bot.commands.get(bot.aliases.get(cmd))
if(commandfile) commandfile.run(bot, message, args)
if(!cooldowns.has(commandfile.name)){
cooldowns.set(commandfile.name, new Discord.Collection());
}
const current_time = Date.now();
const time_stamps = cooldowns.get(commandfile.name);
const cooldown_amount = (commandfile.cooldown) * 1000;
if(time_stamps.has(message.author.id)){
const experation_time = time_stamps.get(message.author.id) + cooldown_amount;
if (current_time < experation_time){
const time_left = (experation_time - current_time) / 1000;
return message.reply(`Please wait ${time_left.toFixed(1)} more seconds before using this command!`)
}
}
time_stamps.set(message.author.id, current_time);
setTimeout(() => time_stamps.delete(message.author.id), cooldown_amount);
}
In the command file I have
module.exports = {
config:{
name: "beg",
aliases: [],
cooldown: 5, // current cooldown in seconds
category: "currency",
description: "Gets you money",
usage: "[command | alias]",
accessableby: "Members"
},
When I use the command the command will work but the cooldown does not work and lets me use the command again. Am I doing something wrong? I would also like to know if I stop running the bot for an update will the cooldown save for example I use the command "!!daily" then re-set the bot for an update and 24 hours did not pass that when it goes back online the cooldown save's and keeps counting.
Cooldown should be a Discord.Collection
const cooldowns = new Discord.Collection(); //that goes on top of your script
Is first time what I comment here, I hope it helps you.
It is a matter of order:
First you call if(commandfile) commandfile.run(bot, message, args) but then only you check if the Cooldown exists. You need to rearange you code like this, move the .run down.
const botconfig = require("../../botconfig.json");
const fs = require("fs")
const Discord = require('discord.js')
const cooldowns = new Discord.Collection();
// While this does not matter, we make a Collection to for consistentcy
module.exports = async (bot, message) => {
if(message.author.bot || message.channel.type === "dm") return;
let prefixes = JSON.parse(fs.readFileSync("././prefixes.json", "utf8"))
if(!prefixes[message.guild.id]){
prefixes[message.guild.id] = {
prefixes: botconfig.prefix
};
}
let prefix = prefixes[message.guild.id].prefixes;
let args = message.content.slice(prefix.length).trim().split(/ +/g);
let cmd = args.shift().toLowerCase();
if(!message.content.startsWith(prefix)) return;
let commandfile = bot.commands.get(cmd) || bot.commands.get(bot.aliases.get(cmd));
if(!commandfile) return;
// return if no command Found, if one is found, proceed to check for cooldown
if(!cooldowns.has(commandfile.name)){
cooldowns.set(commandfile.name, new Discord.Collection());
}
const current_time = Date.now();
const time_stamps = cooldowns.get(commandfile.name);
const cooldown_amount = (commandfile.cooldown) * 1000;
if(time_stamps.has(message.author.id)){
const experation_time = time_stamps.get(message.author.id) + cooldown_amount;
if (current_time < experation_time){
const time_left = (experation_time - current_time) / 1000;
return message.reply(`Please wait ${time_left.toFixed(1)} more seconds before using this command!`);
}
}
// above here is the return, if the cooldown is still active, if so it returns with the message
time_stamps.set(message.author.id, current_time);
// here we set the time_stamp and now can run the command
commandfile.run(bot, message, args);
}
Related
Im trying to make a stopwatch command that when you say !duty on and then !duty off it will calculate the time took to stop it. It works like a regular stopwatch but it is for discord. I have been trying to fix the err for a week but i cant understand why it doesnt work pls help me. The err is in line 10 id where it says message.guild.id
the code:
const Discord = require('discord.js');
const StopWatch = require("timer-stopwatch-dev");
const moment = require('moment');
module.exports = {
name: 'duty',
description: "This is a stopwatch command",
async execute(client, message, args, CurrentTimers) {
try {
let guildTimers = CurrentTimers.get(message.guild.id);
let guildTimersUser = guildTimers.get(message.author.id);
if(!guildTimersUser){ guildTimers.set(message.author.id, new StopWatch()); guildTimersUser = guildTimers.get(message.author.id); };
if(!args[0] || args[0] === 'on'){
if(guildTimersUser.isRunning()) return message.channel.send('You need to stop your shift first!')
guildTimersUser.start();
message.channel.send('You have started your shift')
} else if(args[0] === 'off'){
if(!guildTimersUser.isRunning()) return message.channel.send('You need to start the Stopwatch first!')
guildTimersUser.stop();
message.channel.send(new Discord.RichEmbed().setTitle('You have stopped the Stopwatch!').setDescription('Total Time: ' + dhm(guildTimersUser.ms)).setTimestamp());
}
}
catch(err) {
console.log(err)
}
function dhm(ms){
days = Math.floor(ms / (24*60*60*1000));
daysms=ms % (24*60*60*1000);
hours = Math.floor((daysms)/(60*60*1000));
hoursms=ms % (60*60*1000);
minutes = Math.floor((hoursms)/(60*1000));
minutesms=ms % (60*1000);
sec = Math.floor((minutesms)/(1000));
return days+" days, "+hours+" hours, "+minutes+" minutes, "+sec+" seconds.";
}
}
}
my main:
require('dotenv').config();
//create cooldowns map
const cooldowns = new Map();
module.exports = (Discord, client, message) => {
const prefix = '!';
if(!message.content.startsWith(prefix) || message.author.bot) return;
const args = message.content.slice(prefix.length).split(/ +/);
const cmd = args.shift().toLowerCase();
const command = client.commands.get(cmd) ||
client.commands.find(a => a.aliases && a.aliases.includes(cmd));
if(command){
//If cooldowns map doesn't have a command.name key then create one.
if(!cooldowns.has(command.name)){
cooldowns.set(command.name, new Discord.Collection());
}
const current_time = Date.now();
const time_stamps = cooldowns.get(command.name);
const cooldown_amount = (command.cooldown) * 1000;
//If time_stamps has a key with the author's id then check the expiration time to send a message to a user.
if(time_stamps.has(message.author.id)){
const expiration_time = time_stamps.get(message.author.id) + cooldown_amount;
if(current_time < expiration_time){
const time_left = (expiration_time - current_time) / 1000;
return message.reply(`Please wait ${time_left.toFixed(1)} more seconds before using ${command.name}`);
}
}
//If the author's id is not in time_stamps then add them with the current time.
time_stamps.set(message.author.id, current_time);
//Delete the user's id once the cooldown is over.
setTimeout(() => time_stamps.delete(message.author.id), cooldown_amount);
}
try{
command.execute(message,args, cmd, client, Discord, CurrentTimers);
} catch (err){
message.reply("There was an error trying to execute this command!");
console.log(err);
}
}
You didn’t show the actual error but I suspect that it is something like Cannot read property 'id' of undefined. The way to fix this is to make sure of 2 things:
Make sure the message is not in DM
Make sure your execution parameters are passed in correctly.
command.execute(client, message, args, CurrentTimers)
//these may not be the same variable names, but make sure the values are correct
TL:DR - I need help using a variable in more than 1 file
Currently I have a bot that counts how many times the word ":p" has been used. It adds that number to the variable "numberofp". On a separate file I want to call the variable on an embed but it says numberofp is undefined. Code is below. If you would like more code just ask!
code for index.js
// variables
var numberofp = 0;
client.on('message', (message) => {
if(message.author.id = 714544589305806868){
if(message.content.includes(':p')){
numberofp = numberofp + 1;
console.log('Porsha_boy said :p, so far it has been sent this many times:', numberofp);
}
}
})
Code for embed
const db = require("quick.db")
const Discord = require('discord.js')
module.exports = {
name: 'rub',
description: 'a command that tells you what your ping is',
execute(message, args, Discord){
// Basic embed
var embed = new Discord.MessageEmbed()
.setAuthor(numberofp)
.setColor("#34BDE1")
console.log('working')
}
}
You need to export the variable to be visible from the module outside:
wordcounter.js
let counter = 0;
function increase(a = 1) {
counter += a;
}
function getCounter() {
return counter;
}
exports.increase = increase;
exports.getCounter = getCounter;
clientone.js
const wc = require('./wordcounter');
wc.increase();
wc.increase(2);
wc.increase(5);
clienttwo.js
const wc = require('./wordcounter');
wc.increase(1);
wc.increase(1);
wc.increase(5);
index.js
const wc = require('./wordcounter');
const c1 = require('./clientone');
const c2 = require('./clienttwo');
console.log(wc.getCounter());
I am attempting to make a command like dank memer has, when someone says F or f, the bot replies with F. My problem is that it will not work without the prefix, but I would like to be able to do it without the prefix.
Here is my code. I use a command handler.
//THIS IS THE INDEX.JS FILE
const Discord = require('discord.js');
const { default_prefix, token_bot } = require('./config.json');
const client = new Discord.Client();
const fs = require('fs');
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.once('ready', () => {
console.log('Ready Player One!');
});
client.on('message', message => {
if (!message.content.startsWith(default_prefix) || message.author.bot) return;
const args = message.content.slice(default_prefix.length).trim().split(/ +/);
const command = args.shift().toLowerCase();
if (command === 'f'){
client.commands.get('f').execute(message, args);
}
And this one is the f.js command that it calls on.
module.exports = {
name: 'f',
description: "This is an f command",
execute(message, args){
message.channel.send('F');
},
};
This is not all of my index.js file, it is too long.
The solution to this is very simple. All commands have prefixes, so I would not consider what you are trying to create as a command, I would say it is technically more of an auto-response. Therefore, you should not be using the code of your args or command variables to check if "F" has been sent, you should instead directly check the message's content.
client.on('message', message => {
if (!message.content.startsWith(default_prefix) || message.author.bot) return;
const args = message.content.slice(default_prefix.length).trim().split(/ +/);
const command = args.shift().toLowerCase();
if (message.content.toLowerCase() == 'f'){
client.commands.get('f').execute(message, args);
}
});
I would advise looking into the args and command variables and learning how their values are being retrieved. Your code, as it is, seems to heavily rely on a simple template, but you cannot entirely depend on this template if you want to fully customize how your bot/commands will look and function.
I've never had a problem with the say command until I start using modules and cleaned up my code but since I have few my commands have bugged. I'm trying to figure out why it is saying the command.
const commandFiles = fs
.readdirSync("./commands/")
.filter(file => file.endsWith(".js"));
for (const file of commandFiles) {
const command = require(`./commands/${file}`);
bot.commands.set(command.name, command);
}
bot.on("message", async message => {
if (!message.content.startsWith(PREFIX)) return;
let args = message.content.substring(PREFIX.length).split(" ");
switch (args[0]) {
case "say":
bot.commands.get("say").execute(message, args);
break;
const Discord = require("discord.js");
module.exports = {
name: "say",
description: "Show's avatar",
async execute(message, args){
const sayMessage = args.join(" ");
message.delete().catch(O_o => {});
message.channel.send(`${sayMessage} - ${message.author}`);
}
}
Thanks in advance!
The code is doing exactly what you programmed it to, be it not intended.
let args = message.content.substring(PREFIX.length).split(" "); // args = ['say', 'Hello', 'World']
bot.commands.get("say").execute(message, args); // Passing in the entire args array
const sayMessage = args.join(" "); // sayMessage = 'say Hello World'
One solution of many:
let args = message.content.substring(PREFIX.length).split(" ");
const command = args.splice(0, 1); // args now only contains the arguments
switch (command) {
...
}
Here you go this is using the anidiots guidebot boiler plate i highly recommend using it to help you better understand incorporating a command handler into your discord bot.
your going to want to download the repo from here https://github.com/AnIdiotsGuide/guidebot/
extract it
run npm install
in the commands folder add say.js using the code below this is how to properly execute what your trying todo
by default the prefix is ~ to change it in discord chat run ~conf edit prefix Example: ~conf edit prefix !
run !say hello world
exports.run = async (client, message, args) => {
const sayMessage = args.join(" ");
message.delete();
message.channel.send(sayMessage + ' - ' + message.author)
};
exports.conf = {
enabled: true,
guildOnly: false,
aliases: [],
permLevel: "User"
};
exports.help = {
name: "say",
category: "Miscelaneous",
description: "say command",
usage: "say"
};```
My bot returns undefined when using bot.channels.get(channelid).
Here's a sample of my code:
//this is executed in a guild with id 416809320513011713
const Discordjs = require("discord.js");
const bot = new Discordjs.Client();
const auth = require('./auth.json');
const FileSys = require("fs");
bot.on('messageDelete', async function (message) {
console.log('message deleted')
let currentguildsettings = JSON.parse(FileSys.readFileSync('./DatStore/GuildDat/' + message.guild.id + '.dat', 'UTF8'));
if (currentguildsettings[0] == 1) {
if (currentguildsettings[1] != 0) {
let channelid = currentguildsettings[1].toString()
let channel = bot.channels.get(channelid);
console.log('settings on true, channelid ' + channelid)
if (channel) {
console.log('channel found')
}
}
}
}
bot.login(auth.token)
file ./DatStore/GuildDat/416809320513011713.dat contains:
[1,424085503361417200,0]
Here's the output:
message deleted
settings on true, channelid 424085503361417200
If the channel was found it should've logged 'channel found' in the output.
What should I change to make it return the channel?
The channel id key is a string, you must enclose it as a string in your array.
let c1 = bot.channels.get(424085503361417200); // Will produce undefined
let c2 = bot.channels.get('424085503361417200'); // Will produce a channel object (if available)
The channel wasn't available since I used the wrong id:
I saved the id's at my server settings command in int format instead of string, parseInt() broke the exact number.
if (logchannelaction == 'set') {
if (currentguildsettings[1] == message.channel.id) return message.reply("logchannel was already set to this channel");
currentguildsettings[1] = parseInt(message.channel.id);
message.reply("logchannel has set to #" + message.channel.name);
if (currentguildsettings[0] == 0) {
currentguildsettings[0] = 1
message.reply("logchannel has automatically enabled");
}
FileSys.writeFileSync(guilddatpath, JSON.stringify(currentguildsettings));
return
}
Thank you for trying to help me.