如何让discord.py机器人触发其他机器人的消息按钮交互?
问题解答
核心结论
Discord API不支持机器人模拟用户点击按钮,这种行为属于伪造用户交互,违反Discord的服务条款与API使用规范。但可以通过直接修改目标消息的组件状态,或者共享按钮逻辑的方式,实现让频道用户看到按钮标签变化的效果。
具体实现方法
方案一:共享按钮逻辑,直接调用处理函数
既然两个机器人都是你维护的,可以把机器人1的按钮逻辑抽离成独立函数,让机器人2直接调用这些逻辑来修改消息的View:
首先在机器人1的代码中抽离逻辑:
# 抽离按钮1的处理逻辑 async def handle_button1(button: discord.ui.Button): if button.label == "On": button.style = discord.ButtonStyle.red button.disabled = True button.label = "Off" # 抽离按钮2的处理逻辑 async def handle_button2(button: discord.ui.Button): value = int(button.label) if button.label else 0 button.label = str(value + 1) # 抽离按钮3的处理逻辑 async def handle_button3(button: discord.ui.Button): value = int(button.label) if button.label else 0 new_value = value - 1 if new_value <= 0: button.style = discord.ButtonStyle.red button.disabled = True button.label = str(new_value) # 原View类改为调用抽离的函数 class addThreeButtons(discord.ui.View): @discord.ui.button(label='On', style=discord.ButtonStyle.green, custom_id="b1") async def turnOff(self, interaction: discord.Interaction, button: discord.ui.Button): await handle_button1(button) await interaction.response.edit_message(view=self) @discord.ui.button(label='0', style=discord.ButtonStyle.grey, custom_id="b2") async def inc(self, interaction: discord.Interaction, button: discord.ui.Button): await handle_button2(button) await interaction.response.edit_message(view=self) @discord.ui.button(label='10', style=discord.ButtonStyle.green, custom_id="b3") async def dec(self, interaction: discord.Interaction, button: discord.ui.Button): await handle_button3(button) await interaction.response.edit_message(view=self)
然后机器人2的代码中调用逻辑并更新消息:
import random from discord.ui import View, Button # 导入机器人1中抽离的处理函数(需将这些函数放在两个机器人都能访问的公共模块) from bot_common import handle_button1, handle_button2, handle_button3 @bot.command() async def find_and_click_button(ctx): target_message = None # 查找目标消息 async for message in ctx.history(limit=10): if message.content.startswith("Here are your buttons!"): target_message = message break if not target_message: await ctx.send("未找到目标消息") return await ctx.send("找到目标消息") # 从消息加载View view = View.from_message(target_message) # 筛选可用按钮 available_buttons = [btn for btn in view.children if isinstance(btn, Button) and not btn.disabled] if not available_buttons: await ctx.send("没有可用按钮") return selected_button = random.choice(available_buttons) # 根据custom_id调用对应逻辑 if selected_button.custom_id == "b1": await handle_button1(selected_button) elif selected_button.custom_id == "b2": await handle_button2(selected_button) elif selected_button.custom_id == "b3": await handle_button3(selected_button) # 更新消息的View await target_message.edit(view=view) await ctx.send(f"已触发按钮:{selected_button.custom_id}")
方案二:直接修改消息组件数据(无需共享逻辑)
如果不想共享代码,机器人2可以直接解析消息的组件数据,修改后重新编辑消息:
import random @bot.command() async def find_and_click_button(ctx): target_message = None async for message in ctx.history(limit=10): if message.content.startswith("Here are your buttons!"): target_message = message break if not target_message: await ctx.send("未找到目标消息") return # 获取消息的组件数据 components = target_message.components if not components: await ctx.send("目标消息没有组件") return # 遍历筛选可用按钮 available_buttons = [] for row in components: for component in row.children: if component.type == discord.ComponentType.button and not component.disabled: available_buttons.append((row, component)) if not available_buttons: await ctx.send("没有可用按钮") return # 随机选择一个按钮修改状态 selected_row, selected_btn = random.choice(available_buttons) if selected_btn.custom_id == "b1": if selected_btn.label == "On": selected_btn.style = discord.ButtonStyle.red selected_btn.disabled = True selected_btn.label = "Off" elif selected_btn.custom_id == "b2": value = int(selected_btn.label) if selected_btn.label else 0 selected_btn.label = str(value + 1) elif selected_btn.custom_id == "b3": value = int(selected_btn.label) if selected_btn.label else 0 new_value = value - 1 selected_btn.label = str(new_value) if new_value <= 0: selected_btn.style = discord.ButtonStyle.red selected_btn.disabled = True # 更新消息组件 await target_message.edit(components=components) await ctx.send(f"已更新按钮:{selected_btn.custom_id}")
注意事项
- 两个机器人需要拥有编辑消息的权限,否则无法修改目标消息。
- 不要尝试模拟用户交互请求,此类操作会导致机器人账号被Discord封禁。
内容的提问来源于stack exchange,提问作者Gabisness
相关产品推荐
相关产品推荐

