[精讚] [會員登入]
400

【JDA/discord bot】取得頻道第一筆或最新(最後一筆)的歷史訊息

在不處理訊息的先後順序下取得相關的歷史訊息

分享此文連結 //n.sfs.tw/16361

分享連結 【JDA/discord bot】取得頻道第一筆或最新(最後一筆)的歷史訊息@小編過路君子
(文章歡迎轉載,務必尊重版權註明連結來源)
2024-02-15 15:04:43 最後編修
2024-02-15 02:36:50 By 過路君子
 

哈囉大家好,這裡是覺得Java很麻煩的小編過路君子

同樣的功能 Python3 都會提供好,但在 JDA 下都必須自行處理相關的問題

 

 

小編所使用的 JDA 版本是:5.0.0-beta.20,有看上一篇的人不用緊張,小編是真的換版本了。

為了以防萬一,小編在此統一事前聲明一下,以下的方式不會進行 Asynchronous 的等待,換句話說,若在查詢頻道訊息的歷史紀錄之前,有使用 sendMessage() 之類的函數傳送訊息的話,有可能會從倒數第二筆的訊息開始取得,而非從剛剛傳送的訊息開始取得。

若想要搭配 sendMessage() 之類的函數使用並正確的取得頻道可以參考小編的另一篇文章:【JDA/discord bot】刪除事件或slash(斜槓)指令的reply訊息

 

 

取得該頻道第一筆的歷史訊息

取得頻道中的第一條訊息比較簡單,因為已經有現成的函示可以呼叫並使用。

import java.util.List;
import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;


public void getFirstMessage(JDA bot)
{
    // Get the channel
    long channelID = 900000000L;
    TextChannel channel = bot.getTextChannelById(channelID);

    // If you want to get the first ten histories
    // Replace getHistoryFromBeginning(1) with getHistoryFromBeginning(10).
    channel.getHistoryFromBeginning(1).queue(history ->
    {
        if(history.isEmpty()) return;

        // Get all historical messages.
        // The number of messages is equal to the value in the getHistoryFromBeginning(n) above.
        List<Message> historyList = history.getRetrievedHistory();

        // The first message is at 0
        // The second message is at 1, and so on.
        Message first = historyList.get(0);

        // Get the message content
        String content = first.getContentDisplay();
    });
}

上方的範例程式碼僅僅只有取回頻道的第一條訊息。

若想要取得頻道的前十條訊息,僅需將上方的 getHistoryFromBeginning(1) 改為 getHistoryFromBeginning(10) 即可,其他數量的訊息也是同樣的動作。

基本上 historyList 的長度就會是 getHistoryFromBeginning 中所給定的數值,若不足,則是因為該頻道中沒有那麼多的訊息,可以使用 historyList.size() 來確認實際的訊息數量。

 

取得該頻道最後一筆的歷史訊息

相較於取得第一筆訊息的輕鬆,取得最後一筆的頻道訊息就稍稍有些麻煩了。

這也是小編為何要撰寫這篇文章,因為怕不寫下來之後小編自己又要花大量時間重新摸索。

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 getLastMessage(JDA bot)
{
    // Get the channel
    long channelID = 9000000000L;
    TextChannel channel = bot.getTextChannelById(channelID);

    try
    {
        // Get all historical messages.
        // The number of messages is equal to the value in the takeAsync(n) above.
        List<Message> message = channel.getIterableHistory().takeAsync(1).thenApply(list -> list.stream().collect(Collectors.toList())).get();
        
        // The last message in the countdown is at 0
        // The penultimate message is at 1, and so on.
        if(message.isEmpty()) return;
        Message lastone = message.get(0);
        
        // Get the message content
        String lastone = first.getContentDisplay();
    }
    catch(Exception error) {System.out.println(error);}
}

上方的程式碼僅會取回位在頻道的最後一條訊息。

但若在此之前有使用諸如 sendMessage() 之類的函式,有可能不會取回剛剛所傳送的訊息,因為以上的範例不會等待 Async 完成。

若需要等待相關的 Async 完成的話,可以去參考小編開頭所提到的文章,那篇便有去處理相關的問題。

 

若想要取回更多筆的資料,可以將上方範例中的 takeAsync(1) 中的數字替換為想要取回的歷史訊息數量。

例如若想要取回十筆的話,就改成 takeAsync(10) 就可以了!

 

 

 

後記

真的沒想到 JDA 竟然沒有提供如 getLastMessage() 這類的快捷函式以供使用,但就算提供了,依照 JDA 的尿性,說不定又是從快取中取得相關的資訊,然後可能結果也不是我們想要的。

但無奈 Java 的執行效率就是比 Python3 還要好,希望未來的 JDA 能越來越強大,讓偉大的 Java 再次崛起吧!

那至於小編會不會考慮 discord.js 呢?雖然小編知道 Node.js 的強大之處,但至少目前是不會的,就讓 Javascript 停留在網頁上吧。

END

你可能感興趣的文章

【Minecraft】[CoreProtect|BungeeCord]如何重新命名世界或維度名稱 當只有一個伺服器的時候,問題往往處理起來非常簡單,但是一旦當伺服器成長至兩台以上,事情便開始有趣了起來

【Docker&Wildfly】(bitnami/wildfly)如何從零開始創建網頁伺服器 使用他人的 docker image 來架設我們的 wildfly web server

【Wicket】[nonce]如何導入css以及javascript 如果只是用一般的 HTML link 或是 script 標籤來寫,會被 CSP 擋住,禁止加載資源,那我們除了關閉 CSP 以外還有沒有辦法來解決呢?

【C++】SFML安裝於Microsoft Visual Studio 2019 此方法僅適用單個C++專案,因為一次就適用整台電腦的方式有人寫了,而且寫得非常不錯。

【Maven】如何夾帶檔案至Jar內以及其讀取方式 想要讀取一個外部的文字文件?Maven是你的好幫手

【SeaChest & Synology】512e(Advanced Format / AF) 轉換至 4Kn 好不容易入手了一顆硬碟,但是卻無法使用,除了賣掉還有更好的方法嗎?

我有話要說

>>

限制:留言最高字數1000字。 限制:未登入訪客,每則留言間隔需超過10分鐘,每日最多5則留言。

訪客留言

[無留言]

隨機好文

高捷少女:小穹與果仁巧克力㊥ 艾咪臉上泛起笑容說:「妳知道嗎?就跟花語一樣,每一種巧克力也都有各自的涵義:薄荷巧克力代表初戀;卡通巧克力代表天真爛漫;而果仁巧克力代表的是窩心,還有想陪伴對方的心情,這在德國是女生之間在慶生時會彼此

【歌評】蓮台野夜行 - 魔術師梅莉(魔術師メリー)  對於同一首歌每一個人都有不同的見解,看看別人對於這一首歌的看法,說不定就可以聽出這首歌想要表達的事情!

【日翻中歌詞】ピースサイン(Peace Sign) 那一天從我們的頭頂 輕掠而過的那架飛機 有點不可思議 還記得 為何呢?毫無意義 

【想法】關於網路上的謾罵這檔事 網路是個自由的世界,每個人都享有平等的發言權,但是,請永遠記得,在網路上漫罵別人一定會留下證據的,就算之後刪文,你怎能確保對方沒有截圖存證?

艾米莉亞和高捷戀旅③ 「妳最好給我一個完整的理由,告訴我妳為什麼要這麼做。」艾米雙手叉腰,看著這位冒名參賽的後輩。「我會根據妳的說詞來判定妳違反規定的懲處。」