【问题标题】:Discord.py list users in a message when reactionDiscord.py 在消息中列出用户时的反应
【发布时间】:2020-11-29 20:54:11
【问题描述】:

我已经尝试解决一个问题好几天了。我想发送一个 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

【问题讨论】:

  • 你打算如何工作?就像现在一样,它正在将 DM 中的嵌入发送给使用该命令的人。是否应该在频道中发送嵌入内容并在会员做出反应时进行更新?
  • 我在反应前后添加了 2 张图像,一个示例。我将列出所有对我的消息有反应的用户

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


【解决方案1】:

如果我理解正确,你想要这样的东西。我一直尝试将 cmets 放入代码中,以便您更好地了解发生了什么。

由于代码是现在的,如果用户删除反应,它不会更新。如果 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

【讨论】:

  • 它看起来不错。但我没有使用或拥有与旧版本一起使用的 ctx 样式。我会尝试在我的鳕鱼上添加这个并提供证据,或者你会在没有 ctx 的情况下为我做这个?
  • @KoriLP 恐怕我还没有使用过旧版本的 discord.py。您是否尝试过解决方案并查看显示的错误?改过来应该不会太难。
  • 它现在的工作就像您的版本的魅力一样。唯一的问题是刷新,当我删除 ✅
  • @KoriLP 我知道asyncio.wait 有一种方法可以检查多个事件,但这不会输出超时错误,因此它会一直循环。而且我不熟悉它,也不知道如何停止。两种不同的方法:不要等待反应,只需循环一个计时器并每秒更新一次嵌入,或者在您的异常中,再次获取消息,更新用户列表并再次嵌入和编辑消息(不会提供“实时”更新,但会提供最后一个更新的嵌入)
  • 我添加了我的最终版本
【解决方案2】:

你要找的是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

【讨论】:

  • 您好,首先感谢您的回答,我已经添加了 2 张前后的图片。我的想法是:我将在用户做出反应后编辑消息并将它们添加到列表中我找到了一个示例但我不使用 ctx 并且示例不完整:stackoverflow.com/questions/61849675/…
  • 你说它不能使用上下文是什么意思?它出什么问题了?请为您的问题添加更多代码,以便我为您提供帮助。
猜你喜欢
  • 1970-01-01
  • 2020-03-28
  • 1970-01-01
  • 2020-11-07
  • 2021-01-31
  • 2021-08-30
  • 1970-01-01
  • 2021-12-15
  • 1970-01-01
相关资源
最近更新 更多