如何在discord.py的discord.Client()模式下为指令添加冷却功能
基于discord.Client的Discord机器人指令冷却实现方案
实现思路
无需切换到commands.Bot架构,通过本地字典存储用户触发指令的时间戳,在现有消息触发逻辑前添加冷却校验即可实现防刷屏机制,不需要修改原有业务逻辑。
步骤1:初始化冷却配置与存储
import time # 全局冷却时长(单位:秒,可根据不同指令单独调整) GLOBAL_COOLDOWN = 3 # 冷却记录存储结构:key为(用户ID, 指令标识),value为上次触发的时间戳 cooldown_records = {}
步骤2:封装冷却校验工具函数
def check_cooldown(user_id: int, command_tag: str) -> bool: """ 校验用户是否处于某指令的冷却期 返回True代表处于冷却期,不可触发指令;返回False代表可正常触发 """ current_time = time.time() record_key = (user_id, command_tag) if record_key not in cooldown_records: cooldown_records[record_key] = current_time return False if current_time - cooldown_records[record_key] < GLOBAL_COOLDOWN: return True cooldown_records[record_key] = current_time return False
步骤3:嵌入现有消息触发逻辑
只需要在原有触发判断前加一行校验即可,示例如下:
@client.event async def on_message(message): # 跳过机器人自身发送的消息,避免循环触发 if message.author.bot: return # 原有"did i ask"触发逻辑,新增冷却校验 if "did i ask" in message.content.lower(): # 传入用户ID和自定义的指令标识,不同指令用不同标识分开统计冷却 if check_cooldown(message.author.id, "did_i_ask"): # 冷却期内直接跳过,也可根据需求发送冷却提示 return await message.channel.send(whoaskedcopypasta) # 其他原有触发逻辑同理,按需添加校验即可 # if "其他关键词" in message.content.lower(): # if check_cooldown(message.author.id, "其他指令标识"): # return # 原有业务逻辑代码
扩展说明
- 如果需要给不同指令设置不同冷却时长,可以修改
check_cooldown函数,新增cooldown_time参数,调用时传入对应指令的冷却时长即可 - 如果需要支持服务器级、频道级的冷却规则,修改存储的key结构,加入guild_id、channel_id参数即可
- 程序重启后冷却记录会自动清空,如果需要持久化冷却记录,可以把存储介质替换为redis、本地数据库或文件
内容的提问来源于stack exchange,提问作者Tawstar
相关产品推荐
相关产品推荐

