Devlel
Devlel

Reputation: 11

Discord bot changing status activity every 30 seconds jda

I would like to make the bot refresh/change status (Activity)for two different messages every 30 seconds

jda.getPresence().setActivity(Activity.playing("message1"));
jda.getPresence().setActivity(Activity.playing("message2"));

Upvotes: 0

Views: 8802

Answers (1)

dan1st
dan1st

Reputation: 16476

Basically, you need to create an array with the messages and an index that alternates between 0 and the last message:

String[] messages={"message 1","message 2"};
int currentIndex=0;

Every 30 seconds, you can then execute the following:

jda.getPresence().setActivity(Activity.playing(messages[currentIndex]));
currentIndex=(currentIndex+1)%messages.length;

This sets the Activity to the current message (element in the array of currentIndex) at first.

After this, it adds 1 to currentIndex.

If currentIndex exceeds the array length, it sets it to 0, again. This is done using the Modulo operation.

In order to execute that every 30 seconds, you can use one of the following methods:

java.util.Timer

The old method for doing this is by creating a Timer:

//Outside of any method
private String[] messages={"message 1","message 2"};
private int currentIndex=0;
//Run this once
new Timer().schedule(new TimerTask(){
  public void run(){
    jda.getPresence().setActivity(Activity.playing(messages[currentIndex]));
    currentIndex=(currentIndex+1)%messages.length;
  }},0,30_000);

Timer#schedule can execute a TimerTask after a specific delay (0 as you want to start rightaway) and let it repeat after a specified period (both the delay and the period are in milliseconds).

java.util.concurrent.ScheduledExecutorService

It is also possible to use a ScheduledExecutorService that allows for more customization (this method is considered "better" than Timer as e.g. stated in Java Concurrency in Practice, Chapter 6.2.5):

//outside of any method
private String[] messages = { "message 1", "message 2" };
private int currentIndex = 0;
private ScheduledExecutorService threadPool = Executors.newSingleThreadScheduledExecutor();
//run this once
threadPool.scheduleWithFixedDelay(() -> {
    jda.getPresence().setActivity(Activity.playing(messages[currentIndex]));
    currentIndex = (currentIndex + 1) % messages.length;
}, 0, 30, TimeUnit.SECONDS);
//when you want to stop it (e.g. when the bot is stopped)
threadPool.shutdown();

At first, a thread pool is created that allows scheduling of tasks.

This thread pool could also be used for other tasks.

In this example, this is done using a single thread. If you want to use multiple threads, you can use Executors.newScheduledThreadPool(numberOfThreads);.

After this, you call ScheduledExecutorService#scheduleWithFixedDelay what runs the provided Runnable every 30 seconds.

If you want it to automatically stop when the application stops without calling shutdown(), you can tell it to use daemon threads by specifying the ThreadFactory:

ScheduledExecutorService threadPool = Executors.newSingleThreadScheduledExecutor(r->{
    Thread t=new Thread(r);
    t.setDaemon(true);
    return t;
});

Upvotes: 1

Related Questions