哈囉大家好,這裡是在回顧自己舊文章的小編過路君子
小編正在回顧自己以前寫的 Wicket 系列文章,恩,沒錯,仍是 Java 這個程式語言
小編所使用的 JDA 版本是:5.0.0-beta.20。
小編之前一直都是使用 discord.py 的 command_prefix 來實現命令的,而小編也比較喜歡這個方式,但似乎 JDA 並未提供相關的設置可以使用,小編目前也在慎重的考慮是否手動實現相關的功能,目前有考慮使用 Map 來達成快速索引以重現相關的功能。
但有一點是可以肯定的,就是那個 reply 是真的很醜,還不如直接 sendMessage() 來的好看。
所以小編就想在 reply 之後刪除剛剛 reply 的訊息並重新傳送一段新的訊息到聊天室內。
但這個時候就又遇到新的問題了,就是如果直接去呼叫 getIterableHistory() 的話,有可能會取得使用者的命令訊息而非機器人的 reply 訊息。
為了解決這個問題,我們勢必得等到整個 reply 或 sendMessage 的 Async 完成之後,再去取得頻道的訊息才行。
那在這邊小編提供兩種情況下的使用。
分別是使用 sendMessage() 和事件的響應,例如 onSlashCommandInteraction 等等事件,順手再各提供一種 onSuccess() 的變體寫法。
刪除sendMessage的訊息
使用 queue()
import java.util.List; import net.dv8tion.jda.api.JDA; import java.util.stream.Collectors; import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; public void deleteSentMessage(JDA bot) { // Get the channel long channelID = 9000000000L; TextChannel channel = bot.getTextChannelById(channelID); // Callback values class type is: // net.dv8tion.jda.internal.interactions.InteractionHookImpl channel.sendMessage("will delete").queue(interactionHookImpl -> { try { // Try to get the last message on that channel. List<Message> message = channel.getIterableHistory().takeAsync(1).thenApply(list -> list.stream().collect(Collectors.toList())).get(); // If successful, get the corresponding message. if(message.isEmpty()) return; Message last = message.get(0); // Delete it. last.delete().queue(); } catch(Exception error) {System.out.println(error);} }); }
使用 onSuccess()
import java.util.List; import net.dv8tion.jda.api.JDA; import java.util.stream.Collectors; import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; public void deleteSentMessage(JDA bot) { // Get the channel long channelID = 9000000000L; TextChannel channel = bot.getTextChannelById(channelID); // Callback values class type is: // net.dv8tion.jda.internal.interactions.InteractionHookImpl channel.sendMessage("will delete").onSuccess(interactionHookImpl -> { try { // Try to get the last message on that channel. List<Message> message = channel.getIterableHistory().takeAsync(1).thenApply(list -> list.stream().collect(Collectors.toList())).get(); // If successful, get the corresponding message. if(message.isEmpty()) return; Message last = message.get(0); // Delete it. last.delete().queue(); } catch(Exception error) {System.out.println(error);} }).queue(); }
大同小異,就是呼叫函數的時機不同而已,整體結構都一樣,依照個人喜好使用即可。
刪除由事件回應(event reply)的訊息
小編在此同樣提供兩種寫法,以供各位自行取用。
由於 JDA 內的事件眾多,而每個事件之間又有些微的差異,這邊小編僅以 onSlashCommandInteraction 這個事件作為範例。
更詳細的訊息可以參考 javadoc 的 ListenerAdapter 說明頁面。
(所有圖片點擊都可以放大、變高清)
使用 queue()
import java.util.stream.Collectors; import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.hooks.ListenerAdapter; import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; public class DiscordEvents extends ListenerAdapter { @Override public void onSlashCommandInteraction(SlashCommandInteractionEvent event) { // callback values class type is: // net.dv8tion.jda.internal.interactions.InteractionHookImpl event.reply("Test!").queue(interactionHookImpl -> { try { // Try to get the message that just replied Message message = event.getChannel().getIterableHistory().takeAsync(1).thenApply(list -> list.stream().collect(Collectors.toList())).get().get(0); // If the user is not the bot itself, // the delete command is not executed. if(last.getAuthor().getIdLong() != event.getJDA().getSelfUser().getIdLong()) return; // Delete it. last.delete().queue(); } catch(Exception error) {System.out.println(error);} }); } }
使用 onSuccess()
import java.util.stream.Collectors; import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.hooks.ListenerAdapter; import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; public class DiscordEvents extends ListenerAdapter { @Override public void onSlashCommandInteraction(SlashCommandInteractionEvent event) { // callback values class type is: // net.dv8tion.jda.internal.interactions.InteractionHookImpl event.reply("Test!").onSuccess(interactionHookImpl -> { try { // Try to get the message that just replied Message message = event.getChannel().getIterableHistory().takeAsync(1).thenApply(list -> list.stream().collect(Collectors.toList())).get().get(0); // If the user is not the bot itself, // the delete command is not executed. if(last.getAuthor().getIdLong() != event.getJDA().getSelfUser().getIdLong()) return; // Delete it. last.delete().queue(); } catch(Exception error) {System.out.println(error);} }).queue(); } }
後記
細心的人應該已經發現了,小編提供的程式碼之中都有些微的差異,而非完全相同,是小編故意的。
不同的寫法因應不同的場景,依照個人需求斟酌使用吧。