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
Related
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);
}
I want my bot to respond to commands that are typen with capital letters, but where should I put it, I really don't know... :heh:. So yea where should I put the .toLowercase for my bot to respond to capital letters?
client.on('message', async message => {
if(message.content.startsWith(";stats")){
cpuStat.usagePercent(function (error, percent) {
if (error) {
return console.error(error)
}
const cores = os.cpus().length // Counting how many cores your hosting has.
const cpuModel = os.cpus()[0].model // Your hosting CPU model.
const guild = client.guilds.cache.size.toLocaleString() // Counting how many servers invite your bot. Tolocalestring, meaning separate 3 numbers with commas.
const user = client.users.cache.size.toLocaleString() // Counting how many members in the server that invite your bot.
const channel = client.channels.cache.size.toLocaleString() // Counting how many channels in the server that invite your bot
const Node = process.version // Your node version.
const CPU = percent.toFixed(2) // Your CPU usage.
const d = moment.duration(message.client.uptime);
const days = (d.days() == 1) ? `${d.days()} day` : `${d.days()} days`;
const hours = (d.hours() == 1) ? `${d.hours()} hour` : `${d.hours()} hours`;
const minutes = (d.minutes() == 1) ? `${d.minutes()} minute` : `${d.minutes()} minutes`;
const seconds = (d.seconds() == 1) ? `${d.seconds()} second` : `${d.seconds()} seconds`;
const date = moment().subtract(d, 'ms').format('dddd, MMMM Do YYYY');
const embed = new Discord.MessageEmbed() // Stable or < below than 11.x.x use RichEmbed. More than 12.x.x or Master or https://github.com/discordjs/discord.js/ (github:discordjs/discord.js) use MessageEmbed.
embed.setTitle('Axmy#0102', message.author.displayAvatarURL());
embed.setDescription('Really non-useful bot, I know that everyone hates Axmy')
embed.addField('Servers 🏠', `\n${client.guilds.cache.size}`)
embed.addField('Users 🧑🤝🧑', `${client.guilds.cache.reduce((a, g) => a + g.memberCount, 0)}`)
embed.addField('Uptime <:tired:811194778149715979>', `${days}, ${hours}, ${minutes}, ${seconds}`)
embed.addField("Discord.js Version <:discord:811200194640216094> ", '12.3.1')
embed.addField("CPU Usage <:down:811195966714937395>", ` ${CPU}%`)
embed.addField("Node.js Version <:node:811196465095376896>", `${Node}`)
embed.setColor('PURPLE')
message.channel.send(embed)
})
}
})
A quick solution to your problem is this:
const prefix=";";
client.on('message', async message => {
if (message.author.bot) return;
if (!message.content.toLowerCase().startsWith(prefix)) return;
const args=message.content.slice(prefix.length).trim().split(/ +/g);
const command = args.shift().toLowerCase();
if (command==="stats") {
cpuStat.usagePercent(function (error, percent) {
if (error) {
return console.error(error)
}
//rest of the code...
But I suggest you to learn about command-handling, your codebase will look much better when you seperate commands into seperate files. There are a lot of youtube tutorials about it.
So I have been trying to figure this out for a while now and I can't figure it out can someone tell me what I'm doing wrong. Btw in new to this and every other command works
const Discord = require("discord.js");
const bot = new Discord.Client();
const prefix = "!";
const token = "token";
const randomMessage = ["Yes this is a bruh moment", "No this is not a bruh moment stop overreacting"];
bot.on("ready", () =>{
console.log(`${bot.user.username} online`);
});
bot.on("message", msg => {
if (msg.content === "is this a bruh moment?") {
var response = randomMessage [Math.floor(Math.random()*randomMessage .length)];
msg.channel.send(response);
}
else if(msg.content === "are you online?"){
msg.reply("I am online and ready to be a bruh");
}});
bot.on("message", msg =>{
if(!msg.content.startsWith(prefix) || msg.author.bot) return;
const args = msg.content.slice(prefix.length).split(/ +/);
const command = args.shift().toLowerCase();
if(command == "ping"){
msg.channel.send("pong!");
}
});
bot.login(token);
There are 2 issues with your code.
You have multiple message events. Every and all commands should execute inside one event. Otherwise this may cause memory leaks along the way.
You incorrectly define an array. Arrays are defined with brackets not paranthesis.
Change
const randomMessage = ("Yes this is a bruh moment", "No this is not a bruh moment stop overreacting")
To
const randomMessage = ["Yes this is a bruh moment", "No this is not a bruh moment stop overreacting"]
I've been trying to create a system that automatically sets the slowmode in a channel to a certain amount depending on how many messages have been sent. Lua is my primary language, and not Node.js, therefore I'm having quite a bit of trouble as to how I would go about this. If anyone had any suggestions, please let me know.
Two ways to go about it:
Use discord.js's <TextChannel>.setRateLimitPerUser(number)
https://discord.js.org/#/docs/main/stable/class/TextChannel?scrollTo=setRateLimitPerUser
Not sure if this actually does what you want though, the other option is creating a session storage of the text channels msgCount and compare it to time, i found setRateLimitPerUser in the middle of writing the code so didn't finish it, be here's a start:
const { Client, Collection } = require("discord.js");
const client = new Client();
client.slowdown = new Collection();
client.on("message", msg => {
const id = msg.channel.id;
const attempt = client.slowdown.get(id);
//4 messages at most per second
const ratio = 4;
//look at last how many seconds
const timeSpace = 5;
//TODO: check if channel already has cooldown
if (attempt) {
attempt.msgCount++;
const currentTime = Date.now();
const timePassed = (currentTime - attempt.time) / 1000;
if (attempt.msgCount >= ratio && attempt.msgCount / timePassed >= ratio) {
//setCoolDown
}
if (timePassed >= timeSpace) {
attempt.time = currentTime;
attempt.msgCount = 0;
}
} else {
client.slowdown.set(id, {
time: Date.now(),
msgCount: 1
});
}
});
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.