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

discord.py中如何传出async def内的Message变量以实现消息删除?

解决Discord机器人垃圾消息检测与删除的问题

看起来你在实现垃圾消息检测时,陷入了「无法在on_message外部获取message对象」的误区,但其实根本不需要把message拿到外部处理——直接在事件回调内部就可以完成删除操作!咱们一步步理清楚问题和解决方案:

1. 先修正当前代码的核心问题

你当前的代码里有几个关键问题:

  • 错误地把msg赋值成了message.author(这是用户对象,不是消息对象),而非message本身;
  • 缺少cont变量的定时重置逻辑(你提到每1秒重置,但当前代码没实现);
  • 试图把message传到外部处理,这完全没必要,反而会引发变量类型或覆盖的问题。

2. 正确的实现思路

第一步:用定时任务重置消息计数

使用discord.ext.tasks的循环任务来自动每秒重置cont,避免手动管理全局变量的混乱:

import discord
from discord.ext import tasks, commands

client = commands.Bot(command_prefix="!", intents=discord.Intents.all())

# 初始化全局消息计数
cont = 0

# 每秒重置一次cont的定时任务
@tasks.loop(seconds=1)
async def reset_cont():
    global cont
    cont = 0

# 机器人启动时启动定时任务
@client.event
async def on_ready():
    reset_cont.start()
    print("Bot is ready!")

第二步:在on_message内部完成检测与删除

在消息事件回调里,直接使用message对象进行判断和删除操作,不需要把它传到外部:

@client.event
async def on_message(message):
    global cont
    # 跳过机器人自己的消息,避免自触发
    if message.author.bot:
        return
    
    cont += 1
    # 检测垃圾消息(每秒内消息数超过6)
    if cont > 6:
        print(f'Spam detected from {message.author}')
        # 直接在内部删除触发的消息
        await message.delete()
        # 可根据需求调整计数逻辑,比如减1避免连续触发
        cont -= 1
    
    # 必须加上这句,否则commands框架的命令无法正常工作
    await client.process_commands(message)

3. 为什么你之前的var=message会变成int类型?

你提到赋值后新变量变成int类型,大概率是不小心把var赋值成了message的某个整数属性(比如message.id),而非message对象本身。但其实根本不需要做这个额外赋值——在on_message内部直接用message就好,它本来就是discord.message.Message类型。

4. 优化建议:按用户单独计数(更合理的垃圾检测)

当前的全局cont会把所有用户的消息加在一起,容易误判(比如多个正常用户同时发消息也会触发)。更合理的方式是按用户ID跟踪每个用户的消息计数:

import discord
from discord.ext import tasks, commands
from collections import defaultdict

client = commands.Bot(command_prefix="!", intents=discord.Intents.all())

# 用字典存储每个用户的消息计数,key是用户ID,value是计数
user_msg_counts = defaultdict(int)

@tasks.loop(seconds=1)
async def reset_counts():
    global user_msg_counts
    user_msg_counts.clear()

@client.event
async def on_ready():
    reset_counts.start()
    print("Bot is ready!")

@client.event
async def on_message(message):
    if message.author.bot:
        return
    
    user_id = message.author.id
    user_msg_counts[user_id] += 1
    
    if user_msg_counts[user_id] > 6:
        print(f'Spam detected from {message.author}')
        await message.delete()
        user_msg_counts[user_id] -= 1
    
    await client.process_commands(message)

这样只会检测单个用户在1秒内发超过6条消息的情况,更符合刷屏类垃圾消息的检测场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:31:26