Skip to content

Basic Bot Tutorial (v3.1)

Ivan Abarca edited this page May 25, 2020 · 3 revisions

Beginnings

This tutorial is up-to-date with version line 3.1.x.

Making your first bot is very simple. This tutorial will walk you through how to make a basic bot that responds to a ping command and listens to some other events.

Constructing the client

The first thing you need to do to actually create the bot is to construct the client. This is done using the DiscordClientBuilder. After that you can login.

🛈 Important Links 🛈

DiscordClientBuilder Javadocs

import discord4j.core.DiscordClientBuilder;
import discord4j.core.GatewayDiscordClient;

public class Bot {

    public static void main(String[] args) {
        GatewayDiscordClient client = DiscordClientBuilder.create("TOKEN HERE")
                .build()
                .login()
                .block();
        client.onDisconnect().block();
    }

}

This is the very least that you need to be able to create a bot and login to show the bot as online.

⚠️ Warning ⚠️

You do not need to call block on login or onDisconnect, but if you do not have a non daemon thread running your program will instantly exit. Only call subscribe for login if you know what you're doing.

🛈 Important Links 🛈

DiscordClient Javadocs

Responding to events

Next let's listen to a couple of events. First let's listen to the ReadyEvent to figure out when we first originally connect to the gateway.

import discord4j.core.DiscordClientBuilder;
import discord4j.core.GatewayDiscordClient;
import discord4j.core.event.domain.lifecycle.ReadyEvent;
import discord4j.core.object.entity.User;

public class Bot {

  public static void main(String[] args) {
    GatewayDiscordClient client = DiscordClientBuilder.create("TOKEN HERE").build().login().block();

    client.getEventDispatcher().on(ReadyEvent.class)
        .subscribe(event -> {
          User self = event.getSelf();
          System.out.println(String.format("Logged in as %s#%s", self.getUsername(), self.getDiscriminator()));
        });

    client.onDisconnect().block();
  }

}

This will listen to when we connect to the gateway and when ReadyEvent fires. This'll then print out the name and discriminator of the bot that is signing in. Next we'll figure out how to listen for a !ping command from only users and respond with a pong!

import discord4j.core.DiscordClientBuilder;
import discord4j.core.GatewayDiscordClient;
import discord4j.core.event.domain.lifecycle.ReadyEvent;
import discord4j.core.event.domain.message.MessageCreateEvent;
import discord4j.core.object.entity.Message;
import discord4j.core.object.entity.User;

public class Bot {

  public static void main(String[] args) {
    GatewayDiscordClient client = DiscordClientBuilder.create("TOKEN HERE").build().login().block();

    client.getEventDispatcher().on(ReadyEvent.class)
        .subscribe(event -> {
          User self = event.getSelf();
          System.out.println(String.format("Logged in as %s#%s", self.getUsername(), self.getDiscriminator()));
        });

    client.getEventDispatcher().on(MessageCreateEvent.class)
        .map(MessageCreateEvent::getMessage)
        .filter(message -> message.getAuthor().map(user -> !user.isBot()).orElse(false))
        .filter(message -> message.getContent().equalsIgnoreCase("!ping"))
        .flatMap(Message::getChannel)
        .flatMap(channel -> channel.createMessage("Pong!"))
        .subscribe();

    client.onDisconnect().block();
  }

}

Now let's look back on this, there is a lot going on here so let's walk through it.

client.getEventDispatcher().on(MessageCreateEvent.class)

This listens for all MessageCreateEvents that come in to the bot.

.map(MessageCreateEvent::getMessage)

This turns all MessageCreate events into the messages that were sent. The :: syntax is just shorthand for map(event -> event.getMessage()).

.filter(message -> message.getAuthor().map(user -> !user.isBot()).orElse(false))

This filters out all members that are bots, so that we only get events from users.

.filter(message -> message.getContent().equalsIgnoreCase("!ping"))

This filters out any messages that don't equal the content !ping.

.flatMap(Message::getChannel)

This turns it into the channel the message came from.

.flatMap(channel -> channel.createMessage("Pong!"))

This creates the message with the content Pong!

.subscribe();

And this tells it to execute!

Finale

Now that you have a basic bot up and running, you can continue to build off of it. Including making your own system so all events aren't in the same class where you construct the client.