如何让discord.py开发的正在刷屏的Discord机器人停止发送垃圾消息
解决方案
你的现有代码直接在命令回调中执行循环发送逻辑,没有暴露可外部终止的控制入口,可通过异步Task+运行状态存储的方式实现终止功能,完整实现如下:
步骤1:定义全局存储结构
首先新增全局字典,用来存储当前正在运行的刷屏任务:
import asyncio # 存储格式:(用户ID, 频道ID) : 对应的异步Task对象 running_spam_tasks = {}
步骤2:修改原有spam命令
将刷屏逻辑封装为可取消的异步Task,运行时存入字典,结束后自动清理:
@bot.command(name="spam", help="spam some message") async def spam(ctx, times:int, *, message): task_key = (ctx.author.id, ctx.channel.id) # 若当前用户在该频道已有运行中的刷屏任务,先取消旧任务 if task_key in running_spam_tasks: running_spam_tasks[task_key].cancel() await ctx.send("已终止当前运行的刷屏任务,即将启动新任务") # 封装刷屏逻辑 async def _spam_task(): try: for _ in range(times): await ctx.send(message) # 可选:加短延迟避免触发Discord速率限制,可自行调整间隔时长 await asyncio.sleep(0.5) except asyncio.CancelledError: await ctx.send("刷屏任务已手动终止") raise finally: # 任务结束后移除存储记录 running_spam_tasks.pop(task_key, None) # 启动异步任务并存入字典 task = asyncio.create_task(_spam_task()) running_spam_tasks[task_key] = task
步骤3:新增终止命令
新增stopspam命令用于主动终止正在运行的刷屏任务:
@bot.command(name="stopspam", help="stop running spam task") async def stop_spam(ctx): task_key = (ctx.author.id, ctx.channel.id) if task_key in running_spam_tasks: running_spam_tasks[task_key].cancel() else: await ctx.send("当前无正在运行的刷屏任务")
可选扩展
- 如果需要允许管理员终止整个频道内的所有刷屏任务,可修改
stopspam命令的逻辑,遍历字典匹配频道ID取消所有对应Task即可 - 可根据需求调整发送间隔,间隔越短触发速率限制的风险越高,建议最低不低于0.3秒
内容的提问来源于stack exchange,提问作者red78massive1573
相关产品推荐
相关产品推荐

