diff --git a/src/main/java/com/alttd/contextMenuManager/contextMenus/ContextMenuForwardToKanboard.java b/src/main/java/com/alttd/contextMenuManager/contextMenus/ContextMenuForwardToKanboard.java index 117bc36..57d6e18 100644 --- a/src/main/java/com/alttd/contextMenuManager/contextMenus/ContextMenuForwardToKanboard.java +++ b/src/main/java/com/alttd/contextMenuManager/contextMenus/ContextMenuForwardToKanboard.java @@ -4,16 +4,13 @@ import com.alttd.contextMenuManager.DiscordContextMenu; import com.alttd.util.Kanboard; import com.alttd.util.Util; import net.dv8tion.jda.api.Permission; -import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.Message; -import net.dv8tion.jda.api.entities.channel.concrete.ThreadChannel; import net.dv8tion.jda.api.events.interaction.command.MessageContextInteractionEvent; import net.dv8tion.jda.api.events.interaction.command.UserContextInteractionEvent; import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions; import net.dv8tion.jda.api.interactions.commands.build.CommandData; import net.dv8tion.jda.api.interactions.commands.build.Commands; import net.dv8tion.jda.api.requests.RestAction; -import net.dv8tion.jda.api.requests.restaction.interactions.ReplyCallbackAction; import java.util.concurrent.CompletableFuture; @@ -35,33 +32,15 @@ public class ContextMenuForwardToKanboard extends DiscordContextMenu { return; } Message message = event.getInteraction().getTarget(); - Member member = message.getMember(); - if (member == null) - return; - String title = ""; - if (member.getUser().equals(event.getJDA().getSelfUser())) { - if (message.getContentRaw().startsWith("**Suggestion by:")) { - if (message.getGuildChannel() instanceof ThreadChannel threadChannel) { - title = threadChannel.getName(); - } - } - } - - ReplyCallbackAction replyCallbackAction = event.deferReply(true); - CompletableFuture booleanCompletableFuture; - if (title.isBlank()) { - booleanCompletableFuture = Kanboard.forwardMessageToKanboard(message); - } else { - booleanCompletableFuture = Kanboard.forwardMessageToKanboard(title, message.getContentDisplay()); - } - booleanCompletableFuture.thenAcceptAsync(result -> { + CompletableFuture booleanCompletableFuture = Kanboard.forwardMessageToKanboard(message); + event.deferReply(true).queue(defer -> booleanCompletableFuture.thenAcceptAsync(result -> { if (!result) { - replyCallbackAction.setEmbeds(Util.genericErrorEmbed("Error", "Unable to forward message to Kanboard")); + defer.editOriginalEmbeds(Util.genericErrorEmbed("Error", "Unable to forward message to Kanboard")).queue(); return; } - replyCallbackAction.setEmbeds(Util.genericSuccessEmbed("Success", "Forwarded message to Kanboard board!")); - }); + defer.editOriginalEmbeds(Util.genericSuccessEmbed("Success", "Forwarded message to Kanboard board!")).queue(); + })); } @Override diff --git a/src/main/java/com/alttd/listeners/TagAdded.java b/src/main/java/com/alttd/listeners/TagAdded.java index ee45aef..3680d80 100644 --- a/src/main/java/com/alttd/listeners/TagAdded.java +++ b/src/main/java/com/alttd/listeners/TagAdded.java @@ -1,33 +1,27 @@ package com.alttd.listeners; -import com.alttd.config.SettingsConfig; import com.alttd.util.Kanboard; import com.alttd.util.Logger; -import net.dv8tion.jda.api.entities.Message; +import net.dv8tion.jda.api.entities.ISnowflake; import net.dv8tion.jda.api.entities.channel.concrete.ThreadChannel; -import net.dv8tion.jda.api.events.channel.forum.ForumTagAddEvent; +import net.dv8tion.jda.api.entities.channel.forums.ForumTag; +import net.dv8tion.jda.api.events.channel.update.ChannelUpdateAppliedTagsEvent; import net.dv8tion.jda.api.hooks.ListenerAdapter; -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; +import java.util.List; public class TagAdded extends ListenerAdapter { @Override - public void onForumTagAdd(ForumTagAddEvent event) { - if (event.getTag().getIdLong() != 0L) {//TODO add tag id + public void onChannelUpdateAppliedTags(ChannelUpdateAppliedTagsEvent event) { + List addedTags = event.getAddedTags(); + if (addedTags.stream().map(ISnowflake::getIdLong).noneMatch(id -> id == 1020378607052398632L)) {//TODO add tag id to config return; } if (!(event.getChannel() instanceof ThreadChannel threadChannel)) { return; } - threadChannel.retrieveStartMessage().queue(Kanboard::forwardMessageToKanboard, error -> { - Logger.altitudeLogs.error(error); - }); + threadChannel.retrieveStartMessage().queue(Kanboard::forwardMessageToKanboard, error -> Logger.altitudeLogs.error(error)); } } diff --git a/src/main/java/com/alttd/util/Kanboard.java b/src/main/java/com/alttd/util/Kanboard.java index 8d86cd2..e711d7f 100644 --- a/src/main/java/com/alttd/util/Kanboard.java +++ b/src/main/java/com/alttd/util/Kanboard.java @@ -1,7 +1,9 @@ package com.alttd.util; import com.alttd.config.SettingsConfig; +import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.Message; +import net.dv8tion.jda.api.entities.channel.concrete.ThreadChannel; import java.io.IOException; import java.net.URI; @@ -9,23 +11,26 @@ import java.net.URISyntaxException; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; +import java.nio.charset.StandardCharsets; import java.util.Arrays; +import java.util.Base64; import java.util.UUID; import java.util.concurrent.CompletableFuture; import java.util.stream.Collectors; public class Kanboard { - public static CompletableFuture forwardMessageToKanboard(String title, String body) { + public static CompletableFuture forwardMessageToKanboard(String title, String body, String webLink) { HttpClient client = HttpClient.newHttpClient(); HttpRequest request; + String jsonPayload = getPayload(UUID.randomUUID().toString(), title, body, webLink); try { - String jsonPayload = getPayload(UUID.randomUUID().toString(), title, body); - + byte[] kanboardTokenBytes = String.join(":", "jsonrpc", SettingsConfig.KANBOARD_TOKEN).getBytes(StandardCharsets.UTF_8); + String token = Base64.getEncoder().encodeToString(kanboardTokenBytes); request = HttpRequest.newBuilder() .uri(new URI("https://kanboard.alttd.com/jsonrpc.php")) .header("Content-Type", "application/json") - .setHeader("Authorization", SettingsConfig.KANBOARD_TOKEN) + .setHeader("Authorization", "Basic " + token) .POST(HttpRequest.BodyPublishers.ofString(jsonPayload)) .build(); } catch (URISyntaxException e) { @@ -43,11 +48,11 @@ public class Kanboard { return false; } - if (response.statusCode() == 200) { - Logger.altitudeLogs.info(response.body()); + if (response.statusCode() == 200 && response.body().matches(".*\"result\":[0-9]+,.*")) { + Logger.altitudeLogs.info(String.format("Response body: [%s]\nFor JsonPayload: [%s]", response.body(), jsonPayload)); return true; } else { - Logger.altitudeLogs.error(String.format("Invalid response [%s]", response.body())); + Logger.altitudeLogs.error(String.format("Invalid response: [%s]\nPayload: [%s]", response.body(), jsonPayload)); return false; } }); @@ -55,31 +60,71 @@ public class Kanboard { public static CompletableFuture forwardMessageToKanboard(Message message) { String body = message.getContentDisplay(); + if (messageIsSuggestion(message) && message.getGuildChannel() instanceof ThreadChannel threadChannel) { + return forwardSuggestionToKanboard(message, threadChannel); + } String[] split = body.split("\n"); String title; if (split.length == 1) { title = "No title"; } else { title = split[0]; - body = Arrays.stream(split).skip(1).collect(Collectors.joining("\n")); + body = Arrays.stream(split).skip(1).filter(str -> !str.isBlank()).collect(Collectors.joining("\n")); } - return forwardMessageToKanboard(title, body); + return forwardMessageToKanboard(title, body, getWebLink(message)); } - private static String getPayload(String id, String title, String body) { + private static CompletableFuture forwardSuggestionToKanboard(Message message, ThreadChannel threadChannel) { + String title = threadChannel.getName(); + String content = Arrays.stream(message.getContentDisplay().split("\n")).skip(1).filter(str -> !str.isBlank()).collect(Collectors.joining("\n")); + return forwardMessageToKanboard(title, content, getWebLink(message)); + } + + private static boolean messageIsSuggestion(Message message) { + Member member = message.getMember(); + if (member == null) + return false; + + if (!member.getUser().equals(message.getJDA().getSelfUser())) { + return false; + } + if (!message.getContentRaw().startsWith("**Suggestion by:")) { + return false; + } + return true; + } + + private static String getPayload(String id, String title, String body, String webLink) { return String.format(""" { "jsonrpc": "2.0", "method": "createTask", - "id": %s, + "id": "%s", "params": { "title": "%s", "project_id": "3", - "description": "%s", + "description": "%s%s", "column_id": "0", "color_id": "red" } - }""", id, title, body); + }""", + escapeSpecialJsonChars(id), + escapeSpecialJsonChars(title), + escapeSpecialJsonChars(body), + escapeSpecialJsonChars(String.format("\n\n[Discord link](%s)", webLink))); } + private static String getWebLink(Message message) { + return String.format("https://discord.com/channels/%d/%d/%d", message.getGuildIdLong(), message.getChannelIdLong(), message.getIdLong()); + } + + private static String escapeSpecialJsonChars(String s) { + return s.replace("\"", "\\\"") + .replace("\\", "\\\\") + .replace("\b", "\\b") + .replace("\f", "\\f") + .replace("\n", "\\n") + .replace("\r", "\\r") + .replace("\t", "\\t"); + } }