I have a Discord bot with a command that take some time to be completed (about 5 seconds). When the command take too much time to complete without any responses to Discord servers, I've seen that Discord make the command crash, and delete the Context, so when I send a response, it raises an error to say that the Context does not exists.
MEE6 by example, when executing a command, Discord returns:
Sending command...
And when MEE6 receive the command, it says:
MEE6 is thinking...
But my bot does not.
How can I do like MEE6, return to Discord that my command is still running ?
Im using Nextcord (a discord.py fork) so discord.py anwsers will works too.
Minimal reproductible code:
import requests, nextcord
from nextcord.ext import commands
bot = commands.Bot(intents=nextcord.Intents.all()) # be sure to enable every discord intents in the discord dev portal
@bot.slash_command(name='axolotl')
async def axolotl(ctx): # do things that take a lot of time
r = requests.get('https://axolotlapi-test.kirondevcoder.repl.co/reddit?nsfw=0', timeout=2)
if r.status_code == 200:
data = r.json()['data'][0]
embed = nextcord.Embed(title='Axolotl !', description=data['text'] or 'No text content.')
medias = ""
for media in data['media']:
embed.set_image(media)
await ctx.send('', embed=embed)
else:
await ctx.send('', embed=nextcord.Embed(title='Axolotl !', description='There was an error while contacting the API.'))
bot.run('your token here')
I know that the ctx
object is not a nextcord.Context
object but a nextcord.interaction.Interaction
object and I think the API docs of this class can be found at https://docs.nextcord.dev/en/stable/api.html#nextcord.Interaction but im not sure.
I allready tried to make the bot typing on the channel, but it does not change anything:
@bot.slash_command(name='axolotl')
async def axolotl(ctx):
async with ctx.channel.typing():
r = requests.get('https://axolotlapi-test.kirondevcoder.repl.co/reddit?nsfw=0', timeout=2)
if r.status_code == 200:
data = r.json()['data'][0]
embed = nextcord.Embed(title='Axolotl !', description=data['text'] or 'No text content.')
medias = ""
for media in data['media']:
embed.set_image(media)
await ctx.send('', embed=embed)
else:
await ctx.send('', embed=nextcord.Embed(title='Axolotl !', description='There was an error while contacting the API.'))
(I only provided the command code, else its the same code as the minimal reproductible code)
Can someone help please ?
If your commands take a while to execute then you can defer()
to tell discord that your commands are going to take a while (and get the "Bot is thinking..." message).
So add await ctx.response.defer()
at the start of your command. You can then use the followup
attribute to send a message and "respond" to the slash command.
@bot.slash_command(name='axolotl')
async def axolotl(ctx):
await ctx.response.defer()
async with ctx.channel.typing():
r = requests.get('https://axolotlapi-test.kirondevcoder.repl.co/reddit?nsfw=0', timeout=2)
if r.status_code == 200:
data = r.json()['data'][0]
embed = nextcord.Embed(title='Axolotl !', description=data['text'] or 'No text content.')
medias = ""
for media in data['media']:
embed.set_image(media)
await ctx.followup.send('', embed=embed)
else:
await ctx.followup.send('', embed=nextcord.Embed(title='Axolotl !', description='There was an error while contacting the API.'))