From 85cab30b5545fa590694766a236a205e5107cb81 Mon Sep 17 00:00:00 2001 From: William Harrison <87287585+wdhdev@users.noreply.github.com> Date: Tue, 3 Dec 2024 12:24:00 +0800 Subject: [PATCH] fix formatting issues + add recurring reminders --- src/commands/reminders/info.ts | 3 ++- src/commands/reminders/reminders.ts | 6 +++--- src/commands/reminders/remindme.ts | 26 +++++++++++++++++++++----- src/events/client/ready.ts | 22 +++++++++++++--------- src/models/Reminder.ts | 7 ++++++- src/util/setReminder.ts | 4 ++-- 6 files changed, 47 insertions(+), 21 deletions(-) diff --git a/src/commands/reminders/info.ts b/src/commands/reminders/info.ts index 37f8a2f..76ce4fd 100644 --- a/src/commands/reminders/info.ts +++ b/src/commands/reminders/info.ts @@ -47,7 +47,8 @@ const command: Command = { .addFields( { name: "Reason", value: reminder.reason }, { name: "Set", value: `<t:${reminder.reminder_set.toString().slice(0, -3)}:f>`, inline: true }, - { name: "Due", value: `<t:${(reminder.reminder_set + reminder.delay).toString().slice(0, -3)}:R>`, inline: true } + { name: "Due", value: `<t:${(Number(reminder.reminder_set) + reminder.delay).toString().slice(0, -3)}:R>`, inline: true }, + { name: "Recurring", value: reminder?.recurring ? emoji.tick : emoji.cross, inline: true } ) await interaction.editReply({ embeds: [info] }); diff --git a/src/commands/reminders/reminders.ts b/src/commands/reminders/reminders.ts index e4147bc..31c57c4 100644 --- a/src/commands/reminders/reminders.ts +++ b/src/commands/reminders/reminders.ts @@ -39,13 +39,13 @@ const command: Command = { return; } - // Sort reminders by due date - reminders = reminders.sort((a: any, b: any) => a.due - b.due); + // Sort reminders by when they were set + reminders = reminders.sort((a: any, b: any) => Number(a.reminder_set) - Number(b.reminder_set)); const list = new Discord.EmbedBuilder() .setColor(client.config.embeds.default as ColorResolvable) .setTitle("Your Reminders") - .setDescription(cap(reminders.map(r => `\`${r.reminder_id}\` (<t:${(r.reminder_set + r.delay).toString().slice(0, -3)}:R>):\n*${!fullReasons ? cap(r.reason, 100): r.reason}*`).join("\n"), 4000)) + .setDescription(cap(reminders.map(r => `\`${r.reminder_id}\` (<t:${(Number(r.reminder_set) + r.delay).toString().slice(0, -3)}:R>):\n*${!fullReasons ? cap(r.reason, 100): r.reason}*`).join("\n"), 4000)) await interaction.editReply({ embeds: [list] }); } catch(err) { diff --git a/src/commands/reminders/remindme.ts b/src/commands/reminders/remindme.ts index 57323e7..d0fa4ce 100644 --- a/src/commands/reminders/remindme.ts +++ b/src/commands/reminders/remindme.ts @@ -23,7 +23,7 @@ const command: Command = { type: 3, name: "reason", description: "The reason for the reminder.", - max_length: 1000, + max_length: 512, required: true }, @@ -32,6 +32,13 @@ const command: Command = { name: "send_in_channel", description: "Send the reminder in this channel, instead of in a direct message.", required: false + }, + + { + type: 5, + name: "recurring", + description: "Set the reminder to automatically repeat.", + required: false } ], default_member_permissions: null, @@ -45,6 +52,7 @@ const command: Command = { let time: number | string = interaction.options.get("time")?.value as string; const reason = interaction.options.get("reason")?.value as string; const sendInChannel = interaction.options.get("send_in_channel")?.value || false as boolean; + const recurring = interaction.options.get("recurring")?.value || false as boolean; const reminders = await Reminder.find({ user: interaction.user.id }); @@ -102,20 +110,28 @@ const command: Command = { channel: interaction.channel?.id ? interaction.channel?.id : null, delay: time, reason: reason, - send_in_channel: sendInChannel + send_in_channel: sendInChannel, + recurring }).save() if(time < client.config.reminders.timeTillSet) { client.reminders.set(`${interaction.user.id}-${reminder.reminder_id}`, setTimeout(async () => { client.reminders.delete(`${interaction.user.id}-${reminder.reminder_id}`); - await Reminder.findOneAndDelete({ reminder_id: reminder.reminder_id, user: interaction.user.id }); + + if(reminder?.recurring) { + reminder.reminder_set = Date.now().toString(); + await reminder.save(); + } else { + await reminder.deleteOne(); + } const embed = new Discord.EmbedBuilder() .setColor(client.config.embeds.default as ColorResolvable) .setTitle("Reminder") .setDescription(reason) .addFields ( - { name: "Set", value: `<t:${reminder.reminder_set.toString().slice(0, -3)}:f> (<t:${reminder.reminder_set.toString().slice(0, -3)}:R>)` } + { name: "Set", value: `<t:${reminder.reminder_set.toString().slice(0, -3)}:f> (<t:${reminder.reminder_set.toString().slice(0, -3)}:R>)` }, + { name: "Recurring", value: reminder?.recurring ? emoji.tick : emoji.cross } ) .setFooter({ text: `ID: ${reminder.reminder_id}` }) .setTimestamp() @@ -149,7 +165,7 @@ const command: Command = { const reminderSet = new Discord.EmbedBuilder() .setColor(client.config.embeds.default as ColorResolvable) - .setDescription(`${emoji.tick} Your reminder has been set for <t:${(reminder.reminder_set + reminder.delay).toString().slice(0, -3)}:f> with ID \`${reminder.reminder_id}\`!`) + .setDescription(`${emoji.tick} Your reminder has been set for <t:${(Number(reminder.reminder_set) + reminder.delay).toString().slice(0, -3)}:f> with ID \`${reminder.reminder_id}\`${reminder?.recurring ? " and will recur until cancelled." : "."}`) await interaction.editReply({ embeds: [reminderSet] }); } catch(err) { diff --git a/src/events/client/ready.ts b/src/events/client/ready.ts index c30340d..58d3c7b 100644 --- a/src/events/client/ready.ts +++ b/src/events/client/ready.ts @@ -19,9 +19,9 @@ const event: Event = { await globalCommands(client); // Manage timeouts - async function manageExistingTimeouts() { + async function manageExistingReminders() { let reminders = await Reminder.find({}); - const dueReminders = reminders.filter(reminder => (reminder.reminder_set + reminder.delay) <= Date.now().toString()); + const dueReminders = reminders.filter(reminder => (Number(reminder.reminder_set) + reminder.delay) <= Date.now()); for(const reminder of dueReminders) { await reminder.deleteOne(); @@ -33,37 +33,41 @@ const event: Event = { .setDescription(reminder.reason) .addFields ( { name: "Set", value: `<t:${reminder.reminder_set.toString().slice(0, -3)}:f>`, inline: true }, - { name: "Overdue Since", value: `<t:${(reminder.reminder_set + reminder.delay).toString().slice(0, -3)}:R>`, inline: true } + { name: "Overdue Since", value: `<t:${(Number(reminder.reminder_set) + reminder.delay).toString().slice(0, -3)}:R>`, inline: true } ) .setFooter({ text: `ID: ${reminder.reminder_id}` }) .setTimestamp() + const recurring = new EmbedBuilder() + .setColor(client.config.embeds.default as ColorResolvable) + .setDescription("This reminder was a recurring reminder, however since it was sent overdue, it has been reset, you will need to set it again if you want it to continue.") + if(reminder?.send_in_channel && reminder.channel) { try { const channel = client.channels.cache.get(reminder.channel) as TextChannel; if(!channel) throw "Channel not found."; - await channel.send({ content: `<@${reminder.user}>`, embeds: [embed] }); + await channel.send({ content: `<@${reminder.user}>`, embeds: reminder?.recurring ? [embed, recurring] : [embed] }); } catch { try { const user = client.users.cache.get(reminder.user); - await user?.send({ embeds: [embed] }); + await user?.send({ embeds: reminder?.recurring ? [embed, recurring] : [embed] }); } catch {} } } else { try { const user = client.users.cache.get(reminder.user); - await user?.send({ embeds: [embed] }); + await user?.send({ embeds: reminder?.recurring ? [embed, recurring] : [embed] }); } catch { try { const channel = client.channels.cache.get(reminder.channel) as TextChannel; if(!channel) return; - await channel.send({ content: `<@${reminder.user}>`, embeds: [embed] }); + await channel.send({ content: `<@${reminder.user}>`, embeds: reminder?.recurring ? [embed, recurring] : [embed] }); } catch {} } } @@ -74,11 +78,11 @@ const event: Event = { } } - manageExistingTimeouts().then(async () => { + manageExistingReminders().then(async () => { setInterval(async () => { const reminders = await Reminder.find({}); - if(reminders.length === 0) return; + if(!reminders.length) return; for(const reminder of reminders) { if(client.reminders.get(`${reminder.user}-${reminder.reminder_id}`)) continue; diff --git a/src/models/Reminder.ts b/src/models/Reminder.ts index 1aa8cc0..60eba2a 100644 --- a/src/models/Reminder.ts +++ b/src/models/Reminder.ts @@ -29,6 +29,7 @@ export interface Reminder extends Document { reminder_set: string; reason: string; send_in_channel?: boolean; + recurring?: boolean; } const schema = new Schema<Reminder>( @@ -50,7 +51,7 @@ const schema = new Schema<Reminder>( }, channel: { type: String, - required: false, + required: true, set: (value: string) => encrypt(value), get: (value: string) => decrypt(value) }, @@ -75,6 +76,10 @@ const schema = new Schema<Reminder>( send_in_channel: { type: Boolean, default: false + }, + recurring: { + type: Boolean, + default: false } }, { timestamps: true } diff --git a/src/util/setReminder.ts b/src/util/setReminder.ts index 2ecdc26..7a4f012 100644 --- a/src/util/setReminder.ts +++ b/src/util/setReminder.ts @@ -5,7 +5,7 @@ import ExtendedClient from "../classes/ExtendedClient"; import { Reminder } from "../models/Reminder"; export default async function (reminder: Reminder, client: ExtendedClient): Promise<Boolean> { - const delay = Number(reminder.reminder_set + reminder.delay) - Date.now(); + const delay = Number(Number(reminder.reminder_set) + reminder.delay) - Date.now(); if(delay > client.config.reminders.timeTillSet) return false; @@ -23,7 +23,7 @@ export default async function (reminder: Reminder, client: ExtendedClient): Prom .setFooter({ text: `ID: ${reminder.reminder_id}` }) .setTimestamp() - if(reminder?.send_in_channel && reminder?.channel) { + if(reminder?.send_in_channel && reminder.channel) { try { const channel = client.channels.cache.get(reminder.channel) as TextChannel;