SpaceTurtle0
SpaceTurtle0

Reputation: 161

How can I get everyone who reacted to a certain reaction into a list?

Basically, I'm trying to collect everyone who reacted to a certain message into a list so I could see who was coming to an event. I know I could just look at everyone who reacted manually but I would like to expand on this later when I get the time.

My plan was to add 2 separate commands, one being the command to start the reaction and the other one was to state everyone who reacted (list). But so far I'm just stuck with this single command which doesn't work. Any tips on how I could rework this into the 2 commands?

Anyway, so far I have this.

@client.command(pass_context = True)
async def react(ctx):

    msg = await ctx.send('React to this if you will be free for the event!')
    await msg.add_reaction("✅")
    await asyncio.sleep(5)
    cache_msg = discord.utils.get(client.messages, id = msg.id)
    for reactor in cache_msg.reactions:
        reactors = await client.get_reaction_users(reactor)
        for member in reactors:
            await ctx.send(member.name)

The full traceback:

Traceback (most recent call last):
  File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/ext/commands/bot.py", line 903, in invoke
    await ctx.command.invoke(ctx)
  File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/ext/commands/core.py", line 859, in invoke
    await injected(*ctx.args, **ctx.kwargs)
  File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/ext/commands/core.py", line 94, in wrapped
    raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'Bot' object has no attribute 'messages'

Upvotes: 0

Views: 674

Answers (2)

AbdurJ
AbdurJ

Reputation: 1033

One important thing to remember is that message.reactions gives you the actual reaction, not the members. If you have multiple reactions, you get a list with multiple "reaction objects"

This is your option with everything within the same command.

@client.command()
async def react(ctx):
    msg = await ctx.send('React to this if you will be free for the event!')
    await msg.add_reaction("✅")
    await asyncio.sleep(5)
    
    # Easiest way of getting channel and message id
    channel = ctx.message.channel
    msg_id = msg.id

    # And since we have both channel and message id, we can:
    cache_msg = await channel.fetch_message(msg_id)

    # Now to get the reactions on the message and create
    # a list of users that reacted to a specific reaction
    # Also ignoring the bot
    for reactions in cache_msg.reactions:
        user_list = [user async for user in reactions.users() if user != client.user]
        for user in user_list:
            await ctx.send(user.name)

To do this in separate commands, you can store channel and message id as global variables, or in a separate file. Example with global variables.

react_channel = ""
cache_msg_id = ""

@client.command(pass_context = True)
async def react(ctx):
    msg = await ctx.send('React to this if you will be free for the event!')
    await msg.add_reaction("✅")
    global react_channel
    react_channel = ctx.message.channel
    global cache_msg_id
    cache_msg_id = msg.id
    
@client.command()
async def reactors(ctx):
    global react_channel
    global cache_msg_id
    
    cache_msg = await react_channel.fetch_message(cache_msg_id)
    for reactions in cache_msg.reactions:
        user_list = [user async for user in reactions.users() if user != client.user]
        for user in user_list:
            await ctx.send(user.name)

Upvotes: 1

Sachin Raja
Sachin Raja

Reputation: 304

You cannot search all the messages ever sent in the bot's servers for obvious reasons. You can get the message with the reactions using channel.fetch_message and passing in the id of the message your bot sent.

msg = await ctx.send("React to this if you will be free for the event!")
await msg.add_reaction("✅")
await asyncio.sleep(10)

new_message = await ctx.channel.fetch_message(msg.id)

for reaction in new_message.reactions:

    # only get the checkmark emoji users
    if (reaction.emoji == "✅"):

        # iterate to get all users except for bot
        async for user in reaction.users():
            if (user != bot.user):
                await ctx.send(user.name)

Upvotes: 0

Related Questions