Pycord-Development / pycord

Pycord is a modern, easy to use, feature-rich, and async ready API wrapper for Discord written in Python
https://docs.pycord.dev
MIT License
2.71k stars 458 forks source link

Components require a reboot of the bot to be caught in on_interaction #753

Closed KosmicAnomaly closed 2 years ago

KosmicAnomaly commented 2 years ago

Summary

Trying to use on_interaction with new components raises NotFound until the bot is restarted

Reproduction Steps

Create a dropdown menu, then try to interact with it and catch the interaction using on_interaction()

Minimal Reproducible Code

No response

Expected Results

Not have an error

Actual Results

Ignoring exception in on_interaction Traceback (most recent call last): File "C:\Users\nvrgonnagiveuup\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\client.py", line 352, in _run_event await coro(*args, **kwargs) File "C:\Users\nvrgonnagiveuup\Desktop\Code\DiscordBots\BlackHole\Modules\Utility\Polls.py", line 127, in on_interaction await response.edit_message(embed=embed) File "C:\Users\nvrgonnagiveuup\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\interactions.py", line 717, in edit_message await adapter.create_interactionresponse( File "C:\Users\nvrgonnagiveuup\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\webhook\async.py", line 192, in request raise NotFound(response, data) discord.errors.NotFound: 404 Not Found (error code: 10062): Unknown interaction

Intents

discord.Intents.all()

System Information

Checklist

Additional Context

No response

1oonie commented 2 years ago

Could you provide some code so that I can try and repro this, this is what the "Minimal reproducible code" section is for y'know

On other note, why are you handling your components in on_interaction???

KosmicAnomaly commented 2 years ago

yeah sure! And I am handling my components in on_interaction because it is the method that makes most sense to me.

from discord.commands import slash_command
from discord.ext.commands import Cog, guild_only
from discord.ui import Select, View

class CoolDropdown(Select):
    def __init__(self):
        optionList = [SelectOption(
            label="thing1", value="Option 1"), SelectOption(
            label="thing2", value="Option 2")]

        super().__init__(
            placeholder="choose one",
            min_values=0,
            max_values=1,
            options=optionList
        )

class CoolView(View):
    def __init__(self):
        super().__init__()

        self.add_item(CoolDropdown())

class randomthing(Cog):
    def __init__(self, bot):
        self.BlackHole = bot

    @slash_command(name="make-dropdown")
    @guild_only()
    async def make_dropdown(self, ctx: ApplicationContext):

        await ctx.defer(ephemeral=True)

        view = CoolView()
        await ctx.send(content="yeet", view=view)
        await ctx.respond("dropdown created!", ephemeral=True)

    @Cog.listener()
    async def on_interaction(self, interaction: Interaction):
        if not interaction.is_component():
            return
        if not interaction.guild:
            return

        response = interaction.response

        await response.send_message("yayeet")

def setup(bot):
    bot.add_cog(randomthing(bot))
phenom4n4n commented 2 years ago

This code doesn't correspond to your traceback, which shows that the erroring line is await response.edit_message(embed=embed).

KosmicAnomaly commented 2 years ago

Sorry, I had changed my code because I needed to create some minimal code. The error is the same tho. Here's the new traceback


Traceback (most recent call last):
  File "C:\Users\nvrgonnagiveuup\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\client.py", line 352, in _run_event
    await coro(*args, **kwargs)
  File "C:\Users\nvrgonnagiveuup\Desktop\Code\DiscordBots\BlackHole\Modules\Utility\randomthing.py", line 51, in on_interaction
    await response.send_message("yayeet")
  File "C:\Users\nvrgonnagiveuup\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\interactions.py", line 610, in send_message
    await adapter.create_interaction_response(
  File "C:\Users\nvrgonnagiveuup\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\webhook\async_.py", line 192, in request
    raise NotFound(response, data)
discord.errors.NotFound: 404 Not Found (error code: 10062): Unknown interaction```
1oonie commented 2 years ago

You can just override the callback method of discord.ui.Select if you want something called when someone selects an item, you can get what was selected with self.values.

KosmicAnomaly commented 2 years ago

The issue is in on_interaction, I don't need to use callback

1oonie commented 2 years ago

I think that this might be because the view auto-defers the interaction for you, I guess just don't use on_interaction.

KosmicAnomaly commented 2 years ago

Why would it start working perfectly fine after a reboot then?

1oonie commented 2 years ago

likely because the library doesn't know about the components after you restart and doesn't attach them to a view object (that does the auto deferring)

KosmicAnomaly commented 2 years ago

Is there a way to disable the auto-deferring?

1oonie commented 2 years ago

No.

KosmicAnomaly commented 2 years ago

Hmm. The reason I am using on_interaction instead of callback is because I have calls to my database (which is attached to my Bot object) every time the dropdown is used. I don't think I can send that to my view easily. And, I can also avoid using persistent views this way.

KosmicAnomaly commented 2 years ago

I have found a solution

class CoolView(View):
    def __init__(self):
        super().__init__()

        self.add_item(CoolDropdown())
        self.stop()
1oonie commented 2 years ago

This is a horrible solution, find a better way to get your bot object instead, ex. ctx.bot

KosmicAnomaly commented 2 years ago

It is a glorious solution

Dorukyum commented 2 years ago

It is highly suggested to use the callback attribute of the component and not on_interaction.