iT邦幫忙

2024 iThome 鐵人賽

DAY 20
0
Software Development

我命由我不由語言 java爬蟲挑戰系列 第 20

java爬蟲挑戰 Day 20 - 使用EmbedBuilder呈現!help指令

  • 分享至 

  • xImage
  •  

開始之前,先說明今天遇到的問題

處理Spring循環依賴

先付上錯誤訊息
https://ithelp.ithome.com.tw/upload/images/20240906/20168635EmBwrh3a3f.png

https://ithelp.ithome.com.tw/upload/images/20240906/20168635Hv7hI7tmBr.png

目前建立 Discord Bot 的Java Bean會同時進行兩個動作:

建立 Java Bean 之 DiscordBotService

  • DiscordBotService: 初始化 JDA
  • JDA 中加入 DiscordBotListener
  • 實作使用 JDA 發送訊息

建立 Java Bean 之 DiscordBotListener

DiscordBotListener: 在事件觸發時使用 DiscordBotService 發送訊息

發生了彼此依賴彼此的循環。為了解決這個問題,我最終選擇在 Service 中自行建立一個新的 JDA,也就是說,我建立了兩個 JDA:一個用來接收訊息,另一個用來發送訊息。

變成只有DiscordBotListener依賴DiscordBotService

大致如下,詳細的還是要看我的git了。

  • 建立一個新的java bean處理DiscordBotListener
@PostConstruct
public void init() throws Exception {
    JDABuilder builder = JDABuilder.createDefault(discordToken);
    builder.enableIntents(GatewayIntent.MESSAGE_CONTENT);
    builder.addEventListeners(discordBotListener);
    builder.build();
}
  • DiscordBotService自己使用自己的JDA
@PostConstruct
public void init() throws Exception {
    JDABuilder builder = JDABuilder.createDefault(discordToken);
    jda = builder.build();
}

這次的做法比較臨時,未來有機會我會深入研究其他更優雅的解決方案。

使用 EmbedBuilder 呈現 !help 指令

接下來我們來實作 !help 指令,這個指令會使用 EmbedBuilder 來顯示 Bot 支援的所有指令集,以便用戶更直觀地了解可以使用的功能。

DiscordBotCommandServiceImpl

實作helpCommand,這裡的 helpCommand 方法會建立一個 EmbedBuilder 物件,並設定訊息的標題、描述、各指令的詳細說明,最後設置訊息的顏色。

@Override
public EmbedBuilder helpCommand() {
    EmbedBuilder embedBuilder = new EmbedBuilder();
    embedBuilder.setTitle("Bot 指令集");
    embedBuilder.setDescription("以下是本 Bot 支援的所有指令:");

    // 添加指令詳細說明
    embedBuilder.addField("`!help`", "顯示所有可用指令的詳細說明。", false);
    embedBuilder.addField("`!sub`", "訂閱租屋資訊推播,當符合條件的租屋資訊出現時,通知使用者。範例: `!sub`", false);
    embedBuilder.addField("`!unsub`", "解除訂閱租屋資訊推播。範例: `!unsub`", false);
    embedBuilder.addField("`!reset`", "清除使用者目前設定的所有搜尋條件。範例: `!reset`", false);
    embedBuilder.addField("`!info`", "顯示使用者目前設定的條件,包括訂閱的房型、價格範圍、地區等。範例: `!info`", false);
    embedBuilder.addField("`!sp_room`", "指定房型條件。可選項: 不限, 整層住家, 獨立套房, 分租套房, 雅房, 車位, 其他。範例: `!sp_room 整層住家 獨立套房`", false);
    embedBuilder.addField("`!sp_price`", "指定價格區間,格式為 最低價格~最高價格。範例: `!sp_price 10000~20000`", false);
    embedBuilder.addField("`!sp_address`", "指定搜尋地區或地址。可選項: 大安區, 內湖區, 士林區, 等。範例: `!sp_address 內湖區`", false);
    embedBuilder.addField("`!sp_floor`", "指定樓層。範例: `!sp_floor 4`", false);
    embedBuilder.addField("`!sp_item`", "指定房屋設備要求。可選項: 冰箱, 洗衣機, 等。範例: `!sp_item 冰箱 洗衣機`", false);

    // 設定訊息顏色
    embedBuilder.setColor(0x00FF00); // 綠色

    return embedBuilder;
}

DiscordBotListener

onMessageReceived 事件觸發時,我們會檢查訊息是否為指令,並且以 ! 開頭。如果指令是 !help,我們會調用 helpCommand 來生成一個 EmbedBuilder,並通過 discordBotService 將訊息發送至所在的頻道。

@Autowired
DiscordBotService discordBotService;

@Autowired
DiscordBotCommandService discordBotCommandService;

Logger log = LoggerFactory.getLogger(ListenerAdapter.class);

@Override
public void onMessageReceived(MessageReceivedEvent event) {
    // 過濾掉機器人傳送的訊息
    if (event.getAuthor().isBot())
        return;
    String message = event.getMessage().getContentRaw();
    if (message.startsWith("!")) {
        String channelId = event.getChannel().getId();
        log.info("所在頻道為: {}", channelId);
        String userId = event.getAuthor().getId();
        log.info("下指令者為: {}", userId);

        log.info("收到指令: {}", message);
        if (message.startsWith("!help")) {
            EmbedBuilder embed = discordBotCommandService.helpCommand();
            discordBotService.sendMessage(channelId, embed);
        }
        
    }
}

實際呈現

https://ithelp.ithome.com.tw/upload/images/20240906/20168635RB7CvMmP8X.png
可以看到我們使用了EmbedBuilder後,客戶可以更清楚的了解如何的使用機器人的指令。

git 現狀

https://ithelp.ithome.com.tw/upload/images/20240906/20168635cbuAUfSPEY.png

小結

今天我們實作了使用 EmbedBuilder 呈現 !help 指令,並解決了 JDA 初始化與事件監聽器的循環依賴問題。透過使用 EmbedBuilder,我們可以更美觀地呈現指令訊息,提升了用戶體驗。
明天將會繼續實作其他指令。


上一篇
java爬蟲挑戰 Day 19 - Discord Bot !help 指令規劃
下一篇
java爬蟲挑戰 Day 21 - 完成訂閱及解除訂閱的指令
系列文
我命由我不由語言 java爬蟲挑戰30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言