開始之前,先說明今天遇到的問題
先付上錯誤訊息
目前建立 Discord Bot 的Java Bean會同時進行兩個動作:
DiscordBotListener: 在事件觸發時使用 DiscordBotService 發送訊息
發生了彼此依賴彼此的循環。為了解決這個問題,我最終選擇在 Service 中自行建立一個新的 JDA,也就是說,我建立了兩個 JDA:一個用來接收訊息,另一個用來發送訊息。
大致如下,詳細的還是要看我的git了。
@PostConstruct
public void init() throws Exception {
JDABuilder builder = JDABuilder.createDefault(discordToken);
builder.enableIntents(GatewayIntent.MESSAGE_CONTENT);
builder.addEventListeners(discordBotListener);
builder.build();
}
@PostConstruct
public void init() throws Exception {
JDABuilder builder = JDABuilder.createDefault(discordToken);
jda = builder.build();
}
這次的做法比較臨時,未來有機會我會深入研究其他更優雅的解決方案。
接下來我們來實作 !help 指令,這個指令會使用 EmbedBuilder 來顯示 Bot 支援的所有指令集,以便用戶更直觀地了解可以使用的功能。
實作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;
}
當 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);
}
}
}
可以看到我們使用了EmbedBuilder後,客戶可以更清楚的了解如何的使用機器人的指令。
今天我們實作了使用 EmbedBuilder 呈現 !help 指令,並解決了 JDA 初始化與事件監聽器的循環依賴問題。透過使用 EmbedBuilder,我們可以更美觀地呈現指令訊息,提升了用戶體驗。
明天將會繼續實作其他指令。