Skip to content

Commit de1e46e

Browse files
committed
mark solution with Answer Overflow when users are thanked by OP
1 parent cf9421d commit de1e46e

3 files changed

Lines changed: 84 additions & 14 deletions

File tree

src/main/java/net/discordjug/javabot/data/config/SystemsConfig.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ public class SystemsConfig {
2424
* The Key used for the bing-search-api.
2525
*/
2626
private String azureSubscriptionKey = "";
27+
28+
/**
29+
* The API key of the Answer Overflow API.
30+
*/
31+
private String answerOverflowApiKey = "";
2732

2833
/**
2934
* The DSN for the Sentry API.
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package net.discordjug.javabot.systems.help;
2+
3+
import java.io.IOException;
4+
import java.net.URI;
5+
import java.net.http.HttpClient;
6+
import java.net.http.HttpRequest;
7+
import java.net.http.HttpRequest.BodyPublishers;
8+
import java.net.http.HttpResponse;
9+
import java.net.http.HttpResponse.BodyHandlers;
10+
11+
import lombok.extern.slf4j.Slf4j;
12+
import net.discordjug.javabot.data.config.BotConfig;
13+
import org.springframework.stereotype.Service;
14+
15+
@Service
16+
@Slf4j
17+
public class AnswerOverflowService {
18+
private final String apiKey;
19+
20+
public AnswerOverflowService(BotConfig config) {
21+
apiKey = config.getSystems().getAnswerOverflowApiKey();
22+
}
23+
24+
public void markAnswer(long postId, long messageId) {
25+
if (apiKey == null || apiKey.isBlank()) {
26+
return;
27+
}
28+
29+
try (HttpClient client = HttpClient.newHttpClient()) {
30+
HttpResponse<String> response = client.send(
31+
HttpRequest.newBuilder(URI.create("https://www.answeroverflow.com/api/v1/messages/" + postId))
32+
.header("x-api-key", apiKey)
33+
.header("Content-Type", "application/json")
34+
.POST(BodyPublishers.ofString("""
35+
{
36+
"solutionId": "%d"
37+
}
38+
""".formatted(messageId)))
39+
.build(),
40+
BodyHandlers.ofString());
41+
if (response.statusCode() != 200) {
42+
log.warn("Answer Overflow responded with unexpected status code {}, post ID: {}, message ID: {}, body: {}", response.statusCode(), postId, messageId, response.body());
43+
}
44+
} catch (IOException e) {
45+
log.error("An exception occured trying to mark a post as an answer.", e);
46+
} catch (InterruptedException e) {
47+
Thread.currentThread().interrupt();
48+
};
49+
}
50+
}

src/main/java/net/discordjug/javabot/systems/help/HelpListener.java

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import xyz.dynxsty.dih4jda.util.ComponentIdBuilder;
3131

3232
import java.util.*;
33+
import java.util.stream.Collectors;
3334
import java.util.stream.Stream;
3435

3536
/**
@@ -79,6 +80,7 @@ protected boolean removeEldestEntry(Map.Entry<Long, Long> eldest) {
7980
return System.currentTimeMillis() > eldest.getValue() || size() >= 32;
8081
}
8182
};
83+
private final AnswerOverflowService answerOverflowService;
8284

8385
@Override
8486
public void onMessageReceived(@NotNull MessageReceivedEvent event) {
@@ -121,12 +123,8 @@ public void onMessageReceived(@NotNull MessageReceivedEvent event) {
121123
return;
122124
}
123125
// cache messages
124-
List<Message> messages = new ArrayList<>();
125-
messages.add(event.getMessage());
126-
if (HELP_POST_MESSAGES.containsKey(post.getIdLong())) {
127-
messages.addAll(HELP_POST_MESSAGES.get(post.getIdLong()));
128-
}
129-
HELP_POST_MESSAGES.put(post.getIdLong(), messages);
126+
HELP_POST_MESSAGES.computeIfAbsent(post.getIdLong(), _ -> new ArrayList<>())
127+
.add(event.getMessage());
130128
// suggest to close post on "problem solved"-messages
131129
replyCloseSuggestionIfPatternMatches(event.getMessage());
132130
}
@@ -291,17 +289,34 @@ private void handleThanksCloseButton(@NotNull ButtonInteractionEvent event, Help
291289
event.getMessage().delete().queue(s -> {
292290
experienceService.addMessageBasedHelpXP(post, true);
293291
// thank all helpers
294-
getButtonStream(event.getMessage())
295-
.filter(b -> b.getCustomId() != null)
296-
.filter(b -> b.isDisabled() || (b.getCustomId().equals(additionalButtonId)))
297-
.forEach(b -> manager.thankHelper(
298-
event.getGuild(),
299-
post,
300-
Long.parseLong(ComponentIdBuilder.split(b.getCustomId())[2])
301-
));
292+
293+
Set<Long> helpersToThank = getButtonStream(event.getMessage())
294+
.filter(b -> b.getCustomId() != null)
295+
.filter(b -> b.isDisabled() || (b.getCustomId().equals(additionalButtonId)))
296+
.map(b -> Long.parseLong(ComponentIdBuilder.split(b.getCustomId())[2]))
297+
.collect(Collectors.toSet());
298+
299+
for (Long helperId : helpersToThank) {
300+
manager.thankHelper(event.getGuild(), post, helperId);
301+
}
302+
markAnswer(post, helpersToThank);
303+
HELP_POST_MESSAGES.remove(post.getIdLong());
302304
});
303305
}
304306

307+
private void markAnswer(ThreadChannel post, Set<Long> helpers) {
308+
List<Message> messages = HELP_POST_MESSAGES.get(post.getIdLong());
309+
if (messages == null) {
310+
return;
311+
}
312+
for (Message msg : messages.reversed()) {
313+
if (helpers.contains(msg.getAuthor().getIdLong())) {
314+
answerOverflowService.markAnswer(post.getIdLong(), msg.getIdLong());
315+
return;
316+
}
317+
}
318+
}
319+
305320
private void handleReplyGuidelines(@NotNull IReplyCallback callback, @NotNull ForumChannel channel) {
306321
callback.replyEmbeds(new EmbedBuilder().setTitle("Help Guidelines")
307322
.setDescription(channel.getTopic())

0 commit comments

Comments
 (0)