Opprette en Discord Bot med Discord4J + Spring Boot

1. Oversikt

Discord4J er et Java-bibliotek med åpen kildekode som primært kan brukes til å raskt få tilgang til Discord Bot API. Det integreres sterkt med Project Reactor for å gi et helt ikke-blokkerende reaktivt API.

Vi bruker Discord4J i denne opplæringen for å lage en enkel Discord-bot som kan svare på en forhåndsdefinert kommando. Vi bygger boten på toppen av Spring Boot for å demonstrere hvor enkelt det ville være å skalere vår bot over mange andre funksjoner som er aktivert av Spring Boot.

Når vi er ferdige, vil denne bot kunne lytte etter en kommando kalt “! Todo” og vil skrive ut en statisk definert oppgaveliste.

2. Opprett et Discord-program

For at boten vår skal motta oppdateringer fra Discord og legge ut svar i kanaler, må vi opprette en Discord-applikasjon i Discord Developer Portal og sette den opp til å være en bot. Dette er en enkel prosess. Siden Discord tillater oppretting av flere applikasjoner eller bots under en enkelt utviklerkonto, kan du gjerne prøve dette flere ganger med forskjellige innstillinger.

Her er trinnene for å opprette en ny applikasjon:

  • Logg deg på Discord Developer Portal
  • Klikk "Ny applikasjon" i kategorien Programmer.
  • Skriv inn et navn på boten vår og klikk "Opprett"
  • Last opp et appikon og en beskrivelse og klikk "Lagre endringer"

Nå som en applikasjon eksisterer, trenger vi ganske enkelt å legge til bot-funksjonalitet i den. Dette vil generere bot-token som Discord4J krever.

Her er trinnene for å transformere et program til en bot:

  • Velg applikasjonen vår i applikasjonsfanen (hvis den ikke allerede er valgt).
  • I fanen Bot klikker du på "Legg til bot" og bekrefter at vi vil gjøre det.

Nå som applikasjonen vår har blitt en ekte bot, kopier du tokenet slik at vi kan legge det til i applikasjonsegenskapene våre. Vær forsiktig så du ikke deler dette token offentlig, siden noen andre vil være i stand til å utføre ondsinnet kode mens de utgir seg for vår bot.

Vi er nå klare til å skrive litt kode!

3. Lag en Spring Boot-app

Etter å ha konstruert en ny Spring Boot-app, må vi være sikker på å inkludere Discord4J-kjerneavhengigheten:

 com.discord4j discord4j-core 3.1.1 

Discord4J fungerer ved å initialisere en GatewayDiscordClient med bot-token vi opprettet tidligere. Dette klientobjektet lar oss registrere lyttere for begivenheter og konfigurere mange ting, men på et minimum må vi i det minste ringe Logg Inn() metode. Dette viser at boten vår er online.

La oss først legge til bot-tokenet vårt application.yml fil:

token: 'vår-token-her'

La oss deretter injisere den i en @Konfigurasjon klasse der vi kan instantiere vår GatewayDiscordClient:

@Configuration offentlig klasse BotConfiguration {@Value ("$ {token}") privat strengtoken; @Bean offentlig GatewayDiscordClient gatewayDiscordClient () {return DiscordClientBuilder.create (token) .build () .login () .block (); }}

På dette punktet vil vår bot bli sett på som online, men den gjør ingenting ennå. La oss legge til litt funksjonalitet.

4. Legg til hendelseslyttere

Den vanligste funksjonen til en chatbot er kommandoen. Dette er en abstraksjon sett i CLI-er der en bruker skriver inn tekst for å utløse visse funksjoner. Vi kan oppnå dette i Discord-bot ved å lytte etter nye meldinger som brukere sender og svare med intelligente svar når det er aktuelt.

Det er mange typer arrangementer som vi kan lytte til. Å registrere en lytter er imidlertid det samme for dem alle, så la oss først lage et grensesnitt for alle hendelseslytterne våre:

importer discord4j.core.event.domain.Event; offentlig grensesnitt EventListener {Logger LOG = LoggerFactory.getLogger (EventListener.class); Klasse getEventType (); Mono execute (T-arrangement); standard Mono handleError (Throwable error) {LOG.error ("Unable to process" + getEventType (). getSimpleName (), error); returner Mono.empty (); }}

Nå kan vi implementere dette grensesnittet for like mange discord4j.core.event.domain.Event utvidelser som vi ønsker.

Før vi implementerer den første lytteren vår, la oss endre klienten vår @Bønne konfigurasjon for å forvente en liste over EventListener slik at den kan registrere alle som er funnet om våren ApplicationContext:

@Bean offentlig GatewayDiscordClient gatewayDiscordClient (Liste eventListeners) {GatewayDiscordClient client = DiscordClientBuilder.create (token) .build () .login () .block (); for (EventListener lytter: eventListeners) {client.on (listener.getEventType ()) .flatMap (lytter :: utfør) .onErrorResume (lytter :: handleError). abonner (); } retur klient; }

Nå er alt vi trenger å gjøre for å registrere lyttere til hendelser, å implementere grensesnittet vårt og kommentere det med Spring's @Komponent-baserte stereotype merknader. Registreringen vil nå skje automatisk for oss!

Vi kunne ha valgt å registrere hvert arrangement separat og eksplisitt. Imidlertid er det generelt bedre å ta en mer modulær tilnærming for bedre skalerbarhet.

Vårt lytteroppsett er nå fullført, men boten gjør fortsatt ikke noe ennå, så la oss legge til noen hendelser å lytte til.

4.1. Kommandobehandling

