discord.py 同时向多人发送消息并接收他们的输入

时间:2021-03-12 00:24:35

标签: python discord.py

我想做的事情:我正在用我的机器人制作一款反人类 (CAH) 游戏,与朋友们一起玩。为此,我希望尽可能在尽可能接近同一时间向所有玩家发送一条消息,而不是一个一个地向他们发送消息并等待某人的输入,然后再获得下一个人的输入。下面是我制作的一个简单直观的例子,以防混淆。

A visual example

我的问题:如何同时向多人发送消息并接收他们单独的输入?

代码

我尝试通过 ctx.invoke 使用多个命令将其分开,因此机器人会按每个人运行该命令。然而,机器人并没有按照我的预期执行操作,而是在单独浏览列表时向他们发送消息,而是在每个人之间停下来等待他们的输入,然后再将消息发送给下一个人。

@client.command() # part 1: beginning the command sequence
@commands.check(check_blacklist)
async def test(ctx, members: commands.Greedy[discord.Member]=None):
    if members != None:
        members.append(ctx.author)
        msg = ""
        for member in members:
            msg += f"\> {member.display_name}\n"
        await ctx.send(f"These people will be test: \n{msg}")
    else:
        await ctx.send("Nobody")
        return
    await ctx.invoke(client.get_command('test2'), members=members)


@client.command() # part 2: sending messages to each person to see if their dms are open
async def test2(ctx, members):
    for member in members:
        try:
            await member.send("wa")
            await ctx.send(f"Successful wa to {member.display_name}")
            await ctx.invoke(client.get_command('test3'), member=member)
        except:
            await ctx.send(f"{member.mention} has their dms closed or is a bot :pensive:")

@client.command() # part 3: receiving inputs from each person
async def test3(ctx, member:discord.Member):        
    def check(msg):
        return msg.author==member and str(msg.channel.type) == "private"
    await member.send("Please provide an input:")
    try:
        response = await client.wait_for('message', check=check, timeout=75)
    except:
        await ctx.send(f"{member.display_name} didn't respond :pensive:")
        return
    await ctx.send(f"{member.mention}: {response.content}")

1 个答案:

答案 0 :(得分:2)

我会使用不是命令的异步函数和 asyncio.gather

def is_dm_check(member):
    def inner_check(msg):
        return msg.author.id==member.id and msg.guild is None
    return inner_check

async def get_input(member):
    await member.send("Please provide an input:")
    return client.wait_for('message', check=is_dm_check(member), timeout=75)

@client.command()
async def play_game(ctx, members: commands.Greedy[discord.Member]=None):
    if not members:
        await ctx.send("No Players")
        return
    responses = asyncio.gather(*map(get_input, members))
    for member, response in zip(members, responses):
        await ctx.send(f"{member.mention}: {response.content}")