How to implement embeds in Discord bot commands

I’m developing a Discord bot and facing challenges with implementing an embed for my command that checks network connectivity. Initially, I had a simple setup that just returned text, but I wanted to enhance the appearance using Discord embeds.

Initial version without embed:

import subprocess

@client.command()
async def check_host(ctx, *, target_ip: str = '8.8.8.8'):
    host_list = [target_ip]
    for host in host_list:
        result = subprocess.run(['ping', '-c', '4', host], capture_output=True, text=True)
        if result.returncode == 0:
            await ctx.send(f"ONLINE {host} - Connection successful")
        else:
            await ctx.send(f"OFFLINE {host} - Connection failed")

Updated version with embed:

@client.command()
async def check_host(ctx, *, target_ip: str = '8.8.8.8'):
    host_list = [target_ip]
    
    status_embed = discord.Embed(title='Network Status:', color=0x00FF00)
    status_embed.set_footer(text=f"Command used by {ctx.author}")
    
    for host in host_list:
        result = subprocess.run(['ping', '-c', '4', host], capture_output=True, text=True)
        if result.returncode == 0:
            status_embed.add_field(name=f"{host} is ONLINE", value="Connection established", inline=False)
        else:
            status_embed.add_field(name=f"{host} is OFFLINE", value="Connection timeout", inline=False)
        await ctx.send(embed=status_embed)

The key was to create a discord.Embed object and utilize add_field() for a structured display of the results.

Good foundation! I learned the hard way that subprocess.run blocks in async environments, especially with network ops. Try asyncio.create_subprocess_exec instead - it’s truly async.

You’ll want input validation for target_ip too. Users will throw invalid hostnames and malformed IPs at it, which breaks subprocess. I wrap the ping logic in try-except to catch subprocess exceptions and handle them cleanly in the embed.

For production bots, add rate limiting on this command. Network checks eat resources.

nice work! just a tip - move that await ctx.send(embed=status_embed) outside the loop, or it’ll spam multiple embeds when checking multiple hosts. also, consider changing the embed color based on ping results - red for offline, green for online!

Nice implementation, but you’ve got a bug with the color. You’re setting color=0x00FF00 upfront, so failed connections still show green embeds - pretty confusing for users. Fix this by setting the color after checking the connection: color = 0x00FF00 if result.returncode == 0 else 0xFF0000 inside your loop. Also, subprocess.run with ping can hang on some systems. Add timeout=10 so your bot doesn’t freeze on dead hosts.