API reference
Waiting
Pause a command until someone sends a message, reacts, clicks or submits a form.
wait_for lets a command ask a question and wait for the answer, all in one run.
Write await in front of wait_for.
Tip
For buttons and menus, use a View instead. It handles clicks for you and is shorter.
wait_for#
Waits for the next event that passes your check. Returns the event.
await wait_for(
event_name,
timeout=None,
check=None,
reset_timeout_on_check_fail=False,
raise_error=False,
)| Argument | What it does |
|---|---|
event_name | What to wait for. See the list below. |
timeout | Seconds to wait. None waits with no end. |
check | A function that gets each event and returns True for the one you want. predicate is another name for it. |
reset_timeout_on_check_fail | True starts the timer again after each event that fails the check. |
raise_error | True stops with an error on timeout. Otherwise you get None. |
event_name | Waits for |
|---|---|
"message" | A new message |
"message_delete" | A deleted message |
"reaction" | Any reaction added or removed |
"reaction_add" | A reaction added |
"reaction_remove" | A reaction removed |
"interaction" | Any click, menu pick or form submit |
"modal_submit" | A form (modal) submitted |
"clock" | A clock you dispatched |
Always add a check
wait_for hears events from every server the bot is in. Always check the channel and the person. Always set a timeout, so the command does not wait forever.
Example: a guessing game
# pre-hook
secret = randomNumber(1, 10)
set_content("I picked a number from 1 to 10. Guess it in the chat!")# post-hook
def same_person(evt):
return evt.channel_id == channel.id and evt.author_id == user.id
evt = await wait_for("message", timeout=30, check=same_person)
if evt is None:
send_message(channel, "Time is up!")
elif evt.content.strip() == str(secret):
send_message(channel, f"Yes! It was {secret}.")
else:
send_message(channel, f"No, it was {secret}.")The question is in the reply, so the wait goes in the post-hook. The post-hook runs after the reply is sent. See How commands run.
What you get back#
You get an event, not the message itself. The message ID is evt.message_id. There is no evt.id.
event_name | Attributes on the event |
|---|---|
"message" | content, author, author_id, member, message, message_id, channel_id, guild_id, embeds, is_bot, is_human, is_webhook |
"message_delete" | message_id, old_message, channel_id, guild_id |
"reaction_add", "reaction_remove" | emoji_name, emoji_id, user_id, member, message_id, channel_id, guild_id, is_animated |
evt = await wait_for("message", timeout=60, check=same_person)
if evt is not None:
delete_message(evt.channel_id, evt.message_id) # not evt.idExample: wait for a reaction
msg = send_message(channel, "React with ✅ to confirm.")
add_reactions(msg, "✅")
def confirmed(evt):
return evt.message_id == msg.id and evt.user_id == user.id and evt.emoji_name == "✅"
evt = await wait_for("reaction_add", timeout=60, check=confirmed)dispatch#
Fires a clock event right now, in this server. Your Clock event, or a wait_for("clock"), picks it up.
dispatch(event)event must be a ClockEvent(custom_id, metadata, server). Anything else fails with "This event can't be dispatched".
dispatch(ClockEvent("refresh_board", {"by": user.id}, server))To fire a clock later instead, use schedule_clock. See Scheduling.
Event classes#
You can pass these instead of a name, or check for them in your function:
MessageCreateEvent, MessageDeleteEvent, ReactionEvent, ReactionAddEvent, ReactionRemoveEvent, ComponentInteraction, ModalInteraction.