If the intention here is to temporarily timeout the command's use to prevent multiple outputs from being generated together, then the below approach is a possible solution.
You can define a variable with the amount of seconds you want to "timeout"(COMMAND_TIMEOUT), the command and/or it's output, and then compare the creation time of the current and previous messages to check whether the time passed is greater than or equal to the COMMAND_TIMEOUT.
To find the previous message of the channel we get the history of the channel(limit = 1 and before the creation time of the current message), using the discord.TextChannel.history() method, and .flatten() it as a list then fetch the zeroth(0th) index of it as the previous message before the current message that triggered the command.
NOTE: For the correct code look at the edit section, the code below has certain errors, but for understanding sake, this section is still intact.
Like so -:
COMMAND_TIMEOUT = 5 # Number of seconds as timeout to ignore any extra calls to the same command.
prev_message = await channel.history(limit = 1, before = m.created_at).flatten()[0]
return m.content == 'hello' and m.channel == channel and (m.channel.created_at - prev_message.created_at).total_seconds() >= COMMAND_TIMEOUT
The full code then becomes -:
@client.event
async def on_message(message):
if message.author == client.user:
return
if message.content.startswith('!newuser'):
message.author == username
channel = message.channel
await channel.send('Hello!')
def check(m):
COMMAND_TIMEOUT = 5 # Number of seconds as timeout to ignore any extra calls to the same command.
prev_message = await channel.history(limit = 1, before = m.created_at).flatten()[0]
return m.content == 'hello' and m.channel == channel and (m.channel.created_at - prev_message.created_at).total_seconds() >= COMMAND_TIMEOUT
msg = await client.wait_for('message', check=check)
await channel.send('Hello {.author}!'.format(msg))
NOTE:
EDIT: As mentioned by @Chuaat, my previously shown approach was not fully correct, as the history function is an async function and cannot be called within check as it is a sync function.
The fix to this can be to simply replace, the call of the history function from inside to outside the check function. This can be done using a lambda statement, the changes will be as follows -:
CHANGES TO THE CHECK FUNCTION:
Remove the call of the history function from within, and rather add an extra argument in the check function for the prev_messagelike so -:
def check(m, prev_message) :
COMMAND_TIMEOUT = 5 # Number of seconds as timeout to ignore any extra calls to the same command.
return m.content == 'hello' and m.channel == channel and (m.channel.created_at - prev_message.created_at).total_seconds() >= COMMAND_TIMEOUT
CHANGES TO THE WAIT_FOR FUNCTION'S PASSED ARGUMENTS: Now the check function passed to the wait_for function has to be modified to a lambda statement like so -:
msg = await client.wait_for('message', check = lambda m : check(m, await channel.history(limit = 1, before = m.created_at).flatten()[0]))
The corrected full code now becomes -:
@client.event
async def on_message(message):
if message.author == client.user:
return
if message.content.startswith('!newuser'):
message.author == username
channel = message.channel
await channel.send('Hello!')
def check(m, prev_message) :
COMMAND_TIMEOUT = 5 # Number of seconds as timeout to ignore any extra calls to the same command.
return m.content == 'hello' and m.channel == channel and (m.channel.created_at - prev_message.created_at).total_seconds() >= COMMAND_TIMEOUT
msg = await client.wait_for('message', check = lambda m : check(m, await channel.history(limit = 1, before = m.created_at).flatten()[0]))
await channel.send('Hello {.author}!'.format(msg))