Discord机器人模态框报告命令报错:'Context'无'response'属性
解决Discord机器人模态框报告命令的AttributeError错误
问题代码
我正在开发Discord机器人,编写了一个基于模态框的报告命令,代码如下:
class ReportModal(discord.ui.Modal, title="Репорт юзер"): user_name = discord.ui.TextInput(label="Юзер дискорд наме", placeholder="eg. Jgfhfhjfkfk#0000", required=True, max_length=10000, style=discord.TextStyle.short) user_id = discord.ui.TextInput(label="Юзер дискорд наме2", placeholder="eg. Jgfhfhjfkfk#0000", required=True, max_length=10000, style=discord.TextStyle.long) @bot.command(name="report", description="Репорт юзер") async def report(interaction: discord.Interaction): modal = ReportModal() await interaction.response.send_modal(modal)
报错信息
运行时出现如下错误:
File "/home/container/.local/lib/python3.11/site-packages/discord/ext/commands/core.py", line 235, in wrapped ret = await coro(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/container/main.py", line 26, in report await interaction.response.send_modal(modal) ^^^^^^^^^^^^^^^^^^^^ AttributeError: 'Context' object has no attribute 'response' The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/home/container/.local/lib/python3.11/site-packages/discord/ext/commands/bot.py", line 1350, in invoke await ctx.command.invoke(ctx) File "/home/container/.local/lib/python3.11/site-packages/discord/ext/commands/core.py", line 1029, in invoke await injected(*ctx.args, **ctx.kwargs) # type: ignore ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/container/.local/lib/python3.11/site-packages/discord/ext/commands/core.py", line 244, in wrapped raise CommandInvokeError(exc) from exc discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'Context' object has no attribute 'response'
解决方案
问题根源
你错误地给**前缀命令(@bot.command)**的回调函数声明了Interaction类型参数。前缀命令实际传入的是Context对象,它没有response属性,而send_modal是Interaction对象的专属方法,因此触发报错。
方法一:改用斜杠命令(推荐)
Discord官方更推荐使用斜杠交互命令,修改步骤如下:
- 将
@bot.command替换为@bot.tree.command - 确保机器人启动时同步命令到Discord服务器
- 保留
Interaction类型参数
修改后的完整代码:
import discord from discord.ext import commands intents = discord.Intents.default() intents.message_content = True bot = commands.Bot(command_prefix="!", intents=intents) class ReportModal(discord.ui.Modal, title="Репорт юзер"): user_name = discord.ui.TextInput(label="Юзер дискорд наме", placeholder="eg. Jgfhfhjfkfk#0000", required=True, max_length=100, style=discord.TextStyle.short) user_id = discord.ui.TextInput(label="Юзер ID/Тег", placeholder="eg. 1234567890 или Jgfhfhjfkfk#0000", required=True, max_length=100, style=discord.TextStyle.short) # 添加模态框提交后的处理逻辑 async def on_submit(self, interaction: discord.Interaction): await interaction.response.send_message(f"Репорт отправлен!\nЮзер: {self.user_name.value}\nID/Тег: {self.user_id.value}", ephemeral=True) @bot.tree.command(name="report", description="Репорт юзер") async def report(interaction: discord.Interaction): modal = ReportModal() await interaction.response.send_modal(modal) # 同步命令到服务器(全局同步可能需要1小时, guild_ids指定服务器可即时生效) @bot.event async def on_ready(): await bot.tree.sync() # 全局同步 # await bot.tree.sync(guild=discord.Object(id=你的服务器ID)) # 指定服务器同步 print(f"Бот {bot.user} запущен!") bot.run("你的机器人令牌")
方法二:前缀命令中通过按钮触发模态框(不推荐)
如果坚持使用前缀命令,需要先发送带按钮的消息,用户点击按钮后触发模态框:
import discord from discord.ext import commands intents = discord.Intents.default() intents.message_content = True bot = commands.Bot(command_prefix="!", intents=intents) class ReportButton(discord.ui.View): @discord.ui.button(label="Отправить репорт", style=discord.ButtonStyle.danger) async def report_button(self, interaction: discord.Interaction, button: discord.ui.Button): modal = ReportModal() await interaction.response.send_modal(modal) class ReportModal(discord.ui.Modal, title="Репорт юзер"): user_name = discord.ui.TextInput(label="Юзер дискорд наме", placeholder="eg. Jgfhfhjfkfk#0000", required=True, max_length=100, style=discord.TextStyle.short) user_id = discord.ui.TextInput(label="Юзер ID/Тег", placeholder="eg. 1234567890 или Jgfhfhjfkfk#0000", required=True, max_length=100, style=discord.TextStyle.short) async def on_submit(self, interaction: discord.Interaction): await interaction.response.send_message(f"Репорт отправлен!\nЮзер: {self.user_name.value}\nID/Тег: {self.user_id.value}", ephemeral=True) @bot.command(name="report", description="Репорт юзер") async def report(ctx: commands.Context): await ctx.send("Нажмите кнопку ниже для отправки репорта:", view=ReportButton()) @bot.event async def on_ready(): print(f"Бот {bot.user} запущен!") bot.run("你的机器人令牌")
内容的提问来源于stack exchange,提问作者zootmn15
相关产品推荐
相关产品推荐

