Skip to content

feat: add QuizQuestion and TriviaManager classes for Java trivia game#40

Open
EJ-Edwards wants to merge 7 commits intoTogether-Java:developfrom
EJ-Edwards:develop
Open

feat: add QuizQuestion and TriviaManager classes for Java trivia game#40
EJ-Edwards wants to merge 7 commits intoTogether-Java:developfrom
EJ-Edwards:develop

Conversation

@EJ-Edwards
Copy link

please review my code and let me know if I am missing any errors. Note be nice since this is my actual first commit I would like guidance on this.

@EJ-Edwards EJ-Edwards requested review from a team as code owners March 9, 2026 17:23
@christolis
Copy link
Member

@EJ-Edwards Hello and congratulations on opening your first pull request in this repository.

Have you tested that this code works in a development environment? If so, it would be nice and convenient to have a preview of how it works in the form of screenshots or GIFs, embedded in the pull request description. 👍

@christolis christolis linked an issue Mar 9, 2026 that may be closed by this pull request
@EJ-Edwards
Copy link
Author

ok so I tested it on my end it works for me. Please let me know if they are any errors and I will fix it.
Screenshot 2026-03-09 170629

@EJ-Edwards
Copy link
Author

also if I am making a mistake or it messes up sorry like I said this is my first time actually contributing.

@christolis
Copy link
Member

christolis commented Mar 9, 2026 via email

- Added JavaQuizCommand: Discord slash command that fetches a random
  Java trivia question via ChatGPT and presents it with answer buttons
- Added TriviaManager: service that prompts ChatGPT for quiz questions
  and parses the JSON response
- Added QuizQuestion: data model for trivia questions
- Added javaquiz.java: standalone entry point for local testing
- Added runQuiz Gradle task for convenience testing
- Registered /javaquiz command in Bot.java

How to play:
  A server member types /javaquiz in Discord. The bot displays a
  random Java trivia question with 4 answer buttons. The user clicks
  their answer and the bot reveals whether it was correct.

Everything should work please let me know if I am missing anything

Best
-EJ
@EJ-Edwards
Copy link
Author

Ok Chris thank you and I just want to say thank you for taking your time and basically guiding me through the contribution process.

@christolis
Copy link
Member

Every time I select an answer, I get the following stacktrace:

00:15:52.365 [JDA MainWS-ReadThread] ERROR net.dv8tion.jda.api.JDA - One of the EventListeners had an uncaught exception
java.lang.IllegalArgumentException: Cannot have empty row!
        at net.dv8tion.jda.internal.utils.Checks.check(Checks.java:62) ~[JDA-5.0.0-beta.21.jar:5.0.0-beta.21]
        at net.dv8tion.jda.api.interactions.components.ActionRow.of(ActionRow.java:126) ~[JDA-5.0.0-beta.21.jar:5.0.0-beta.21]
        at net.dv8tion.jda.api.utils.messages.MessageRequest.setActionRow(MessageRequest.java:329) ~[JDA-5.0.0-beta.21.jar:5.0.0-beta.21]
        at com.togetherjava.tjplays.listeners.commands.JavaQuizCommand.onButtonInteraction(JavaQuizCommand.java:84) ~[main/:?]
        at net.dv8tion.jda.api.hooks.ListenerAdapter.onEvent(ListenerAdapter.java:447) ~[JDA-5.0.0-beta.21.jar:5.0.0-beta.21]
        at net.dv8tion.jda.api.hooks.InterfacedEventManager.handle(InterfacedEventManager.java:96) [JDA-5.0.0-beta.21.jar:5.0.0-beta.21]
        at net.dv8tion.jda.internal.hooks.EventManagerProxy.handleInternally(EventManagerProxy.java:88) [JDA-5.0.0-beta.21.jar:5.0.0-beta.21]
        at net.dv8tion.jda.internal.hooks.EventManagerProxy.handle(EventManagerProxy.java:70) [JDA-5.0.0-beta.21.jar:5.0.0-beta.21]
        at net.dv8tion.jda.internal.JDAImpl.handleEvent(JDAImpl.java:173) [JDA-5.0.0-beta.21.jar:5.0.0-beta.21]
        at net.dv8tion.jda.internal.handle.InteractionCreateHandler.handleAction(InteractionCreateHandler.java:134) [JDA-5.0.0-beta.21.jar:5.0.0-beta.21]
        at net.dv8tion.jda.internal.handle.InteractionCreateHandler.handleInternally(InteractionCreateHandler.java:86) [JDA-5.0.0-beta.21.jar:5.0.0-beta.21]
        at net.dv8tion.jda.internal.handle.SocketHandler.handle(SocketHandler.java:39) [JDA-5.0.0-beta.21.jar:5.0.0-beta.21]
        at net.dv8tion.jda.internal.requests.WebSocketClient.onDispatch(WebSocketClient.java:1007) [JDA-5.0.0-beta.21.jar:5.0.0-beta.21]
        at net.dv8tion.jda.internal.requests.WebSocketClient.onEvent(WebSocketClient.java:893) [JDA-5.0.0-beta.21.jar:5.0.0-beta.21]
        at net.dv8tion.jda.internal.requests.WebSocketClient.handleEvent(WebSocketClient.java:871) [JDA-5.0.0-beta.21.jar:5.0.0-beta.21]
        at net.dv8tion.jda.internal.requests.WebSocketClient.onBinaryMessage(WebSocketClient.java:1046) [JDA-5.0.0-beta.21.jar:5.0.0-beta.21]
        at com.neovisionaries.ws.client.ListenerManager.callOnBinaryMessage(ListenerManager.java:385) [nv-websocket-client-2.14.jar:?]
        at com.neovisionaries.ws.client.ReadingThread.callOnBinaryMessage(ReadingThread.java:276) [nv-websocket-client-2.14.jar:?]
        at com.neovisionaries.ws.client.ReadingThread.handleBinaryFrame(ReadingThread.java:996) [nv-websocket-client-2.14.jar:?]
        at com.neovisionaries.ws.client.ReadingThread.handleFrame(ReadingThread.java:755) [nv-websocket-client-2.14.jar:?]
        at com.neovisionaries.ws.client.ReadingThread.main(ReadingThread.java:108) [nv-websocket-client-2.14.jar:?]
        at com.neovisionaries.ws.client.ReadingThread.runMain(ReadingThread.java:64) [nv-websocket-client-2.14.jar:?]
        at com.neovisionaries.ws.client.WebSocketThread.run(WebSocketThread.java:45) [nv-websocket-client-2.14.jar:?]

