
本文详细讲解如何使用 discord.py 实现消息删除和编辑的完整日志功能,包括构建结构化 embed 日志、区分编辑前后的消息内容,并安全发送至指定日志频道。
本文详细讲解如何使用 discord.py 实现消息删除和编辑的完整日志功能,包括构建结构化 embed 日志、区分编辑前后的消息内容,并安全发送至指定日志频道。
要为 Discord 服务器构建一套可靠的审核日志系统,关键在于准确捕获 on_message_delete 和 on_message_edit 两个事件,并以清晰、可读的方式呈现变更细节。你已成功实现删除日志,接下来需补全编辑日志逻辑——核心在于理解 on_message_edit 的双参数签名:before 表示编辑前的消息对象,after 表示编辑后的消息对象。
以下是完整的、生产就绪的实现示例(适用于 Cog 类):
@commands.Cog.listener()
async def on_message_delete(self, message: discord.Message):
# 跳过机器人自身消息或无内容消息(如仅含附件)
if not message.content.strip() and not message.attachments:
return
embed = discord.Embed(
title="?️ Message Deleted",
color=0xff4444,
timestamp=message.created_at
)
embed.add_field(name="Author", value=f"{message.author.mention} (`{message.author}`)", inline=False)
embed.add_field(name="Channel", value=message.channel.mention, inline=False)
embed.add_field(name="Content", value=message.content or "(No text content)", inline=False)
# 尝试获取并显示附件信息
if message.attachments:
attach_list = "\n".join([f"• `{a.filename}` ({self._format_size(a.size)})" for a in message.attachments])
embed.add_field(name="Attachments", value=attach_list, inline=False)
log_channel = discord.utils.get(message.guild.channels, name="logging")
if log_channel:
await log_channel.send(embed=embed)
@commands.Cog.listener()
async def on_message_edit(self, before: discord.Message, after: discord.Message):
# 忽略由机器人触发的编辑(如自动生成的响应),或内容未实际变化的情况
if before.author.bot or before.content == after.content:
return
embed = discord.Embed(
title="✏️ Message Edited",
color=0xffff44,
timestamp=after.edited_at or after.created_at
)
embed.add_field(name="Author", value=f"{before.author.mention} (`{before.author}`)", inline=False)
embed.add_field(name="Channel", value=before.channel.mention, inline=False)
embed.add_field(name="Before", value=before.content[:1024] or "(Empty)", inline=False)
embed.add_field(name="After", value=after.content[:1024] or "(Empty)", inline=False)
# 若编辑后内容过长,添加截断提示
if len(before.content) > 1024:
embed.set_footer(text="⚠️ Content truncated — full history available via audit log")
log_channel = discord.utils.get(before.guild.channels, name="logging")
if log_channel:
await log_channel.send(embed=embed)
# 辅助方法:格式化文件大小(可选)
def _format_size(self, size_bytes: int) -> str:
for unit in ["B", "KB", "MB"]:
if size_bytes <p><strong>重要注意事项:</strong> </p>
- ✅ 权限校验:确保机器人在日志频道拥有 Send Messages 和 Embed Links 权限;
- ✅ 频道存在性检查:使用 if log_channel: 避免因频道不存在导致异常;
- ✅ 防重复/无效日志:跳过空内容、机器人消息及无实质变更的编辑(before.content == after.content);
- ✅ 内容长度限制:Discord Embed 字段单值上限为 1024 字符,务必截断并提示;
- ✅ 时间戳准确性:优先使用 edited_at(若存在),否则回退至 created_at;
- ⚠️ 敏感信息保护:避免记录用户 ID、令牌等敏感字段,仅展示必要上下文。
通过以上实现,你的日志频道将同时呈现删除与编辑事件的结构化信息,便于管理员快速追溯变更源头,显著提升服务器治理透明度与响应效率。











