如何创建可记录消息、编辑等内容到文本文件的Python Discord机器人?
社团Discord日志机器人实现方案
嘿,我来帮你搞定这个用于社团服务器的日志机器人!既然你已经了解on_message()的基本用法,那咱们直接切入正题,一步步实现全量内容的记录功能。
1. 基础准备
首先确保你已经安装了discord.py库(推荐用v2.x版本,API更稳定):
pip install discord.py
另外,机器人需要在Discord开发者平台开启以下核心权限(邀请机器人时务必勾选):
- 读取消息/查看频道
- 查看服务器邀请
- 消息内容意图(这个是读取消息文本的关键,必须在开发者平台的"Privileged Gateway Intents"里手动开启)
2. 捕获并记录普通消息
在on_message()事件里,message对象包含了所有你需要的消息细节,直接调用属性就能获取:
message.content: 消息的文本内容message.author: 发送者的用户信息(用户名、ID等)message.channel: 消息所在频道(名称、ID)message.created_at: 消息发送时间
写入日志时用追加模式,避免覆盖历史记录,同时指定utf-8编码防止乱码:
import discord from datetime import datetime # 配置机器人意图,必须开启消息内容和消息相关权限 intents = discord.Intents.default() intents.message_content = True intents.messages = True client = discord.Client(intents=intents) # 封装日志写入函数,复用性更强 def write_log(log_content): timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") with open("discord_guild_logs.txt", "a", encoding="utf-8") as f: f.write(f"[{timestamp}] {log_content}\n") @client.event async def on_message(message): # 跳过机器人自己的消息,避免循环记录 if message.author.bot: return # 构造结构化日志内容,方便教师查看 log_text = f"普通消息 | 用户: {message.author.name}({message.author.id}) | 频道: {message.channel.name}({message.channel.id}) | 内容: {message.content}" write_log(log_text) # 替换成你的机器人TOKEN client.run("你的机器人TOKEN")
3. 记录消息编辑操作
用on_message_edit事件捕获编辑行为,它会返回编辑前(before)和编辑后(after)的消息对象,只有内容真正变化时才记录:
@client.event async def on_message_edit(before, after): if before.author.bot: return if before.content != after.content: log_text = f"消息编辑 | 用户: {before.author.name}({before.author.id}) | 频道: {before.channel.name}({before.channel.id}) | 原内容: {before.content} | 新内容: {after.content}" write_log(log_text)
4. 记录消息删除操作
通过on_message_delete事件捕获被删除的消息,直接提取消息的历史内容:
@client.event async def on_message_delete(message): if message.author.bot: return log_text = f"消息删除 | 用户: {message.author.name}({message.author.id}) | 频道: {message.channel.name}({message.channel.id}) | 被删内容: {message.content}" write_log(log_text)
5. 捕获邀请链接(两种场景)
场景1:用户发送的邀请链接
在on_message里用正则匹配消息中的Discord邀请链接:
import re @client.event async def on_message(message): if message.author.bot: return # 匹配所有格式的Discord邀请链接 invite_pattern = r"(https?://)?(discord\.gg|discord\.com/invite)/([a-zA-Z0-9]+)" invites = re.findall(invite_pattern, message.content) if invites: # 拼接完整的邀请链接 full_invites = [f"{prefix}{domain}/{code}" for prefix, domain, code in invites] invite_log = f"邀请链接发送 | 用户: {message.author.name}({message.author.id}) | 频道: {message.channel.name}({message.channel.id}) | 链接: {', '.join(full_invites)}" write_log(invite_log) # 别忘了记录普通消息 message_log = f"普通消息 | 用户: {message.author.name}({message.author.id}) | 频道: {message.channel.name}({message.channel.id}) | 内容: {message.content}" write_log(message_log)
场景2:新创建的服务器邀请
如果要捕获管理员后台创建的邀请(不管有没有发到频道),需要开启服务器意图,用on_invite_create事件:
intents.guilds = True # 开启服务器相关意图 @client.event async def on_invite_create(invite): creator = invite.inviter.name if invite.inviter else "未知用户" creator_id = invite.inviter.id if invite.inviter else "未知ID" log_text = f"邀请链接创建 | 创建者: {creator}({creator_id}) | 服务器: {invite.guild.name}({invite.guild.id}) | 链接: {invite.url} | 有效期: {invite.max_age//3600}小时 | 最大使用次数: {invite.max_uses}" write_log(log_text)
6. 日志优化建议
- 按日期分割日志文件(比如每天生成
discord_logs_20240520.txt),避免单文件过大 - 给日志文件设置权限,确保只有授权教师能读取
- 如果需要更规范的格式,可以用JSON格式写入日志,方便后续导出分析
完整整合代码
把所有功能整合起来,就是一个开箱即用的日志机器人:
import discord import re from datetime import datetime intents = discord.Intents.default() intents.message_content = True intents.messages = True intents.guilds = True client = discord.Client(intents=intents) def write_log(log_content): timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") with open("discord_guild_logs.txt", "a", encoding="utf-8") as f: f.write(f"[{timestamp}] {log_content}\n") @client.event async def on_ready(): print(f"已登录为 {client.user},开始记录社团服务器日志...") write_log(f"机器人上线 | 账号: {client.user.name}({client.user.id})") @client.event async def on_message(message): if message.author.bot: return # 检测邀请链接 invite_pattern = r"(https?://)?(discord\.gg|discord\.com/invite)/([a-zA-Z0-9]+)" invites = re.findall(invite_pattern, message.content) if invites: full_invites = [f"{prefix}{domain}/{code}" for prefix, domain, code in invites] write_log(f"邀请链接发送 | 用户: {message.author.name}({message.author.id}) | 频道: {message.channel.name}({message.channel.id}) | 链接: {', '.join(full_invites)}") # 记录普通消息 write_log(f"普通消息 | 用户: {message.author.name}({message.author.id}) | 频道: {message.channel.name}({message.channel.id}) | 内容: {message.content}") @client.event async def on_message_edit(before, after): if before.author.bot or before.content == after.content: return write_log(f"消息编辑 | 用户: {before.author.name}({before.author.id}) | 频道: {before.channel.name}({before.channel.id}) | 原内容: {before.content} | 新内容: {after.content}") @client.event async def on_message_delete(message): if message.author.bot: return write_log(f"消息删除 | 用户: {message.author.name}({message.author.id}) | 频道: {message.channel.name}({message.channel.id}) | 被删内容: {message.content}") @client.event async def on_invite_create(invite): creator = invite.inviter.name if invite.inviter else "未知用户" creator_id = invite.inviter.id if invite.inviter else "未知ID" write_log(f"邀请链接创建 | 创建者: {creator}({creator_id}) | 服务器: {invite.guild.name}({invite.guild.id}) | 链接: {invite.url} | 有效期: {invite.max_age//3600}小时 | 最大使用次数: {invite.max_uses}") client.run("YOUR_BOT_TOKEN_HERE")
最后提醒:部署前一定要确认学校的隐私政策,确保日志记录符合相关规定,只对授权教师开放日志访问权限哦!
内容的提问来源于stack exchange,提问作者MrSam123
相关产品推荐
相关产品推荐

