diff --git a/src/main/java/com/alttd/AltitudeBot.java b/src/main/java/com/alttd/AltitudeBot.java index cd6751a..555e18e 100644 --- a/src/main/java/com/alttd/AltitudeBot.java +++ b/src/main/java/com/alttd/AltitudeBot.java @@ -7,6 +7,7 @@ import com.alttd.database.Database; import com.alttd.database.DatabaseTables; import com.alttd.listeners.JDAListener; import com.alttd.util.Logger; +import lombok.Getter; import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.JDABuilder; import net.dv8tion.jda.api.requests.GatewayIntent; @@ -17,12 +18,9 @@ import java.net.URISyntaxException; public class AltitudeBot { private JDA jda; + @Getter private static AltitudeBot instance; - public static AltitudeBot getInstance() { - return instance; - } - public static void main(String[] args) { instance = new AltitudeBot(); instance.start(); @@ -33,7 +31,7 @@ public class AltitudeBot { initConfigs(); jda = JDABuilder.createDefault(SettingsConfig.TOKEN, GatewayIntent.GUILD_MEMBERS, - GatewayIntent.GUILD_BANS, + GatewayIntent.GUILD_MODERATION, GatewayIntent.GUILD_EMOJIS_AND_STICKERS, GatewayIntent.GUILD_WEBHOOKS, GatewayIntent.GUILD_PRESENCES, @@ -70,7 +68,7 @@ public class AltitudeBot { return new File(AltitudeBot.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath()).getPath(); } catch (URISyntaxException e) { Logger.altitudeLogs.error("Unable to retrieve config directory"); - e.printStackTrace(); + Logger.altitudeLogs.error(e); } return (null); } diff --git a/src/main/java/com/alttd/contextMenuManager/ContextMenuManager.java b/src/main/java/com/alttd/contextMenuManager/ContextMenuManager.java index fa8c5e2..2d153ca 100644 --- a/src/main/java/com/alttd/contextMenuManager/ContextMenuManager.java +++ b/src/main/java/com/alttd/contextMenuManager/ContextMenuManager.java @@ -1,5 +1,6 @@ package com.alttd.contextMenuManager; +import com.alttd.contextMenuManager.contextMenus.ContextMenuForwardToKanboard; import com.alttd.contextMenuManager.contextMenus.ContextMenuRespondSuggestion; import com.alttd.modalManager.ModalManager; import com.alttd.util.Util; @@ -21,7 +22,8 @@ public class ContextMenuManager extends ListenerAdapter { public ContextMenuManager(ModalManager modalManager) { contextMenus = List.of( - new ContextMenuRespondSuggestion(modalManager) + new ContextMenuRespondSuggestion(modalManager), + new ContextMenuForwardToKanboard() ); } diff --git a/src/main/java/com/alttd/contextMenuManager/contextMenus/ContextMenuForwardToKanboard.java b/src/main/java/com/alttd/contextMenuManager/contextMenus/ContextMenuForwardToKanboard.java new file mode 100644 index 0000000..117bc36 --- /dev/null +++ b/src/main/java/com/alttd/contextMenuManager/contextMenus/ContextMenuForwardToKanboard.java @@ -0,0 +1,73 @@ +package com.alttd.contextMenuManager.contextMenus; + +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; + +public class ContextMenuForwardToKanboard extends DiscordContextMenu { + @Override + public String getContextMenuId() { + return "Forward To Kanboard"; + } + + @Override + public void execute(UserContextInteractionEvent event) { + event.getInteraction().replyEmbeds(Util.genericErrorEmbed("Error", "This interaction should have been a message interaction")) + .setEphemeral(true).queue(RestAction.getDefaultSuccess(), Util::handleFailure); + } + + @Override + public void execute(MessageContextInteractionEvent event) { + if (!event.isFromGuild()) { + 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 -> { + if (!result) { + replyCallbackAction.setEmbeds(Util.genericErrorEmbed("Error", "Unable to forward message to Kanboard")); + return; + } + replyCallbackAction.setEmbeds(Util.genericSuccessEmbed("Success", "Forwarded message to Kanboard board!")); + }); + } + + @Override + public CommandData getUserContextInteraction() { + return Commands.message(getContextMenuId()) + .setGuildOnly(true) + .setDefaultPermissions(DefaultMemberPermissions.enabledFor(Permission.ADMINISTRATOR)); + } +} diff --git a/src/main/java/com/alttd/listeners/TagAdded.java b/src/main/java/com/alttd/listeners/TagAdded.java index 63db373..ee45aef 100644 --- a/src/main/java/com/alttd/listeners/TagAdded.java +++ b/src/main/java/com/alttd/listeners/TagAdded.java @@ -1,6 +1,7 @@ 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.channel.concrete.ThreadChannel; @@ -16,55 +17,17 @@ import java.net.http.HttpResponse; public class TagAdded extends ListenerAdapter { - public void tagAdded(ForumTagAddEvent event) { + @Override + public void onForumTagAdd(ForumTagAddEvent event) { if (event.getTag().getIdLong() != 0L) {//TODO add tag id return; } if (!(event.getChannel() instanceof ThreadChannel threadChannel)) { return; } - threadChannel.retrieveStartMessage().queue(this::forwardMessageToKanboard, error -> { + threadChannel.retrieveStartMessage().queue(Kanboard::forwardMessageToKanboard, error -> { Logger.altitudeLogs.error(error); }); } - //TODO move to its own util class - public void forwardMessageToKanboard(Message message) { - String contentDisplay = message.getContentDisplay(); - HttpClient client = HttpClient.newHttpClient(); - HttpRequest request; - try { - String jsonPayload = String.format("{" - + "\"title\": \"%s\"," - + "\"description\": \"%s\"," - + "\"project_id\": \"%d\"" - + "}", "New Task" /*TODO config*/, contentDisplay, 3/*TODO config*/); - - request = HttpRequest.newBuilder() - .uri(new URI("https://kanboard.alttd.com/jsonrpc.php")) //TODO correct URL - .header("Content-Type", "application/json") - .setHeader("Authorization", SettingsConfig.KANBOARD_TOKEN) - .POST(HttpRequest.BodyPublishers.ofString(jsonPayload)) - .build(); - } catch (URISyntaxException e) { - Logger.altitudeLogs.error(e); - //TODO handle better - return; - } - - HttpResponse response; - try { - response = client.send(request, HttpResponse.BodyHandlers.ofString()); - } catch (InterruptedException | IOException e) { - Logger.altitudeLogs.error(e); - return; - } - - if (response.statusCode() == 200) { - Logger.altitudeLogs.info(response.body()); - } else { - Logger.altitudeLogs.error(String.format("Invalid response [%s]", response.body())); - } - } - } diff --git a/src/main/java/com/alttd/util/Kanboard.java b/src/main/java/com/alttd/util/Kanboard.java new file mode 100644 index 0000000..8d86cd2 --- /dev/null +++ b/src/main/java/com/alttd/util/Kanboard.java @@ -0,0 +1,85 @@ +package com.alttd.util; + +import com.alttd.config.SettingsConfig; +import net.dv8tion.jda.api.entities.Message; + +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.Arrays; +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) { + HttpClient client = HttpClient.newHttpClient(); + HttpRequest request; + try { + String jsonPayload = getPayload(UUID.randomUUID().toString(), title, body); + + request = HttpRequest.newBuilder() + .uri(new URI("https://kanboard.alttd.com/jsonrpc.php")) + .header("Content-Type", "application/json") + .setHeader("Authorization", SettingsConfig.KANBOARD_TOKEN) + .POST(HttpRequest.BodyPublishers.ofString(jsonPayload)) + .build(); + } catch (URISyntaxException e) { + Logger.altitudeLogs.error(e); + //TODO handle better + return CompletableFuture.completedFuture(false); + } + + return CompletableFuture.supplyAsync(() -> { + HttpResponse response; + try { + response = client.send(request, HttpResponse.BodyHandlers.ofString()); + } catch (InterruptedException | IOException e) { + Logger.altitudeLogs.error(e); + return false; + } + + if (response.statusCode() == 200) { + Logger.altitudeLogs.info(response.body()); + return true; + } else { + Logger.altitudeLogs.error(String.format("Invalid response [%s]", response.body())); + return false; + } + }); + } + + public static CompletableFuture forwardMessageToKanboard(Message message) { + String body = message.getContentDisplay(); + 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")); + } + return forwardMessageToKanboard(title, body); + } + + private static String getPayload(String id, String title, String body) { + return String.format(""" + { + "jsonrpc": "2.0", + "method": "createTask", + "id": %s, + "params": { + "title": "%s", + "project_id": "3", + "description": "%s", + "column_id": "0", + "color_id": "red" + } + }""", id, title, body); + } + +}