如何用discord.py追踪服务器用户活动?可行性及实现疑问
使用discord.py实现用户活动追踪与自动封禁功能
一、功能可行性说明
- discord.py完全可以实现你需要的功能,核心是通过监听Discord事件记录用户活动,再基于记录的数据实现查询和自动封禁逻辑。
- Discord官方API没有直接提供“获取用户最后活动时间”的接口,所以需要机器人在运行过程中自行存储用户的活动数据(消息发送、语音频道加入)。
二、手动查询命令实现步骤
1. 数据存储方案
可以用简单的JSON文件或SQLite数据库存储用户活动记录,以下是JSON文件示例:
import json from datetime import datetime # 加载或初始化活动记录 def load_activity_data(): try: with open("user_activity.json", "r") as f: return json.load(f) except FileNotFoundError: return {} def save_activity_data(data): with open("user_activity.json", "w") as f: json.dump(data, f, indent=2, default=str)
2. 监听事件记录活动
import discord from discord.ext import commands # 启用必要的权限意图 intents = discord.Intents.default() intents.message_content = True intents.voice_states = True intents.members = True bot = commands.Bot(command_prefix="!", intents=intents) @bot.event async def on_message(message): if message.author.bot: # 忽略机器人自身消息 return activity_data = load_activity_data() user_id = str(message.author.id) # 更新最后发送消息时间 activity_data[user_id] = activity_data.get(user_id, {}) activity_data[user_id]["last_message"] = datetime.now().isoformat() save_activity_data(activity_data) await bot.process_commands(message) @bot.event async def on_voice_state_update(member, before, after): # 检测用户从无频道状态加入语音频道的行为 if not before.channel and after.channel: activity_data = load_activity_data() user_id = str(member.id) activity_data[user_id] = activity_data.get(user_id, {}) activity_data[user_id]["last_voice"] = datetime.now().isoformat() save_activity_data(activity_data)
3. 查询命令实现
@bot.command() async def checkactivity(ctx, member: discord.Member): activity_data = load_activity_data() user_id = str(member.id) user_data = activity_data.get(user_id, {}) last_msg = user_data.get("last_message", "无记录") last_voice = user_data.get("last_voice", "无记录") # 格式化时间为易读格式 try: if last_msg != "无记录": last_msg = datetime.fromisoformat(last_msg).strftime("%Y-%m-%d %H:%M:%S") if last_voice != "无记录": last_voice = datetime.fromisoformat(last_voice).strftime("%Y-%m-%d %H:%M:%S") except: pass await ctx.send(f"用户 {member.display_name} 的活动记录:\n最后发送消息时间:{last_msg}\n最后加入语音频道时间:{last_voice}")
三、自动封禁功能实现
1. 定时任务设置
使用discord.ext.tasks模块实现每日检查:
from discord.ext import tasks from datetime import timedelta @tasks.loop(hours=24) # 每天执行一次检查 async def check_inactive_users(): activity_data = load_activity_data() now = datetime.now() one_year_ago = now - timedelta(days=365) for guild in bot.guilds: # 跳过机器人无封禁权限的服务器 if not guild.me.guild_permissions.ban_members: continue for member in guild.members: # 忽略机器人和管理员 if member.bot or member.guild_permissions.administrator: continue user_id = str(member.id) user_data = activity_data.get(user_id, {}) # 获取用户最后活动时间(取消息和语音中较晚的记录) last_activity = None if "last_message" in user_data: last_activity = datetime.fromisoformat(user_data["last_message"]) if "last_voice" in user_data: voice_time = datetime.fromisoformat(user_data["last_voice"]) if last_activity is None or voice_time > last_activity: last_activity = voice_time # 无活动记录或超过一年未活动则封禁 if last_activity is None or last_activity < one_year_ago: try: await member.ban(reason="超过一年无服务器活动") print(f"已封禁用户 {member.display_name} ({member.id})") except discord.Forbidden: print(f"无权限封禁用户 {member.display_name} ({member.id})") except discord.HTTPException as e: print(f"封禁用户 {member.display_name} 失败:{e}") # 机器人启动后启动定时任务 @bot.event async def on_ready(): print(f"Logged in as {bot.user}") check_inactive_users.start()
四、关于discord.js的可行性
discord.js同样可以实现该功能,逻辑完全一致:
- 监听
messageCreate事件记录消息发送时间 - 监听
voiceStateUpdate事件记录语音加入时间 - 用JSON或数据库存储数据
- 借助
node-schedule等库实现定时检查并封禁用户
Discord API提供的事件和权限要求是通用的,仅语法和生态工具存在差异,不存在技术障碍。
内容的提问来源于stack exchange,提问作者Tomception
相关产品推荐
相关产品推荐

