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

如何在discord.py中用Discord原生系统设置带单位的Timeout

在discord.py中使用原生系统设置用户Timeout(支持带单位时长)

前提依赖

确保你使用的是discord.py v2.0及以上版本,原生Timeout功能是在这个版本之后正式加入的。安装/更新命令:

pip install discord.py>=2.0

1. 解析带单位的时长字符串

先实现一个函数,将1m、2h、3d这类格式的字符串转换为datetime.timedelta对象,同时遵守Discord对Timeout的最长限制(28天):

import re
from datetime import timedelta

def parse_duration(duration_str: str) -> timedelta:
    # 匹配数字+单位的模式,支持s(秒)、m(分)、h(时)、d(天)
    pattern = re.compile(r'(\d+)([smhd])')
    matches = pattern.findall(duration_str.lower())
    
    if not matches:
        raise ValueError("无效的时长格式,请使用如1m、2h、3d的格式")
    
    total_seconds = 0
    for value, unit in matches:
        value = int(value)
        if unit == 's':
            total_seconds += value
        elif unit == 'm':
            total_seconds += value * 60
        elif unit == 'h':
            total_seconds += value * 3600
        elif unit == 'd':
            total_seconds += value * 86400
    
    # Discord限制Timeout最长为28天,超出则自动截断
    max_duration = timedelta(days=28)
    parsed_duration = timedelta(seconds=total_seconds)
    return parsed_duration if parsed_duration <= max_duration else max_duration

2. 从数据库获取目标用户ID

根据你的数据库结构,实现查询逻辑(以下为示例,需根据实际数据库类型调整):

def get_user_id_by_username(target_username: str) -> int | None:
    # 替换为你实际的数据库操作代码,比如SQLite/MySQL查询
    cursor.execute("SELECT user_id FROM users WHERE username = ?", (target_username,))
    result = cursor.fetchone()
    return result[0] if result else None

3. 实现原生Timeout命令

使用discord.py提供的Member.timeout()原生方法(无需角色循环),结合上述函数完成完整命令:

import discord
from discord.ext import commands

# 初始化Bot,启用message_content意图(前缀命令需要)
intents = discord.Intents.default()
intents.message_content = True
bot = commands.Bot(command_prefix='!', intents=intents)

@bot.command(name='timeout')
@commands.has_permissions(moderate_members=True)  # 限制仅有权限的用户执行
async def timeout_user(ctx: commands.Context, target_username: str, duration_str: str):
    # 1. 从数据库获取目标用户ID
    user_id = get_user_id_by_username(target_username)
    if not user_id:
        await ctx.send(f"未找到用户 {target_username}")
        return
    
    # 2. 获取服务器内的成员对象(Timeout仅针对服务器成员)
    target_member = ctx.guild.get_member(user_id)
    if not target_member:
        await ctx.send(f"用户 {target_username} 不在当前服务器中")
        return
    
    # 3. 解析输入的时长
    try:
        duration = parse_duration(duration_str)
    except ValueError as e:
        await ctx.send(str(e))
        return
    
    # 4. 执行原生Timeout操作
    try:
        await target_member.timeout(duration, reason="管理员执行Timeout")
        await ctx.send(f"已将 {target_username} 禁言 {duration_str}")
    except discord.Forbidden:
        await ctx.send("我没有权限执行该操作")
    except discord.HTTPException as e:
        await ctx.send(f"执行Timeout时出错:{e}")

# 启动Bot
bot.run('你的Bot令牌')

额外说明

  • 权限要求:Bot需要服务器的「Moderate Members」权限,命令执行者也需拥有该权限。
  • 时长限制:Discord原生Timeout最长支持28天,超出的时长会自动截断为28天。
  • Slash命令适配:如果需要使用Slash命令,只需将命令改为@bot.tree.command()格式,参数处理逻辑基本一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 13:05:13