How can I make my Discord Bot pause for a specific user's reply using JDA?

I’m new to Java and trying to create a Discord bot using JDA. I want my bot to do this:

  1. Someone says “Hey Oranges!”
  2. Bot asks for their name
  3. Bot waits for that same person to reply
  4. Bot says “Hello [name]!”

Right now, my bot doesn’t wait for the user’s name. It just spits out everything at once:

Bot: What's your name? Or say "Quit"!
Bot: Hello Hey Oranges!!
Bot: Hold on a sec, UserNickname!

How can I make the bot wait for the original user’s input? Also, is there a way to add a timeout?

Here’s a simplified version of what I’ve tried:

public void onMessageReceived(MessageReceivedEvent event) {
    if (event.getAuthor().isBot()) return;
    
    String message = event.getMessage().getContentRaw();
    MessageChannel channel = event.getChannel();
    
    if (message.equals("Hey Oranges!")) {
        channel.sendMessage("What's your name? Or say \"Quit\"!").queue();
        
        // This part doesn't work as expected
        while (true) {
            String reply = event.getMessage().getContentRaw();
            if (reply.equals("Quit")) break;
            channel.sendMessage("Hello " + reply + "!").queue();
            break;
        }
    }
}

Any ideas on how to fix this? Thanks!

I’ve worked on similar Discord bots, and the key is to use event listeners and a state management system. Instead of a while loop, create a Map to store user states. When ‘Hey Oranges!’ is received, set the user’s state to ‘awaiting_name’ in the Map. Then, in your onMessageReceived method, check the user’s state before processing messages.

For timeouts, you can use a ScheduledExecutorService to clear the user’s state after a set period. This approach allows your bot to handle multiple conversations simultaneously without blocking.

Remember to handle edge cases, like users quitting mid-conversation or sending multiple ‘Hey Oranges!’ messages. With proper state management, your bot will feel much more responsive and natural in conversations.

I’ve faced a similar challenge when developing my Discord bot. The key is to use a message listener and a CompletableFuture to handle the user’s response asynchronously. Here’s a simplified approach that worked for me:

  1. Create a Map to store pending responses, keyed by user ID.
  2. In your onMessageReceived method, check if the user has a pending response.
  3. If they do, complete the future with their message.
  4. If not, start the conversation and add a pending response to the map.

This way, you can wait for the specific user’s reply without blocking the entire bot. You can also add a timeout using the orTimeout method on the CompletableFuture.

Remember to clean up the map entry once you’ve received the response or hit the timeout. This approach has served me well in creating interactive bot conversations.