DEV Community

Cover image for Creating a Simple Discord Bot in Rust with Serenity
Devind Dev
Devind Dev

Posted on

Creating a Simple Discord Bot in Rust with Serenity

Photo by Ant Rozetsky on Unsplash

In the world of software, simplicity is power. Building something complex like a Discord bot doesn’t have to be overwhelming—it can be clear, incremental, and satisfying. Let’s take a journey into creating a bot in Rust, the language known for precision and performance. By the end, you’ll have a bot that responds to a simple command, and more importantly, you’ll understand every step.

Like crafting a habit, building a bot starts with a small, achievable step. Here, that step is responding to a single command: !ping.

Why Rust? Why a Bot?

Rust gives you the tools to write clean, safe, and efficient code. It’s not just about coding; it’s about coding right. Combine that with Discord, where bots transform communities into dynamic hubs, and you’ve got a chance to create something truly impactful.

Step 1: Laying the Foundation

First, set up your environment. Like any good project, we need the tools ready before we build.

Tools You’ll Need:

  • Rust Installed: Get it here.
  • Discord Developer Account: Create one at the Discord Developer Portal.
  • Bot Token: You’ll generate this while setting up your bot. Keep it safe—it’s your bot’s identity.

Now, create your project from your terminal at your desired location:

cargo new discord-bot
cd discord-bot
Enter fullscreen mode Exit fullscreen mode

Step 2: Add Dependencies

In your Cargo.toml file, include the required dependencies:

[dependencies]
serenity = "0.12"
tokio = { version = "1", features = ["full"] }
Enter fullscreen mode Exit fullscreen mode
  • Serenity: A library for building Discord bots.
  • Tokio: Provides an asynchronous runtime for handling concurrent tasks.

Save the file and run:
cargo build

Step 3: Implement the Bot

Open src/main.rs and replace its contents with the following code:

use std::env;

use serenity::async_trait;
use serenity::model::channel::Message;
use serenity::model::gateway::Ready;
use serenity::prelude::*;

// Define the event handler
struct Handler;

#[async_trait]
impl EventHandler for Handler {
    // Handle incoming messages
    async fn message(&self, ctx: Context, msg: Message) {
        // Ignore messages from bots
        if msg.author.bot {
            return;
        }

        // Respond to the "!ping" command
        if msg.content.eq_ignore_ascii_case("!ping") {
            println!("Received !ping command from {}", msg.author.name);

            // Send a plain text response
            if let Err(why) = msg.channel_id.say(&ctx.http, "Pong!").await {
                eprintln!("Error sending message: {:?}", why);
            }
        }
    }

    // Log when the bot is ready
    async fn ready(&self, _: Context, ready: Ready) {
        println!("{} is connected and ready!", ready.user.name);
    }
}

#[tokio::main]
async fn main() {
    // Retrieve the bot token from the environment
    let token = env::var("DISCORD_TOKEN").expect("Expected a token in the environment");

    // Specify the bot's intents
    let intents = GatewayIntents::GUILD_MESSAGES
        | GatewayIntents::DIRECT_MESSAGES
        | GatewayIntents::MESSAGE_CONTENT;

    // Initialize the bot client
    let mut client = Client::builder(&token, intents)
        .event_handler(Handler)
        .await
        .expect("Error creating client");

    // Start the bot
    if let Err(why) = client.start().await {
        eprintln!("Client error: {:?}", why);
    }
}
Enter fullscreen mode Exit fullscreen mode

Key Features of the Code:

  • Command Handling: The bot listens for the !ping command and replies with "Pong!".
  • Event Logging: Logs activity when the bot is ready or when it processes commands.
  • Safety: Ignores messages from other bots, including itself.

Step 4: Invite the Bot

To invite the bot to your server:

  1. Go to the Discord Developer Portal.
  2. Under your bot application, navigate to OAuth2 > URL Generator.
  3. Select the bot scope and appropriate permissions (e.g., Send Messages).
  4. Copy the generated URL, paste it in your browser, and invite the bot to your server.
  5. Now keep your bot token ready for the next step.

Step 5: Run and Test

Add Your Token
Export your bot token as an environment variable:

In your terminal,
Linux/MacOS:
export DISCORD_TOKEN="your-bot-token-here"

Windows (Command Prompt):
set DISCORD_TOKEN=your-bot-token-here

Build and Run
Compile and run your bot with the following commands:

cargo build
cargo run
Enter fullscreen mode Exit fullscreen mode

Step 6: Testing the Bot

In any text channel where your bot has permissions, type: !ping

The bot will reply like this:

ping response by discord bot developed with rust

Conclusion

You’ve now created a simple Discord bot using Rust and Serenity. This foundational bot responds to a basic command and provides a starting point for more complex functionality. With this setup, you can expand the bot to include custom commands, interactive responses, and integrations with external APIs.

Next Steps

Here are some potential enhancements for your bot:

  • Add More Commands: Implement additional features such as !help, !joke, or !weather.
  • Use Embeds: Create visually rich responses with Discord embeds.
  • Integrate APIs: Fetch live data for commands or connect to other services.
  • For more details, refer to the Serenity documentation. With Rust’s power and Serenity’s flexibility, your bot can become an invaluable tool for your Discord community.

Top comments (0)