Discord.py 反应时在消息中列出用户

Discord.py list users in a message when reaction

几天来我一直在努力解决一个问题。我想发送 embet naricht,一旦有人做出反应,就应该对其进行编辑。

这里是我截取的代码:

embed = discord.Embed(title='General Information', color=16769251)
embed.set_footer(text='General information')
embed.set_thumbnail(url=message.guild.icon_url)
embed.add_field(name='Text Header ', value=all_lines[1], inline=False)
embed.add_field(name='Text Header 2: ', value=all_lines[2], inline=False)
embed.add_field(name='Accepted Users: ', 'HERE ALL USERS WITH ✅', inline=False)
mess = await message.send(embed=embed)
await mess.add_reaction('✅')
await mess.add_reaction('❌')

我已经尝试了很多东西,但不幸的是没有成功我认为真的把所有东西都放在这里太多了我仍然希望有人可以帮助我

举个例子: 之前(无反应)

https://i.gyazo.com/1518bc2bfe8b55e2e790ff6481c261f7.png

反应后:

https://i.gyazo.com/8bf97513e1eaf567ca9dda66f54fa2f0.png

有 1 个小刷新错误的最终版本:

async def ReportRaid(self, message, bot):
    name = message.author
    if message.author.bot:
        return
    else:
        await message.delete()
    args = message.content.split(' ')
    # raid <type> <name> <setting> <min>
    #   0     1      2       3       4
    if args[0] == "/raid" or args[0] == "/Raid":
        embed = discord.Embed(title='Raid meldung von ' + str(message.author.display_name))
        embed.add_field(name='Raid Typ: ', value=args[1], inline=True)
        embed.add_field(name='Name: ', value=args[2], inline=True)
        embed.add_field(name=settings.RaidSetings[args[3]], value=args[4] + " Minuten", inline=True)
        embed.add_field(name='Zusagen:', value='Keine Zusagen', inline=True)
        if not args[2].lower() in pkm.pokeDir[args[1].lower()]:
            await message.channel.send('Das pokemon konnte nicht gefunden werden.', delete_after=30.0)
            return
        else:
            embed.set_thumbnail(
                
                url=settings.ServerSettings["ImageURL"] + pkm.pokeDir[args[1].lower()][args[2].lower()] + '.png')
        try:
            with open('accounts/Ac' + str(name) + '.txt', "r") as fp:
                all_lines = fp.readlines()
                embed.set_footer(text='Trainer name: {} \nTrainer Code: {}'.format(all_lines[1], all_lines[3]))
                tgName = all_lines[3]
        except IOError:
            embed.set_footer(text='Keine Informationen gefunden')
            tgName = "Keinen Trainer code gefunden"
        channel = bot.get_channel(int(await guild_setings.LoadGuildSettings().get_raid_channel(message)))
        mess = await channel.send(embed=embed, delete_after=int(args[4]) * 60)
        tg.TelegramBot(message, '**\nRaid Typ: ' + args[1] + "\nName: " + args[2] + "\n" + settings.RaidSetings[args[3]] + " " + args[4] + ' Minuten\nTriainer Code: ' + tgName + '\nRaid Meldung von: ' + str(message.author.display_name)).SendToTelegramm()
        re_time = int(args[4]) * 60
        emoji_list = ['✅', '❌']
        for i in emoji_list:
            await mess.add_reaction(i)
        while True:
            users = ""
            try:
                reaction, user= await bot.wait_for("reaction_add", timeout=re_time)
                if str(reaction) == '✅':
                    mess = await channel.fetch_message(mess.id)
                    reaction_list = mess.reactions

                    for reactions in reaction_list:
                        if str(reactions) == "✅":
                            user_list = [user async for user in reactions.users() if user != bot.user]
                            for user in user_list:
                                users = users + user.mention + "\n"
                    embed_1 = discord.Embed(title='Raid meldung von ' + str(message.author.display_name))
                    embed_1.add_field(name='Raid Typ: ', value=args[1], inline=True)
                    embed_1.add_field(name='Name: ', value=args[2], inline=True)
                    embed_1.add_field(name=settings.RaidSetings[args[3]], value=args[4] + " Minuten", inline=True)
                    embed_1.add_field(name='Zusagen:', value=users, inline=True)
                    if not args[2].lower() in pkm.pokeDir[args[1].lower()]:
                        await message.channel.send('Das pokemon konnte nicht gefunden werden.', delete_after=30.0)
                        return
                    else:
                        embed_1.set_thumbnail(
                            
                            url=settings.ServerSettings["ImageURL"] + pkm.pokeDir[args[1].lower()][args[2].lower()] + '.png')
                    try:
                        with open('accounts/Ac' + str(name) + '.txt', "r") as fp:
                            all_lines = fp.readlines()
                            embed_1.set_footer(text='Trainer name: {} \nTrainer Code: {}'.format(all_lines[1], all_lines[3]))
                    except IOError:
                        embed_1.set_footer(text='Keine Informationen gefunden')
                    await mess.edit(embed = embed_1)
            except asyncio.TimeoutError:
                break

