Bot für Discord

Freshy

Mitglied
Hi,

ich bin neu auf dem Forum und brauche Hilfe.

Ich möchte einen Discord Bot erstellen, der in einer bestimmten Zeit einen bestimmten Befehl schreiben/ausführen soll.

Nun hänge ich an einem Timer fest. Ich habe alle Anleitungen probiert, doch keine Hilft.

Mein derz. Code:
Code:
package de.coaster.timer;

import net.dv8tion.jda.api.entities.ChannelType;
import net.dv8tion.jda.api.entities.TextChannel;

public class Main {
    
    static int t=60;
    public static void main(String[] args) {
        
    }
    
    public static void timer() {
        
        t++ ;
            
        }
        
    }

Ich hoffe, mit kann jemand helfen.

LG.,
Freshy
 
Zuletzt bearbeitet:
Ich habe ja noch keinen Code für den Timer, der funktioniert.

Hier wäre eine Idee;
Java:
package de.coaster.timer;

import net.dv8tion.jda.api.entities.ChannelType;
import net.dv8tion.jda.api.entities.TextChannel;

public class Main {
    
    static int t=60;
    public static void main(String[] args) {
        
    }
    
    public static void timer() {
        
        t++ ;
            
        }
        
    }
 
Warum möchtest du diesen Timer denn unbedingt selber schreiben? Mit Java Bordmitteln kann man das doch super umsetzen:
Java:
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
Runnable task = () -> {
    System.out.println("Do something here..");
};
executor.schedule(task, 10, TimeUnit.MINUTES); // run task after 10 min
executor.shutdown();
 
Mit dem Timer den ich gefunden habe, kann ich ja nicht arbeiten. Aber das Beispiel ist hilfreich. Danke. Ich werde es mal probieren.
 
Wieso kannst Du mit dem Timer nicht arbeiten? Was hast Du probiert? Was für Probleme gab es?
 
Also der Code, den du da gepostet hast, enthält ja keinerlei Timer. Nur eine leere main Methode, so dass da nichts gemacht wird.
 
Bist du dir sicher, dass du dich schon für die Programmierung eines Bots bereit fühlst? Wenn man mit der JDA API arbeitet sollte man die Java Basics auf jeden Fall drauf haben.

Ich frage nur weil die Antworten bisher etwas wirr sind.
 

Das Beispiel klappt schon mal. Aber was ist denn überhaupt dieses "Daemon"? Und wo kann ich denn jetzt genau die Aufgabe eingeben, die mein Bot letztendlich machen soll? Bei
Code:
    public void run() {
        System.out.println("Timer task started at: "+new Date());
        completeTask();
        System.out.println("Timer task finished at: "+new Date());
    }
? Also anstatt den System.out.println?
 
@kneitzel Ja die Seite kenne ich, davon habe ich auch einige Bots. Aber ich finde halt keinen Bot, der alle x Minuten einen Befehl ausführt.

