Pending bot reply from a slash command pycord

112 Views Asked by At

I have a bot, and I want to type the command /chat and then have the bot create a thread and respond to the command there. I did that successfully, but the problem is that the message "bot is thinking" keeps pending even after bot completed everything I asked.

So I was wondering, how can I dismiss this pending in the code?

My code:

import discord
from tools.config import TOKEN
from tools.gpt_helper.gpt_custom_classes import generate_response
from discord.ext import commands
bot = discord.Bot()


@bot.event
async def on_ready():
    print(f"{bot.user} is ready and online!")


@bot.slash_command(name="chat", description="some desc")
async def chat(ctx, msg):
    channel = bot.get_channel(MY_CHANNEL_ID)
    await ctx.response.defer(ephemeral=True)
    resp = await generate_response(prompt=msg)
    thread = await channel.create_thread(name="wop", type=None)
    await thread.send(resp)


bot.run(TOKEN)

I am using g4f python module here to interact with chat gpt, it generates the answer to user response (variable "msg" in chat() function) with the line resp = await generate_response(prompt=msg) . And then I create a thread and respond there:

thread = await channel.create_thread(name="wop", type=None)
await thread.send(resp)

Here a picture of pending bot reply

enter image description here

2

There are 2 best solutions below

3
On BEST ANSWER

The problem is the way you're responding:

    await ctx.response.defer(ephemeral=True)

I'll assume that the thread creation is 100% correct and won't cover that here. Deferring the thread (see here):

Defers the interaction response.

This is typically used when the interaction is acknowledged and a secondary action will be done later.

You don't have a secondary action, so the interaction stays in the "deferred" state. So, you should do:

await ctx.respond('insert message here')

This responds with that message in the same channel and cancels the deferred state.

1
On

Basically defer() is a response designed for codes that take more than 3s (the max. time before Discord timeout the section). Therefore it continues to be pending because discord is waiting the bot to give the section a follow-up action. So defer() is not designed for your case.

I see you are trying to response users in threads, other than in commands' reply.
However, slash commands required at least one and only one response, so you cannot get rid of the command replying section.
To avoid the pending state, you first have to remove the await ctx.response.defer(ephemeral=True) statement. Your can just simply replace it with

await ctx.response.send_message('a message you want')

Or giving no responses, force leaving the command function like:

@bot.slash_command(name="chat", description="some desc")
async def chat(ctx, msg):
    channel = bot.get_channel(MY_CHANNEL_ID)
    resp = await generate_response(prompt=msg)
    thread = await channel.create_thread(name="wop", type=None)
    await thread.send(resp)
    return

Note that this is not a proper way so there may be a error message telling that the command failed but actually not.