feat: Reminders #44

Merged
Anri merged 54 commits from feat/reminders into main 2023-01-17 12:15:15 +01:00
5 changed files with 113 additions and 50 deletions
Showing only changes of commit 759f974e15 - Show all commits

View file

@ -142,7 +142,6 @@ export default {
const filename = getFilename(__filename); const filename = getFilename(__filename);
const loc = getLocale(client, interaction.locale); const loc = getLocale(client, interaction.locale);
/* Votre code ici */
const subcommand = interaction.options.getSubcommand(); const subcommand = interaction.options.getSubcommand();
switch (subcommand) { switch (subcommand) {
// New reminder // New reminder
@ -154,7 +153,7 @@ export default {
if (time != null) { if (time != null) {
// Use the cli because we already have enough data // Use the cli because we already have enough data
return newReminder(client, time, { return newReminder(client, time, {
locale: loc, locale: interaction.locale,
message: interaction.options.getString(loc_default?.get('c_reminder_sub1_opt2_name') as string), message: interaction.options.getString(loc_default?.get('c_reminder_sub1_opt2_name') as string),
createdAt: interaction.createdAt.getTime(), createdAt: interaction.createdAt.getTime(),
channelId: interaction.channelId, channelId: interaction.channelId,

View file

@ -1,9 +1,60 @@
import { Client } from 'discord.js';
import { deleteReminder, infoReminder, OptionReminder, sendReminder } from '../../utils/reminder';
export const once = true; export const once = true;
type dbReminder = {
id: number,
data: string,
expiration_date: number,
option_id: number,
channel_id: number,
creation_date: number,
user_id: number,
guild_id: number,
locale: string
}
/** https://discord.js.org/#/docs/discord.js/main/class/Client?scrollTo=e-ready */ /** https://discord.js.org/#/docs/discord.js/main/class/Client?scrollTo=e-ready */
export default async () => { export default async (client: Client) => {
console.log('Connected to Discord!'); console.log('Connected to Discord!');
// Restart all the timeout about reminders here // Restart all the timeout about reminders here
// TODO: Reminders timeout new Promise((ok, ko) => {
// Fetch all reminders
client.db.all('SELECT * FROM reminder', [], (err, row) => {
if (err) {
ko(err);
}
// Send all the current reminders
ok(row);
});
}).then((data) => {
const now = Date.now();
(data as dbReminder[]).forEach((element) => {
if (element.expiration_date <= now) {
// Reminder expired
deleteReminder(client, element.creation_date, `${element.user_id}`).then((res) => {
if (res != true) {
throw res;
}
});
const info = {
locale: element.locale,
message: element.data,
createdAt: element.creation_date,
channelId: `${element.channel_id}`,
userId: `${element.user_id}`,
guildId: `${element.guild_id}`,
} as infoReminder;
sendReminder(client, info, element.option_id as OptionReminder);
} else {
// Restart timeout
}
});
}).catch(err => {
throw err;
});
}; };

View file

@ -1,5 +1,4 @@
import { Client, ModalSubmitInteraction } from 'discord.js'; import { Client, ModalSubmitInteraction } from 'discord.js';
import { getLocale } from '../../utils/locales';
import { getFilename } from '../../utils/misc'; import { getFilename } from '../../utils/misc';
import { newReminder } from '../../utils/reminder'; import { newReminder } from '../../utils/reminder';
@ -9,7 +8,7 @@ export default {
}, },
interaction: async (interaction: ModalSubmitInteraction, client: Client) => interaction: async (interaction: ModalSubmitInteraction, client: Client) =>
newReminder(client, interaction.fields.fields.get('reminderGUI-time')?.value as string, { newReminder(client, interaction.fields.fields.get('reminderGUI-time')?.value as string, {
locale: getLocale(client, interaction.locale), locale: interaction.locale,
message: interaction.fields.fields.get('reminderGUI-message')?.value ?? null, message: interaction.fields.fields.get('reminderGUI-message')?.value ?? null,
createdAt: interaction.createdAt.getTime(), createdAt: interaction.createdAt.getTime(),
channelId: interaction.channelId, channelId: interaction.channelId,

View file

@ -66,6 +66,6 @@ const initDatabase = (db: Database) => {
creation_date INTEGER, \ creation_date INTEGER, \
user_id INTEGER, \ user_id INTEGER, \
guild_id INTEGER, \ guild_id INTEGER, \
timeout_id INTEGER \ locale TEXT \
);'); );');
}; };

View file

@ -1,10 +1,11 @@
import { Client } from 'discord.js'; import { Client } from 'discord.js';
import { getLocale } from './locales';
import { strToSeconds } from './time'; import { strToSeconds } from './time';
/** /**
* Option possible for reminders * Option possible for reminders
*/ */
enum OptionReminder { export enum OptionReminder {
/** No parameters */ /** No parameters */
Nothing, Nothing,
/** @ */ /** @ */
@ -16,8 +17,8 @@ enum OptionReminder {
/** /**
* Store data about the remidner * Store data about the remidner
*/ */
type infoReminder = { export type infoReminder = {
locale: Map<string, Map<string, string>>, locale: string,
message: string | null, message: string | null,
createdAt: number, createdAt: number,
channelId: string | null, channelId: string | null,
@ -51,11 +52,11 @@ export const newReminder = async (client: Client, time: string, info: infoRemind
new Promise((ok, ko) => { new Promise((ok, ko) => {
const data = splitTime(time); const data = splitTime(time);
const timeout = strToSeconds(data.time); const timeout = strToSeconds(data.time);
const timeoutId = setTimeoutReminder(client, info, data.option, timeout); setTimeoutReminder(client, info, data.option, timeout);
// Add the remind to the db // Add the remind to the db
client.db.run('INSERT INTO reminder ( \ client.db.run('INSERT INTO reminder ( \
data, expiration_date, option_id, channel_id, creation_date, user_id, guild_id, timeout_id \ data, expiration_date, option_id, channel_id, creation_date, user_id, guild_id, locale \
) VALUES ( ?, ?, ?, ?, ?, ?, ?, ? );', [ ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ? );', [
info.message, info.message,
info.createdAt + timeout, info.createdAt + timeout,
@ -64,16 +65,61 @@ export const newReminder = async (client: Client, time: string, info: infoRemind
info.createdAt, info.createdAt,
info.userId, info.userId,
info.guildId, info.guildId,
timeoutId], (err) => { info.locale], (err) => {
if (err) { if (err) {
ko(err); ko(err);
} }
// Send confirmation to user // Send confirmation to user
ok(`${info.locale.get('c_reminder1')} ${data.time}.`); const loc = getLocale(client, info.locale);
ok(`${loc.get('c_reminder1')} ${data.time}.`);
}); });
}); });
/**
* Delete a reminder
* @param client Client
* @param createdAt Creation of the reminder
* @param userId User ID who created the reminder
* @returns what the SQlite request sended
*/
export const deleteReminder = (client: Client, createdAt: number, userId: string) => {
// Delete the reminder for the database
return new Promise((ok, ko) => {
// Add the remind to the db
client.db.run('DELETE FROM reminder WHERE creation_date = ? AND user_id = ?', [createdAt, userId], (err) => {
if (err) {
ko(err);
}
// Send confirmation to user
ok(true);
});
});
};
export const sendReminder = (client: Client, info: infoReminder, option: OptionReminder) => {
// 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
// TODO: Locales
// TODO: Embed
channel.send(`Here your reminder: ${info.message} :)`);
}
});
}
};
/** /**
* Create a timeout for a reminder * Create a timeout for a reminder
@ -81,47 +127,15 @@ export const newReminder = async (client: Client, time: string, info: infoRemind
* @param info info about the reminder * @param info info about the reminder
* @param option option used for this reminder (aka location of the response) * @param option option used for this reminder (aka location of the response)
* @param timeout Amout of time before the reminder ends * @param timeout Amout of time before the reminder ends
* @returns timeout ID
*/ */
const setTimeoutReminder = (client: Client, info: infoReminder, option: OptionReminder, timeout: number) => { const setTimeoutReminder = (client: Client, info: infoReminder, option: OptionReminder, timeout: number) => {
// TODO: Reminders timeout setTimeout(() => {
return Number(setTimeout(() => { deleteReminder(client, info.createdAt, info.userId).then((val) => {
// 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) { if (val != true) {
throw val; throw val;
} }
// Send the message in the appropriate channel sendReminder(client, info, option);
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)); }, timeout * 1000);
}; };