Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I was trying to create a discord bot with giveaway command which updates time left every 1-2 mins in giveaway embed . I have been trying it since 3 days but wasn't able to find a solution. I managed to make it update seconds, but if I specify time more than 1m i.e. 60 seconds it automatically converts it to seconds and starts giveaway with time left in just seconds . I want it to keep time in given unit and update time in --days, --hours, --minutes, --seconds left.

Here are a few images what i mean:

What it currently do:

enter image description here

What i want it to do:

enter image description here

Its just Ends In Or Time remaining what i want to be changed!

My current code:

@commands.command()
    @commands.guild_only()
    async def gstart(self, ctx, duration, *, prize):
        time = self.convert(duration)
        if time == -1:
            await ctx.send(f'Answer Time With A Proper Unit (s, m, h, d)')
            return
        elif time == -2:
            await ctx.send(f'Time Must Be A Integer!')
            return
        giveawayembed = discord.Embed(
            title="?? New Giveaway! ??",
            description=f"**Prize:** {prize}
"
                        f"**Hosted By:** {ctx.author.mention}
"
                        f"**Ends In:** {time} Seconds",
            colour=discord.Color.green()
        )

        msg = await ctx.send(embed=giveawayembed)

        reactions = await msg.add_reaction("??")

        while time:
            await sleep(10)
            time -= 10
            giveawayembed.description= f"**Prize:** {prize}
**Hosted By:** {ctx.author.mention}
**Ends In:** {time} Seconds"
            await msg.edit(embed=giveawayembed)

        new_msg = await ctx.fetch_message(msg.id)

        users = await new_msg.reactions[0].users().flatten()
        users.pop(users.index(self.client.user))

        winner = random.choice(users)

        endembed = discord.Embed(
            title="Giveaway ended!",
            description=f"Prize: {prize}
Winner: {winner.mention}")

        await msg.edit(embed=endembed)
        await ctx.send(f"?? Giveaway Winner: {winner.mention} | Prize: {prize}")

For Converting Time I Have:

class Giveaway(commands.Cog):
    def __init__(self, client):
        self.client = client

    def convert(self, 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]

Any help is highly appreciated! ?? And I m sorry if I wasn't able to make you understand my problem. ??

question from:https://stackoverflow.com/questions/65943784/adding-a-timer-to-giveaway-command-discord-py

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
759 views
Welcome To Ask or Share your Answers For Others

1 Answer

I understand your problem as it is actually a very simple fix, you can either import time, or use await asyncio.sleep(time)

Before using the code I am providing, make sure to import asyncio in your imports.

Your code:

    @commands.command()
    @commands.guild_only()
    async def gstart(self, ctx, duration, *, prize):
        time = self.convert(duration)
        if time == -1:
            await ctx.send(f'Answer Time With A Proper Unit (s, m, h, d)')
            return
        elif time == -2:
            await ctx.send(f'Time Must Be A Integer!')
            return
        giveawayembed = discord.Embed(
            title="?? New Giveaway! ??",
            description=f"**Prize:** {prize}
"
                        f"**Hosted By:** {ctx.author.mention}
"
                        f"**Ends In:** {time} Seconds",
            colour=discord.Color.green()
        )

        msg = await ctx.send(embed=giveawayembed)

        reactions = await msg.add_reaction("??")

        while time:
            await sleep(10)
            time -= 10
            giveawayembed.description= f"**Prize:** {prize}
**Hosted By:** {ctx.author.mention}
**Ends In:** {time} Seconds"
            await msg.edit(embed=giveawayembed)

        new_msg = await ctx.fetch_message(msg.id)

        users = await new_msg.reactions[0].users().flatten()
        users.pop(users.index(self.client.user))

        winner = random.choice(users)

        endembed = discord.Embed(
            title="Giveaway ended!",
            description=f"Prize: {prize}
Winner: {winner.mention}")

        await msg.edit(embed=endembed)
        await ctx.send(f"?? Giveaway Winner: {winner.mention} | Prize: {prize}")

In both fixes I will fix a slight problem that could easily be fixed, you have it so while time, it will go down by 10, I recommend doing it so it says while time > 0: so that once it hits 0 it wont keep counting down.

Easy fix using await asyncio.sleep(time):

    @commands.command()
    @commands.guild_only()
    async def gstart(self, ctx, duration, *, prize):
        time = self.convert(duration)
        if time == -1:
            await ctx.send(f'Answer Time With A Proper Unit (s, m, h, d)')
            return
        elif time == -2:
            await ctx.send(f'Time Must Be A Integer!')
            return
        giveawayembed = discord.Embed(
            title="?? New Giveaway! ??",
            description=f"**Prize:** {prize}
"
                        f"**Hosted By:** {ctx.author.mention}
"
                        f"**Ends In:** {time} Seconds",
            colour=discord.Color.green()
        )

        msg = await ctx.send(embed=giveawayembed)

        reactions = await msg.add_reaction("??")

                while time >= 0:
            if time <= 60:
                giveaway.remove_field(index=1)
                giveaway.insert_field_at(index=1, name='Ends:', value=f'{time} second(s) from now')
                await my_msg.edit(embed=giveaway)
                time -= 10
                await asyncio.sleep(10)
            elif 60 <= time < 3600:
                giveaway.remove_field(index=1)
                giveaway.insert_field_at(index=1, name='Ends:', value=f'{time/60} minute(s) from now')
                await my_msg.edit(embed=giveaway)
                time -= 6
                await asyncio.sleep(6)
            elif 3600 <= time < 86400:
                giveaway.remove_field(index=1)
                giveaway.insert_field_at(index=1, name='Ends:', value=f'{time/3600} hour(s) from now')
                await my_msg.edit(embed=giveaway)
                time -= 360
                await asyncio.sleep(360)
            elif time >= 86400:
                giveaway.remove_field(index=1)
                giveaway.insert_field_at(index=1, name='Ends:', value=f'{time/86400} day(s) from now')
                await my_msg.edit(embed=giveaway)
                time -= 8640
                await asyncio.sleep(8640)
        if time <= 0:
            giveaway.remove_field(index=1)
            giveaway.insert_field_at(index=1, name='Ends:', value=f'Ended at {datetime.datetime.now().strftime("%B %d, %I:%M %p")}') # noqa
            await my_msg.edit(embed=giveaway)

        await asyncio.sleep(time)

        new_msg = await ctx.fetch_message(msg.id)

        users = await new_msg.reactions[0].users().flatten()
        users.pop(users.index(self.client.user))

        winner = random.choice(users)

        endembed = discord.Embed(
            title="Giveaway ended!",
            description=f"Prize: {prize}
Winner: {winner.mention}")

        await msg.edit(embed=endembed)
        await ctx.send(f"?? Giveaway Winner: {winner.mention} | Prize: {prize}")

If you are still confused or have any more questions you can contact me on discord at killrebeest#7187 or comment on this answer. Have a good day!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share

548k questions

547k answers

4 comments

86.3k users

...