[FEAT] Support for Webhook URL's with Thread ID's
This commit is contained in:
@@ -9,6 +9,7 @@ import com.hypherionmc.sdlink.core.discord.BotController;
|
|||||||
import com.hypherionmc.sdlink.core.messaging.MessageDestination;
|
import com.hypherionmc.sdlink.core.messaging.MessageDestination;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import net.dv8tion.jda.api.JDA;
|
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.MessageChannel;
|
||||||
import net.dv8tion.jda.api.entities.channel.middleman.StandardGuildChannel;
|
import net.dv8tion.jda.api.entities.channel.middleman.StandardGuildChannel;
|
||||||
import net.dv8tion.jda.api.entities.channel.middleman.StandardGuildMessageChannel;
|
import net.dv8tion.jda.api.entities.channel.middleman.StandardGuildMessageChannel;
|
||||||
@@ -22,9 +23,9 @@ import java.util.HashMap;
|
|||||||
*/
|
*/
|
||||||
public class ChannelManager {
|
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
|
@Getter
|
||||||
private static MessageChannel consoleChannel;
|
private static GuildMessageChannel consoleChannel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load configured channel, while always defaulting back to ChatChannel for channels that aren't configured
|
* 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();
|
JDA jda = BotController.INSTANCE.getJDA();
|
||||||
|
|
||||||
MessageChannel chatChannel = jda.getChannelById(MessageChannel.class, SDLinkConfig.INSTANCE.channelsAndWebhooks.channels.chatChannelID);
|
GuildMessageChannel chatChannel = jda.getChannelById(GuildMessageChannel.class, SDLinkConfig.INSTANCE.channelsAndWebhooks.channels.chatChannelID);
|
||||||
MessageChannel eventChannel = jda.getChannelById(MessageChannel.class, SDLinkConfig.INSTANCE.channelsAndWebhooks.channels.eventsChannelID);
|
GuildMessageChannel eventChannel = jda.getChannelById(GuildMessageChannel.class, SDLinkConfig.INSTANCE.channelsAndWebhooks.channels.eventsChannelID);
|
||||||
consoleChannel = jda.getChannelById(MessageChannel.class, SDLinkConfig.INSTANCE.channelsAndWebhooks.channels.consoleChannelID);
|
consoleChannel = jda.getChannelById(GuildMessageChannel.class, SDLinkConfig.INSTANCE.channelsAndWebhooks.channels.consoleChannelID);
|
||||||
|
|
||||||
if (chatChannel != null) {
|
if (chatChannel != null) {
|
||||||
channelMap.put(MessageDestination.CHAT, Pair.of(chatChannel, false));
|
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));
|
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();
|
return channelMap.get(destination).getLeft();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -9,6 +9,8 @@ import com.hypherionmc.sdlink.core.discord.BotController;
|
|||||||
import net.dv8tion.jda.api.Permission;
|
import net.dv8tion.jda.api.Permission;
|
||||||
import net.dv8tion.jda.api.entities.Guild;
|
import net.dv8tion.jda.api.entities.Guild;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
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 net.dv8tion.jda.api.entities.channel.middleman.StandardGuildMessageChannel;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -153,7 +155,7 @@ public class PermissionChecker {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
StandardGuildMessageChannel channel = BotController.INSTANCE.getJDA().getChannelById(StandardGuildMessageChannel.class, channelID);
|
GuildMessageChannel channel = BotController.INSTANCE.getJDA().getChannelById(GuildMessageChannel.class, channelID);
|
||||||
|
|
||||||
if (channel == null) {
|
if (channel == null) {
|
||||||
errCount.incrementAndGet();
|
errCount.incrementAndGet();
|
||||||
@@ -163,7 +165,7 @@ public class PermissionChecker {
|
|||||||
.append(" ID does not point to a valid Discord Channel. Please double check this")
|
.append(" ID does not point to a valid Discord Channel. Please double check this")
|
||||||
.append("\r\n");
|
.append("\r\n");
|
||||||
} else {
|
} else {
|
||||||
EnumSet<Permission> chatPerms = bot.getPermissionsExplicit(channel);
|
EnumSet<Permission> chatPerms = bot.getPermissions(channel);
|
||||||
|
|
||||||
BASE_CHANNEL_PERMS.forEach(perm -> {
|
BASE_CHANNEL_PERMS.forEach(perm -> {
|
||||||
if (!chatPerms.contains(perm)) {
|
if (!chatPerms.contains(perm)) {
|
||||||
|
@@ -10,8 +10,13 @@ import com.hypherionmc.sdlink.core.discord.BotController;
|
|||||||
import com.hypherionmc.sdlink.core.messaging.MessageDestination;
|
import com.hypherionmc.sdlink.core.messaging.MessageDestination;
|
||||||
import com.hypherionmc.sdlink.core.messaging.SDLinkWebhookClient;
|
import com.hypherionmc.sdlink.core.messaging.SDLinkWebhookClient;
|
||||||
import com.hypherionmc.sdlink.core.util.EncryptionUtil;
|
import com.hypherionmc.sdlink.core.util.EncryptionUtil;
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
import java.util.HashMap;
|
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
|
* @author HypherionSA
|
||||||
@@ -21,6 +26,7 @@ public class WebhookManager {
|
|||||||
|
|
||||||
private static final HashMap<MessageDestination, WebhookClient> clientMap = new HashMap<>();
|
private static final HashMap<MessageDestination, WebhookClient> clientMap = new HashMap<>();
|
||||||
private static WebhookClient chatWebhookClient, eventWebhookClient, consoleWebhookClient;
|
private static WebhookClient chatWebhookClient, eventWebhookClient, consoleWebhookClient;
|
||||||
|
private static final Pattern THREAD_PATTERN = Pattern.compile("thread_id=(\\d+)");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load configured webhook clients
|
* Load configured webhook clients
|
||||||
@@ -36,26 +42,26 @@ public class WebhookManager {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (!SDLinkConfig.INSTANCE.channelsAndWebhooks.webhooks.chatWebhook.isEmpty()) {
|
if (!SDLinkConfig.INSTANCE.channelsAndWebhooks.webhooks.chatWebhook.isEmpty()) {
|
||||||
chatWebhookClient = new SDLinkWebhookClient(
|
chatWebhookClient = createClient(
|
||||||
"Chat",
|
"Chat",
|
||||||
EncryptionUtil.INSTANCE.decrypt(SDLinkConfig.INSTANCE.channelsAndWebhooks.webhooks.chatWebhook)
|
EncryptionUtil.INSTANCE.decrypt(SDLinkConfig.INSTANCE.channelsAndWebhooks.webhooks.chatWebhook)
|
||||||
).build();
|
);
|
||||||
BotController.INSTANCE.getLogger().info("Using Webhook for Chat Messages");
|
BotController.INSTANCE.getLogger().info("Using Webhook for Chat Messages");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!SDLinkConfig.INSTANCE.channelsAndWebhooks.webhooks.eventsWebhook.isEmpty()) {
|
if (!SDLinkConfig.INSTANCE.channelsAndWebhooks.webhooks.eventsWebhook.isEmpty()) {
|
||||||
eventWebhookClient = new SDLinkWebhookClient(
|
eventWebhookClient = createClient(
|
||||||
"Events",
|
"Events",
|
||||||
EncryptionUtil.INSTANCE.decrypt(SDLinkConfig.INSTANCE.channelsAndWebhooks.webhooks.eventsWebhook)
|
EncryptionUtil.INSTANCE.decrypt(SDLinkConfig.INSTANCE.channelsAndWebhooks.webhooks.eventsWebhook)
|
||||||
).build();
|
);
|
||||||
BotController.INSTANCE.getLogger().info("Using Webhook for Event Messages");
|
BotController.INSTANCE.getLogger().info("Using Webhook for Event Messages");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!SDLinkConfig.INSTANCE.channelsAndWebhooks.webhooks.consoleWebhook.isEmpty()) {
|
if (!SDLinkConfig.INSTANCE.channelsAndWebhooks.webhooks.consoleWebhook.isEmpty()) {
|
||||||
consoleWebhookClient = new SDLinkWebhookClient(
|
consoleWebhookClient = createClient(
|
||||||
"Console",
|
"Console",
|
||||||
EncryptionUtil.INSTANCE.decrypt(SDLinkConfig.INSTANCE.channelsAndWebhooks.webhooks.consoleWebhook)
|
EncryptionUtil.INSTANCE.decrypt(SDLinkConfig.INSTANCE.channelsAndWebhooks.webhooks.consoleWebhook)
|
||||||
).build();
|
);
|
||||||
BotController.INSTANCE.getLogger().info("Using Webhook for Console Messages");
|
BotController.INSTANCE.getLogger().info("Using Webhook for Console Messages");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,4 +88,41 @@ public class WebhookManager {
|
|||||||
consoleWebhookClient.close();
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -24,4 +24,9 @@ public class SDLinkWebhookClient extends WebhookClientBuilder {
|
|||||||
this.setWait(false);
|
this.setWait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SDLinkWebhookClient setThreadChannelID(String id) {
|
||||||
|
this.setThreadId(Long.parseLong(id));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -19,6 +19,7 @@ import com.hypherionmc.sdlink.core.messaging.MessageType;
|
|||||||
import com.hypherionmc.sdlink.core.util.SDLinkUtils;
|
import com.hypherionmc.sdlink.core.util.SDLinkUtils;
|
||||||
import net.dv8tion.jda.api.EmbedBuilder;
|
import net.dv8tion.jda.api.EmbedBuilder;
|
||||||
import net.dv8tion.jda.api.entities.Role;
|
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.MessageChannel;
|
||||||
import net.dv8tion.jda.api.entities.channel.middleman.StandardGuildChannel;
|
import net.dv8tion.jda.api.entities.channel.middleman.StandardGuildChannel;
|
||||||
import net.dv8tion.jda.api.entities.channel.middleman.StandardGuildMessageChannel;
|
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
|
* Send a Non Console relay message to discord
|
||||||
*/
|
*/
|
||||||
private void sendNormalMessage() {
|
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
|
// Check if a webhook is configured, and use that instead
|
||||||
if (channel.getMiddle() != null && SDLinkConfig.INSTANCE.channelsAndWebhooks.webhooks.enabled) {
|
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
|
* 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) {
|
switch (messageType) {
|
||||||
case CHAT -> {
|
case CHAT -> {
|
||||||
MessageChannelConfig.DestinationObject chat = SDLinkConfig.INSTANCE.messageDestinations.chat;
|
MessageChannelConfig.DestinationObject chat = SDLinkConfig.INSTANCE.messageDestinations.chat;
|
||||||
|
Reference in New Issue
Block a user