如何限制 on_message 回复(Discord Python 机器人)

Posted

技术标签:

【中文标题】如何限制 on_message 回复(Discord Python 机器人)【英文标题】:How can I limit the on_message replies (Discord Python bot) 【发布时间】:2020-10-11 16:38:03 【问题描述】:

我正在制作一个 Discord Bot,它可以做各种事情,包括对提到该机器人的人做出反应,以及对某些用户在某个频道中所说的话做出反应。 我的代码(为清楚起见而缩短)是:

BOT = os.getenv('DISCORD_BOT_MENTION') 
CHANNEL = os.getenv('DISCORD_CHANNEL')
USER1 = os.getenv('DISCORD_USER1_ID')
USER2 = os.getenv('DISCORD_USER2_ID')

@bot.event 
async def on_message(message):  
    content = message.content # Did bot get mentioned?
    channel = message.channel # Where was the bot mentioned
    channel_ID = message.channel.id #
    user = message.author.name # Who mentioned the bot
    user_ID = message.author.id

    if user == client.user:
        return

    elif BOT in content:
        brankos_responses = [
            "Hello",
            "Hi",
        ]
        weights_responses = [
            15,
            10,
        ]
        response = random.choices(brankos_responses, weights_responses, k = 1)
        await asyncio.sleep(0.7) # Wait 0.7s before answering
        await channel.send(response[0])
    
    elif channel_ID == int(CHANNEL):
        if user_ID == int(USER_ID_1): 
            brankos_responses = [
                "Test Message 1 for User 1 in Channel",
                "Test Message 2 for User 1 in Channel",
            ]
            response = random.choice(brankos_responses)
            await channel.send(response)

        if user_ID == int(USER_id_2):
            brankos_responses = [
                "Test Message 1 for User 2 In Channel",
                "Test Message 2 for User 2 in Channel",
            ]
            response = random.choice(brankos_responses)
            await channel.send(response)

    else: 
        return

    await bot.process_commands(message)

但是我发现,如果您向机器人发送垃圾邮件,或者如果用户 1 和 2 在频道中交谈,它会继续回复,我想限制这种情况。 例如,在使用@commands.cooldown(1, 3600, commands.BucketType.user) 很容易的 discord.py 命令中,但是我拥有的不是命令,因此不能在这里使用。

我认为我可以让机器人休眠(使用 await asyncio),当它注意到频道中来自一位用户的消息时,然后当该人 5 秒钟内没有说任何话时,它会运行代码并发送 1 个回复,但这只会导致所有回复堆积起来,并在几秒钟后全部发送出去。

所以我的问题是:如何限制机器人的回复数量?

现在我正在尝试这个:

        user_list = [
            int(USER1_ID),
            int(USER2_ID),
            int(USER3_ID),
            int(USER4_ID),
        ]

        messages = 0 # Define the count
        
        if user_ID in user_list:
            messages += 1 # Add one to count
            print(messages)

            if messages > 5: # If messages is more than 5, execute code
                response = random.choice(brankos_responses)
                await channel.send(response)
                messages = 0 # Reset count

但是因为它再次运行,它再次重置为messages = 1,如果我将messages = 0放在函数之外它不起作用。

【问题讨论】:

您可以使用一种非常常见的设计模式。设置允许下一步操作的时间。尝试执行该操作时,请检查当前时间是否早于该设置时间。如果是这样,请取消该操作。否则,执行该操作并将下一个允许的时间重置为未来不久的某个时间 这听起来合乎逻辑,但我什至不知道如何开始尝试这个想法:\ 【参考方案1】:

如果您的目的纯粹是为了让机器人按时冷却,那么您可以执行以下操作:

class ***(commands.Cog):
    def __init__(self, client):
        self.client = client
        self.last_timeStamp = datetime.datetime.utcfromtimestamp(0)

    @commands.Cog.listener()
    async def on_message(self, message):
        time_difference = (datetime.datetime.utcnow() - self.last_timeStamp).total_seconds()
        if time_difference < 120:
            # Don't do anything and return
            return

        else:
            #Do things
            self.last_timeStamp = datetime.datetime.utcnow()

这是在 Cog 中完成的,因此如果您想在 Cog 之外使用它,可能需要进行更改。 如果您只想计算消息的数量,那么只需有一个 int 变量,每条消息递增它并更改 if 语句。

【讨论】:

嘿!谢谢你的回答,是的,我试过你说的最后一句话。我用我的新代码更新了我的问题。但它不起作用,你能看一下吗? 检查您的代码是否真的通过了 if 语句。打印出user_ID和user_list列表 我刚看到你的编辑。将messages = 0 int 放在函数外部,然后在函数内部将global messages 放在messages+=1 之前

以上是关于如何限制 on_message 回复(Discord Python 机器人)的主要内容,如果未能解决你的问题,请参考以下文章

在 discord.py 中发送其他人看不到的回复

如何在“on_message”中提及某人

Tornado websocket 客户端:如何异步 on_message? (从未等待协程)

如何限制龙卷风 websocket 消息大小

如何让机器人休眠并停止响应命令(或 on_messages)

如何在 discord.py 中将 on_message 与 sqlite3 集成?