#my_group.child
#lightbulb.command('five', '5 minute countdown')
#lightbulb.implements(lightbulb.SlashSubCommand)
async def subcommand(ctx):
await ctx.respond("Timer for 5 minute⌛ start!")
await ctx.respond("https://upload.wikimedia.org/wikipedia/commons/7/7a/Alarm_Clock_GIF_Animation_High_Res.gif")
for i in range(5*60):
time.sleep(1) #5 min
if i % 60 == 0 and i != 0:
await ctx.respond(str(int(i/60)) + " minute⌛ has passed!")
await ctx.respond("Timer ended!")
#my_group.child
#lightbulb.command('ten', '10 minute countdown')
#lightbulb.implements(lightbulb.SlashSubCommand)
async def subcommand(ctx):
await ctx.respond("Timer for 10 minute⌛ start!")
await ctx.respond("https://upload.wikimedia.org/wikipedia/commons/7/7a/Alarm_Clock_GIF_Animation_High_Res.gif")
for i in range(10*60):
time.sleep(1) #10 min
if i % 60 == 0 and i != 0:
await ctx.respond(str(int(i/60)) + " minute⌛ has passed!")
await ctx.respond("Timer ended!")
#my_group.child
#lightbulb.command('thirty', '30 minute countdown')
#lightbulb.implements(lightbulb.SlashSubCommand)
async def subcommand(ctx):
await ctx.respond("Timer for 30 minute⌛ start!")
await ctx.respond("https://upload.wikimedia.org/wikipedia/commons/7/7a/Alarm_Clock_GIF_Animation_High_Res.gif")
for i in range(30*60):
time.sleep(1) #30 min
if i % 300 == 0 and i != 0:
await ctx.respond(str(int(i/300)) + " minute⌛ has passed!")
await ctx.respond("Timer ended!")
When run, the timer will start however every other script is unable to run due to it being stuck in the for loop while the timer is still going. Is there an alternate way of making a timer that won't stop other scripts from running?
The issue here is probably that your threads while sleeping, are not releasing the resources for the other threads.
It should work once you change the time.sleep(1) to await asyncio.sleep(1)
You can find more information here and here.
What I'm doing: I'm trying to make a typeracer in discord.py, but first I'm trying to wrap my head around using def check and def inner_check.
Problem: As seen in the image below, when I type the correct sentence it still tells me that I'm wrong. There is no error as far as I have checked. I used the code from this link here, which helped with the author input in case that helps.
Code:
#client.command()
async def tr(ctx):
starttime = time.time()
C = "Just a nice little test"
await ctx.send(f"Type: {C}")
a = 1
def check(author):
def inner_check(message):
return message.author == author and message.content == C
return inner_check
while a == 1:
msg = await client.wait_for('message', check=check(ctx.author))
if msg == True:
a = a - 1
else:
await ctx.send("wrong")
fintime = time.time()
total = fintime - starttime
await ctx.send(round(total,2),"seconds")
Based off of Doyousketch2's answer, I've written the other way to do it with the #client.command since it required a bit more tweaking. I've included the time taken (rounded to the nearest whole second) as well.
What was changed:
Used #client.command rather than `if message.content == '!type'
message.channel.send is now ctx.send here
message.author was changed to ctx.author, since message would give an error of name 'message' is not defined
#client.command()
async def type(ctx):
starttime = time.time()
answer = 'Just a nice little test'
timer = 17.0
await ctx.send(f"You have {timer} seconds to type: {answer}")
def is_correct(msg):
return msg.author==ctx.author
try:
guess = await client.wait_for('message', check=is_correct, timeout=timer)
except asyncio.TimeoutError:
return await ctx.send("You took too long :(")
if guess.content == answer:
await ctx.send("You got it!")
fintime = time.time()
total = fintime - starttime
await ctx.send(f"{round(total)} seconds")
else:
await ctx.send("Nope, that wasn't really right")
fintime = time.time()
total = fintime - starttime
await ctx.send(f"{round(total)} seconds")
Basically their Github example, just tweaked a bit.
#! /usr/bin/env python3
import discord
import random
import asyncio
token = 'bot_token'
class MyClient(discord.Client):
async def on_ready(self):
print('Logged in as: ', self.user.name, self.user.id)
print('--------------------------------------------------')
async def on_message(self, message):
## no need for bot to reply to itself
if message.author.id == self.user.id:
return
if message.content == '!type': ## begin typeracer game with "!type" command
answer = 'Just a nice little test'
timer = 5.0
await message.channel.send(f'You have {timer} seconds to type: {answer}')
def is_correct(msg):
return msg.author == message.author
try:
guess = await self.wait_for('message', check=is_correct, timeout=timer)
except asyncio.TimeoutError:
return await message.channel.send('Sorry, you took too long.')
if guess.content == answer:
await message.channel.send('Right on!')
else:
await message.channel.send('Oops.')
client = MyClient()
client.run(token)
I've tried this and i didn't really get the logic through it, I need some help making it have:
🎉 Emoji
Message
Setting the time
My Code:
#bot.command()
async def giveaway(ctx, msg, duration):
embed=discord.Embed()
embed.title=msg
embed.description="React To Giveaway With 🎉 To Join."
embed.set_footer(text="👑 MTND Bot Development")
embed.color=0x00ffff
msg = await ctx.send(embed=embed)
await msg.add_reaction('🎉')
Please help if you could.
Here is one.
def convert(time):
pos = ["s","m","h","d"]
time_dict = {"s" : 1, "m" : 60, "h" : 3600, "d": 3600*24}
unit = time[-1]
if unit not in pos:
return -1
try:
val = int(time[:-1])
except:
return -2
return val * time_dict[unit]
#client.command()
#commands.has_permissions(kick_members=True)
async def giveaway(ctx):
await ctx.send("Let's start with this giveaway! Answer these questions within 15 seconds!")
questions = ["Which channel should it be hosted in?", "What should be the duration of the giveaway? (s|m|h|d)", "What is the prize of the giveaway?"]
answers = []
def check(m):
return m.author == ctx.author and m.channel == ctx.channel
for i in questions:
await ctx.send(i)
try:
msg = await client.wait_for('messsage', timeout=15.0, check=check)
except asyncio.TimeoutError:
await ctx.send('You didn\'t answer in time, please be quicker next time!')
return
else:
answers.append(msg.content)
try:
c_id = int(answers[0][2:-1])
except:
await ctx.send(f"You didn't mention a channel properly. Do it like this {ctx.channel.mention} next time.")
return
channel = client.get_channel(c_id)
time = convert(answers[1])
if time == -1:
await ctx.send(f"You didn't answer with a proper unit. Use (s|m|h|d) next time!")
return
elif time == -2:
await ctx.send(f"The time just be an integer. Please enter an integer next time.")
return
prize = answers[2]
await ctx.send(f"The giveaway will be in {channel.mention} and will last {answers[1]} seconds!")
embed = discord.embed(title = "Giveaway!", description = f"{prize}", color = ctx.author.color)
embed.add_field(name = "Hosted by:", value = ctx.author.mention)
embed.set_footer(text = f"Ends {answers[1]} from now!")
my_msg = await channel.send(embed = embed)
await my_msg.add_reaction("🎉")
await asyncio.sleep(time)
new_msg = await channel.fetch_message(my_msg.id)
users = await new_msg.reactions[0].users().flatten()
users.pop(users.index(client.user))
winner = random.choice(users)
await channel.send(f"Congratulations! {winner.mention} won the prize: {prize}!")
#client.command()
#commands.has_permissions(kick_members=True)
async def reroll(ctx, channel : discord.TextChannel, id_ : int):
try:
new_msg = await channel.fetch_message(id_)
except:
await ctx.send("The ID that was entered was incorrect, make sure you have entered the correct giveaway message ID.")
users = await new_msg.reactions[0].users().flatten()
users.pop(users.index(client.user))
winner = random.choice(users)
await channel.send(f"Congratulations the new winner is: {winner.mention} for the giveaway rerolled!")
This is my whole code for my gcreate command
This is a command with embeds and steps
#client.command()
#commands.has_role("Giveaways")
async def gcreate(ctx):
await ctx.send("Let's start with this giveaway!\n`Answer these questions within 15 seconds!`")
questions = ["**Which channel should it be hosted in?**",
"**What should be the duration of the giveaway?** `(s|m|h|d)`",
"**What is the prize of the giveaway?**"]
answers = []
def check(m):
return m.author == ctx.author and m.channel == ctx.channel
for i in questions:
await ctx.send(i)
try:
msg = await client.wait_for('message', timeout=15.0, check=check)
except asyncio.TimeoutError:
await ctx.send('You didn\'t answer in time, please be quicker next time!')
return
else:
answers.append(msg.content)
try:
c_id = int(answers[0][2:-1])
except:
await ctx.send(f"You didn't mention a channel properly. **Do it like this {ctx.channel.mention} next time.**")
return
channel = client.get_channel(c_id)
time = convert(answers[1])
if time == -1:
await ctx.send("You didn't answer the time with a proper unit. Use `(s|m|h|d)` next time!")
return
elif time == -2:
await ctx.send("The time must be a number. Please enter a number next time")
return
elif time < 10:
await ctx.send("Time Cannot Be Less Than 10s!!")
return
prize = answers[2]
await ctx.send(f"The Giveaway will be in {channel.mention} and will last {answers[1]}!")
embed = discord.Embed(title = "Giveaway!", description = "React To 🎉 To Enter The **Giveaway**!", color = discord.Color.blue())
embed.add_field(name=":gift: Prize:-", value=f"{prize}", inline=False)
embed.add_field(name=":timer: Ends In:-", value=f"{answers[1]}", inline=False)
embed.set_thumbnail(url=ctx.guild.icon_url)
embed.set_footer(text=f"Hosted By {ctx.author.name}", icon_url=ctx.author.avatar_url)
my_msg = await channel.send(embed = embed)
await my_msg.add_reaction("🎉")
await asyncio.sleep(time)
new_msg = await channel.fetch_message(my_msg.id)
users = await new_msg.reactions[0].users().flatten()
users.pop(users.index(self.client.user))
users.pop(users.index(ctx.author))
if len(users) == 0:
await channel.send("No Winner Was Decided!")
return
winner = random.choice(users)
embed2 = discord.Embed(title = "Giveaway!", description ="**Giveaway Has Ended**!", color = discord.Color.blue())
embed2.add_field(name=":gift: Prize:-", value=f"{prize}", inline=False)
embed2.add_field(name=":trophy: Winner:-", value=f"{winner.mention}", inline=False)
embed2.set_thumbnail(url=ctx.guild.icon_url)
embed2.set_footer(text=f"Hosted By {ctx.author.name}", icon_url=ctx.author.avatar_url)
await my_msg.edit(embed=embed2)
await channel.send(f"Congratulations! {winner.mention} Won The Prize:-`{prize}`!\nhttps://discord.com/channels/{channel.guild.id}/{channel.id}/{my_msg.id}")
def convert(time):
pos = ["s", "m", "h", "d"]
time_dict = {"s" : 1, "m" : 60, "h" : 3600, "d" : 3600*24}
unit = time[-1]
if unit not in pos:
return -1
try:
val = int(time[:-1])
except:
return -2
return val * time_dict[unit]#client.command()
#commands.has_role("Giveaways")
async def gcreate(ctx):
await ctx.send("Let's start with this giveaway!\n`Answer these questions within 15 seconds!`")
questions = ["**Which channel should it be hosted in?**",
"**What should be the duration of the giveaway?** `(s|m|h|d)`",
"**What is the prize of the giveaway?**"]
answers = []
def check(m):
return m.author == ctx.author and m.channel == ctx.channel
for i in questions:
await ctx.send(i)
try:
msg = await client.wait_for('message', timeout=15.0, check=check)
except asyncio.TimeoutError:
await ctx.send('You didn\'t answer in time, please be quicker next time!')
return
else:
answers.append(msg.content)
try:
c_id = int(answers[0][2:-1])
except:
await ctx.send(f"You didn't mention a channel properly. **Do it like this {ctx.channel.mention} next time.**")
return
channel = client.get_channel(c_id)
time = convert(answers[1])
if time == -1:
await ctx.send("You didn't answer the time with a proper unit. Use `(s|m|h|d)` next time!")
return
elif time == -2:
await ctx.send("The time must be a number. Please enter a number next time")
return
elif time < 10:
await ctx.send("Time Cannot Be Less Than 10s!!")
return
prize = answers[2]
await ctx.send(f"The Giveaway will be in {channel.mention} and will last {answers[1]}!")
embed = discord.Embed(title = "Giveaway!", description = "React To 🎉 To Enter The **Giveaway**!", color = discord.Color.blue())
embed.add_field(name=":gift: Prize:-", value=f"{prize}", inline=False)
embed.add_field(name=":timer: Ends In:-", value=f"{answers[1]}", inline=False)
embed.set_thumbnail(url=ctx.guild.icon_url)
embed.set_footer(text=f"Hosted By {ctx.author.name}", icon_url=ctx.author.avatar_url)
my_msg = await channel.send(embed = embed)
await my_msg.add_reaction("🎉")
await asyncio.sleep(time)
new_msg = await channel.fetch_message(my_msg.id)
users = await new_msg.reactions[0].users().flatten()
users.pop(users.index(self.client.user))
users.pop(users.index(ctx.author))
if len(users) == 0:
await channel.send("No Winner Was Decided!")
return
winner = random.choice(users)
embed2 = discord.Embed(title = "Giveaway!", description ="**Giveaway Has Ended**!", color = discord.Color.blue())
embed2.add_field(name=":gift: Prize:-", value=f"{prize}", inline=False)
embed2.add_field(name=":trophy: Winner:-", value=f"{winner.mention}", inline=False)
embed2.set_thumbnail(url=ctx.guild.icon_url)
embed2.set_footer(text=f"Hosted By {ctx.author.name}", icon_url=ctx.author.avatar_url)
await my_msg.edit(embed=embed2)
await channel.send(f"Congratulations! {winner.mention} Won The Prize:-`{prize}`!\nhttps://discord.com/channels/{channel.guild.id}/{channel.id}/{my_msg.id}")
def convert(time):
pos = ["s", "m", "h", "d"]
time_dict = {"s" : 1, "m" : 60, "h" : 3600, "d" : 3600*24}
unit = time[-1]
if unit not in pos:
return -1
try:
val = int(time[:-1])
except:
return -2
return val * time_dict[unit]**strong text**
```
In order to make an giveaway command you need first of all, on going giveaways variables:
cmdsettings = {}
allowedRiggers = config.riggers
ongoingGiveaways = {}
like that then embed:
actualTitle = 'Giveaway: ' + str(msg)
embed = discord.Embed(color=0x0040ff,title=actualTitle)
info = "React with 🎉 on this message to enter"
embed.add_field(name='Message from creator', value=message, inline=False)
embed.add_field(name='How to enter', value=info, inline=False)
embed.add_field(name='Giveaway end date', value=endDate, inline=False)
that end date can be anything, but I am not going to show how to do it since i assume you know python. and them use those vars what i sent before, also this code is based on https://github.com/AnimeHasFallen/discordbot-giveaway/ so view the full source code there.
key39
I am trying to make an alarm discord bot using python. No errors are happening, but also no output from the bot past the try, except function
Please note: alarm, not timer
#client.command(aliases = ["alarm"])
async def alarm_at(ctx, time):
alarm = False
if alarm == False:
alarm = True
now = datetime.now()
mtimeA = time
mtimeB = mtimeA.split(":")
hr = int(mtimeB[0])
min = int(mtimeB[1])
secsleft = int((timedelta(hours=24) - (now - now.replace(hour=hr, minute=min, second=0, microsecond=0))).total_seconds() % (24 * 3600))
print(secsleft)
await ctx.send(f"OK\Alarm go off at {time}")
def check(message):
return message.author == ctx.author and message.content.lower() == "cancel alarm"
try:
await client.wait_for("message", check=check, timeout=time)
await ctx.send("alarm cancelled")
except:
if secsleft == 0:
await ctx.send(f"{ctx.guild.default_role} alarm finished")
elif alarm == True:
await ctx.send("Please cancel the current alarm to run a new alarm")
If the error is happening in the try ... except, you won't see anything. Try this instead:
try:
await client.wait_for("message", check=check, timeout=time)
await ctx.send("alarm cancelled")
except Exception as e:
print(f"Error: {e}")
if secsleft == 0:
await ctx.send(f"{ctx.guild.default_role} alarm finished")
I'm trying to make a trivia bot and it has a command that makes it countdown from 30-1 in seconds. When it hits 1 I don't know how to make say something in the discord chat.
I've already tried looking through the API.
questionTimer = 30
#while questionTimer > 1:
#questionTimer = questionTimer - 1
#time.sleep(1)
#print (questionTimer)
I'm hoping that it can say Times up in the chat when questionTimer = 1
If you want it to print out every number you can do something like
#client.command()
async def quiz():
seconds = 30
while seconds > 0:
await client.say(seconds)
await asyncio.sleep(1)
seconds-=1
await client.say("Done")
But if you just want to make it wait 30 seconds and then display a message you can do something like
#client.command()
async def quiz():
await asyncio.sleep(30)
await client.say("Done")
Depending if you are using the rewrite or the old async version of discord.py I would recommend the following :
Discord.py async (0.16.x) :
#client.event
async def on_message(self, message):
if message.content.startswith('!quiz'):
quizMsg = 'Question of the quiz'
msg = await client.say(f"{quizMsg}\n\n{secs}s left !")
secs = 30
while secs > 0:
await asyncio.sleep(1)
await client.edit_message(msg, f"{quizMsg}\n\n{secs}s left !")
secs--
await client.say("Time is up ! The answer was...")
Discord.py rewrite (1.0.x) :
#commands.command(name="quiz", aliases=["q"])
async def quiz():
quizMsg = 'Question of the quiz'
msg = await ctx.send(f"{quizMsg}\n\n{secs}s left !")
secs = 30
while secs > 0:
await asyncio.sleep(1)
await msg.edit(content = f"{quizMsg}\n\n{secs}s left !")
secs--
await ctx.send("Time is up ! The answer was...")
Mind the difference between the two methods