discord.py计算器机器人按钮交互提示This interaction failed修复求助
Discord计算器机器人交互失败修复方案
核心错误点
- 事件名拼写错误:discord-components库的按钮点击事件名为
button_click,原代码写为button click(空格错误) - 死循环阻塞逻辑:原代码写了独立的
while True: res = await client.wait_for("button click")死循环,后续处理逻辑完全无法执行 - 表达式替换逻辑错误:
calculator函数中替换乘号后,第二次替换除号依然使用原始字符串,导致乘号替换失效 - Embed标题缺少用户ID标识:原代码校验用户身份时尝试从Embed标题拆分
|后的用户ID,但初始化Embed时根本没有写入该信息,会触发类型转换报错 - 按钮输入逻辑错误:普通数字/运算符按钮点击后直接覆盖表达式,而非拼接内容,不符合计算器使用逻辑
- 响应参数拼写错误:
res.respond时传递的组件参数为component,正确参数名为components - 超时逻辑错误:原代码判断
m.created_at < delta永远为真,循环不会自动超时退出,应该判断当前时间是否小于超时时间 - 缺少消息内容意图配置:新版discord.py要求显式开启
message_content意图,否则前缀命令无法触发 - 未校验交互归属:没有判断当前点击的按钮是否属于当前计算器实例,也没有对非发起者的操作做单独响应,会触发交互超时
修正后完整代码
import discord import os from discord.ext import commands, tasks from online import keep_alive from discord_slash import SlashCommand from itertools import cycle from discord_components import * import datetime # 显式声明intents intents = discord.Intents.default() intents.message_content = True client = commands.Bot(command_prefix="!", intents=intents) slash = SlashCommand(client, sync_commands=True) status = cycle([ " Unanswered Question of Life", " Self - Referential Paradox", " Near-infinite density?", " Dark matter ?", " Measurement of the speed of light in one straight line", " Schrodinger's cat ???", "The light side of Discord is the path of many unnatural abilities" ]) @client.event async def on_ready(): print("I have logged in as {0.user}".format(client)) status_swap.start() DiscordComponents(client) buttons = [[ Button(style=ButtonStyle.grey, label='1'), Button(style=ButtonStyle.grey, label='2'), Button(style=ButtonStyle.grey, label='3'), Button(style=ButtonStyle.blue, label='+'), Button(style=ButtonStyle.red, label='Clear') ], [ Button(style=ButtonStyle.grey, label='4'), Button(style=ButtonStyle.grey, label='5'), Button(style=ButtonStyle.grey, label='6'), Button(style=ButtonStyle.blue, label='-'), Button(style=ButtonStyle.red, label='Exit') ], [ Button(style=ButtonStyle.grey, label='7'), Button(style=ButtonStyle.grey, label='8'), Button(style=ButtonStyle.grey, label='9'), Button(style=ButtonStyle.blue, label='×'), Button(style=ButtonStyle.red, label='←') ], [ Button(style=ButtonStyle.grey, label='00'), Button(style=ButtonStyle.grey, label='0'), Button(style=ButtonStyle.grey, label='.'), Button(style=ButtonStyle.blue, label='÷'), Button(style=ButtonStyle.red, label='=') ]] def calculator(exp): o = exp.replace('×', '*') o = o.replace('÷', '/') try: result = str(eval(o)) except: result = "An error occurs" return result @client.command() async def operator(ctx): m = await ctx.send(content="Loading calculator") expression = "" delta = datetime.datetime.utcnow() + datetime.timedelta(minutes = 5) # 标题加入用户ID用于后续校验 e = discord.Embed(title=f"Basic Operation Calculator | {ctx.author.id}",description=expression) await m.edit(content="", components=buttons, embed=e) # 合并循环逻辑,避免死循环 while datetime.datetime.utcnow() < delta : res = await client.wait_for("button_click") # 先判断是否是当前计算器的点击 if res.message.id != m.id: continue # 判断是否是发起者操作 if res.author.id != ctx.author.id: await res.respond(content="你不是该计算器的发起者,无法操作", ephemeral=True) continue expression = res.message.embeds[0].description if expression == 'An error occurs': expression = '' if res.component.label == 'Exit': await res.respond(content='Calculator Closed. Thanks for using Basic Operation Calculator.',type=7, components=[]) break elif res.component.label == "←": expression = expression[:-1] elif res.component.label == 'Clear': expression = '' elif res.component.label == '=': expression = calculator(expression) else: # 拼接输入内容而非覆盖 expression += res.component.label f = discord.Embed(title=f'Basic Operation Calculator | {ctx.author.id}',description=expression) await res.respond(content='', embed = f, components=buttons, type=7) # 超时后禁用按钮 else: await m.edit(components=[[Button(style=ButtonStyle.grey, label=b.label, disabled=True) for b in row] for row in buttons]) await ctx.send("计算器已超时关闭") @tasks.loop(minutes=5) async def status_swap(): await client.change_presence(activity=discord.Game(next(status))) keep_alive() client.run(os.getenv('MATH_VAR'))
内容的提问来源于stack exchange,提问作者Daniesh Rieza
相关产品推荐
相关产品推荐

