Discord Bot Displays Multiple Embed Messages

I’ve been developing a Discord bot using Python to showcase cryptocurrency prices via embed messages. However, there’s an issue where when I send a command like !crypto (with ! as my command prefix), it returns both embed messages instead of just one. Below is a snippet of my code:

async def handle_message(msg):
    if msg.content.startswith(command_prefix):
        user_input = msg.content[15:]
    else:
        return
    
    if user_input.lower() == "dogecoin":
        api_url = "https://example-crypto-api.com/dogecoin/"
        headers = {'User-Agent': 'Mozilla/5.0'}
        request = Request(api_url, headers=headers)
        response = urlopen(request).read()
        parser = BeautifulSoup(response, 'html.parser')
        
        price_data = parser.find_all("div", class_="current-price")
        current_price = [item.get_text().strip() for item in price_data[:10]]
        price_str = " ".join(current_price)
        
        change_data = parser.find_all("span", class_="price-change")
        price_change = [item.get_text().strip() for item in change_data[:10]]
        change_str = " ".join(price_change)
        
        market_data = parser.find_all("div", class_="market-info")
        market_cap = [item.get_text().strip() for item in market_data[:1]]
        cap_str = " ".join(market_cap)

        doge_embed = discord.Embed(title="Dogecoin", description="Current DOGE price", color=0xFFD700)
        doge_embed.add_field(name="Current Price", value=f"Price: {price_str} | {change_str}", inline=False)
        doge_embed.add_field(name="Market Cap", value=f"Cap: {cap_str}", inline=False)
        await msg.channel.send(embed=doge_embed)
        
    if user_input.lower() == "litecoin":
        api_url = "https://example-crypto-api.com/litecoin/"
        headers = {'User-Agent': 'Mozilla/5.0'}
        request = Request(api_url, headers=headers)
        response = urlopen(request).read()
        parser = BeautifulSoup(response, 'html.parser')

        ltc_price = parser.find_all("div", class_="current-price")
        price_info = [item.get_text().strip() for item in ltc_price[:10]]
        final_price = " ".join(price_info)
        
        ltc_embed = discord.Embed(title="Litecoin", description="Current LTC price", color=0x345D9D)
        ltc_embed.add_field(name="Current Price", value=f"Price: {final_price}", inline=False)
        await msg.channel.send(embed=ltc_embed)

I am currently unsure why both embed messages appear instead of just the one triggered by the command. Can anyone provide insights on what’s going wrong?

Your main problem is the string slicing plus using if instead of elif. But there’s another issue no one’s caught yet - you’re using msg.content[15:] when !crypto is only 7 characters. You’re slicing way past the actual command, which can cause weird substring matches that trigger multiple conditions.

I hit this same bug when I hardcoded slice positions instead of calculating them properly. Replace that line with user_input = msg.content[len('!crypto '):].strip() to grab just the crypto name after the command.

Also, add some logging to see what user_input actually contains before it hits your conditionals - you might be shocked at what’s getting parsed.

Your problem is the conditional structure - you’re using separate if statements instead of elif. This lets both blocks run when both conditions are true. Also, your input parsing is wrong. You’re slicing msg.content[15:] but your prefix is just !, so you’re cutting off way more than you need. Change it to msg.content[1:] or msg.content[len(command_prefix):]. I had the same issue with my bot - improper string slicing caused multiple triggers. Try adding some debug prints to check what user_input actually contains.

Your slice index is wrong. You’re using msg.content[15:] but !crypto is only 8 characters including the space. That’s why you’re getting weird matches triggering both conditions. Use msg.content[8:] or calculate it dynamically. And switch those separate if statements to elif.

I see two problems with your code. You’re using separate if statements instead of elif - both conditions can trigger if they’re somehow true at the same time. Also, your input parsing is off - msg.content[15:] doesn’t work with a ! prefix.

Honestly though, debugging Discord bot message parsing and juggling multiple API calls manually sucks. I’ve built similar crypto price bots and you’re basically reinventing the wheel here.

You need proper automation that handles parsing, API calls, and message routing cleanly. I moved all my Discord stuff to Latenode since it processes webhooks and handles conditional logic without those messy if/elif chains. You can build flows that parse Discord messages, route to the right crypto API based on commands, format responses, and send back embeds.

No more string slicing bugs or duplicate messages. The visual workflow shows exactly what’s happening and you can test each step separately.

Check it out: https://latenode.com

Your command parsing logic is broken. You’re checking if the message starts with command_prefix (just !), but then you slice with msg.content[15:] no matter what command gets sent. So when someone types !crypto dogecoin, you’re grabbing characters way past the input length or getting random substrings that trigger your conditions. I hit this same issue building my first crypto bot. Easy fix - parse the command structure properly. Use user_input = msg.content.split()[1] to grab the first argument after the command, then switch to elif statements instead of multiple if blocks. Also, scraping crypto APIs directly like this breaks constantly when sites change their HTML. Most exchanges have free JSON APIs that are way more reliable.