Discord.py count reactions on a message

11,842

Solution 1

You need to use the ids in the payload to get the Message object of the message and then check the count attribute of the appropriate Reaction from Message.reactions:

from discord.utils import get

@client.event
async def on_raw_reaction_add(payload):
    if payload.channel_id == 614467771866021944:
        if payload.emoji.name == "🔁":
            channel = client.get_channel(payload.channel_id)
            message = await channel.fetch_message(payload.message_id)
            reaction = get(message.reactions, emoji=payload.emoji.name)
            if reaction and reaction.count > 4:
                await message.delete()

Solution 2

How Do I Get a Custom Emoji Count in Discord.py?

Patrick Haugh's answer works for native emojis, but I wanted to add an additional answer to explain getting the count attribute for custom emojis since Discord.py defines these attributes differently. The solution itself is easily applies and you can skip to the solution example below if you don't want to read the explanation.

The emoji attribute for custom emoji reactions contains a nested set of attributes instead of the single value that native emojis have. Say there is a reaction using a custom emoji named kirby. If you were to print message.reactions, it would output something like this (assuming you have already appropriately defined message):

[<Reaction emoji='🔁' me=True count=1>, <Reaction emoji=<Emoji id=900000000123456789 name='kirby' animated=False managed=False> me=False count=1>]

The first reaction has the emoji itself as the attribute emoji.
So when you call get(message.reactions, emoji=payload.emoji.name) it is just passing the values like so: get(message.reactions, emoji='🔁')

Now look at the emoji attribute for the custom emoji called kirby. Instead of using the emoji as the value here, you will see four attributes nested as the value for the emoji attribute. The attributes are id, name, animated, managed. Your custom emoji only exists on your server. That means you can't simply paste the emoji into your bot's code the way you can do with native emojis.

You also can't pass the name value alone as payload.emoji.name will do. Passing emoji='kirby in the get() utility will cause it to return None because it will not be able to match kirby in the emoji attribute.

If nothing is found that matches the attributes passed, then None is returned.1

Solution

The simplest way I've found is to drop the .name attribute and just pass payload.emoji as your value. Discord.py seems to prefer working with this name:id format for custom emojis. In this example, get() will match the emoji attribute to a string of nested values <kirby:900000000123456789>

Now the get() utility will be able to match and return the reaction which includes the count attribute you are looking to work with. This example assumes you have already defined message:

  if payload.emoji.name == 'kirby':
      # payload.emoji will be defined as <kirby:900000000123456789>
      reaction = discord.utils.get(message.reactions, emoji=payload.emoji)
      # Now you can get reaction.count for the custom emoji!
      print(f'The reaction count for this custom emoji is: {reaction.count}.')
Share:
11,842

Related videos on Youtube

Tutez
Author by

Tutez

Teenager passionate about computer science trying to learn programming (:

Updated on June 04, 2022

Comments

  • Tutez
    Tutez almost 2 years

    I'm doing a bot discord and I'd like my bot to count the number of reactions to a message before deleting him

    @client.event
    async def on_raw_reaction_add(payload):
        if payload.channel_id == 614467771866021944:
            if payload.emoji.name == "🔁":
                # if number of reactions > 4:
                # delete the message
    
    • Patrick Haugh
      Patrick Haugh over 4 years
      Are you looking for 4 times that reaction has been used, 4 reactions total, or 4 unique reactions?
    • Tutez
      Tutez over 4 years
      5 reactions "🔁"
  • Tutez
    Tutez over 4 years
    don't work :/ i.imgur.com/8J0nrQC.png I don't have errors
  • Patrick Haugh
    Patrick Haugh over 4 years
    Try emoji=payload.emoji.name. Failing that, try printing all of the reaction.emoji in message.reactions and we can see what's going on.
  • Tutez
    Tutez over 4 years
    how can I do the same thing but with custom emote ?
  • Patrick Haugh
    Patrick Haugh over 4 years
    In that case, payload.emoji.name will be the name of the custom emoji. See the documentation of PartialEmoji