如何用面向对象方式实现Java JDA Discord频道自动化管理?
解决方案实现步骤
1. 定义核心枚举与内容载体类
先实现Ob_Type枚举覆盖所有需处理的消息类型,再创建ChannelContentData作为统一内容容器,存储类型、执行顺序和对应数据:
// 消息类型枚举 public enum Ob_Type { TEXT_MESSAGE, EMBEDDED_MESSAGE_WITHOUT_BUTTONS, EMBEDDED_MESSAGE_WITH_BUTTONS, FILE_MESSAGE // 补充适配文件发送需求 } // 统一内容管理类 public class ChannelContentData implements Comparable<ChannelContentData> { private final Ob_Type type; private final int indexOrder; // 存储对应类型的数据 private String textContent; private MessageEmbed embed; private List<ActionRow> actionRows; private File file; private String fileDescription; // 私有构造,通过Builder模式创建实例(避免冗余构造) private ChannelContentData(Builder builder) { this.type = builder.type; this.indexOrder = builder.indexOrder; this.textContent = builder.textContent; this.embed = builder.embed; this.actionRows = builder.actionRows; this.file = builder.file; this.fileDescription = builder.fileDescription; } // 实现排序接口,按indexOrder排序 @Override public int compareTo(ChannelContentData other) { return Integer.compare(this.indexOrder, other.indexOrder); } // Getter方法 public Ob_Type getType() { return type; } public String getTextContent() { return textContent; } public MessageEmbed getEmbed() { return embed; } public List<ActionRow> getActionRows() { return actionRows; } public File getFile() { return file; } public String getFileDescription() { return fileDescription; } // Builder内部类 public static class Builder { private final Ob_Type type; private final int indexOrder; private String textContent; private MessageEmbed embed; private List<ActionRow> actionRows; private File file; private String fileDescription; public Builder(Ob_Type type, int indexOrder) { this.type = type; this.indexOrder = indexOrder; } public Builder textContent(String text) { this.textContent = text; return this; } public Builder embed(MessageEmbed embed) { this.embed = embed; return this; } public Builder actionRows(List<ActionRow> rows) { this.actionRows = rows; return this; } public Builder file(File file, String description) { this.file = file; this.fileDescription = description; return this; } public ChannelContentData build() { return new ChannelContentData(this); } } }
2. 完善抽象基类HandledChannelBot
抽象类封装频道创建、权限配置、内容管理和批量发送的核心逻辑,具体频道类只需实现内容填充和频道名称定义:
import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.TextChannel; import net.dv8tion.jda.api.requests.restaction.ChannelAction; import net.dv8tion.jda.api.Permission; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.EnumSet; public abstract class HandledChannelBot { protected final Guild guild; protected TextChannel targetChannel; protected final List<ChannelContentData> contentList = new ArrayList<>(); protected HandledChannelBot(Guild guild) { this.guild = guild; } // 抽象方法:定义频道名称 protected abstract String getChannelName(); // 抽象方法:填充频道内容(子类实现) protected abstract void populateChannelContent(); // 创建带权限限制的频道:仅机器人可发送消息 public void createLockedChannel() { ChannelAction<TextChannel> channelAction = guild.createTextChannel(getChannelName()); // 配置权限:拒绝普通成员发消息,允许机器人发消息 channelAction.addPermissionOverride(guild.getPublicRole(), null, EnumSet.of(Permission.MESSAGE_SEND)) .addPermissionOverride(guild.getSelfMember(), EnumSet.of(Permission.MESSAGE_SEND), null); targetChannel = channelAction.complete(); // 填充内容并按顺序发送 populateChannelContent(); sendContentInOrder(); } // 添加内容到列表 protected void addContent(ChannelContentData content) { contentList.add(content); } // 按顺序发送所有内容 private void sendContentInOrder() { // 按indexOrder排序 Collections.sort(contentList); for (ChannelContentData content : contentList) { switch (content.getType()) { case TEXT_MESSAGE: targetChannel.sendMessage(content.getTextContent()).queue(); break; case EMBEDDED_MESSAGE_WITHOUT_BUTTONS: targetChannel.sendMessageEmbeds(content.getEmbed()).queue(); break; case EMBEDDED_MESSAGE_WITH_BUTTONS: targetChannel.sendMessageEmbeds(content.getEmbed()) .setActionRows(content.getActionRows()) .queue(); break; case FILE_MESSAGE: targetChannel.sendFile(content.getFile(), content.getFileDescription()).queue(); break; } } } }
3. 实现具体频道类
创建3个继承自HandledChannelBot的子类,各自实现频道名称和内容填充逻辑:
示例1:欢迎频道
import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.interactions.components.buttons.Button; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.MessageEmbed; import java.awt.Color; import java.util.List; public class WelcomeChannel extends HandledChannelBot { public WelcomeChannel(Guild guild) { super(guild); } @Override protected String getChannelName() { return "欢迎频道"; } @Override protected void populateChannelContent() { // 1. 发送欢迎文本消息 addContent(new ChannelContentData.Builder(Ob_Type.TEXT_MESSAGE, 1) .textContent("🎉 欢迎加入服务器!请仔细阅读下方规则哦~") .build()); // 2. 发送带按钮的规则嵌入 MessageEmbed rulesEmbed = new EmbedBuilder() .setTitle("服务器规则") .addField("规则1", "禁止刷屏", false) .addField("规则2", "禁止广告", false) .setColor(Color.GREEN) .build(); List<ActionRow> buttons = List.of( ActionRow.of(Button.success("confirm_rules", "已阅读规则")) ); addContent(new ChannelContentData.Builder(Ob_Type.EMBEDDED_MESSAGE_WITH_BUTTONS, 2) .embed(rulesEmbed) .actionRows(buttons) .build()); } }
示例2:官方公告频道
import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.MessageEmbed; import java.awt.Color; import java.time.OffsetDateTime; import java.io.File; public class AnnouncementChannel extends HandledChannelBot { public AnnouncementChannel(Guild guild) { super(guild); } @Override protected String getChannelName() { return "官方公告"; } @Override protected void populateChannelContent() { // 发送无按钮的公告嵌入 MessageEmbed announcementEmbed = new EmbedBuilder() .setTitle("📢 服务器更新公告") .setDescription("本次更新新增了欢迎频道和规则频道") .setColor(Color.BLUE) .setTimestamp(OffsetDateTime.now()) .build(); addContent(new ChannelContentData.Builder(Ob_Type.EMBEDDED_MESSAGE_WITHOUT_BUTTONS, 1) .embed(announcementEmbed) .build()); // 发送更新日志文件 File updateLog = new File("update_log.txt"); addContent(new ChannelContentData.Builder(Ob_Type.FILE_MESSAGE, 2) .file(updateLog, "更新日志详情") .build()); } }
示例3:资源下载频道
import net.dv8tion.jda.api.entities.Guild; import java.io.File; public class ResourceChannel extends HandledChannelBot { public ResourceChannel(Guild guild) { super(guild); } @Override protected String getChannelName() { return "资源下载"; } @Override protected void populateChannelContent() { addContent(new ChannelContentData.Builder(Ob_Type.TEXT_MESSAGE, 1) .textContent("📥 以下是服务器专属资源,点击下载即可") .build()); File resourcePack = new File("server_resource_pack.zip"); addContent(new ChannelContentData.Builder(Ob_Type.FILE_MESSAGE, 2) .file(resourcePack, "服务器资源包") .build()); } }
4. 触发频道创建
在JDA就绪事件中初始化三个频道:
import net.dv8tion.jda.api.events.session.ReadyEvent; import net.dv8tion.jda.api.hooks.ListenerAdapter; import net.dv8tion.jda.api.entities.Guild; public class BotReadyListener extends ListenerAdapter { @Override public void onReady(ReadyEvent event) { Guild guild = event.getJDA().getGuildById("你的服务器ID"); if (guild != null) { new WelcomeChannel(guild).createLockedChannel(); new AnnouncementChannel(guild).createLockedChannel(); new ResourceChannel(guild).createLockedChannel(); } } }
内容的提问来源于stack exchange,提问作者SpicyCodexff00
相关产品推荐
相关产品推荐

