Search code examples
discord.pyembed

discord.py embed message doesn't update


sorry for my english^^

I'm doing a discord bot in python (i'm a beginner in python) and i'm doing it step by step. I had some GREAT help here and I want again a little help if possible :)

I don't know how to do it correctly, but i try to edit the embed with the @user who click on the emoji. If someone click on the "tank smiley", it edit the embed on the field "tank", and i want that the 5 fields (1 tank, 1 heal, 3 dps) can be fill.

Tell me if it's possible, and if i'm trying right with discord.edit ?

Thanks :)

# bot.py
import os
from discord.ext import commands
from discord.ext.commands import Bot
import discord
from discord import Embed, Emoji
from dotenv import load_dotenv
import random
import asyncio

load_dotenv()
TOKEN = os.getenv('DISCORD_TOKEN')
GUILD = os.getenv('DISCORD_GUILD')

# On définit le préfixe
bot = commands.Bot(command_prefix='!')

# On print les infos après le lancement du bot et
# on affiche un message d'activité pour le bot.
@bot.event
async def on_ready():
    for guild in bot.guilds:
        if guild.name == GUILD:
            break

    print(
        f'{bot.user} is connected to the following guild:\n'
        f'{guild.name}(id: {guild.id})'
    )
    await bot.change_presence(activity = discord.Activity(
                          type = discord.ActivityType.watching,
                          name = 'Sylàn être mauvais'))

# Commande mm+ dans un embed
@bot.command()
async def mm(ctx, arg, arg2, arg3, help="permet de créer une invit mm+ avec !mm clé niveau heure. Exemple: !mm Boralus +14 21h00"):
      embed = discord.Embed(title="Inscription pour {} en {} vers {}" .format(arg, arg2, arg3), description="Composition du groupe") #,color=Hex code
      embed.add_field(name="Tank", value="<:tank:761252435720667157>tank\n", inline = False)
      embed.add_field(name="Heal", value="<:heal:761252937548169246>heal\n", inline = False)
      embed.add_field(name="Dps1", value="<:dps:761252937066217512>dps1\n", inline = False)
      embed.add_field(name="Dps2", value="<:dps:761252937066217512>dps2\n", inline = False)
      embed.add_field(name="Dps3", value="<:dps:761252937066217512>dps3\n", inline = False)

      sent = await ctx.send(embed=embed)
      emojis=['<:tank:761252435720667157>', '<:heal:761252937548169246>', '<:dps:761252937066217512>']
      for emoji in emojis:
            await sent.add_reaction(emoji)
             
@bot.event
async def on_raw_reaction_add(payload):
    channel = bot.get_channel(payload.channel_id)
    message = await channel.fetch_message(payload.message_id)
    if message.author != payload.member:
        return

    reaction = discord.utils.get(message.reactions, emoji=payload.emoji.name)
    embed  = message.embeds[0]
    tank = bot.get_emoji(761252435720667157)
    heal = bot.get_emoji(761252937548169246)
    dps = bot.get_emoji(761252937066217512)

    if reaction == 'tank':
        embed.set_field_at(1, name='Tank', value='Modified value')
    elif reaction == 'heal':
        embed.set_field_at(2, name='Heal', value='Modified value')
    elif reaction == 'dps':
        embed.set_field_at(3, name='Dps', value='Modified value')    
    await message.edit(embed=embed)


#Message d'erreur si mauvaise utilisation
@mm.error
async def mm_error(ctx, error):
    if isinstance(error, commands.MissingRequiredArgument):
                await ctx.send("Merci d'utiliser le bot avec !mm clé niveau heure. Exemple: !mm Boralus +14 21h00")
# EOF

bot.run(TOKEN)

Solution

  • You're on the right track with the Message.edit() method.
    Since you're just asking for some code, here's a simple example of what you want to do:

    @bot.command()
    async def send_embed(self, ctx):
        embed = (Embed(name='A nice embed')
                 .add_field(name='Field 1', value='Value 1')
                 .add_field(name='Field 2', value='Value 2'))
        emojis = ['1️⃣', '2️⃣']
        message = await ctx.send(embed=embed)
        for emoji in emojis:
            await message.add_reaction(emoji)
    
    @bot.event
    async def on_raw_reaction_add(self, payload):
        if payload.member.bot:
            return
        channel = bot.get_channel(payload.channel_id)
        message = await channel.fetch_message(payload.message_id)
        embed, emojis  = message.embeds[0], ['1️⃣', '2️⃣']
        index = emojis.index(payload.emoji.name)
    
        embed.set_field_at(index, name=embed.fields[index].name, value=payload.member.mention, inline=False)
        await message.edit(embed=embed)
    

    The advantage with on_raw_reaction_add is that you don't need that while loop anymore, however, it would be triggered if you add a reaction to any message so you'd need to store the message id and compare it. You decide what you prefer :)

    References :