diff --git a/src/events/client/ready.ts b/src/events/client/ready.ts index 4621ee6..75b3b63 100644 --- a/src/events/client/ready.ts +++ b/src/events/client/ready.ts @@ -3,4 +3,7 @@ export const once = true; /** https://discord.js.org/#/docs/discord.js/main/class/Client?scrollTo=e-ready */ export default async () => { console.log('Connected to Discord!'); + + // Restart all the timeout about reminders here + // TODO: Reminders timeout }; diff --git a/src/utils/client.ts b/src/utils/client.ts index 9725d9c..91d5285 100644 --- a/src/utils/client.ts +++ b/src/utils/client.ts @@ -58,6 +58,7 @@ const initDatabase = (db: Database) => { channel_id INTEGER, \ creation_date INTEGER, \ user_id INTEGER, \ - guild_id INTEGER \ + guild_id INTEGER, \ + timeout_id INTEGER \ );'); }; diff --git a/src/utils/reminder.ts b/src/utils/reminder.ts index cab23df..7c53755 100644 --- a/src/utils/reminder.ts +++ b/src/utils/reminder.ts @@ -1,12 +1,21 @@ import { Client } from 'discord.js'; import { strToSeconds } from './time'; +/** + * Option possible for reminders + */ enum OptionReminder { + /** No parameters */ Nothing, + /** @ */ Mention, + /** p */ DirectMessage, } +/** + * Store data about the remidner + */ type infoReminder = { locale: Map>, message: string | null, @@ -16,6 +25,11 @@ type infoReminder = { guildId: string | null } +/** + * Split the time and the extra args `p` and `@` + * @param time raw text from user + * @returns An object with the time and the option + */ const splitTime = (time: string) => { if (time?.endsWith('@')) { return { time: time.slice(0, -1), option: OptionReminder.Mention }; @@ -26,20 +40,31 @@ const splitTime = (time: string) => { return { time: time, option: OptionReminder.Nothing }; }; +/** + * Create a new reminder + * @param client Client + * @param time raw text from user about the time wanted + * @param info data about the context of the reminder + * @returns Promise resolution of the sql request + */ export const newReminder = async (client: Client, time: string, info: infoReminder) => new Promise((ok, ko) => { const data = splitTime(time); + const timeout = strToSeconds(data.time); + const timeoutId = setTimeoutReminder(client, info, data.option, timeout); + // Add the remind to the db client.db.run('INSERT INTO reminder ( \ - data, expiration_date, option_id, channel_id, creation_date, user_id, guild_id \ - ) VALUES ( ?, ?, ?, ?, ?, ?, ?);', [ + data, expiration_date, option_id, channel_id, creation_date, user_id, guild_id, timeout_id \ + ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ? );', [ info.message, - info.createdAt + strToSeconds(data.time), + info.createdAt + timeout, data.option.valueOf(), info.channelId, info.createdAt, info.userId, - info.guildId], (err) => { + info.guildId, + timeoutId], (err) => { if (err) { ko(err); } @@ -48,3 +73,55 @@ export const newReminder = async (client: Client, time: string, info: infoRemind ok(`${info.locale.get('c_reminder1')} ${data.time}.`); }); }); + + +/** + * Create a timeout for a reminder + * @param client Client + * @param info info about the reminder + * @param option option used for this reminder (aka location of the response) + * @param timeout Amout of time before the reminder ends + * @returns timeout ID + */ +const setTimeoutReminder = (client: Client, info: infoReminder, option: OptionReminder, timeout: number) => { + // TODO: Reminders timeout + return Number(setTimeout(() => { + // Delete the reminder for the database + new Promise((ok, ko) => { + // Add the remind to the db + client.db.run('DELETE FROM reminder WHERE creation_date = ? AND user_id = ?', [info.createdAt, info.userId], (err) => { + if (err) { + ko(err); + } + + // Send confirmation to user + ok(true); + }); + }).then((val) => { + if (val != true) { + throw val; + } + + // Send the message in the appropriate channel + if (option == OptionReminder.DirectMessage) { + // Direct message + const user = client.users.cache.get(info.userId); + // TODO: Locales + user?.send(`Here your reminder: ${info.message} :)`); + } else { + // Channel + client.channels.fetch(info.channelId ?? '').then((channel) => { + if (channel?.isTextBased()) { + // TODO: Check if option == OptionReminder.Mention and mention + // everyone who are in the message + + // TODO: Test if a message exist + console.log(typeof info.message, info.message); + // TODO: Locales + channel.send(`Here your reminder: ${info.message} :)`); + } + }); + } + }); + }, timeout * 1000)); +};