diff --git a/backend/src/plugins/Logs/util/log.ts b/backend/src/plugins/Logs/util/log.ts index ab6a29e4..6df069e8 100644 --- a/backend/src/plugins/Logs/util/log.ts +++ b/backend/src/plugins/Logs/util/log.ts @@ -1,4 +1,4 @@ -import { MessageEmbedOptions, MessageMentionTypes, Snowflake, TextChannel } from "discord.js"; +import { MessageCreateOptions, MessageMentionTypes, Snowflake, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; import { allowTimeout } from "../../../RegExpRunner"; import { ILogTypeData, LogsPluginType, TLogChannel, TLogChannelMap } from "../types"; @@ -141,7 +141,7 @@ export async function log( const buffer = pluginData.state.buffers.get(channelId)!; buffer.push({ content: typeof message === "string" ? message : message.content || "", - embeds: typeof message === "string" ? [] : ((message.embeds || []) as MessageEmbedOptions[]), + embeds: typeof message === "string" ? [] : ((message.embeds || []) as MessageCreateOptions[]), }); } } diff --git a/backend/src/plugins/ModActions/commands/CasesModCmd.ts b/backend/src/plugins/ModActions/commands/CasesModCmd.ts index 14e89870..60f11c29 100644 --- a/backend/src/plugins/ModActions/commands/CasesModCmd.ts +++ b/backend/src/plugins/ModActions/commands/CasesModCmd.ts @@ -1,4 +1,4 @@ -import { MessageEmbedOptions, User } from "discord.js"; +import { EmbedData, MessageCreateOptions, User } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage } from "../../../pluginUtils"; import { emptyEmbedValue, resolveUser, trimLines } from "../../../utils"; @@ -54,7 +54,7 @@ export const CasesModCmd = modActionsCmd({ const lastCaseNum = page * casesPerPage; const title = `Most recent cases ${firstCaseNum}-${lastCaseNum} of ${totalCases} by ${modName}`; - const embed: MessageEmbedOptions = { + const embed: EmbedData = { author: { name: title, iconURL: mod instanceof User ? mod.displayAvatarURL() : undefined, diff --git a/backend/src/plugins/ModActions/commands/CasesUserCmd.ts b/backend/src/plugins/ModActions/commands/CasesUserCmd.ts index c6646711..56777088 100644 --- a/backend/src/plugins/ModActions/commands/CasesUserCmd.ts +++ b/backend/src/plugins/ModActions/commands/CasesUserCmd.ts @@ -1,4 +1,4 @@ -import { MessageEmbedOptions, User } from "discord.js"; +import { EmbedData, User } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { CaseTypes } from "../../../data/CaseTypes"; import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; @@ -116,13 +116,13 @@ export const CasesUserCmd = modActionsCmd({ const chunkStart = i * linesPerChunk + 1; const chunkEnd = Math.min((i + 1) * linesPerChunk, lines.length); - const embed: MessageEmbedOptions = { + const embed: EmbedData = { author: { name: lineChunks.length === 1 ? `Cases for ${userName} (${lines.length} total)` : `Cases ${chunkStart}–${chunkEnd} of ${lines.length} for ${userName}`, - icon_url: user instanceof User ? user.displayAvatarURL() : undefined, + iconURL: user instanceof User ? user.displayAvatarURL() : undefined, }, fields: [ ...getChunkedEmbedFields(emptyEmbedValue, linesInChunk.join("\n")), diff --git a/backend/src/plugins/Post/commands/PostEmbedCmd.ts b/backend/src/plugins/Post/commands/PostEmbedCmd.ts index e822cd3b..ee115a90 100644 --- a/backend/src/plugins/Post/commands/PostEmbedCmd.ts +++ b/backend/src/plugins/Post/commands/PostEmbedCmd.ts @@ -1,4 +1,4 @@ -import { MessageEmbedOptions } from "discord.js"; +import { EmbedData } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage } from "../../../pluginUtils"; import { isValidEmbed, trimLines } from "../../../utils"; @@ -46,7 +46,7 @@ export const PostEmbedCmd = postCmd({ } } - let embed: MessageEmbedOptions = {}; + let embed: EmbedData = {}; if (args.title) embed.title = args.title; if (color) embed.color = color; diff --git a/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts b/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts index 053389db..6b0d768c 100644 --- a/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts +++ b/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts @@ -28,7 +28,7 @@ export function createStarboardEmbedFromMessage( embed.color = color; } - embed.author.icon_url = msg.author.displayAvatarURL({ dynamic: true }); + embed.author.iconURL = msg.author.displayAvatarURL(); // The second condition here checks for messages with only an image link that is then embedded. // The message content in that case is hidden by the Discord client, so we hide it here too. diff --git a/backend/src/plugins/Starboard/util/saveMessageToStarboard.ts b/backend/src/plugins/Starboard/util/saveMessageToStarboard.ts index ed2bd3f9..039ed2a0 100644 --- a/backend/src/plugins/Starboard/util/saveMessageToStarboard.ts +++ b/backend/src/plugins/Starboard/util/saveMessageToStarboard.ts @@ -1,4 +1,4 @@ -import { Message, MessageEmbedOptions, Snowflake, TextChannel } from "discord.js"; +import { EmbedData, Message, Snowflake, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; import { StarboardPluginType, TStarboardOpts } from "../types"; import { createStarboardEmbedFromMessage } from "./createStarboardEmbedFromMessage"; @@ -16,6 +16,6 @@ export async function saveMessageToStarboard( const embed = createStarboardEmbedFromMessage(msg, Boolean(starboard.copy_full_embed), starboard.color); embed.fields!.push(createStarboardPseudoFooterForMessage(starboard, msg, starboard.star_emoji![0], starCount)); - const starboardMessage = await (channel as TextChannel).send({ embeds: [embed as MessageEmbedOptions] }); + const starboardMessage = await (channel as TextChannel).send({ embeds: [embed as EmbedData] }); await pluginData.state.starboardMessages.createStarboardMessage(channel.id, msg.id, starboardMessage.id); } diff --git a/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts b/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts index 639f9b6f..bc17c51f 100644 --- a/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts @@ -58,7 +58,7 @@ export async function getChannelInfoEmbed( embed.author = { name: `${channelType}: ${channel.name}`, - icon_url: icon, + iconURL: icon, }; let channelName = `#${channel.name}`; diff --git a/backend/src/plugins/Utility/functions/getInviteInfoEmbed.ts b/backend/src/plugins/Utility/functions/getInviteInfoEmbed.ts index 84277c64..c0241b0b 100644 --- a/backend/src/plugins/Utility/functions/getInviteInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getInviteInfoEmbed.ts @@ -36,7 +36,7 @@ export async function getInviteInfoEmbed( }; if (invite.guild.icon) { - embed.author.icon_url = `https://cdn.discordapp.com/icons/${invite.guild.id}/${invite.guild.icon}.png?size=256`; + embed.author.iconURL = `https://cdn.discordapp.com/icons/${invite.guild.id}/${invite.guild.icon}.png?size=256`; } if (invite.guild.description) { diff --git a/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts b/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts index 9d3c6d68..35140759 100644 --- a/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts @@ -31,7 +31,7 @@ export async function getMessageInfoEmbed( embed.author = { name: `Message: ${message.id}`, - icon_url: MESSAGE_ICON, + iconURL: MESSAGE_ICON, }; const createdAt = moment.utc(message.createdAt, "x"); diff --git a/backend/src/plugins/Utility/functions/getRoleInfoEmbed.ts b/backend/src/plugins/Utility/functions/getRoleInfoEmbed.ts index 7edab97d..2a12d1f3 100644 --- a/backend/src/plugins/Utility/functions/getRoleInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getRoleInfoEmbed.ts @@ -20,7 +20,7 @@ export async function getRoleInfoEmbed( embed.author = { name: `Role: ${role.name}`, - icon_url: MENTION_ICON, + iconURL: MENTION_ICON, }; embed.color = role.color; diff --git a/backend/src/plugins/Utility/functions/getSnowflakeInfoEmbed.ts b/backend/src/plugins/Utility/functions/getSnowflakeInfoEmbed.ts index 3ef1777f..6ffb454f 100644 --- a/backend/src/plugins/Utility/functions/getSnowflakeInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getSnowflakeInfoEmbed.ts @@ -21,7 +21,7 @@ export async function getSnowflakeInfoEmbed( embed.author = { name: `Snowflake: ${snowflake}`, - icon_url: SNOWFLAKE_ICON, + iconURL: SNOWFLAKE_ICON, }; if (showUnknownWarning) { diff --git a/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts b/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts index dd75d807..27fb274e 100644 --- a/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts @@ -47,7 +47,7 @@ export async function getUserInfoEmbed( }; const avatarURL = user.displayAvatarURL(); - embed.author.icon_url = avatarURL; + embed.author.iconURL = avatarURL; const createdAt = moment.utc(user.createdAt, "x"); const tzCreatedAt = requestMemberId diff --git a/backend/src/plugins/Utility/search.ts b/backend/src/plugins/Utility/search.ts index 7fcccb99..ac98f3f3 100644 --- a/backend/src/plugins/Utility/search.ts +++ b/backend/src/plugins/Utility/search.ts @@ -1,8 +1,11 @@ import { + ActionRowBuilder, + ButtonBuilder, + ButtonStyle, GuildMember, Message, - MessageActionRow, - MessageButton, + MessageActionRowComponent, + MessageActionRowComponentBuilder, MessageComponentInteraction, PermissionsBitField, Snowflake, @@ -169,23 +172,23 @@ export async function displaySearch( // Set up pagination reactions if needed. The reactions are cleared after a timeout. if (searchResult.totalResults > perPage) { const idMod = `${searchMsg.id}:${moment.utc().valueOf()}`; - const buttons: MessageButton[] = []; + const buttons: ButtonBuilder[] = []; buttons.push( - new MessageButton() - .setStyle("SECONDARY") + new ButtonBuilder() + .setStyle(ButtonStyle.Secondary) .setEmoji("⬅") .setCustomId(`previousButton:${idMod}`) .setDisabled(currentPage === 1), - new MessageButton() - .setStyle("SECONDARY") + new ButtonBuilder() + .setStyle(ButtonStyle.Secondary) .setEmoji("➡") .setCustomId(`nextButton:${idMod}`) .setDisabled(currentPage === searchResult.lastPage), - new MessageButton().setStyle("SECONDARY").setEmoji("🔄").setCustomId(`reloadButton:${idMod}`), + new ButtonBuilder().setStyle(ButtonStyle.Secondary).setEmoji("🔄").setCustomId(`reloadButton:${idMod}`), ); - const row = new MessageActionRow().addComponents(buttons); + const row = new ActionRowBuilder().addComponents(buttons); await searchMsg.edit({ content: result, components: [row] }); const collector = searchMsg.createMessageComponentCollector({ time: 2 * MINUTES }); diff --git a/backend/src/utils.ts b/backend/src/utils.ts index e4a2f5b2..ac44706b 100644 --- a/backend/src/utils.ts +++ b/backend/src/utils.ts @@ -3,6 +3,9 @@ import { Client, Constants, DiscordAPIError, + Embed, + EmbedData, + EmbedType, Emoji, escapeCodeBlock, Guild, @@ -16,10 +19,8 @@ import { InviteGuild, LimitedCollection, Message, - MessageEmbed, - MessageEmbedOptions, + MessageCreateOptions, MessageMentionOptions, - MessageOptions, PartialChannelData, PartialMessage, Snowflake, @@ -391,8 +392,7 @@ export const zEmbedInput = z.object({ .nullable(), }); -export type EmbedWith = MessageEmbedOptions & - Pick, T>; +export type EmbedWith = EmbedData & Pick, T>; export const zStrictMessageContent = z.object({ content: z.string().optional(), @@ -405,7 +405,7 @@ export type ZStrictMessageContent = z.infer; export type StrictMessageContent = { content?: string; tts?: boolean; - embeds?: MessageEmbedOptions[]; + embeds?: EmbedData[]; }; export const tStrictMessageContent = t.type({ @@ -647,7 +647,7 @@ interface MatchedURL extends URL { } export function getUrlsInString(str: string, onlyUnique = false): MatchedURL[] { - let matches = [...str.match(urlRegex)]; + let matches = [...(str.match(urlRegex) ?? [])]; if (onlyUnique) { matches = unique(matches); } @@ -1405,7 +1405,7 @@ export async function resolveStickerId(bot: Client, id: Snowflake): Promise { return waitForButtonConfirm(channel, content, { restrictToId: userId }); } @@ -1415,7 +1415,7 @@ export function messageSummary(msg: SavedMessage) { let result = "```\n" + (msg.data.content ? escapeCodeBlock(msg.data.content) : "") + "```"; // Rich embed - const richEmbed = (msg.data.embeds || []).find((e) => (e as MessageEmbed).type === "rich"); + const richEmbed = (msg.data.embeds || []).find((e) => (e as EmbedData).type === EmbedType.Rich); if (richEmbed) result += "Embed:```" + escapeCodeBlock(JSON.stringify(richEmbed)) + "```"; // Attachments diff --git a/backend/src/utils/calculateEmbedSize.ts b/backend/src/utils/calculateEmbedSize.ts index 124aa03b..fd40c2d4 100644 --- a/backend/src/utils/calculateEmbedSize.ts +++ b/backend/src/utils/calculateEmbedSize.ts @@ -1,4 +1,4 @@ -import { MessageEmbedOptions } from "discord.js"; +import { EmbedData } from "discord.js"; function sumStringLengthsRecursively(obj: any): number { if (obj == null) return 0; @@ -12,6 +12,6 @@ function sumStringLengthsRecursively(obj: any): number { return 0; } -export function calculateEmbedSize(embed: MessageEmbedOptions): number { +export function calculateEmbedSize(embed: EmbedData): number { return sumStringLengthsRecursively(embed); } diff --git a/backend/src/utils/createPaginatedMessage.ts b/backend/src/utils/createPaginatedMessage.ts index e711c620..74a77c19 100644 --- a/backend/src/utils/createPaginatedMessage.ts +++ b/backend/src/utils/createPaginatedMessage.ts @@ -1,11 +1,13 @@ import { Client, + GuildTextBasedChannel, Message, + MessageCreateOptions, MessageEditOptions, - MessageOptions, MessageReaction, PartialMessageReaction, PartialUser, + TextBasedChannel, TextChannel, User, } from "discord.js"; @@ -13,7 +15,7 @@ import { Awaitable } from "knub/dist/utils"; import { MINUTES, noop } from "../utils"; import Timeout = NodeJS.Timeout; -export type LoadPageFn = (page: number) => Awaitable; +export type LoadPageFn = (page: number) => Awaitable; export interface PaginateMessageOpts { timeout: number; @@ -27,7 +29,7 @@ const defaultOpts: PaginateMessageOpts = { export async function createPaginatedMessage( client: Client, - channel: TextChannel | User, + channel: TextBasedChannel | User, totalPages: number, loadPageFn: LoadPageFn, opts: Partial = {}, diff --git a/backend/src/utils/messageHasContent.ts b/backend/src/utils/messageHasContent.ts index b70918be..f5eeb72e 100644 --- a/backend/src/utils/messageHasContent.ts +++ b/backend/src/utils/messageHasContent.ts @@ -1,4 +1,5 @@ -import { MessageOptions } from "discord.js"; +import { MessageOptions } from "child_process"; +import { MessageCreateOptions, MessagePayload } from "discord.js"; function embedHasContent(embed: any) { for (const [key, value] of Object.entries(embed)) { @@ -18,7 +19,7 @@ function embedHasContent(embed: any) { return false; } -export function messageHasContent(content: string | MessageOptions): boolean { +export function messageHasContent(content: string | MessageCreateOptions): boolean { if (typeof content === "string") { return content.trim() !== ""; } diff --git a/backend/src/utils/messageIsEmpty.ts b/backend/src/utils/messageIsEmpty.ts index d1b1f117..e2c0ef3a 100644 --- a/backend/src/utils/messageIsEmpty.ts +++ b/backend/src/utils/messageIsEmpty.ts @@ -1,6 +1,6 @@ -import { MessageOptions } from "discord.js"; +import { MessageCreateOptions } from "discord.js"; import { messageHasContent } from "./messageHasContent"; -export function messageIsEmpty(content: string | MessageOptions): boolean { +export function messageIsEmpty(content: string | MessageCreateOptions): boolean { return !messageHasContent(content); }