Discord bot editing its own message by appending text using discord.py

I’m trying to build a Discord bot that can modify its previous messages by adding new content to them. The bot is for managing game reservations where players can claim different countries.

Here’s what should happen: The bot posts a list of available countries from a text file. When someone uses a command like !claim Germany, the bot should edit that original message and add the player’s name next to Germany in the list.

Original bot message:

Country Selection
Germany
France
Russia

After !claim Germany command:

Country Selection
Germany @player
France
Russia

I can get the message ID and fetch the message, but I’m stuck on how to modify just part of the content instead of replacing everything. Here’s my current code:

import discord
from discord.ext import commands

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

@bot.command()
async def setup(ctx):
    with open('countries.txt', 'r') as file:
        msg = await ctx.send(file.read())
    with open('msg_id.txt', 'w') as storage:
        storage.write(str(msg.id))

@bot.command()
async def claim_germany(ctx):
    channel_obj = bot.get_channel(CHANNEL_ID)
    with open("msg_id.txt", "r") as storage:
        saved_id = int(storage.read())
    original_msg = await channel_obj.fetch_message(saved_id)
    await original_msg.edit(content="NEW_CONTENT") # Need help here

bot.run(TOKEN)

Contents of ‘countries.txt’:

Available Countries

Germany
France
Russia
China
Brazil
Canada

How do I edit specific lines in the message content rather than replacing the whole thing?

You need to grab the existing message content as a string and manipulate it before editing. Fetch the original message, get its content, split into lines, find your target country line, and modify it. Here’s how I did it in my bot:

@bot.command()
async def claim(ctx, country):
    channel_obj = bot.get_channel(CHANNEL_ID)
    with open("msg_id.txt", "r") as storage:
        saved_id = int(storage.read())
    original_msg = await channel_obj.fetch_message(saved_id)
    
    current_content = original_msg.content
    lines = current_content.split('\n')
    
    for i, line in enumerate(lines):
        if country.lower() in line.lower() and '@' not in line:
            lines[i] = f"{line} {ctx.author.mention}"
            break
    
    new_content = '\n'.join(lines)
    await original_msg.edit(content=new_content)

Treat the message content like a list of lines, find the right line to modify, then rebuild the full message. Add some error handling for when the country isn’t found or already claimed.

You’re missing a key point - treat the message content as text that needs parsing. I hit this same problem building a tournament bracket bot. What worked: keep your original file structure and track changes separately. Don’t modify the message content string directly. Instead, re-read countries.txt when processing the claim command, then apply changes to that fresh data. This avoids string manipulation errors and keeps formatting consistent. Store claimed countries in a dictionary or separate file so you can rebuild the message each time. One gotcha - handle cases where someone claims an already taken country or one that doesn’t exist. String replace can create weird duplicates without proper validation first.

String manipulation works, but you’re creating a maintenance nightmare. Want to add unclaiming, different reservation types, or expiration times? You’ll be wrestling with text parsing hell.

I’ve built similar resource allocation systems at work. Here’s the thing - treat this as data management, not text editing. You need proper state tracking, event handling, and some persistence.

Latenode nails this. Set up a workflow that:

  • Stores country reservations in a database or spreadsheet
  • Listens for Discord commands via webhook
  • Updates data when claims happen
  • Regenerates and edits the Discord message with fresh content

You get proper validation, conflict handling, and can easily add features like time limits or admin overrides. Plus you can connect it to Google Sheets for easy management or send notifications to other channels.

No more fragile string parsing or file juggling. Just clean data flow and reliable message updates.

store the original content in a var first, then use string methods to replace the specific line. Something like new_text = original_msg.content.replace('Germany', f'Germany {ctx.author.mention}') works fine for simple cases.