Building Simple Command-Based Bots

SA
StudyAI Editorial
Reviewed by StudyAI tutors
· Published Updated

From the Bot curriculum

Building Simple Command-Based Bots

TL;DR

You'll learn how to make a bot that responds to specific text commands. This involves listening for messages, checking if they start with your command prefix, and then performing an action based on the command. It's a fundamental skill for building interactive bot experiences.

1. The Mental Model

Think of your bot as a really simple digital assistant. It patiently waits for someone to say a special "trigger word" (its command prefix), then it listens closely for a keyword (the command), and finally, it tries to follow those instructions.

2. The Core Material

Building a command-based bot boils down to three main steps:
1. Listen for messages: Your bot needs to be constantly watching for new messages in its chat environment.
2. Identify commands: When a message comes in, your bot checks if it's meant for it. This usually involves looking for a specific starting character (the command prefix) like ! or /.
3. Execute actions: If it finds a command, your bot needs to figure out what that command means and then do something in response.

### Setting Up Your Bot's Environment

Before you write any command logic, you'll need to set up your bot. This usually means installing a library for your chosen platform (e.g., discord.py for Discord, python-telegram-bot for Telegram) and connecting your bot using an API token.

Here's a basic Python example using a hypothetical BotFramework (this isn't real code, just for illustration, but shows the structure):

import bot_framework # This would be your actual bot library

# Your unique token from the bot platform
BOT_TOKEN = "YOUR_SUPER_SECRET_TOKEN"
COMMAND_PREFIX = "!" # This is what makes your bot listen

bot = bot_framework.Client()

@bot.event # This decorator tells our framework this function handles an event
async def on_ready():
    print(f"Bot connected as {bot.user}")

@bot.event
async def on_message(message):
    # Don't let the bot reply to its own messages, or you'll get an infinite loop!
    if message.author == bot.user:
        return

    # More logic goes here!

bot.run(BOT_TOKEN)

### Processing Commands

Once your on_message handler is set up, you'll add the command processing logic. You'll check for the prefix, then extract the command and any arguments.

# Inside your on_message function from the previous example:

    if message.content.startswith(COMMAND_PREFIX):
        full_command = message.content[len(COMMAND_PREFIX):].strip() # Remove prefix and any leading/trailing spaces
        parts = full_command.split(' ', 1) # Split into command and remaining arguments (max 1 split)
        command_name = parts[0].lower() # Get the command and make it lowercase for easy comparison
        arguments = parts[1] if len(parts) > 1 else "" # Get arguments if they exist

        if command_name == "ping":
            await message.channel.send("Pong!")
        elif command_name == "echo":
            if arguments:
                await message.channel.send(f"You said: {arguments}")
            else:
                await message.channel.send("What do you want me to echo?")
        elif command_name == "help":
            await message.channel.send("Available commands: `!ping`, `!echo <text>`")
        else:
            await message.channel.send(f"Sorry, I don't know the command `{command_name}`.")

    # If it doesn't start with our prefix, ignore it or handle it differently
    # e.g., using AI or other non-command logic if your bot does that.

Here's how the command processing flow looks:

graph TD
    A["Bot Starts"] --> B["Connect to Platform"];
    B --> C{"New Message Received?"};
    C -- Yes --> D{"Is Message from Bot Itself?"};
    D -- Yes --> F["Ignore Message"];
    D -- No --> G{"Message Starts with `!` (Command Prefix)?"};
    G -- No --> H["Process as Regular Chat/Ignore"];
    G -- Yes --> I["Extract Command & Arguments"];
    I --> J{"Command is 'ping'?"};
    J -- Yes --> K["Reply 'Pong!'"];
    J -- No --> L{"Command is 'echo'?"};
    L -- Yes --> M{"Has Arguments?"};
    M -- Yes --> N["Reply 'You said: <args>'"];
    M -- No --> P["Reply 'What to echo?'"];
    L -- No --> Q{"Command is 'help'?"};
    Q -- Yes --> S["Reply 'Available commands...'"];
    Q -- No --> T["Reply 'Unknown command!'"];
    K --> E;
    N --> E;
    P --> E;
    S --> E;
    T --> E;
    F --> E;
    H --> E;
    E(["Wait for Next Message"]) --> C;

