merge dev to main (#169)
All checks were successful
Publish latest version / build (push) Successful in 1m33s

Close #63
Close #78
Close #79
Close #137

Mutiples fixed, mainly aimed to reminder commands

Also add the Rich Presence, and fix a bug for forwarded messages

Reviewed-on: #169
Co-authored-by: Mylloon <kennel.anri@tutanota.com>
Co-committed-by: Mylloon <kennel.anri@tutanota.com>
This commit is contained in:
Mylloon 2024-09-17 22:57:55 +02:00 committed by Mylloon
parent fdc081fd6d
commit 23d3918459
Signed by: Forgejo
GPG key ID: E72245C752A07631
8 changed files with 69 additions and 15 deletions

View file

@ -158,12 +158,19 @@ export default {
channelId: interaction.channelId, channelId: interaction.channelId,
userId: interaction.user.id, userId: interaction.user.id,
guildId: interaction.guildId, guildId: interaction.guildId,
}).then((msg) => })
.then((msg) =>
interaction.reply({ interaction.reply({
content: msg as string, content: msg as string,
ephemeral: true, ephemeral: true,
}), }),
); )
.catch((err) => {
interaction.reply({
content: err,
ephemeral: true,
});
});
} else { } else {
// Show modal to user to get at least the time // Show modal to user to get at least the time
const modal = new ModalBuilder() const modal = new ModalBuilder()

View file

@ -65,7 +65,19 @@ export default async (message: Message, client: Client) => {
[], [],
) )
.map(async ({ message_id, channel }) => { .map(async ({ message_id, channel }) => {
const quoted_message = await channel.messages.fetch(message_id).catch(() => undefined); let quoted_message = await channel.messages.fetch(message_id).catch(() => undefined);
// If it's a reference, we only check for reference once
const message_reference = quoted_message?.reference;
if (message_reference && message_reference.messageId) {
const channel_reference = client.channels.cache.get(
message_reference.channelId,
) as TextBasedChannel;
quoted_message = await channel_reference.messages
.fetch(message_reference.messageId)
.catch(() => undefined);
}
// If message doesn't exist or empty // If message doesn't exist or empty
if ( if (

View file

@ -77,6 +77,7 @@
"c_reminder15": "Message sent in DM because you have left", "c_reminder15": "Message sent in DM because you have left",
"c_reminder16": "Message sent in DM because the Discord guild is no longer available.", "c_reminder16": "Message sent in DM because the Discord guild is no longer available.",
"c_reminder17": "Message from", "c_reminder17": "Message from",
"c_reminder18": "Invalid time, try again.",
"c_play_name": "play", "c_play_name": "play",
"c_play_desc": "Plays a song/playlist, no query displays the now playing song", "c_play_desc": "Plays a song/playlist, no query displays the now playing song",

View file

@ -77,6 +77,7 @@
"c_reminder15": "Message envoyé en DM car vous avez quitté", "c_reminder15": "Message envoyé en DM car vous avez quitté",
"c_reminder16": "Message envoyé en DM car le serveur Discord n'est plus disponible.", "c_reminder16": "Message envoyé en DM car le serveur Discord n'est plus disponible.",
"c_reminder17": "Message d'il y a", "c_reminder17": "Message d'il y a",
"c_reminder18": "Temps invalide, réessayez.",
"c_play_name": "play", "c_play_name": "play",
"c_play_desc": "Joue une chanson/playlist, pas de requête affiche la chanson en cours actuellement", "c_play_desc": "Joue une chanson/playlist, pas de requête affiche la chanson en cours actuellement",

View file

@ -1,5 +1,5 @@
import { Player } from "discord-player"; import { Player } from "discord-player";
import { Client, Collection, GatewayIntentBits } from "discord.js"; import { ActivityType, Client, Collection, GatewayIntentBits } from "discord.js";
import { readFileSync } from "fs"; import { readFileSync } from "fs";
import { Database } from "sqlite3"; import { Database } from "sqlite3";
import "../modules/client"; import "../modules/client";
@ -16,6 +16,9 @@ export default async () => {
GatewayIntentBits.MessageContent, GatewayIntentBits.MessageContent,
GatewayIntentBits.GuildVoiceStates, GatewayIntentBits.GuildVoiceStates,
], ],
presence: {
activities: [{ name: "/help", type: ActivityType.Watching }],
},
}); });
client.config = { client.config = {

View file

@ -98,7 +98,7 @@ export const cleanCodeBlock = (text: string) => {
); );
// Fix issues // Fix issues
text = text.replace("``", ""); text = text.replaceAll("``", "");
return text; return text;
}; };

