diff --git a/src/main/java/com/hypherionmc/sdlink/core/managers/ChannelManager.java b/src/main/java/com/hypherionmc/sdlink/core/managers/ChannelManager.java index 6d23c34..51042f2 100644 --- a/src/main/java/com/hypherionmc/sdlink/core/managers/ChannelManager.java +++ b/src/main/java/com/hypherionmc/sdlink/core/managers/ChannelManager.java @@ -9,6 +9,7 @@ import com.hypherionmc.sdlink.core.discord.BotController; import com.hypherionmc.sdlink.core.messaging.MessageDestination; import lombok.Getter; import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel; import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel; import net.dv8tion.jda.api.entities.channel.middleman.StandardGuildChannel; import net.dv8tion.jda.api.entities.channel.middleman.StandardGuildMessageChannel; @@ -22,9 +23,9 @@ import java.util.HashMap; */ public class ChannelManager { - private static final HashMap> channelMap = new HashMap<>(); + private static final HashMap> channelMap = new HashMap<>(); @Getter - private static MessageChannel consoleChannel; + private static GuildMessageChannel consoleChannel; /** * Load configured channel, while always defaulting back to ChatChannel for channels that aren't configured @@ -34,9 +35,9 @@ public class ChannelManager { JDA jda = BotController.INSTANCE.getJDA(); - MessageChannel chatChannel = jda.getChannelById(MessageChannel.class, SDLinkConfig.INSTANCE.channelsAndWebhooks.channels.chatChannelID); - MessageChannel eventChannel = jda.getChannelById(MessageChannel.class, SDLinkConfig.INSTANCE.channelsAndWebhooks.channels.eventsChannelID); - consoleChannel = jda.getChannelById(MessageChannel.class, SDLinkConfig.INSTANCE.channelsAndWebhooks.channels.consoleChannelID); + GuildMessageChannel chatChannel = jda.getChannelById(GuildMessageChannel.class, SDLinkConfig.INSTANCE.channelsAndWebhooks.channels.chatChannelID); + GuildMessageChannel eventChannel = jda.getChannelById(GuildMessageChannel.class, SDLinkConfig.INSTANCE.channelsAndWebhooks.channels.eventsChannelID); + consoleChannel = jda.getChannelById(GuildMessageChannel.class, SDLinkConfig.INSTANCE.channelsAndWebhooks.channels.consoleChannelID); if (chatChannel != null) { channelMap.put(MessageDestination.CHAT, Pair.of(chatChannel, false)); @@ -46,7 +47,7 @@ public class ChannelManager { channelMap.put(MessageDestination.CONSOLE, consoleChannel != null ? Pair.of(consoleChannel, true) : Pair.of(chatChannel, false)); } - public static MessageChannel getDestinationChannel(MessageDestination destination) { + public static GuildMessageChannel getDestinationChannel(MessageDestination destination) { return channelMap.get(destination).getLeft(); } } diff --git a/src/main/java/com/hypherionmc/sdlink/core/managers/PermissionChecker.java b/src/main/java/com/hypherionmc/sdlink/core/managers/PermissionChecker.java index f36ca5d..9e74d00 100644 --- a/src/main/java/com/hypherionmc/sdlink/core/managers/PermissionChecker.java +++ b/src/main/java/com/hypherionmc/sdlink/core/managers/PermissionChecker.java @@ -9,6 +9,8 @@ import com.hypherionmc.sdlink.core.discord.BotController; import net.dv8tion.jda.api.Permission; import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel; +import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel; import net.dv8tion.jda.api.entities.channel.middleman.StandardGuildMessageChannel; import java.util.ArrayList; @@ -153,7 +155,7 @@ public class PermissionChecker { return; } - StandardGuildMessageChannel channel = BotController.INSTANCE.getJDA().getChannelById(StandardGuildMessageChannel.class, channelID); + GuildMessageChannel channel = BotController.INSTANCE.getJDA().getChannelById(GuildMessageChannel.class, channelID); if (channel == null) { errCount.incrementAndGet(); @@ -163,7 +165,7 @@ public class PermissionChecker { .append(" ID does not point to a valid Discord Channel. Please double check this") .append("\r\n"); } else { - EnumSet chatPerms = bot.getPermissionsExplicit(channel); + EnumSet chatPerms = bot.getPermissions(channel); BASE_CHANNEL_PERMS.forEach(perm -> { if (!chatPerms.contains(perm)) { diff --git a/src/main/java/com/hypherionmc/sdlink/core/managers/WebhookManager.java b/src/main/java/com/hypherionmc/sdlink/core/managers/WebhookManager.java index 88c47bf..968d401 100644 --- a/src/main/java/com/hypherionmc/sdlink/core/managers/WebhookManager.java +++ b/src/main/java/com/hypherionmc/sdlink/core/managers/WebhookManager.java @@ -10,8 +10,13 @@ import com.hypherionmc.sdlink.core.discord.BotController; import com.hypherionmc.sdlink.core.messaging.MessageDestination; import com.hypherionmc.sdlink.core.messaging.SDLinkWebhookClient; import com.hypherionmc.sdlink.core.util.EncryptionUtil; +import org.apache.commons.lang3.tuple.Pair; import java.util.HashMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static club.minnced.discord.webhook.WebhookClientBuilder.WEBHOOK_PATTERN; /** * @author HypherionSA @@ -21,6 +26,7 @@ public class WebhookManager { private static final HashMap clientMap = new HashMap<>(); private static WebhookClient chatWebhookClient, eventWebhookClient, consoleWebhookClient; + private static final Pattern THREAD_PATTERN = Pattern.compile("thread_id=(\\d+)"); /** * Load configured webhook clients @@ -36,26 +42,26 @@ public class WebhookManager { return; if (!SDLinkConfig.INSTANCE.channelsAndWebhooks.webhooks.chatWebhook.isEmpty()) { - chatWebhookClient = new SDLinkWebhookClient( + chatWebhookClient = createClient( "Chat", EncryptionUtil.INSTANCE.decrypt(SDLinkConfig.INSTANCE.channelsAndWebhooks.webhooks.chatWebhook) - ).build(); + ); BotController.INSTANCE.getLogger().info("Using Webhook for Chat Messages"); } if (!SDLinkConfig.INSTANCE.channelsAndWebhooks.webhooks.eventsWebhook.isEmpty()) { - eventWebhookClient = new SDLinkWebhookClient( + eventWebhookClient = createClient( "Events", EncryptionUtil.INSTANCE.decrypt(SDLinkConfig.INSTANCE.channelsAndWebhooks.webhooks.eventsWebhook) - ).build(); + ); BotController.INSTANCE.getLogger().info("Using Webhook for Event Messages"); } if (!SDLinkConfig.INSTANCE.channelsAndWebhooks.webhooks.consoleWebhook.isEmpty()) { - consoleWebhookClient = new SDLinkWebhookClient( + consoleWebhookClient = createClient( "Console", EncryptionUtil.INSTANCE.decrypt(SDLinkConfig.INSTANCE.channelsAndWebhooks.webhooks.consoleWebhook) - ).build(); + ); BotController.INSTANCE.getLogger().info("Using Webhook for Console Messages"); } @@ -82,4 +88,41 @@ public class WebhookManager { consoleWebhookClient.close(); } } + + /** + * Workaround to support ThreadID's in Webhook URLS + * @param name The name of the Webhook Client + * @param url The Webhook URL + * @return The client with thread id set, if found + */ + private static WebhookClient createClient(String name, String url) { + url = EncryptionUtil.INSTANCE.decrypt(url); + + Matcher threadMatcher = THREAD_PATTERN.matcher(url); + Matcher webhookMatcher = WEBHOOK_PATTERN.matcher(url); + + if (threadMatcher.find() && webhookMatcher.find()) { + return new SDLinkWebhookClient( + name, + String.format("https://discord.com/api/webhooks/%s/%s", webhookMatcher.group(1), webhookMatcher.group(2)) + ).setThreadChannelID(threadMatcher.group(1)).build(); + } else if (webhookMatcher.matches()) { + return new SDLinkWebhookClient(name, String.format("https://discord.com/api/webhooks/%s/%s", webhookMatcher.group(1), webhookMatcher.group(2))).build(); + } + + return new SDLinkWebhookClient(name, url).build(); + } + + private static Pair parseWebhookUrl(String url) { + final Pattern pattern = Pattern.compile("\\?thread_id=[0-9]+", Pattern.CASE_INSENSITIVE); + String thread = "0"; + + if (pattern.matcher(url).find()) { + thread = pattern.matcher(url).group(0); + } + + String whurl = url.replace("?thread_id=" + thread, ""); + + return Pair.of(whurl, thread); + } } diff --git a/src/main/java/com/hypherionmc/sdlink/core/messaging/SDLinkWebhookClient.java b/src/main/java/com/hypherionmc/sdlink/core/messaging/SDLinkWebhookClient.java index 8401fe9..4abf4ea 100644 --- a/src/main/java/com/hypherionmc/sdlink/core/messaging/SDLinkWebhookClient.java +++ b/src/main/java/com/hypherionmc/sdlink/core/messaging/SDLinkWebhookClient.java @@ -24,4 +24,9 @@ public class SDLinkWebhookClient extends WebhookClientBuilder { this.setWait(false); } + public SDLinkWebhookClient setThreadChannelID(String id) { + this.setThreadId(Long.parseLong(id)); + return this; + } + } diff --git a/src/main/java/com/hypherionmc/sdlink/core/messaging/discord/DiscordMessage.java b/src/main/java/com/hypherionmc/sdlink/core/messaging/discord/DiscordMessage.java index 4dab89a..af8c4e5 100644 --- a/src/main/java/com/hypherionmc/sdlink/core/messaging/discord/DiscordMessage.java +++ b/src/main/java/com/hypherionmc/sdlink/core/messaging/discord/DiscordMessage.java @@ -19,6 +19,7 @@ import com.hypherionmc.sdlink.core.messaging.MessageType; import com.hypherionmc.sdlink.core.util.SDLinkUtils; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.Role; +import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel; import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel; import net.dv8tion.jda.api.entities.channel.middleman.StandardGuildChannel; import net.dv8tion.jda.api.entities.channel.middleman.StandardGuildMessageChannel; @@ -82,7 +83,7 @@ public final class DiscordMessage { * Send a Non Console relay message to discord */ private void sendNormalMessage() { - Triple channel = resolveDestination(); + Triple channel = resolveDestination(); // Check if a webhook is configured, and use that instead if (channel.getMiddle() != null && SDLinkConfig.INSTANCE.channelsAndWebhooks.webhooks.enabled) { @@ -186,7 +187,7 @@ public final class DiscordMessage { /** * Figure out where the message must be delivered to, based on the config values */ - private Triple resolveDestination() { + private Triple resolveDestination() { switch (messageType) { case CHAT -> { MessageChannelConfig.DestinationObject chat = SDLinkConfig.INSTANCE.messageDestinations.chat;