如何使用Discord.js实现支持定期更新倒计时的定时器命令
实现思路与代码示例
前置说明
以下基于 Python 生态最常用的 discord.py v2.x 版本实现,核心逻辑对其他 Discord bot 开发库通用,仅语法存在差异。
核心实现步骤
- 第一步:做时长参数解析,将用户输入的
10m/1h/30s这类带单位的时间字符串转换为总秒数,方便后续计算 - 第二步:收到定时器命令后,先发送初始倒计时消息,留存该消息对象用于后续状态更新
- 第三步:启动独立异步任务执行倒计时逻辑,避免阻塞 bot 其他命令响应:
- 每次循环使用
random.randint(20, 30)生成随机等待秒数,满足20-30秒更新的要求 - 等待结束后计算当前剩余时长,格式化后编辑之前留存的倒计时消息
- 剩余时长归0后编辑消息发送倒计时结束提示,可@触发命令的用户做提醒
- 每次循环使用
可直接参考的代码片段
import discord from discord.ext import commands import asyncio import random import re # 时间解析正则,匹配数字+单位的格式 TIME_REGEX = re.compile(r"(\d+)([smh])") # 此处prefix可替换为你自定义的命令前缀 bot = commands.Bot(command_prefix="!", intents=discord.Intents.all()) # 时长解析函数,返回总秒数 def parse_time(time_str: str) -> int: total = 0 matches = TIME_REGEX.findall(time_str.lower()) for num, unit in matches: num = int(num) if unit == "s": total += num elif unit == "m": total += num * 60 elif unit == "h": total += num * 3600 return total @bot.command(name="timer") async def start_timer(ctx, time_str: str): total_seconds = parse_time(time_str) if total_seconds <= 0: await ctx.send("时间格式错误,请输入类似 `10m`/`1h`/`30s` 的格式") return if total_seconds > 86400: await ctx.send("最长支持24小时以内的定时器") return remaining = total_seconds # 发送初始倒计时消息 countdown_msg = await ctx.send(f"⏰ 倒计时启动,剩余时间:{remaining//3600}时{(remaining%3600)//60}分{remaining%60}秒") # 异步倒计时任务 while remaining > 0: # 随机生成20-30秒的等待时间 wait_time = random.randint(20, 30) # 如果剩余时间小于等待时间,直接等待剩余时长即可结束 if wait_time > remaining: wait_time = remaining await asyncio.sleep(wait_time) remaining -= wait_time # 更新倒计时消息 if remaining > 0: hours = remaining // 3600 mins = (remaining % 3600) // 60 secs = remaining % 60 await countdown_msg.edit(content=f"⏰ 倒计时进行中,剩余时间:{hours}时{mins}分{secs}秒") else: await countdown_msg.edit(content=f"⏰ 倒计时结束!{ctx.author.mention}") bot.run("你的bot token")
注意事项
- 不要使用同步
time.sleep()实现等待,会阻塞整个 bot 的所有命令响应,必须用异步的asyncio.sleep() - 如果需要支持多用户同时启动多个定时器,当前逻辑已经支持,asyncio 会自动调度多个倒计时任务互不干扰
- 可以根据需求添加取消定时器的命令,只需要给每个定时器加唯一标识,用户触发取消时终止对应异步任务即可
内容的提问来源于stack exchange,提问作者ItsChris
相关产品推荐
相关产品推荐

