diff --git a/pom.xml b/pom.xml
index 261c5788..c4cbf78d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -58,10 +58,17 @@
guava
33.4.8-jre
+
- com.konghq
- unirest-java-core
- 4.5.0
+ org.springframework.boot
+ spring-boot-restclient
+ 4.0.0-M2
+
+
+
+ io.vavr
+ vavr
+ 0.10.7
com.google.code.gson
diff --git a/src/main/java/org/papertrail/listeners/commandlisteners/AuditLogSetupCommandListener.java b/src/main/java/org/papertrail/listeners/commandlisteners/AuditLogSetupCommandListener.java
index fd07bb25..0aeeefc6 100644
--- a/src/main/java/org/papertrail/listeners/commandlisteners/AuditLogSetupCommandListener.java
+++ b/src/main/java/org/papertrail/listeners/commandlisteners/AuditLogSetupCommandListener.java
@@ -3,10 +3,10 @@
import java.awt.Color;
import java.util.Objects;
-import org.papertrail.sdk.http.HttpServiceResponse;
-import org.papertrail.sdk.model.ErrorResponse;
+import io.vavr.control.Either;
+import org.papertrail.sdk.model.ErrorObject;
import org.papertrail.sdk.client.AuditLogClient;
-import org.papertrail.sdk.model.AuditLogResponse;
+import org.papertrail.sdk.model.AuditLogObject;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.Permission;
@@ -50,38 +50,41 @@ public void onSlashCommandInteraction(SlashCommandInteractionEvent event) {
private void setAuditLogging(SlashCommandInteractionEvent event) {
-
- // Only members with MANAGE_SERVER permissions should be able to use this command
- Member member = event.getMember();
- if (member == null || !member.hasPermission(Permission.MANAGE_SERVER)) {
- event.reply("â You don't have the permission required to use this command.").setEphemeral(true).queue();
- return;
- }
+
+ // Only members with MANAGE_SERVER permissions should be able to use this command
+ Member member = event.getMember();
+ if (member == null || !member.hasPermission(Permission.MANAGE_SERVER)) {
+ event.reply("â You don't have the permission required to use this command.").setEphemeral(true).queue();
+ return;
+ }
// Call the API to register the guild and the channel
- String channelIdToRegister = event.getChannel().asTextChannel().getId();
- HttpServiceResponse guildRegistration = AuditLogClient.registerGuild(Objects.requireNonNull(event.getGuild()).getId(), channelIdToRegister);
- if(guildRegistration.requestSuccess()){
+ String guildId = Objects.requireNonNull(event.getGuild()).getId();
+ String channelId = event.getChannel().asTextChannel().getId();
+
+ Either response = AuditLogClient.registerGuild(guildId, channelId);
+ response.peek(success -> {
EmbedBuilder eb = new EmbedBuilder();
eb.setTitle("đ Audit Log Configuration");
- eb.addField("â
Channel Registration Success","â°ââ¤"+"All audit log info will be logged here", false);
+ eb.addField("â
Channel Registration Success", "â°ââ¤" + "All audit log info will be logged here", false);
eb.setColor(Color.GREEN);
MessageEmbed mb = eb.build();
event.replyEmbeds(mb).setEphemeral(false).queue();
- } else {
+
+ }).peekLeft(failure -> {
EmbedBuilder eb = new EmbedBuilder();
eb.setTitle("đ Audit Log Configuration");
eb.addField("â Channel Registration Failure", "â°ââ¤" + "Channel could not be registered", false);
- eb.addField("\uD83C\uDF10 API Response", "â°ââ¤"+guildRegistration.error().message(), false);
+ eb.addField("\uD83C\uDF10 API Response", "â°ââ¤" + failure.message(), false);
eb.setColor(Color.YELLOW);
MessageEmbed mb = eb.build();
- event.replyEmbeds(mb).setEphemeral(false).queue();
- }
- }
+ event.replyEmbeds(mb).setEphemeral(false).queue();
+ });
+ }
private void retrieveAuditLoggingChannel(SlashCommandInteractionEvent event) {
@@ -95,13 +98,13 @@ private void retrieveAuditLoggingChannel(SlashCommandInteractionEvent event) {
String guildId = Objects.requireNonNull(event.getGuild()).getId();
// Call the API to retrieve the registered channel
- HttpServiceResponse guildRegistrationCheck = AuditLogClient.getRegisteredGuild(guildId);
+ Either response = AuditLogClient.getRegisteredGuild(guildId);
// if there is no channel_id for the given guild_id returned by the API, then inform
// the user of the same, else link the channel that has been registered
- if (guildRegistrationCheck.requestSuccess()) {
+ response.peek(success -> {
- String registeredChannelId = guildRegistrationCheck.success().channelId();
+ String registeredChannelId = success.channelId();
GuildChannel registeredChannel = event.getJDA().getGuildChannelById(registeredChannelId);
EmbedBuilder eb = new EmbedBuilder();
@@ -110,7 +113,8 @@ private void retrieveAuditLoggingChannel(SlashCommandInteractionEvent event) {
eb.addField("â
Channel Registration Check", "â°ââ¤"+(registeredChannel!=null ? registeredChannel.getAsMention() : registeredChannelId)+ " is found to be registered as the audit log channel", false);
MessageEmbed mb = eb.build();
event.replyEmbeds(mb).setEphemeral(false).queue();
- } else {
+
+ }).peekLeft(failure -> {
EmbedBuilder eb = new EmbedBuilder();
eb.setTitle("đ Audit Log Configuration");
@@ -118,7 +122,8 @@ private void retrieveAuditLoggingChannel(SlashCommandInteractionEvent event) {
eb.setColor(Color.YELLOW);
MessageEmbed mb = eb.build();
event.replyEmbeds(mb).setEphemeral(false).queue();
- }
+
+ });
}
private void unsetAuditLogging(SlashCommandInteractionEvent event) {
@@ -132,8 +137,8 @@ private void unsetAuditLogging(SlashCommandInteractionEvent event) {
String guildId = Objects.requireNonNull(event.getGuild()).getId();
// Call the API to unregister guild
- HttpServiceResponse guildUnregistration = AuditLogClient.deleteRegisteredGuild(guildId);
- if(guildUnregistration.requestSuccess()) {
+ Either response = AuditLogClient.deleteRegisteredGuild(guildId);
+ response.peek(success -> {
EmbedBuilder eb = new EmbedBuilder();
eb.setTitle("đ Audit Log Configuration");
@@ -143,17 +148,18 @@ private void unsetAuditLogging(SlashCommandInteractionEvent event) {
event.replyEmbeds(mb).setEphemeral(false).queue();
- } else {
+ }).peekLeft(failure -> {
EmbedBuilder eb = new EmbedBuilder();
eb.setTitle("đ Audit Log Configuration");
eb.addField("â Channel Removal Failure", "â°ââ¤"+"Channel could not be unset", false);
- eb.addField("\uD83C\uDF10 API Response", "â°ââ¤"+guildUnregistration.error().message(), false);
+ eb.addField("\uD83C\uDF10 API Response", "â°ââ¤"+failure.message(), false);
eb.setColor(Color.YELLOW);
MessageEmbed mb = eb.build();
event.replyEmbeds(mb).setEphemeral(false).queue();
- }
+ });
+
}
}
diff --git a/src/main/java/org/papertrail/listeners/commandlisteners/MessageLogSetupCommandListener.java b/src/main/java/org/papertrail/listeners/commandlisteners/MessageLogSetupCommandListener.java
index 11bfc3f1..484f1fd7 100644
--- a/src/main/java/org/papertrail/listeners/commandlisteners/MessageLogSetupCommandListener.java
+++ b/src/main/java/org/papertrail/listeners/commandlisteners/MessageLogSetupCommandListener.java
@@ -3,14 +3,13 @@
import java.awt.Color;
import java.util.Objects;
-import org.papertrail.sdk.http.HttpServiceResponse;
-import org.papertrail.sdk.model.ErrorResponse;
+import io.vavr.control.Either;
+import org.papertrail.sdk.model.ErrorObject;
import org.papertrail.sdk.client.MessageLogClient;
-import org.papertrail.sdk.model.MessageLogResponse;
+import org.papertrail.sdk.model.MessageLogObject;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.Permission;
-import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.MessageEmbed;
import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel;
@@ -57,13 +56,12 @@ private void setMessageLogging(SlashCommandInteractionEvent event) {
event.reply("â You don't have the permission required to use this command.").setEphemeral(true).queue();
return;
}
-
- Guild guild = event.getGuild();
- String guildId = Objects.requireNonNull(guild).getId();
+
+ String guildId = Objects.requireNonNull(event.getGuild()).getId();
// Call the API to register guild for message logging
- HttpServiceResponse guildRegistration = MessageLogClient.registerGuild(guildId, event.getChannelId());
- if(guildRegistration.requestSuccess()) {
+ Either response = MessageLogClient.registerGuild(guildId, event.getChannelId());
+ response.peek(success -> {
EmbedBuilder eb = new EmbedBuilder();
eb.setTitle("Message Log Registration");
@@ -72,17 +70,19 @@ private void setMessageLogging(SlashCommandInteractionEvent event) {
MessageEmbed mb = eb.build();
event.replyEmbeds(mb).setEphemeral(false).queue();
- } else {
+
+ }).peekLeft(failure -> {
EmbedBuilder eb = new EmbedBuilder();
eb.setTitle("Message Log Registration");
eb.addField("â Channel Registration Failure","â°ââ¤"+"Channel could not be registered", false);
- eb.addField("\uD83C\uDF10 API Response", "â°ââ¤"+guildRegistration.error().message(), false);
+ eb.addField("\uD83C\uDF10 API Response", "â°ââ¤"+failure.message(), false);
eb.setColor(Color.YELLOW);
MessageEmbed mb = eb.build();
event.replyEmbeds(mb).setEphemeral(false).queue();
- }
+ });
+
}
private void retrieveMessageLoggingChannel(SlashCommandInteractionEvent event) {
@@ -94,15 +94,13 @@ private void retrieveMessageLoggingChannel(SlashCommandInteractionEvent event) {
return;
}
- Guild guild = event.getGuild();
- String guildId = Objects.requireNonNull(guild).getId();
+ String guildId = Objects.requireNonNull(event.getGuild()).getId();
// Call the API to check for registered guild
- HttpServiceResponse guildRegistrationCheck = MessageLogClient.getRegisteredGuild(guildId);
-
- if(guildRegistrationCheck.requestSuccess()){
+ Either response = MessageLogClient.getRegisteredGuild(guildId);
+ response.peek(success -> {
- String registeredChannelId = guildRegistrationCheck.success().channelId();
+ String registeredChannelId = success.channelId();
GuildChannel registeredChannel = event.getJDA().getGuildChannelById(registeredChannelId);
EmbedBuilder eb = new EmbedBuilder();
@@ -112,7 +110,7 @@ private void retrieveMessageLoggingChannel(SlashCommandInteractionEvent event) {
MessageEmbed mb = eb.build();
event.replyEmbeds(mb).setEphemeral(false).queue();
- } else {
+ }).peekLeft(failure -> {
EmbedBuilder eb = new EmbedBuilder();
eb.setTitle("đ Message Log Configuration");
@@ -120,8 +118,7 @@ private void retrieveMessageLoggingChannel(SlashCommandInteractionEvent event) {
eb.setColor(Color.YELLOW);
MessageEmbed mb = eb.build();
event.replyEmbeds(mb).setEphemeral(false).queue();
-
- }
+ });
}
private void unsetMessageLogging(SlashCommandInteractionEvent event) {
@@ -133,12 +130,11 @@ private void unsetMessageLogging(SlashCommandInteractionEvent event) {
return;
}
- Guild guild = event.getGuild();
- String guildId = Objects.requireNonNull(guild).getId();
+ String guildId = Objects.requireNonNull(event.getGuild()).getId();
// Call the API to unregister guild
- HttpServiceResponse guildUnregistration = MessageLogClient.deleteRegisteredGuild(guildId);
- if (guildUnregistration.requestSuccess()) {
+ Either response = MessageLogClient.deleteRegisteredGuild(guildId);
+ response.peek(success -> {
EmbedBuilder eb = new EmbedBuilder();
eb.setTitle("đ Message Log Configuration");
@@ -147,17 +143,19 @@ private void unsetMessageLogging(SlashCommandInteractionEvent event) {
MessageEmbed mb = eb.build();
event.replyEmbeds(mb).setEphemeral(false).queue();
- } else {
+
+ }).peekLeft(failure -> {
EmbedBuilder eb = new EmbedBuilder();
eb.setTitle("đ Message Log Configuration");
eb.addField("â Channel Removal Failure", "â°ââ¤" + "Channel could not be unset", false);
- eb.addField("\uD83C\uDF10 API Response", "â°ââ¤" + guildUnregistration.error().message(), false);
+ eb.addField("\uD83C\uDF10 API Response", "â°ââ¤" + failure.message(), false);
eb.setColor(Color.YELLOW);
MessageEmbed mb = eb.build();
event.replyEmbeds(mb).setEphemeral(false).queue();
- }
+ });
+
}
}
diff --git a/src/main/java/org/papertrail/listeners/guildlisteners/ServerBoostListener.java b/src/main/java/org/papertrail/listeners/guildlisteners/ServerBoostListener.java
index 407810a9..9a9737fb 100644
--- a/src/main/java/org/papertrail/listeners/guildlisteners/ServerBoostListener.java
+++ b/src/main/java/org/papertrail/listeners/guildlisteners/ServerBoostListener.java
@@ -6,6 +6,7 @@
import java.util.Objects;
import java.util.concurrent.Executor;
+import io.vavr.control.Either;
import org.jetbrains.annotations.NotNull;
import net.dv8tion.jda.api.EmbedBuilder;
@@ -15,9 +16,8 @@
import net.dv8tion.jda.api.events.guild.member.update.GuildMemberUpdateBoostTimeEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import org.papertrail.sdk.client.AuditLogClient;
-import org.papertrail.sdk.http.HttpServiceResponse;
-import org.papertrail.sdk.model.AuditLogResponse;
-import org.papertrail.sdk.model.ErrorResponse;
+import org.papertrail.sdk.model.AuditLogObject;
+import org.papertrail.sdk.model.ErrorObject;
public class ServerBoostListener extends ListenerAdapter {
@@ -33,44 +33,43 @@ public void onGuildMemberUpdateBoostTime(@NotNull GuildMemberUpdateBoostTimeEven
vThreadPool.execute(()->{
// server boost logs are mapped to audit log table
// Call the API and see if the event came from a registered Guild
- HttpServiceResponse guildCheck = AuditLogClient.getRegisteredGuild(event.getGuild().getId());
+ Either response = AuditLogClient.getRegisteredGuild(event.getGuild().getId());
+ response.peek(success -> {
+ String registeredChannelId= success.channelId();
- if(!guildCheck.requestSuccess()){
- return;
- }
- String registeredChannelId= guildCheck.success().channelId();
+ Member member = event.getMember();
+ Guild guild = event.getGuild();
- Member member = event.getMember();
- Guild guild = event.getGuild();
+ String mentionableMember = member.getAsMention();
- String mentionableMember = member.getAsMention();
+ OffsetDateTime newBoostTime = event.getNewTimeBoosted(); // Will be null if the member stopped boosting
- OffsetDateTime newBoostTime = event.getNewTimeBoosted(); // Will be null if the member stopped boosting
+ EmbedBuilder eb = new EmbedBuilder();
+ eb.setTitle("đ Server Boost Event ");
+ eb.setThumbnail(guild.getIconUrl());
- EmbedBuilder eb = new EmbedBuilder();
- eb.setTitle("đ Server Boost Event ");
- eb.setThumbnail(guild.getIconUrl());
+ if (newBoostTime != null) {
+ eb.setDescription("đ **" + guild.getName() + "** has been boosted!");
+ eb.setColor(Color.PINK);
+ eb.addField("đ Booster Gained", "â°ââ¤"+mentionableMember+" has started boosting your server", false);
+ eb.addField("đ Total Boosts In The Server", "â°ââ¤"+guild.getBoostCount(), false);
+ eb.addField("đī¸ Current Boost Tier", "â°ââ¤"+ guild.getBoostTier(), false);
+ } else {
+ eb.setDescription("â ī¸ **" + guild.getName() + "** has lost a boost.");
+ eb.setColor(Color.GRAY);
+ eb.addField("đĒĢ Booster Lost", "â°ââ¤"+mentionableMember+" has removed their boost from your server", false);
+ eb.addField("đ Remaining Boosts In The Server", "â°ââ¤"+guild.getBoostCount(), false);
+ eb.addField("đī¸ Current Boost Tier", "â°ââ¤"+ guild.getBoostTier(), false);
+ eb.addField("Notice", "Boosts remain active for a period even after a member stops boosting, so the server's boost count doesn't update immediately.", false);
+ }
- if (newBoostTime != null) {
- eb.setDescription("đ **" + guild.getName() + "** has been boosted!");
- eb.setColor(Color.PINK);
- eb.addField("đ Booster Gained", "â°ââ¤"+mentionableMember+" has started boosting your server", false);
- eb.addField("đ Total Boosts In The Server", "â°ââ¤"+guild.getBoostCount(), false);
- eb.addField("đī¸ Current Boost Tier", "â°ââ¤"+ guild.getBoostTier(), false);
- } else {
- eb.setDescription("â ī¸ **" + guild.getName() + "** has lost a boost.");
- eb.setColor(Color.GRAY);
- eb.addField("đĒĢ Booster Lost", "â°ââ¤"+mentionableMember+" has removed their boost from your server", false);
- eb.addField("đ Remaining Boosts In The Server", "â°ââ¤"+guild.getBoostCount(), false);
- eb.addField("đī¸ Current Boost Tier", "â°ââ¤"+ guild.getBoostTier(), false);
- eb.addField("Notice", "Boosts remain active for a period even after a member stops boosting, so the server's boost count doesn't update immediately.", false);
- }
+ eb.setFooter("Server Boost Detection");
+ eb.setTimestamp(Instant.now());
- eb.setFooter("Server Boost Detection");
- eb.setTimestamp(Instant.now());
+ MessageEmbed mb = eb.build();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(registeredChannelId)).sendMessageEmbeds(mb).queue();
+ });
- MessageEmbed mb = eb.build();
- Objects.requireNonNull(event.getGuild().getTextChannelById(registeredChannelId)).sendMessageEmbeds(mb).queue();
});
}
}
diff --git a/src/main/java/org/papertrail/listeners/loglisteners/AuditLogListener.java b/src/main/java/org/papertrail/listeners/loglisteners/AuditLogListener.java
index b7f88b9e..93705e76 100644
--- a/src/main/java/org/papertrail/listeners/loglisteners/AuditLogListener.java
+++ b/src/main/java/org/papertrail/listeners/loglisteners/AuditLogListener.java
@@ -6,12 +6,12 @@
import java.util.Objects;
import java.util.concurrent.Executor;
+import io.vavr.control.Either;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.papertrail.sdk.client.AuditLogClient;
-import org.papertrail.sdk.http.HttpServiceResponse;
-import org.papertrail.sdk.model.AuditLogResponse;
-import org.papertrail.sdk.model.ErrorResponse;
+import org.papertrail.sdk.model.AuditLogObject;
+import org.papertrail.sdk.model.ErrorObject;
import org.papertrail.utilities.ColorFormatter;
import org.papertrail.utilities.DurationFormatter;
import org.papertrail.utilities.GuildSystemChannelFlagResolver;
@@ -50,12 +50,11 @@ public void onGuildAuditLogEntryCreate(@NotNull GuildAuditLogEntryCreateEvent ev
vThreadPool.execute(()->{
// Call the API and see if the event came from a registered Guild
- HttpServiceResponse guildCheck = AuditLogClient.getRegisteredGuild(event.getGuild().getId());
-
- if(guildCheck.requestSuccess()){
+ Either response = AuditLogClient.getRegisteredGuild(event.getGuild().getId());
+ response.peek(success -> {
AuditLogEntry ale = event.getEntry();
- auditLogParser(event, ale, guildCheck.success().channelId());
- }
+ auditLogParser(event, ale, success.channelId());
+ });
});
}
diff --git a/src/main/java/org/papertrail/listeners/loglisteners/MessageLogListener.java b/src/main/java/org/papertrail/listeners/loglisteners/MessageLogListener.java
index 626cf2fe..dd91339f 100644
--- a/src/main/java/org/papertrail/listeners/loglisteners/MessageLogListener.java
+++ b/src/main/java/org/papertrail/listeners/loglisteners/MessageLogListener.java
@@ -10,6 +10,7 @@
import com.google.common.base.Splitter;
import com.google.common.util.concurrent.Striped;
+import io.vavr.control.Either;
import org.jetbrains.annotations.NotNull;
import org.jspecify.annotations.NonNull;
@@ -22,10 +23,9 @@
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import org.papertrail.sdk.client.MessageContentLogClient;
import org.papertrail.sdk.client.MessageLogClient;
-import org.papertrail.sdk.http.HttpServiceResponse;
-import org.papertrail.sdk.model.ErrorResponse;
-import org.papertrail.sdk.model.MessageContentResponse;
-import org.papertrail.sdk.model.MessageLogResponse;
+import org.papertrail.sdk.model.ErrorObject;
+import org.papertrail.sdk.model.MessageContentObject;
+import org.papertrail.sdk.model.MessageLogObject;
import org.papertrail.utilities.MessageEncryption;
import org.tinylog.Logger;
@@ -68,22 +68,15 @@ public void onMessageReceived(MessageReceivedEvent event) {
// get the guild id for which the event was fired
String guildId = event.getGuild().getId();
// Call the API to see if the guild is registered for Message Logging
- HttpServiceResponse guildRegistrationCheck = MessageLogClient.getRegisteredGuild(guildId);
-
- // if not registered, exit
- if(!guildRegistrationCheck.requestSuccess()) {
- return;
- }
-
- // else log the message with its ID and author
- String messageId = event.getMessageId();
- String encryptedMessage = MessageEncryption.encrypt(event.getMessage().getContentRaw());
- String authorId = event.getAuthor().getId();
-
- withMessageLock(messageId, ()-> MessageContentLogClient.logMessage(messageId, encryptedMessage, authorId));
+ Either response = MessageLogClient.getRegisteredGuild(guildId);
+ response.peek(success -> {
+ String messageId = event.getMessageId();
+ String encryptedMessage = MessageEncryption.encrypt(event.getMessage().getContentRaw());
+ String authorId = event.getAuthor().getId();
+
+ withMessageLock(messageId, ()-> MessageContentLogClient.logMessage(messageId, encryptedMessage, authorId));
+ });
});
-
-
}
@Override
@@ -95,66 +88,62 @@ public void onMessageUpdate(MessageUpdateEvent event) {
vThreadPool.execute(()->{
+ // Get the guild id for which the event was fired
String guildId = event.getGuild().getId();
+ // get the message id of the message which was updated
+ String messageId = event.getMessageId();
// Call the API to see if the guild is registered for Message Logging
- HttpServiceResponse guildRegistrationCheck = MessageLogClient.getRegisteredGuild(guildId);
-
- // if not registered, exit
- if(!guildRegistrationCheck.requestSuccess()) {
- return;
- }
-
- // get the message id of the message which was updated
- String messageId = event.getMessageId();
-
- // fetch the old message object from the API
- HttpServiceResponse loggedMessageResponse = MessageContentLogClient.retrieveMessage(messageId);
- if(!loggedMessageResponse.requestSuccess()){ // if message does not exist (it wasn't logged), then return
- return;
- }
- // Decrypt the fetched message
- assert loggedMessageResponse.success() != null;
- String decryptedMessage = MessageEncryption.decrypt(loggedMessageResponse.success().messageContent());
- // fetch the updated message and its author from the event
- String updatedMessage = event.getMessage().getContentRaw();
-
- // Ignore events where the message content wasn't edited (e.g., pin, embed resolve, thread creates and updates)
- // This is required since MessageUpdateEvent is triggered in case of pins and embed resolves with no change to content
- if(updatedMessage.equals(decryptedMessage)) {
- return;
- }
-
- // Splitting is required because each field in an embed can display only up-to 1024 characters
- assert decryptedMessage != null;
- List decryptedMessageSplits = Splitter.fixedLength(1024).splitToList(decryptedMessage);
- List updatedMessageSplits = Splitter.fixedLength(1024).splitToList(updatedMessage);
-
- EmbedBuilder eb = new EmbedBuilder();
- eb.setTitle("đ Message Edit Event");
- eb.setDescription("A message sent by "+event.getAuthor().getAsMention()+" has been edited in: "+event.getJumpUrl());
- eb.setColor(Color.YELLOW);
-
- decryptedMessageSplits.forEach(split -> eb.addField("Old Message", split, false)); // get only the message and not the author
- updatedMessageSplits.forEach(split -> eb.addField("New Message", split, false));
-
- eb.setFooter(event.getGuild().getName());
- eb.setTimestamp(Instant.now());
- // update the database with the new message
- withMessageLock(messageId, ()->
- MessageContentLogClient.updateMessage(
- messageId, MessageEncryption.encrypt(updatedMessage), event.getAuthor().getId()
- )
- );
- // the reason this is above the send queue is that in case where the user did not give sufficient permissions to
- // the bot, the error responses wouldn't block the update of the message in the database.
-
- // fetch the channel id from the database
- // this channel is where the logs will be sent to
- // wrap the embed and send
- MessageEmbed mb = eb.build();
- assert guildRegistrationCheck.success() != null;
- String channelIdToSendTo = guildRegistrationCheck.success().channelId();
- Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
+ Either response = MessageLogClient.getRegisteredGuild(guildId);
+ response.peek(success -> {
+
+ // retrieve the channel id where the logs must be sent
+ String channelIdToSendTo = success.channelId();
+
+ // fetch the old message object from the API
+ Either updatedMessageObject = MessageContentLogClient.retrieveMessage(messageId);
+ updatedMessageObject.peek(content -> {
+ // Decrypt the fetched message
+ String decryptedMessage = MessageEncryption.decrypt(content.messageContent());
+ // fetch the updated message and its author from the event
+ String updatedMessage = event.getMessage().getContentRaw();
+
+ // Ignore events where the message content wasn't edited (e.g., pin, embed resolve, thread creates and updates)
+ // This is required since MessageUpdateEvent is triggered in case of pins and embed resolves with no change to content
+ if(updatedMessage.equals(decryptedMessage)) {
+ return;
+ }
+
+ // Splitting is required because each field in an embed can display only up-to 1024 characters
+ assert decryptedMessage != null;
+ List decryptedMessageSplits = Splitter.fixedLength(1024).splitToList(decryptedMessage);
+ List updatedMessageSplits = Splitter.fixedLength(1024).splitToList(updatedMessage);
+
+ EmbedBuilder eb = new EmbedBuilder();
+ eb.setTitle("đ Message Edit Event");
+ eb.setDescription("A message sent by "+event.getAuthor().getAsMention()+" has been edited in: "+event.getJumpUrl());
+ eb.setColor(Color.YELLOW);
+
+ decryptedMessageSplits.forEach(split -> eb.addField("Old Message", split, false)); // get only the message and not the author
+ updatedMessageSplits.forEach(split -> eb.addField("New Message", split, false));
+
+ eb.setFooter(event.getGuild().getName());
+ eb.setTimestamp(Instant.now());
+ // update the database with the new message
+ withMessageLock(messageId, ()->
+ MessageContentLogClient.updateMessage(
+ messageId, MessageEncryption.encrypt(updatedMessage), event.getAuthor().getId()
+ )
+ );
+ // the reason this is above the send queue is that in case where the user did not give sufficient permissions to
+ // the bot, the error responses wouldn't block the update of the message in the database.
+
+ // fetch the channel id from the database
+ // this channel is where the logs will be sent to
+ // wrap the embed and send
+ MessageEmbed mb = eb.build();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
+ });
+ });
});
}
@@ -163,58 +152,53 @@ public void onMessageDelete(@NotNull MessageDeleteEvent event) {
vThreadPool.execute(()-> {
+ // Get the guild id for which the event was fired
String guildId = event.getGuild().getId();
- // Call the API to see if the guild is registered for Message Logging
- HttpServiceResponse guildRegistrationCheck = MessageLogClient.getRegisteredGuild(guildId);
+ // get the message id of the message which was deleted
+ String messageId = event.getMessageId();
- // if not registered, exit
- if(!guildRegistrationCheck.requestSuccess()) {
- return;
- }
-
- // get the message id of the message which was deleted
- String messageId = event.getMessageId();
+ // Call the API to see if the guild is registered for Message Logging
+ Either response = MessageLogClient.getRegisteredGuild(guildId);
+ response.peek(success -> {
- // fetch the old message object from the API
- HttpServiceResponse loggedMessageResponse = MessageContentLogClient.retrieveMessage(messageId);
- if(!loggedMessageResponse.requestSuccess()){ // if message does not exist (it wasn't logged), then return
- return;
- }
+ // retrieve the channel id where the logs must be sent
+ String channelIdToSendTo = success.channelId();
- // retrieve the channel id where the logs must be sent
- assert guildRegistrationCheck.success() != null;
- String channelIdToSendTo = guildRegistrationCheck.success().channelId();
+ // fetch the old message object from the API
+ Either deletedMessageObject = MessageContentLogClient.retrieveMessage(messageId);
+ deletedMessageObject.peek(content -> {
- // retrieve the stored message and author in the database which was deleted
- assert loggedMessageResponse.success() != null;
- String deletedMessage = MessageEncryption.decrypt(loggedMessageResponse.success().messageContent());
- String deletedMessageAuthorId = loggedMessageResponse.success().authorId();
+ // retrieve the stored message and author in the database which was deleted
+ String deletedMessage = MessageEncryption.decrypt(content.messageContent());
+ String deletedMessageAuthorId = content.authorId();
- User author = event.getJDA().getUserById(deletedMessageAuthorId);
- String mentionableAuthor = (author !=null ? author.getAsMention() : deletedMessageAuthorId);
+ User author = event.getJDA().getUserById(deletedMessageAuthorId);
+ String mentionableAuthor = (author !=null ? author.getAsMention() : deletedMessageAuthorId);
- // Splitting is required because each field in an embed can display only up-to 1024 characters
- assert deletedMessage != null;
- List deletedMessageSplits = Splitter.fixedLength(1024).splitToList(deletedMessage);
+ // Splitting is required because each field in an embed can display only up-to 1024 characters
+ assert deletedMessage != null;
+ List deletedMessageSplits = Splitter.fixedLength(1024).splitToList(deletedMessage);
- EmbedBuilder eb = new EmbedBuilder();
- eb.setTitle("đī¸ Message Delete Event");
- eb.setDescription("A message sent by "+mentionableAuthor+" has been deleted");
- eb.setColor(Color.RED);
+ EmbedBuilder eb = new EmbedBuilder();
+ eb.setTitle("đī¸ Message Delete Event");
+ eb.setDescription("A message sent by "+mentionableAuthor+" has been deleted");
+ eb.setColor(Color.RED);
- deletedMessageSplits.forEach(split-> eb.addField("Deleted Message", split, false));
+ deletedMessageSplits.forEach(split-> eb.addField("Deleted Message", split, false));
- eb.setFooter(event.getGuild().getName());
- eb.setTimestamp(Instant.now());
+ eb.setFooter(event.getGuild().getName());
+ eb.setTimestamp(Instant.now());
- // delete the message from the database
- withMessageLock(messageId, ()-> MessageContentLogClient.deleteMessage(messageId));
- // the reason this is above the send queue is that, in case where the user did not give sufficient permissions to
- // the bot, (such as no send message permissions) the exceptions wouldn't block the deletion in the database.
+ // delete the message from the database
+ withMessageLock(messageId, ()-> MessageContentLogClient.deleteMessage(messageId));
+ // the reason this is above the send queue is that, in case where the user did not give sufficient permissions to
+ // the bot, (such as no send message permissions) the exceptions wouldn't block the deletion in the database.
- // send the fetched deleted message to the logging channel
- MessageEmbed mb = eb.build();
- Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
+ // send the fetched deleted message to the logging channel
+ MessageEmbed mb = eb.build();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(channelIdToSendTo)).sendMessageEmbeds(mb).queue();
+ });
+ });
});
}
}
diff --git a/src/main/java/org/papertrail/listeners/memberlisteners/GuildMemberJoinAndLeaveListener.java b/src/main/java/org/papertrail/listeners/memberlisteners/GuildMemberJoinAndLeaveListener.java
index 552a7d8e..21e4afba 100644
--- a/src/main/java/org/papertrail/listeners/memberlisteners/GuildMemberJoinAndLeaveListener.java
+++ b/src/main/java/org/papertrail/listeners/memberlisteners/GuildMemberJoinAndLeaveListener.java
@@ -1,5 +1,6 @@
package org.papertrail.listeners.memberlisteners;
+import io.vavr.control.Either;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
@@ -10,9 +11,8 @@
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import org.jetbrains.annotations.NotNull;
import org.papertrail.sdk.client.AuditLogClient;
-import org.papertrail.sdk.http.HttpServiceResponse;
-import org.papertrail.sdk.model.AuditLogResponse;
-import org.papertrail.sdk.model.ErrorResponse;
+import org.papertrail.sdk.model.AuditLogObject;
+import org.papertrail.sdk.model.ErrorObject;
import org.papertrail.utilities.DurationFormatter;
import java.awt.Color;
@@ -35,33 +35,32 @@ public void onGuildMemberJoin(@NotNull GuildMemberJoinEvent event) {
vThreadPool.execute(()->{
// guild member join and leave events are mapped to audit log table
// Call the API and see if the event came from a registered Guild
- HttpServiceResponse guildCheck = AuditLogClient.getRegisteredGuild(event.getGuild().getId());
+ Either response = AuditLogClient.getRegisteredGuild(event.getGuild().getId());
+ response.peek(success -> {
- if(!guildCheck.requestSuccess()){
- return;
- }
- String registeredChannelId = guildCheck.success().channelId();
+ String registeredChannelId = success.channelId();
- Guild guild = event.getGuild();
- User user = event.getUser();
+ Guild guild = event.getGuild();
+ User user = event.getUser();
- EmbedBuilder eb = new EmbedBuilder();
- eb.setTitle("đŦ Member Join Event");
- eb.setDescription("A Member has joined "+guild.getName());
- eb.setColor(Color.GREEN);
+ EmbedBuilder eb = new EmbedBuilder();
+ eb.setTitle("đŦ Member Join Event");
+ eb.setDescription("A Member has joined "+guild.getName());
+ eb.setColor(Color.GREEN);
- eb.addField("đˇī¸ Member Name", "â°ââ¤"+user.getName(), false);
- eb.setThumbnail(user.getEffectiveAvatarUrl());
- eb.addField("âšī¸ Member Mention", "â°ââ¤"+user.getAsMention(), false);
- eb.addField("đ Member ID", "â°ââ¤"+user.getId(), false);
- eb.addField("đ
Account Created", "â°ââ¤"+DurationFormatter.isoToLocalTimeCounter(user.getTimeCreated()), false);
- eb.addField("đ¤ Is Application ?", "â°ââ¤"+((user.isBot()) ? "â
" : "â"), false);
- eb.setFooter("Member Join Detection");
- eb.setTimestamp(Instant.now());
+ eb.addField("đˇī¸ Member Name", "â°ââ¤"+user.getName(), false);
+ eb.setThumbnail(user.getEffectiveAvatarUrl());
+ eb.addField("âšī¸ Member Mention", "â°ââ¤"+user.getAsMention(), false);
+ eb.addField("đ Member ID", "â°ââ¤"+user.getId(), false);
+ eb.addField("đ
Account Created", "â°ââ¤"+DurationFormatter.isoToLocalTimeCounter(user.getTimeCreated()), false);
+ eb.addField("đ¤ Is Application ?", "â°ââ¤"+((user.isBot()) ? "â
" : "â"), false);
+ eb.setFooter("Member Join Detection");
+ eb.setTimestamp(Instant.now());
- MessageEmbed mb = eb.build();
+ MessageEmbed mb = eb.build();
- Objects.requireNonNull(event.getGuild().getTextChannelById(registeredChannelId)).sendMessageEmbeds(mb).queue();
+ Objects.requireNonNull(event.getGuild().getTextChannelById(registeredChannelId)).sendMessageEmbeds(mb).queue();
+ });
});
}
@@ -70,42 +69,42 @@ public void onGuildMemberRemove(@NotNull GuildMemberRemoveEvent event) {
vThreadPool.execute(() -> {
// Call the API and see if the event came from a registered Guild
- HttpServiceResponse guildCheck = AuditLogClient.getRegisteredGuild(event.getGuild().getId());
-
- if(!guildCheck.requestSuccess()){
- return;
- }
- String registeredChannelId = guildCheck.success().channelId();
-
- Guild guild = event.getGuild();
- User user = event.getUser();
- Member member = event.getMember();
-
- String memberJoinDate = "Member Not Cached";
- boolean memberJoinDateTrustable = false;
- if(member!=null){
- memberJoinDate = "";
- memberJoinDateTrustable = member.hasTimeJoined();
- }
-
- EmbedBuilder eb = new EmbedBuilder();
- eb.setTitle("đĢ Member Leave Event");
- eb.setDescription("A Member has left "+guild.getName());
- eb.setColor(Color.RED);
-
- eb.addField("đˇī¸ Member Name", "â°ââ¤"+user.getName(), false);
- eb.setThumbnail(user.getEffectiveAvatarUrl());
- eb.addField("đ Member ID", "â°ââ¤"+user.getId(), false);
- eb.addField("â Member Joined The Server On","â°ââ¤"+memberJoinDate, false);
- eb.addField("â Member Join Date Accurate?", memberJoinDateTrustable ? "â
" : "â" , false);
-
- eb.setFooter("Join timestamp may fall back to guild creation time if not provided by Discord during lazy loading of members. " +
- "Accuracy of the timestamp can be determined by the extra field provided.");
- eb.setTimestamp(Instant.now());
-
- MessageEmbed mb = eb.build();
-
- Objects.requireNonNull(event.getGuild().getTextChannelById(registeredChannelId)).sendMessageEmbeds(mb).queue();
+ Either response = AuditLogClient.getRegisteredGuild(event.getGuild().getId());
+ response.peek(success -> {
+
+ String registeredChannelId = success.channelId();
+
+ Guild guild = event.getGuild();
+ User user = event.getUser();
+ Member member = event.getMember();
+
+ String memberJoinDate = "Member Not Cached";
+ boolean memberJoinDateTrustable = false;
+ if(member!=null){
+ memberJoinDate = "";
+ memberJoinDateTrustable = member.hasTimeJoined();
+ }
+
+ EmbedBuilder eb = new EmbedBuilder();
+ eb.setTitle("đĢ Member Leave Event");
+ eb.setDescription("A Member has left "+guild.getName());
+ eb.setColor(Color.RED);
+
+ eb.addField("đˇī¸ Member Name", "â°ââ¤"+user.getName(), false);
+ eb.setThumbnail(user.getEffectiveAvatarUrl());
+ eb.addField("đ Member ID", "â°ââ¤"+user.getId(), false);
+ eb.addField("â Member Joined The Server On","â°ââ¤"+memberJoinDate, false);
+ eb.addField("â Member Join Date Accurate?", memberJoinDateTrustable ? "â
" : "â" , false);
+
+ eb.setFooter("Join timestamp may fall back to guild creation time if not provided by Discord during lazy loading of members. " +
+ "Accuracy of the timestamp can be determined by the extra field provided.");
+ eb.setTimestamp(Instant.now());
+
+ MessageEmbed mb = eb.build();
+
+ Objects.requireNonNull(event.getGuild().getTextChannelById(registeredChannelId)).sendMessageEmbeds(mb).queue();
+ });
+
});
}
diff --git a/src/main/java/org/papertrail/listeners/voicelisteners/GuildVoiceListener.java b/src/main/java/org/papertrail/listeners/voicelisteners/GuildVoiceListener.java
index 8c31f85b..e9ee04d3 100644
--- a/src/main/java/org/papertrail/listeners/voicelisteners/GuildVoiceListener.java
+++ b/src/main/java/org/papertrail/listeners/voicelisteners/GuildVoiceListener.java
@@ -5,6 +5,7 @@
import java.util.Objects;
import java.util.concurrent.Executor;
+import io.vavr.control.Either;
import org.jetbrains.annotations.NotNull;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.entities.Member;
@@ -13,9 +14,8 @@
import net.dv8tion.jda.api.events.guild.voice.GuildVoiceUpdateEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import org.papertrail.sdk.client.AuditLogClient;
-import org.papertrail.sdk.http.HttpServiceResponse;
-import org.papertrail.sdk.model.AuditLogResponse;
-import org.papertrail.sdk.model.ErrorResponse;
+import org.papertrail.sdk.model.AuditLogObject;
+import org.papertrail.sdk.model.ErrorObject;
public class GuildVoiceListener extends ListenerAdapter {
@@ -32,47 +32,48 @@ public void onGuildVoiceUpdate(@NotNull GuildVoiceUpdateEvent event) {
// guild voice events are mapped to audit log table
// Call the API and see if the event came from a registered Guild
- HttpServiceResponse guildCheck = AuditLogClient.getRegisteredGuild(event.getGuild().getId());
-
- if(!guildCheck.requestSuccess()){
- return ;
- }
- String registeredChannelId = guildCheck.success().channelId();
-
- EmbedBuilder eb = new EmbedBuilder();
- eb.setTitle("đ Voice Activity Log");
-
- Member member = event.getMember();
- AudioChannel left = event.getOldValue(); // can be null if user joined for first time
- AudioChannel joined = event.getNewValue(); // can be null if user left
-
- if(left==null && joined!=null) {
- // User has joined a vc
- eb.setDescription("A Member has joined a voice channel");
- eb.setColor(Color.GREEN);
- eb.addField("â
Member Joined", "â°ââ¤"+member.getAsMention()+" joined the voice channel "+joined.getAsMention(), false);
- }
-
- if (left != null && joined != null) {
- // Moved from one channel to another
- eb.setDescription("A Member has switched voice channels");
- eb.setColor(Color.YELLOW);
- eb.addField("đ Member Switched Channels", "â°ââ¤"+member.getAsMention()+" joined the switched from channel "+left.getAsMention()+ " to "+joined.getAsMention(), false);
- }
-
- if (left!=null && joined==null) {
- // User disconnected voluntarily (or was disconnected by a moderator)
- eb.setDescription("A Member has left a voice channel");
- eb.setColor(Color.RED);
- eb.addField("â Member Left A Voice Channel", "â°ââ¤"+member.getAsMention()+" left the voice channel "+left.getAsMention(), false);
- }
-
- eb.setFooter("Voice Activity Detection");
- eb.setTimestamp(Instant.now());
-
- MessageEmbed mb = eb.build();
-
- Objects.requireNonNull(event.getGuild().getTextChannelById(registeredChannelId)).sendMessageEmbeds(mb).queue();
+ Either response = AuditLogClient.getRegisteredGuild(event.getGuild().getId());
+
+ response.peek(success -> {
+
+ String registeredChannelId = success.channelId();
+
+ EmbedBuilder eb = new EmbedBuilder();
+ eb.setTitle("đ Voice Activity Log");
+
+ Member member = event.getMember();
+ AudioChannel left = event.getOldValue(); // can be null if user joined for first time
+ AudioChannel joined = event.getNewValue(); // can be null if user left
+
+ if(left==null && joined!=null) {
+ // User has joined a vc
+ eb.setDescription("A Member has joined a voice channel");
+ eb.setColor(Color.GREEN);
+ eb.addField("â
Member Joined", "â°ââ¤"+member.getAsMention()+" joined the voice channel "+joined.getAsMention(), false);
+ }
+
+ if (left != null && joined != null) {
+ // Moved from one channel to another
+ eb.setDescription("A Member has switched voice channels");
+ eb.setColor(Color.YELLOW);
+ eb.addField("đ Member Switched Channels", "â°ââ¤"+member.getAsMention()+" joined the switched from channel "+left.getAsMention()+ " to "+joined.getAsMention(), false);
+ }
+
+ if (left!=null && joined==null) {
+ // User disconnected voluntarily (or was disconnected by a moderator)
+ eb.setDescription("A Member has left a voice channel");
+ eb.setColor(Color.RED);
+ eb.addField("â Member Left A Voice Channel", "â°ââ¤"+member.getAsMention()+" left the voice channel "+left.getAsMention(), false);
+ }
+
+ eb.setFooter("Voice Activity Detection");
+ eb.setTimestamp(Instant.now());
+
+ MessageEmbed mb = eb.build();
+
+ Objects.requireNonNull(event.getGuild().getTextChannelById(registeredChannelId)).sendMessageEmbeds(mb).queue();
+ });
+
});
}
}
diff --git a/src/main/java/org/papertrail/main/FireRun.java b/src/main/java/org/papertrail/main/FireRun.java
index 54ab73b3..28bf507f 100644
--- a/src/main/java/org/papertrail/main/FireRun.java
+++ b/src/main/java/org/papertrail/main/FireRun.java
@@ -65,11 +65,8 @@ public static void main(String[] args) throws IOException {
manager.addEventListener(new BotInfoCommandListener());
manager.addEventListener(new BotSetupCommandListener());
manager.addEventListener(new RequiredPermissionCheckCommandListener());
-
- /*
- * This is required only to set up a cron-job to periodically ping this end-point so that
- * hosting services that spin down after inactivity don't do that anymore
- */
+
+ // Custom health check endpoint
HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0);
server.createContext("/ping", new PingHandler());
server.setExecutor(null); // creates a default executor
diff --git a/src/main/java/org/papertrail/sdk/client/AuditLogClient.java b/src/main/java/org/papertrail/sdk/client/AuditLogClient.java
index 6ad91257..1b168ce1 100644
--- a/src/main/java/org/papertrail/sdk/client/AuditLogClient.java
+++ b/src/main/java/org/papertrail/sdk/client/AuditLogClient.java
@@ -1,67 +1,72 @@
package org.papertrail.sdk.client;
-import kong.unirest.core.HttpMethod;
+import io.vavr.control.Either;
+import org.jetbrains.annotations.NotNull;
import org.papertrail.sdk.http.HttpServiceEngine;
-import org.papertrail.sdk.http.HttpServiceResponse;
-import org.papertrail.sdk.model.ErrorResponse;
-import org.papertrail.sdk.model.AuditLogResponse;
+import org.papertrail.sdk.model.AuditLogObject;
+import org.papertrail.sdk.model.ErrorObject;
import org.papertrail.utilities.EnvConfig;
-import java.util.Map;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+
+import java.util.List;
public class AuditLogClient {
- private AuditLogClient(){
- throw new IllegalStateException("Utility Class");
+ private static final String BASE_URL = EnvConfig.get("API_URL");
+ private static final HttpHeaders httpHeaders = new HttpHeaders();
+ private static final HttpServiceEngine engine = HttpServiceEngine.getInstance();
+
+ static {
+ httpHeaders.put("Content-Type", List.of("application/json"));
}
- private static final String BASE_URL = EnvConfig.get("API_URL");
- private static final Map CONTENT_HEADER = Map.of("Content-Type", "application/json");
+ private AuditLogClient() {
+ throw new IllegalStateException("Client class");
+ }
- public static HttpServiceResponse registerGuild(String guildId, String channelId){
+ @NotNull
+ public static Either registerGuild(String guildId, String channelId){
- return HttpServiceEngine.makeRequest(
+ return engine.makeRequestWithBody(
HttpMethod.POST,
BASE_URL +"api/v1/log/audit",
- CONTENT_HEADER,
- new AuditLogResponse(guildId, channelId),
- AuditLogResponse.class,
- ErrorResponse.class
+ httpHeaders,
+ new AuditLogObject(guildId, channelId),
+ AuditLogObject.class
);
}
- public static HttpServiceResponse getRegisteredGuild(String guildId){
+ @NotNull
+ public static Either getRegisteredGuild(String guildId){
- return HttpServiceEngine.makeRequest(
+ return engine.makeRequest(
HttpMethod.GET,
BASE_URL +"api/v1/log/audit/"+guildId,
- CONTENT_HEADER,
- null,
- AuditLogResponse.class,
- ErrorResponse.class
+ httpHeaders,
+ AuditLogObject.class
);
}
- public static HttpServiceResponse updateRegisteredGuild(String guildId, String channelId){
+ @NotNull
+ public static Either updateRegisteredGuild(String guildId, String channelId){
- return HttpServiceEngine.makeRequest(
+ return engine.makeRequestWithBody(
HttpMethod.PUT,
BASE_URL +"api/v1/log/audit",
- CONTENT_HEADER,
- new AuditLogResponse(guildId, channelId),
- AuditLogResponse.class,
- ErrorResponse.class
+ httpHeaders,
+ new AuditLogObject(guildId, channelId),
+ AuditLogObject.class
);
}
- public static HttpServiceResponse deleteRegisteredGuild(String guildId){
+ public static Either deleteRegisteredGuild(String guildId){
- return HttpServiceEngine.makeRequest(
+ return engine.makeRequest(
HttpMethod.DELETE,
BASE_URL +"api/v1/log/audit/"+guildId,
- CONTENT_HEADER,
- null,
- Void.class,
- ErrorResponse.class
+ httpHeaders,
+ Void.class
);
}
}
diff --git a/src/main/java/org/papertrail/sdk/client/MessageContentLogClient.java b/src/main/java/org/papertrail/sdk/client/MessageContentLogClient.java
index d8ac1aa4..4f609f15 100644
--- a/src/main/java/org/papertrail/sdk/client/MessageContentLogClient.java
+++ b/src/main/java/org/papertrail/sdk/client/MessageContentLogClient.java
@@ -1,69 +1,74 @@
package org.papertrail.sdk.client;
-import kong.unirest.core.HttpMethod;
+import io.vavr.control.Either;
+import org.jetbrains.annotations.NotNull;
import org.papertrail.sdk.http.HttpServiceEngine;
-import org.papertrail.sdk.http.HttpServiceResponse;
-import org.papertrail.sdk.model.ErrorResponse;
-import org.papertrail.sdk.model.MessageContentResponse;
+import org.papertrail.sdk.model.ErrorObject;
+import org.papertrail.sdk.model.MessageContentObject;
import org.papertrail.utilities.EnvConfig;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
-import java.util.Map;
+import java.util.List;
public class MessageContentLogClient {
- private MessageContentLogClient(){
- throw new IllegalStateException("Utility Class");
+ private static final String BASE_URL = EnvConfig.get("API_URL")+"api/v1/content/message";
+ private static final HttpHeaders httpHeaders = new HttpHeaders();
+ private static final HttpServiceEngine engine = HttpServiceEngine.getInstance();
+
+ static {
+ httpHeaders.put("Content-Type", List.of("application/json"));
}
- private static final String BASE_URL = EnvConfig.get("API_URL")+"api/v1/content/message";
- private static final Map CONTENT_HEADER = Map.of("Content-Type", "application/json");
+ private MessageContentLogClient() {
+ throw new IllegalStateException("Client class");
+ }
- public static HttpServiceResponse logMessage(String messageId, String messageContent, String authorId){
+ @NotNull
+ public static Either logMessage(String messageId, String messageContent, String authorId){
- return HttpServiceEngine.makeRequest(
+ return engine.makeRequestWithBody(
HttpMethod.POST,
BASE_URL,
- CONTENT_HEADER,
- new MessageContentResponse(messageId, messageContent, authorId),
- MessageContentResponse.class,
- ErrorResponse.class
+ httpHeaders,
+ new MessageContentObject(messageId, messageContent, authorId),
+ MessageContentObject.class
);
}
- public static HttpServiceResponse retrieveMessage(String messageId){
+ @NotNull
+ public static Either retrieveMessage(String messageId){
- return HttpServiceEngine.makeRequest(
+ return engine.makeRequest(
HttpMethod.GET,
BASE_URL+"/"+messageId,
- CONTENT_HEADER,
- null,
- MessageContentResponse.class,
- ErrorResponse.class
+ httpHeaders,
+ MessageContentObject.class
);
}
- public static HttpServiceResponse updateMessage(String messageId, String messageContent, String authorId){
+ @NotNull
+ public static Either updateMessage(String messageId, String messageContent, String authorId){
- return HttpServiceEngine.makeRequest(
+ return engine.makeRequestWithBody(
HttpMethod.PUT,
BASE_URL,
- CONTENT_HEADER,
- new MessageContentResponse(messageId, messageContent, authorId),
- MessageContentResponse.class,
- ErrorResponse.class
+ httpHeaders,
+ new MessageContentObject(messageId, messageContent, authorId),
+ MessageContentObject.class
);
}
- public static HttpServiceResponse deleteMessage(String messageId) {
+ @NotNull
+ public static Either deleteMessage(String messageId) {
- return HttpServiceEngine.makeRequest(
+ return engine.makeRequest(
HttpMethod.DELETE,
BASE_URL+"/"+messageId,
- CONTENT_HEADER,
- null,
- Void.class,
- ErrorResponse.class
+ httpHeaders,
+ Void.class
);
}
diff --git a/src/main/java/org/papertrail/sdk/client/MessageLogClient.java b/src/main/java/org/papertrail/sdk/client/MessageLogClient.java
index 5ec4750b..0e95224b 100644
--- a/src/main/java/org/papertrail/sdk/client/MessageLogClient.java
+++ b/src/main/java/org/papertrail/sdk/client/MessageLogClient.java
@@ -1,69 +1,72 @@
package org.papertrail.sdk.client;
-import kong.unirest.core.HttpMethod;
+import io.vavr.control.Either;
+import org.jetbrains.annotations.NotNull;
import org.papertrail.sdk.http.HttpServiceEngine;
-import org.papertrail.sdk.http.HttpServiceResponse;
-import org.papertrail.sdk.model.ErrorResponse;
-import org.papertrail.sdk.model.MessageLogResponse;
+import org.papertrail.sdk.model.ErrorObject;
+import org.papertrail.sdk.model.MessageLogObject;
import org.papertrail.utilities.EnvConfig;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+
+import java.util.List;
-import java.util.Map;
public class MessageLogClient {
- private MessageLogClient(){
- throw new IllegalStateException("Utility Class");
+ private static final String BASE_URL = EnvConfig.get("API_URL");
+ private static final HttpHeaders httpHeaders = new HttpHeaders();
+ private static final HttpServiceEngine engine = HttpServiceEngine.getInstance();
+
+ static {
+ httpHeaders.put("Content-Type", List.of("application/json"));
}
- private static final String BASE_URL = EnvConfig.get("API_URL");
- private static final Map CONTENT_HEADER = Map.of("Content-Type", "application/json");
+ private MessageLogClient(){
+ throw new IllegalStateException("Client class");
+ }
- public static HttpServiceResponse registerGuild(String guildId, String channelId){
+ @NotNull
+ public static Either registerGuild(String guildId, String channelId){
- return HttpServiceEngine.makeRequest(
+ return engine.makeRequestWithBody(
HttpMethod.POST,
BASE_URL +"api/v1/log/message",
- CONTENT_HEADER,
- new MessageLogResponse(guildId, channelId),
- MessageLogResponse.class,
- ErrorResponse.class
+ httpHeaders,
+ new MessageLogObject(guildId, channelId),
+ MessageLogObject.class
);
}
- public static HttpServiceResponse getRegisteredGuild(String guildId){
+ public static Either getRegisteredGuild(String guildId){
- return HttpServiceEngine.makeRequest(
+ return engine.makeRequest(
HttpMethod.GET,
BASE_URL +"api/v1/log/message/"+guildId,
- CONTENT_HEADER,
- null,
- MessageLogResponse.class,
- ErrorResponse.class
+ httpHeaders,
+ MessageLogObject.class
);
}
- public static HttpServiceResponse updateRegisteredGuild(String guildId, String channelId){
+ public static Either updateRegisteredGuild(String guildId, String channelId){
- return HttpServiceEngine.makeRequest(
+ return HttpServiceEngine.getInstance().makeRequestWithBody(
HttpMethod.PUT,
- BASE_URL +"api/v1/log/message",
- CONTENT_HEADER,
- new MessageLogResponse(guildId, channelId),
- MessageLogResponse.class,
- ErrorResponse.class
+ BASE_URL + "api/v1/log/message",
+ httpHeaders,
+ new MessageLogObject(guildId, channelId),
+ MessageLogObject.class
);
}
- public static HttpServiceResponse deleteRegisteredGuild(String guildId){
+ public static Either deleteRegisteredGuild(String guildId){
- return HttpServiceEngine.makeRequest(
+ return engine.makeRequest(
HttpMethod.DELETE,
BASE_URL +"api/v1/log/message/"+guildId,
- CONTENT_HEADER,
- null,
- Void.class,
- ErrorResponse.class
+ httpHeaders,
+ Void.class
);
}
}
diff --git a/src/main/java/org/papertrail/sdk/http/HttpServiceEngine.java b/src/main/java/org/papertrail/sdk/http/HttpServiceEngine.java
index 110efa94..69dcdfb8 100644
--- a/src/main/java/org/papertrail/sdk/http/HttpServiceEngine.java
+++ b/src/main/java/org/papertrail/sdk/http/HttpServiceEngine.java
@@ -1,47 +1,92 @@
package org.papertrail.sdk.http;
-import com.google.gson.Gson;
-import kong.unirest.core.HttpMethod;
-import kong.unirest.core.HttpRequestWithBody;
-import kong.unirest.core.HttpResponse;
-import kong.unirest.core.Unirest;
+import io.vavr.control.Either;
import org.jetbrains.annotations.NotNull;
+import org.papertrail.sdk.model.ErrorObject;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.web.client.HttpClientErrorException;
+import org.springframework.web.client.HttpServerErrorException;
+import org.springframework.web.client.ResourceAccessException;
+import org.springframework.web.client.RestClient;
+import org.tinylog.Logger;
-import java.util.Map;
+import java.net.URI;
+import java.time.Instant;
public class HttpServiceEngine {
+ private final RestClient client;
+ private static final HttpServiceEngine INSTANCE = new HttpServiceEngine();
+
private HttpServiceEngine() {
- throw new IllegalStateException("Utility Class");
+ client = RestClient.builder().build();
+ }
+
+ public static HttpServiceEngine getInstance() {
+ return INSTANCE;
}
- public static HttpServiceResponse makeRequest (
+ public Either makeRequest (
@NotNull HttpMethod httpMethod,
- @NotNull String url, Map headerMap,
- Object requestBody,
- @NotNull Class successResponseClass,
- @NotNull Class errorResponseClass) {
-
- HttpRequestWithBody request = Unirest
- .request(httpMethod.toString(), url)
- .headers(headerMap);
-
- Gson gson = new Gson();
- HttpResponse response;
- if (requestBody != null) {
- String jsonBody = gson.toJson(requestBody);
- response = request.body(jsonBody).asString();
- } else {
- response = request.asString();
+ @NotNull String url,
+ @NotNull HttpHeaders headers,
+ @NotNull Class successResponseClass) {
+
+ try {
+ S body = client.method(httpMethod)
+ .uri(URI.create(url))
+ .headers(h-> h.addAll(headers))
+ .retrieve()
+ .toEntity(successResponseClass)
+ .getBody();
+
+ return Either.right(body);
+ } catch (HttpClientErrorException e) {
+ Logger.trace("Client error when calling {} {}: {}", httpMethod, url, e.getMessage(), e);
+ ErrorObject error = e.getResponseBodyAs(ErrorObject.class);
+ return Either.left(error);
+ } catch (HttpServerErrorException e) {
+ Logger.error("Server error when calling {} {}: {}", httpMethod, url, e.getMessage(), e);
+ ErrorObject error = e.getResponseBodyAs(ErrorObject.class);
+ return Either.left(error);
+ } catch (ResourceAccessException e) {
+ Logger.error("Resource access error when calling {} {}: {}", httpMethod, url, e.getMessage(), e);
+ ErrorObject error = new ErrorObject(503, "API Unreachable", e.getMessage(), Instant.now().toString(), url);
+ return Either.left(error);
}
+ }
+
+ public Either makeRequestWithBody (
+ @NotNull HttpMethod httpMethod,
+ @NotNull String url,
+ @NotNull HttpHeaders headers,
+ @NotNull Object requestBody,
+ @NotNull Class successResponseClass) {
+
+ try {
+ S body = client.method(httpMethod)
+ .uri(URI.create(url))
+ .headers(h-> h.addAll(headers))
+ .body(requestBody)
+ .retrieve()
+ .toEntity(successResponseClass)
+ .getBody();
- if(response.isSuccess()) {
- S success = gson.fromJson(response.getBody(), successResponseClass);
- return new HttpServiceResponse<>(success, null, true);
+ return Either.right(body);
- } else {
- E error = gson.fromJson(response.getBody(), errorResponseClass);
- return new HttpServiceResponse<>(null, error, false);
+ } catch (HttpClientErrorException e) {
+ Logger.trace("Client error when calling {} {}: {}", httpMethod, url, e.getMessage(), e);
+ ErrorObject error = e.getResponseBodyAs(ErrorObject.class);
+ return Either.left(error);
+ } catch (HttpServerErrorException e) {
+ Logger.error("Server error when calling {} {}: {}", httpMethod, url, e.getMessage(), e);
+ ErrorObject error = e.getResponseBodyAs(ErrorObject.class);
+ return Either.left(error);
+ } catch (ResourceAccessException e) {
+ Logger.error("Resource access error when calling {} {}: {}", httpMethod, url, e.getMessage(), e);
+ ErrorObject error = new ErrorObject(503, "API Unreachable", e.getMessage(), Instant.now().toString(), url);
+ return Either.left(error);
}
}
}
diff --git a/src/main/java/org/papertrail/sdk/http/HttpServiceResponse.java b/src/main/java/org/papertrail/sdk/http/HttpServiceResponse.java
deleted file mode 100644
index af5ef724..00000000
--- a/src/main/java/org/papertrail/sdk/http/HttpServiceResponse.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package org.papertrail.sdk.http;
-
-import org.jspecify.annotations.Nullable;
-
-public record HttpServiceResponse(@Nullable S success, @Nullable E error, boolean requestSuccess) {
-
-}
diff --git a/src/main/java/org/papertrail/sdk/model/AuditLogObject.java b/src/main/java/org/papertrail/sdk/model/AuditLogObject.java
new file mode 100644
index 00000000..8c4df960
--- /dev/null
+++ b/src/main/java/org/papertrail/sdk/model/AuditLogObject.java
@@ -0,0 +1,5 @@
+package org.papertrail.sdk.model;
+
+public record AuditLogObject(String guildId, String channelId) {
+
+}
diff --git a/src/main/java/org/papertrail/sdk/model/AuditLogResponse.java b/src/main/java/org/papertrail/sdk/model/AuditLogResponse.java
deleted file mode 100644
index 1e421975..00000000
--- a/src/main/java/org/papertrail/sdk/model/AuditLogResponse.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package org.papertrail.sdk.model;
-
-public record AuditLogResponse(String guildId, String channelId) {
-
-}
diff --git a/src/main/java/org/papertrail/sdk/model/ErrorResponse.java b/src/main/java/org/papertrail/sdk/model/ErrorObject.java
similarity index 83%
rename from src/main/java/org/papertrail/sdk/model/ErrorResponse.java
rename to src/main/java/org/papertrail/sdk/model/ErrorObject.java
index 41ce3abe..a0ca5257 100644
--- a/src/main/java/org/papertrail/sdk/model/ErrorResponse.java
+++ b/src/main/java/org/papertrail/sdk/model/ErrorObject.java
@@ -1,6 +1,6 @@
package org.papertrail.sdk.model;
-public record ErrorResponse(
+public record ErrorObject(
int status,
String error,
String message,
diff --git a/src/main/java/org/papertrail/sdk/model/MessageContentObject.java b/src/main/java/org/papertrail/sdk/model/MessageContentObject.java
new file mode 100644
index 00000000..2d1cc70b
--- /dev/null
+++ b/src/main/java/org/papertrail/sdk/model/MessageContentObject.java
@@ -0,0 +1,4 @@
+package org.papertrail.sdk.model;
+
+public record MessageContentObject(String messageId, String messageContent, String authorId) {
+}
diff --git a/src/main/java/org/papertrail/sdk/model/MessageContentResponse.java b/src/main/java/org/papertrail/sdk/model/MessageContentResponse.java
deleted file mode 100644
index 478f1161..00000000
--- a/src/main/java/org/papertrail/sdk/model/MessageContentResponse.java
+++ /dev/null
@@ -1,4 +0,0 @@
-package org.papertrail.sdk.model;
-
-public record MessageContentResponse(String messageId, String messageContent, String authorId) {
-}
diff --git a/src/main/java/org/papertrail/sdk/model/MessageLogObject.java b/src/main/java/org/papertrail/sdk/model/MessageLogObject.java
new file mode 100644
index 00000000..f07c8a11
--- /dev/null
+++ b/src/main/java/org/papertrail/sdk/model/MessageLogObject.java
@@ -0,0 +1,5 @@
+package org.papertrail.sdk.model;
+
+public record MessageLogObject(String guildId, String channelId) {
+
+}
diff --git a/src/main/java/org/papertrail/sdk/model/MessageLogResponse.java b/src/main/java/org/papertrail/sdk/model/MessageLogResponse.java
deleted file mode 100644
index 2d1b9b53..00000000
--- a/src/main/java/org/papertrail/sdk/model/MessageLogResponse.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package org.papertrail.sdk.model;
-
-public record MessageLogResponse(String guildId, String channelId) {
-
-}
diff --git a/src/main/java/org/papertrail/version/ProjectInfo.java b/src/main/java/org/papertrail/version/ProjectInfo.java
index 36076784..b5bc3e21 100644
--- a/src/main/java/org/papertrail/version/ProjectInfo.java
+++ b/src/main/java/org/papertrail/version/ProjectInfo.java
@@ -7,7 +7,7 @@ private ProjectInfo() {
}
public static final String APPNAME = "PaperTrail";
- public static final String VERSION = "v2.0.0-beta";
+ public static final String VERSION = "v2.0.0";
public static final String PROJECT_LINK = "https://github.com/Egg-03/PaperTrailBot";
public static final String PROJECT_ISSUE_LINK="https://github.com/Egg-03/PaperTrailBot/issues";