Search code examples
discord

Discord bot repeats the same function and it doesnt even post the embed and it repeats same reaction


`import discord
from discord.ext import commands

intents = discord.Intents.all()
bot = commands.Bot(command_prefix='!', intents=intents)

@bot.command(name='sendmessage')
async def send_message(ctx, *, message: str):
    for member in ctx.guild.members:
        if not member.bot:
            dm_channel = await member.create_dm()
            sent_message = await dm_channel.send(message)
            await sent_message.add_reaction("✅")
            await sent_message.add_reaction("❌")
            await sent_message.add_reaction("🟡")

@bot.event
async def on_raw_reaction_add(payload):
    if payload.member == bot.user:
        return

    guild = bot.get_guild(payload.guild_id)
    member = guild.get_member(payload.user_id)
    channel = bot.get_channel(payload.channel_id)
    message = await channel.fetch_message(payload.message_id)

    if message.author != bot.user:
        return

    log_channel = bot.get_channel(1095834015421972550)
    embed = discord.Embed(title="Reaction Log", color=0x00ff00)
    embed.add_field(name="User", value=f"{member.mention} ({member.id})", inline=True)
    embed.add_field(name="Reaction", value=payload.emoji.name, inline=True)
    embed.add_field(name="Roles", value=" ".join([role.mention for role in member.roles]), inline=False)
    embed.add_field(name="Nickname", value=member.nick, inline=True)
    embed.add_field(name="Joined At", value=member.joined_at.strftime("%Y-%m-%d %H:%M:%S"), inline=True)
    await log_channel.send(embed=embed)


it repeats it

i expect it to give me one reaction with the embed stated below and it repeats the same thing and i tried to debugg and it always repeats the reaction


Solution

  • The payload that you are receiving with on_raw_reaction_add appears to not provide you with the member as it is in a private dm. Instead you can use the user_id field to check if the user is not a bot. Then, you can use your guild id to get the member object instead of the user object. The code below shows the changes I made that fixes your issue.

    @bot.event
    async def on_raw_reaction_add(payload):
        member = bot.get_user(payload.user_id) # Using the user_id here
        if member == bot.user:
            return
    
        guild = bot.get_guild(GUILD_ID) # Since this is in a dm, use the integer value for your guild.
        member = guild.get_member(payload.user_id)
        channel = bot.get_channel(payload.channel_id)
        message = await channel.fetch_message(payload.message_id)
    
        if message.author != bot.user:
            return
    
        log_channel = bot.get_channel(CHANNEL_ID)
        embed = discord.Embed(title="Reaction Log", color=0x00ff00)
        embed.add_field(name="User", value=f"{member.mention} ({member.id})", inline=True)
        embed.add_field(name="Reaction", value=payload.emoji.name, inline=True)
        embed.add_field(name="Roles", value=" ".join([role.mention for role in member.roles]), inline=False)
        embed.add_field(name="Nickname", value=member.nick, inline=True)
        embed.add_field(name="Joined At", value=member.joined_at.strftime("%Y-%m-%d %H:%M:%S"), inline=True)
        await log_channel.send(embed=embed)
    

    I have tested these changes myself and it all appears to work as I think you intended, but if something is wrong let me know and I'll update my answer.