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

discord.py如何正确编写timeout超时禁言命令

问题根因

你的代码有三个核心问题,导致逻辑始终触发失败分支:

  • 参数类型不匹配:timed_out_until 明确要求传入带时区信息的datetime类型到期时间点,你传入的datetime.timedelta(minutes=ender)是时间差对象,完全不符合参数要求。
  • 判断逻辑错误:Member.edit() 是异步执行的操作方法,执行成功时不会返回任何有效对象(返回值为None),你用变量接收返回值后判断if not handover,哪怕操作完全成功也会因为None被判定为假,走到打印no的分支。
  • 遗漏前置校验:执行超时操作需要机器人拥有moderate_members(管理成员超时)权限,且机器人在服务器的角色排序必须高于被操作的成员,否则接口会直接抛出权限错误。
可直接运行的修正代码
from datetime import timedelta
import discord

# 请提前在代码头部定义myid、完成bot实例初始化
@bot.command()
async def timeout(ctx, mem: discord.Member, ender: int):
    if ctx.author.id != myid:
        return
    # Discord官方限制超时禁言最长有效期为28天,提前做参数校验
    if ender > 28*24*60:
        await ctx.send("超时禁言最长时长为28天,请重新输入分钟数")
        return
    try:
        # 生成符合要求的带UTC时区的到期时间
        expire_time = discord.utils.utcnow() + timedelta(minutes=ender)
        await mem.edit(timed_out_until=expire_time)
        await ctx.send(f"✅ 已对 {mem.mention} 执行{ender}分钟超时禁言")
    except discord.Forbidden:
        await ctx.send("❌ 操作失败:机器人权限不足,请检查是否拥有「超时成员」权限,且角色层级高于被操作成员")
    except discord.HTTPException as e:
        await ctx.send(f"❌ 接口请求失败:{str(e)}")
补充使用说明
  • 解除用户超时禁言只需要调用await mem.edit(timed_out_until=None)即可。
  • 不要使用本地时间生成datetime对象传入,必须使用带UTC时区的时间,discord.utils.utcnow()是官方推荐的生成方式,不会出现时区偏移导致的禁言时长异常问题。
  • 上述代码默认ender参数单位为分钟,如果需要支持秒/小时/天的多单位输入,可以自行扩展参数解析逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 05:00:57