diff --git a/src/main/java/com/jaoafa/javajaotan2/Main.java b/src/main/java/com/jaoafa/javajaotan2/Main.java index a57940f3..b20772bd 100644 --- a/src/main/java/com/jaoafa/javajaotan2/Main.java +++ b/src/main/java/com/jaoafa/javajaotan2/Main.java @@ -14,6 +14,7 @@ import com.jagrosh.jdautilities.command.Command; import com.jagrosh.jdautilities.command.CommandClient; import com.jagrosh.jdautilities.command.CommandClientBuilder; +import com.jagrosh.jdautilities.command.ContextMenu; import com.jagrosh.jdautilities.commons.waiter.EventWaiter; import com.jaoafa.javajaotan2.lib.*; import com.jaoafa.javajaotan2.tasks.Task_CheckMailVerified; @@ -115,7 +116,8 @@ public static void main(String[] args) { GatewayIntent.MESSAGE_CONTENT, GatewayIntent.GUILD_MESSAGE_TYPING, GatewayIntent.DIRECT_MESSAGE_TYPING, - GatewayIntent.GUILD_EMOJIS_AND_STICKERS + GatewayIntent.GUILD_EMOJIS_AND_STICKERS, + GatewayIntent.GUILD_MESSAGE_REACTIONS ) .setAutoReconnect(true) .setBulkDeleteSplittingEnabled(false) @@ -155,6 +157,7 @@ static CommandClient getCommandClient() { builder.setOwnerId(config.getOwnerId()); registerCommand(builder); + registerMenu(builder); // とりあえずスラッシュコマンドはサポートしない @@ -306,6 +309,22 @@ static void registerEvent(JDABuilder jdaBuilder) { } } + static void registerMenu(CommandClientBuilder builder) { + final String commandPackage = "com.jaoafa.javajaotan2.menu"; + Reflections reflections = new Reflections(commandPackage); + Set> subTypes = reflections.getSubTypesOf(ContextMenu.class); + + for (Class theClass : subTypes) { + try { + builder.addContextMenu(theClass.getDeclaredConstructor().newInstance()); + getLogger().info("%s: メニューの登録に成功しました".formatted(theClass.getSimpleName())); + } catch (Throwable throwable) { + throwable.printStackTrace(); + getLogger().error("%s: メニューの登録に失敗しました".formatted(theClass.getSimpleName())); + } + } + } + static void registerTask() { SchedulerFactory factory = new StdSchedulerFactory(); List tasks = List.of( diff --git a/src/main/java/com/jaoafa/javajaotan2/event/Event_BugReaction.java b/src/main/java/com/jaoafa/javajaotan2/event/Event_BugReaction.java deleted file mode 100644 index f016884f..00000000 --- a/src/main/java/com/jaoafa/javajaotan2/event/Event_BugReaction.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * jaoLicense - * - * Copyright (c) 2022 jao Minecraft Server - * - * The following license applies to this project: jaoLicense - * - * Japanese: https://github.com/jaoafa/jao-Minecraft-Server/blob/master/jaoLICENSE.md - * English: https://github.com/jaoafa/jao-Minecraft-Server/blob/master/jaoLICENSE-en.md - */ - -package com.jaoafa.javajaotan2.event; - -import com.jaoafa.javajaotan2.Main; -import com.jaoafa.javajaotan2.lib.Channels; -import com.jaoafa.javajaotan2.lib.JavajaotanLibrary; -import net.dv8tion.jda.api.EmbedBuilder; -import net.dv8tion.jda.api.entities.Message; -import net.dv8tion.jda.api.entities.TextChannel; -import net.dv8tion.jda.api.entities.ThreadChannel; -import net.dv8tion.jda.api.entities.User; -import net.dv8tion.jda.api.entities.channel.unions.MessageChannelUnion; -import net.dv8tion.jda.api.entities.emoji.Emoji; -import net.dv8tion.jda.api.entities.emoji.EmojiUnion; -import net.dv8tion.jda.api.events.message.react.MessageReactionAddEvent; -import net.dv8tion.jda.api.hooks.ListenerAdapter; -import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder; -import org.jetbrains.annotations.NotNull; - -import java.awt.*; -import java.time.Instant; -import java.time.ZoneId; -import java.time.ZonedDateTime; -import java.time.format.DateTimeFormatter; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.TimeUnit; - -public class Event_BugReaction extends ListenerAdapter { - final String targetReaction = "\uD83D\uDC1B"; // :bug: - final String repo = "jaoafa/jao-Minecraft-Server"; - - @Override - public void onMessageReactionAdd(@NotNull MessageReactionAddEvent event) { - if (Main.getConfig().getGuildId() != event.getGuild().getIdLong()) return; - - User user = event.getUser(); - - if (user == null) user = event.retrieveUser().complete(); - if (user.isBot()) return; - - EmojiUnion emoji = event.getEmoji(); - - if (emoji.getType() != Emoji.Type.UNICODE) return; - if (!emoji.asUnicode().getName().equals(targetReaction)) return; - - Message message = event.retrieveMessage().complete(); - List users = message.retrieveReactionUsers(Emoji.fromUnicode(targetReaction)).complete(); - - if (users.size() != 1) { - // 1人以外 = 0もしくは2人以上 = 既に報告済み - return; - } - MessageChannelUnion channel = event.getChannel(); - - // Issueを作成する - ZonedDateTime createdAt = message.getTimeCreated().atZoneSameInstant(ZoneId.of("Asia/Tokyo")); - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"); - String title = user.getAsTag() + " による #" + message.getChannel().getName() + " での不具合報告"; - String body = """ - ## 不具合と思われるメッセージ (または報告) - - %s - - URL: %s - - ## 不具合報告者 - - %s - """.formatted( - createdAt.format(formatter) + " に送信された `" + message.getAuthor().getAsTag() + "` による `#" + message.getChannel().getName() + "` でのメッセージ", - message.getJumpUrl(), - "`" + user.getAsTag() + "`" - ); - - JavajaotanLibrary.CreateIssueResponse response = JavajaotanLibrary.createIssue(repo, title, body); - JavajaotanLibrary.IssueResponseType responseType = response.responseType(); - int issueNumber = response.issueNumber(); - - // スレッドを立てる - TextChannel developmentChannel = Channels.development.getChannel(); - if (developmentChannel == null) { - // チャンネルが見つからない - channel - .sendMessage(user.getAsMention() + " スレッドの作成に失敗しました。developmentチャンネルが見つかりません。") - .delay(1, TimeUnit.MINUTES, Main.getScheduler()) // delete 1 minute later - .flatMap(Message::delete) - .queue(); - return; - } - - List messages = new ArrayList<>(); - if (responseType == JavajaotanLibrary.IssueResponseType.SUCCESS) { - messages.add("[LINKED-ISSUE:jaoafa/jao-Minecraft-Server#" + issueNumber + "]"); - messages.add(""); - } - messages.add("<@&959313488113717298> / " + user.getAsMention() + " / " + message.getAuthor().getAsMention()); - - EmbedBuilder embed = new EmbedBuilder() - .setTitle(":bug: リアクションによる不具合の報告") - .addField("不具合と思われるメッセージ (または報告)", "%s に送信された %s による %s でのメッセージ\n\n%s".formatted(createdAt.format(formatter), message.getAuthor().getAsMention(), message.getChannel().getAsMention(), message.getJumpUrl()), false) - .addField("不具合報告者", user.getAsMention(), false) - .setTimestamp(Instant.now()) - .setFooter("投稿者、または報告者は不具合内容についての説明(何が不具合と思ったのか、期待される動作など)をお願いします。") - .setColor(Color.YELLOW); - - if (responseType == JavajaotanLibrary.IssueResponseType.SUCCESS) { - embed.addField("Issue Url", "https://github.com/jaoafa/jao-Minecraft-Server/issues/" + issueNumber, false); - } - - String threadTitle = (responseType == JavajaotanLibrary.IssueResponseType.SUCCESS ? "*" + issueNumber + " " : "") + title; - ThreadChannel thread = developmentChannel.createThreadChannel(threadTitle).complete(); - thread.sendMessage(new MessageCreateBuilder() - .setContent(String.join("\n", messages)) - .setEmbeds(embed.build()) - .build()).queue(); - - message.addReaction(Emoji.fromUnicode(targetReaction)).queue(); - } -} diff --git a/src/main/java/com/jaoafa/javajaotan2/lib/JavajaotanLibrary.java b/src/main/java/com/jaoafa/javajaotan2/lib/JavajaotanLibrary.java index 74cd2f3b..31bb0eb2 100644 --- a/src/main/java/com/jaoafa/javajaotan2/lib/JavajaotanLibrary.java +++ b/src/main/java/com/jaoafa/javajaotan2/lib/JavajaotanLibrary.java @@ -11,16 +11,9 @@ package com.jaoafa.javajaotan2.lib; -import com.jaoafa.javajaotan2.Main; import net.dv8tion.jda.api.entities.*; import net.dv8tion.jda.api.entities.emoji.CustomEmoji; -import okhttp3.*; -import org.json.JSONArray; -import org.json.JSONObject; -import javax.annotation.Nonnull; -import java.io.IOException; -import java.util.Objects; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -99,62 +92,6 @@ public static String getContentDisplay(Message message, String raw) { return tmp; } - @Nonnull - public static CreateIssueResponse createIssue(String repo, String title, String body) { - String githubToken = Main.getConfig().getGitHubAPIToken(); - if (githubToken == null || githubToken.isEmpty()) { - return new CreateIssueResponse( - IssueResponseType.FAILED, - "GitHub API Token が設定されていません。", - -1 - ); - } - String url = String.format("https://api.github.com/repos/%s/issues", repo); - JSONObject json = new JSONObject() - .put("title", title) - .put("body", body) - .put("labels", new JSONArray() - .put("\uD83D\uDC1Bbug")); - - try { - OkHttpClient client = new OkHttpClient(); - RequestBody requestBody = RequestBody.create(json.toString(), MediaType.parse("application/json; charset=UTF-8")); - Request request = new Request.Builder() - .url(url) - .header("Authorization", String.format("token %s", githubToken)) - .post(requestBody) - .build(); - JSONObject obj; - try (Response response = client.newCall(request).execute()) { - if (response.code() != 201) { - return new CreateIssueResponse( - IssueResponseType.FAILED, - "Issue の作成に失敗しました。", - -1 - ); - } - obj = new JSONObject(Objects.requireNonNull(response.body()).string()); - } - - int issueNum = obj.getInt("number"); - return new CreateIssueResponse( - IssueResponseType.SUCCESS, - "Issue の作成に成功しました。", - issueNum - ); - } catch (IOException e) { - e.printStackTrace(); - return new CreateIssueResponse( - IssueResponseType.FAILED, - "Issue の作成に失敗しました。" + e.getMessage(), - -1 - ); - } - } - - public record CreateIssueResponse(IssueResponseType responseType, String message, int issueNumber) { - } - public enum IssueResponseType { SUCCESS, FAILED