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

Discord.py循环实现:持有特定角色一段时间后自动踢出成员

实现角色持有时长达标后自动踢出功能

你的原始代码会直接踢出所有拥有指定角色的成员,但要实现「持有角色达到一定时长再踢」,需要解决两个核心问题:记录用户获得角色的时间,以及定期循环检查时长是否达标。下面是具体实现方案:

1. 准备基础存储与事件监听

我们需要先记录每个用户获得目标角色的时间,这里先用内存字典临时存储(如果Bot重启后不想丢失数据,可以换成JSON文件或数据库):

import discord
from discord.ext import tasks, commands
from datetime import datetime, timedelta

intents = discord.Intents.default()
intents.members = True  # 必须开启成员意图,否则无法监听角色变动
bot = commands.Bot(command_prefix="!", intents=intents)

# 存储用户ID和对应的角色获得时间(键:用户ID,值:datetime对象)
role_add_time = {}
TARGET_ROLE_ID = 1066518590813118494  # 你的目标角色ID
KICK_AFTER = timedelta(hours=2)  # 设置需要达到的时长,比如2小时

然后监听角色添加事件,记录时间:

@bot.event
async def on_member_role_add(member, role):
    if role.id == TARGET_ROLE_ID:
        role_add_time[member.id] = datetime.now()
        print(f"记录用户 {member.name} 获得角色时间:{role_add_time[member.id]}")

2. 用定时循环实现定期检查

使用tasks.loop创建一个定时任务,比如每分钟检查一次(可自行调整间隔),这就是你需要的「循环执行逻辑」:

@tasks.loop(minutes=1)
async def check_kick_condition():
    # 遍历所有存储的用户记录
    for user_id, add_time in list(role_add_time.items()):
        # 计算当前时间与角色获得时间的差值
        time_elapsed = datetime.now() - add_time
        if time_elapsed >= KICK_AFTER:
            try:
                member = bot.get_user(user_id) or await bot.fetch_user(user_id)
                # 确认用户还在服务器且仍持有目标角色
                if member.guild and TARGET_ROLE_ID in [r.id for r in member.roles]:
                    await member.kick(reason=f"持有目标角色超过{KICK_AFTER.total_seconds()/3600}小时")
                    del role_add_time[user_id]  # 踢完后移除记录
                    print(f"已踢出用户 {member.name}")
            except discord.Forbidden:
                print(f"没有权限踢用户 {member.name}")
            except discord.NotFound:
                del role_add_time[user_id]  # 用户已离开服务器,移除记录

# 启动Bot时同时启动定时任务
@bot.event
async def on_ready():
    print(f"Bot已登录:{bot.user}")
    check_kick_condition.start()

3. 关键逻辑说明

  • 迭代循环的作用:tasks.loop会按设置的间隔自动重复执行检查函数,函数内部的for循环遍历所有记录的用户,逐一判断是否满足踢人条件——这是两层迭代逻辑:外层是定时循环重复触发检查,内层是遍历用户列表做时长判断。
  • 持久化存储:如果Bot重启后不想丢失已记录的角色时间,可以把role_add_time字典的内容写入JSON文件,启动时再读取,用json.dump()和json.load()即可实现。
  • 权限注意:确保Bot拥有「踢出成员」的服务器权限,且Bot的角色位置高于目标角色,否则会踢人失败。

内容的提问来源于stack exchange,提问作者Heeryun Cho

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 00:35:27