你要找的是bot.wait_for,这里是一个简单的例子

@bot.command()
async def react(ctx):
    # Sending the message
    message = await ctx.send('React with ✅')

    def check(reaction, user):
        # Checking if the user that reacted is the same as the one that invoked the command
        # also checking if the reaction is `✅` and if the reacted message is the one sent before
        return user == ctx.author and str(reaction) == '✅' and reaction.message == message

    try:
        # Waiting for the reaction
        reaction, user = await bot.wait_for('reaction_add', check=check, timeout=60.0)
    except asyncio.TimeoutError:
        # If the timeout is over, deleting the message
        await message.delete()
        await ctx.send('Timeout is over')
    else:
        # If the reaction is not the one we're waiting for, send this
        await ctx.send('Bad reaction')

Reference

如果我没理解错的话,你想要这样的东西。我一直在尝试在代码中添加注释,以便您可以更好地理解发生了什么。

由于代码是正确的,如果用户删除反应,它不会更新。如果 user_1 和 user_2 添加反应,然后 user_1 删除反应,它们仍然会显示,当 user_3 添加反应时,它将更新为仅显示 user_2 和 user_3

您也可以在异常中的 *** 之间添加代码,以便在循环结束时最后一次更新嵌入。

另一件事是我不知道你的 all_lines 是什么,所以我在测试期间把它当作一个字符串。

@client.command() # Correct this according to your code, if you're using bot or client
async def rtest(ctx):
    message = ctx.message

    # At first we create create the embed
    embed = discord.Embed(title='General Information', color=16769251)
    embed.set_footer(text='General information')
    embed.set_thumbnail(url=message.guild.icon_url)
    embed.add_field(name='Text Header ', value=all_lines[1], inline=False)
    embed.add_field(name='Text Header 2: ', value=all_lines[2], inline=False)
    embed.add_field(name='Accepted Users: ', value='HERE ALL USERS WITH ✅', inline=False)
    mess = await ctx.send(embed=embed)

    # And add our reactions to the embed
    emoji_list = ['✅', '❌']
    for i in emoji_list:
        await mess.add_reaction(i)

    # Create a while loop that will wait for users to react
    while True:
        users = "" # Create empty string that we need later
        try:
            reaction, user= await client.wait_for("reaction_add", timeout=60)

            # Check that if the reaction added is ✅, and if it is:
            if str(reaction) == "✅":
                mess = await ctx.channel.fetch_message(mess.id) #*** Need to fetch message again to get updated reaction information
                reaction_list = mess.reactions 

                # Check our reactions on the message, get user list for the ✅ reaction, ignoring the bot
                for reactions in mess.reactions:
                    if str(reactions) == "✅":
                        user_list = [user async for user in reactions.users() if user != client.user]
                        # Update the users string, to add user that reacted
                        for user in user_list:
                            users = users + user.mention + "\n"
                
                # Create an updated embed with different name, it's the same as before, but with users in last field
                embed_1 = discord.Embed(title='General Information', color=16769251)
                embed_1.set_footer(text='General information')
                embed_1.set_thumbnail(url=message.guild.icon_url)
                embed_1.add_field(name='Text Header ', value=all_lines[1], inline=False)
                embed_1.add_field(name='Text Header 2: ', value=all_lines[2], inline=False)
                embed_1.add_field(name='Accepted Users: ', value='HERE ALL USERS WITH ✅\n'+users, inline=False)

                await mess.edit(embed = embed_1) # Edit message to be the updated embed
        #***        

        # End the loop after the set amount of time (from timeout earlier)
        except asyncio.TimeoutError:
            break