How can I update a Discord bot's last message using a command?

I’m trying to create a Discord bot that can modify its own messages when users run specific commands. The bot I’m building is for managing player reservations in strategy games we play together.

Here’s what I want to happen: The bot posts a message showing all available countries. When someone types a command like !claim Germany, the bot should update that original message to show that Germany is now taken by that user.

The tricky part is that I delete and recreate the main message regularly, so the message ID keeps changing. I can’t just hardcode a message ID because it won’t stay the same.

I’ve been trying to use fetch_message() but that requires knowing the exact message ID ahead of time. Is there a way to make the bot remember which message it should edit, or maybe find its most recent message in the channel?

Here’s what I have so far:

import discord
from discord.ext import commands

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

@bot.event
async def on_ready():
    print("Bot is online")

@bot.command()
async def start_game(ctx):
    game_msg = await ctx.send("Available Nations: France, Germany, Russia")

@bot.command()
async def claim(ctx, nation):
    # Need to find and edit the game message here
    # How do I get the message without hardcoding the ID?
    pass

Any ideas on how to track which message needs updating?

I’ve had good luck with a class that manages game state and message references. When your bot starts up, make a dictionary that maps channel IDs to their message objects:

class GameManager:
    def __init__(self):
        self.active_games = {}  # channel_id: message_object
    
    async def update_game_message(self, channel_id, new_content):
        if channel_id in self.active_games:
            await self.active_games[channel_id].edit(content=new_content)

This beats searching through message history since you keep direct references to the actual messages. Just update the dictionary entry when you recreate a message. I use this for tournament brackets and it handles the dynamic ID issue without constantly fetching message history.

Try ctx.channel.history() to grab the bot’s last message instead of storing IDs. Something like:

async for message in ctx.channel.history(limit=50):
    if message.author == bot.user:
        await message.edit(content="new content")
        break

This way you don’t need to worry about changing message IDs when you recreate stuff.

I faced a similar issue while developing a Discord bot for event coordination. One effective method is to store the message ID in a variable when you initially post the message. For instance, during your start_game() function, you can save the message ID like this: game_message_id = game_msg.id. Then, in your claim() function, you can retrieve and edit the message using await ctx.channel.fetch_message(game_message_id). If you want persistence across bot restarts, consider storing the IDs in a JSON file or a database. This way, you can update the stored ID anytime you recreate the message. Keeping track of pinned messages as a fallback can also be helpful, although it can clutter the channel if there are many pins.