[精讚] [會員登入]
508

【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

你可能感興趣的文章

【Docker hub】[Linux]以IPv6來pull容器(container)吧! 在一個 IPv6 還不盛行的年代,做事情總是特別麻煩

【MySQL Workbench】如何透過TCP/IP進行SSL連線到遠端MySQL資料庫 通常MySQL伺服器都不是只提供某人連線,而是多人都可以連線進來使用,這時就不能繼續使用localhost的那種寫法

【Wildfly/jBoss】[Linux] 如何從無到有建立Wildfly網頁伺服器 包含一切所需的指令

【C】〔無條件捨去〕如何忽略float數據 直接儲存成int型態(數據100%不失真) a148: You Cannot Pass?! 解題時所意外研究出來的神奇寫法,懂了原理之後要自行改寫成四捨五入或無條件進位應該就簡單了吧!

【C++】如何解決TLE,換句話說便是加速cin, cout的執行速度 [ZERO JUDGE](UVa) a159: 11743 - Credit Check 題目練習和副程式練習

【C++】使用struct array和一維int array模擬二維int array 主要是因為用sort去排序int array的二維陣列小編懶得研究,於是就研究了一種維持一維陣列但是有二維陣列效果的程式,小編就廢~~

我有話要說

>>

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

訪客留言

[無留言]

隨機好文

高捷少女:美麗島的守護者② 這是在亦晨離開前的下午拍的,當時亦晨在美麗島跟小穹艾米等人在美麗島散步,為離開前補充一些回憶,這時剛好經過的小雅被艾米抓過來,做為同樣是高捷新人的她倆一同拍了一張紀念照。說起來她跟亦晨並不太熟,不過也

婕兒──她的青春③ 「墮天使穹音!」婕兒拿出平底鍋。 耐耐憋著笑搖搖頭。「不是喔,她是我的……我的……」 「替身。」小穹小聲提醒忘記台詞的耐耐。

【數學】徐氏數學簡明講義(三) 第二章 直線與園 P2.1-17 Q34 34.設P(x , y)為座標平面上一點,   且滿足,則P點的位置可能在哪裡?   (1)第一象限(2)第二象限(3)

艾米莉亞和高捷戀旅⑤ 「小滷,這位先生是誰呢?」果果問道。「○○!」小滷說:「他是曾經在中國四川省的國營餐廳擔任大廚的上等大廚師,是一位精通川菜的料理達人。據說學過中國料理的人,沒有一個不知道他。」

小穹‧動畫化‧體驗記① 某個星期六的下午,娟姊所在的某間咖啡廳內,傳來了一陣雀躍的交談聲。「這是當然的啊。」娟姊高興地說:「上級真是太不夠意思了,居然現在才告訴我。」「為執行長說您跟她們一定會同意,所以才事先決定好計畫的大要