### Handling Arguments

Many commands need extra information. For example, a !remind me to buy milk command needs "buy milk" as an argument. The split(' ', 1) trick is useful because it splits the string only once, giving you the first word (the command) and then the rest of the message as the arguments, which is often what you want.

3. Worked Example

Let's build a simple "dice roll" command. We want !roll 6 to roll a 6-sided die, and !roll 20 to roll a 20-sided die. If no number is given, we'll default to a 6-sided die.

import random
# Assume bot setup and on_message structure from "The Core Material" is already in place.

# Inside your on_message function:
    if message.content.startswith(COMMAND_PREFIX):
        full_command = message.content[len(COMMAND_PREFIX):].strip()
        parts = full_command.split(' ', 1)
        command_name = parts[0].lower()
        arguments = parts[1] if len(parts) > 1 else ""

        if command_name == "roll":
            try:
                # Try to convert the argument to an integer for the number of sides
                sides = int(arguments) if arguments else 6 # Default to 6 if no argument
                if sides <= 0:
                    await message.channel.send("You can't roll a die with zero or negative sides!")
                    return

                result = random.randint(1, sides)
                await message.channel.send(f"You rolled a {result} (out of {sides} sides).")
            except ValueError:
                await message.channel.send("Please provide a valid number of sides for the die, e.g., `!roll 6` or `!roll`.")
        # ... other commands (ping, echo, help) ...
        else:
            await message.channel.send(f"Sorry, I don't know the command `{command_name}`.")

How it works:
1. If the message is !roll 10, command_name becomes "roll" and arguments becomes "10".
2. int(arguments) converts "10" to the number 10.
3. random.randint(1, 10) generates a number between 1 and 10.
4. If the message is !roll, arguments is an empty string. int(arguments) if arguments else 6 makes sides equal to 6.
5. If the message is !roll potato, int("potato") would raise a ValueError, caught by our try-except block, and the bot would tell you it needs a number.

4. Key Takeaways

  • Always check if a message begins with your defined command prefix.
  • Use strip() to clean up extra spaces around commands and arguments.
  • split(' ', 1) is a handy trick for separating the main command from its arguments.
  • Always prevent your bot from responding to its own messages to avoid loops.
  • Use try-except blocks to gracefully handle incorrect user input, like non-numeric arguments where numbers are expected.
  • Keep command names simple and lowercase for easier parsing and comparison.
  • Provide helpful error messages when a user's command is misunderstood.

5. Now Try It

Modify the !roll command. Instead of just rolling one die, let your bot handle !roll 2d6 (rolling two 6-sided dice) or !roll 1d20 (one 20-sided die). If the format isn't matched (e.g., !roll 5 or !roll 20), default to rolling a single die with that many sides. You'll need to parse the NdS format, where N is the number of dice and S is the number of sides. Test it with valid inputs like !roll 3d8, valid single-number inputs like !roll 12, and invalid inputs like !roll hello.

Frequently asked about Building Simple Command-Based Bots

# Building Simple Command-Based Bots ## TL;DR You'll learn how to make a bot that responds to specific text commands. This involves listening for messages, checking if they start with your command prefix, and then performing an action based on the command. It's a fundamental Read the full notes above.

Building Simple Command-Based Bots is a core topic in Bot. Most exam papers test it via a mix of definitions, worked examples, and applied problems. The notes above cover the high-yield sub-topics, common pitfalls, and the kind of questions examiners typically set.

Yes. Every note in the StudyAI Campus Hub is free to read. Create a free account if you want to clone the full plan, generate your own notes from your textbook, or get AI-powered practice quizzes and flashcards.

More from Bot


Get the full Bot curriculum

Clone the complete plan to your dashboard for unlimited AI-generated notes, practice quizzes, and a personalised revision schedule.

Create Free Account