From 53bd30bd20c2f8b9fbaccf7614b936619f262e1e Mon Sep 17 00:00:00 2001 From: Egg-03 <111327101+Egg-03@users.noreply.github.com> Date: Thu, 19 Jun 2025 13:51:41 +0530 Subject: [PATCH 1/9] Add message logging feature with commands and listeners Introduces message logging functionality, including new slash commands for setting, viewing, and removing message log channels. Adds MessageLogListener to track and log message edits and deletions, storing message content and author in the database. Refactors database connector to support message log operations and updates command names for audit log management. Updates command registration and integrates new listeners in the main application. --- .../database/DatabaseConnector.java | 87 ++++++++- .../org/papertrail/database/TableNames.java | 3 + .../guildlisteners/ServerBoostListener.java | 2 +- .../loglisteners/AuditLogListener.java | 2 +- .../loglisteners/LogCommandListener.java | 14 +- .../GuildMemberJoinAndLeaveListener.java | 4 +- .../MessageLogCommandListener.java | 183 ++++++++++++++++++ .../messagelisteners/MessageLogListener.java | 132 +++++++++++++ .../messagelisteners/package-info.java | 4 + .../voicelisteners/GuildVoiceListener.java | 2 +- .../java/org/papertrail/main/FireRun.java | 4 + .../main/SlashCommandRegistrar.java | 24 ++- src/main/resources/tinylog.properties | 2 +- 13 files changed, 444 insertions(+), 19 deletions(-) create mode 100644 src/main/java/org/papertrail/listeners/messagelisteners/MessageLogCommandListener.java create mode 100644 src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java create mode 100644 src/main/java/org/papertrail/listeners/messagelisteners/package-info.java diff --git a/src/main/java/org/papertrail/database/DatabaseConnector.java b/src/main/java/org/papertrail/database/DatabaseConnector.java index a6e52f2b..6c5ff24b 100644 --- a/src/main/java/org/papertrail/database/DatabaseConnector.java +++ b/src/main/java/org/papertrail/database/DatabaseConnector.java @@ -5,6 +5,8 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.Collections; +import java.util.List; import org.papertrail.utilities.EnvConfig; import org.tinylog.Logger; @@ -31,9 +33,9 @@ public void registerGuildAndChannel(String guildId, String channelId, String tab } - public String retrieveChannelId(String guildId, String tableName) { + public String retrieveRegisteredChannelId(String guildId, String tableName) { - String sqlStatement = "SELECT (channel_id) FROM " + tableName + " WHERE guild_id = ?"; + String sqlStatement = "SELECT channel_id FROM " + tableName + " WHERE guild_id = ?"; String channelId = ""; try (PreparedStatement psmt = connect.prepareStatement(sqlStatement)) { @@ -56,6 +58,29 @@ public String retrieveChannelId(String guildId, String tableName) { } } + public String retrieveRegisteredGuildId(String guildId, String tableName) { + + String sqlStatement = "SELECT guild_id FROM " + tableName + " WHERE guild_id = ?"; + + try (PreparedStatement psmt = connect.prepareStatement(sqlStatement)) { + psmt.setString(1, guildId); + + try (ResultSet rs = psmt.executeQuery()) { + if (!rs.isBeforeFirst()) { + return null; + } else { + while (rs.next()) { + return rs.getString("guild_id"); + } + } + } + return null; + } catch (SQLException e) { + Logger.error("Could not retrieve registered guild channel id", e); + return null; + } + } + public void unregisterGuildAndChannel(String guildId, String tableName) throws SQLException { String sqlStatement = "DELETE FROM "+tableName+" WHERE guild_id = ?"; @@ -65,5 +90,63 @@ public void unregisterGuildAndChannel(String guildId, String tableName) throws S psmt.executeUpdate(); } } + + public void logMessage(String messageId, String messageContent, String authorId, String tableName) throws SQLException { + + String sqlStatement = "INSERT INTO "+tableName+" (message_id, message_content, author_id) VALUES (?, ?, ?)"; + + try(PreparedStatement psmt = connect.prepareStatement(sqlStatement)){ + psmt.setString(1, messageId); + psmt.setString(2, messageContent); + psmt.setString(3, authorId); + psmt.executeUpdate(); + } + } + + public List retrieveAuthorAndMessage(String messageId, String tableName) { + + String sqlStatement = "SELECT author_id, message_content FROM " + tableName + " WHERE message_id = ?"; + + String messageContent = ""; + String authorId = ""; + + try (PreparedStatement psmt = connect.prepareStatement(sqlStatement)) { + psmt.setString(1, messageId); + + try (ResultSet rs = psmt.executeQuery()) { + if (rs.next()) { // only one message is logged per row per message id + messageContent = rs.getString("message_content"); + authorId = rs.getString("author_id"); + return List.of(authorId, messageContent); + } + } + return Collections.emptyList(); + } catch (SQLException e) { + Logger.error("Could not retrieve message", e); + e.printStackTrace(); + return Collections.emptyList(); + } + } + + public void updateMessage(String messageId, String messageContent, String tableName) throws SQLException { + + String sqlStatement = "UPDATE " + tableName + " SET message_content = ? WHERE message_id = ?"; + + try(PreparedStatement psmt = connect.prepareStatement(sqlStatement)){ + psmt.setString(1, messageContent); + psmt.setString(2, messageId); + psmt.executeUpdate(); + } + } + + public void deleteMessage(String messageId, String tableName) throws SQLException { + + String sqlStatement = "DELETE FROM "+tableName+" WHERE message_id = ?"; + + try(PreparedStatement psmt = connect.prepareStatement(sqlStatement)){ + psmt.setString(1, messageId); + psmt.executeUpdate(); + } + } } diff --git a/src/main/java/org/papertrail/database/TableNames.java b/src/main/java/org/papertrail/database/TableNames.java index 2a8af971..6bc3e047 100644 --- a/src/main/java/org/papertrail/database/TableNames.java +++ b/src/main/java/org/papertrail/database/TableNames.java @@ -5,5 +5,8 @@ public class TableNames { private TableNames() { throw new IllegalStateException("Utility Class"); } + public static final String AUDIT_LOG_TABLE = "audit_log_table"; + public static final String MESSAGE_LOG_REGISTRATION_TABLE = "message_log_registration_table"; + public static final String MESSAGE_LOG_CONTENT_TABLE = "message_log_content_table"; } diff --git a/src/main/java/org/papertrail/listeners/guildlisteners/ServerBoostListener.java b/src/main/java/org/papertrail/listeners/guildlisteners/ServerBoostListener.java index 12297b6c..c8a5d602 100644 --- a/src/main/java/org/papertrail/listeners/guildlisteners/ServerBoostListener.java +++ b/src/main/java/org/papertrail/listeners/guildlisteners/ServerBoostListener.java @@ -26,7 +26,7 @@ public ServerBoostListener(DatabaseConnector dc) { public void onGuildMemberUpdateBoostTime(GuildMemberUpdateBoostTimeEvent event) { // this will return a non-null text id if a channel was previously registered in the database - String registeredChannelId=dc.retrieveChannelId(event.getGuild().getId(), TableNames.AUDIT_LOG_TABLE); + String registeredChannelId=dc.retrieveRegisteredChannelId(event.getGuild().getId(), TableNames.AUDIT_LOG_TABLE); if(registeredChannelId==null ||registeredChannelId.isBlank()) { return; diff --git a/src/main/java/org/papertrail/listeners/loglisteners/AuditLogListener.java b/src/main/java/org/papertrail/listeners/loglisteners/AuditLogListener.java index 0458452b..6c02a65b 100644 --- a/src/main/java/org/papertrail/listeners/loglisteners/AuditLogListener.java +++ b/src/main/java/org/papertrail/listeners/loglisteners/AuditLogListener.java @@ -45,7 +45,7 @@ public AuditLogListener(DatabaseConnector dc) { public void onGuildAuditLogEntryCreate(GuildAuditLogEntryCreateEvent event) { // this will return a non-null text id if a channel was previously registered in the database - String registeredChannelId=dc.retrieveChannelId(event.getGuild().getId(), TableNames.AUDIT_LOG_TABLE); + String registeredChannelId=dc.retrieveRegisteredChannelId(event.getGuild().getId(), TableNames.AUDIT_LOG_TABLE); if(registeredChannelId==null ||registeredChannelId.isBlank()) { return; diff --git a/src/main/java/org/papertrail/listeners/loglisteners/LogCommandListener.java b/src/main/java/org/papertrail/listeners/loglisteners/LogCommandListener.java index bbbf5651..5867e55f 100644 --- a/src/main/java/org/papertrail/listeners/loglisteners/LogCommandListener.java +++ b/src/main/java/org/papertrail/listeners/loglisteners/LogCommandListener.java @@ -30,7 +30,7 @@ public LogCommandListener(DatabaseConnector dc) { public void onSlashCommandInteraction(SlashCommandInteractionEvent event) { // Command for binding the listener to a channel - if (event.getName().equals("ralc")) { + if (event.getName().equals("auditlogchannel-set")) { // Only members with MANAGE_SERVER permissions should be able to use this command Member member = event.getMember(); @@ -44,7 +44,7 @@ public void onSlashCommandInteraction(SlashCommandInteractionEvent event) { String guildId = event.getGuild().getId(); // retrieve the previously registered channel_id associated with the given // guild_id - String registeredChannelId = dc.retrieveChannelId(guildId, TableNames.AUDIT_LOG_TABLE); + String registeredChannelId = dc.retrieveRegisteredChannelId(guildId, TableNames.AUDIT_LOG_TABLE); // if there is a registered channel_id in the database, send a warning message // in the channel where the command was called from, stating that a channel has @@ -92,7 +92,7 @@ public void onSlashCommandInteraction(SlashCommandInteractionEvent event) { } // Command for getting the channel where audit logs are posted - if (event.getName().equals("galc")) { + if (event.getName().equals("auditlogchannel-view")) { // Only members with MANAGE_SERVER permissions should be able to use this command Member member = event.getMember(); @@ -106,7 +106,7 @@ public void onSlashCommandInteraction(SlashCommandInteractionEvent event) { String guildId = event.getGuild().getId(); // retrieve the channel_id registered in the database - String registeredChannelId = dc.retrieveChannelId(guildId, TableNames.AUDIT_LOG_TABLE); + String registeredChannelId = dc.retrieveRegisteredChannelId(guildId, TableNames.AUDIT_LOG_TABLE); // if there is no channel_id for the given guild_id in the database, then inform // the user of the same, else link the channel that has been registered @@ -122,7 +122,7 @@ public void onSlashCommandInteraction(SlashCommandInteractionEvent event) { // this is particularly useful when a channel that was set for logging may have been deleted GuildChannel registeredChannel = event.getJDA().getGuildChannelById(registeredChannelId); if(registeredChannel==null) { - eb.addField("⚠️ Channel Registration Check", "╰┈➤"+registeredChannelId+" does not exist. Please remove it using `/ualc` and re-register using `/ralc`", false); + eb.addField("⚠️ Channel Registration Check", "╰┈➤"+registeredChannelId+" does not exist. Please remove it using `/auditlogchannel-remove` and re-register using `/auditlogchannel-set`", false); eb.setColor(Color.RED); } else { eb.setColor(Color.CYAN); @@ -137,7 +137,7 @@ public void onSlashCommandInteraction(SlashCommandInteractionEvent event) { } // Command for un-setting a previously bound listener from a channel - if (event.getName().equals("ualc")) { + if (event.getName().equals("auditlogchannel-remove")) { // Only members with MANAGE_SERVER permissions should be able to use this command Member member = event.getMember(); @@ -149,7 +149,7 @@ public void onSlashCommandInteraction(SlashCommandInteractionEvent event) { } String guildId = event.getGuild().getId(); - String registeredChannelId = dc.retrieveChannelId(guildId, TableNames.AUDIT_LOG_TABLE); + String registeredChannelId = dc.retrieveRegisteredChannelId(guildId, TableNames.AUDIT_LOG_TABLE); if (registeredChannelId == null || registeredChannelId.isBlank()) { eb.addField("ℹ️ Channel Removal", "╰┈➤"+"No channel has been registered for audit logs", false); diff --git a/src/main/java/org/papertrail/listeners/memberlisteners/GuildMemberJoinAndLeaveListener.java b/src/main/java/org/papertrail/listeners/memberlisteners/GuildMemberJoinAndLeaveListener.java index 8795b257..9246829a 100644 --- a/src/main/java/org/papertrail/listeners/memberlisteners/GuildMemberJoinAndLeaveListener.java +++ b/src/main/java/org/papertrail/listeners/memberlisteners/GuildMemberJoinAndLeaveListener.java @@ -28,7 +28,7 @@ public void onGuildMemberJoin(GuildMemberJoinEvent event) { // this will return a non-null text id if a channel was previously registered in // the database - String registeredChannelId = dc.retrieveChannelId(event.getGuild().getId(), TableNames.AUDIT_LOG_TABLE); + String registeredChannelId = dc.retrieveRegisteredChannelId(event.getGuild().getId(), TableNames.AUDIT_LOG_TABLE); if (registeredChannelId == null || registeredChannelId.isBlank()) { return; @@ -61,7 +61,7 @@ public void onGuildMemberRemove(GuildMemberRemoveEvent event) { // this will return a non-null text id if a channel was previously registered in // the database - String registeredChannelId = dc.retrieveChannelId(event.getGuild().getId(), TableNames.AUDIT_LOG_TABLE); + String registeredChannelId = dc.retrieveRegisteredChannelId(event.getGuild().getId(), TableNames.AUDIT_LOG_TABLE); if (registeredChannelId == null || registeredChannelId.isBlank()) { return; diff --git a/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogCommandListener.java b/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogCommandListener.java new file mode 100644 index 00000000..619fa413 --- /dev/null +++ b/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogCommandListener.java @@ -0,0 +1,183 @@ +package org.papertrail.listeners.messagelisteners; + +import java.awt.Color; +import java.sql.SQLException; + +import org.papertrail.database.DatabaseConnector; +import org.papertrail.database.TableNames; +import org.tinylog.Logger; + +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; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.hooks.ListenerAdapter; + +public class MessageLogCommandListener extends ListenerAdapter { + + private DatabaseConnector dc; + private final EmbedBuilder eb = new EmbedBuilder(); + + public MessageLogCommandListener(DatabaseConnector dc) { + this.dc = dc; + eb.setTitle("📝 Message Log Configuration"); + eb.setColor(Color.CYAN); + } + + @Override + public void onSlashCommandInteraction(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; + } + + switch(event.getName()) { + + case "messagelogchannel-set": + setMessageLogging(event); + break; + + case "messagelogchannel-view": + retrieveMessageLoggingChannel(event); + break; + + case "messagelogchannel-remove": + unsetMessageLogging(event); + break; + + default: + break; + } + } + + private void setMessageLogging(SlashCommandInteractionEvent event) { + + Guild guild = event.getGuild(); + String guildId = guild.getId(); + + String registeredChannelId = dc.retrieveRegisteredChannelId(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE); + + if(registeredChannelId!=null && !registeredChannelId.isBlank()) { + + GuildChannel registeredChannel = event.getGuild().getGuildChannelById(registeredChannelId); + eb.addField("⚠️ Channel Already Registered", "╰┈➤"+(registeredChannel !=null ? registeredChannel.getAsMention() : registeredChannelId)+ " has already been selected as the message log channel", false); + eb.setColor(Color.YELLOW); + + MessageEmbed mb = eb.build(); + event.replyEmbeds(mb).setEphemeral(false).queue(); + + eb.clearFields(); + return; + } + + String channelIdToRegister = event.getChannelId(); + try { + // register the channel_id along with guild_id in the database + dc.registerGuildAndChannel(guildId, channelIdToRegister, TableNames.MESSAGE_LOG_REGISTRATION_TABLE); + + eb.addField("✅ Channel Registration Success","╰┈➤"+"All edited and deleted messages will be logged here", false); + eb.setColor(Color.GREEN); + MessageEmbed mb = eb.build(); + + event.replyEmbeds(mb).setEphemeral(false).queue(); + + eb.clearFields(); + + } catch (SQLException e) { + + eb.addField("❌ Channel Registration Failure","╰┈➤"+"Channel could not be registered", false); + eb.setColor(Color.BLACK); + MessageEmbed mb = eb.build(); + + event.replyEmbeds(mb).setEphemeral(false).queue(); + + eb.clearFields(); + + Logger.error("Message Log Channel could not be registered", e); + } + + } + + private void retrieveMessageLoggingChannel(SlashCommandInteractionEvent event) { + + Guild guild = event.getGuild(); + String guildId = guild.getId(); + + String registeredChannelId = dc.retrieveRegisteredChannelId(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE); + // if there is no channel_id for the given guild_id in the database, then inform + // the user of the same, else link the channel that has been registered + if (registeredChannelId == null || registeredChannelId.isBlank()) { + eb.addField("⚠️ Channel Registration Check", "╰┈➤"+"No channel has been registered for message logging", false); + eb.setColor(Color.YELLOW); + MessageEmbed mb = eb.build(); + event.replyEmbeds(mb).setEphemeral(false).queue(); + + eb.clearFields(); + } else { + // check if the channelId actually exists in the guild + // this is particularly useful when a channel that was set for logging may have been deleted + GuildChannel registeredChannel = event.getJDA().getGuildChannelById(registeredChannelId); + if(registeredChannel==null) { + eb.addField("⚠️ Channel Registration Check", "╰┈➤"+registeredChannelId+" does not exist. Please remove it using `/messagelogchannel-remove` and re-register using `/messagelogchannel-set`", false); + eb.setColor(Color.RED); + } else { + eb.setColor(Color.CYAN); + eb.addField("✅ Channel Registration Check", "╰┈➤"+registeredChannel.getAsMention()+ " is found to be registered as the message log channel", false); + } + + MessageEmbed mb = eb.build(); + event.replyEmbeds(mb).setEphemeral(false).queue(); + + eb.clearFields(); + } + } + + private void unsetMessageLogging(SlashCommandInteractionEvent event) { + + Guild guild = event.getGuild(); + String guildId = guild.getId(); + + String registeredChannelId = dc.retrieveRegisteredChannelId(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE); + + if (registeredChannelId == null || registeredChannelId.isBlank()) { + eb.addField("ℹ️ Channel Removal", "╰┈➤"+"No channel has been registered for message logs", false); + eb.setColor(Color.YELLOW); + MessageEmbed mb = eb.build(); + + event.replyEmbeds(mb).setEphemeral(false).queue(); + + eb.clearFields(); + + } else { + try { + + dc.unregisterGuildAndChannel(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE); + + eb.addField("✅ Channel Removal", "╰┈➤"+"Channel successfully unset", false); + eb.setColor(Color.GREEN); + MessageEmbed mb = eb.build(); + + event.replyEmbeds(mb).setEphemeral(false).queue(); + + eb.clearFields(); + } catch (SQLException e) { + eb.addField("❌ Channel Removal Failure", "╰┈➤"+"Channel could not be unset", false); + eb.setColor(Color.BLACK); + MessageEmbed mb = eb.build(); + + event.replyEmbeds(mb).setEphemeral(false).queue(); + + eb.clearFields(); + Logger.error("Could not un-register message log channel", e); + } + } + + } + +} diff --git a/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java b/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java new file mode 100644 index 00000000..8660af65 --- /dev/null +++ b/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java @@ -0,0 +1,132 @@ +package org.papertrail.listeners.messagelisteners; + +import java.awt.Color; +import java.sql.SQLException; +import java.util.List; + +import org.papertrail.database.DatabaseConnector; +import org.papertrail.database.TableNames; +import org.tinylog.Logger; + +import net.dv8tion.jda.api.EmbedBuilder; +import net.dv8tion.jda.api.entities.MessageEmbed; +import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.events.message.MessageDeleteEvent; +import net.dv8tion.jda.api.events.message.MessageReceivedEvent; +import net.dv8tion.jda.api.events.message.MessageUpdateEvent; +import net.dv8tion.jda.api.hooks.ListenerAdapter; + +public class MessageLogListener extends ListenerAdapter { + + private DatabaseConnector dc; + private final EmbedBuilder eb = new EmbedBuilder(); + + public MessageLogListener(DatabaseConnector dc) { + this.dc = dc; + eb.setTitle("📝 Message Log Event"); + } + + @Override + public void onMessageReceived(MessageReceivedEvent event) { + + if(event.getAuthor().isBot() || event.getAuthor().isSystem()) { + return; + } + + String guildId = event.getGuild().getId(); + String registeredGuildId = dc.retrieveRegisteredGuildId(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE); + + if(registeredGuildId==null) { + return; + } + + if(registeredGuildId.equals(guildId)) { + try { + String messageId = event.getMessageId(); + dc.logMessage(messageId, event.getMessage().getContentDisplay(), event.getAuthor().getId(), TableNames.MESSAGE_LOG_CONTENT_TABLE); + } catch (SQLException e) { + Logger.error("Could not log message", e); + e.printStackTrace(); + } + } + } + + @Override + public void onMessageUpdate(MessageUpdateEvent event) { + + if(event.getAuthor().isBot() || event.getAuthor().isSystem()) { + return; + } + + String guildId = event.getGuild().getId(); + + String registeredGuildId = dc.retrieveRegisteredGuildId(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE); + if(registeredGuildId==null) { + return; + } + + if(registeredGuildId.equals(guildId)) { + try { + String messageId = event.getMessageId(); + String channelIdToSendTo = dc.retrieveRegisteredChannelId(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE); + + List oldAuthorAndMessage = dc.retrieveAuthorAndMessage(messageId, TableNames.MESSAGE_LOG_CONTENT_TABLE); + String updatedMessage = event.getMessage().getContentDisplay(); + + eb.setDescription("A message has been edited in: "+event.getJumpUrl()); + eb.setThumbnail(event.getAuthor().getEffectiveAvatarUrl()); + eb.setColor(Color.YELLOW); + eb.addField("Old Message", oldAuthorAndMessage.getLast(), false); // get only the message and not the author + eb.addField("New Message", updatedMessage, false); + + MessageEmbed mb = eb.build(); + event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue(); + eb.clearFields(); + // log the new message replacing the old one + dc.updateMessage(messageId, updatedMessage, TableNames.MESSAGE_LOG_CONTENT_TABLE); + } catch (SQLException e) { + Logger.error("Could not log updated message", e); + e.printStackTrace(); + eb.clearFields(); + } + } + } + + @Override + public void onMessageDelete(MessageDeleteEvent event) { + + String guildId = event.getGuild().getId(); + + String registeredGuildId = dc.retrieveRegisteredGuildId(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE); + if(registeredGuildId==null) { + return; + } + + if(registeredGuildId.equals(guildId)) { + try { + String messageId = event.getMessageId(); + // TODO if message id not found in db ,return + String channelIdToSendTo = dc.retrieveRegisteredChannelId(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE); + List oldAuthorAndMessage = dc.retrieveAuthorAndMessage(messageId, TableNames.MESSAGE_LOG_CONTENT_TABLE); + + User author = event.getJDA().getUserById(oldAuthorAndMessage.getFirst()); + String mentionableAuthor = (author !=null ? author.getAsMention() : oldAuthorAndMessage.getFirst()); + + eb.setDescription("A message sent by"+mentionableAuthor+"has been deleted"); + eb.setColor(Color.RED); + eb.addField("Deleted Message", oldAuthorAndMessage.getLast(), false); + + MessageEmbed mb = eb.build(); + event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue(); + eb.clearFields(); + // delete the message from the db after displaying + dc.deleteMessage(messageId, TableNames.MESSAGE_LOG_CONTENT_TABLE); + } catch (SQLException e) { + Logger.error("Could not delete message", e); + e.printStackTrace(); + eb.clearFields(); + } + } + } + +} diff --git a/src/main/java/org/papertrail/listeners/messagelisteners/package-info.java b/src/main/java/org/papertrail/listeners/messagelisteners/package-info.java new file mode 100644 index 00000000..ff3f1938 --- /dev/null +++ b/src/main/java/org/papertrail/listeners/messagelisteners/package-info.java @@ -0,0 +1,4 @@ +/* + * Groups listeners related to message activities + */ +package org.papertrail.listeners.messagelisteners; \ No newline at end of file diff --git a/src/main/java/org/papertrail/listeners/voicelisteners/GuildVoiceListener.java b/src/main/java/org/papertrail/listeners/voicelisteners/GuildVoiceListener.java index af1a44fa..96df3c88 100644 --- a/src/main/java/org/papertrail/listeners/voicelisteners/GuildVoiceListener.java +++ b/src/main/java/org/papertrail/listeners/voicelisteners/GuildVoiceListener.java @@ -26,7 +26,7 @@ public void onGuildVoiceUpdate(GuildVoiceUpdateEvent event) { // this will return a non-null text id if a channel was previously registered in // the database - String registeredChannelId = dc.retrieveChannelId(event.getGuild().getId(), TableNames.AUDIT_LOG_TABLE); + String registeredChannelId = dc.retrieveRegisteredChannelId(event.getGuild().getId(), TableNames.AUDIT_LOG_TABLE); if (registeredChannelId == null || registeredChannelId.isBlank()) { return; diff --git a/src/main/java/org/papertrail/main/FireRun.java b/src/main/java/org/papertrail/main/FireRun.java index aba89242..95b0fedd 100644 --- a/src/main/java/org/papertrail/main/FireRun.java +++ b/src/main/java/org/papertrail/main/FireRun.java @@ -13,6 +13,8 @@ import org.papertrail.listeners.loglisteners.AuditLogListener; import org.papertrail.listeners.loglisteners.LogCommandListener; import org.papertrail.listeners.memberlisteners.GuildMemberJoinAndLeaveListener; +import org.papertrail.listeners.messagelisteners.MessageLogCommandListener; +import org.papertrail.listeners.messagelisteners.MessageLogListener; import org.papertrail.listeners.voicelisteners.GuildVoiceListener; import com.sun.net.httpserver.HttpExchange; @@ -34,6 +36,8 @@ public static void main(String[] args) throws IOException, SQLException { ci.getManager().addEventListener(new GuildMemberJoinAndLeaveListener(dc)); ci.getManager().addEventListener(new ServerBoostListener(dc)); ci.getManager().addEventListener(new BotKickListener(dc)); + ci.getManager().addEventListener(new MessageLogCommandListener(dc)); + ci.getManager().addEventListener(new MessageLogListener(dc)); ci.getManager().addEventListener(new ServerStatListener()); ci.getManager().addEventListener(new BotInfoListener()); diff --git a/src/main/java/org/papertrail/main/SlashCommandRegistrar.java b/src/main/java/org/papertrail/main/SlashCommandRegistrar.java index 6aa569bb..cd836c69 100644 --- a/src/main/java/org/papertrail/main/SlashCommandRegistrar.java +++ b/src/main/java/org/papertrail/main/SlashCommandRegistrar.java @@ -20,19 +20,35 @@ public void onReady(@NotNull ReadyEvent event) { private void setAuditLogCommands(JDA jda) { - CommandData auditLogChannelRegistration = Commands.slash("ralc", + CommandData auditLogChannelRegistration = Commands.slash("auditlogchannel-set", "Registers the channel where audit log updates will be posted (Requires Manage Server Permission)"); - CommandData auditLogChannelFetch = Commands.slash("galc", + CommandData auditLogChannelFetch = Commands.slash("auditlogchannel-view", "Shows the channel where audit log updates gets posted (Requires Manage Server Permission)"); - CommandData auditLogChannelDeletion = Commands.slash("ualc", + CommandData auditLogChannelDeletion = Commands.slash("auditlogchannel-remove", "Unsets the channel where audit log updates used to be posted (Requires Manage Server Permission)"); + + CommandData messageLogChannelRegistration = Commands.slash("messagelogchannel-set", + "Sets the channel where messages are logged (Requires Manage Server Permission)"); + CommandData messageLogChannelFetch = Commands.slash("messagelogchannel-view", + "Shows the channel messages are logged (Requires Manage Server Permission)"); + CommandData messageLogChannelDeletion = Commands.slash("messagelogchannel-remove", + "Unsets the channel messages are logged (Requires Manage Server Permission)"); + CommandData serverStats = Commands.slash("stats", "Provides Server Statistics"); CommandData botInfo = Commands.slash("about", "Provides Bot Info"); CommandData setup = Commands.slash("setup", "Provides a guide on setting up the bot"); jda.updateCommands() - .addCommands(auditLogChannelRegistration, auditLogChannelFetch, auditLogChannelDeletion, serverStats, botInfo, setup) + .addCommands(auditLogChannelRegistration, + auditLogChannelFetch, + auditLogChannelDeletion, + messageLogChannelRegistration, + messageLogChannelFetch, + messageLogChannelDeletion, + serverStats, + botInfo, + setup) .queue(); } } diff --git a/src/main/resources/tinylog.properties b/src/main/resources/tinylog.properties index 26631144..0396c495 100644 --- a/src/main/resources/tinylog.properties +++ b/src/main/resources/tinylog.properties @@ -1,5 +1,5 @@ writer1 = console -writer1.format = {level}: {class}.{method}()\t{message} +writer1.format = {level}: {class}.{method}()\t{message}\n{exception} writer1.level = debug writingthread = true \ No newline at end of file From ee0452227c31bb11fdc6bab4f6dcd5b8864af343 Mon Sep 17 00:00:00 2001 From: Egg-03 <111327101+Egg-03@users.noreply.github.com> Date: Thu, 19 Jun 2025 14:01:21 +0530 Subject: [PATCH 2/9] Add message existence check before log retrieval Introduced a retrieveMessageId method in DatabaseConnector to check if a message exists in the database. Updated MessageLogListener to exit early if the message ID is not found, preventing unnecessary processing for unlogged messages. --- .../database/DatabaseConnector.java | 20 +++++++++++++++++++ .../messagelisteners/MessageLogListener.java | 5 ++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/papertrail/database/DatabaseConnector.java b/src/main/java/org/papertrail/database/DatabaseConnector.java index 6c5ff24b..92a2a9a4 100644 --- a/src/main/java/org/papertrail/database/DatabaseConnector.java +++ b/src/main/java/org/papertrail/database/DatabaseConnector.java @@ -128,6 +128,26 @@ public List retrieveAuthorAndMessage(String messageId, String tableName) } } + public String retrieveMessageId(String messageId, String tableName) { + + String sqlStatement = "SELECT message_id FROM " + tableName + " WHERE message_id = ?"; + + try (PreparedStatement psmt = connect.prepareStatement(sqlStatement)) { + psmt.setString(1, messageId); + + try (ResultSet rs = psmt.executeQuery()) { + if (rs.next()) { // only one message is logged per row per message id + return rs.getString("message_id"); + } + } + return null; + } catch (SQLException e) { + Logger.error("Could not retrieve message id", e); + e.printStackTrace(); + return null; + } + } + public void updateMessage(String messageId, String messageContent, String tableName) throws SQLException { String sqlStatement = "UPDATE " + tableName + " SET message_content = ? WHERE message_id = ?"; diff --git a/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java b/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java index 8660af65..314071f4 100644 --- a/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java +++ b/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java @@ -105,7 +105,10 @@ public void onMessageDelete(MessageDeleteEvent event) { if(registeredGuildId.equals(guildId)) { try { String messageId = event.getMessageId(); - // TODO if message id not found in db ,return + // if the message id does not exist in db, it means the message has not been logged. in that case, exit + if(dc.retrieveMessageId(messageId, TableNames.MESSAGE_LOG_CONTENT_TABLE)==null) { + return; + } String channelIdToSendTo = dc.retrieveRegisteredChannelId(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE); List oldAuthorAndMessage = dc.retrieveAuthorAndMessage(messageId, TableNames.MESSAGE_LOG_CONTENT_TABLE); From a74fa2513d18f6c3d1c68f602a3ac76558c7f791 Mon Sep 17 00:00:00 2001 From: Egg-03 <111327101+Egg-03@users.noreply.github.com> Date: Thu, 19 Jun 2025 16:54:41 +0530 Subject: [PATCH 3/9] Refactor audit log command listener and improve logging Replaces LogCommandListener with AuditLogCommandListener for audit log channel management, updating all references and registration in FireRun. Refactors DatabaseConnector with clearer method names and adds channel/message registration checks. Enhances message logging in MessageLogListener, including improved handling of message edits and deletions, and clarifies audit log mapping in various listeners. --- .../papertrail/cleanup/BotKickListener.java | 1 + .../database/DatabaseConnector.java | 97 +++++---- .../guildlisteners/ServerBoostListener.java | 1 + .../loglisteners/AuditLogCommandListener.java | 181 +++++++++++++++++ .../loglisteners/LogCommandListener.java | 189 ------------------ .../GuildMemberJoinAndLeaveListener.java | 1 + .../messagelisteners/MessageLogListener.java | 47 +++-- .../voicelisteners/GuildVoiceListener.java | 1 + .../java/org/papertrail/main/FireRun.java | 4 +- 9 files changed, 280 insertions(+), 242 deletions(-) create mode 100644 src/main/java/org/papertrail/listeners/loglisteners/AuditLogCommandListener.java delete mode 100644 src/main/java/org/papertrail/listeners/loglisteners/LogCommandListener.java diff --git a/src/main/java/org/papertrail/cleanup/BotKickListener.java b/src/main/java/org/papertrail/cleanup/BotKickListener.java index c34f56b7..aa490b98 100644 --- a/src/main/java/org/papertrail/cleanup/BotKickListener.java +++ b/src/main/java/org/papertrail/cleanup/BotKickListener.java @@ -26,6 +26,7 @@ public void onGuildLeave(@NotNull GuildLeaveEvent event) { Guild leftGuild = event.getGuild(); try { dc.unregisterGuildAndChannel(leftGuild.getId(), TableNames.AUDIT_LOG_TABLE); + dc.unregisterGuildAndChannel(leftGuild.getId(), TableNames.MESSAGE_LOG_REGISTRATION_TABLE); } catch (SQLException e) { Logger.error("Could not auto-unregister guild upon guild leave", e); } diff --git a/src/main/java/org/papertrail/database/DatabaseConnector.java b/src/main/java/org/papertrail/database/DatabaseConnector.java index 92a2a9a4..2b1d3cb1 100644 --- a/src/main/java/org/papertrail/database/DatabaseConnector.java +++ b/src/main/java/org/papertrail/database/DatabaseConnector.java @@ -14,25 +14,25 @@ public class DatabaseConnector { private static final String DB_URL = EnvConfig.get("DATABASEURL"); - + private Connection connect; - + public DatabaseConnector() throws SQLException { connect = DriverManager.getConnection(DB_URL); } - + public void registerGuildAndChannel(String guildId, String channelId, String tableName) throws SQLException { - + String sqlStatement = "INSERT INTO "+tableName+" (guild_id, channel_id) VALUES (?, ?)"; - + try(PreparedStatement psmt = connect.prepareStatement(sqlStatement)){ psmt.setString(1, guildId); psmt.setString(2, channelId); psmt.executeUpdate(); } - + } - + public String retrieveRegisteredChannelId(String guildId, String tableName) { String sqlStatement = "SELECT channel_id FROM " + tableName + " WHERE guild_id = ?"; @@ -42,13 +42,10 @@ public String retrieveRegisteredChannelId(String guildId, String tableName) { psmt.setString(1, guildId); try (ResultSet rs = psmt.executeQuery()) { - if (!rs.isBeforeFirst()) { - return null; - } else { - while (rs.next()) { // by configuration, there will always be only one channel id row at a time - // because registering multiple channels is not allowed - channelId = rs.getString("channel_id"); - } + + while (rs.next()) { // by configuration, there will always be only one channel id row at a time + // because registering multiple channels is not allowed + channelId = rs.getString("channel_id"); } } return channelId; @@ -57,21 +54,21 @@ public String retrieveRegisteredChannelId(String guildId, String tableName) { return null; } } - - public String retrieveRegisteredGuildId(String guildId, String tableName) { + /* + * If a guild of the given id is found, will return that id, otherwise null + */ + public String checkGuildRegistration(String guildId, String tableName) { String sqlStatement = "SELECT guild_id FROM " + tableName + " WHERE guild_id = ?"; - + try (PreparedStatement psmt = connect.prepareStatement(sqlStatement)) { psmt.setString(1, guildId); try (ResultSet rs = psmt.executeQuery()) { - if (!rs.isBeforeFirst()) { - return null; - } else { - while (rs.next()) { - return rs.getString("guild_id"); - } + + while (rs.next()) { + return rs.getString("guild_id"); + } } return null; @@ -80,21 +77,45 @@ public String retrieveRegisteredGuildId(String guildId, String tableName) { return null; } } - + + /* + * If a channel of the given id is found, will return that id, otherwise null + */ + public String checkChannelRegistration(String channelId, String tableName) { + + String sqlStatement = "SELECT channel_id FROM " + tableName + " WHERE channel_id = ?"; + + try (PreparedStatement psmt = connect.prepareStatement(sqlStatement)) { + psmt.setString(1, channelId); + + try (ResultSet rs = psmt.executeQuery()) { + while (rs.next()) { + return rs.getString("guild_id"); + } + } + return null; + } catch (SQLException e) { + Logger.error("Could not retrieve registered guild channel id", e); + return null; + } + } + public void unregisterGuildAndChannel(String guildId, String tableName) throws SQLException { - + String sqlStatement = "DELETE FROM "+tableName+" WHERE guild_id = ?"; - + try(PreparedStatement psmt = connect.prepareStatement(sqlStatement)){ psmt.setString(1, guildId); psmt.executeUpdate(); } } + + // MESSAGE FUNCTIONS public void logMessage(String messageId, String messageContent, String authorId, String tableName) throws SQLException { - + String sqlStatement = "INSERT INTO "+tableName+" (message_id, message_content, author_id) VALUES (?, ?, ?)"; - + try(PreparedStatement psmt = connect.prepareStatement(sqlStatement)){ psmt.setString(1, messageId); psmt.setString(2, messageContent); @@ -102,7 +123,7 @@ public void logMessage(String messageId, String messageContent, String authorId, psmt.executeUpdate(); } } - + public List retrieveAuthorAndMessage(String messageId, String tableName) { String sqlStatement = "SELECT author_id, message_content FROM " + tableName + " WHERE message_id = ?"; @@ -127,8 +148,10 @@ public List retrieveAuthorAndMessage(String messageId, String tableName) return Collections.emptyList(); } } - - public String retrieveMessageId(String messageId, String tableName) { + /* + * Checks if the message id exists in the database and returns the same if found, else null + */ + public String checkMessageId(String messageId, String tableName) { String sqlStatement = "SELECT message_id FROM " + tableName + " WHERE message_id = ?"; @@ -147,22 +170,22 @@ public String retrieveMessageId(String messageId, String tableName) { return null; } } - + public void updateMessage(String messageId, String messageContent, String tableName) throws SQLException { - + String sqlStatement = "UPDATE " + tableName + " SET message_content = ? WHERE message_id = ?"; - + try(PreparedStatement psmt = connect.prepareStatement(sqlStatement)){ psmt.setString(1, messageContent); psmt.setString(2, messageId); psmt.executeUpdate(); } } - + public void deleteMessage(String messageId, String tableName) throws SQLException { - + String sqlStatement = "DELETE FROM "+tableName+" WHERE message_id = ?"; - + try(PreparedStatement psmt = connect.prepareStatement(sqlStatement)){ psmt.setString(1, messageId); psmt.executeUpdate(); diff --git a/src/main/java/org/papertrail/listeners/guildlisteners/ServerBoostListener.java b/src/main/java/org/papertrail/listeners/guildlisteners/ServerBoostListener.java index c8a5d602..2ae0d976 100644 --- a/src/main/java/org/papertrail/listeners/guildlisteners/ServerBoostListener.java +++ b/src/main/java/org/papertrail/listeners/guildlisteners/ServerBoostListener.java @@ -26,6 +26,7 @@ public ServerBoostListener(DatabaseConnector dc) { public void onGuildMemberUpdateBoostTime(GuildMemberUpdateBoostTimeEvent event) { // this will return a non-null text id if a channel was previously registered in the database + // server boost logs are mapped to audit log table String registeredChannelId=dc.retrieveRegisteredChannelId(event.getGuild().getId(), TableNames.AUDIT_LOG_TABLE); if(registeredChannelId==null ||registeredChannelId.isBlank()) { diff --git a/src/main/java/org/papertrail/listeners/loglisteners/AuditLogCommandListener.java b/src/main/java/org/papertrail/listeners/loglisteners/AuditLogCommandListener.java new file mode 100644 index 00000000..ef76f980 --- /dev/null +++ b/src/main/java/org/papertrail/listeners/loglisteners/AuditLogCommandListener.java @@ -0,0 +1,181 @@ +package org.papertrail.listeners.loglisteners; + +import java.awt.Color; +import java.sql.SQLException; + +import org.papertrail.database.DatabaseConnector; +import org.papertrail.database.TableNames; +import org.tinylog.Logger; + +import net.dv8tion.jda.api.EmbedBuilder; +import net.dv8tion.jda.api.Permission; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.MessageEmbed; +import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.hooks.ListenerAdapter; + +public class AuditLogCommandListener extends ListenerAdapter { + + private DatabaseConnector dc; + private final EmbedBuilder eb = new EmbedBuilder(); + + public AuditLogCommandListener(DatabaseConnector dc) { + this.dc = dc; + eb.setTitle("📝 Audit Log Configuration"); + eb.setColor(Color.CYAN); + } + + @Override + public void onSlashCommandInteraction(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; + } + + switch(event.getName()) { + + case "auditlogchannel-set": + setAuditLogging(event); + break; + + case "auditlogchannel-view": + retrieveAuditLoggingChannel(event); + break; + + case "auditlogchannel-remove": + unsetAuditLogging(event); + break; + + default: + break; + } + } + + + private void setAuditLogging(SlashCommandInteractionEvent event) { + String guildId = event.getGuild().getId(); + // retrieve the previously registered channel_id associated with the given + // guild_id + String registeredChannelId = dc.retrieveRegisteredChannelId(guildId, TableNames.AUDIT_LOG_TABLE); + + // if there is a registered channel_id in the database, send a warning message + // in the channel where the command was called from, stating that a channel has + // already been registered + if (registeredChannelId != null && !registeredChannelId.isBlank()) { + + GuildChannel registeredChannel = event.getGuild().getGuildChannelById(registeredChannelId); + eb.addField("⚠️ Channel Already Registered", "╰┈➤"+(registeredChannel !=null ? registeredChannel.getAsMention() : registeredChannelId)+ " has already been selected as the audit log channel", false); + eb.setColor(Color.YELLOW); + + MessageEmbed mb = eb.build(); + event.replyEmbeds(mb).setEphemeral(false).queue(); + + eb.clearFields(); + return; + } + + // if there is no channel registered, get the channel id from where the command + // was called + String channelIdToRegister = event.getChannel().asTextChannel().getId(); + try { + // register the channel_id along with guild_id in the database + dc.registerGuildAndChannel(guildId, channelIdToRegister, TableNames.AUDIT_LOG_TABLE); + + 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(); + + eb.clearFields(); + + } catch (SQLException e) { + + eb.addField("❌ Channel Registration Failure","╰┈➤"+"Channel could not be registered", false); + eb.setColor(Color.BLACK); + MessageEmbed mb = eb.build(); + + event.replyEmbeds(mb).setEphemeral(false).queue(); + + eb.clearFields(); + + Logger.error("Audit Log Channel could not be registered", e); + } + } + + private void retrieveAuditLoggingChannel(SlashCommandInteractionEvent event) { + String guildId = event.getGuild().getId(); + + // retrieve the channel_id registered in the database + String registeredChannelId = dc.retrieveRegisteredChannelId(guildId, TableNames.AUDIT_LOG_TABLE); + + // if there is no channel_id for the given guild_id in the database, then inform + // the user of the same, else link the channel that has been registered + if (registeredChannelId == null || registeredChannelId.isBlank()) { + eb.addField("⚠️ Channel Registration Check", "╰┈➤"+"No channel has been registered for audit logs", false); + eb.setColor(Color.YELLOW); + MessageEmbed mb = eb.build(); + event.replyEmbeds(mb).setEphemeral(false).queue(); + + eb.clearFields(); + } else { + // check if the channelId actually exists in the guild + // this is particularly useful when a channel that was set for logging may have been deleted + GuildChannel registeredChannel = event.getJDA().getGuildChannelById(registeredChannelId); + if(registeredChannel==null) { + eb.addField("⚠️ Channel Registration Check", "╰┈➤"+registeredChannelId+" does not exist. Please remove it using `/auditlogchannel-remove` and re-register using `/auditlogchannel-set`", false); + eb.setColor(Color.RED); + } else { + eb.setColor(Color.CYAN); + eb.addField("✅ Channel Registration Check", "╰┈➤"+registeredChannel.getAsMention()+ " is found to be registered as the audit log channel", false); + } + + MessageEmbed mb = eb.build(); + event.replyEmbeds(mb).setEphemeral(false).queue(); + + eb.clearFields(); + } + } + + private void unsetAuditLogging(SlashCommandInteractionEvent event) { + String guildId = event.getGuild().getId(); + String registeredChannelId = dc.retrieveRegisteredChannelId(guildId, TableNames.AUDIT_LOG_TABLE); + + if (registeredChannelId == null || registeredChannelId.isBlank()) { + eb.addField("ℹ️ Channel Removal", "╰┈➤"+"No channel has been registered for audit logs", false); + eb.setColor(Color.YELLOW); + MessageEmbed mb = eb.build(); + + event.replyEmbeds(mb).setEphemeral(false).queue(); + + eb.clearFields(); + + } else { + try { + + dc.unregisterGuildAndChannel(guildId, TableNames.AUDIT_LOG_TABLE); + + eb.addField("✅ Channel Removal", "╰┈➤"+"Channel successfully unset", false); + eb.setColor(Color.GREEN); + MessageEmbed mb = eb.build(); + + event.replyEmbeds(mb).setEphemeral(false).queue(); + + eb.clearFields(); + } catch (SQLException e) { + eb.addField("❌ Channel Removal Failure", "╰┈➤"+"Channel could not be unset", false); + eb.setColor(Color.BLACK); + MessageEmbed mb = eb.build(); + + event.replyEmbeds(mb).setEphemeral(false).queue(); + + eb.clearFields(); + Logger.error("Could not un-register audit log channel", e); + } + } + } +} diff --git a/src/main/java/org/papertrail/listeners/loglisteners/LogCommandListener.java b/src/main/java/org/papertrail/listeners/loglisteners/LogCommandListener.java deleted file mode 100644 index 5867e55f..00000000 --- a/src/main/java/org/papertrail/listeners/loglisteners/LogCommandListener.java +++ /dev/null @@ -1,189 +0,0 @@ -package org.papertrail.listeners.loglisteners; - -import java.awt.Color; -import java.sql.SQLException; - -import org.papertrail.database.DatabaseConnector; -import org.papertrail.database.TableNames; -import org.tinylog.Logger; - -import net.dv8tion.jda.api.EmbedBuilder; -import net.dv8tion.jda.api.Permission; -import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.MessageEmbed; -import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel; -import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; -import net.dv8tion.jda.api.hooks.ListenerAdapter; - -public class LogCommandListener extends ListenerAdapter { - - private DatabaseConnector dc; - private final EmbedBuilder eb = new EmbedBuilder(); - - public LogCommandListener(DatabaseConnector dc) { - this.dc = dc; - eb.setTitle("📝 Audit Log Configuration"); - eb.setColor(Color.CYAN); - } - - @Override - public void onSlashCommandInteraction(SlashCommandInteractionEvent event) { - - // Command for binding the listener to a channel - if (event.getName().equals("auditlogchannel-set")) { - - // 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; - } - - String guildId = event.getGuild().getId(); - // retrieve the previously registered channel_id associated with the given - // guild_id - String registeredChannelId = dc.retrieveRegisteredChannelId(guildId, TableNames.AUDIT_LOG_TABLE); - - // if there is a registered channel_id in the database, send a warning message - // in the channel where the command was called from, stating that a channel has - // already been registered - if (registeredChannelId != null && !registeredChannelId.isBlank()) { - - GuildChannel registeredChannel = event.getGuild().getGuildChannelById(registeredChannelId); - eb.addField("⚠️ Channel Already Registered", "╰┈➤"+(registeredChannel !=null ? registeredChannel.getAsMention() : registeredChannelId)+ " has already been selected as the audit log channel", false); - eb.setColor(Color.YELLOW); - - MessageEmbed mb = eb.build(); - event.replyEmbeds(mb).setEphemeral(false).queue(); - - eb.clearFields(); - return; - } - - // if there is no channel registered, get the channel id from where the command - // was called - String channelIdToRegister = event.getChannel().asTextChannel().getId(); - try { - // register the channel_id along with guild_id in the database - dc.registerGuildAndChannel(guildId, channelIdToRegister, TableNames.AUDIT_LOG_TABLE); - - 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(); - - eb.clearFields(); - - } catch (SQLException e) { - - eb.addField("❌ Channel Registration Failure","╰┈➤"+"Channel could not be registered", false); - eb.setColor(Color.BLACK); - MessageEmbed mb = eb.build(); - - event.replyEmbeds(mb).setEphemeral(false).queue(); - - eb.clearFields(); - - Logger.error("Audit Log Channel could not be registered", e); - } - } - - // Command for getting the channel where audit logs are posted - if (event.getName().equals("auditlogchannel-view")) { - - // 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; - } - - String guildId = event.getGuild().getId(); - - // retrieve the channel_id registered in the database - String registeredChannelId = dc.retrieveRegisteredChannelId(guildId, TableNames.AUDIT_LOG_TABLE); - - // if there is no channel_id for the given guild_id in the database, then inform - // the user of the same, else link the channel that has been registered - if (registeredChannelId == null || registeredChannelId.isBlank()) { - eb.addField("⚠️ Channel Registration Check", "╰┈➤"+"No channel has been registered for audit logs", false); - eb.setColor(Color.YELLOW); - MessageEmbed mb = eb.build(); - event.replyEmbeds(mb).setEphemeral(false).queue(); - - eb.clearFields(); - } else { - // check if the channelId actually exists in the guild - // this is particularly useful when a channel that was set for logging may have been deleted - GuildChannel registeredChannel = event.getJDA().getGuildChannelById(registeredChannelId); - if(registeredChannel==null) { - eb.addField("⚠️ Channel Registration Check", "╰┈➤"+registeredChannelId+" does not exist. Please remove it using `/auditlogchannel-remove` and re-register using `/auditlogchannel-set`", false); - eb.setColor(Color.RED); - } else { - eb.setColor(Color.CYAN); - eb.addField("✅ Channel Registration Check", "╰┈➤"+registeredChannel.getAsMention()+ " is found to be registered as the audit log channel", false); - } - - MessageEmbed mb = eb.build(); - event.replyEmbeds(mb).setEphemeral(false).queue(); - - eb.clearFields(); - } - } - - // Command for un-setting a previously bound listener from a channel - if (event.getName().equals("auditlogchannel-remove")) { - - // 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; - } - - String guildId = event.getGuild().getId(); - String registeredChannelId = dc.retrieveRegisteredChannelId(guildId, TableNames.AUDIT_LOG_TABLE); - - if (registeredChannelId == null || registeredChannelId.isBlank()) { - eb.addField("ℹ️ Channel Removal", "╰┈➤"+"No channel has been registered for audit logs", false); - eb.setColor(Color.YELLOW); - MessageEmbed mb = eb.build(); - - event.replyEmbeds(mb).setEphemeral(false).queue(); - - eb.clearFields(); - - } else { - try { - - dc.unregisterGuildAndChannel(guildId, TableNames.AUDIT_LOG_TABLE); - - eb.addField("✅ Channel Removal", "╰┈➤"+"Channel successfully unset", false); - eb.setColor(Color.GREEN); - MessageEmbed mb = eb.build(); - - event.replyEmbeds(mb).setEphemeral(false).queue(); - - eb.clearFields(); - } catch (SQLException e) { - eb.addField("❌ Channel Removal Failure", "╰┈➤"+"Channel could not be unset", false); - eb.setColor(Color.BLACK); - MessageEmbed mb = eb.build(); - - event.replyEmbeds(mb).setEphemeral(false).queue(); - - eb.clearFields(); - Logger.error("Could not un-register audit log channel", e); - } - } - - } - } -} diff --git a/src/main/java/org/papertrail/listeners/memberlisteners/GuildMemberJoinAndLeaveListener.java b/src/main/java/org/papertrail/listeners/memberlisteners/GuildMemberJoinAndLeaveListener.java index 9246829a..b34770e9 100644 --- a/src/main/java/org/papertrail/listeners/memberlisteners/GuildMemberJoinAndLeaveListener.java +++ b/src/main/java/org/papertrail/listeners/memberlisteners/GuildMemberJoinAndLeaveListener.java @@ -28,6 +28,7 @@ public void onGuildMemberJoin(GuildMemberJoinEvent event) { // this will return a non-null text id if a channel was previously registered in // the database + // guild member join and leave events are mapped to audit log table String registeredChannelId = dc.retrieveRegisteredChannelId(event.getGuild().getId(), TableNames.AUDIT_LOG_TABLE); if (registeredChannelId == null || registeredChannelId.isBlank()) { diff --git a/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java b/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java index 314071f4..f3580b8a 100644 --- a/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java +++ b/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java @@ -29,21 +29,30 @@ public MessageLogListener(DatabaseConnector dc) { @Override public void onMessageReceived(MessageReceivedEvent event) { + // if the author is a bot or system, don't log if(event.getAuthor().isBot() || event.getAuthor().isSystem()) { return; } - - String guildId = event.getGuild().getId(); - String registeredGuildId = dc.retrieveRegisteredGuildId(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE); + // don't register non-textual contents + if(event.getMessage().getContentRaw().isEmpty()) { + return; + } + + // get the guild id for which the event was fired + String guildId = event.getGuild().getId(); + // see if the guild id is registered in the database for logging + String registeredGuildId = dc.checkGuildRegistration(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE); + // if not registered, exit if(registeredGuildId==null) { return; } + // else if the registered guild id matches with the event fetched guild id, log the message with its ID and author if(registeredGuildId.equals(guildId)) { try { String messageId = event.getMessageId(); - dc.logMessage(messageId, event.getMessage().getContentDisplay(), event.getAuthor().getId(), TableNames.MESSAGE_LOG_CONTENT_TABLE); + dc.logMessage(messageId, event.getMessage().getContentRaw(), event.getAuthor().getId(), TableNames.MESSAGE_LOG_CONTENT_TABLE); } catch (SQLException e) { Logger.error("Could not log message", e); e.printStackTrace(); @@ -60,20 +69,27 @@ public void onMessageUpdate(MessageUpdateEvent event) { String guildId = event.getGuild().getId(); - String registeredGuildId = dc.retrieveRegisteredGuildId(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE); + String registeredGuildId = dc.checkGuildRegistration(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE); if(registeredGuildId==null) { return; } if(registeredGuildId.equals(guildId)) { try { + // get the message id of the message which was updated String messageId = event.getMessageId(); + // fetch the channel id from the database + // this channel is where the logs will be sent to String channelIdToSendTo = dc.retrieveRegisteredChannelId(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE); + // fetch the old message content and its author from the database List oldAuthorAndMessage = dc.retrieveAuthorAndMessage(messageId, TableNames.MESSAGE_LOG_CONTENT_TABLE); - String updatedMessage = event.getMessage().getContentDisplay(); - eb.setDescription("A message has been edited in: "+event.getJumpUrl()); + // fetch the updated message from the event + String updatedMessage = event.getMessage().getContentRaw(); + String mentionableAuthor = event.getAuthor().getAsMention(); + + eb.setDescription("A message sent by "+mentionableAuthor+" has been edited in: "+event.getJumpUrl()); eb.setThumbnail(event.getAuthor().getEffectiveAvatarUrl()); eb.setColor(Color.YELLOW); eb.addField("Old Message", oldAuthorAndMessage.getLast(), false); // get only the message and not the author @@ -82,7 +98,7 @@ public void onMessageUpdate(MessageUpdateEvent event) { MessageEmbed mb = eb.build(); event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue(); eb.clearFields(); - // log the new message replacing the old one + // update the database with the new message dc.updateMessage(messageId, updatedMessage, TableNames.MESSAGE_LOG_CONTENT_TABLE); } catch (SQLException e) { Logger.error("Could not log updated message", e); @@ -97,32 +113,36 @@ public void onMessageDelete(MessageDeleteEvent event) { String guildId = event.getGuild().getId(); - String registeredGuildId = dc.retrieveRegisteredGuildId(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE); + String registeredGuildId = dc.checkGuildRegistration(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE); if(registeredGuildId==null) { return; } if(registeredGuildId.equals(guildId)) { try { + // get the message id of the message which was deleted String messageId = event.getMessageId(); - // if the message id does not exist in db, it means the message has not been logged. in that case, exit - if(dc.retrieveMessageId(messageId, TableNames.MESSAGE_LOG_CONTENT_TABLE)==null) { + // if the message id does not exist in db, it means the message has not been logged in the first place + if(dc.checkMessageId(messageId, TableNames.MESSAGE_LOG_CONTENT_TABLE)==null) { return; } + + // retrieve the channel id where the logs must be sent String channelIdToSendTo = dc.retrieveRegisteredChannelId(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE); + // retrieve the stored message in the database which was deleted List oldAuthorAndMessage = dc.retrieveAuthorAndMessage(messageId, TableNames.MESSAGE_LOG_CONTENT_TABLE); User author = event.getJDA().getUserById(oldAuthorAndMessage.getFirst()); String mentionableAuthor = (author !=null ? author.getAsMention() : oldAuthorAndMessage.getFirst()); - eb.setDescription("A message sent by"+mentionableAuthor+"has been deleted"); + eb.setDescription("A message sent by "+mentionableAuthor+" has been deleted"); eb.setColor(Color.RED); eb.addField("Deleted Message", oldAuthorAndMessage.getLast(), false); MessageEmbed mb = eb.build(); event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue(); eb.clearFields(); - // delete the message from the db after displaying + // delete the message from the database after logging dc.deleteMessage(messageId, TableNames.MESSAGE_LOG_CONTENT_TABLE); } catch (SQLException e) { Logger.error("Could not delete message", e); @@ -131,5 +151,4 @@ public void onMessageDelete(MessageDeleteEvent event) { } } } - } diff --git a/src/main/java/org/papertrail/listeners/voicelisteners/GuildVoiceListener.java b/src/main/java/org/papertrail/listeners/voicelisteners/GuildVoiceListener.java index 96df3c88..68faeb85 100644 --- a/src/main/java/org/papertrail/listeners/voicelisteners/GuildVoiceListener.java +++ b/src/main/java/org/papertrail/listeners/voicelisteners/GuildVoiceListener.java @@ -26,6 +26,7 @@ public void onGuildVoiceUpdate(GuildVoiceUpdateEvent event) { // this will return a non-null text id if a channel was previously registered in // the database + // guild voice events are mapped to audit log table String registeredChannelId = dc.retrieveRegisteredChannelId(event.getGuild().getId(), TableNames.AUDIT_LOG_TABLE); if (registeredChannelId == null || registeredChannelId.isBlank()) { diff --git a/src/main/java/org/papertrail/main/FireRun.java b/src/main/java/org/papertrail/main/FireRun.java index 95b0fedd..cd409fa1 100644 --- a/src/main/java/org/papertrail/main/FireRun.java +++ b/src/main/java/org/papertrail/main/FireRun.java @@ -11,7 +11,7 @@ import org.papertrail.listeners.customlisteners.SetupListener; import org.papertrail.listeners.guildlisteners.ServerBoostListener; import org.papertrail.listeners.loglisteners.AuditLogListener; -import org.papertrail.listeners.loglisteners.LogCommandListener; +import org.papertrail.listeners.loglisteners.AuditLogCommandListener; import org.papertrail.listeners.memberlisteners.GuildMemberJoinAndLeaveListener; import org.papertrail.listeners.messagelisteners.MessageLogCommandListener; import org.papertrail.listeners.messagelisteners.MessageLogListener; @@ -30,7 +30,7 @@ public static void main(String[] args) throws IOException, SQLException { DatabaseConnector dc = new DatabaseConnector(); ConnectionInitializer ci = new ConnectionInitializer(); - ci.getManager().addEventListener(new LogCommandListener(dc)); + ci.getManager().addEventListener(new AuditLogCommandListener(dc)); ci.getManager().addEventListener(new AuditLogListener(dc)); ci.getManager().addEventListener(new GuildVoiceListener(dc)); ci.getManager().addEventListener(new GuildMemberJoinAndLeaveListener(dc)); From 4c9586d08e0e21db5c533e52106b37e9661d075a Mon Sep 17 00:00:00 2001 From: Egg-03 <111327101+Egg-03@users.noreply.github.com> Date: Thu, 19 Jun 2025 17:27:26 +0530 Subject: [PATCH 4/9] Refactor EmbedBuilder usage in log listeners Moved EmbedBuilder instantiation inside methods in AuditLogCommandListener and MessageLogListener to avoid shared mutable state and potential concurrency issues. Removed unnecessary clearFields() calls and improved code clarity by creating new EmbedBuilder instances for each event. --- .../loglisteners/AuditLogCommandListener.java | 62 +++++++++++-------- .../messagelisteners/MessageLogListener.java | 36 ++++++----- 2 files changed, 57 insertions(+), 41 deletions(-) diff --git a/src/main/java/org/papertrail/listeners/loglisteners/AuditLogCommandListener.java b/src/main/java/org/papertrail/listeners/loglisteners/AuditLogCommandListener.java index ef76f980..a83c53bb 100644 --- a/src/main/java/org/papertrail/listeners/loglisteners/AuditLogCommandListener.java +++ b/src/main/java/org/papertrail/listeners/loglisteners/AuditLogCommandListener.java @@ -18,12 +18,10 @@ public class AuditLogCommandListener extends ListenerAdapter { private DatabaseConnector dc; - private final EmbedBuilder eb = new EmbedBuilder(); + public AuditLogCommandListener(DatabaseConnector dc) { - this.dc = dc; - eb.setTitle("📝 Audit Log Configuration"); - eb.setColor(Color.CYAN); + this.dc = dc; } @Override @@ -68,13 +66,14 @@ private void setAuditLogging(SlashCommandInteractionEvent event) { if (registeredChannelId != null && !registeredChannelId.isBlank()) { GuildChannel registeredChannel = event.getGuild().getGuildChannelById(registeredChannelId); + EmbedBuilder eb = new EmbedBuilder(); + eb.setTitle("📝 Audit Log Configuration"); eb.addField("⚠️ Channel Already Registered", "╰┈➤"+(registeredChannel !=null ? registeredChannel.getAsMention() : registeredChannelId)+ " has already been selected as the audit log channel", false); eb.setColor(Color.YELLOW); MessageEmbed mb = eb.build(); event.replyEmbeds(mb).setEphemeral(false).queue(); - eb.clearFields(); return; } @@ -84,25 +83,24 @@ private void setAuditLogging(SlashCommandInteractionEvent event) { try { // register the channel_id along with guild_id in the database dc.registerGuildAndChannel(guildId, channelIdToRegister, TableNames.AUDIT_LOG_TABLE); - + + EmbedBuilder eb = new EmbedBuilder(); + eb.setTitle("📝 Audit Log Configuration"); 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(); - eb.clearFields(); - } catch (SQLException e) { - + + EmbedBuilder eb = new EmbedBuilder(); + eb.setTitle("📝 Audit Log Configuration"); eb.addField("❌ Channel Registration Failure","╰┈➤"+"Channel could not be registered", false); eb.setColor(Color.BLACK); MessageEmbed mb = eb.build(); - event.replyEmbeds(mb).setEphemeral(false).queue(); - eb.clearFields(); - Logger.error("Audit Log Channel could not be registered", e); } } @@ -116,28 +114,36 @@ private void retrieveAuditLoggingChannel(SlashCommandInteractionEvent event) { // if there is no channel_id for the given guild_id in the database, then inform // the user of the same, else link the channel that has been registered if (registeredChannelId == null || registeredChannelId.isBlank()) { + + EmbedBuilder eb = new EmbedBuilder(); + eb.setTitle("📝 Audit Log Configuration"); eb.addField("⚠️ Channel Registration Check", "╰┈➤"+"No channel has been registered for audit logs", false); eb.setColor(Color.YELLOW); MessageEmbed mb = eb.build(); event.replyEmbeds(mb).setEphemeral(false).queue(); - - eb.clearFields(); + } else { // check if the channelId actually exists in the guild // this is particularly useful when a channel that was set for logging may have been deleted GuildChannel registeredChannel = event.getJDA().getGuildChannelById(registeredChannelId); if(registeredChannel==null) { + + EmbedBuilder eb = new EmbedBuilder(); + eb.setTitle("📝 Audit Log Configuration"); eb.addField("⚠️ Channel Registration Check", "╰┈➤"+registeredChannelId+" does not exist. Please remove it using `/auditlogchannel-remove` and re-register using `/auditlogchannel-set`", false); eb.setColor(Color.RED); + MessageEmbed mb = eb.build(); + event.replyEmbeds(mb).setEphemeral(false).queue(); + } else { + + EmbedBuilder eb = new EmbedBuilder(); + eb.setTitle("📝 Audit Log Configuration"); eb.setColor(Color.CYAN); eb.addField("✅ Channel Registration Check", "╰┈➤"+registeredChannel.getAsMention()+ " is found to be registered as the audit log channel", false); - } - - MessageEmbed mb = eb.build(); - event.replyEmbeds(mb).setEphemeral(false).queue(); - - eb.clearFields(); + MessageEmbed mb = eb.build(); + event.replyEmbeds(mb).setEphemeral(false).queue(); + } } } @@ -146,34 +152,36 @@ private void unsetAuditLogging(SlashCommandInteractionEvent event) { String registeredChannelId = dc.retrieveRegisteredChannelId(guildId, TableNames.AUDIT_LOG_TABLE); if (registeredChannelId == null || registeredChannelId.isBlank()) { + + EmbedBuilder eb = new EmbedBuilder(); + eb.setTitle("📝 Audit Log Configuration"); eb.addField("ℹ️ Channel Removal", "╰┈➤"+"No channel has been registered for audit logs", false); eb.setColor(Color.YELLOW); MessageEmbed mb = eb.build(); event.replyEmbeds(mb).setEphemeral(false).queue(); - - eb.clearFields(); - } else { try { dc.unregisterGuildAndChannel(guildId, TableNames.AUDIT_LOG_TABLE); - + + EmbedBuilder eb = new EmbedBuilder(); + eb.setTitle("📝 Audit Log Configuration"); eb.addField("✅ Channel Removal", "╰┈➤"+"Channel successfully unset", false); eb.setColor(Color.GREEN); MessageEmbed mb = eb.build(); event.replyEmbeds(mb).setEphemeral(false).queue(); - eb.clearFields(); } catch (SQLException e) { + + EmbedBuilder eb = new EmbedBuilder(); + eb.setTitle("📝 Audit Log Configuration"); eb.addField("❌ Channel Removal Failure", "╰┈➤"+"Channel could not be unset", false); eb.setColor(Color.BLACK); MessageEmbed mb = eb.build(); - event.replyEmbeds(mb).setEphemeral(false).queue(); - eb.clearFields(); Logger.error("Could not un-register audit log channel", e); } } diff --git a/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java b/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java index f3580b8a..2d525c14 100644 --- a/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java +++ b/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java @@ -19,16 +19,14 @@ public class MessageLogListener extends ListenerAdapter { private DatabaseConnector dc; - private final EmbedBuilder eb = new EmbedBuilder(); - public MessageLogListener(DatabaseConnector dc) { this.dc = dc; - eb.setTitle("📝 Message Log Event"); + } @Override public void onMessageReceived(MessageReceivedEvent event) { - + // if the author is a bot or system, don't log if(event.getAuthor().isBot() || event.getAuthor().isSystem()) { return; @@ -89,21 +87,25 @@ public void onMessageUpdate(MessageUpdateEvent event) { String updatedMessage = event.getMessage().getContentRaw(); String mentionableAuthor = event.getAuthor().getAsMention(); + EmbedBuilder eb = new EmbedBuilder(); + eb.setTitle("📝 Message Edit Event"); eb.setDescription("A message sent by "+mentionableAuthor+" has been edited in: "+event.getJumpUrl()); eb.setThumbnail(event.getAuthor().getEffectiveAvatarUrl()); eb.setColor(Color.YELLOW); eb.addField("Old Message", oldAuthorAndMessage.getLast(), false); // get only the message and not the author eb.addField("New Message", updatedMessage, false); - MessageEmbed mb = eb.build(); - event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue(); - eb.clearFields(); // update the database with the new message dc.updateMessage(messageId, updatedMessage, TableNames.MESSAGE_LOG_CONTENT_TABLE); + // the reason this is above the send queue is because 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. + + // send to the logging channel + MessageEmbed mb = eb.build(); + event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue(); } catch (SQLException e) { Logger.error("Could not log updated message", e); - e.printStackTrace(); - eb.clearFields(); + e.printStackTrace(); } } } @@ -135,19 +137,25 @@ public void onMessageDelete(MessageDeleteEvent event) { User author = event.getJDA().getUserById(oldAuthorAndMessage.getFirst()); String mentionableAuthor = (author !=null ? author.getAsMention() : oldAuthorAndMessage.getFirst()); + EmbedBuilder eb = new EmbedBuilder(); + eb.setTitle("📝 Message Delete Event"); eb.setDescription("A message sent by "+mentionableAuthor+" has been deleted"); eb.setColor(Color.RED); eb.addField("Deleted Message", oldAuthorAndMessage.getLast(), false); - MessageEmbed mb = eb.build(); - event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue(); - eb.clearFields(); - // delete the message from the database after logging + // delete the message from the database dc.deleteMessage(messageId, TableNames.MESSAGE_LOG_CONTENT_TABLE); + // the reason this is above the send queue is because in case where the user did not give sufficient permissions to + // the bot, the error responses wouldn't block the deletion in the database. + + // send the fetched deleted message to the logging channel + MessageEmbed mb = eb.build(); + event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue(); + } catch (SQLException e) { Logger.error("Could not delete message", e); e.printStackTrace(); - eb.clearFields(); + } } } From 25540e3bdb75294721d907bb3d5d3ed94e73bd6c Mon Sep 17 00:00:00 2001 From: Egg-03 <111327101+Egg-03@users.noreply.github.com> Date: Thu, 19 Jun 2025 18:54:55 +0530 Subject: [PATCH 5/9] Ignore message update events with no content change Added a check to skip logging and database updates when a MessageUpdateEvent is triggered but the message content remains unchanged (such as pin or embed resolve events). This prevents unnecessary log entries and database writes for non-content edits. --- .../messagelisteners/MessageLogListener.java | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java b/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java index 2d525c14..c0da098c 100644 --- a/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java +++ b/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java @@ -65,6 +65,7 @@ public void onMessageUpdate(MessageUpdateEvent event) { return; } + String guildId = event.getGuild().getId(); String registeredGuildId = dc.checkGuildRegistration(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE); @@ -76,20 +77,22 @@ public void onMessageUpdate(MessageUpdateEvent event) { try { // get the message id of the message which was updated String messageId = event.getMessageId(); - // fetch the channel id from the database - // this channel is where the logs will be sent to - String channelIdToSendTo = dc.retrieveRegisteredChannelId(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE); - + // fetch the old message content and its author from the database List oldAuthorAndMessage = dc.retrieveAuthorAndMessage(messageId, TableNames.MESSAGE_LOG_CONTENT_TABLE); // fetch the updated message from the event - String updatedMessage = event.getMessage().getContentRaw(); - String mentionableAuthor = event.getAuthor().getAsMention(); + String updatedMessage = event.getMessage().getContentRaw(); + // Ignore events where the message content wasn't edited (e.g., pin, embed resolve) + // This is required since MessageUpdateEvent is triggered in case of pins and embed resolves with no change to content + if(updatedMessage.equals(oldAuthorAndMessage.getLast())) { + return; + } + EmbedBuilder eb = new EmbedBuilder(); eb.setTitle("📝 Message Edit Event"); - eb.setDescription("A message sent by "+mentionableAuthor+" has been edited in: "+event.getJumpUrl()); + eb.setDescription("A message sent by "+event.getAuthor().getAsMention()+" has been edited in: "+event.getJumpUrl()); eb.setThumbnail(event.getAuthor().getEffectiveAvatarUrl()); eb.setColor(Color.YELLOW); eb.addField("Old Message", oldAuthorAndMessage.getLast(), false); // get only the message and not the author @@ -98,10 +101,13 @@ public void onMessageUpdate(MessageUpdateEvent event) { // update the database with the new message dc.updateMessage(messageId, updatedMessage, TableNames.MESSAGE_LOG_CONTENT_TABLE); // the reason this is above the send queue is because 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. + // the bot, the error responses wouldn't block the update of the message in the database. - // send to the logging channel + // 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(); + String channelIdToSendTo = dc.retrieveRegisteredChannelId(guildId, TableNames.MESSAGE_LOG_REGISTRATION_TABLE); event.getGuild().getTextChannelById(channelIdToSendTo).sendMessageEmbeds(mb).queue(); } catch (SQLException e) { Logger.error("Could not log updated message", e); From 5832b2465818b07f9b1a852ba10d0657c6d2783e Mon Sep 17 00:00:00 2001 From: Egg-03 <111327101+Egg-03@users.noreply.github.com> Date: Thu, 19 Jun 2025 19:00:43 +0530 Subject: [PATCH 6/9] Update MessageLogListener.java --- .../listeners/messagelisteners/MessageLogListener.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java b/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java index c0da098c..0fff3df1 100644 --- a/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java +++ b/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java @@ -84,7 +84,7 @@ public void onMessageUpdate(MessageUpdateEvent event) { // fetch the updated message from the event String updatedMessage = event.getMessage().getContentRaw(); - // Ignore events where the message content wasn't edited (e.g., pin, embed resolve) + // 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(oldAuthorAndMessage.getLast())) { return; From ce13763ede376e1f9f04408ba6b150ebf08f6ccf Mon Sep 17 00:00:00 2001 From: Egg-03 <111327101+Egg-03@users.noreply.github.com> Date: Thu, 19 Jun 2025 19:13:13 +0530 Subject: [PATCH 7/9] Add footer and timestamp to message log embeds Embeds for edited and deleted messages now include the guild name as a footer and the current timestamp. This improves context and traceability in message logs. --- .../listeners/messagelisteners/MessageLogListener.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java b/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java index 0fff3df1..cad00615 100644 --- a/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java +++ b/src/main/java/org/papertrail/listeners/messagelisteners/MessageLogListener.java @@ -2,6 +2,7 @@ import java.awt.Color; import java.sql.SQLException; +import java.time.Instant; import java.util.List; import org.papertrail.database.DatabaseConnector; @@ -95,9 +96,12 @@ public void onMessageUpdate(MessageUpdateEvent event) { eb.setDescription("A message sent by "+event.getAuthor().getAsMention()+" has been edited in: "+event.getJumpUrl()); eb.setThumbnail(event.getAuthor().getEffectiveAvatarUrl()); eb.setColor(Color.YELLOW); + eb.addField("Old Message", oldAuthorAndMessage.getLast(), false); // get only the message and not the author eb.addField("New Message", updatedMessage, false); + eb.setFooter(event.getGuild().getName()); + eb.setTimestamp(Instant.now()); // update the database with the new message dc.updateMessage(messageId, updatedMessage, TableNames.MESSAGE_LOG_CONTENT_TABLE); // the reason this is above the send queue is because in case where the user did not give sufficient permissions to @@ -149,6 +153,9 @@ public void onMessageDelete(MessageDeleteEvent event) { eb.setColor(Color.RED); eb.addField("Deleted Message", oldAuthorAndMessage.getLast(), false); + eb.setFooter(event.getGuild().getName()); + eb.setTimestamp(Instant.now()); + // delete the message from the database dc.deleteMessage(messageId, TableNames.MESSAGE_LOG_CONTENT_TABLE); // the reason this is above the send queue is because in case where the user did not give sufficient permissions to From ca9241f32c3ae07b710bc0aa8e808d6b27e89d91 Mon Sep 17 00:00:00 2001 From: Egg-03 <111327101+Egg-03@users.noreply.github.com> Date: Fri, 20 Jun 2025 10:15:32 +0530 Subject: [PATCH 8/9] Use Long types for ID fields in database operations Replaced usage of setString and getString with setLong and getLong for guild, channel, author, and message IDs in all database queries and updates. This ensures IDs are handled as numeric types, improving type safety and consistency with the database schema. --- .../database/DatabaseConnector.java | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/main/java/org/papertrail/database/DatabaseConnector.java b/src/main/java/org/papertrail/database/DatabaseConnector.java index 2b1d3cb1..a8a285e4 100644 --- a/src/main/java/org/papertrail/database/DatabaseConnector.java +++ b/src/main/java/org/papertrail/database/DatabaseConnector.java @@ -26,8 +26,8 @@ public void registerGuildAndChannel(String guildId, String channelId, String tab String sqlStatement = "INSERT INTO "+tableName+" (guild_id, channel_id) VALUES (?, ?)"; try(PreparedStatement psmt = connect.prepareStatement(sqlStatement)){ - psmt.setString(1, guildId); - psmt.setString(2, channelId); + psmt.setLong(1, Long.parseLong(guildId)); + psmt.setLong(2, Long.parseLong(channelId)); psmt.executeUpdate(); } @@ -39,13 +39,13 @@ public String retrieveRegisteredChannelId(String guildId, String tableName) { String channelId = ""; try (PreparedStatement psmt = connect.prepareStatement(sqlStatement)) { - psmt.setString(1, guildId); + psmt.setLong(1, Long.parseLong(guildId)); try (ResultSet rs = psmt.executeQuery()) { while (rs.next()) { // by configuration, there will always be only one channel id row at a time // because registering multiple channels is not allowed - channelId = rs.getString("channel_id"); + channelId = String.valueOf(rs.getLong("channel_id")); } } return channelId; @@ -62,12 +62,12 @@ public String checkGuildRegistration(String guildId, String tableName) { String sqlStatement = "SELECT guild_id FROM " + tableName + " WHERE guild_id = ?"; try (PreparedStatement psmt = connect.prepareStatement(sqlStatement)) { - psmt.setString(1, guildId); + psmt.setLong(1, Long.parseLong(guildId)); try (ResultSet rs = psmt.executeQuery()) { while (rs.next()) { - return rs.getString("guild_id"); + return String.valueOf(rs.getLong("guild_id")); } } @@ -86,11 +86,11 @@ public String checkChannelRegistration(String channelId, String tableName) { String sqlStatement = "SELECT channel_id FROM " + tableName + " WHERE channel_id = ?"; try (PreparedStatement psmt = connect.prepareStatement(sqlStatement)) { - psmt.setString(1, channelId); + psmt.setLong(1, Long.parseLong(channelId)); try (ResultSet rs = psmt.executeQuery()) { while (rs.next()) { - return rs.getString("guild_id"); + return String.valueOf(rs.getLong("guild_id")); } } return null; @@ -105,7 +105,7 @@ public void unregisterGuildAndChannel(String guildId, String tableName) throws S String sqlStatement = "DELETE FROM "+tableName+" WHERE guild_id = ?"; try(PreparedStatement psmt = connect.prepareStatement(sqlStatement)){ - psmt.setString(1, guildId); + psmt.setLong(1, Long.parseLong(guildId)); psmt.executeUpdate(); } } @@ -117,9 +117,9 @@ public void logMessage(String messageId, String messageContent, String authorId, String sqlStatement = "INSERT INTO "+tableName+" (message_id, message_content, author_id) VALUES (?, ?, ?)"; try(PreparedStatement psmt = connect.prepareStatement(sqlStatement)){ - psmt.setString(1, messageId); + psmt.setLong(1, Long.parseLong(messageId)); psmt.setString(2, messageContent); - psmt.setString(3, authorId); + psmt.setLong(3, Long.parseLong(authorId)); psmt.executeUpdate(); } } @@ -132,12 +132,12 @@ public List retrieveAuthorAndMessage(String messageId, String tableName) String authorId = ""; try (PreparedStatement psmt = connect.prepareStatement(sqlStatement)) { - psmt.setString(1, messageId); + psmt.setLong(1, Long.parseLong(messageId)); try (ResultSet rs = psmt.executeQuery()) { if (rs.next()) { // only one message is logged per row per message id messageContent = rs.getString("message_content"); - authorId = rs.getString("author_id"); + authorId = String.valueOf(rs.getLong("author_id")); return List.of(authorId, messageContent); } } @@ -156,11 +156,11 @@ public String checkMessageId(String messageId, String tableName) { String sqlStatement = "SELECT message_id FROM " + tableName + " WHERE message_id = ?"; try (PreparedStatement psmt = connect.prepareStatement(sqlStatement)) { - psmt.setString(1, messageId); + psmt.setLong(1, Long.parseLong(messageId)); try (ResultSet rs = psmt.executeQuery()) { if (rs.next()) { // only one message is logged per row per message id - return rs.getString("message_id"); + return String.valueOf(rs.getLong("message_id")); } } return null; @@ -177,7 +177,7 @@ public void updateMessage(String messageId, String messageContent, String tableN try(PreparedStatement psmt = connect.prepareStatement(sqlStatement)){ psmt.setString(1, messageContent); - psmt.setString(2, messageId); + psmt.setLong(2, Long.parseLong(messageId)); psmt.executeUpdate(); } } @@ -187,7 +187,7 @@ public void deleteMessage(String messageId, String tableName) throws SQLExceptio String sqlStatement = "DELETE FROM "+tableName+" WHERE message_id = ?"; try(PreparedStatement psmt = connect.prepareStatement(sqlStatement)){ - psmt.setString(1, messageId); + psmt.setLong(1, Long.parseLong(messageId)); psmt.executeUpdate(); } } From c9dd984f8278d3af744872d1daf278de505a1e1a Mon Sep 17 00:00:00 2001 From: Egg-03 <111327101+Egg-03@users.noreply.github.com> Date: Fri, 20 Jun 2025 13:41:42 +0530 Subject: [PATCH 9/9] Refactor setup listener and update version to 1.1.0 Replaces SetupListener with BotSetupListener, providing improved setup instructions and updated command names. Updates BotInfoListener to show server and database locations. Bumps version to 1.1.0 and adds new fields in VersionInfo for server and database locations. --- pom.xml | 2 +- .../customlisteners/BotInfoListener.java | 6 +- .../customlisteners/BotSetupListener.java | 77 +++++++++++++++++++ .../customlisteners/SetupListener.java | 60 --------------- .../java/org/papertrail/main/FireRun.java | 4 +- .../org/papertrail/version/VersionInfo.java | 5 +- 6 files changed, 88 insertions(+), 66 deletions(-) create mode 100644 src/main/java/org/papertrail/listeners/customlisteners/BotSetupListener.java delete mode 100644 src/main/java/org/papertrail/listeners/customlisteners/SetupListener.java diff --git a/pom.xml b/pom.xml index f0277e54..11b2fbe5 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 org.egg.papertrail paper-trail-bot - 1.0.0 + 1.1.0 PaperTrail A simple bot for logging all user actions diff --git a/src/main/java/org/papertrail/listeners/customlisteners/BotInfoListener.java b/src/main/java/org/papertrail/listeners/customlisteners/BotInfoListener.java index 2fc513e6..b51a574b 100644 --- a/src/main/java/org/papertrail/listeners/customlisteners/BotInfoListener.java +++ b/src/main/java/org/papertrail/listeners/customlisteners/BotInfoListener.java @@ -26,9 +26,11 @@ public void onSlashCommandInteraction(SlashCommandInteractionEvent event) { eb.addField("🏷️ App Name", "╰┈➤"+VersionInfo.APPNAME, false); eb.addField("⚙️ App Version", "╰┈➤"+VersionInfo.VERSION, false); - eb.addField("🗂️ App Source Code", VersionInfo.PROJECT_LINK, false); + eb.addField("📃 App Source Code", VersionInfo.PROJECT_LINK, false); + eb.addField("🖧 App Server", "╰┈➤"+VersionInfo.SERVER_LOCATION, false); + eb.addField("🛢 App Database", "╰┈➤"+VersionInfo.DATABASE_LOCATION, false); - eb.setFooter(VersionInfo.APPNAME+" is free and open source "); + eb.setFooter(VersionInfo.APPNAME+" "+VersionInfo.VERSION); eb.setTimestamp(Instant.now()); MessageEmbed mb = eb.build(); diff --git a/src/main/java/org/papertrail/listeners/customlisteners/BotSetupListener.java b/src/main/java/org/papertrail/listeners/customlisteners/BotSetupListener.java new file mode 100644 index 00000000..ad288933 --- /dev/null +++ b/src/main/java/org/papertrail/listeners/customlisteners/BotSetupListener.java @@ -0,0 +1,77 @@ +package org.papertrail.listeners.customlisteners; + +import java.awt.Color; +import java.time.Instant; + +import org.papertrail.version.VersionInfo; + +import net.dv8tion.jda.api.EmbedBuilder; +import net.dv8tion.jda.api.entities.MessageEmbed; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.hooks.ListenerAdapter; + +public class BotSetupListener extends ListenerAdapter { + + @Override + public void onSlashCommandInteraction(SlashCommandInteractionEvent event) { + + if (event.getName().equals("setup")) { + + EmbedBuilder eb = new EmbedBuilder(); + eb.setTitle("🛠️ Setup Guide for " + VersionInfo.APPNAME); + eb.setDescription("Welcome to **" + VersionInfo.APPNAME + "**!\nHere's how to get started using the bot in your server."); + eb.setColor(Color.decode("#38e8bc")); + + eb.addField("1️⃣ Register Audit Log Channel", + "- Use `/auditlogchannel-set` to **register the current channel** for receiving audit log updates.\n╰┈➤ User must have `Manage Server` permission.", + false); + + eb.addField("2️⃣ View Registered Audit Log Channel", + "- Use `/auditlogchannel-view` to **check which channel** is currently registered for audit logs.\nThis is helpful if you're unsure where logs are going.\n╰┈➤ User must have `Manage Server` permission.", + false); + + eb.addField("3️⃣ Unregister Audit Log Channel", + "- Use `/auditlogchannel-remove` to **unset the audit log channel** if you wish to stop logging or switch to another one.\n╰┈➤ User must have `Manage Server` permission.", + false); + + eb.addBlankField(false); + + eb.addField("4️⃣ Register Message Log Channel", + "- Use `/messagelogchannel-set` to **register the current channel** for receiving audit log updates.\n╰┈➤ User must have `Manage Server` permission.", + false); + + eb.addField("5️⃣ View Registered Message Log Channel", + "- Use `/messagelogchannel-view` to **check which channel** is currently registered for message logs.\nThis is helpful if you're unsure where logs are going.\n╰┈➤ User must have `Manage Server` permission.", + false); + + eb.addField("6️⃣ Unregister Message Log Channel", + "- Use `/messagelogchannel-remove` to **unset the message log channel** if you wish to stop logging or switch to another one.\n╰┈➤ User must have `Manage Server` permission.", + false); + + eb.addBlankField(false); + + eb.addField("7️⃣ View Server Stats", + "- Use `/stats` to **get useful server information** like member count, channel count, and more.", + false); + + eb.addField("8️⃣ Bot Information", + "- Use `/about` to **view bot details**, including author info and version.", + false); + + String tips = """ + - Make sure the bot has view and message send permissions for the logging channel. + - Commands only work in servers (guilds), not in DMs. + - The bot will lose its configuration if kicked from the server. + - By default, all messages are stored in the database for 30 days, after which the newer ones will replace the older ones."""; + + eb.addField("💡 Tips",tips,false); + eb.addField("📬 Need help?", "Create an issue on [GitHub](" + VersionInfo.PROJECT_ISSUE_LINK+")", false); + eb.setFooter(VersionInfo.APPNAME+" "+VersionInfo.VERSION); + eb.setTimestamp(Instant.now()); + + MessageEmbed mb = eb.build(); + event.replyEmbeds(mb).setEphemeral(false).queue(); + } + } +} + diff --git a/src/main/java/org/papertrail/listeners/customlisteners/SetupListener.java b/src/main/java/org/papertrail/listeners/customlisteners/SetupListener.java deleted file mode 100644 index 39ead7c6..00000000 --- a/src/main/java/org/papertrail/listeners/customlisteners/SetupListener.java +++ /dev/null @@ -1,60 +0,0 @@ -package org.papertrail.listeners.customlisteners; - -import java.awt.Color; -import java.time.Instant; - -import org.papertrail.version.VersionInfo; - -import net.dv8tion.jda.api.EmbedBuilder; -import net.dv8tion.jda.api.entities.MessageEmbed; -import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; -import net.dv8tion.jda.api.hooks.ListenerAdapter; - -public class SetupListener extends ListenerAdapter { - - @Override - public void onSlashCommandInteraction(SlashCommandInteractionEvent event) { - - if (event.getName().equals("setup")) { - - EmbedBuilder eb = new EmbedBuilder(); - eb.setTitle("🛠️ Setup Guide for " + VersionInfo.APPNAME); - eb.setDescription("Welcome to **" + VersionInfo.APPNAME + "**!\nHere's how to get started using the bot in your server."); - eb.setColor(Color.decode("#38e8bc")); - - eb.addField("1️⃣ Register Audit Log Channel", - "- Use `/ralc` to **register the current channel** for receiving audit log updates.\n╰┈➤ User must have `Manage Server` permission.", - false); - - eb.addField("2️⃣ View Registered Channel", - "- Use `/galc` to **check which channel** is currently registered for audit logs.\nThis is helpful if you're unsure where logs are going.\n╰┈➤ User must have `Manage Server` permission.", - false); - - eb.addField("3️⃣ Unregister Audit Log Channel", - "- Use `/ualc` to **unset the audit log channel** if you wish to stop logging or switch to another one.\n╰┈➤ User must have `Manage Server` permission.", - false); - - eb.addField("4️⃣ View Server Stats", - "- Use `/stats` to **get useful server information** like member count, channel count, and more.", - false); - - eb.addField("5️⃣ Bot Information", - "- Use `/about` to **view bot details**, including author info and version.", - false); - - String tips = """ - - Make sure the bot has proper permissions for it to work correctly. - - Commands only work in servers (guilds), not in DMs. - - The bot will lose its configuration if kicked from the server."""; - - eb.addField("💡 Tips",tips,false); - eb.addField("📬 Need help?", "Create an issue on [GitHub](" + VersionInfo.PROJECT_ISSUE_LINK+")", false); - eb.setFooter(VersionInfo.APPNAME+" "+VersionInfo.VERSION); - eb.setTimestamp(Instant.now()); - - MessageEmbed mb = eb.build(); - event.replyEmbeds(mb).setEphemeral(false).queue(); - } - } -} - diff --git a/src/main/java/org/papertrail/main/FireRun.java b/src/main/java/org/papertrail/main/FireRun.java index cd409fa1..14007a7b 100644 --- a/src/main/java/org/papertrail/main/FireRun.java +++ b/src/main/java/org/papertrail/main/FireRun.java @@ -8,7 +8,7 @@ import org.papertrail.database.DatabaseConnector; import org.papertrail.listeners.customlisteners.BotInfoListener; import org.papertrail.listeners.customlisteners.ServerStatListener; -import org.papertrail.listeners.customlisteners.SetupListener; +import org.papertrail.listeners.customlisteners.BotSetupListener; import org.papertrail.listeners.guildlisteners.ServerBoostListener; import org.papertrail.listeners.loglisteners.AuditLogListener; import org.papertrail.listeners.loglisteners.AuditLogCommandListener; @@ -41,7 +41,7 @@ public static void main(String[] args) throws IOException, SQLException { ci.getManager().addEventListener(new ServerStatListener()); ci.getManager().addEventListener(new BotInfoListener()); - ci.getManager().addEventListener(new SetupListener()); + ci.getManager().addEventListener(new BotSetupListener()); /* * This is required only to set up a cron-job to periodically ping this end-point so that diff --git a/src/main/java/org/papertrail/version/VersionInfo.java b/src/main/java/org/papertrail/version/VersionInfo.java index 1c8c33b4..85cea726 100644 --- a/src/main/java/org/papertrail/version/VersionInfo.java +++ b/src/main/java/org/papertrail/version/VersionInfo.java @@ -7,7 +7,10 @@ private VersionInfo() { } public static final String APPNAME = "PaperTrail"; - public static final String VERSION = "v1.0.0"; + public static final String VERSION = "v1.1.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"; + + public static final String SERVER_LOCATION = "Render: Frankfurt(Germany, Europe)"; + public static final String DATABASE_LOCATION = "Aiven: England(UK, Europe)"; }