how to trigger a command from another file - discord

I am trying to create a music bot, but i have an issue with the loop command, I want to trigger loop.js when the user clicks on a certain react emoji on the playing menu, for now, the command runs independently in both play.js and loop.js. The reason I want to do this is because in case a user selects the reaction and then does the command itself, the bot would say the opposite if it was either on or off.
Here is my loop.js
module.exports = {
name: "loop",
aliases: ['l'],
description: "Toggle music loop",
execute(message) {
const queue = message.client.queue.get(message.guild.id);
if (!queue) return message.reply("There is nothing playing.").catch(console.error);
if (!canModifyQueue(message.member)) return;
let loopembed = new MessageEmbed()
.setTitle("Loop settings")
.setDescription(`Loop is now ${queue.loop ? "**on**" : "**off**"}`)
.setColor(message.guild.me.displayColor)
.setFooter(`Action performed by ${message.author.tag}`)
// toggle from false to true and reverse
queue.loop = !queue.loop;
return queue.textChannel
.send(loopembed)
.catch(console.error);
}
};
And here is my loop reaction command from play.js
case "🔁":
reaction.users.remove(user).catch(console.error);
if (!canModifyQueue(member)) return;
queue.loop = !queue.loop;
queue.textChannel.send(`Loop is now ${queue.loop ? "**on**" : "**off**"}`).catch(console.error);
break;
I'm trying to make loop.js run instead of it being run independently in case of the reacted emoji.
Thank you for helping in advance

Related

How to prevent discord bot to send message automatically?

My discord bot is sending a message automatically everyday at 4am . I don't know why . Here is the code :
let embed = new Discord.MessageEmbed()
.setTitle("Hello")
.setColor(0x36393f)
.setDescription(
`\`\`\`${table(membersLimited, {
border: getBorderCharacters(`void`),
})}\`\`\``
)
.setTimestamp();
guild.channels.cache
.get(guildData.config.channels.announcements)
.send(embed);
I can't figure out why my bot send this message every day automatically to ALL the server where it is invited in.
Any idea ?
This thread is useful, after you define the cronjon, simply do <cron name>.stop();
var cron = require('cron').CronJob;
var j = cron.scheduleJob(unique_name, '*/1 * * * * *',()=>{
//Do some work
});
// for some condition in some code
let my_job = cron.scheduledJobs[unique_name];
my_job.stop();

(discord.js) How to set a time limit on a command?

I am trying to make a Judge bot for my server that will give the person who used the command the role "Plaintiff", and give the person that they mentioned the "Defendant" role. Everything works perfectly as intended except the fact that multiple trials can be started at the same time. Like if someone uses the command and it makes them the plaintiff and a 2nd person the defendant, if a 3rd person uses the command on a 4th person they will become a defendant and plaintiff as well. I want to make it so that while the events of the command are playing out that nobody else in the server can use the command until the 1st trial ends. I have tried to give the entire server the role "jury" and make it so that if anyone has the role "jury" they can't use the command but i couldn't ever get that to work. Also I tried to set a time limit for the command and that didn't work at all either. I have no clue how to get this working and any advice is appreciated!! Thanks!!!
client.on("message", message => {
const args = message.content.slice(prefix.length).trim().split(/ +/g);
const command = args.shift().toLowerCase();
if (command === "sue") {
let member1 = message.mentions.members.first();
message.member.roles.add("797738368737345536")
member1.roles.add("797738235715256331");
message.guild.members.cache.forEach(member => member.roles.add("797743010346565672"))
message.channel.send("Court is now in session.")
client.channels.cache.find(channel => channel.name === 'courtroom').send( + " **All rise.**");
client.channels.cache.find(channel => channel.name === 'courtroom').send("Plaintiff, you have 2 minutes to state your case.");
setTimeout(function(){
client.channels.cache.find(channel => channel.name === 'courtroom').send("Thank you Plaintiff. Defendant, you now have 2 minutes to defend yourself.");
}, 120000);
setTimeout(function(){
client.channels.cache.find(channel => channel.name === 'courtroom').send("Thank you. The court may be seated as we turn to the jury for their verdict.");
}, 240000);
const Responses = [
"The Jury hereby finds you.... **GUILTY!** You will be sentanced to 10 minutes in jail.",
"The Jury hereby finds you.... **NOT GUILTY!** You are free to go. The Jury is dismissed."
];
const Response = Responses[Math.floor(Math.random() * Responses.length)];
setTimeout(function(){
client.channels.cache.find(channel => channel.name === 'courtroom').send(Response)
if (Response === "The Jury hereby finds you.... **NOT GUILTY!** You are free to go. The Jury is dismissed." ) {
message.member.roles.remove("797738368737345536")
member1.roles.remove("797738235715256331");
message.guild.members.cache.forEach(member => member.roles.remove("797743010346565672"))
}
if (Response === "The Jury hereby finds you.... **GUILTY!** You will be sentanced to 10 minutes in jail.") {
message.member.roles.remove("797738368737345536")
member1.roles.add("797738617338069002")
member1.roles.remove("797738235715256331");
message.guild.members.cache.forEach(member => member.roles.remove("797743010346565672"))
}
}, 250000);
setTimeout(function(){
member1.roles.remove("797738617338069002");
}, 850000);
}
});
You could create a file, so nobody is able to use the command while the file exists.
const fs = require("fs");
if (command_gets_executed) { // If the command gets executed
if (fs.existsSync("./commandAlreadyUsed")) { // Checking if the file exists
// YOUR CODE - When the command should not be usable
} else {
fs.writeFileSync("./commandAlreadyUsed"); // Creating the file
// YOUR CODE - When nobody else used the command before
}
}
And if you want the command usable again just use fs.unlinkSync("./commandAlreadyUsed").
You can try to use a CronJob to set a time limit, I used it before for a similar case, may be it can be useful for you

