diff --git a/src/main/java/com/alttd/buttonManager/buttons/remindMeConfirm/ButtonRemindMeConfirm.java b/src/main/java/com/alttd/buttonManager/buttons/remindMeConfirm/ButtonRemindMeConfirm.java index 9ab6d7c..f8ac61c 100644 --- a/src/main/java/com/alttd/buttonManager/buttons/remindMeConfirm/ButtonRemindMeConfirm.java +++ b/src/main/java/com/alttd/buttonManager/buttons/remindMeConfirm/ButtonRemindMeConfirm.java @@ -53,17 +53,7 @@ public class ButtonRemindMeConfirm extends DiscordButton { return false; } - reminder = new Reminder( - id, - reminder.title(), - reminder.description(), - reminder.userId(), - reminder.guildId(), - reminder.channelId(), - reminder.messageId(), - reminder.shouldRepeat(), - reminder.creationDate(), - reminder.remindDate()); + reminder = Reminder.reCreateReminder(id, reminder); ReminderScheduler instance = ReminderScheduler.getInstance(event.getJDA()); if (instance == null) { diff --git a/src/main/java/com/alttd/database/DatabaseTables.java b/src/main/java/com/alttd/database/DatabaseTables.java index cce08de..a5d99a3 100644 --- a/src/main/java/com/alttd/database/DatabaseTables.java +++ b/src/main/java/com/alttd/database/DatabaseTables.java @@ -111,6 +111,8 @@ public class DatabaseTables { "should_repeat TINYINT(1) NOT NULL, " + "creation_date LONG NOT NULL, " + "remind_date LONG NOT NULL, " + + "reminder_type INT NOT NULL default (-1), " + + "data BLOB NULL default NULL, " + "PRIMARY KEY (id)" + ")"; try { diff --git a/src/main/java/com/alttd/database/queries/QueriesReminders/QueriesReminders.java b/src/main/java/com/alttd/database/queries/QueriesReminders/QueriesReminders.java index 015e119..71acdf0 100644 --- a/src/main/java/com/alttd/database/queries/QueriesReminders/QueriesReminders.java +++ b/src/main/java/com/alttd/database/queries/QueriesReminders/QueriesReminders.java @@ -3,18 +3,16 @@ package com.alttd.database.queries.QueriesReminders; import com.alttd.database.Database; import com.alttd.util.Logger; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; +import java.io.IOException; +import java.sql.*; import java.util.ArrayList; public class QueriesReminders { public static int storeReminder(Reminder reminder) { String sql = "INSERT INTO new_reminders " + - "(title, description, user_id, guild_id, channel_id, message_id, should_repeat, creation_date, remind_date) " + - "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"; + "(title, description, user_id, guild_id, channel_id, message_id, should_repeat, creation_date, remind_date, reminder_type, data) " + + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; try { PreparedStatement preparedStatement = Database.getDatabase().getConnection().prepareStatement(sql, Statement.RETURN_GENERATED_KEYS); @@ -27,6 +25,8 @@ public class QueriesReminders { preparedStatement.setInt(7, reminder.shouldRepeat() ? 1 : 0); preparedStatement.setLong(8, reminder.creationDate()); preparedStatement.setLong(9, reminder.remindDate()); + preparedStatement.setInt(10, reminder.reminderType().getId()); + preparedStatement.setBytes(11, reminder.data()); if (preparedStatement.executeUpdate() == 1) { ResultSet generatedKeys = preparedStatement.getGeneratedKeys(); @@ -42,13 +42,13 @@ public class QueriesReminders { return -1; } - public static int updateReminderDate(Reminder reminder) { + public static int updateReminderDate(long reminderDate, int reminderId) { String sql = "UPDATE new_reminders SET remind_date = ? WHERE id = ?"; try { PreparedStatement preparedStatement = Database.getDatabase().getConnection().prepareStatement(sql, Statement.RETURN_GENERATED_KEYS); - preparedStatement.setLong(1, reminder.remindDate()); - preparedStatement.setInt(2, reminder.id()); + preparedStatement.setLong(1, reminderDate); + preparedStatement.setInt(2, reminderId); if (preparedStatement.executeUpdate() == 1) { ResultSet generatedKeys = preparedStatement.getGeneratedKeys(); @@ -106,7 +106,16 @@ public class QueriesReminders { boolean shouldRepeat = resultSet.getInt("should_repeat") == 1; long creationDate = resultSet.getLong("creation_date"); long remindDate = resultSet.getLong("remind_date"); - return new Reminder(id, title, desc, userId, guildId, channelId, messageId, shouldRepeat, creationDate, remindDate); + ReminderType reminderType = ReminderType.getReminder(resultSet.getInt("reminder_type")); + byte[] data = null; + + try { + data = resultSet.getBlob("data").getBinaryStream().readAllBytes(); + } catch (IOException e) { + Logger.warning("Unable to read data for reminder with id: " + id); + } + + return new Reminder(id, title, desc, userId, guildId, channelId, messageId, shouldRepeat, creationDate, remindDate, reminderType, data); } } diff --git a/src/main/java/com/alttd/database/queries/QueriesReminders/Reminder.java b/src/main/java/com/alttd/database/queries/QueriesReminders/Reminder.java index 6cb9934..c924030 100644 --- a/src/main/java/com/alttd/database/queries/QueriesReminders/Reminder.java +++ b/src/main/java/com/alttd/database/queries/QueriesReminders/Reminder.java @@ -6,7 +6,24 @@ import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; public record Reminder (int id, String title, String description, long userId, long guildId, long channelId, - long messageId, boolean shouldRepeat, long creationDate, long remindDate) { + long messageId, boolean shouldRepeat, long creationDate, long remindDate, ReminderType reminderType, byte[] data) { + + public static Reminder reCreateReminder(int id, Reminder reminder) { + return new Reminder( + id, + reminder.title(), + reminder.description(), + reminder.userId(), + reminder.guildId(), + reminder.channelId(), + reminder.messageId(), + reminder.shouldRepeat(), + reminder.creationDate(), + reminder.remindDate(), + reminder.reminderType(), + reminder.data()); + } + public TextChannel getChannel(JDA jda) { Guild guildById = getGuild(jda); if (guildById == null) diff --git a/src/main/java/com/alttd/database/queries/QueriesReminders/ReminderType.java b/src/main/java/com/alttd/database/queries/QueriesReminders/ReminderType.java new file mode 100644 index 0000000..858ece7 --- /dev/null +++ b/src/main/java/com/alttd/database/queries/QueriesReminders/ReminderType.java @@ -0,0 +1,24 @@ +package com.alttd.database.queries.QueriesReminders; + +public enum ReminderType { + NONE(-1), + MANUAL(0), + APPEAL(1); + private final int id; + + ReminderType(int id) { + this.id = id; + } + + public int getId() { + return id; + } + + public static ReminderType getReminder(int id) { + ReminderType[] values = ReminderType.values(); + if (values.length < id) { + return NONE; + } + return values[id]; + } +} diff --git a/src/main/java/com/alttd/listeners/AppealRepost.java b/src/main/java/com/alttd/listeners/AppealRepost.java index 31e80ea..588a7c4 100644 --- a/src/main/java/com/alttd/listeners/AppealRepost.java +++ b/src/main/java/com/alttd/listeners/AppealRepost.java @@ -1,20 +1,30 @@ package com.alttd.listeners; -import com.alttd.AltitudeBot; import com.alttd.buttonManager.ButtonManager; import com.alttd.database.queries.QueriesAssignAppeal; +import com.alttd.database.queries.QueriesReminders.QueriesReminders; +import com.alttd.database.queries.QueriesReminders.Reminder; +import com.alttd.database.queries.QueriesReminders.ReminderType; +import com.alttd.schedulers.ReminderScheduler; import com.alttd.util.Logger; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.entities.MessageEmbed; +import net.dv8tion.jda.api.entities.channel.concrete.ThreadChannel; import net.dv8tion.jda.api.events.message.MessageReceivedEvent; import net.dv8tion.jda.api.hooks.ListenerAdapter; import net.dv8tion.jda.api.interactions.components.buttons.Button; +import net.dv8tion.jda.api.requests.restaction.MessageCreateAction; import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; import java.util.List; +import java.util.concurrent.TimeUnit; public class AppealRepost extends ListenerAdapter { @@ -89,11 +99,63 @@ public class AppealRepost extends ListenerAdapter { Logger.warning("Unable to get a button for appeals"); return; } - message.getChannel().sendMessageEmbeds(embed).queue(res -> { + MessageCreateAction messageCreateAction = message.getChannel().sendMessageEmbeds(embed); + if (member != null) + messageCreateAction = messageCreateAction.mentionUsers(member.getIdLong()); + messageCreateAction.queue(res -> { res.editMessageComponents().setActionRow(reminderAccepted, reminderInProgress, reminderDenied).queue(); - res.createThreadChannel("Appeal").queue(); + res.createThreadChannel("Appeal").queue(( + threadChannel -> scheduleReminder(res, member, threadChannel)), + failure -> Logger.warning("Unable to create thread channel so won't schedule reminder...")); }); message.delete().queue(); + + } + + private void scheduleReminder(Message message, @Nullable Member member, ThreadChannel threadChannel) { + String memberMention = member == null ? "the appeals team" : member.getAsMention(); + ByteArrayOutputStream outputStream = null; + if (member != null) { + outputStream = new ByteArrayOutputStream(); + DataOutputStream out = new DataOutputStream(outputStream); + try { + out.writeLong(member.getIdLong()); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + Reminder reminder = new Reminder( + -1, + "Reminder", + "I am reminding " + memberMention + " that we aim to resolve appeals within 24h or in more complex circumstances 48 hours!", + member == null ? 0 : member.getIdLong(), + message.getGuild().getIdLong(), + threadChannel.getIdLong(), + message.getIdLong(), + true, + System.currentTimeMillis(), + System.currentTimeMillis() + TimeUnit.DAYS.toMillis(1), + ReminderType.APPEAL, + outputStream == null ? null : outputStream.toByteArray() + ); + + int id = QueriesReminders.storeReminder(reminder); + if (id == 0) { + Logger.warning("Unable to store reminder for appeal with message id: " + message.getId()); + return; + } + + reminder = Reminder.reCreateReminder(id, reminder); + + ReminderScheduler instance = ReminderScheduler.getInstance(message.getJDA()); + if (instance == null) { + QueriesReminders.removeReminder(reminder.id()); + Logger.warning("Unable to start reminder, removing it from the database..."); + return; + } + + instance.addReminder(reminder); } } diff --git a/src/main/java/com/alttd/modalManager/modals/ModalRemindMe.java b/src/main/java/com/alttd/modalManager/modals/ModalRemindMe.java index 01d8186..9f8ea95 100644 --- a/src/main/java/com/alttd/modalManager/modals/ModalRemindMe.java +++ b/src/main/java/com/alttd/modalManager/modals/ModalRemindMe.java @@ -3,6 +3,7 @@ package com.alttd.modalManager.modals; import com.alttd.buttonManager.ButtonManager; import com.alttd.buttonManager.buttons.remindMeConfirm.ButtonRemindMeConfirm; import com.alttd.database.queries.QueriesReminders.Reminder; +import com.alttd.database.queries.QueriesReminders.ReminderType; import com.alttd.modalManager.DiscordModal; import com.alttd.util.Util; import net.dv8tion.jda.api.EmbedBuilder; @@ -73,7 +74,9 @@ public class ModalRemindMe extends DiscordModal { 0, false, new Date().getTime(), - remindMeData.timestamp); + remindMeData.timestamp, + ReminderType.MANUAL, + null); Button remindMeConfirm = buttonManager.getButtonFor("remind_me_confirm"); Button remindMeCancel = buttonManager.getButtonFor("remind_me_cancel"); diff --git a/src/main/java/com/alttd/schedulers/ReminderScheduler.java b/src/main/java/com/alttd/schedulers/ReminderScheduler.java index 791e84c..a795b53 100644 --- a/src/main/java/com/alttd/schedulers/ReminderScheduler.java +++ b/src/main/java/com/alttd/schedulers/ReminderScheduler.java @@ -10,7 +10,12 @@ import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; import net.dv8tion.jda.api.requests.RestAction; +import net.dv8tion.jda.api.requests.restaction.MessageCreateAction; +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.IOException; +import java.io.InputStream; import java.util.ArrayList; import java.util.Comparator; import java.util.Date; @@ -56,20 +61,21 @@ public class ReminderScheduler { nextReminder = reminders.get(0); } - public synchronized void removeReminder(Reminder reminder) { + public synchronized void removeReminder(Reminder reminder, boolean removeFromDatabase) { reminders.remove(reminder); if (reminders.size() == 0) nextReminder = null; else nextReminder = reminders.get(0); - QueriesReminders.removeReminder(reminder.id()); + if (removeFromDatabase) + QueriesReminders.removeReminder(reminder.id()); } public synchronized void removeReminder(long messageId) { reminders.stream() .filter(reminder -> reminder.messageId() == messageId) .findAny() - .ifPresent(this::removeReminder); + .ifPresent(reminder -> removeReminder(reminder, true)); } private class ReminderRun implements Runnable { @@ -95,14 +101,17 @@ public class ReminderScheduler { nextReminder.guildId(), nextReminder.channelId(), nextReminder.messageId(), - nextReminder.shouldRepeat(), + true, nextReminder.creationDate(), - nextReminder.remindDate() + TimeUnit.DAYS.toMillis(1)); + nextReminder.remindDate() + TimeUnit.DAYS.toMillis(1), + nextReminder.reminderType(), + nextReminder.data()); + removeReminder(nextReminder, false); addReminder(repeatedReminder); - QueriesReminders.updateReminderDate(repeatedReminder); + QueriesReminders.updateReminderDate(nextReminder.remindDate() + TimeUnit.DAYS.toMillis(1), nextReminder.id()); } else - removeReminder(nextReminder); + removeReminder(nextReminder, true); } } @@ -123,7 +132,33 @@ public class ReminderScheduler { private void sendEmbed(Reminder reminder, TextChannel channel, EmbedBuilder embedBuilder, Member member) { embedBuilder.setAuthor(member.getEffectiveName(), null, member.getEffectiveAvatarUrl()); - channel.sendMessageEmbeds(embedBuilder.build()).queue(RestAction.getDefaultSuccess(), Util::handleFailure); + switch (reminder.reminderType()) { + case NONE, MANUAL -> { + channel.sendMessageEmbeds(embedBuilder.build()).queue(RestAction.getDefaultSuccess(), Util::handleFailure); + } + case APPEAL -> { + if (reminder.data() == null) + break; + InputStream inputStream = new ByteArrayInputStream(reminder.data()); + DataInputStream dataInputStream = new DataInputStream(inputStream); + long userId = 0; + try { + userId = dataInputStream.readLong(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + dataInputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + MessageCreateAction messageCreateAction = channel.sendMessageEmbeds(embedBuilder.build()); + if (userId != 0) + messageCreateAction = messageCreateAction.mentionUsers(userId); + messageCreateAction.queue(RestAction.getDefaultSuccess(), Util::handleFailure); + } + } } private void sendEmbed(Reminder reminder, TextChannel channel, EmbedBuilder embedBuilder) {