[精讚] [會員登入]
663

【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

你可能感興趣的文章

【Maven / Jython】建立可直接執行的JAR檔案 以小編的前一篇文章為基礎,加了一些新東西進去,就變成另一個樣貌了

【JAVA】[java.lang.Class]如何不透過new來實體化class 在某些極端狀態下,我們沒有辦法直接將實體化後的 Object 傳入函數內,只能採用傳入 Class 在實體化成物件這種極端的方式來進行

【Maven】用Maven來託管Wildfly/jBoss的部屬(deploy)、解部屬(undeploy) 極簡版,給未來想要抄作業的小編自己,完整的一切設定檔,可以依照個人需求作增刪。

【Discord bot 2.0.1】(discord.ui.View)如何將舊機器人升級至目前最新版本 很多時候升級軟體是為了讓別人覺得你的程式很先進,但這次卻是因為要使用某個新功能

【Maven】如何創建一個簡單可部屬的WAR檔 滿重要的一個大功能,在使用JAVA網頁伺服器的時候一定會需要這個WAR檔來進行部屬

【JDA/discord bot】如何獲得訊息中的圖片和影片並儲存或轉傳 如何將訊息中的圖片或影片之類的多媒體提取出來之後,再進行相關的處理

我有話要說

>>

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

訪客留言

[無留言]

隨機好文

高捷少女:布拉格體驗㊦ 「各位想到盧卡站的乘客,請到我們左手邊排隊!」婕兒大聲地喊道。     「這孩子怎麼穿著地鐵站制服?童工嗎?」一位大嬸歪頭問道。

高捷少女:地下城的探險少女① 婕兒心中一奇,便走上前看著仔細。那塊凹進去的地方中心大約三公分厚,越往邊緣就越淺,圓型直徑十五公分。婕兒拿出銅盤對比一下,發現兩者大小竟然一致,銅盤似乎能夠完整的嵌進去。     婕兒看著凹槽,心中

高捷少女:地下城的探險少女③ 過了十分鐘後,前方的天花板滴下一滴水珠,發出「噠」一聲響亮地落在石地上,讓大家嚇一跳。     「什麼嘛,只是水珠而已。」艾米撫著胸口噓了一聲。     忽然間,耐耐的臉色發白起來。「各位,你們看

高捷少女:地下城的探險少女⑤ 小穹寫好後,耐耐看了一遍。「我想我應該辦得到。」她說完跪坐在地上,然後把古箏安放在大腿上,並將樂譜放在前面的地板。「要開始囉。」耐耐閉上眼睛,深呼吸一口氣,小穹等人在一旁看著她,心中暗自替她打氣。

高捷少女:耐耐的新年驚喜(終) 他的話說到一半,便被一陣響亮的哭聲打住了,是從產房中的傳來的。聽起來就像嬰兒的哭聲。 婕兒、小穹跟艾米也被哭聲吵醒,婕兒揉揉眼睛,看向呆若木雞的耐耐父女。「剛剛的聲音,該不會是……」