[FEAT] Support for Webhook URL's with Thread ID's

This commit is contained in:
2024-03-17 20:02:32 +02:00
parent 28adbf6569
commit 5c478c5ca6
5 changed files with 68 additions and 16 deletions

View File

@@ -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<MessageDestination, Pair<MessageChannel, Boolean>> channelMap = new HashMap<>();
private static final HashMap<MessageDestination, Pair<GuildMessageChannel, Boolean>> 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();
}
}

View File

@@ -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<Permission> chatPerms = bot.getPermissionsExplicit(channel);
EnumSet<Permission> chatPerms = bot.getPermissions(channel);
BASE_CHANNEL_PERMS.forEach(perm -> {
if (!chatPerms.contains(perm)) {

View File

@@ -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<MessageDestination, WebhookClient> 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<String, String> 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);
}
}

View File

@@ -24,4 +24,9 @@ public class SDLinkWebhookClient extends WebhookClientBuilder {
this.setWait(false);
}
public SDLinkWebhookClient setThreadChannelID(String id) {
this.setThreadId(Long.parseLong(id));
return this;
}
}

View File

@@ -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<MessageChannel, WebhookClient, MessageChannelConfig.DestinationObject> channel = resolveDestination();
Triple<GuildMessageChannel, WebhookClient, MessageChannelConfig.DestinationObject> 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<MessageChannel, WebhookClient, MessageChannelConfig.DestinationObject> resolveDestination() {
private Triple<GuildMessageChannel, WebhookClient, MessageChannelConfig.DestinationObject> resolveDestination() {
switch (messageType) {
case CHAT -> {
MessageChannelConfig.DestinationObject chat = SDLinkConfig.INSTANCE.messageDestinations.chat;