You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 12:51:17