From 0e8c272a3db32d558bafb83e8e59540543dd7f0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20H?= Date: Wed, 7 Jun 2023 13:29:48 +0200 Subject: [PATCH 01/13] test(message.test.ts): add tests for isDiscordLink function feat(message.util.ts): add isDiscordLink function to check if a link is a valid discord link --- src/utils/message/message.test.ts | 28 +++++++++++++++++++++++++++- src/utils/message/message.util.ts | 4 ++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/utils/message/message.test.ts b/src/utils/message/message.test.ts index 00ee393a..35168125 100644 --- a/src/utils/message/message.test.ts +++ b/src/utils/message/message.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect } from "vitest"; -import { msgParams } from "./message.util"; +import { isDiscordLink, msgParams } from "./message.util"; describe("msgParams function", () => { it("should correctly replace placeholders with provided words", () => { @@ -33,4 +33,30 @@ describe("msgParams function", () => { it("should ignore extra words when there are no placeholders", () => { expect(msgParams("Hello", ["Hello", "World"])).toBe("Hello"); }); +}); + +describe("isDiscordLink function", () => { + it("should return true when the link is a discord canary link", () => { + expect(isDiscordLink("https://canary.discord.com/channels/732251741999071303/1113731433123565589/1113731587570413588")).toBe(true); + }); + + it("should return true when the link is a discord ptb link", () => { + expect(isDiscordLink("https://ptb.discord.com/channels/732251741999071303/786216771723198514/1075749993631191110")).toBe(true); + }); + + it("should return true when the link is a discord link", () => { + expect(isDiscordLink("https://discord.com/channels/732251741999071303/786216771723198514/803532192793493544")).toBe(true); + }); + + it("should return false because is not valid", () => { + expect(isDiscordLink("https://discord.com/channels/732251741999071303")).toBe(false); + }); + + it("should return false because is litteraly not a discord link", () => { + expect(isDiscordLink("https://www.youtube.com/watch?v=dQw4w9WgXcQ")).toBe(false); + }); + + it("should return false when the link is not a discord link", () => { + expect(isDiscordLink("https://fakediscord.com/channels/732251741999071303/1113731433123565589/1113731587570413588")).toBe(false); + }); }); \ No newline at end of file diff --git a/src/utils/message/message.util.ts b/src/utils/message/message.util.ts index def0a9b7..90bc82c7 100644 --- a/src/utils/message/message.util.ts +++ b/src/utils/message/message.util.ts @@ -6,4 +6,8 @@ export const msgParams = (message: string, params: (string | number)[]): string } return message; +}; + +export const isDiscordLink = (link: string): boolean => { + return link.match(/^http(s?):\/\/(www\.|canary\.|ptb\.)?discord.com\/channels(\/\d*){3}$/gi) !== null; }; \ No newline at end of file From 0a6cdcd59d1f2b3188860dbdb82b6090bb969a7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20H?= Date: Wed, 7 Jun 2023 13:55:37 +0200 Subject: [PATCH 02/13] refactor(resolve.cmd.ts): replace trustDiscordLinks with isDiscordLink function from message.util module --- src/commands/forum/[sub-commands]/resolve.cmd.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/commands/forum/[sub-commands]/resolve.cmd.ts b/src/commands/forum/[sub-commands]/resolve.cmd.ts index 77b2b78d..583a7118 100644 --- a/src/commands/forum/[sub-commands]/resolve.cmd.ts +++ b/src/commands/forum/[sub-commands]/resolve.cmd.ts @@ -6,7 +6,7 @@ import { commands } from "#/configs/message/command"; import { ChannelType, ForumChannel } from "discord.js"; import { logger } from "#/utils/logger"; import { userWithId } from "#/utils/discord/user"; -import { trustDiscordLinks } from "../forum.const"; +import { isDiscordLink } from "#/utils/message/message.util"; export const execute: CommandExecute = async(command) => { const channel = command.channel; @@ -21,7 +21,7 @@ export const execute: CommandExecute = async(command) => { const answerLink = command.options.getString(commands.forum.subcmds.resolve.options.answer.name, true); - if (!answerLink.match(trustDiscordLinks)) { + if (!isDiscordLink(answerLink)) { void command.reply({ embeds: [simpleEmbed(commands.forum.exec.resolve.isntDiscordMessageLink, "error")], ephemeral: true From 03e7d8d459845a7330ee8e86fb9b208f46ea0569 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20H?= Date: Thu, 8 Jun 2023 00:44:42 +0200 Subject: [PATCH 03/13] feat(utils/message): add isDiscordLink and getMessageContentFromLink functions test(utils/message): add tests for isDiscordLink, getMessageContentFromLink and msgParams functions --- src/utils/message/_test/discord-link.test.ts | 28 ++++++++++++++++ src/utils/message/_test/get-message.test.ts | 28 ++++++++++++++++ .../msg-params.test.ts} | 28 +--------------- src/utils/message/index.ts | 2 +- src/utils/message/message.util.ts | 33 +++++++++++++++++++ 5 files changed, 91 insertions(+), 28 deletions(-) create mode 100644 src/utils/message/_test/discord-link.test.ts create mode 100644 src/utils/message/_test/get-message.test.ts rename src/utils/message/{message.test.ts => _test/msg-params.test.ts} (51%) diff --git a/src/utils/message/_test/discord-link.test.ts b/src/utils/message/_test/discord-link.test.ts new file mode 100644 index 00000000..a1bc69ae --- /dev/null +++ b/src/utils/message/_test/discord-link.test.ts @@ -0,0 +1,28 @@ +import { describe, expect, it } from "vitest"; +import { isDiscordLink } from "#/utils/message"; + +describe("isDiscordLink function", () => { + it("should return true when the link is a discord canary link", () => { + expect(isDiscordLink("https://canary.discord.com/channels/732251741999071303/1113731433123565589/1113731587570413588")).toBe(true); + }); + + it("should return true when the link is a discord ptb link", () => { + expect(isDiscordLink("https://ptb.discord.com/channels/732251741999071303/786216771723198514/1075749993631191110")).toBe(true); + }); + + it("should return true when the link is a discord link", () => { + expect(isDiscordLink("https://discord.com/channels/732251741999071303/786216771723198514/803532192793493544")).toBe(true); + }); + + it("should return false because is not valid", () => { + expect(isDiscordLink("https://discord.com/channels/732251741999071303")).toBe(false); + }); + + it("should return false because is litteraly not a discord link", () => { + expect(isDiscordLink("https://www.youtube.com/watch?v=dQw4w9WgXcQ")).toBe(false); + }); + + it("should return false when the link is not a discord link", () => { + expect(isDiscordLink("https://fakediscord.com/channels/732251741999071303/1113731433123565589/1113731587570413588")).toBe(false); + }); +}); \ No newline at end of file diff --git a/src/utils/message/_test/get-message.test.ts b/src/utils/message/_test/get-message.test.ts new file mode 100644 index 00000000..2558bf2d --- /dev/null +++ b/src/utils/message/_test/get-message.test.ts @@ -0,0 +1,28 @@ +import { describe, expect, it } from "vitest"; +import { getMessageContentFromLink } from "#/utils/message"; + +describe("isDiscordLink function", () => { + it("should return the text from discord link", async() => { + expect(await getMessageContentFromLink( + "https://discord.com/channels/732251741999071303/732392873667854372/1116134183648116787" + )).toBe("Bottly > ChatGPT"); + }); + + it("should return the text from discord canary link", async() => { + expect(await getMessageContentFromLink( + "https://canary.discord.com/channels/732251741999071303/732392873667854372/1116128755258249338" + )).toBe("ahahahahahh"); + }); + + it("should return the text from discord ptb link", async() => { + expect(await getMessageContentFromLink( + "https://ptb.discord.com/channels/732251741999071303/732392873667854372/1116003681414959324" + )).toBe("Il en est ou le site du Royaume ?"); + }); + + it("should return undefined if link is invalid", async() => { + expect(await getMessageContentFromLink( + "https://discord.com/channels/732251741999071303/975780913013227630/1116120913306468384/1116120913306468384" + )).toBe(undefined); + }); +}); \ No newline at end of file diff --git a/src/utils/message/message.test.ts b/src/utils/message/_test/msg-params.test.ts similarity index 51% rename from src/utils/message/message.test.ts rename to src/utils/message/_test/msg-params.test.ts index 35168125..f4e4747c 100644 --- a/src/utils/message/message.test.ts +++ b/src/utils/message/_test/msg-params.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect } from "vitest"; -import { isDiscordLink, msgParams } from "./message.util"; +import { msgParams } from "#/utils/message"; describe("msgParams function", () => { it("should correctly replace placeholders with provided words", () => { @@ -33,30 +33,4 @@ describe("msgParams function", () => { it("should ignore extra words when there are no placeholders", () => { expect(msgParams("Hello", ["Hello", "World"])).toBe("Hello"); }); -}); - -describe("isDiscordLink function", () => { - it("should return true when the link is a discord canary link", () => { - expect(isDiscordLink("https://canary.discord.com/channels/732251741999071303/1113731433123565589/1113731587570413588")).toBe(true); - }); - - it("should return true when the link is a discord ptb link", () => { - expect(isDiscordLink("https://ptb.discord.com/channels/732251741999071303/786216771723198514/1075749993631191110")).toBe(true); - }); - - it("should return true when the link is a discord link", () => { - expect(isDiscordLink("https://discord.com/channels/732251741999071303/786216771723198514/803532192793493544")).toBe(true); - }); - - it("should return false because is not valid", () => { - expect(isDiscordLink("https://discord.com/channels/732251741999071303")).toBe(false); - }); - - it("should return false because is litteraly not a discord link", () => { - expect(isDiscordLink("https://www.youtube.com/watch?v=dQw4w9WgXcQ")).toBe(false); - }); - - it("should return false when the link is not a discord link", () => { - expect(isDiscordLink("https://fakediscord.com/channels/732251741999071303/1113731433123565589/1113731587570413588")).toBe(false); - }); }); \ No newline at end of file diff --git a/src/utils/message/index.ts b/src/utils/message/index.ts index 7a0665e5..cb720278 100644 --- a/src/utils/message/index.ts +++ b/src/utils/message/index.ts @@ -1 +1 @@ -export { msgParams } from "./message.util"; \ No newline at end of file +export { msgParams, isDiscordLink, getMessageContentFromLink } from "./message.util"; \ No newline at end of file diff --git a/src/utils/message/message.util.ts b/src/utils/message/message.util.ts index 90bc82c7..bcc83e88 100644 --- a/src/utils/message/message.util.ts +++ b/src/utils/message/message.util.ts @@ -1,3 +1,10 @@ +import { client } from "#/client"; +import { StageChannel, ThreadChannel } from "discord.js"; +import { TextChannel } from "discord.js"; +import { ForumChannel } from "discord.js"; +import { VoiceChannel } from "discord.js"; +import { NewsChannel } from "discord.js"; + export const msgParams = (message: string, params: (string | number)[]): string => { const words = message.match(/\{[^}]+\}/g); @@ -10,4 +17,30 @@ export const msgParams = (message: string, params: (string | number)[]): string export const isDiscordLink = (link: string): boolean => { return link.match(/^http(s?):\/\/(www\.|canary\.|ptb\.)?discord.com\/channels(\/\d*){3}$/gi) !== null; +}; + +export const getMessageContentFromLink = async(link: string): Promise => { + if (!isDiscordLink(link)) return undefined; + + const [_, __, ___, ____, guildId, channelId, messageId] = link.split("/"); + + try { + const guild = await client.guilds.fetch(guildId); + const channel = await guild.channels.fetch(channelId); + + if (channel instanceof StageChannel + || channel instanceof NewsChannel + || channel instanceof TextChannel + || channel instanceof VoiceChannel + || channel instanceof ForumChannel + || channel instanceof ThreadChannel + ) { + const message = await channel.messages.fetch(messageId); + return message.content; + } + } catch (error) { + console.error(error); + } + + return undefined; }; \ No newline at end of file From 0d2820a9d6173992a8a12dc7d0b026ef239a9f5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20H?= Date: Tue, 20 Jun 2023 15:37:56 +0200 Subject: [PATCH 04/13] refactor(utils/message): rename isDiscordLink to containsDiscordLink and remove getMessageContentFromLink function test(utils/message): add tests for containsDiscordLink function feat(utils/message): export containsDiscordLink function instead of isDiscordLink function --- .../_test/contains-discord-link.test.ts | 32 ++++++++++++++++ src/utils/message/_test/discord-link.test.ts | 28 -------------- src/utils/message/_test/get-message.test.ts | 28 -------------- src/utils/message/index.ts | 2 +- src/utils/message/message.util.ts | 38 ++----------------- 5 files changed, 36 insertions(+), 92 deletions(-) create mode 100644 src/utils/message/_test/contains-discord-link.test.ts delete mode 100644 src/utils/message/_test/discord-link.test.ts delete mode 100644 src/utils/message/_test/get-message.test.ts diff --git a/src/utils/message/_test/contains-discord-link.test.ts b/src/utils/message/_test/contains-discord-link.test.ts new file mode 100644 index 00000000..72e88c2f --- /dev/null +++ b/src/utils/message/_test/contains-discord-link.test.ts @@ -0,0 +1,32 @@ +import { describe, expect, it } from "vitest"; +import { containsDiscordLink } from "#/utils/message"; + +describe("isDiscordLink function", () => { + it("should return true when the link is a discord canary link", () => { + expect( + containsDiscordLink("Salut check : https://canary.discord.com/channels/732251741999071303/1113731433123565589/1113731587570413588") + ).toBe(true); + }); + + it("should return true when the link is a discord ptb link", () => { + expect( + containsDiscordLink("Salut check : https://ptb.discord.com/channels/732251741999071303/786216771723198514/1075749993631191110") + ).toBe(true); + }); + + it("should return true when the link is a discord link", () => { + expect(containsDiscordLink("Salut check : https://discord.com/channels/732251741999071303/786216771723198514/803532192793493544")).toBe(true); + }); + + it("should return false because is not valid", () => { + expect(containsDiscordLink("Salut check : https://discord.com/channels/732251741999071303")).toBe(false); + }); + + it("should return false because is litteraly not a discord link", () => { + expect(containsDiscordLink("Salut check la superbe vidéo: https://www.youtube.com/watch?v=dQw4w9WgXcQ")).toBe(false); + }); + + it("should return false when the link is not a discord link", () => { + expect(containsDiscordLink("Ahah https://fakediscord.com/channels/732251741999071303/1113731433123565589/1113731587570413588")).toBe(false); + }); +}); \ No newline at end of file diff --git a/src/utils/message/_test/discord-link.test.ts b/src/utils/message/_test/discord-link.test.ts deleted file mode 100644 index a1bc69ae..00000000 --- a/src/utils/message/_test/discord-link.test.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { describe, expect, it } from "vitest"; -import { isDiscordLink } from "#/utils/message"; - -describe("isDiscordLink function", () => { - it("should return true when the link is a discord canary link", () => { - expect(isDiscordLink("https://canary.discord.com/channels/732251741999071303/1113731433123565589/1113731587570413588")).toBe(true); - }); - - it("should return true when the link is a discord ptb link", () => { - expect(isDiscordLink("https://ptb.discord.com/channels/732251741999071303/786216771723198514/1075749993631191110")).toBe(true); - }); - - it("should return true when the link is a discord link", () => { - expect(isDiscordLink("https://discord.com/channels/732251741999071303/786216771723198514/803532192793493544")).toBe(true); - }); - - it("should return false because is not valid", () => { - expect(isDiscordLink("https://discord.com/channels/732251741999071303")).toBe(false); - }); - - it("should return false because is litteraly not a discord link", () => { - expect(isDiscordLink("https://www.youtube.com/watch?v=dQw4w9WgXcQ")).toBe(false); - }); - - it("should return false when the link is not a discord link", () => { - expect(isDiscordLink("https://fakediscord.com/channels/732251741999071303/1113731433123565589/1113731587570413588")).toBe(false); - }); -}); \ No newline at end of file diff --git a/src/utils/message/_test/get-message.test.ts b/src/utils/message/_test/get-message.test.ts deleted file mode 100644 index 2558bf2d..00000000 --- a/src/utils/message/_test/get-message.test.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { describe, expect, it } from "vitest"; -import { getMessageContentFromLink } from "#/utils/message"; - -describe("isDiscordLink function", () => { - it("should return the text from discord link", async() => { - expect(await getMessageContentFromLink( - "https://discord.com/channels/732251741999071303/732392873667854372/1116134183648116787" - )).toBe("Bottly > ChatGPT"); - }); - - it("should return the text from discord canary link", async() => { - expect(await getMessageContentFromLink( - "https://canary.discord.com/channels/732251741999071303/732392873667854372/1116128755258249338" - )).toBe("ahahahahahh"); - }); - - it("should return the text from discord ptb link", async() => { - expect(await getMessageContentFromLink( - "https://ptb.discord.com/channels/732251741999071303/732392873667854372/1116003681414959324" - )).toBe("Il en est ou le site du Royaume ?"); - }); - - it("should return undefined if link is invalid", async() => { - expect(await getMessageContentFromLink( - "https://discord.com/channels/732251741999071303/975780913013227630/1116120913306468384/1116120913306468384" - )).toBe(undefined); - }); -}); \ No newline at end of file diff --git a/src/utils/message/index.ts b/src/utils/message/index.ts index cb720278..37dc6710 100644 --- a/src/utils/message/index.ts +++ b/src/utils/message/index.ts @@ -1 +1 @@ -export { msgParams, isDiscordLink, getMessageContentFromLink } from "./message.util"; \ No newline at end of file +export { msgParams, containsDiscordLink } from "./message.util"; \ No newline at end of file diff --git a/src/utils/message/message.util.ts b/src/utils/message/message.util.ts index 9ab746d4..3817ce24 100644 --- a/src/utils/message/message.util.ts +++ b/src/utils/message/message.util.ts @@ -1,10 +1,3 @@ -import { client } from "#/client"; -import { StageChannel, ThreadChannel } from "discord.js"; -import { TextChannel } from "discord.js"; -import { ForumChannel } from "discord.js"; -import { VoiceChannel } from "discord.js"; -import { NewsChannel } from "discord.js"; - export const msgParams = (message: string, params: (string | number)[]): string => { const words = message.match(/{[^}]+}/g); @@ -15,32 +8,7 @@ export const msgParams = (message: string, params: (string | number)[]): string return message; }; -export const isDiscordLink = (link: string): boolean => { - return link.match(/^http(s?):\/\/(www\.|canary\.|ptb\.)?discord.com\/channels(\/\d*){3}$/gi) !== null; -}; - -export const getMessageContentFromLink = async(link: string): Promise => { - if (!isDiscordLink(link)) return undefined; - - const [_, __, ___, ____, guildId, channelId, messageId] = link.split("/"); - - try { - const guild = await client.guilds.fetch(guildId); - const channel = await guild.channels.fetch(channelId); - - if (channel instanceof StageChannel - || channel instanceof NewsChannel - || channel instanceof TextChannel - || channel instanceof VoiceChannel - || channel instanceof ForumChannel - || channel instanceof ThreadChannel - ) { - const message = await channel.messages.fetch(messageId); - return message.content; - } - } catch (error) { - console.error(error); - } - - return undefined; +export const containsDiscordLink = (content: string): boolean => { + const discordLinkRegex = /http(s?):\/\/(www\.|canary\.|ptb\.)?discord.com\/channels(\/\d*){3}$/gi; + return discordLinkRegex.test(content); }; \ No newline at end of file From 4f1d142ca0bc3c8b308145e24c67e22e3f05d36c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20H?= Date: Tue, 20 Jun 2023 15:40:32 +0200 Subject: [PATCH 05/13] refactor(resolve.cmd.ts): rename isDiscordLink to containsDiscordLink for clarity and consistency with other functions --- src/commands/forum/[sub-commands]/resolve.cmd.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/commands/forum/[sub-commands]/resolve.cmd.ts b/src/commands/forum/[sub-commands]/resolve.cmd.ts index 583a7118..ac4d4402 100644 --- a/src/commands/forum/[sub-commands]/resolve.cmd.ts +++ b/src/commands/forum/[sub-commands]/resolve.cmd.ts @@ -6,7 +6,7 @@ import { commands } from "#/configs/message/command"; import { ChannelType, ForumChannel } from "discord.js"; import { logger } from "#/utils/logger"; import { userWithId } from "#/utils/discord/user"; -import { isDiscordLink } from "#/utils/message/message.util"; +import { containsDiscordLink } from "#/utils/message/message.util"; export const execute: CommandExecute = async(command) => { const channel = command.channel; @@ -21,7 +21,7 @@ export const execute: CommandExecute = async(command) => { const answerLink = command.options.getString(commands.forum.subcmds.resolve.options.answer.name, true); - if (!isDiscordLink(answerLink)) { + if (!containsDiscordLink(answerLink)) { void command.reply({ embeds: [simpleEmbed(commands.forum.exec.resolve.isntDiscordMessageLink, "error")], ephemeral: true From 3f4a580a22e0c96675eb9a28aa415023fdd6901b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20H?= Date: Tue, 20 Jun 2023 16:24:13 +0200 Subject: [PATCH 06/13] feat(utils): add extractDiscordLink function to message.util.ts test(utils): add tests for extractDiscordLink function in extract-discord-link.test.ts --- .../_test/extract-discord-link.test.ts | 21 +++++++++++++++++++ src/utils/message/index.ts | 2 +- src/utils/message/message.util.ts | 8 +++++++ 3 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 src/utils/message/_test/extract-discord-link.test.ts diff --git a/src/utils/message/_test/extract-discord-link.test.ts b/src/utils/message/_test/extract-discord-link.test.ts new file mode 100644 index 00000000..fe8a88ad --- /dev/null +++ b/src/utils/message/_test/extract-discord-link.test.ts @@ -0,0 +1,21 @@ +import { describe, it, expect } from "vitest"; +import { extractDiscordLink } from "#/utils/message"; + +describe("msgParams function", () => { + it("should correctly extract discord link", () => { + expect( + extractDiscordLink([ + "Salut check : https://discord.com/channels/732251741999071303/786216771723198514/803532192793493544", + "et https://canary.discord.com/channels/732251741999071303/786216771723198514/803532192793493544"].join(" ")) + ).toEqual([ + "https://discord.com/channels/732251741999071303/786216771723198514/803532192793493544", + "https://canary.discord.com/channels/732251741999071303/786216771723198514/803532192793493544" + ]); + }); + + it("should return null when no discord link is found", () => { + expect( + extractDiscordLink("Salut check : https://www.youtube.com/watch?v=dQw4w9WgXcQ") + ).toBe(null); + }); +}); \ No newline at end of file diff --git a/src/utils/message/index.ts b/src/utils/message/index.ts index 37dc6710..275320ab 100644 --- a/src/utils/message/index.ts +++ b/src/utils/message/index.ts @@ -1 +1 @@ -export { msgParams, containsDiscordLink } from "./message.util"; \ No newline at end of file +export { msgParams, containsDiscordLink, extractDiscordLink } from "./message.util"; \ No newline at end of file diff --git a/src/utils/message/message.util.ts b/src/utils/message/message.util.ts index 3817ce24..d8595073 100644 --- a/src/utils/message/message.util.ts +++ b/src/utils/message/message.util.ts @@ -11,4 +11,12 @@ export const msgParams = (message: string, params: (string | number)[]): string export const containsDiscordLink = (content: string): boolean => { const discordLinkRegex = /http(s?):\/\/(www\.|canary\.|ptb\.)?discord.com\/channels(\/\d*){3}$/gi; return discordLinkRegex.test(content); +}; + +export const extractDiscordLink = (content: string): string | string[] | null => { + const discordLinkRegex = /http(s?):\/\/(www\.|canary\.|ptb\.)?discord.com\/channels(\/\d*){3}/gi; + const discordLinks = content.match(discordLinkRegex); + + if (discordLinks) return discordLinks; + return null; }; \ No newline at end of file From 00364d87d50f5f451c7f10b062f2ab00d985d155 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20H?= Date: Tue, 20 Jun 2023 16:26:43 +0200 Subject: [PATCH 07/13] feat(message.util.ts): add discordLinkRegex to message.type.ts and import it to message.util.ts to avoid code duplication. --- src/utils/message/message.type.ts | 1 + src/utils/message/message.util.ts | 5 ++--- 2 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 src/utils/message/message.type.ts diff --git a/src/utils/message/message.type.ts b/src/utils/message/message.type.ts new file mode 100644 index 00000000..ce8892c0 --- /dev/null +++ b/src/utils/message/message.type.ts @@ -0,0 +1 @@ +export const discordLinkRegex = /http(s?):\/\/(www\.|canary\.|ptb\.)?discord.com\/channels(\/\d*){3}/gi; \ No newline at end of file diff --git a/src/utils/message/message.util.ts b/src/utils/message/message.util.ts index d8595073..a0372db4 100644 --- a/src/utils/message/message.util.ts +++ b/src/utils/message/message.util.ts @@ -1,3 +1,5 @@ +import { discordLinkRegex } from "./message.type"; + export const msgParams = (message: string, params: (string | number)[]): string => { const words = message.match(/{[^}]+}/g); @@ -9,14 +11,11 @@ export const msgParams = (message: string, params: (string | number)[]): string }; export const containsDiscordLink = (content: string): boolean => { - const discordLinkRegex = /http(s?):\/\/(www\.|canary\.|ptb\.)?discord.com\/channels(\/\d*){3}$/gi; return discordLinkRegex.test(content); }; export const extractDiscordLink = (content: string): string | string[] | null => { - const discordLinkRegex = /http(s?):\/\/(www\.|canary\.|ptb\.)?discord.com\/channels(\/\d*){3}/gi; const discordLinks = content.match(discordLinkRegex); - if (discordLinks) return discordLinks; return null; }; \ No newline at end of file From 940241f8ddc3f3dd4d685715be7ed2e2512de404 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20H?= Date: Tue, 20 Jun 2023 16:32:40 +0200 Subject: [PATCH 08/13] refactor(message.util.ts): use match instead of test for containsDiscordLink function --- src/utils/message/message.util.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/message/message.util.ts b/src/utils/message/message.util.ts index a0372db4..1f35c7fe 100644 --- a/src/utils/message/message.util.ts +++ b/src/utils/message/message.util.ts @@ -11,7 +11,7 @@ export const msgParams = (message: string, params: (string | number)[]): string }; export const containsDiscordLink = (content: string): boolean => { - return discordLinkRegex.test(content); + return content.match(discordLinkRegex) !== null; }; export const extractDiscordLink = (content: string): string | string[] | null => { From 0ebb1af260a2f8f05216710a33c4008edba7eea1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20H?= Date: Tue, 20 Jun 2023 16:39:20 +0200 Subject: [PATCH 09/13] feat(utils): add getMessageFromLink function to get a message instance from a Discord message link test(utils): add test for getMessageFromLink function to check if it returns an instance of Message --- .../_test/get-message-instance.test.ts | 10 ++++++++ src/utils/message/index.ts | 2 +- src/utils/message/message.util.ts | 23 +++++++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 src/utils/message/_test/get-message-instance.test.ts diff --git a/src/utils/message/_test/get-message-instance.test.ts b/src/utils/message/_test/get-message-instance.test.ts new file mode 100644 index 00000000..1536056c --- /dev/null +++ b/src/utils/message/_test/get-message-instance.test.ts @@ -0,0 +1,10 @@ +import { describe, expect, it } from "vitest"; +import { getMessageFromLink } from "#/utils/message"; +import { Message } from "discord.js"; + +describe("isDiscordLink function", () => { + it("should return instance of Message", async() => { + const message = await getMessageFromLink("https://discord.com/channels/732251741999071303/786216771723198514/803532192793493544"); + expect(message).toBeInstanceOf(Message); + }); +}); \ No newline at end of file diff --git a/src/utils/message/index.ts b/src/utils/message/index.ts index 275320ab..8232d19c 100644 --- a/src/utils/message/index.ts +++ b/src/utils/message/index.ts @@ -1 +1 @@ -export { msgParams, containsDiscordLink, extractDiscordLink } from "./message.util"; \ No newline at end of file +export { msgParams, containsDiscordLink, extractDiscordLink, getMessageFromLink } from "./message.util"; \ No newline at end of file diff --git a/src/utils/message/message.util.ts b/src/utils/message/message.util.ts index 1f35c7fe..9769d96a 100644 --- a/src/utils/message/message.util.ts +++ b/src/utils/message/message.util.ts @@ -1,4 +1,6 @@ +import type { Message } from "discord.js"; import { discordLinkRegex } from "./message.type"; +import { client } from "#/client"; export const msgParams = (message: string, params: (string | number)[]): string => { const words = message.match(/{[^}]+}/g); @@ -18,4 +20,25 @@ export const extractDiscordLink = (content: string): string | string[] | null => const discordLinks = content.match(discordLinkRegex); if (discordLinks) return discordLinks; return null; +}; + +export const getMessageFromLink = async(link: string): Promise | null> => { + const ids = [...link.match(/(\d+)/g) ?? []]; + + if (ids.length !== 3) return null; + + const guildId = ids[0]; + const channelId = ids[1]; + const messageId = ids[2]; + + const guild = await client.guilds.fetch(guildId); + if (!guild) return null; + + const channel = await guild.channels.fetch(channelId); + if (!channel || !channel.isTextBased()) return null; + + const message = await channel.messages.fetch(messageId); + if (!message) return null; + + return message; }; \ No newline at end of file From 19721b461728a8a5b7f9d71b05c29505f4e61d6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20H?= Date: Tue, 20 Jun 2023 16:40:34 +0200 Subject: [PATCH 10/13] test(get-message-instance.test.ts): add tests for PTB and Canary links and non-discord links --- .../message/_test/get-message-instance.test.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/utils/message/_test/get-message-instance.test.ts b/src/utils/message/_test/get-message-instance.test.ts index 1536056c..5c8346e9 100644 --- a/src/utils/message/_test/get-message-instance.test.ts +++ b/src/utils/message/_test/get-message-instance.test.ts @@ -7,4 +7,19 @@ describe("isDiscordLink function", () => { const message = await getMessageFromLink("https://discord.com/channels/732251741999071303/786216771723198514/803532192793493544"); expect(message).toBeInstanceOf(Message); }); + + it("should return instance of Message with PTB link", async() => { + const message = await getMessageFromLink("https://ptb.discord.com/channels/732251741999071303/786216771723198514/803532192793493544"); + expect(message).toBeInstanceOf(Message); + }); + + it("should return instance of Message with Canary link", async() => { + const message = await getMessageFromLink("https://canary.discord.com/channels/732251741999071303/786216771723198514/803532192793493544"); + expect(message).toBeInstanceOf(Message); + }); + + it("should return null when the link is not a discord link", async() => { + const message = await getMessageFromLink("https://www.youtube.com/watch?v=dQw4w9WgXcQ"); + expect(message).toBe(null); + }); }); \ No newline at end of file From 0099e2dcf5f56205fc500afc28eb464368c79dd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20H?= Date: Tue, 11 Jul 2023 13:06:26 +0200 Subject: [PATCH 11/13] test(contains-discord-link.test.ts): update test descriptions and link examples chore(contains-discord-link.test.ts): remove unnecessary test case --- .../message/_test/contains-discord-link.test.ts | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/utils/message/_test/contains-discord-link.test.ts b/src/utils/message/_test/contains-discord-link.test.ts index 72e88c2f..06bde3a5 100644 --- a/src/utils/message/_test/contains-discord-link.test.ts +++ b/src/utils/message/_test/contains-discord-link.test.ts @@ -4,29 +4,25 @@ import { containsDiscordLink } from "#/utils/message"; describe("isDiscordLink function", () => { it("should return true when the link is a discord canary link", () => { expect( - containsDiscordLink("Salut check : https://canary.discord.com/channels/732251741999071303/1113731433123565589/1113731587570413588") + containsDiscordLink("A discord canary link: https://canary.discord.com/channels/732251741999071303/1113731433123565589/1113731587570413588") ).toBe(true); }); it("should return true when the link is a discord ptb link", () => { expect( - containsDiscordLink("Salut check : https://ptb.discord.com/channels/732251741999071303/786216771723198514/1075749993631191110") + containsDiscordLink("A discord ptb link: https://ptb.discord.com/channels/732251741999071303/786216771723198514/1075749993631191110") ).toBe(true); }); it("should return true when the link is a discord link", () => { - expect(containsDiscordLink("Salut check : https://discord.com/channels/732251741999071303/786216771723198514/803532192793493544")).toBe(true); + expect(containsDiscordLink("A discord link: https://discord.com/channels/732251741999071303/786216771723198514/803532192793493544")).toBe(true); }); it("should return false because is not valid", () => { - expect(containsDiscordLink("Salut check : https://discord.com/channels/732251741999071303")).toBe(false); + expect(containsDiscordLink("A invalid discord link: https://discord.com/channels/732251741999071303")).toBe(false); }); it("should return false because is litteraly not a discord link", () => { - expect(containsDiscordLink("Salut check la superbe vidéo: https://www.youtube.com/watch?v=dQw4w9WgXcQ")).toBe(false); - }); - - it("should return false when the link is not a discord link", () => { - expect(containsDiscordLink("Ahah https://fakediscord.com/channels/732251741999071303/1113731433123565589/1113731587570413588")).toBe(false); + expect(containsDiscordLink("A link that not discord: https://www.youtube.com/watch?v=dQw4w9WgXcQ")).toBe(false); }); }); \ No newline at end of file From 82394b37679097c85c939718e6d0cae28a229981 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20H?= Date: Tue, 11 Jul 2023 13:22:11 +0200 Subject: [PATCH 12/13] chore(contains-discord-link.test.ts): remove contains-discord-link.test.ts file chore(extract-discord-link.test.ts): update tests for extractDiscordLink function chore(index.ts): remove containsDiscordLink from export chore(message.type.ts): add DiscordMessage type chore(message.util.ts): update extractDiscordLink function to return DiscordMessage or empty array --- .../_test/contains-discord-link.test.ts | 28 -------------- .../_test/extract-discord-link.test.ts | 37 ++++++++++++------- src/utils/message/index.ts | 2 +- src/utils/message/message.type.ts | 10 ++++- src/utils/message/message.util.ts | 19 ++++++---- 5 files changed, 45 insertions(+), 51 deletions(-) delete mode 100644 src/utils/message/_test/contains-discord-link.test.ts diff --git a/src/utils/message/_test/contains-discord-link.test.ts b/src/utils/message/_test/contains-discord-link.test.ts deleted file mode 100644 index 06bde3a5..00000000 --- a/src/utils/message/_test/contains-discord-link.test.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { describe, expect, it } from "vitest"; -import { containsDiscordLink } from "#/utils/message"; - -describe("isDiscordLink function", () => { - it("should return true when the link is a discord canary link", () => { - expect( - containsDiscordLink("A discord canary link: https://canary.discord.com/channels/732251741999071303/1113731433123565589/1113731587570413588") - ).toBe(true); - }); - - it("should return true when the link is a discord ptb link", () => { - expect( - containsDiscordLink("A discord ptb link: https://ptb.discord.com/channels/732251741999071303/786216771723198514/1075749993631191110") - ).toBe(true); - }); - - it("should return true when the link is a discord link", () => { - expect(containsDiscordLink("A discord link: https://discord.com/channels/732251741999071303/786216771723198514/803532192793493544")).toBe(true); - }); - - it("should return false because is not valid", () => { - expect(containsDiscordLink("A invalid discord link: https://discord.com/channels/732251741999071303")).toBe(false); - }); - - it("should return false because is litteraly not a discord link", () => { - expect(containsDiscordLink("A link that not discord: https://www.youtube.com/watch?v=dQw4w9WgXcQ")).toBe(false); - }); -}); \ No newline at end of file diff --git a/src/utils/message/_test/extract-discord-link.test.ts b/src/utils/message/_test/extract-discord-link.test.ts index fe8a88ad..0abc1039 100644 --- a/src/utils/message/_test/extract-discord-link.test.ts +++ b/src/utils/message/_test/extract-discord-link.test.ts @@ -1,21 +1,32 @@ import { describe, it, expect } from "vitest"; import { extractDiscordLink } from "#/utils/message"; -describe("msgParams function", () => { +describe("extractDiscordLink function", () => { + it("should correctly extract discord canary link", () => { + expect(extractDiscordLink("https://canary.discord.com/channels/732251741999071303/973634573936246834/1128283771691601942")).toEqual({ + guildID: "732251741999071303", + channelID: "973634573936246834", + messageID: "1128283771691601942" + }); + }); + + it("should correctly extract discord ptb link", () => { + expect(extractDiscordLink("https://canary.discord.com/channels/732251741999071303/977731788002697326/1119643273695346820")).toEqual({ + guildID: "732251741999071303", + channelID: "977731788002697326", + messageID: "1119643273695346820" + }); + }); + it("should correctly extract discord link", () => { - expect( - extractDiscordLink([ - "Salut check : https://discord.com/channels/732251741999071303/786216771723198514/803532192793493544", - "et https://canary.discord.com/channels/732251741999071303/786216771723198514/803532192793493544"].join(" ")) - ).toEqual([ - "https://discord.com/channels/732251741999071303/786216771723198514/803532192793493544", - "https://canary.discord.com/channels/732251741999071303/786216771723198514/803532192793493544" - ]); + expect(extractDiscordLink("https://discord.com/channels/732251741999071303/786216771723198514/803532192793493544")).toEqual({ + guildID: "732251741999071303", + channelID: "786216771723198514", + messageID: "803532192793493544" + }); }); - it("should return null when no discord link is found", () => { - expect( - extractDiscordLink("Salut check : https://www.youtube.com/watch?v=dQw4w9WgXcQ") - ).toBe(null); + it("should return empty array when no discord link is found", () => { + expect(extractDiscordLink("https://www.youtube.com/watch?v=dQw4w9WgXcQ")).toStrictEqual([]); }); }); \ No newline at end of file diff --git a/src/utils/message/index.ts b/src/utils/message/index.ts index 8232d19c..cb6e8bfd 100644 --- a/src/utils/message/index.ts +++ b/src/utils/message/index.ts @@ -1 +1 @@ -export { msgParams, containsDiscordLink, extractDiscordLink, getMessageFromLink } from "./message.util"; \ No newline at end of file +export { msgParams, extractDiscordLink, getMessageFromLink } from "./message.util"; \ No newline at end of file diff --git a/src/utils/message/message.type.ts b/src/utils/message/message.type.ts index ce8892c0..2b1fa433 100644 --- a/src/utils/message/message.type.ts +++ b/src/utils/message/message.type.ts @@ -1 +1,9 @@ -export const discordLinkRegex = /http(s?):\/\/(www\.|canary\.|ptb\.)?discord.com\/channels(\/\d*){3}/gi; \ No newline at end of file +import type { Snowflake } from "discord.js"; + +export const discordLinkRegex = /http(s?):\/\/(www\.|canary\.|ptb\.)?discord.com\/channels(\/\d*){3}/gi; + +export type DiscordMessage = { + guildID: Snowflake; + channelID: Snowflake; + messageID: Snowflake; +} \ No newline at end of file diff --git a/src/utils/message/message.util.ts b/src/utils/message/message.util.ts index 9769d96a..4fc19a4b 100644 --- a/src/utils/message/message.util.ts +++ b/src/utils/message/message.util.ts @@ -1,6 +1,7 @@ import type { Message } from "discord.js"; -import { discordLinkRegex } from "./message.type"; +import type { DiscordMessage } from "./message.type"; import { client } from "#/client"; +import { messageUrlRegex } from "#/events/message-link-reaction/message-link-reaction.const"; export const msgParams = (message: string, params: (string | number)[]): string => { const words = message.match(/{[^}]+}/g); @@ -12,14 +13,16 @@ export const msgParams = (message: string, params: (string | number)[]): string return message; }; -export const containsDiscordLink = (content: string): boolean => { - return content.match(discordLinkRegex) !== null; -}; +export const extractDiscordLink = (content: string): DiscordMessage | [] => { + if (!content.match(messageUrlRegex)) return []; + const [guildID, channelID, messageID] = [...content.match(/(\d+)/g) ?? []]; + if (!guildID || !channelID || !messageID) return []; -export const extractDiscordLink = (content: string): string | string[] | null => { - const discordLinks = content.match(discordLinkRegex); - if (discordLinks) return discordLinks; - return null; + return { + guildID, + channelID, + messageID + }; }; export const getMessageFromLink = async(link: string): Promise | null> => { From cbdc681e3002b99fb5143affe3ed39612471f9ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20H?= Date: Tue, 11 Jul 2023 14:14:52 +0200 Subject: [PATCH 13/13] fix(resolve.cmd.ts): change function name from containsDiscordLink to extractDiscordLink fix(resolve.cmd.ts): change type of extracted message from array to DiscordMessage | null fix(resolve.cmd.ts): change variable name from message to fetchedMessage --- .../forum/[sub-commands]/resolve.cmd.ts | 20 ++++++++++--------- src/commands/forum/forum.builder.ts | 2 ++ src/utils/message/message.util.ts | 6 +++--- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/commands/forum/[sub-commands]/resolve.cmd.ts b/src/commands/forum/[sub-commands]/resolve.cmd.ts index ac4d4402..9d45de87 100644 --- a/src/commands/forum/[sub-commands]/resolve.cmd.ts +++ b/src/commands/forum/[sub-commands]/resolve.cmd.ts @@ -6,9 +6,11 @@ import { commands } from "#/configs/message/command"; import { ChannelType, ForumChannel } from "discord.js"; import { logger } from "#/utils/logger"; import { userWithId } from "#/utils/discord/user"; -import { containsDiscordLink } from "#/utils/message/message.util"; +import { extractDiscordLink } from "#/utils/message/message.util"; +import type { DiscordMessage } from "#/utils/message/message.type"; export const execute: CommandExecute = async(command) => { + const channel = command.channel; if (channel?.type !== ChannelType.PublicThread || !(channel.parent instanceof ForumChannel)) { @@ -21,7 +23,9 @@ export const execute: CommandExecute = async(command) => { const answerLink = command.options.getString(commands.forum.subcmds.resolve.options.answer.name, true); - if (!containsDiscordLink(answerLink)) { + const message: DiscordMessage | null = extractDiscordLink(answerLink); + + if (!message) { void command.reply({ embeds: [simpleEmbed(commands.forum.exec.resolve.isntDiscordMessageLink, "error")], ephemeral: true @@ -29,9 +33,7 @@ export const execute: CommandExecute = async(command) => { return; } - const ids = [...answerLink.match(/(\d+)/g) ?? []]; - - if (ids[0] !== channel.guildId || ids[1] !== channel.id) { + if (message.guildID !== channel.guildId || message.channelID !== channel.id) { void command.reply({ embeds: [simpleEmbed(commands.forum.exec.resolve.badLocation, "error")], ephemeral: true @@ -39,10 +41,10 @@ export const execute: CommandExecute = async(command) => { return; } - let message: Message; + let fetchedMessage: Message; try { - message = await channel.messages.fetch(ids[2]); + fetchedMessage = await channel.messages.fetch(message.messageID); } catch (error) { void command.reply({ embeds: [simpleEmbed(commands.forum.exec.resolve.unknownMessage, "error")], @@ -51,7 +53,7 @@ export const execute: CommandExecute = async(command) => { return; } - if (!message.pinnable) { + if (!fetchedMessage.pinnable) { void command.reply({ embeds: [simpleEmbed(commands.forum.exec.resolve.unpinnableMessage, "error")], ephemeral: true @@ -59,7 +61,7 @@ export const execute: CommandExecute = async(command) => { return; } - await message.pin(); + await fetchedMessage.pin(); await command.reply({ embeds: [simpleEmbed(msgParams(commands.forum.exec.resolve.succes, [answerLink]))] }); diff --git a/src/commands/forum/forum.builder.ts b/src/commands/forum/forum.builder.ts index 3afd0a82..647df93d 100644 --- a/src/commands/forum/forum.builder.ts +++ b/src/commands/forum/forum.builder.ts @@ -5,6 +5,8 @@ import type { GuildsCommand } from "#/utils/handler/command/command.type"; export const guilds: GuildsCommand = ["pro"]; +export const enableInDev = true; + export const slashCommand: SlashCommandDefition = new SlashCommandBuilder() .setName(commands.forum.name) .setDescription(commands.forum.description) diff --git a/src/utils/message/message.util.ts b/src/utils/message/message.util.ts index 4fc19a4b..7633bba3 100644 --- a/src/utils/message/message.util.ts +++ b/src/utils/message/message.util.ts @@ -13,10 +13,10 @@ export const msgParams = (message: string, params: (string | number)[]): string return message; }; -export const extractDiscordLink = (content: string): DiscordMessage | [] => { - if (!content.match(messageUrlRegex)) return []; +export const extractDiscordLink = (content: string): DiscordMessage | null => { + if (!content.match(messageUrlRegex)) return null; const [guildID, channelID, messageID] = [...content.match(/(\d+)/g) ?? []]; - if (!guildID || !channelID || !messageID) return []; + if (!guildID || !channelID || !messageID) return null; return { guildID,