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

Discord.py tempmute命令如何支持s/m/h/d时间单位后缀

实现tempmute命令识别s/m/h/d时间后缀的改造方案

改造核心逻辑

不需要复杂的自定义discord.py转换器,只需要新增时间字符串解析逻辑,替换原有直接读取整数秒的参数逻辑即可。改造完成后命令调用格式和预期完全一致,示例:tempmute @张三 30m 恶意刷屏,会自动识别30m为30分钟,后面的内容自动拼接为违规原因,同时兼容原有的纯数字(默认按秒计算)的输入习惯。

支持的输入规则

  • 带后缀格式:30s(30秒)、30m(30分钟)、2h(2小时)、1d(1天),后缀大小写不敏感(比如30M和30m效果一致)
  • 兼容原有格式:纯数字输入默认按秒计算,比如60等同于60s
  • 非法输入(比如30x、abc、负数时长)会自动触发报错提示,不会导致机器人崩溃

改造后完整代码

import asyncio
import discord
from discord.ext import commands

# 时间单位和秒数的映射规则,可自行扩展支持的单位
TIME_UNITS = {
    "s": 1,
    "m": 60,
    "h": 3600,
    "d": 86400
}

def parse_time(time_input: str):
    """解析时间字符串,返回(总秒数, 人类可读时间描述),非法输入返回(None, None)"""
    time_input = time_input.strip().lower()
    # 处理纯数字的情况,默认单位为秒
    if time_input.isdigit():
        total_seconds = int(time_input) * TIME_UNITS["s"]
        return total_seconds, f"{time_input}秒"
    # 提取最后一位作为单位校验
    unit = time_input[-1]
    if unit not in TIME_UNITS:
        return None, None
    # 提取数值部分校验
    num_part = time_input[:-1]
    if not num_part.isdigit():
        return None, None
    num = int(num_part)
    total_seconds = num * TIME_UNITS[unit]
    unit_cn = {"s": "秒", "m": "分钟", "h": "小时", "d": "天"}[unit]
    return total_seconds, f"{num}{unit_cn}"

# 以下为原有客户端初始化逻辑,按实际配置替换
client = commands.Bot(command_prefix="!")

@client.command()
@commands.has_permissions(manage_messages=True)
async def tempmute(ctx, member: discord.Member, time_str: str, reason=None):
    # 处理未提供原因的默认情况
    if reason == None:
        reason = "未提供违规原因"
    
    # 自静音校验,补充原代码缺失的return逻辑,否则校验后仍会继续执行静音流程
    if member.id == ctx.author.id:
        await ctx.send(f"{ctx.author.mention}, 你不能给自己使用临时静音命令")
        return

    # 解析并校验时间参数合法性
    total_seconds, time_desc = parse_time(time_str)
    if total_seconds is None or total_seconds <= 0:
        await ctx.send("时间格式有误!请输入类似 `30s`/`30m`/`2h`/`1d` 的格式,纯数字默认按秒计算,且时长必须大于0")
        return

    role = discord.utils.get(ctx.guild.roles, name="Muted")
    guild = ctx.guild

    # 不存在Muted角色时自动创建并配置全频道权限
    if not role:
        role = await guild.create_role(name="Muted")
        for channel in guild.channels:
            await channel.set_permissions(role, speak=False, send_messages=False, read_message_history=True, read_messages=False)
    
    embed = discord.Embed(title="临时静音生效", description=f"{member.mention} 已被临时静音", colour=discord.Colour.light_gray())
    embed.add_field(name="违规原因", value=reason, inline=False)
    embed.add_field(name="静音时长", value=time_desc, inline=False)
    await member.add_roles(role)
    await ctx.send(embed=embed)
    # 等待对应时长后自动移除静音角色
    await asyncio.sleep(total_seconds)
    await member.remove_roles(role)

# 以下为原有机器人运行逻辑,按实际配置替换
# client.run("你的机器人Token")

额外注意点

  • 目前的解析逻辑仅支持单单位后缀,不支持组合格式(比如1h30m),如果需要支持组合格式可以自行扩展解析函数的拆分逻辑
  • 原有逻辑的临时静音状态存储在内存中,如果机器人重启,所有未到期的临时静音会直接失效,不会自动恢复,属于原有代码的设计限制,本次改造未调整这部分逻辑
  • 请确保机器人的角色层级在「Muted」角色上方,且拥有管理频道权限、管理角色的权限,否则会出现创建角色、设置频道权限失败的问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.23 04:36:00