Has this feature been tested thoroughly?

@EJ-Edwards
Copy link
Author

Hello Chris and I actually thought this would work thank you for letting me know also is there a bot token where I can test the bot in a discord server or no?

Copy link
Contributor

@tj-wazei tj-wazei left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall a pretty small and simple PR, great work. Just some small comments.

Could you provide some screenshots of how this looks in action? Possible a screen recording if that isn't too much to ask?

Thanks

@tj-wazei
Copy link
Contributor

tj-wazei commented Mar 9, 2026

Hello Chris and I actually thought this would work thank you for letting me know also is there a bot token where I can test the bot in a discord server or no?

You'll need to create your own Discord server and Discord bot token via the website. We unfortunantely, cannot give you ours. https://discord.com/developers/applications

…Manager for single question retrieval

chore: Remove unused javaquiz main class and add gradle.properties for JDK configuration
fix: Improve button interaction handling in JavaQuizCommand

I addressed all the review feedback and pushed the changes. I wasn't able to provide screenshots because the bot hangs on startup — it appears the shared OpenAI API key from the pinned message may be expired or invalid. The bot connects to Discord fine (I confirmed it joins the server and receives slash commands), but the ChatGPT API call in ChatGptService times out during initialization. Could someone verify the key is still active?
@EJ-Edwards
Copy link
Author

Ok so that should be everything please let me know that this works.

@EJ-Edwards EJ-Edwards requested review from Zabuzard and tj-wazei March 10, 2026 12:49
Copy link
Member

@christolis christolis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additionally while testing the game on my local Discord server It turns out that I can call the command multiple times without answering the previous question and I can effectively spam the chat by doing so, even if I am muted or have a time out in my account.

Kindly check that out.

Screenshot

Image


import java.util.List;

public record QuizQuestion(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is public-facing, it should have a JavaDoc explaining what it is, where it's used in and where it could be used by future contributors.

public record QuizQuestion(
@JsonProperty("question") String question,
@JsonProperty("choices") List<String> choices,
@JsonProperty("correct") int correctIndex
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: It took me a little bit to understand what correctIndex represents. Something like correctAnswerIndex would help.

@@ -0,0 +1,27 @@
package com.togetherjava.tjplays.games.game2048;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this class part of the games.game2048 package?

@@ -0,0 +1,30 @@
package com.togetherjava.tjplays.games.game2048;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this class part of the games.game2048 package?

import java.util.Optional;

public class TriviaManager {
private final ChatGptService gpt;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please properly name this variable to chatGptService.


public JavaQuizCommand(String openAiKey) {
super(Commands.slash(COMMAND_NAME, "Get a random Java trivia question"));
this.triviaManager = new TriviaManager(openAiKey);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just like in this code review comment, I believe that we should let callers pass down an instance of TriviaManager.

return;
}

QuizQuestion q = question.get();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use proper variable names instead of a single letter for readability. q could be quizQuestion and the current question can be quizQuestionOptional.

Comment on lines +39 to +44
StringBuilder sb = new StringBuilder();
sb.append("**Java Quiz**\n\n");
sb.append(q.getQuestion()).append("\n\n");
for (int i = 0; i < choices.size(); i++) {
sb.append("`").append(i + 1).append(")` ").append(choices.get(i)).append("\n");
}
Copy link
Member

@christolis christolis Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's not use sb as a variable name. This whole highlighted code block is also unreadable.

A lot of things could be changed here, and the removal of StringBuilder is a good place to start from.

Firstly, we should use String.format(...) as it's more readable and does not have .append() being repeated a lot.

Secondly, sending a MessageEmbed would allow for the code to be cleaner but also for the UI/UX to be significantly more structured.

@EJ-Edwards EJ-Edwards requested a review from christolis March 10, 2026 16:29
…onality. Created a new folder for the package let me know if this works.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Java quiz game

4 participants