Java JDA Discord机器人,读取textchannel的最后一条消息

Java JDA Discord机器人,读取textchannel的最后一条消息,java,nullpointerexception,discord,discord-jda,message-channel,Java,Nullpointerexception,Discord,Discord Jda,Message Channel,我希望我的Discord jda bot在启动后读取textchannel的最后一条消息 因此,我呼吁: textChannel.getHistory().getMessageById(config.getLatestMessageId()); MessageHistory类没有getLatestMessage方法。 由于某些原因,textChannel.getHistory()始终为空,因此始终返回null 是否有其他读取消息的方法(在启动bot之前编写) 一些传统信息: textchann

我希望我的Discord jda bot在启动后读取textchannel的最后一条消息

因此,我呼吁:

textChannel.getHistory().getMessageById(config.getLatestMessageId());
MessageHistory类没有getLatestMessage方法。 由于某些原因,textChannel.getHistory()始终为空,因此始终返回null

是否有其他读取消息的方法(在启动bot之前编写)

一些传统信息: textchannel是正确的textchannel。 它不是空的,我还尝试在bot处于活动状态时编写新消息。 但是消息历史总是空的

还有一件事我觉得很奇怪:
textchannel.gethistory().isempty()
为true 和
textchannel.hasLastMessage
也是正确的。

编辑: 请执行以下操作:

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
MessageHistory h = channel.getHistory();
h.retrievePast(1).complete();
List<Message> ml = h.getRetrievedHistory();
if (ml.size() > 0) System.out.println(ml.get(0).getContentDisplay());
以前的: 如果我在我的机器人上执行以下操作,它将正常工作:

channel.getHistory().retrievePast(1).queue(messages -> {
    if (messages.size() > 0) System.out.println(messages.get(0).getContentDisplay());
});
调用成功并执行lambda后,调用

channel.getHistory().getRetrievedHistory()
应返回收到的聊天记录


您还可以通过执行以下操作直接执行操作并阻止当前线程,直到收到消息历史记录:

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
MessageHistory h = channel.getHistory();
h.retrievePast(1).complete();
List<Message> ml = h.getRetrievedHistory();
if (ml.size() > 0) System.out.println(ml.get(0).getContentDisplay());
MessageHistory h=channel.getHistory();
h、 retrievepass(1.complete();
List ml=h.getRetrievedHistory();
if(ml.size()>0)System.out.println(ml.get(0.getContentDisplay());
但我不建议这样做,因为它会阻止当前线程。改为使用我答案第一部分中的代码,它不会阻止执行,并将用数据填充消息历史记录,一旦准备好,它将调用lambda

请注意,我传入1作为调用“retrievePast”的参数。这将只接收文本频道内发送的最后一条消息。
我猜您无法接收整个文本频道,因为将所有发送的数据存储在RAM中会很昂贵,或者需要很长时间。

您的机器人是否具有读取邮件历史记录所需的权限?您在将机器人添加到discord服务器时指定了哪些权限我为他授予了NOOK的管理员权限。给我一点时间我想你应该先让dicord把历史填上data@Dude2345您应该使用第一个,但是消息历史记录只有在收到历史记录后才可用,这意味着您将只能访问lambda主体内部的历史记录(我在这里完成了系统输出)当您使用队列向discord api发送请求时,它将在另一个线程上处理该请求。意思是System.out.println(“messages”+messagesTest);将在另一个线程接收结果之前调用。它将按预期将所有收到的消息添加到列表中,但在您的方法完成之后executing@Overridepublic void onGuildMessageReceived(@NotNull GuildMessageReceivedEvent事件){super.onGuildMessageReceived(事件);TextChannel TextChannel=event.getChannel();TextChannel.getHistory().retrievePast(1)。队列(消息->{List messagesTest=new ArrayList();messagesTest.addAll(textChannel.getHistory().getRetrievedHistory());System.out.println(“messages”+messagesTest);});}确实如此,以便在不阻塞当前线程的情况下处理您的请求。因为这意味着bot一次只能处理一个请求。如果您使用“完成”而不是“队列”,它将阻塞当前线程,但结果将在调用后直接可用(它将阻塞直到结果就绪,但它仍将在另一个线程上执行所有处理,因为到discord服务器的整个连接都在另一个线程上运行)。这也是为什么在关闭bot时应该调用JDA实例上的shutdown,因为这将停止正在运行的线程。为了保持与discord服务器的连接打开(因为您不想为每个litte请求重新打开连接),同时也不会阻止在curren线程上执行,整个服务器/客户端连接需要在另一个线程上运行。如果您使用队列请求某些内容,它将在某个位置列出该请求,一旦另一个线程准备好处理另一个任务,它将处理您的任务