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

能否在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 21:50:15