diff --git a/src/main/java/tech/allydoes/Constants.java b/src/main/java/tech/allydoes/Constants.java index d9fbc49..7bf4583 100644 --- a/src/main/java/tech/allydoes/Constants.java +++ b/src/main/java/tech/allydoes/Constants.java @@ -2,5 +2,5 @@ package tech.allydoes; public class Constants { public static final boolean PRODUCTION = false; - public static final String TESTING_GUILD = ""; + public static final String TESTING_GUILD = "926369143186403329"; } diff --git a/src/main/java/tech/allydoes/Main.java b/src/main/java/tech/allydoes/Main.java index 1ce2c74..2f5fefb 100644 --- a/src/main/java/tech/allydoes/Main.java +++ b/src/main/java/tech/allydoes/Main.java @@ -31,7 +31,7 @@ public class Main { discordManager = new DiscordManager(); databaseManager = new DatabaseManager(); - new Main(8080).start(); + new Main(6123).start(); } public void start() { diff --git a/src/main/java/tech/allydoes/database/DatabaseManager.java b/src/main/java/tech/allydoes/database/DatabaseManager.java index fd3119a..d6033c0 100644 --- a/src/main/java/tech/allydoes/database/DatabaseManager.java +++ b/src/main/java/tech/allydoes/database/DatabaseManager.java @@ -5,6 +5,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import java.sql.*; +import java.util.ArrayList; public class DatabaseManager { private final Logger LOGGER = LogManager.getLogger(DatabaseManager.class); @@ -20,56 +21,56 @@ public class DatabaseManager { String host = dotenv.get("DB_HOST"); String port = dotenv.get("DB_PORT"); - String defaultDbUrl = String.format("jdbc:postgresql://%s:%s/postgres?sslmode=require", host, port); + String defaultDbUrl = String.format("jdbc:postgresql://%s:%s/postgres", host, port); try (Connection conn = DriverManager.getConnection(defaultDbUrl, user, password)) { conn.setAutoCommit(true); - boolean dbExists = false; - try (Statement statement = conn.createStatement()) { - if (statement.execute(Queries.CHECK_IF_DATABASE_EXISTS)) { - ResultSet resultSet = statement.getResultSet(); - resultSet.next(); - dbExists = true; + + try (Statement statement = conn.createStatement(); + ResultSet resultSet = statement.executeQuery(Queries.CHECK_IF_DATABASE_EXISTS)) { + if (resultSet.next()) { + dbExists = resultSet.getBoolean(1); } } if (!dbExists) { LOGGER.debug("Database does not exist. Creating..."); try (Statement statement = conn.createStatement()) { - if (statement.execute(Queries.CREATE_DATABASE)) { - ResultSet resultSet = statement.getResultSet(); - resultSet.next(); - LOGGER.debug("Database created successfully."); - } + // Use executeUpdate for DDL (CREATE DATABASE) - it does not return a ResultSet + statement.executeUpdate(Queries.CREATE_DATABASE); + LOGGER.debug("Database created successfully."); } catch (SQLException e) { LOGGER.error("Failed to create database: {}", e.getMessage()); } - - try (Statement statement = conn.createStatement()) { - if (statement.execute(Queries.CREATE_SERVER_TABLE)) { - ResultSet resultSet = statement.getResultSet(); - resultSet.next(); - LOGGER.debug("Server table created successfully."); - } - } catch (SQLException e) { - LOGGER.error("Failed to create server table: {}", e.getMessage()); - } } else { LOGGER.debug("Database already exists."); } - } catch (Exception e) { - LOGGER.error("Database initialization failed: {}", e.getMessage()); + } catch (SQLException e) { + LOGGER.error("Database initialization failed on default DB: {}", e.getMessage()); + } + + String notifierDbUrl = String.format("jdbc:postgresql://%s:%s/notifier", host, port); + try (Connection conn = DriverManager.getConnection(notifierDbUrl, user, password)) { + try (Statement statement = conn.createStatement()) { + statement.executeUpdate(Queries.CREATE_SERVER_TABLE); + LOGGER.debug("Server table verified/created successfully."); + } catch (SQLException e) { + LOGGER.error("Failed to create server table: {}", e.getMessage()); + } + } catch (SQLException e) { + LOGGER.error("Failed to connect to 'notifier' database: {}", e.getMessage()); } } - public void getAllNotifiers() { + public ArrayList getAllNotifiers() { String user = dotenv.get("DB_USER"); String password = dotenv.get("DB_PASSWORD"); String host = dotenv.get("DB_HOST"); String port = dotenv.get("DB_PORT"); - String defaultDbUrl = String.format("jdbc:postgresql://%s:%s/postgres?sslmode=require", host, port); + ArrayList notified = new ArrayList<>(); + String defaultDbUrl = String.format("jdbc:postgresql://%s:%s/notifier", host, port); try (Connection conn = DriverManager.getConnection(defaultDbUrl, user, password)) { conn.setAutoCommit(true); @@ -81,11 +82,14 @@ public class DatabaseManager { String channelId = resultSet.getString("channel_id"); String messageId = resultSet.getString("message_id"); LOGGER.debug("Notifier for guild {}, channel {}, message {}", guildId, channelId, messageId); + notified.add(new Notified(guildId, channelId, messageId)); } + return notified; } } catch (SQLException e) { LOGGER.error("getAllNotifiers: Failed to connect: {}", e.getMessage()); } + return null; } public void putNotifier(String guildId, String channelId, String messageId) { @@ -94,7 +98,7 @@ public class DatabaseManager { String host = dotenv.get("DB_HOST"); String port = dotenv.get("DB_PORT"); - String defaultDbUrl = String.format("jdbc:postgresql://%s:%s/postgres?sslmode=require", host, port); + String defaultDbUrl = String.format("jdbc:postgresql://%s:%s/notifier", host, port); try (Connection conn = DriverManager.getConnection(defaultDbUrl, user, password)) { conn.setAutoCommit(true); @@ -110,4 +114,6 @@ public class DatabaseManager { LOGGER.error("putNotifier: Failed to connect: {}", e.getMessage()); } } + + public record Notified(String guildId, String channelId, String messageId) {} } diff --git a/src/main/java/tech/allydoes/database/Queries.java b/src/main/java/tech/allydoes/database/Queries.java index c912d6a..10e8d78 100644 --- a/src/main/java/tech/allydoes/database/Queries.java +++ b/src/main/java/tech/allydoes/database/Queries.java @@ -1,8 +1,8 @@ package tech.allydoes.database; public class Queries { - public static final String CHECK_IF_DATABASE_EXISTS = "SELECT 1 FROM pg_database WHERE datname = notifier"; - public static final String CREATE_DATABASE = "CREATE DATABASE IF NOT EXISTS notifier"; + public static final String CHECK_IF_DATABASE_EXISTS = "SELECT 1 FROM pg_database WHERE datname = 'notifier'"; + public static final String CREATE_DATABASE = "CREATE DATABASE notifier"; public static final String CREATE_SERVER_TABLE = "CREATE TABLE IF NOT EXISTS notifier_channels (guild_id VARCHAR(22) PRIMARY KEY, channel_id VARCHAR(22), message_id VARCHAR(22))"; public static final String INSERT_SERVER_CHANNEL = "INSERT INTO notifier_channels (guild_id, channel_id, message_id) VALUES (?, ?, ?)"; public static final String DELETE_SERVER_CHANNEL = "DELETE FROM notifier_channels WHERE message_id = ?"; diff --git a/src/main/java/tech/allydoes/discord/DiscordManager.java b/src/main/java/tech/allydoes/discord/DiscordManager.java index 3ba8de8..2d02163 100644 --- a/src/main/java/tech/allydoes/discord/DiscordManager.java +++ b/src/main/java/tech/allydoes/discord/DiscordManager.java @@ -5,13 +5,18 @@ import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.JDABuilder; import net.dv8tion.jda.api.entities.Activity; import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.requests.GatewayIntent; import net.dv8tion.jda.api.requests.restaction.CommandListUpdateAction; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import tech.allydoes.Constants; +import tech.allydoes.Main; +import tech.allydoes.database.DatabaseManager; import tech.allydoes.discord.commands.SaveChannelCommand; +import tech.allydoes.discord.listener.SlashCommandInteractionListener; +import java.util.ArrayList; import java.util.HashMap; public class DiscordManager { @@ -28,6 +33,7 @@ public class DiscordManager { String botToken = Constants.PRODUCTION ? dotenv.get("DISCORD_TOKEN") : dotenv.get("TESTING_TOKEN"); jda = JDABuilder .create(botToken, GatewayIntent.GUILD_MESSAGES) + .addEventListeners(new SlashCommandInteractionListener()) .build() .awaitReady(); registerSlashCommands(); @@ -65,6 +71,33 @@ public class DiscordManager { updateAction.queue(); } + public void setDoorStatus(Status status) { + ArrayList notified = Main.getDatabaseManager().getAllNotifiers(); + + for (DatabaseManager.Notified notifiedEntry : notified) { + try { + Message message = getMessage(notifiedEntry.channelId(), notifiedEntry.messageId()); + switch (status) { + case OPEN: + message.editMessageEmbeds(Embeds.createOpenLabStatus()).queue(); + break; + case CLOSED: + message.editMessageEmbeds(Embeds.createClosedLabStatus()).queue(); + break; + case UNKNOWN: + message.editMessageEmbeds(Embeds.createUnknownLabStatus()).queue(); + break; + } + } catch (Exception e) { + LOGGER.error("setDoorStatus: Failed to edit message: {}", e.getMessage()); + } + } + } + + private Message getMessage(String channelID, String messageID) { + return jda.getTextChannelById(channelID).retrieveMessageById(messageID).complete(); + } + public Command getCommand(String command) { return commands.get(command); } @@ -72,4 +105,17 @@ public class DiscordManager { public JDA getJDA() { return jda; } + + public enum Status { + OPEN(0), CLOSED(1), UNKNOWN(2); + + private final int code; + Status(int code) { this.code = code; } + public static Status fromCode(int code) { + for (Status s : Status.values()) { + if (s.code == code) return s; + } + throw new IllegalArgumentException("Invalid code: " + code); + } + } } diff --git a/src/main/java/tech/allydoes/discord/Embeds.java b/src/main/java/tech/allydoes/discord/Embeds.java index 704bcbd..efd3ccb 100644 --- a/src/main/java/tech/allydoes/discord/Embeds.java +++ b/src/main/java/tech/allydoes/discord/Embeds.java @@ -14,4 +14,20 @@ public class Embeds { .setTimestamp(Instant.now()) .build(); } + public static MessageEmbed createOpenLabStatus() { + return new EmbedBuilder() + .setTitle("Lab is open!") + .setDescription("Feel free to come at work!") + .setColor(0x00FF00) + .setTimestamp(Instant.now()) + .build(); + } + public static MessageEmbed createClosedLabStatus() { + return new EmbedBuilder() + .setTitle("Lab is closed!") + .setDescription("Request for the lab to be opened.") + .setColor(0xFF0000) + .setTimestamp(Instant.now()) + .build(); + } } diff --git a/src/main/java/tech/allydoes/discord/listener/SlashCommandInteractionListener.java b/src/main/java/tech/allydoes/discord/listener/SlashCommandInteractionListener.java new file mode 100644 index 0000000..5bc2731 --- /dev/null +++ b/src/main/java/tech/allydoes/discord/listener/SlashCommandInteractionListener.java @@ -0,0 +1,18 @@ +package tech.allydoes.discord.listener; + +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.hooks.ListenerAdapter; +import tech.allydoes.Constants; +import tech.allydoes.Main; +import tech.allydoes.discord.Command; +import tech.allydoes.discord.DiscordManager; + +public class SlashCommandInteractionListener extends ListenerAdapter { + @Override + public void onSlashCommandInteraction(SlashCommandInteractionEvent event) { + DiscordManager discordManager = Main.getDiscordManager(); + Command command = discordManager.getCommand(event.getName()); + if (command == null) return; + command.processSlashCommandInteractionEvent(event); + } +} diff --git a/src/main/java/tech/allydoes/web/HttpServerHandler.java b/src/main/java/tech/allydoes/web/HttpServerHandler.java index 107b09b..a505b6f 100644 --- a/src/main/java/tech/allydoes/web/HttpServerHandler.java +++ b/src/main/java/tech/allydoes/web/HttpServerHandler.java @@ -10,9 +10,7 @@ import io.netty.handler.codec.http.*; import io.netty.util.CharsetUtil; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import tech.allydoes.leaderboards.handlers.GET.*; -import tech.allydoes.leaderboards.handlers.POST.SetPlayerProfile; -import tech.allydoes.leaderboards.handlers.POST.SetScore; +import tech.allydoes.web.POST.PostStatus; import java.util.HashMap; import java.util.List; @@ -27,7 +25,7 @@ public class HttpServerHandler extends SimpleChannelInboundHandler> parameters) { - int status = Integer.parseInt(parameters.get(STATUS).getFirst()); + int statusInt = Integer.parseInt(parameters.get(STATUS).getFirst()); + DiscordManager.Status status = DiscordManager.Status.fromCode(statusInt); + Main.getDiscordManager().setDoorStatus(status); + return channelHandlerContext.writeAndFlush(new DefaultFullHttpResponse(request.protocolVersion(), HttpResponseStatus.OK)); } @Override public String getRequestName() { - return "PostStatus"; + return "/PostStatus"; } @Override