javanullpointerexceptiondiscorddiscord-jdamessage-channel

JDA Discord bot, read last message of textchannel


I want that my Discord jda bot reads the last message of an textchannel after starting.

So I call :

textChannel.getHistory().getMessageById(config.getLatestMessageId());

The MessageHistory class doesn't have an getLatestMessage method somehow. And for some reason textChannel.getHistory() is always empty and therefore always return null.

is there an other way to read messages (written before the bot was started).

Some aditional information: The textchannel is the correct textchannel. it is not empty, and I also tried writing new messages while the bot is active. But the messagehistory is always empty.

Also something I find weird: textchannel.gethistory().isempty() is true and textchannel.hasLastMessage is true as well.


Solution

  • EDIT:

    Do the following:

    channel.getHistory().retrievePast(1).queue(messages -> {
        // messages (list) contains all received messages
        // Access them in here
        // Use for example messages.get(0) to get the received message
        // (messages is of type List)
    });
    // DON'T access the received messages outside here
    // If you use queue the received messages WON'T be available directly after the call
    

    PREVIOUS:

    If I do the following on my bot it works:

    channel.getHistory().retrievePast(1).queue(messages -> {
        if (messages.size() > 0) System.out.println(messages.get(0).getContentDisplay());
    });
    

    After the call succeeded and the lambda is executed, calling

    channel.getHistory().getRetrievedHistory()
    

    should return the received chat history


    You can also execute the action directly and block the current thread until the message history was received by doing the following:

    MessageHistory h = channel.getHistory();
    h.retrievePast(1).complete();
    List<Message> ml = h.getRetrievedHistory();
    if (ml.size() > 0) System.out.println(ml.get(0).getContentDisplay());
    

    but I don't recommand doing this, since it will block the current thread. Use the code in the first part of my answer instead, which won't block execution, and will fill the message history with data and once its ready it will call the lambda.

    Notice that I'm passing in 1 as an argument for the call to 'retrievePast'. This will only receive the last message send inside the text channel. I guess you can't receive the entire text channel, since it would be to expensive to store all the sent data in the RAM or it would just take to long.