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
相关产品推荐
相关产品推荐

