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.
Related
I'm in the process of debugging the /purge command for my Discord bot.
My intention is to fetch the entirety of a text channel, and delete any amount of messages, by calling the TextChannel.bulkDelete method multiple times, since that method has a limit of deleting 100 messages at a time. This is my code:
async purgeDelete(
channel: TextChannel,
amount: number | undefined,
target: GuildMember | undefined,
keyword: string | undefined
): Promise<number> {
// Most confused about this line: Am I doing the right thing?
const messages = await channel.messages.fetch();
const twoWeeksAgo = new Date();
twoWeeksAgo.setDate(twoWeeksAgo.getDate() - 14);
const purgelist = messages.filter(message => (
(!target || message.author.id === target.id)
&& (!keyword || message.content.includes(keyword))
&& this.resultMessage?.id !== message.id
&& message.createdAt > twoWeeksAgo
));
let purgeAmount: number;
if (amount === undefined) {
purgeAmount = purgelist.size;
} else {
console.log(purgelist.size, messages.size);
purgeAmount = Math.min(amount, purgelist.size);
}
const slicedPurgelist = purgelist.first(purgeAmount);
const partitionedPurgelist = [];
for (let i = 0; i < slicedPurgelist.length; i += 100) {
partitionedPurgelist.push(slicedPurgelist.slice(i, i + 100));
}
await Promise.all(partitionedPurgelist.map(messages => channel.bulkDelete(messages)));
return purgeAmount;
}
I'm pretty sure the only line that matters is the fetch() call. When called in my program, the API is giving me 50 messages. Is that intentional? I know there is an option for limit, but that only goes up to 100. If there is any workarounds to this, please let me know!
The Discord API has a hard limit of 100 messages per GET request. Unfortunately, this is a hard limit you can't bypass, and is intentional on Discord's part.
Furthermore, fetching the entirety of a text channel is probably a bad idea, especially with larger servers which could have 100k+ messages per channel.
A "sort-of" workaround is to use the before param in FetchMessageOptions plus a loop to continue fetching messages. See below for an example:
const messages = [];
const messagesToFetch = 1000
while(messages.length < messagesToFetch) {
// Handle first run
if(!messages.length) {
const msg = await channel.messages.fetch({ limit: 100 })
messages.push(msg)
continue;
}
// Fetch messages before the oldest message in the array
messages.push(await channel.messages.fetch({ limit: 100, before: messages[0].id }))
}
I'm quite new to Javascript, normally a Python person. I've looked at some other answers but my embed does not add the fields as expected. The embed itself is sent.
My Discord bot follows the guide provided by the devs (primary file, slash commands, command files). I am trying to loop through the entries in an SQLite query and add them as fields.
My command file is below.
const { SlashCommandBuilder } = require('#discordjs/builders');
const { MessageEmbed } = require('discord.js')
const sqlite = require('sqlite3').verbose();
module.exports = {
data: new SlashCommandBuilder()
.setName('rank')
.setDescription('Rank all points.'),
async execute(interaction) {
const rankEmbed = new MessageEmbed()
.setColor('#0099ff')
.setTitle('Rank Board')
let db = new sqlite.Database('./databases/ranktest.db', sqlite.OPEN_READWRITE);
let queryall = 'SELECT name, points FROM pointstable ORDER BY points DESC'
db.all(queryall, [], (err, rows) => {
if (err) {
console.log('There was an error');
} else {
rows.forEach((row) => {
console.log(row.name, row.points)
rankEmbed.addField('\u200b', `${row.name}: ${row.points}`, true);
});
}
})
return interaction.reply({embeds: [ rankEmbed ] });
}
}
I would also like to convert row.name - held as Discord IDs - to usernames i.e. MYNAME#0001. How do I do this by interaction? I was able to obtain the User ID in another command by using interaction.member.id, but in this case I need to grab them from the guild. In Python I did this with await client.fetch_user but in this case the error await is only valid in async functions and the top level bodies of modules is thrown.
Thanks.
OK I've solved the first aspect, I had the return interaction.reply in the wrong place.
Relevant snippet:
rows.forEach((row) => {
console.log(row.name, row.points)
rankEmbed.addField('\u200b', `${row.name}: ${row.points}`, false);
})
return interaction.reply({embeds: [rankEmbed ]} );
Would still appreciate an answer to the converting row.name (user ID) to user name via fetch.
I've solved the second aspect also. Add the below into the loop.
rows.forEach((row) => {
let client = interaction.client
const uname = client.users.cache.get(row.name);
rankEmbed.addField('\u200b', `${uname}: ${row.points}`, false);
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
My bot is not responding to any commands except for the .purge command.
Here is my code.
const { Client, MessageEmbed } = require('discord.js');
const client = new Client();
const { prefix, token } = require('./config.json');
client.on('ready', () => {
client.user.setStatus('invisible');
console.log('Bot ready!');
client.user.setActivity('Bot is in WIP Do not expect stuff to work', {
type: 'STREAMING',
url: "https://www.twitch.tv/jonkps4"
});
console.log('Changed status!');
});
client.on('message', message => {
if (message.content.startsWith(".") || message.author.bot) return;
const args = message.content.slice(prefix.length).trim().split(/ +/);
const command = args.shift().toLowerCase();
if (message === 'apply') {
message.reply("The Small Developers Application form link is:")
message.reply("https://forms.gle/nb6QwNySjC63wSMUA")
}
if (message === 'kick') {
const user = message.mentions.users.first();
// If we have a user mentioned
if (user) {
// Now we get the member from the user
const member = message.guild.member(user);
// If the member is in the guild
if (member) {
member
.kick('Optional reason that will display in the audit logs')
.then(() => {
// We let the message author know we were able to kick the person
message.reply(`Successfully kicked ${user.tag}`);
})
.catch(err => {
message.reply('I was unable to kick the member \n Maybe due to I having missing permissions or My role is not the higher than the role the person to kick has');
// Log the error
console.error(err);
});
} else {
// The mentioned user isn't in this guild
message.reply("That user isn't in this guild!");
}
// Otherwise, if no user was mentioned
} else {
message.reply("You didn't mention the user to kick!");
}
}
if (command === 'purge') {
const amount = parseInt(args[0]) + 1;
if (isNaN(amount)) {
return message.reply('Not a valid number');
} else if (amount > 100) {
return message.reply('Too many messages to clear. \n In order to clear the whole channel or clear more please either ```1. Right click on the channel and click Clone Channel``` or ```2. Execute this command again but more times and a number less than 100.```');
} else if (amount <= 1) {
return message.reply('Amount of messages to clear **MUST** not be less than 1 or more than 100.')
}
message.channel.bulkDelete(amount, true).catch(err => {
console.error(err);
message.channel.send('**There was an error trying to prune messages in this channel!**');
});
}
});
client.login(token);
I need a specific command to work which is the .apply command
and i would like to know why my embeds do not work.
I tried this embed example It didn't work.
const embed = new MessageEmbed()
// Set the title of the field
.setTitle('A slick little embed')
// Set the color of the embed
.setColor(0xff0000)
// Set the main content of the embed
.setDescription('Hello, this is a slick embed!');
.setThumbnail('https://tr.rbxcdn.com/23e104f6348dd71d597c3246990b9d84/420/420/Decal/Png')
// Send the embed to the same channel as the message
message.channel.send(embed);
What did I do wrong? I am quite new to Discord.JS Any help would be needed.
You used the message parameter instead of command. Instead of message === 'xxx' put command === 'xxx'. Simple mistake, I think that was what you meant anyways. Of course the purge command worked because you put command === 'purge' there
I am trying to make a sort of trivia bot but the problem is that I can't get it working. I have it so that when you type "-quiz" it sends a embed with a random question. Now you might say that I need to make a separate JSON file and put the questions and answers there, the problem is, is that I need variables in those strings and when I tried it, it wouldn't work because the order or something like that. I tried to fix that but it seems like a bad solution anyway. I set it up so it looks for a message after the initial commands, problem is that it reads it's own embed and I honestly don't know how to make it skip bot messages
client.on('message', message =>{
if(!message.content.startsWith(prefix) || message.author.bot) return;
const args = message.content.slice(prefix.length).split(/ +/);
const command = args.shift().toLowerCase();
if(command === 'quiz'){
var TypeID = (Math.floor(Math.random() * 11))
var toLog = (Math.floor(Math.random() * 2))
{ //there is something here that is used for the variables above but it is super long
}
var question = [`Question one`, `Question two`]
var answers = [[Answer1_1, Answer1_2],[Answer1_1]]
if(toLog === 0){
const quizEmbed1 = new Discord.MessageEmbed()
.setColor('#0099ff')
.setTitle('quiz')
.setDescription(`${question[0]}`)
message.channel.send(quizEmbed1)
if(!message.content || message.author.bot) return;
if(message.content === [answers[0], answers[1], answers[2], answers[3], answers[4], answers[5]]){
message.channel.send('Good Job! That is right!')
}else{
message.channel.send('Oops! that is wrong.')
}
}else if(toLog == 1){
const quizEmbed2 = new Discord.MessageEmbed()
.setColor('#0099ff')
.setTitle('quiz')
.setDescription(`${question[1]}`)
message.channel.send(quizEmbed2)
if(!message.content || message.author.bot) return;
if(message.content === [answers[6]]){
message.channel.send('Good Job! That is right!')
}else{
message.channel.send('Oops! That is wrong.')
}
}
}
});
if something it wrong it is most likely because I changed it to make it smaller, I am fairly newer to coding in JavaScript
Try using a MessageCollector. There is a good guide on the discord.js guide
Or using awaitMessages. Again there is a guide on the discord.js guide
Here is the example using awaitMessages
const filter = response => {
return item.answers.some(answer => answer.toLowerCase() === response.content.toLowerCase());
};
message.channel.send(item.question).then(() => {
message.channel.awaitMessages(filter, { max: 1, time: 30000, errors: ['time'] })
.then(collected => {
message.channel.send(`${collected.first().author} got the correct answer!`);
})
.catch(collected => {
message.channel.send('Looks like nobody got the answer this time.');
});
});