@mihe7 Unter einem Bot (von englisch robot ‚Roboter') versteht man ein Computerprogramm, das weitgehend automatisch sich wiederholende Aufgaben abarbeitet, ohne dabei auf eine Interaktion mit einem menschlichen Benutzer angewiesen zu sein.
 
@mihe7 Achso. Ich möchte, dass der Bot in einen definierten Channel alle x Stunden einen Befehl hinein schreibt, worauf ein anderer Bot den Befehl ausführen soll.

Bei mir sieht der Quellcode jetzt folgendermaßen aus:
Code:
public class timer extends TimerTask {
    
    public void run() {
        System.out.println("Timer task started at: "+new Date());
        completeTask();
        TextChannel channel = event.getTextChannel();
        channel.sendMessage("Hi");
        System.out.println("Timer task finished at: "+new Date());
    }

    private void completeTask() {
        try {
            //assuming it takes 20 secs to complete the task
            Thread.sleep(20000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    
    public static void main(String args[]){
        TimerTask timerTask = new timer();
        //running timer task as daemon thread
        Timer timer = new Timer(true);
        timer.scheduleAtFixedRate(timerTask, 0, 10*1000);
        System.out.println("TimerTask started");
        //cancel after sometime
        try {
            Thread.sleep(120000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        timer.cancel();
        System.out.println("TimerTask cancelled");
        try {
            Thread.sleep(30000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    
}

Bei der Zeile, wo
Code:
 TextChannel channel = event.getTextChannel();
steht,
kommt der Fehler: event cannot be resolved.
 
Mal grob skizziert (aber ohne IDE getestet .. kann also Typos enthalten 😉 )
Java:
class BotExample extends ListenerAdapter {
    public static void main(String[] args) {
        try {
            JDA jda = new JDABuilder("TOKEN")
                    .addEventListener(new BotExample())
                    .build();
            jda.awaitReady();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
    
    @Override
    public void onMessageReceived(MessageReceivedEvent event) {
        if(!event.getAuthor().isBot()) {
            String message = event.getMessage().getContentDisplay();
            if(message.equalsIgnoreCase("/start")) {
                final MessageChannel channel = event.getChannel();
                final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
                scheduler.scheduleAtFixedRate(() -> {
                    channel.sendMessage("Nachricht von /start .. nächste Nachricht in 1h").queue();
                }, 0, 1, TimeUnit.HOURS);
            }
        }
    }
}
 
Das steht doch auf der Seite:

Java:
public class ReadyListener implements EventListener
{
    public static void main(String[] args)
            throws LoginException, InterruptedException
    {
        // Note: It is important to register your ReadyListener before building
        JDA jda = new JDABuilder("token")
            .addEventListener(new ReadyListener())
            .build();

        // optionally block until JDA is ready
        jda.awaitReady();
    }

    @Override
    public void onEvent(Event event)
    {
        if (event instanceof ReadyEvent)
            System.out.println("API is ready!");
    }
}

Außerdem: https://github.com/DV8FromTheWorld/JDA/wiki/3)-Getting-Started

EDIT: @Robat war schneller.
 
@Robat Danke. Jetz kommen aber folgende Fehler:

  • Multiple markers at this line
- JDA cannot be resolved to a type
- JDABuilder cannot be resolved
to a type

  • MessageChannel cannot be resolved to a type

  • Multiple markers at this line
- ScheduledExecutorService cannot be resolved
to a type
- Executors cannot be resolved

  • TimeUnit cannot be resolved to a variable
@mihe7 Das hat doch aber nix mit einem Timer zu tun?
 
@Freshy und genau deswegen habe ich am Anfang gefragt, ob du die nötigen Grundlagen drauf hast.
Du musst natürlich die Klassen importieren. Und natürlich hat die Antwort von @mihe7 erstmal nichts mit einem Timer zu tun. Das ganze sollte als Grundlage dienen, wo du das Event herbekommst.

Nicht böse gemeint aber geh noch mal 3 Schritte zurück, nimm dir ein gutes Grundlagenbuch / Video / .. und lern die Basics.
 
Die Klassen sind doch aber schon importiert, oder welche meinst du?

Kannst du mir da was empfehlen? Ich würde jetzt aber kein Buch für 50€ kaufen, was nicht viel bringt. Ich denke, die Videos von simpleclub auf YT sind hilfreich.

Ich dachte, es kann doch nicht so schwer sein, einen Timer zu coden...
 
Die Klassen sind doch aber schon importiert, oder welche meinst du?
Das kann ich dir nicht sagen. In meinem Beispielcode oben habe ich zB keine Imports mit angeführt.
Ich denke, die Videos von simpleclub auf YT sind hilfreich.
Nicht wirklich - die erklären das ganze nur seeehr grob. Ich kann dir nur die Oracle Docu + Tutorial empfehlen. Andere schwören auf die Java Insel.
Ich dachte, es kann doch nicht so schwer sein, einen Timer zu coden...
Ist es auch nicht wenn man die Grundlagen drauf hat 😉
 
Gibts auch kostenlos im Netz.
Ich sehe aber bloß in Englisch, Deutsch ist da effektiver.
Auch da streiten sich die Geister. Wenn man wirklich Software entwickeln will kommt man irgendwann um Englisch nicht mehr drumherum.
Ich war ja mal bei einem Grundlagen Kurs, vor nem Jahr. Also sollte ich die Grundlagen ja drauf haben^^
Ich glaube wir haben eine unterschiedliche Auffassung von "Grundlagen". Die Grundlagen lernt man nicht mal eben in einem Kurs.
Da muss man schon etwas üben 😉
 
Gibts auch kostenlos im Netz.

Hier?

Wenn man wirklich Software entwickeln will kommt man irgendwann um Englisch nicht mehr drumherum.

Das ist mir schon klar. Aber ich muss ja verstehen, wenn man z.B. erklärt was eine Deklaration ist, was die mir da sagen. Da hilft Google Übersetzer auch nicht mehr. Es geht mir ja nicht um die Befehle usw. sondern um die Erklärungen etc. wie bei der Java Insel.

Die Grundlagen lernt man nicht mal eben in einem Kurs.

Naja, mein Kurs ging 1 Jahr.
 
Aber ich muss ja verstehen, wenn man z.B. erklärt was eine Deklaration ist, was die mir da sagen.
Das sollte man auch auf Englisch verstehen. Aber da kommen wir wohl nicht auf einen Nenner. 😉 Ist auch egal. Der Link von dir sollte der richtige sein.

Wie stehts denn nun eigentlich um deinen Bot.. wie weit bist du da?
 
Und was für Fehler kommen? Die Imports die du für das Beispiel von oben brauchst:
Java:
import net.dv8tion.jda.core.JDA;
import net.dv8tion.jda.core.JDABuilder;
import net.dv8tion.jda.core.entities.MessageChannel;
import net.dv8tion.jda.core.events.message.MessageReceivedEvent;
import net.dv8tion.jda.core.hooks.ListenerAdapter;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

Wie hast du eigentlich das coden gelernt?
Ich zitiere mal (ich glaub Sokrates war es): "Ich weiß, dass ich nichts weiß." 😛
Man lernt beim Programmieren jeden Tag dazu. Angefangen hab ich vor ca 8 Jahren.
 
import net.dv8tion.jda.core.JDA; import net.dv8tion.jda.core.JDABuilder; import net.dv8tion.jda.core.entities.MessageChannel; import net.dv8tion.jda.core.events.message.MessageReceivedEvent; import net.dv8tion.jda.core.hooks.ListenerAdapter;

Bei den Imports kommt folgendes: The import (Import)cannot be resolved.

Woher will man denn wissen, welche Import man braucht?
 
Kann es sein, dass du ohne IDE (Eclipse, Netbeans, Intellij, ... ) programmierst?
Eine IDE würde dir automatisch sagen wenn Klassen einen Import brauchen.

Bei welchem Import wird denn gemeckert?
 
Dann hast du wohl die JDA API nicht (richtig) eingebunden. Entweder JAR downloaden und diese dem Classpath deines Projekt hinzufügen oder - bessere Variante - maven/gradle nutzen und die Dependency hinzufügen.
 
Also nur um es mal etwas zu konkretisieren: Du hast erst einmal kein Problem mit einem Timer. Der würde funktionieren, aber Du hast ein Problem, in dem Timer dann etwas sinnvolles zu machen....

Dann nur ein paar Dinge, die mir so aufgefallen sind:
a) In deinem Code solltest Du doch sehen, dass dieses completeTask() nur ein Dummy war, in dem man seinen Code schreiben könnte. Da ist nur ein sleep drin und das macht so ja für Dich keinen Sinn. Da Du Deinen Code direkt in run() haben willst, kannst Du completeTask komplett entfernen.

b) Du musst über die Architektur nachdenken. Du willst ja eben nicht auf irgend ein event reagieren sondern willst selbst etwas machen. Daher hast du eben keine Variable event oder so.
==> Schau Dir die API in Ruhe an: Wie kannst Du eine Verbindung aufbauen? Irgendwo rein joinen und da dann etwas schreiben? Wären drei Schritte, die Du nach und nach implementieren kannst. Wenn Du das hast, dann kannst Du auch den Timer hinzu fügen um dann regelmäßig etwas zu machen ...
 
@Robat Maven und Dependency sind ja auch schon vorhanden:
Code:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>CommandLoopBot</groupId>
  <artifactId>CommandLoopBot</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <build>
    <sourceDirectory>src</sourceDirectory>
    <plugins>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.8.0</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
        </configuration>
      </plugin>
    </plugins>
  </build>
  <repositories>
      <repository>
        <id>jcenter</id>
        <name>jcenter-bintray</name>
        <url>http://jcenter.bintray.com</url>
    </repository>
  </repositories>
  <dependencies>
      <dependency>
        <groupId>net.dv8tion</groupId>
        <artifactId>JDA</artifactId>
        <version>4.BETA.0_18</version>
        <exclusions>
            <exclusion>
                <groupId>club.minnced</groupId>
                <artifactId>opus-java</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
  </dependencies>
</project>

@kneitzel
a) In deinem Code solltest Du doch sehen, dass dieses completeTask() nur ein Dummy war, in dem man seinen Code schreiben könnte. Da ist nur ein sleep drin und das macht so ja für Dich keinen Sinn. Da Du Deinen Code direkt in run() haben willst, kannst Du completeTask komplett entfernen.

Da steht aber "assuming it takes 20 secs to complete the task". Und das ist halt genau das, was ich brauche. Bei mir müssten dann aber die Millisekunden für 1 Stunde drin stehen. Wofür ich die main brauche, verstehe ich nicht, denn was ist denn dieses "Daemon"?

Wie kannst Du eine Verbindung aufbauen? Irgendwo rein joinen und da dann etwas schreiben?

Der Bot ist ja schon auf dem Server. Ich muss dafür auch nicht irgendwo rein joinen. Was der Bot aber machen muss, ist die Nachricht in einen definierten Channel rein zu schreiben. Danach soll er halt die Nachricht senden.
 
Also da scheint Dir etwas das Verständnis zu fehlen. Das Beispiel selbst sich nur rein auf den Timer konzentriert hat, gab es keine Aktivität, die Zeit beansprucht. Daher das "Thread.sleep(20000);" was einfach 20 Sekunden schläft.
Das macht aber doch bei Dir überhaupt keinen Sinn. Der Timer wird aufgerufen, wenn Die Tätigkeit ausgeführt werden soll und dann wird diese Tätigkeit direkt durchgeführt.

Und erst einmal hast Du nur ein reines Java Programm. Das ist nicht mit Discord verbunden. So wie ich das verstanden habe, dient zum Kontakt aufnehmen der JDABuilder: https://ci.dv8tion.net/job/JDA/javadoc/net/dv8tion/jda/core/JDABuilder.html.
Da kannst Du dann über ein Token die Verbindung aufbauen.

Nach dem build() Aufruf hast Du eine JDA instanz. Damit kannst Du dann weiter arbeiten. Also z.B. getTextChanelById um den TextChannel zu bekommen auf dem du etwas schreiben kannst. https://ci.dv8tion.net/job/JDA/javadoc/net/dv8tion/jda/core/JDA.html

Und da hast Du dann z.B. das sendMessage.

Daher halte ich meine Hinweise für gerechtfertigt und Du solltest Deinen Ansatz / Vorgehen überdenken und erst einmal zu einem generellen Verständnis kommen.
 
Das ist nicht mit Discord verbunden. So wie ich das verstanden habe, dient zum Kontakt aufnehmen der JDABuilder

Natürlich ist es bereit in Discord voll integriert:
Java:
    public CommandLoopBot() throws LoginException, IllegalArgumentException {
        INSTANCE = this;
        
        DefaultShardManagerBuilder builder = new DefaultShardManagerBuilder();
        builder.setToken("TOKEN");
        
        builder.setActivity(Activity.playing("EUGaming Bot by CEO."));
        builder.setStatus(OnlineStatus.ONLINE);
        
        this.cmdMan = new CommandManager();
        
        builder.addEventListeners(new CommandListener());
        
        shardMan = builder.build();
        System.out.println("Bot ist jetzt online.");
 
Der letzte Code von Dir war in #22 und da war außer dem Timer nichts zu sehen. Sorry, dass meine Glaskugel kaputt ist und ich daher Deinen aktuellen Stand nicht sehen konnte.

Sicher, dass Du da zwei Mal new CommandManager() brauchst und nicht cmdMan beim addEventListeners angeben musst?

Und wo ist jetzt Dein Problem? Du hast dann ja jetzt in shardMan die IDA Instanz so dass Du die Schritte wie von mir beschrieben ausführen können müsstest. Hast Du das schon einmal probiert? Und ggf. mehr bezüglich der Probleme, die Du derzeit hast, sagen.
 
Maven und Dependency sind ja auch schon vorhanden:
In der 4.0 BETA Version wurden das `core` Package in `api` umbenannt.
Aus `net.dv8tion.jda.core.JDA;` wird also `net.dv8tion.jda.api.JDA` ... gleiches Spiel mit den anderen Packages.
Außerdem wurde aus der `addEventListener()` Methode eine `addEventListeners()` Methode ..

Die Punkte müsste man also in meinem Beispiel umändern.

Die ganzen Punkte, dass du zB schon einen lauffähigen Bot hast etc, hättest du ruhig am Anfang mit nennen können. Im ersten Post sah es so aus als hättest du NUR die main-Methode.
 

Zurück
Oben