Reputation: 38
I'm trying to make a new Discord bot. I'm stuck at getting cooldowns of slash commands. Here is my imports;
import asyncio
from utils import TOKEN
import aiosqlite
import nextcord
from nextcord import Interaction, SlashOption, ChannelType
from nextcord.abc import GuildChannel
from nextcord.ext import commands, tasks
import random
import time
import cooldowns
from cooldowns import SlashBucket, CallableOnCooldown
I'm getting cooldown error for my basic slash command and I can display it. My command;
@Bot.slash_command(guild_ids=[test_guild], name="beg", description="Beggin in the street. Poor guy.")
@cooldowns.cooldown(1, 30, bucket=cooldowns.SlashBucket.author)
async def beg(interaction: Interaction):
chances = random.randint(1, 4)
if chances == 1:
embed = nextcord.Embed(title="You begged", colour=nextcord.Colour.from_rgb(255, 0, 0))
embed.add_field(name="And you got nothing.", value="Poor guy")
return await interaction.response.send_message(embed=embed)
amount = random.randint(10, 100)
res = await update_wallet(interaction.user, amount)
if res == 0:
return await interaction.response.send_message("No account found so one has been created for you. Please run the command again!")
embed = nextcord.Embed(title="You begged", colour=nextcord.Colour.from_rgb(35, 209, 0))
embed.add_field(name="Wow someone gave you some coins", value=f"You got `{amount} coins`")
await interaction.response.send_message(embed=embed)
And error handler;
@Bot.event
async def on_application_command_error(interaction: Interaction, error):
error = getattr(error, "original", error)
cdown = error.retry_after
embed = nextcord.Embed(title="Hold on", colour=nextcord.Colour.from_rgb(255, 0, 0))
if isinstance(error, CallableOnCooldown):
cdown = "%.0f" % error.retry_after
if int(cdown) >= 3600:
cd = round(error.retry_after)
hours = str(cd // 3600)
minute = int(cd // 60)
minutes = str(minute % 60)
seconds = str(cd % 60)
embed.add_field(name="You are on cooldown for this command", value=f"Remaining time: `{hours} hours {minutes} minutes {seconds} seconds`")
await interaction.response.send_message(embed=embed)
elif int(cdown) >= 60 and int(cdown) < 3600:
cd = round(error.retry_after)
minutes = str(cd // 60)
seconds = str(cd % 60)
embed.add_field(name="You are on cooldown for this command", value=f"Remaining time: `{minutes} minutes {seconds} seconds`")
await interaction.response.send_message(embed=embed)
elif int(cdown) < 60:
embed.add_field(name="You are on cooldown for this command", value=f"Remaining time: `{cdown} seconds`")
await interaction.response.send_message(embed=embed)
I have one more command like that called claim and I want to display both of them at once with another command. Like this;
@Bot.slash_command(guild_ids=[test_guild])
async def cooldown(interaction: Interaction):
claim_c = Bot.get_command("claim")
cooldown_claim = claim_c.get_cooldown_retry_after(interaction)
beg_c = Bot.get_command("beg")
cooldown_beg = beg_c.get_cooldown_retry_after(interaction)
# await interaction.response.send_message(f"Cooldown left {command.get_cooldown_retry_after(ctx)}")
embed = nextcord.Embed(title="COOLDOWNS", colour=nextcord.Colour.from_rgb(255, 0, 0))
if cooldown_claim >= 3600:
cd = round(cooldown_claim)
hours = str(cd // 3600)
minute = int(cd // 60)
minutes = str(minute % 60)
seconds = str(cd % 60)
embed.add_field(name="Claim", value=f"`{hours} hours {minutes} minutes {seconds} seconds`", inline=False)
elif int(cooldown_claim) >= 60 and int(cooldown_claim) < 3600:
cd = round(cooldown_claim)
minutes = str(cd // 60)
seconds = str(cd % 60)
embed.add_field(name="Claim", value=f"`{minutes} minutes {seconds} seconds`", inline=False)
elif int(cooldown_claim) < 60 and int(cooldown_claim) > 0:
embed.add_field(name="Claim", value=f"`{cooldown_claim} seconds`", inline=False)
elif int(cooldown_claim) == 0:
embed.add_field(name="Claim", value="`Ready`", inline=False)
if cooldown_beg >= 3600:
cd = round(cooldown_beg)
hours = str(cd // 3600)
minute = int(cd // 60)
minutes = str(minute % 60)
seconds = str(cd % 60)
embed.add_field(name="Beg", value=f"`{hours} hours {minutes} minutes {seconds} seconds`", inline=False)
elif int(cooldown_beg) >= 60 and int(cooldown_beg) < 3600:
cd = round(cooldown_beg)
minutes = str(cd // 60)
seconds = str(cd % 60)
embed.add_field(name="Beg", value=f"`{minutes} minutes {seconds} seconds`", inline=False)
elif int(cooldown_beg) < 60 and int(cooldown_beg) > 0:
cd = round(cooldown_beg)
embed.add_field(name="Beg", value=f"`{cd} seconds`", inline=False)
elif int(cooldown_beg) == 0.0:
embed.add_field(name="Beg", value="`Ready`", inline=False)
await interaction.response.send_message(embed=embed)
When I try to run this code. I got errors;
Ignoring exception in on_application_command_error
Traceback (most recent call last):
File "C:\Users\nmgir\PycharmProjects\girginbot.py\lib\site-packages\nextcord\client.py", line 499, in _run_event
await coro(*args, **kwargs)
File "C:\Users\nmgir\OneDrive\Desktop\slashcomamnds\main.py", line 56, in on_application_command_error
cdown = error.retry_after
AttributeError: 'AttributeError' object has no attribute 'retry_after'
This is just a little bit weird because line 56 is cdown = error.retry_after. It works properly on other commands.
I know i'm doing something wrong but I can't figure it out. Maybe you guys can help me.
Upvotes: 1
Views: 1139
Reputation: 1
You aren't doing anything wrong. You are stuck at the same place as I am for some time already. Thing is, nextcord slash commands don't have cooldown. Standard prefix commands do have it however,I personally need slash as I am fetching some info from the backend as arguments.
Here is git issue thread talking about that and some possible alternatives:
https://github.com/nextcord/nextcord/discussions/715
Upvotes: 0