Your first bot
Let’s build the simplest low level bot you can using AckCord. The only thing it will do is to log in, and print a line to the console when it has done so.
First add AckCord to your project by adding these statements to your build.sbt
file.
libraryDependencies += "net.katsstuff" %% "ackcord-core" % "0.18.1"
Most of these examples assume these two imports.
import ackcord._
import ackcord.data._
Next we need a bot token. You can get one by going to https://discord.com/developers/applications, creating a new application, and then creating a bot for your application.
val token = "<token>" //Your Discord token. Be very careful to never give this to anyone else
When working with the low level API, you’re the one responsible for setting stuff up, and knowing how it works. Therefore there isn’t one correct way to do this. What I will show here is a very barebones way to do it, but ultimately you’re the one that will have to decide how to do it.
First we need an actor system. In most applications you probably already have one lying around.
import akka.actor.typed._
import akka.actor.typed.scaladsl._
import akka.stream.scaladsl.Sink
import akka.util.Timeout
import scala.concurrent.duration._
import ackcord.requests.{Ratelimiter, RatelimiterActor, RequestSettings}
implicit val system: ActorSystem[Nothing] = ActorSystem(Behaviors.ignore, "AckCord")
import system.executionContext
Next we create the Cache
, and the RequestHelper
. The Cache
helps you know
when stuff happens, and keeps around the changes from old things that have
happened. The RequestHelper
helps you make stuff happen. I’d recommend
looking into the settings used when creating both the Cache
and RequestHelper
if you want to fine tune your bot.
val cache = Events.create()
val ratelimitActor = system.systemActorOf(RatelimiterActor(), "Ratelimiter")
val requests = {
implicit val timeout: Timeout = 2.minutes //For the ratelimiter
new Requests(
RequestSettings(
Some(BotAuthentication(token)),
Ratelimiter.ofActor(ratelimitActor)
)
)
}
Now that we have all the pieces we want, we can create our event listener.
In the low level API, events are represented as a Source
you can materialize
as many times as you want.
cache
.subscribeAPI
.collectType[APIMessage.Ready]
.to(Sink.foreach(_ => println("Now ready")))
.run()
Finally we can create our GatewaySettings
and start the shard.
val gatewaySettings = GatewaySettings(token)
DiscordShard.fetchWsGateway.foreach { wsUri =>
val shard = system.systemActorOf(DiscordShard(wsUri, gatewaySettings, cache), "DiscordShard")
//shard ! DiscordShard.StartShard
}