pycord

Using Pycord, Editing an embed to include the new users who reacted to a message with a certain emoji


I'm trying to make a starboard-like cog in my bot.

Say a message receives one "star" emoji reaction, the bot will take the message and embed it in the starboard channel, the embed shows the content, the channel, and the user who starred it.

However, when the message receives more than one reaction, can I edit the embedded message to show the additional users?

    @commands.Cog.listener()
    async def on_raw_reaction_add(self, payload):
        if str(payload.emoji) == "\U00002B50":
            channel = self.bot.get_channel(payload.channel_id)
            message = await channel.fetch_message(payload.message_id)

            user = self.bot.get_user(payload.user_id)
            if user.bot:
                return
            
            reactions = discord.utils.get(message.reactions, emoji=payload.emoji.name)
            if reactions and reactions.count == 1:
                starboard_channel_id = 1141847109528735866
                starboard_channel = self.bot.get_channel(starboard_channel_id)

                if starboard_channel:
                    reacted_users = await reactions.users().flatten()
                    mentions = ' '.join([u.mention for u in reacted_users])
                    print(mentions)
                
                if starboard_channel:
                    embed =  discord.Embed(description=message.content,color=discord.Color.blurple())
                    embed.set_author(name=message.author.display_name)
                    embed.add_field(name="Starred by", value=mentions, inline=True)
                    embed.add_field(name="Starred in", value=channel.mention, inline=True)
                    embed.add_field(name="Jump to message", value=f"[Click here]({message.jump_url})", inline=True)
                    embed.set_thumbnail(url=message.author.avatar)
                    await starboard_channel.send(embed=embed)
                    
                    if reactions and reactions.count > 1:
                        updated_users = await reactions.users().flatten()
                        updated_mentions = ' '.join([u.mention for u in updated_users])
                        print(updated_mentions)

                        embed_new = discord.Embed(description=message.content,color=discord.Color.blurple())
                        embed_new.set_author(name=message.author.display_name)
                        embed_new.add_field(name="Starred by", value=updated_mentions, inline=True)
                        embed_new.add_field(name="Starred in", value=channel.mention, inline=True)
                        embed_new.add_field(name="Jump to message", value=f"[Click here]({message.jump_url})", inline=True)
                        embed_new.set_thumbnail(url=message.author.avatar)
                        await starboard_channel.edit(embed=embed_new)

I tried adding print statements to print the initial mention of the user who starred the message, and it prints. The second print statement does not, referring to the print(updated_mentions.


Solution

  • To edit the original message that contains the embed you would need to store the message ID of the starred message along with the message ID of the starboard message. The best way to do this is with a database. When using a database you should ensure that the library you use to interact with the database is async compatible otherwise it will block your bot. When a user adds the first star you need to save the ID of the message you send in the starboard channel (The discord.Message object is returned by the send function). When more stars are added you just need to fetch the ID and edit the message with get_partial_message and PartialMessage.edit

    The reason it does not print when a second user stars the message is due to you first checking if the reaction count is 1 in this line if reactions and reactions.count == 1:. Then your code to check if it is greater than 1 is within the if statement. This looks like it is just an indentation issue.