Get Discord user current game AND custom status?

Currently, using Discord.js, member.user.presence.game.name will return the game name IF said user doesn't have a custom status set, but if they do, this returns "Custom Status". Not their actual status, or their game name, just... "Custom status". I'd like to be able to return the game name and custom status both independently if they are set. Currently my code looks like:
const embed = new RichEmbed()
let statusField
if (member.user.presence.status)
statusField = statusField + `\n**► Status:** ${member.user.presence.status}`
if (member.user.presence.game.name)
statusField = statusField + `\n**► ${gameTypeToString(member.user.presence.game.type)}:** ${member.user.presence.game.name}`
embed.addField("User Status", statusField)
message.channel.send(embed);
Notes:
As a side note for context, my embed is bigger and has more
information in it, I'm just only showing the relevant pieces.
I'm aware that member.user.presence.status is the online/idle/dnd/offline status, I am also displaying that in the embed, but along with the custom status and/or current game.
gameTypeToString is a simple function that looks like this:
gameTypeToString: function(gameType) {
switch (gameType) {
case 0:
return "Playing"
case 1:
return "Streaming"
case 2:
return "Listening to"
case 3:
return "Watching"
default:
return "Doing"
}
}

Best way to get arguments from string by user for chat bot

I need to accept 2 arguments: first is time argument for example "1m", "2h 42m", "1d 23h 3s", second is text. I thought I can just convert input string to array and split it into 2 array using regex maybe, first with "d", "h", "m" and "s", second everything else and convert in back to string. but then I realize I'll need 3rd argument which gonna be optional target channel (dm or current channel, where command been executed), and also what if user want to include 1m in his text (it's reminder command)
The easiest way to do this is to have the user seperate each argument by a comma. Although this creates the issue where the user can't user a comma in their text part. So if that isn't an option, another way to do it is to get the message content and start by stripping parts of it away. You begin by grabbing the time portion with a regex. Then you look for channel mentions and strip those away. What you're left with should solely be the text.
Below is some (non-tested) code which could lead you in the right direction. Give it a try and let me know if you have any problems
let msg = {
content: "1d 3h 45m 52s I feel like 4h would be to long <#222079895583457280>",
mentions: {
channels: ['<#222079895583457280>']
}
};
// Mocked Message object for testing purpose
let messageObject = {
mentions: {
CHANNELS_PATTERN: /<#([0-9]+)>/g
}
}
function handleCommand (message) {
let content = message.content;
let timeParts = content.match(/^(([0-9])+[dhms] )+/g);
let timePart = '';
if (timeParts.length) {
// Get only the first match. We don't care about others
timePart = timeParts[0];
// Removes the time part from the content
content = content.replace(timePart, '');
}
// Get all the (possible) channel mentions
let channels = message.mentions.channels;
let channel = undefined;
// Check if there have been channel mentions
if (channels.length) {
channel = channels[0];
// Remove each channel mention from the message content
let channelMentions = content.match(messageObject.mentions.CHANNELS_PATTERN);
channelMentions.forEach((mention) => {
content = content.replace(mention, '');
})
}
console.log('Timepart:', timePart);
console.log('Channel:', channel, '(Using Discord JS this will return a valid channel to do stuff with)');
console.log('Remaining text:', content);
}
handleCommand(msg);
For the messageObject.mentions.CHANNEL_PATTERN look at this reference

How to create a "TempMute" command?

How to create a TempMute command for discord.js which supports the command handler from An Idiot's Guide.
I understand you need to use .addRole(), but I have no idea how to create it with a timer. The range of the timer needs to be from 60 to 15 minutes.
If you want an action to be executed after some time, you need to use setTimeout(). Here's an example:
// If the command is like: -tempMute <mention> <minutes> [reason]
exports.run = (client, message, [mention, minutes, ...reason]) => {
// You need to parse those arguments, I'll leave that to you.
// This is the role you want to assign to the user
let mutedRole = message.guild.roles.cache.find(role => role.name == "Your role's name");
// This is the member you want to mute
let member = message.mentions.members.first();
// Mute the user
member.roles.add(mutedRole, `Muted by ${message.author.tag} for ${minutes} minutes. Reason: ${reason}`);
// Unmute them after x minutes
setTimeout(() => {
member.roles.remove(mutedRole, `Temporary mute expired.`);
}, minutes * 60000); // time in ms
};
This is just a pseudo-code, you'll need to parse the arguments and get the role.

Resources