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

如何用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 20:25:25