diff --git a/backend/src/data/entities/ScheduledPost.ts b/backend/src/data/entities/ScheduledPost.ts index 1729bca7..c4b31c52 100644 --- a/backend/src/data/entities/ScheduledPost.ts +++ b/backend/src/data/entities/ScheduledPost.ts @@ -1,4 +1,4 @@ -import { MessageAttachment } from "discord.js"; +import { Attachment } from "discord.js"; import { Column, Entity, PrimaryColumn, PrimaryGeneratedColumn } from "typeorm"; import { StrictMessageContent } from "../../utils"; @@ -17,7 +17,7 @@ export class ScheduledPost { @Column("simple-json") content: StrictMessageContent; - @Column("simple-json") attachments: MessageAttachment[]; + @Column("simple-json") attachments: Attachment[]; @Column({ type: String, nullable: true }) post_at: string | null; diff --git a/backend/src/plugins/Automod/triggers/matchAttachmentType.ts b/backend/src/plugins/Automod/triggers/matchAttachmentType.ts index 142e7b0e..80154ec9 100644 --- a/backend/src/plugins/Automod/triggers/matchAttachmentType.ts +++ b/backend/src/plugins/Automod/triggers/matchAttachmentType.ts @@ -1,4 +1,4 @@ -import { Snowflake, TextChannel, Util } from "discord.js"; +import { escapeInlineCode, Snowflake, TextChannel } from "discord.js"; import * as t from "io-ts"; import { asSingleLine, messageSummary, verboseChannelMention } from "../../../utils"; import { automodTrigger } from "../helpers"; @@ -71,7 +71,7 @@ export const MatchAttachmentTypeTrigger = automodTrigger()({ return ( asSingleLine(` - Matched attachment type \`${Util.escapeInlineCode(matchResult.extra.matchedType)}\` + Matched attachment type \`${escapeInlineCode(matchResult.extra.matchedType)}\` (${matchResult.extra.mode === "blacklist" ? "blacklisted" : "not in whitelist"}) in message (\`${contexts[0].message!.id}\`) in ${prettyChannel}: `) + messageSummary(contexts[0].message!) diff --git a/backend/src/plugins/Automod/triggers/matchLinks.ts b/backend/src/plugins/Automod/triggers/matchLinks.ts index 248a19f3..f1270e7c 100644 --- a/backend/src/plugins/Automod/triggers/matchLinks.ts +++ b/backend/src/plugins/Automod/triggers/matchLinks.ts @@ -1,4 +1,3 @@ -import { Util } from "discord.js"; import escapeStringRegexp from "escape-string-regexp"; import * as t from "io-ts"; import { allowTimeout } from "../../../RegExpRunner"; @@ -11,6 +10,7 @@ import { mergeRegexes } from "../../../utils/mergeRegexes"; import { mergeWordsIntoRegex } from "../../../utils/mergeWordsIntoRegex"; import { PhishermanPlugin } from "../../Phisherman/PhishermanPlugin"; import { phishermanDomainIsSafe } from "../../../data/Phisherman"; +import { escapeInlineCode } from "discord.js"; interface MatchResultType { type: MatchableTextType; @@ -186,7 +186,7 @@ export const MatchLinksTrigger = automodTrigger()({ renderMatchInformation({ pluginData, contexts, matchResult }) { const partialSummary = getTextMatchPartialSummary(pluginData, matchResult.extra.type, contexts[0]); - let information = `Matched link \`${Util.escapeInlineCode(matchResult.extra.link)}\``; + let information = `Matched link \`${escapeInlineCode(matchResult.extra.link)}\``; if (matchResult.extra.details) { information += ` ${matchResult.extra.details}`; } diff --git a/backend/src/plugins/Automod/triggers/matchMimeType.ts b/backend/src/plugins/Automod/triggers/matchMimeType.ts index 6e1b447e..6af0d381 100644 --- a/backend/src/plugins/Automod/triggers/matchMimeType.ts +++ b/backend/src/plugins/Automod/triggers/matchMimeType.ts @@ -1,7 +1,7 @@ import { automodTrigger } from "../helpers"; import * as t from "io-ts"; import { asSingleLine, messageSummary, verboseChannelMention } from "../../../utils"; -import { GuildChannel, Util } from "discord.js"; +import { escapeInlineCode, GuildChannel } from "discord.js"; interface MatchResultType { matchedType: string; @@ -71,7 +71,7 @@ export const MatchMimeTypeTrigger = automodTrigger()({ return ( asSingleLine(` - Matched MIME type \`${Util.escapeInlineCode(matchedType)}\` + Matched MIME type \`${escapeInlineCode(matchedType)}\` (${mode === "blacklist" ? "blacklisted" : "not in whitelist"}) in message (\`${message!.id}\`) in ${prettyChannel} `) + messageSummary(message!) diff --git a/backend/src/plugins/Automod/triggers/matchWords.ts b/backend/src/plugins/Automod/triggers/matchWords.ts index c7603496..c5ca79fc 100644 --- a/backend/src/plugins/Automod/triggers/matchWords.ts +++ b/backend/src/plugins/Automod/triggers/matchWords.ts @@ -1,4 +1,3 @@ -import { Util } from "discord.js"; import escapeStringRegexp from "escape-string-regexp"; import * as t from "io-ts"; import { normalizeText } from "../../../utils/normalizeText"; diff --git a/backend/src/plugins/Automod/triggers/threadArchive.ts b/backend/src/plugins/Automod/triggers/threadArchive.ts index d4ed631b..3e2d852f 100644 --- a/backend/src/plugins/Automod/triggers/threadArchive.ts +++ b/backend/src/plugins/Automod/triggers/threadArchive.ts @@ -1,5 +1,5 @@ import { Snowflake } from "discord-api-types/v9"; -import { User, Util } from "discord.js"; +import { escapeBold, User } from "discord.js"; import * as t from "io-ts"; import { tNullable } from "../../../utils"; import { automodTrigger } from "../helpers"; @@ -49,7 +49,7 @@ export const ThreadArchiveTrigger = automodTrigger()({ const parentName = matchResult.extra.matchedThreadParentName; const base = `Thread **#${threadName}** (\`${threadId}\`) has been archived in the **#${parentName}** (\`${parentId}\`) channel`; if (threadOwner) { - return `${base} by **${Util.escapeBold(threadOwner.tag)}** (\`${threadOwner.id}\`)`; + return `${base} by **${escapeBold(threadOwner.tag)}** (\`${threadOwner.id}\`)`; } return base; }, diff --git a/backend/src/plugins/Automod/triggers/threadCreate.ts b/backend/src/plugins/Automod/triggers/threadCreate.ts index c0ae6ad3..5c1b9ee0 100644 --- a/backend/src/plugins/Automod/triggers/threadCreate.ts +++ b/backend/src/plugins/Automod/triggers/threadCreate.ts @@ -1,5 +1,5 @@ import { Snowflake } from "discord-api-types/v9"; -import { User, Util } from "discord.js"; +import { escapeBold, User } from "discord.js"; import * as t from "io-ts"; import { automodTrigger } from "../helpers"; @@ -41,7 +41,7 @@ export const ThreadCreateTrigger = automodTrigger()({ const parentName = matchResult.extra.matchedThreadParentName; const base = `Thread **#${threadName}** (\`${threadId}\`) has been created in the **#${parentName}** (\`${parentId}\`) channel`; if (threadOwner) { - return `${base} by **${Util.escapeBold(threadOwner.tag)}** (\`${threadOwner.id}\`)`; + return `${base} by **${escapeBold(threadOwner.tag)}** (\`${threadOwner.id}\`)`; } return base; }, diff --git a/backend/src/plugins/Automod/triggers/threadDelete.ts b/backend/src/plugins/Automod/triggers/threadDelete.ts index cecb5862..3e1fd2dc 100644 --- a/backend/src/plugins/Automod/triggers/threadDelete.ts +++ b/backend/src/plugins/Automod/triggers/threadDelete.ts @@ -1,5 +1,5 @@ import { Snowflake } from "discord-api-types/v9"; -import { User, Util } from "discord.js"; +import { escapeBold, User } from "discord.js"; import * as t from "io-ts"; import { automodTrigger } from "../helpers"; @@ -40,7 +40,7 @@ export const ThreadDeleteTrigger = automodTrigger()({ const parentId = matchResult.extra.matchedThreadParentId; const parentName = matchResult.extra.matchedThreadParentName; if (threadOwner) { - return `Thread **#${threadName ?? "Unknown"}** (\`${threadId}\`) created by **${Util.escapeBold( + return `Thread **#${threadName ?? "Unknown"}** (\`${threadId}\`) created by **${escapeBold( threadOwner.tag, )}** (\`${threadOwner.id}\`) in the **#${parentName}** (\`${parentId}\`) channel has been deleted`; } diff --git a/backend/src/plugins/Automod/triggers/threadUnarchive.ts b/backend/src/plugins/Automod/triggers/threadUnarchive.ts index ce3adf81..e50e8186 100644 --- a/backend/src/plugins/Automod/triggers/threadUnarchive.ts +++ b/backend/src/plugins/Automod/triggers/threadUnarchive.ts @@ -1,5 +1,5 @@ import { Snowflake } from "discord-api-types/v9"; -import { User, Util } from "discord.js"; +import { escapeBold, User } from "discord.js"; import * as t from "io-ts"; import { tNullable } from "../../../utils"; import { automodTrigger } from "../helpers"; @@ -49,7 +49,7 @@ export const ThreadUnarchiveTrigger = automodTrigger()({ const parentName = matchResult.extra.matchedThreadParentName; const base = `Thread **#${threadName}** (\`${threadId}\`) has been unarchived in the **#${parentName}** (\`${parentId}\`) channel`; if (threadOwner) { - return `${base} by **${Util.escapeBold(threadOwner.tag)}** (\`${threadOwner.id}\`)`; + return `${base} by **${escapeBold(threadOwner.tag)}** (\`${threadOwner.id}\`)`; } return base; }, diff --git a/backend/src/plugins/Cases/functions/getCaseEmbed.ts b/backend/src/plugins/Cases/functions/getCaseEmbed.ts index 5a1b2ab8..45550ef8 100644 --- a/backend/src/plugins/Cases/functions/getCaseEmbed.ts +++ b/backend/src/plugins/Cases/functions/getCaseEmbed.ts @@ -1,4 +1,4 @@ -import { MessageEditOptions, MessageOptions, Util } from "discord.js"; +import { escapeCodeBlock, MessageEditOptions, MessageOptions } from "discord.js"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; import { CaseTypes } from "../../../data/CaseTypes"; @@ -67,7 +67,7 @@ export async function getCaseEmbed( if (theCase.notes.length) { for (const note of theCase.notes) { const noteDate = moment.utc(note.created_at); - let noteBody = Util.escapeCodeBlock(note.body.trim()); + let noteBody = escapeCodeBlock(note.body.trim()); if (noteBody === "") { noteBody = emptyEmbedValue; } diff --git a/backend/src/plugins/Logs/LogsPlugin.ts b/backend/src/plugins/Logs/LogsPlugin.ts index e0c39d35..618d9f7c 100644 --- a/backend/src/plugins/Logs/LogsPlugin.ts +++ b/backend/src/plugins/Logs/LogsPlugin.ts @@ -35,7 +35,6 @@ import { log } from "./util/log"; import { onMessageDelete } from "./util/onMessageDelete"; import { onMessageDeleteBulk } from "./util/onMessageDeleteBulk"; import { onMessageUpdate } from "./util/onMessageUpdate"; -import { Util } from "discord.js"; import { createTypedTemplateSafeValueContainer, TemplateSafeValueContainer, @@ -113,6 +112,7 @@ import { logVoiceChannelMove } from "./logFunctions/logVoiceChannelMove"; import { logMemberTimedUnban } from "./logFunctions/logMemberTimedUnban"; import { logDmFailed } from "./logFunctions/logDmFailed"; import { InternalPosterPlugin } from "../InternalPoster/InternalPosterPlugin"; +import { escapeCodeBlock } from "discord.js"; const defaultOptions: PluginOptions = { config: { @@ -300,7 +300,7 @@ export const LogsPlugin = zeppelinGuildPlugin()({ The following regex has taken longer than ${timeoutMs}ms for ${failedTimes} times and has been temporarily disabled: `.trim() + "\n```" + - Util.escapeCodeBlock(regexSource) + + escapeCodeBlock(regexSource) + "```", }), ); diff --git a/backend/src/plugins/ModActions/functions/formatReasonWithAttachments.ts b/backend/src/plugins/ModActions/functions/formatReasonWithAttachments.ts index 77194a3f..3fd92ee8 100644 --- a/backend/src/plugins/ModActions/functions/formatReasonWithAttachments.ts +++ b/backend/src/plugins/ModActions/functions/formatReasonWithAttachments.ts @@ -1,6 +1,6 @@ -import { MessageAttachment } from "discord.js"; +import { Attachment } from "discord.js"; -export function formatReasonWithAttachments(reason: string, attachments: MessageAttachment[]) { +export function formatReasonWithAttachments(reason: string, attachments: Attachment[]) { const attachmentUrls = attachments.map((a) => a.url); return ((reason || "") + " " + attachmentUrls.join(" ")).trim(); } diff --git a/backend/src/plugins/Post/commands/ScheduledPostsListCmd.ts b/backend/src/plugins/Post/commands/ScheduledPostsListCmd.ts index a0a88766..c118440f 100644 --- a/backend/src/plugins/Post/commands/ScheduledPostsListCmd.ts +++ b/backend/src/plugins/Post/commands/ScheduledPostsListCmd.ts @@ -1,4 +1,4 @@ -import { Util } from "discord.js"; +import { escapeCodeBlock } from "discord.js"; import humanizeDuration from "humanize-duration"; import moment from "moment-timezone"; import { createChunkedMessage, DBDateFormat, deactivateMentions, sorter, trimLines } from "../../../utils"; @@ -26,7 +26,7 @@ export const ScheduledPostsListCmd = postCmd({ const isTruncated = previewText.length > SCHEDULED_POST_PREVIEW_TEXT_LENGTH; - previewText = Util.escapeCodeBlock(deactivateMentions(previewText)) + previewText = escapeCodeBlock(deactivateMentions(previewText)) .replace(/\s+/g, " ") .slice(0, SCHEDULED_POST_PREVIEW_TEXT_LENGTH); diff --git a/backend/src/plugins/Post/util/postMessage.ts b/backend/src/plugins/Post/util/postMessage.ts index 4a10f809..dd5cca03 100644 --- a/backend/src/plugins/Post/util/postMessage.ts +++ b/backend/src/plugins/Post/util/postMessage.ts @@ -1,7 +1,7 @@ import { + Attachment, GuildTextBasedChannel, Message, - MessageAttachment, MessageOptions, NewsChannel, TextChannel, @@ -19,7 +19,7 @@ export async function postMessage( pluginData: GuildPluginData, channel: GuildTextBasedChannel, content: MessageOptions, - attachments: MessageAttachment[] = [], + attachments: Attachment[] = [], enableMentions: boolean = false, ): Promise { if (typeof content === "string") { diff --git a/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts b/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts index d86a59f0..70f20fbd 100644 --- a/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts +++ b/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts @@ -1,4 +1,11 @@ -import { ChannelType, GuildTextBasedChannel, PermissionsBitField, TextChannel, ThreadChannel, Util } from "discord.js"; +import { + ChannelType, + escapeInlineCode, + GuildTextBasedChannel, + PermissionsBitField, + TextChannel, + ThreadChannel, +} from "discord.js"; import humanizeDuration from "humanize-duration"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; @@ -132,7 +139,7 @@ export const SlowmodeSetCmd = slowmodeCmd({ rateLimitPerUser: rateLimitSeconds, }); } catch (e) { - sendErrorMessage(pluginData, msg.channel, `Failed to set native slowmode: ${Util.escapeInlineCode(e.message)}`); + sendErrorMessage(pluginData, msg.channel, `Failed to set native slowmode: ${escapeInlineCode(e.message)}`); return; } } else { diff --git a/backend/src/plugins/TimeAndDate/commands/SetTimezoneCmd.ts b/backend/src/plugins/TimeAndDate/commands/SetTimezoneCmd.ts index d88a0740..90d00b3b 100644 --- a/backend/src/plugins/TimeAndDate/commands/SetTimezoneCmd.ts +++ b/backend/src/plugins/TimeAndDate/commands/SetTimezoneCmd.ts @@ -1,4 +1,4 @@ -import { Util } from "discord.js"; +import { escapeInlineCode } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { trimLines } from "../../../utils"; @@ -20,7 +20,7 @@ export const SetTimezoneCmd = timeAndDateCmd({ pluginData, message.channel, trimLines(` - Invalid timezone: \`${Util.escapeInlineCode(args.timezone)}\` + Invalid timezone: \`${escapeInlineCode(args.timezone)}\` Zeppelin uses timezone locations rather than specific timezone names. See the **TZ database name** column at for a list of valid options. `), diff --git a/backend/src/plugins/Utility/commands/JumboCmd.ts b/backend/src/plugins/Utility/commands/JumboCmd.ts index d07855c1..867ac321 100644 --- a/backend/src/plugins/Utility/commands/JumboCmd.ts +++ b/backend/src/plugins/Utility/commands/JumboCmd.ts @@ -1,4 +1,4 @@ -import { MessageAttachment } from "discord.js"; +import { Attachment, AttachmentBuilder } from "discord.js"; import fs from "fs"; import photon from "@silvia-odwyer/photon-node"; import twemoji from "twemoji"; @@ -50,7 +50,7 @@ export const JumboCmd = utilityCmd({ const emojiRegex = new RegExp(`(<.*:).*:(\\d+)`); const results = emojiRegex.exec(args.emoji); let extension = ".png"; - let file: MessageAttachment | undefined; + let file: AttachmentBuilder | undefined; if (!isEmoji(args.emoji)) { sendErrorMessage(pluginData, msg.channel, "Invalid emoji"); @@ -65,10 +65,10 @@ export const JumboCmd = utilityCmd({ url += `${results[2]}${extension}`; if (extension === ".png") { const image = resizeBuffer(await getBufferFromUrl(url), size, size); - file = new MessageAttachment(image, `emoji${extension}`); + file = new AttachmentBuilder(image, { name: `emoji${extension}` }); } else { const image = await getBufferFromUrl(url); - file = new MessageAttachment(image, `emoji${extension}`); + file = new AttachmentBuilder(image, { name: `emoji${extension}` }); } } else { let url = `${twemoji.base}${twemoji.size}/${twemoji.convert.toCodePoint(args.emoji)}${twemoji.ext}`; @@ -87,7 +87,7 @@ export const JumboCmd = utilityCmd({ return; } - file = new MessageAttachment(image, "emoji.png"); + file = new AttachmentBuilder(image, { name: "emoji.png" }); } msg.channel.send({ files: [file] }); diff --git a/backend/src/plugins/Utility/commands/NicknameCmd.ts b/backend/src/plugins/Utility/commands/NicknameCmd.ts index f689a6af..6f4b6073 100644 --- a/backend/src/plugins/Utility/commands/NicknameCmd.ts +++ b/backend/src/plugins/Utility/commands/NicknameCmd.ts @@ -1,8 +1,8 @@ -import { Util } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { errorMessage } from "../../../utils"; import { canActOn, sendSuccessMessage } from "../../../pluginUtils"; import { utilityCmd } from "../types"; +import { escapeBold } from "discord.js"; export const NicknameCmd = utilityCmd({ trigger: ["nickname", "nick"], @@ -20,7 +20,7 @@ export const NicknameCmd = utilityCmd({ if (!args.member.nickname) { msg.channel.send(`<@!${args.member.id}> does not have a nickname`); } else { - msg.channel.send(`The nickname of <@!${args.member.id}> is **${Util.escapeBold(args.member.nickname)}**`); + msg.channel.send(`The nickname of <@!${args.member.id}> is **${escapeBold(args.member.nickname)}**`); } return; } diff --git a/backend/src/utils.ts b/backend/src/utils.ts index 692c67a6..e1324c7a 100644 --- a/backend/src/utils.ts +++ b/backend/src/utils.ts @@ -4,6 +4,7 @@ import { Constants, DiscordAPIError, Emoji, + escapeCodeBlock, Guild, GuildAuditLogs, GuildAuditLogsEntry, @@ -15,7 +16,6 @@ import { InviteGuild, LimitedCollection, Message, - MessageAttachment, MessageEmbed, MessageEmbedOptions, MessageMentionOptions, @@ -27,7 +27,6 @@ import { TextChannel, ThreadChannel, User, - Util, } from "discord.js"; import emojiRegex from "emoji-regex"; import { either } from "fp-ts/lib/Either"; @@ -258,7 +257,7 @@ export function nonNullish(v: V): v is NonNullable { export type GuildInvite = Invite & { guild: InviteGuild | Guild }; export type GroupDMInvite = Invite & { channel: PartialChannelData; - type: typeof Constants.ChannelTypes.GROUP_DM; + type: typeof ChannelType.GroupDM; }; /** @@ -648,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); } @@ -1409,11 +1408,11 @@ export async function confirm(channel: TextChannel, userId: string, content: Mes export function messageSummary(msg: SavedMessage) { // Regular text content - let result = "```\n" + (msg.data.content ? Util.escapeCodeBlock(msg.data.content) : "") + "```"; + let result = "```\n" + (msg.data.content ? escapeCodeBlock(msg.data.content) : "") + "```"; // Rich embed const richEmbed = (msg.data.embeds || []).find((e) => (e as MessageEmbed).type === "rich"); - if (richEmbed) result += "Embed:```" + Util.escapeCodeBlock(JSON.stringify(richEmbed)) + "```"; + if (richEmbed) result += "Embed:```" + escapeCodeBlock(JSON.stringify(richEmbed)) + "```"; // Attachments if (msg.data.attachments && msg.data.attachments.length) {