I am trying to make a smart questions bot, and I was wondering if there is a way for allowing command B to be executed if command A was executed first
} else if(message.content.match(/Discord/gi)){
const Embed = new Discord.MessageEmbed()
}
This looks for messages that contains Discord (lowercase or uppercase)
I don't want the bot to look for every message that contains Discord.
I was hoping that It would only execute if the preceding command was executed first, and then after that it would also be disabled, sounds complicated but possible
Assuming I understood your intentions correctly, you want to only look for command B after command A is called, and then once command B is executed, you want to stop looking for it. This can be achieved using a message collector that searches for command B. Here is some sample code (works in the latest version):
if (message.content.match("Command A")) {
//Execute your command A code
message.channel.send("Did some command A stuff");
//After command A code is executed, do the following:
var filter = m => m.author.id == message.author.id;
//Creates a message collector, to collect messages sent by the same user
//When max is 1, only 1 message will be collected and then the collector dies
const collector = new Discord.MessageCollector(message.channel, filter, {max: 1});
collector.on("collect", msg => {
//msg is the new message that the user just sent, so check if it contains Discord
if(msg.content.match(/Discord/gi)){
//Do your command B stuff:
const Embed = new Discord.MessageEmbed()
}
});
}
This code checks for Command A, and executes the Command A code. Then it creates a message collector. The message collector will wait until the user that just executed Command A sends another message. Once the user sends another message, it will run the code listening for the collect event. So we take the collected message, in this case msg, and we check if it matches "Discord". From there, you can do your Command B functionality.
Note that immediately after the user sends a message after executing Command A, the collector ends. That means if the user does not enter a message containing "Discord" within 1 attempt, the collector ends and the user must execute Command A once again in order to attempt to execute Command B again. If you want to allow the user to make more attempts to execute Command B, or if you want the user to be able to execute Command B more than once in a row after executing Command A, then you'll need to increase the value of max.
Related
I have a command called "work". This command has 3 parts, list, apply and regular work. When user runs -work list, available jobs are being listed, I don't want any cooldown for this part. -work apply changes the job of the user, and -work just generates random number. So, I want it like when user runs -work apply and change their job, a 1-day cooldown must be applied. And when user just passes -work I want a 1-hour cooldown. I thought of something like different parts of the command would return different strings, such as work_apply and work_work, and use that information to apply different cooldown lengths. But that isn't possible since I can't apply any cooldown without having the output from the command, and to have some output I must run the command. So I can't apply any cooldown without running it.
I dont really know how your command handler works so i will give you an idea.
you can try making a map and pushing the message author and the time they ran the command. once you done this, the next time the same person runs the code under the time limit, set it so that the command handler looks for the member in the map and if they find it, they check when they last ran the command and if its under the time limit, it returns the function
again i dont know how your command handler works but here is how i did it
PS. If your entire command is in 1 file then the code im gonna show wont work. you should try to edit some parts of the code to make it work to ur liking
// command handler file
const cooldowns = new Map();
let name = command.name;
if (!cooldowns.has(name)) {
cooldowns.set(name, new Discord.Collection());
}
if (!message.member.roles.cache.has('ROLE_ID')) { // role that bypass cooldown
const current_time = Date.now();
const time_stamps = cooldowns.get(name);
const cooldown_amount = (command.cooldown) * 1000;
if (time_stamps.has(message.author.id)) {
const expiration_time = time_stamps.get(message.author.id) + cooldown_amount;
if (current_time < expiration_time) {
message.reply({
content: `Please wait until the cooldown has ended`
});
return;
}
}
time_stamps.set(message.author.id, current_time);
setTimeout(() => time_stamps.delete(message.author.id), cooldown_amount);
}
// command file
module.exports = {
name: 'commandname',
cooldown: 15 // this has to be in seconds | you can type '0' if there r no cooldowns
async execute(YOUR PARAMETERS) {
// command code
}
}
Let's say I made an infinite command for my bot, Would there be any way to stop the loop at any time? I want to be able to stop it from the server, not in the actual code.
Example:
if(msg.content === "Just Monika"){
msg.channel.send('Just Monika')
}
})
Is there any way I can type something in chat, and it stops the command? thanks.
Making your bot respond to itself infinitely probably isn't a good idea. But just for learning, it's very possible to do what you wish.
You could make a different phrase (let's call it the stop command) set a boolean variable in your code to true. Then, whenever the looping command gets triggered by a user message or by one of its own, it should check if this boolean telling it to stop is true. If it is, it should set it to false and not send that message, else it should just send that message as per usual.
// The following should be defined in the outmost scope
let loopPhrase = "Just Monika";
let stopPhrase = "Stop Spamming The API";
let triggerStop = false;
// The following should be a part of the message event
if (msg.content === loopPhrase) {
if (!triggerStop) msg.channel.send(loopPhrase);
else triggerStop = false;
} else if (msg.content === stopPhrase) triggerStop = true;
So I created a program that allows you to have a variable that shows how many times a command has been executed, and here is what it looks like:
var timesRunned = 0
if(message.content.startsWith(`${prefix}command`)) {
timesRunned++
let myGuild = client.guilds.cache.get('Guild-ID')
let channel = myGuild.channels.cache.get('Voice-Channel-ID')
channel.setName('Commands Executed: ' + timesRunned)
.catch()
}
But after I run the command more than 3 Times, The voice channel does not even change no matter how many times I run the command, it just stays as "Commands Executed: 2"
Am I doing something wrong? This is in the main app javascript file. The bot itself has enough permissions.
Okay, here's the problem. It seems like you are putting the var timesRunned = 0 in the message event. This means that every time you run a command, this number is reset to 0, which means it forever stays at 1.
If you move the variable to outside the message event, it should work fine.
I will give you another tip, because by just moving it to outside the message event, the variable will clear every time it restarts.
What you can do is get the channel each time the command is run and see how many are on the channel already, then add 1. You would end up with something like this:
var channel = client.channels.cache.get('someID');
var numberExecuted = parseInt(channel.name.split(':').trim());
channel.setName(`Commands Executed: ${numberExecuted + 1}`);
Hope this helps.
I'm writing a discord bot using python to log options trade. What I'm looking to do with my bot is when a user type execute a command, !opentrade, the bot would private message the user with a series of questions. The bot would then capture the answer in a series of variables and use that to process the answer. Is this possible or does it have to be in the channel where the command is called. Additionally, is it by default multithread, meaning 2 or 3 people can call that command at the same time and it would fud up the answer
I have the following thus far and it isn't working:
async def opentrade(ctx):
def check(author):
def inner_check(message):
if message.author != author:
return False
try:
int(message.content)
return True
except ValueError:
return False
return inner_check
try:
await ctx.author.send('Enter the underlying: ')
underlying = await client.wait_for('message', check=check(ctx.author), timeout=30)
print (underlying)
except Exception as err:
await ctx.channel.send("Something went wrong: {}".format(err))
thanks
What I'm looking to do with my bot is when a user type execute a command, !opentrade, the bot would private message the user with a series of questions. The bot would then capture the answer in a series of variables and use that to process the answer. Is this possible or does it have to be in the channel where the command is called.
Possible. You need to put the whole logic into the coroutine that executes the command.
Additionally, is it by default multithread, meaning 2 or 3 people can call that command at the same time and it would fud up the answer
If you implement the checks properly it won't fud the answer. In your code you already implemented the logic that checks for the author so noone else can change it def check(author).
When executing the commands multiple times by different users it will also not fud the answer since the threads are independent.
You should extend this check so it checks for a message in a DM channel. The way your check is written now the caller can DM the bot or respond in a guild text channel.
I'm not sure what's saved in the ctx variable but I'm certain it has a message attribute.
Try await ctx.message.author.send(). If you are running into an error provide the error log.
javascript is still vague to my knowledge, and I cannot be precise on the sensibility in the following code I have manufactured. I am programming a discord bot that categorizes messages into a variety of channels, and the question has approached me to how I can program the bot by deleting follow up bot messages after 2 user messages were sent subsequently after the bot message.
if (bot.on(client, user.msg = '2'));{
msg.channel('message' = msg.delete)
}
Help is to be requested and I hope my query makes sense in the context I am implying, Regards, Coder
P.S: How do I change the bot messages text color as well?
No offense, but your code was completely faulty, so I just made some new code.
bot.on('message', aysnc message => {
var messagenumber = 0; //Makes variable for the number of messages sent
if(message.member.user.username === bot.user.username) return; //If the person who posts a message is the bot, it doesn't the code below.
if(messagenumber = 1) return bulkDelete(100), messagenumber = 0 //Checks if the variable is 1, and if it is, this means it's the second time a message posted, so it deletes messages (Limit is 100) then resets variable.
messagenumber = 1; //Makes variable 1 (This is to make it know it is the the second time a message is posted for the next time).
});
I didn't test this code, so it may not work properly, but if it does work I hope it helps you with your bot.
For the P.S (Changing text color): You can use these (Replace "NoKeyWordsHere" with your message). I don't recommend this, cause it'd take a long time to add it to every message sent. (You can use these on your messages too)