For å motta en brukers kommando kan vi lytte til to forskjellige hendelsestyper: MessageCreateEvent for nye meldinger og MessageUpdateEvent for oppdaterte meldinger. Vi vil kanskje bare lytte etter nye meldinger, men som en læringsmulighet, la oss anta at vi vil støtte begge typer hendelser for vår bot. Dette vil gi et ekstra lag med robusthet som brukerne våre kan sette pris på.

Begge hendelsesobjektene inneholder all relevant informasjon om hver hendelse. Spesielt er vi interessert i innholdet i meldingen, forfatteren av meldingen og kanalen den ble lagt ut til. Heldigvis lever alle disse datapunktene i Beskjed objekt som begge disse hendelsestypene gir.

Når vi har fått Beskjed, kan vi sjekke forfatteren for å sikre at det ikke er en bot, vi kan sjekke innholdet i meldingen for å sikre at den samsvarer med kommandoen vår, og vi kan bruke meldingens kanal til å sende et svar.

Siden vi fullt ut kan operere fra begge arrangementene gjennom deres Beskjed objekter, la oss sette all nedstrøms logikk på et felles sted slik at begge hendelseslytterne kan bruke den:

importer diskord4j.core.object.entity.Message; offentlig abstrakt klasse MessageListener {public Mono processCommand (Message eventMessage) {return Mono.just (eventMessage) .filter (message -> message.getAuthor (). map (user ->! user.isBot ()). orElse (false)) .filter (melding -> message.getContent (). equalsIgnoreCase ("! todo")) .flatMap (Message :: getChannel) .flatMap (channel -> channel.createMessage ("Ting å gjøre i dag: \ n - skriv en bot \ n - spis lunsj \ n - spill et spill ")) .then (); }}

Det skjer mye her, men dette er den mest grunnleggende formen for en kommando og respons. Denne tilnærmingen bruker en reaktiv funksjonell design, men det er mulig å skrive dette på en mer tradisjonell imperativ måte ved hjelp av blokkere().

Å skalere på tvers av flere bot-kommandoer, påkalle forskjellige tjenester eller datalagre, eller til og med bruke Discord-roller som autorisasjon for visse kommandoer, er vanlige deler av en god bot-kommandearkitektur. Siden lytterne våre er vårstyrte @Services, vi kunne enkelt injisere andre vårstyrte bønner for å ivareta disse oppgavene. Imidlertid vil vi ikke takle noe av det i denne artikkelen.

4.2. EventListener

For å motta nye meldinger fra en bruker, må vi lytte til MessageCreateEvent. Siden kommandobehandlingslogikken allerede lever i MessageListener, kan vi utvide den til å arve den funksjonaliteten. Vi må også implementere vår EventListener grensesnitt for å overholde vårt registreringsdesign:

@Service public class MessageCreateListener utvider MessageListener implementerer EventListener {@Override public Class getEventType () {return MessageCreateEvent.class; } @ Override public Mono execute (MessageCreateEvent event) {return processCommand (event.getMessage ()); }}

Gjennom arv blir budskapet videreført til vårt processCommand () metode der alle bekreftelser og svar forekommer.

På dette tidspunktet vil bot motta og svare på "! Todo" -kommandoen. Imidlertid, hvis en bruker korrigerer feil skrevet kommando, vil ikke boten svare. La oss støtte denne brukssaken med en annen hendelseslytter.

4.3. EventListener

De MessageUpdateEvent sendes ut når en bruker redigerer en melding. Vi kan lytte etter at denne hendelsen gjenkjenner kommandoer, omtrent som hvordan vi lytter etter MessageCreateEvent.

For vårt formål bryr vi oss bare om denne hendelsen hvis innholdet i meldingen ble endret. Vi kan ignorere andre forekomster av denne hendelsen. Heldigvis kan vi bruke isContentChanged () metode for å filtrere ut slike forekomster:

@Service public class MessageUpdateListener utvider MessageListener implementerer EventListener {@Override public Class getEventType () {return MessageUpdateEvent.class; } @Override offentlig mono-utføring (MessageUpdateEvent-hendelse) {return Mono.just (event) .filter (MessageUpdateEvent :: isContentChanged) .flatMap (MessageUpdateEvent :: getMessage) .flatMap (super :: processCommand); }}

I dette tilfellet, siden getMessage () returnerer Mono i stedet for en rå Beskjed, må vi bruke flatMap () å sende den til superklassen vår.

5. Test Bot i uoverensstemmelse

Nå som vi har en fungerende Discord-bot, kan vi invitere den til en Discord-server og teste den.

For å opprette en invitasjonskobling, må vi spesifisere hvilke tillatelser boten krever for å fungere skikkelig. En populær tredjeparts kalkulator for diskordtillatelser brukes ofte til å generere en invitasjonskobling med nødvendige tillatelser. Selv om det ikke anbefales for produksjon, kan vi bare velge "Administrator" for testformål og ikke bekymre oss for de andre tillatelsene. Bare oppgi klient-ID for bot (funnet i Discord Developer Portal) og bruk den genererte lenken for å invitere bot til en server.

Hvis vi ikke gir administratortillatelser til boten, kan det hende vi må justere kanaltillatelser slik at boten kan lese og skrive i en kanal.

Boten svarer nå på meldingen "! Todo" og når en melding redigeres for å si "! Todo":

6. Oversikt

Denne opplæringen beskrev alle nødvendige trinn for å lage en Discord-bot ved hjelp av Discord4J-biblioteket og Spring Boot. Til slutt beskrev den hvordan du setter opp en grunnleggende skalerbar kommando- og responsstruktur for bot.

For en komplett og fungerende bot, se kildekoden på GitHub. Et gyldig bot-token kreves for å kjøre det.


$config[zx-auto] not found$config[zx-overlay] not found