如何在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_repeatsstores each user's active repeat task, so we can easily find and cancel it later. - Isolated Task Function:
repeat_taskwraps the original loop logic. It catchesasyncio.CancelledError(thrown whentask.cancel()is called) to send a user-friendly message, and usesfinallyto clean up the task tracker. - Duplicate Prevention: The
repeatcommand checks if the user already has a running task before starting a new one. - Stop Command:
.stoprepeatchecks 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
CancelledErrorexplicitly—no unhandled exceptions will crash your bot.
内容的提问来源于stack exchange,提问作者Yuma
相关产品推荐
相关产品推荐

