能否在discord.py中实现命令运行时仅按频道生效的冷却机制?
实现按频道隔离的Feed命令运行限制
完全可以实现你要的需求,分两种场景给你具体方案:
场景1:固定时间内同频道不能重复触发(冷却限制)
如果你的Feed命令是一次性执行(比如发一批梗图就结束),只是需要同频道在指定时间内不能重复调用,直接给@commands.cooldown指定基于频道ID的自定义冷却键就行:
from discord.ext import commands # 自定义冷却键:返回当前频道ID,让每个频道独立计算冷却 def get_channel_cooldown_key(ctx): return ctx.channel.id @commands.command() # 参数说明:1次调用,冷却60秒,使用自定义键规则 @commands.cooldown(1, 60, commands.BucketType.custom, key=get_channel_cooldown_key) async def feed(ctx): # 你的梗图推送逻辑(一次性执行) await ctx.send("推送一波梗图!") # ...这里写你的发图代码
场景2:命令运行期间同频道禁止重复启动(实时锁定)
如果你的Feed是持续运行的(比如每隔几秒自动发图,直到手动停止),这时候用冷却装饰器就不合适了,得手动维护一个状态集合来跟踪正在运行的频道:
from discord.ext import commands import asyncio # 存储正在运行Feed的频道ID(如果需要停止功能,可以改成字典存任务对象) active_feed_channels = set() @commands.command() async def feed(ctx): # 检查当前频道是否已经在运行Feed if ctx.channel.id in active_feed_channels: await ctx.send("这个频道已经在推梗图了,别重复开!") return # 标记频道为运行中 active_feed_channels.add(ctx.channel.id) try: await ctx.send("开始自动推梗图啦,输入`!stopfeed`可以叫停") # 模拟持续推送逻辑,每隔5秒发一张图 while True: # 替换成你的梗图获取+发送代码 await ctx.send("😎 新鲜梗图送达!") await asyncio.sleep(5) except asyncio.CancelledError: # 停止时移除频道标记 active_feed_channels.remove(ctx.channel.id) await ctx.send("梗图推送已停止") # 配套的停止命令(可选) @commands.command() async def stopfeed(ctx): if ctx.channel.id not in active_feed_channels: await ctx.send("当前频道没在推梗图啊") return # 如需精准停止任务,建议将active_feed_channels改为字典存储{频道ID: 任务对象} # 示例优化逻辑:在feed命令中创建任务并存入字典,stopfeed时取出任务取消 active_feed_channels.remove(ctx.channel.id) await ctx.send("梗图推送已停止")
注意:第二种场景里,如果需要支持手动停止,建议用字典存储每个频道对应的任务对象,这样才能精准取消正在运行的推送循环。
内容的提问来源于stack exchange,提问作者Luke
相关产品推荐
相关产品推荐

