检测更新消息失败

时间:2019-08-22 18:42:12

标签: java discord-jda

我正在开发一个Discord机器人,在该机器人上应该更新或创建特定消息(如果不存在)。如果该消息已被具有访问权限的某人删除,则会出现问题。创建一个悬空引用,并在该时间更新异常。如何检测当前通道中是否不存在具有特定ID的消息?

这是当前代码:

    TextChannel scoreChannel = channel.getGuild().getTextChannelsByName(gameType + "-ladder", true).get(0);
    String id = ScoreboardController.getScoreboardMessageId(gameType);
    if (id == null)
        scoreChannel.sendMessage(eb.build()).queue();
    else {
        scoreChannel.editMessageById(id, eb.build()).queue(); // this part can fail
    }

请注意,getScoreboardMessageId从数据库中获取先前存储的ID。

我需要按标题查询消息,或者通过其他方式查找消息是否丢失。


我试图像这样检索嵌入的消息,但没有成功:

    List<Message> messages = scoreChannel.getHistory().getRetrievedHistory();

After some more searching I managed to do this which works but is not Async:

 TextChannel scoreChannel = channel.getGuild().getTextChannelsByName(gameType + "-ladder", true).get(0);
        List<Message> messages = new MessageHistory(scoreChannel).retrievePast(10).complete();
        boolean wasUpdated = false;
        for (Message msg : messages) {
            if (msg.getEmbeds().get(0).getTitle().equals(content[0])) {
                scoreChannel.editMessageById(msg.getId(), eb.build()).queue();
                wasUpdated = true;
            }
        }
        if (!wasUpdated)
            scoreChannel.sendMessage(eb.build()).queue();

1 个答案:

答案 0 :(得分:1)

您可以使用队列的失败回调:

channel.editMessageById(messageId, embed).queue(
    (success) -> {
        System.out.printf("[%#s] %s (edited)\n",
                   success.getAuthor(), success.getContentDisplay()); // its a Message
    },
    (failure) -> {
        failure.printStackTrace(); // its a throwable
    }
);

被调用的失败回调意味着编辑失败。如果消息不再存在或发生某些连接问题,则可能发生这种情况。请注意,您可以为这两个回调中的任何一个传递null,以简化仅应处理失败或仅成功的情况。

文档建议getRetrievedHistory()的方法返回一个空列表,除非您先前使用了都返回的 retrievePast retrieveFuture RestAction<List<Message>> 。这意味着您必须使用:

history.retrievePast(amount).queue((messages) -> {
    /* use messages here */
});

该数量限制为每个呼叫最多100条消息。 channel.getIterableHistory().takeAsync(amount)提供了一种不受此限制的更简单的API,该API返回CompletableFuture,并且可以与thenAccept结合使用。

最好使用channel.retrieveMessageById(messageId),它仅检索消息,如果消息不存在则失败。但是,在您的情况下则不需要此操作,因为您可以通过id来编辑消息,并且可以仅使用该消息的失败响应,而不必遇到TOCTOU Problem