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

如何在discord.py中终止已执行的repeat命令?支持.stoprepeat触发

How to Terminate a Running repeat Command in discord.py

Absolutely! You can implement a .stoprepeat command to cancel an ongoing repeat task by tracking active asynchronous tasks. Here's how to modify your existing code to add this functionality:

Core Idea

We'll use a dictionary to track active repeat tasks (keyed by the user's ID, so each user can only run one repeat task at a time). When .stoprepeat is called, we'll look up the user's active task and cancel it.

Modified Full Code

import discord
from discord.ext import commands, tasks
import asyncio
import string
import time
import random
import datetime
from datetime import datetime
import os

class Botting(commands.Cog):
    def __init__(self, client):
        self.client = client
        # Track active repeat tasks: {user_id: asyncio.Task}
        self.active_repeats = {}

    @commands.Cog.listener()
    async def on_ready(self):
        print("Botting Cog is online and connected to Discord")

    async def repeat_task(self, ctx, times, content):
        try:
            for i in range(times):
                await ctx.send(content)
                await asyncio.sleep(0.75)
        except asyncio.CancelledError:
            # Send feedback when the task is cancelled
            await ctx.send("✅ Your repeat task has been stopped.")
        finally:
            # Clean up: remove the task from our tracker regardless of outcome
            if ctx.author.id in self.active_repeats:
                del self.active_repeats[ctx.author.id]

    @commands.command()
    async def repeat(self, ctx, times: int, *, content):
        """Repeats a message multiple times. Use .stoprepeat to cancel early."""
        # Prevent duplicate tasks for the same user
        if ctx.author.id in self.active_repeats:
            await ctx.send("⚠️ You already have an active repeat task running!")
            return
        
        # Create and start the repeat task, then track it
        task = asyncio.create_task(self.repeat_task(ctx, times, content))
        self.active_repeats[ctx.author.id] = task
        await ctx.send(f"🔄 Started repeating your message {times} times. Use `.stoprepeat` to cancel.")

    @commands.command()
    async def stoprepeat(self, ctx):
        """Stops your currently running repeat task."""
        if ctx.author.id not in self.active_repeats:
            await ctx.send("ℹ️ You don't have any active repeat task running.")
            return
        
        # Cancel the active task
        task = self.active_repeats[ctx.author.id]
        task.cancel()

def setup(client):
    client.add_cog(Botting(client))

Key Changes Explained

  • Task Tracking: self.active_repeats stores each user's active repeat task, so we can easily find and cancel it later.
  • Isolated Task Function: repeat_task wraps the original loop logic. It catches asyncio.CancelledError (thrown when task.cancel() is called) to send a user-friendly message, and uses finally to clean up the task tracker.
  • Duplicate Prevention: The repeat command checks if the user already has a running task before starting a new one.
  • Stop Command: .stoprepeat checks for an active task and cancels it immediately if it exists.

Notes

  • This setup limits each user to one active repeat task at a time (which is usually ideal to avoid spam). If you want to allow multiple tasks per user, you could use a more unique identifier (like a random task ID) instead of the user ID as the dictionary key.
  • Canceling a task is safe here because we're handling the CancelledError explicitly—no unhandled exceptions will crash your bot.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:05:43