How do I send a modal after a deferred button call in Pycord?

58 views Asked by At

I'm trying to defer a button call and then send a modal afterward in Pycord. Here's a portion of my code:

class AddItemButton(Button):  # Button class from discord.ui.Button
    def __init__(self, title):
        super().__init__(style=discord.ButtonStyle.blurple, label="Add Item", emoji="➕")
        self.title = title  # Title is just something from the database to access things

    async def callback(self, interaction):
        await interaction.response.defer()  # Defer the call
        # -- Add deletion if there's one or more items in the database --
        fetch_one = itemsExistInList(title=self.title, user_id=interaction.user.id)

        if fetch_one and self.view.get_item("delete"):
            self.view.add_item(ItemDeleteSelect(title=self.title, user_id=interaction.user.id))

        await self.view.message.edit(view=self.view)
        await interaction.response.send_modal(AddItemModal(message=self.view.message, title=self.title))  
        # ^ Attempt a response

Specifically this portion:

await interaction.response.send_modal(AddItemModal(message=self.view.message, title=self.title))

When I try the above, I get the following error:

discord.errors.InteractionResponded: This interaction has already been responded to before

Because the interaction has already been responded to, I decided to use a followup. A followup in Pycord is:

Returns the followup webhook for followup interactions.

When I attempted to exchange the previous line with:

        await interaction.followup.send_modal(AddItemModal(message=self.view.message, title=self.title))

It returned:

    await interaction.followup.send_modal(AddItemModal(message=self.view.message, title=self.title))
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'Webhook' object has no attribute 'send_modal'
1

There are 1 answers

0
Blue Robin On BEST ANSWER

After some research, it turns out you can't send a modal after a button defer. This is because Pycord's followup returns a Webhook object which: Webhook params

See here


This means you can't send a modal through the webhook. The solution to this is to not defer the webhook. Code:

class AddItemButton(Button):
    def __init__(self, title):
        super().__init__(style=discord.ButtonStyle.blurple, label="Add Item", emoji="➕")
        self.title = title

    async def callback(self, interaction):
        await interaction.response.send_modal(AddItemModal(message=self.view.message, title=self.title))


        await self.view.message.edit(view=self.view)```