【问题标题】:Python Bot send message in orderPython Bot按顺序发送消息
【发布时间】:2018-11-25 12:36:13
【问题描述】:

在 Discord 中,发送消息有 2000 个字符的限制,因此我们需要拆分并发送多条消息。我使用下面的代码,它可以工作,但是消息没有按指定的顺序发送,所以我在每条消息之后都使用了sleep()。现在它可以工作了,但有时消息仍然不符合顺序。由于顺序混乱,阅读长消息时会变得混乱。

@bot.command(pass_context=True)
async def ping(ctx):
    msg = "Message 1".format(ctx.message)
    await bot.say(msg)
    await sleep(.5)

    msg = "Message 2".format(ctx.message)
    await bot.say(msg)
    await sleep(.5)

    msg = "Message 3".format(ctx.message)
    await bot.say(msg)
    await sleep(.5)

    msg = "Message 4 {0.author.mention}".format(ctx.message)
    await bot.say(msg)

我需要在每条消息之后检查发送的消息,然后它应该在最后一条消息之后发送第二条消息。或者有没有其他解决方案来解决这个问题?

【问题讨论】:

    标签: python python-3.x discord discord.py


    【解决方案1】:

    只需在消息之间添加一点延迟:

    from asyncio import sleep
    
    @bot.command(pass_context=True)
    async def ping(ctx):
        msg = "Message 1 {0.author.mention}".format(ctx.message)
        await bot.say(msg)
        await sleep(.5)
    
        msg = "Message 2 {0.author.mention}".format(ctx.message)
        await bot.say(msg)
        await sleep(.5)
    
        msg = "Message 3 {0.author.mention}".format(ctx.message)
        await bot.say(msg)
        await sleep(.5)
    
        msg = "Message 4 {0.author.mention}".format(ctx.message)
        await bot.say(msg)
    

    【讨论】:

    • @Demotry 看起来像是您的 on_command_error 协程中的问题。
    • 嗨@Patrick 我更新了on_command_error,这是我为上面的commands.CommandInvokeError 添加的。
    • 您可能应该问一个单独的问题。当你这样做时,请说明exceptions 是什么以及它来自哪里
    • 什么是exceptions.Halt?如果您取消注册您的on_command_error,(只需注释掉@bot.event)这将如何改变您遇到的错误?
    • 刚刚删除了所有on_command_error 现在当我使用await sleep(.5) 运行命令时,它给出了我在上面添加的错误。
    【解决方案2】:

    这似乎是一项简单的任务,但实际上相当复杂。也可能会推荐使用bot.wait_for_message(...),但该逻辑存在漏洞(机器人发送消息wait_for_message 已准备好),因为它不适合执行您的任务。

    我现在能想到的最好的方法是制作一个自定义的未来事件,并在发送消息后添加wait_for。未来应该注册一个on_message 事件来检查机器人的消息是否已发送。

    import asyncio
    
    def wait(check):
        f = asyncio.Future(loop=bot.loop)
    
        async def _wait(future, check):
            @bot.listen()
            async def on_message(msg):
                if check(msg):
                    bot.remove_listener(on_message)
                    future.set_result(msg)
    
        asyncio.ensure_future(_wait(f, check), loop=bot.loop)
        return f
    
    def ping_check(content):
        def check(msg):
            if msg.content == content and msg.author == bot.user:
                return True
            return False
        return check
    
    @bot.command(pass_context=True)
    async def ping(ctx):
        msg = "Message 1 {0.author.mention}".format(ctx.message)
        f = wait(ping_check(msg))
        await bot.say(msg)
        await asyncio.wait_for(f, None, loop=bot.loop)
    
        msg = "Message 2 {0.author.mention}".format(ctx.message)
        f = wait(ping_check(msg))
        await bot.say(msg)
        await asyncio.wait_for(f, None, loop=bot.loop)
    
        msg = "Message 3 {0.author.mention}".format(ctx.message)
        f = wait(ping_check(msg))
        await bot.say(msg)
        await asyncio.wait_for(f, None, loop=bot.loop)
    
        msg = "Message 4 {0.author.mention}".format(ctx.message)
        f = wait(ping_check(msg))
        await bot.say(msg)
        await asyncio.wait_for(f, None, loop=bot.loop)
    

    我进一步编辑了这个解决方案,加入了check(),这使得wait() 函数更加灵活,删除了之前的硬编码检查。

    【讨论】:

    • 是的,现在它按顺序发送消息。如果我对这个问题有任何需要,我会发消息给你。谢谢兄弟...
    猜你喜欢
    • 2016-09-06
    • 2021-02-05
    • 1970-01-01
    • 2018-12-24
    • 1970-01-01
    • 2018-12-17
    • 1970-01-01
    • 2019-03-03
    • 1970-01-01
    相关资源
    最近更新 更多