Search code examples
pythonpython-3.xdiscorddiscord.py

How to make Discord bot edit it's own previous message via a command?


I can't seem to figure out how to make a user's command edit the Discord bot's previously sent message. I am using discord.py.

I'm creating a bot that reserves players for nations in a grand-strategy video game we play. The bot will create a message with a list of all the nations available, and the Discord users must do a command such as '!reserve (X Nation)', and the bot will update their list message to include the user's chosen nation and their username after it.

The problem is that, the only function I can think of to achieve the editing of the bot's message is a 'fetch_message(ID)' function. But this won't work, because the bot will remove their list message after our games are over, and re-post it for the next game. So the message ID will be changing constantly.

I need a '!reserve (X Nation)' command that immediately understands where the desired list it's wishing to affect is located at, and successfully edit that list.

Here's my code so far:

import discord
from discord import app_commands
from discord.ext import commands
from discord.utils import get

intents = discord.Intents.all()
client = commands.Bot(command_prefix='!', intents = intents)
tree = app_commands.CommandTree

@client.event
async def on_ready():
    print("The bot is now ready")
    try:
        synced = await tree.sync(guild=discord.Object(id=1210361385112961024))
        print(f"Synced {len(synced)} command(s)")
    except Exception as e:
        print(e)

@client.command()
async def host(ctx):
    message = await ctx.send("Reservations :star: USA")

@client.command()
async def reserve(ctx):
    channel = client.get_channel(CHANNEL ID)
    message = await client.fetch_message() #A fetch message function won't work as the message it's going to be fetching from will have a different ID every few days.
    await message.edit(content="Reservations :star: USA :star: Japan")

Solution

  • You need to store the message ID somewhere, preferably a database but if it's just going to be the ID and nothing else, you can use a text file to store the message ID and retrieve it when the reserve command gets invoked.

    import discord
    from discord import app_commands
    from discord.ext import commands
    from discord.utils import get
    
    intents = discord.Intents.all()
    client = commands.Bot(command_prefix='!', intents = intents)
    tree = app_commands.CommandTree
    
    @client.event
    async def on_ready():
        print("The bot is now ready")
        try:
            synced = await tree.sync(guild=discord.Object(id=1210361385112961024))
            print(f"Synced {len(synced)} command(s)")
        except Exception as e:
            print(e)
    
    @client.command()
    async def host(ctx):
        message = await ctx.send("Reservations :star: USA") # If this is the message, then store its ID in a file
        with open("message.txt", "w") as f:
            f.write(str(message.id))
    
    @client.command()
    async def reserve(ctx):
        channel = client.get_channel(CHANNEL_ID)
        # Then, later on in the command
        with open("message.txt", "r") as f:
            message_id = int(f.read())
        message = await channel.fetch_message(message_id) # There you have the message.
        await message.edit(content="Reservations :star: USA :star: Japan")