如何解决AttributeError: 'Interaction'对象无'custom_id'属性问题
问题解决方法
错误原因
你触发的AttributeError: 'Interaction'对象没有'custom_id'属性,是因为discord.Interaction本身没有直接暴露custom_id属性,按钮的自定义ID存储在interaction.data字典中,需要从这里读取。
临时修复:修改on_interaction事件
如果坚持使用on_interaction事件,可按以下方式修改代码,先判断交互类型为组件交互,再从data中获取custom_id:
@bot.event async def on_interaction(interaction: discord.Interaction): async def give_req_form(interaction: discord.Interaction): modal = ReqQuestion() await interaction.response.send_modal(modal) await modal.wait() # 仅处理组件类型的交互 if interaction.type == discord.InteractionType.component: custom_id = interaction.data.get('custom_id') if custom_id == 'req': await give_req_form(interaction)
推荐方案:使用视图类绑定按钮回调
这种写法更符合discord.py的设计规范,还能解决按钮一段时间后失效的问题(通过持久化视图实现):
# 定义带按钮回调的视图类 class ReqView(discord.ui.View): def __init__(self): # 设置timeout=None让按钮永久有效,也可设置具体秒数(如3600=1小时) super().__init__(timeout=None) # 直接绑定按钮的回调函数 @discord.ui.button(label='Отправить Реквест', style=discord.ButtonStyle.green, custom_id='req') async def req_button_click(self, interaction: discord.Interaction, button: discord.ui.Button): modal = ReqQuestion() await interaction.response.send_modal(modal) await modal.wait() @bot.hybrid_command(description='Form') @commands.has_permissions(administrator=True) async def req_form(ctx): global green embed = discord.Embed(title='Отправка реквестов', description= 'Тут вы можете отправить ваш уровень нашему модератору, а тот перекинет уровень GD-модераторам на оценку!\n```Правила реквестов```\n- Ваш уровень должен соответствовать как правилам проекта, так и правилам игры\n- Нельзя пользоватся данной системой не в серьёз. За ложный реквест вы получите наказание, а позже и блокировку доступа к системе!\n- Вы получите такое-же наказание как и за прошлый пункт, если вы отправите в анкете рофл-уровень!\n- Не используйте систему чрезмерно часто!', color=green) embed.set_image(url='https://cdn.discordapp.com/attachments/1051774366758735902/1236724216712134706/REQ-05-05-2024_1.png?ex=66390cae&is=6637bb2e&hm=28ad7939dafe85e3ba606c3b09178e375438f12060eb7de8f4cfda4eb0eebed6&') view = ReqView() await ctx.reply(embed=embed, view=view) # 机器人启动时注册持久化视图,确保重启后按钮仍有效 @bot.event async def on_ready(): await bot.add_view(ReqView()) print(f'已登录为 {bot.user}')
说明
- 视图类的回调函数会自动响应对应
custom_id的按钮点击,无需手动在on_interaction中判断 - 设置
timeout=None配合bot.add_view()可实现按钮持久化,解决一段时间后失效的问题 - 如果不需要永久有效,可将
timeout设置为具体秒数(如timeout=3600表示1小时后按钮失效)
内容的提问来源于stack exchange,提问作者TheNeyre
相关产品推荐
相关产品推荐

