Skip to content

Release v4.18 #1274

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 37 commits into from
Jul 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
956bdcf
Bump jacksonVersion from 2.18.1 to 2.19.0 (#1221)
dependabot[bot] May 5, 2025
514a6cf
Bump org.kohsuke:github-api from 1.326 to 1.327 (#1223)
dependabot[bot] May 5, 2025
a995f8b
Bump org.jsoup:jsoup from 1.18.1 to 1.20.1 (#1225)
dependabot[bot] May 5, 2025
e1aa007
Bump org.gradle.toolchains.foojay-resolver-convention (#1227)
dependabot[bot] May 5, 2025
9cb661c
Bump org.sonarqube from 6.0.1.5171 to 6.1.0.5360 (#1228)
dependabot[bot] May 5, 2025
57c3a5f
Bump org.xerial:sqlite-jdbc from 3.47.1.0 to 3.49.1.0 (#1229)
dependabot[bot] May 5, 2025
4bdb4da
Bump com.apptasticsoftware:rssreader from 3.8.1 to 3.9.3 (#1230)
dependabot[bot] May 5, 2025
44eb430
Bump org.jooq:jooq from 3.19.1 to 3.20.4 (#1224)
dependabot[bot] May 5, 2025
aeb504d
Bump org.flywaydb:flyway-core from 11.1.0 to 11.8.0 (#1237)
dependabot[bot] May 6, 2025
be58c7b
Bump com.github.ben-manes.caffeine:caffeine from 3.1.1 to 3.2.0 (#1233)
dependabot[bot] May 6, 2025
54fb954
Bump org.apache.commons:commons-text from 1.12.0 to 1.13.1 (#1234)
dependabot[bot] May 6, 2025
a51375e
Bump com.diffplug.spotless from 6.25.0 to 7.0.3 (#1232)
dependabot[bot] May 6, 2025
ace5c37
Bump org.sonarqube from 6.1.0.5360 to 6.2.0.5505 (#1238)
dependabot[bot] May 16, 2025
b0a97b0
Bump org.gradle.toolchains.foojay-resolver-convention (#1239)
dependabot[bot] May 20, 2025
1eae4de
Bump org.mockito:mockito-core from 5.17.0 to 5.18.0 (#1240)
dependabot[bot] May 21, 2025
8224f93
Bump net.dv8tion:JDA from 5.2.1 to 5.5.1 (#1236)
dependabot[bot] Jun 1, 2025
8afd27c
Optimize auto prune routine to not spam requests for all users (#1208)
SquidXTV Jun 1, 2025
08a3144
Bump com.sigpwned:jackson-modules-java17-sealed-classes (#1242)
dependabot[bot] Jun 1, 2025
51ce33a
Bump com.sigpwned:jackson-modules-java17-sealed-classes (#1246)
dependabot[bot] Jun 2, 2025
f1ce79d
Bump org.flywaydb:flyway-core from 11.8.0 to 11.9.0 (#1248)
dependabot[bot] Jun 3, 2025
7decc98
Bump org.xerial:sqlite-jdbc from 3.49.1.0 to 3.50.1.0 (#1254)
dependabot[bot] Jun 10, 2025
76a0590
Bump org.apache.logging.log4j:log4j-core from 2.24.3 to 2.25.0 (#1255)
dependabot[bot] Jun 17, 2025
96b7f55
Bump net.dv8tion:JDA from 5.5.1 to 5.6.1 (#1251)
dependabot[bot] Jun 17, 2025
ae350db
Bump org.jsoup:jsoup from 1.20.1 to 1.21.1 (#1256)
dependabot[bot] Jun 24, 2025
99bc173
changed /modmail stay-anonymous to reveal-name for better UX (#1260)
Zabuzard Jun 26, 2025
0cbe7b2
Feature: Add useful links to ChatGPT response (#1125)
firasrg Jun 26, 2025
f215304
Bump org.flywaydb:flyway-core from 11.9.0 to 11.10.0 (#1261)
dependabot[bot] Jun 27, 2025
4f03aa8
Improved ChatGpt requests and response handling (#1262)
Zabuzard Jun 27, 2025
8b2d3c5
fix(logger): friendlier handling of default values (#1263)
christolis Jun 27, 2025
d7d360b
Switched to better RSS feed (#1264)
pot Jun 29, 2025
6c630d5
Include error in rss feed (#1267)
pot Jun 29, 2025
d2eb7ef
build: bump to log4j-slf4j2-impl v2.25.0 (#1269)
christolis Jun 30, 2025
3bc3e7c
Fix RSS Headers (#1268)
pot Jun 30, 2025
f206bd4
Bump Java Version to 24 (#1071)
Taz03 Jul 1, 2025
28eb518
Bump devcontainer from Java 18 to 24 (#1271)
Zabuzard Jul 1, 2025
39224f1
version bumps, removed some warnings (#1272)
Zabuzard Jul 1, 2025
2e1fb91
Merge junit version to have one consistent, single source of truth ve…
SquidXTV Jul 1, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
},
"features": {
"ghcr.io/devcontainers/features/java:1": {
"version": "18.0.2.1-tem",
"version": "24-tem",
"jdkDistro": "tem",
"installGradle": true
},
Expand All @@ -35,4 +35,4 @@
"postCreateCommand": {
"config": "cp application/config.json.template application/config.json"
}
}
}
2 changes: 1 addition & 1 deletion .github/workflows/basic-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: Basic checks
on: [pull_request]

env:
JAVA_VERSION: 21
JAVA_VERSION: 24

jobs:
spotless:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/code-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ on:
- cron: '0 20 * * 4'

env:
JAVA_VERSION: 21
JAVA_VERSION: 24

jobs:
sonar:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/docker-publish.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ on:
- 'master'

env:
JAVA_VERSION: 21
JAVA_VERSION: 24

jobs:
docker:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/docker-verify.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: Docker Verify
on: [pull_request]

env:
JAVA_VERSION: 21
JAVA_VERSION: 24

jobs:
docker:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/releases.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ defaults:
shell: bash

env:
JAVA_VERSION: 21
JAVA_VERSION: 24

jobs:

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# TJ-Bot

[![codefactor](https://img.shields.io/codefactor/grade/github/together-java/tj-bot)](https://www.codefactor.io/repository/github/together-java/tj-bot)
![Java](https://img.shields.io/badge/Java-21-ff696c)
![Java](https://img.shields.io/badge/Java-24-ff696c)
[![license](https://img.shields.io/github/license/Together-Java/TJ-Bot)](https://github.com/Together-Java/TJ-Bot/blob/master/LICENSE)
![GitHub release (latest by date)](https://img.shields.io/github/v/release/Together-Java/TJ-Bot?label=release)

Expand Down
35 changes: 18 additions & 17 deletions application/build.gradle
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
buildscript {
dependencies {
classpath 'org.xerial:sqlite-jdbc:3.47.1.0'
classpath 'org.xerial:sqlite-jdbc:3.50.1.0'
}
}

plugins {
id 'application'
id 'com.google.cloud.tools.jib' version '3.4.0'
id 'com.google.cloud.tools.jib' version '3.4.5'
id 'com.github.johnrengelman.shadow' version '8.1.1'
id 'database-settings'
}
Expand All @@ -18,7 +18,7 @@ repositories {
var outputImage = 'togetherjava.org:5001/togetherjava/tjbot:' + System.getenv('BRANCH_NAME') ?: 'latest'

jib {
from.image = 'eclipse-temurin:21'
from.image = 'eclipse-temurin:24'
to {
image = outputImage
auth {
Expand Down Expand Up @@ -46,18 +46,18 @@ dependencies {
implementation project(':utils')
implementation project(':formatter')

implementation 'net.dv8tion:JDA:5.2.1'
implementation 'net.dv8tion:JDA:5.6.1'

implementation 'org.apache.logging.log4j:log4j-core:2.24.3'
runtimeOnly 'org.apache.logging.log4j:log4j-slf4j18-impl:2.18.0'
implementation 'org.apache.logging.log4j:log4j-core:2.25.0'
runtimeOnly 'org.apache.logging.log4j:log4j-slf4j2-impl:2.25.0'

implementation 'club.minnced:discord-webhooks:0.8.2'
implementation 'club.minnced:discord-webhooks:0.8.4'

implementation "org.jooq:jooq:$jooqVersion"

implementation 'io.mikael:urlbuilder:2.0.9'

implementation 'org.jsoup:jsoup:1.18.1'
implementation 'org.jsoup:jsoup:1.21.1'

implementation 'org.scilab.forge:jlatexmath:1.0.7'
implementation 'org.scilab.forge:jlatexmath-font-greek:1.0.7'
Expand All @@ -67,29 +67,30 @@ dependencies {
implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:$jacksonVersion"
implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-xml:$jacksonVersion"
implementation "com.fasterxml.jackson.core:jackson-databind:$jacksonVersion"
implementation "com.sigpwned:jackson-modules-java17-sealed-classes:0.0.0"
implementation "com.sigpwned:jackson-modules-java17-sealed-classes:2.19.0.0"

implementation 'com.github.freva:ascii-table:1.8.0'

implementation 'io.github.url-detector:url-detector:0.1.23'

implementation 'com.github.ben-manes.caffeine:caffeine:3.1.1'
implementation 'com.github.ben-manes.caffeine:caffeine:3.2.0'

implementation 'org.kohsuke:github-api:1.326'
implementation 'org.kohsuke:github-api:1.327'

implementation 'org.apache.commons:commons-text:1.12.0'
implementation 'com.apptasticsoftware:rssreader:3.8.1'
implementation 'org.apache.commons:commons-text:1.13.1'
implementation 'com.apptasticsoftware:rssreader:3.9.3'

testImplementation 'org.mockito:mockito-core:5.17.0'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.11.4'
testImplementation 'org.junit.jupiter:junit-jupiter-params:5.11.0'
testImplementation 'org.mockito:mockito-core:5.18.0'
testImplementation "org.junit.jupiter:junit-jupiter-api:$junitVersion"
testImplementation "org.junit.jupiter:junit-jupiter-params:$junitVersion"
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.11.1'
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:$junitVersion"

implementation "com.theokanning.openai-gpt3-java:api:$chatGPTVersion"
implementation "com.theokanning.openai-gpt3-java:service:$chatGPTVersion"
}

application {
mainClass = 'org.togetherjava.tjbot.Application'
applicationDefaultJvmArgs = ["--enable-native-access=ALL-UNNAMED"]
}
4 changes: 2 additions & 2 deletions application/config.json.template
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,9 @@
"rssConfig": {
"feeds": [
{
"url": "https://wiki.openjdk.org/spaces/createrssfeed.action?types=page&types=comment&types=blogpost&types=mail&types=attachment&spaces=JDKUpdates&maxResults=15&title=%5BJDK+Updates%5D+All+Content+Feed&publicFeed=true",
"url": "https://blogs.oracle.com/java/rss",
"targetChannelPattern": "java-news-and-changes",
"dateFormatterPattern": "yyyy-MM-dd'T'HH:mm:ssX"
"dateFormatterPattern": "EEE, d MMM yyyy HH:mm:ss z"
}
],
"fallbackChannelPattern": "java-news-and-changes",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
import net.dv8tion.jda.api.events.interaction.component.EntitySelectInteractionEvent;
import net.dv8tion.jda.api.events.interaction.component.StringSelectInteractionEvent;
import net.dv8tion.jda.api.interactions.InteractionContextType;
import net.dv8tion.jda.api.interactions.commands.Command;
import net.dv8tion.jda.api.interactions.commands.build.CommandData;
import org.jetbrains.annotations.Contract;
Expand All @@ -15,6 +16,7 @@

import java.util.List;
import java.util.Objects;
import java.util.Set;

/**
* Adapter implementation of a {@link BotCommand}. The minimal setup only requires implementation of
Expand Down Expand Up @@ -51,7 +53,14 @@ public abstract class BotCommandAdapter implements BotCommand {
* @param visibility the visibility of the command
*/
protected BotCommandAdapter(CommandData data, CommandVisibility visibility) {
this.data = data.setGuildOnly(visibility == CommandVisibility.GUILD);
this.data = data;

Set<InteractionContextType> contexts = switch (visibility) {
case GUILD -> Set.of(InteractionContextType.GUILD);
case GLOBAL -> InteractionContextType.ALL;
};

data.setContexts(contexts);
this.visibility = Objects.requireNonNull(visibility, "The visibility shouldn't be null");

name = data.getName();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
import org.togetherjava.tjbot.features.help.HelpThreadMetadataPurger;
import org.togetherjava.tjbot.features.help.MarkHelpThreadCloseInDBRoutine;
import org.togetherjava.tjbot.features.help.PinnedNotificationRemover;
import org.togetherjava.tjbot.features.javamail.RSSHandlerRoutine;
import org.togetherjava.tjbot.features.jshell.JShellCommand;
import org.togetherjava.tjbot.features.jshell.JShellEval;
import org.togetherjava.tjbot.features.mathcommands.TeXCommand;
Expand Down Expand Up @@ -66,6 +65,7 @@
import org.togetherjava.tjbot.features.projects.ProjectsThreadCreatedListener;
import org.togetherjava.tjbot.features.reminder.RemindRoutine;
import org.togetherjava.tjbot.features.reminder.ReminderCommand;
import org.togetherjava.tjbot.features.rss.RSSHandlerRoutine;
import org.togetherjava.tjbot.features.system.BotCore;
import org.togetherjava.tjbot.features.system.LogLevelCommand;
import org.togetherjava.tjbot.features.tags.TagCommand;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,11 @@ public void onSlashCommand(SlashCommandInteractionEvent event) {
public void onModalSubmitted(ModalInteractionEvent event, List<String> args) {
event.deferReply().queue();

String context = "";
String question = event.getValue(QUESTION_INPUT).getAsString();

Optional<String> optional = chatGptService.ask(question, context);
if (optional.isPresent()) {
Optional<String> chatgptResponse =
chatGptService.ask(question, "You may use markdown syntax for the response");
if (chatgptResponse.isPresent()) {
userIdToAskedAtCache.put(event.getMember().getId(), Instant.now());
}

Expand All @@ -93,7 +93,7 @@ public void onModalSubmitted(ModalInteractionEvent event, List<String> args) {
Please try again later.
""";

String response = optional.orElse(errorResponse);
String response = chatgptResponse.orElse(errorResponse);
SelfUser selfUser = event.getJDA().getSelfUser();

MessageEmbed responseEmbed = helper.generateGptResponseEmbed(response, selfUser, question);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@

import org.togetherjava.tjbot.config.Config;

import javax.annotation.Nullable;

import java.time.Duration;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
Expand Down Expand Up @@ -91,37 +92,33 @@ public ChatGptService(Config config) {
* @see <a href="https://platform.openai.com/docs/guides/chat/managing-tokens">ChatGPT
* Tokens</a>.
*/
public Optional<String> ask(String question, String context) {
public Optional<String> ask(String question, @Nullable String context) {
if (isDisabled) {
return Optional.empty();
}

String contextText = context == null ? "" : ", Context: %s.".formatted(context);
String fullQuestion = "(KEEP IT CONCISE, NOT MORE THAN 280 WORDS%s) - %s"
.formatted(contextText, question);

ChatMessage chatMessage = new ChatMessage(ChatMessageRole.USER.value(), fullQuestion);
ChatCompletionRequest chatCompletionRequest = ChatCompletionRequest.builder()
.model(AI_MODEL)
.messages(List.of(chatMessage))
.frequencyPenalty(FREQUENCY_PENALTY)
.temperature(TEMPERATURE)
.maxTokens(MAX_TOKENS)
.n(MAX_NUMBER_OF_RESPONSES)
.build();
logger.debug("ChatGpt Request: {}", fullQuestion);

String response = null;
try {
String instructions = "KEEP IT CONCISE, NOT MORE THAN 280 WORDS";
String questionWithContext = "context: Category %s on a Java Q&A discord server. %s %s"
.formatted(context, instructions, question);
ChatMessage chatMessage = new ChatMessage(ChatMessageRole.USER.value(),
Objects.requireNonNull(questionWithContext));
ChatCompletionRequest chatCompletionRequest = ChatCompletionRequest.builder()
.model(AI_MODEL)
.messages(List.of(chatMessage))
.frequencyPenalty(FREQUENCY_PENALTY)
.temperature(TEMPERATURE)
.maxTokens(MAX_TOKENS)
.n(MAX_NUMBER_OF_RESPONSES)
.build();

String response = openAiService.createChatCompletion(chatCompletionRequest)
response = openAiService.createChatCompletion(chatCompletionRequest)
.getChoices()
.getFirst()
.getMessage()
.getContent();

if (response == null) {
return Optional.empty();
}

return Optional.of(response);
} catch (OpenAiHttpException openAiHttpException) {
logger.warn(
"There was an error using the OpenAI API: {} Code: {} Type: {} Status Code: {}",
Expand All @@ -131,6 +128,12 @@ public Optional<String> ask(String question, String context) {
logger.warn("There was an error using the OpenAI API: {}",
runtimeException.getMessage());
}
return Optional.empty();

logger.debug("ChatGpt Response: {}", response);
if (response == null) {
return Optional.empty();
}

return Optional.of(response);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ public void onMessageUpdated(MessageUpdateEvent event) {

// Re-apply the current action
return codeReplyMessage.editMessageEmbeds(maybeCodeAction.orElseThrow().apply(code));
}).queue(any -> {
}).queue(_ -> {
}, failure -> logger.warn(
"Attempted to update a code-reply-message ({}), but failed. The original code-message was {}",
codeReplyMessageId, originalMessageId, failure));
Expand Down Expand Up @@ -253,7 +253,7 @@ public void onMessageDeleted(MessageDeleteEvent event) {
// Delete the code reply as well
originalMessageToCodeReply.invalidate(originalMessageId);

event.getChannel().deleteMessageById(codeReplyMessageId).queue(any -> {
event.getChannel().deleteMessageById(codeReplyMessageId).queue(_ -> {
}, failure -> logger.warn(
"Attempted to delete a code-reply-message ({}), but failed. The original code-message was {}",
codeReplyMessageId, originalMessageId, failure));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ public void addComponentIdRemovedListener(Consumer<ComponentId> listener) {
* @throws InvalidComponentIdFormatException if the given component ID was in an unexpected
* format and could not be serialized
*/
@SuppressWarnings("WeakerAccess")
@SuppressWarnings({"WeakerAccess", "squid:S2259"})
public Optional<ComponentId> get(UUID uuid) {
synchronized (storeLock) {
// Get it from the cache or, if not found, the database
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ Optional<GHIssue> findIssue(int id, String targetIssueTitle) {
if (issue.getTitle().equals(targetIssueTitle)) {
return Optional.of(issue);
}
} catch (FileNotFoundException ignored) {
} catch (FileNotFoundException _) {
return Optional.<GHIssue>empty();
} catch (IOException ex) {
throw new UncheckedIOException(ex);
Expand All @@ -255,7 +255,7 @@ Optional<GHIssue> findIssue(int id, long defaultRepoId) {
issue = repository.getPullRequest(id);
}
return Optional.of(issue);
} catch (FileNotFoundException ignored) {
} catch (FileNotFoundException _) {
return Optional.<GHIssue>empty();
} catch (IOException ex) {
throw new UncheckedIOException(ex);
Expand Down
Loading
Loading