AttributeError: 'Context' object has no attribute 'response' | discord.py

Question:

`import discord
from discord.ext import commands
import time
import json
import platform
from discord import ui


class MyModal(ui.Modal):
    added = ui.TextInput(label='What did you add', placeholder='## What did you add...', style=discord.TextStyle.long)
    removed = ui.TextInput(label='What did you remove', placeholder='## What did you remove...', style=discord.TextStyle.long)


class Client(commands.Bot):

    client = commands.Bot(command_prefix='!', intents=discord.Intents().all())
    async def on_ready(self):
        print('Logged in as: ' + self.user.name)
        print('Bot ID:' + str(self.user.id))
        print('Discord Version: ' + discord.__version__)
        print('Python Version: ' + str(platform.python_version()))


client = Client.client


@client.command(name="modal")
async def modal(interaction: discord.Interaction):
    await interaction.response.send_modal(MyModal)

client.run(TOKEN)`

I followed a youtube tutorial
I didn’t write everything the same.

Basically I wanted to achieve a modal in discord when command (with prefix) is typed: ‘modal’
I wrote like the guy in the video:

await interaction.response.send_modal(MyModal())

And because it worked for him, I thought I would work for me too.

I also tried:

client.tree.command

but then the error was: "Command ‘modal’ is not found",
Also the async def on_ready(self) isn’t working either, but I don’t think that matters in this problem. The program is detecting the ‘!modal’ command, but isn’t showing the actuall modal.

AttributeError: ‘Context’ object has no attribute ‘response’, I don’t have context there, so it shouldn’t be detected as one. I know that context doesn’t have ‘response’ but I have a interaction there.

  • I need help, because I can’t figure it out.
Asked By: Pleysek

||

Answers:

I read your problem and it’s actually very easy to resolve.

First of all, you defined a ~commands.Bot var inside a class of ~commands.Bot. Your bot class must be something like this:

class MyBot(commands.Bot):
    
    def __init__(self, *args, **kwargs) -> None:
        super().__init__(*args, **kwargs)


client = MyBot(...) # replace the ... with the args and kwargs you are going to use

All fine in the modal class but the error is in the response. As your problem description says, you are trying to use !modal to invoke it, right? Well, you must know that ~commands.Context can’t send modals as responses, Modals can only being invoked by ~Interaction.response.send_modal (in app commands and in views)
Also, you are defining a client.commandwith an discord.Interaction response, replace the @client.command() with @client.tree.command(), and you are missing the title and the parentheses on the Modal when sending it, fix it like this:

@client.tree.command()
async def modal(interaction: discord.Interaction) -> None:
    await interaction.response.send_modal(Modal(title="Your Title"))

Keep in mind you will need to synchronise the commands and this can take up to 1 hour.
To sync them I strictly recommend to use a command like this:

@client.command()
async def sync(ctx: commands.Context) -> None:
    synced = await client.tree.sync()
    await ctx.reply("Synced {} commands".format(len(synced)))

Any other doubt ask it in the comments

Edit:

You actually forgot the callback on the modal:

class Modal(ui.Modal):
    
    ...

    async def callback(self, interaction: discord.Interaction) -> None:

        embed = discord.Embed(title="Modal Results", description = f"Added: {self.added.value}nRemoved: {self.removed.value}") # you can remove the `.value` on `self.added` and `self.removed` if error is raised.

        await interaction.response.send_message(embeds=, ephemeral=True)
Answered By: Developer Anonymous