I’m working on a discord.py bot for managing game reservations but I’m stuck on something. The bot needs to post a message showing available countries, then when users type commands like !claim CountryName, it should update that same message.
My bot handles reservations for strategy games. It posts a list of nations players can pick from. When someone uses a command to pick a nation, the bot should modify its previous message to show that country is taken by that user.
The issue is I don’t know how to reference the bot’s last message without hardcoding the message ID. The message gets deleted and recreated regularly so the ID keeps changing.
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, Italy")
@bot.command()
async def claim(ctx, *, country_name):
# Need to find and edit the nations list message here
# But how do I get the message without knowing its ID?
target_msg = await ctx.fetch_message(???) # This won't work since ID changes
await target_msg.edit(content=f"Available Nations: Germany, Italy\nTaken: France - {ctx.author}")
How can I make the claim command find and update the right message automatically?
just assign the message to a variable when u send it, then use that var later. you’ve already got game_msg = await ctx.send(...) in ur start_game function - make it global or pass it around. don’t overcomplicate things with db stuff unless u need it to survive restarts.
Try a class-based approach - it’s way cleaner. Make a GameSession class that holds both the message object and game state. When you create it in start_game, save the message as an attribute. Then your claim command can just grab that stored message instead of searching for it or hardcoding IDs. You get better organization and can easily add stuff like multiple games per server. Just catch NotFound exceptions when editing in case someone deletes the original message. This scales much better than global dictionaries as your bot gets bigger.
Use a dict to track game messages per channel. Set up game_messages = {} then in start_game do game_messages[ctx.channel.id] = game_msg. For your claim command, grab it with target_msg = game_messages.get(ctx.channel.id) and check it’s not None before editing. Works great unless ur bot restarts constantly.
You can skip storing IDs and just search the channel’s message history for your bot’s last message. When someone runs the claim command, loop backwards through recent messages until you find the one from your bot with the nations list.
@bot.command()
async def claim(ctx, *, country_name):
async for message in ctx.channel.history(limit=50):
if message.author == bot.user and "Available Nations:" in message.content:
# Found the target message
await message.edit(content=f"Available Nations: Germany, Italy\nTaken: France - {ctx.author}")
return
await ctx.send("Could not find game message to update")
This works even after bot restarts since you’re not relying on stored data. Just make sure your nations message has unique text that other bot messages don’t use. The limit stops it from searching too far back in busy channels.
Storing message IDs in memory or a database works for simple cases, but what happens when your bot restarts or you need to scale across multiple servers?
I hit this exact problem building management bots at work. You’re managing state manually when you could automate the whole thing.
Latenode handles this way better. Set up a workflow that triggers on claim commands. It stores game states in a database, tracks which messages need updates, and auto-edits Discord messages through the API.
Best part? You can add logic for preventing duplicate claims, handling timeouts, and resetting games on schedule. No more worrying about message IDs or losing data when your bot restarts.
I use this pattern for all my Discord automation now. Way cleaner than cramming everything into bot code.
Searching message history works but gets painfully slow in busy channels. And you’re doing it every single time someone claims a country.
I dealt with this exact nightmare managing tournament brackets through Discord bots. Tracking dynamic messages that need constant updates is a pain when you’re doing everything manually.
What saved me was moving the logic outside the bot completely. Latenode watches for Discord commands, keeps your game state clean, and handles all the message editing automatically.
Just set up a webhook that fires when someone uses the claim command. Latenode stores which message to update, validates the claim, updates your game data, then edits the Discord message through the API.
You get proper error handling when messages get deleted, automatic retries, and zero performance hits from searching message history. Plus you can add stuff like auto-expiring unclaimed countries or blocking duplicate reservations without making your bot code a mess.
Survives bot restarts and scales way better than stuffing everything into dictionaries or databases you have to babysit.
Go with database storage for production bots. I’ve been running game management bots for two years and memory storage screwed me over constantly. Every restart or update wipes everything, and that happens way more than you think.
Set up a basic SQLite database with tables for active games and message IDs. When start_game runs, throw the message ID in there with the channel. Your claim command just queries the database for the message ID, then edits normally.
# After sending the game message
cursor.execute("INSERT OR REPLACE INTO active_games (channel_id, message_id) VALUES (?, ?)",
(ctx.channel.id, game_msg.id))
# In claim command
result = cursor.execute("SELECT message_id FROM active_games WHERE channel_id = ?",
(ctx.channel.id,)).fetchone()
if result:
target_msg = await ctx.fetch_message(result[0])
Survives bot restarts and makes adding stuff like game timeouts or multi-server support dead simple later. Don’t forget to clean up finished games though.