View file

@ -64,8 +64,15 @@ const splitTime = (time: string) => {
*/ */
export const newReminder = async (client: Client, time: string, info: infoReminder) => export const newReminder = async (client: Client, time: string, info: infoReminder) =>
new Promise((ok, ko) => { new Promise((ok, ko) => {
const loc = getLocale(client, info.locale);
const data = splitTime(time); const data = splitTime(time);
const timeout = strToSeconds(data.time); const timeout = strToSeconds(data.time);
if (timeout < 0) {
ko(loc.get("c_reminder18"));
return;
}
const timeoutId = setTimeoutReminder(client, info, data.option, timeout); const timeoutId = setTimeoutReminder(client, info, data.option, timeout);
// Add the remind to the db // Add the remind to the db
@ -90,7 +97,6 @@ export const newReminder = async (client: Client, time: string, info: infoRemind
} }
// Send confirmation to user // Send confirmation to user
const loc = getLocale(client, info.locale);
ok(`${loc.get("c_reminder1")} ${data.time}.`); ok(`${loc.get("c_reminder1")} ${data.time}.`);
}, },
); );
@ -202,8 +208,19 @@ export const setTimeoutReminder = (
option: OptionReminder, option: OptionReminder,
timeout: number, timeout: number,
) => { ) => {
return Number( const setChunkedTimeout = (remainingTime: number) => {
setTimeout(() => { // Maximum for setTimeout is Int32
if (remainingTime > 2147483647) {
// Schedule a 24-hour delay (24 * 60 * 60 * 1000), then check again
const dayChunk = 86400000;
return setTimeout(() => {
setChunkedTimeout(remainingTime - dayChunk);
}, dayChunk);
}
// Final timeout when remaining time is within limit
return setTimeout(() => {
deleteReminder(client, String(info.createdAt), info.userId).then((val) => { deleteReminder(client, String(info.createdAt), info.userId).then((val) => {
if (val != true) { if (val != true) {
throw val; throw val;
@ -211,8 +228,11 @@ export const setTimeoutReminder = (
sendReminder(client, info, option); sendReminder(client, info, option);
}); });
}, timeout * 1000), }, remainingTime);
); };
// Convert to milliseconds
return Number(setChunkedTimeout(timeout * 1000));
}; };
/** /**

View file

@ -24,6 +24,11 @@ enum TimeSecond {
* @returns time in seconds * @returns time in seconds
*/ */
export const strToSeconds = (time: string) => { export const strToSeconds = (time: string) => {
if (time.length > 15) {
// 15 is a magic value, weird to be this long
return -1;
}
const regex = new RegExp( const regex = new RegExp(
`(?<${TimeSecond[TimeSecond.Year]}>[0-9]+(?=[y|a]))|(?<${ `(?<${TimeSecond[TimeSecond.Year]}>[0-9]+(?=[y|a]))|(?<${
TimeSecond[TimeSecond.Week] TimeSecond[TimeSecond.Week]
@ -34,7 +39,12 @@ export const strToSeconds = (time: string) => {
}>[0-9]+(?=[s]?))`, }>[0-9]+(?=[s]?))`,
); );
const data = Object.assign({}, regex.exec(time)?.groups); const data = Object.assign({}, regex.exec(time.toLowerCase())?.groups);
if (Object.keys(data).length === 0) {
// Regex returned an invalid time
return -1;
}
let res = 0; let res = 0;
Object.entries(data).forEach(([key, value]) => { Object.entries(data).forEach(([key, value]) => {