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

Discord Bot消息编辑失效问题排查及功能实现咨询

Discord Bot消息编辑失效排查与操作日志实现

一、消息编辑失效问题修复

原代码存在三个核心问题导致消息无法正常编辑:

  • 按钮回调未绑定:创建按钮后未将回调方法与按钮关联,且错误使用了discord.py不存在的on_button_click事件,点击按钮不会触发预期逻辑。需在View初始化时为按钮绑定对应回调函数。
  • 状态数据不持久:每次点击按钮都新建SimpleView实例,导致记录在线人员的trabalhando列表始终为空,无法积累状态。需确保整个Bot运行期间使用同一个View实例维护状态。
  • 编辑目标错误:原代码试图编辑按钮所在的消息,但需求是更新下方的人员列表消息,且启动时发送的人员列表消息未保存引用,后续无法定位编辑目标。需保存该消息对象供后续操作使用。

二、操作日志实现

添加一个日志列表,限制最多存储20条操作记录,每条记录包含操作时间、用户及动作类型(登录/退出),在更新人员列表时同步展示日志内容。

修正后完整代码

import discord
from discord.ext import commands
import settings
from datetime import datetime


class SimpleView(discord.ui.View):
    def __init__(self, status_message):
        super().__init__(timeout=None)  # 设置View永不超时
        self.trabalhando = []
        self.status_message = status_message  # 保存人员列表消息引用
        self.action_logs = []  # 操作日志列表

        # 创建登录按钮并绑定回调
        entrar_button = discord.ui.Button(label="Entrar", style=discord.ButtonStyle.green, custom_id="entrar_button")
        entrar_button.callback = self.enter_button_callback
        self.add_item(entrar_button)

        # 创建退出按钮并绑定回调
        sair_button = discord.ui.Button(label="Sair", style=discord.ButtonStyle.red, custom_id="sair_button")
        sair_button.callback = self.sair_button_callback
        self.add_item(sair_button)

    def _update_log(self, member, action):
        """更新操作日志,最多保留20条"""
        current_time = datetime.now().strftime("%d/%m/%Y %H:%M:%S")
        log_entry = f"[{current_time}] {member.display_name} - {action}"
        self.action_logs.append(log_entry)
        # 超过20条则删除最早的记录
        if len(self.action_logs) > 20:
            self.action_logs.pop(0)

    async def update_message(self):
        """更新人员列表消息,包含在线人员和操作日志"""
        # 构建在线人员文本
        workers_text = "\n".join([member.display_name for member in self.trabalhando]) or "Nenhum"
        # 构建日志文本
        logs_text = "\n".join(self.action_logs) or "Nenhuma ação registrada"
        # 组合内容并编辑消息
        content = f"```Mecânicos trabalhando:\n{workers_text}\n\n--- Histórico de ações ---\n{logs_text}```"
        await self.status_message.edit(content=content)

    async def enter_button_callback(self, interaction: discord.Interaction):
        member = interaction.user
        if member not in self.trabalhando:
            self.trabalhando.append(member)
            self._update_log(member, "Entrou")
            await self.update_message()
        # 回复交互,避免Discord提示按钮无响应
        await interaction.response.defer(ephemeral=True)

    async def sair_button_callback(self, interaction: discord.Interaction):
        member = interaction.user
        if member in self.trabalhando:
            self.trabalhando.remove(member)
            self._update_log(member, "Saiu")
            await self.update_message()
        # 回复交互,避免Discord提示按钮无响应
        await interaction.response.defer(ephemeral=True)


bot = commands.Bot(command_prefix='!', intents=discord.Intents.all())


@bot.event
async def on_ready():
    print(f"Bot conectado como {bot.user}")
    guild = bot.get_guild(settings.GUILD_ID_INT)
    if not guild:
        print("无法找到指定服务器")
        return
    channel = guild.get_channel(settings.FEEDBACK_CH)
    if not channel:
        print("无法找到指定频道")
        return

    # 先发送人员列表消息,保存引用
    status_message = await channel.send("```Mecânicos trabalhando:\nNenhum\n\n--- Histórico de ações ---\nNenhuma ação registrada```")
    # 创建View并传入消息引用,发送按钮消息
    view = SimpleView(status_message)
    await channel.send("Controle de presença:", view=view)


bot.run(settings.DISCORD_API_SECRET, root_logger=True)

关键修正说明

  • 给View设置timeout=None确保按钮长期有效,不会超时失效。
  • 每个按钮通过button.callback = 回调方法绑定交互逻辑,替代原错误的on_button_click事件。
  • 将人员列表消息引用传入View,确保每次操作都编辑正确的目标消息。
  • 添加_update_log方法维护操作日志,自动截断超过20条的旧记录。
  • 每次按钮交互后调用interaction.response.defer(),避免Discord返回"按钮无响应"的提示。

内容的提问来源于stack exchange,提问作者Rafael Oliveira

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 06:12:02