From b05fbe1d04a2d27c95088bac271d44b40407bd26 Mon Sep 17 00:00:00 2001 From: Dragory <2606411+Dragory@users.noreply.github.com> Date: Mon, 13 Jun 2022 21:19:56 +0300 Subject: [PATCH] Update to discord.js v13.8.0, adding support for text-in-voice --- backend/package-lock.json | 110 +++++++----------- backend/package.json | 2 +- backend/src/commandTypes.ts | 10 +- .../commands/NewAutoReactionsCmd.ts | 4 +- .../AutoReactions/events/AddReactionsEvt.ts | 13 +-- backend/src/plugins/Automod/actions/alert.ts | 2 +- backend/src/plugins/Automod/actions/reply.ts | 2 +- .../functions/resolveActionContactMethods.ts | 2 +- .../src/plugins/Censor/util/censorMessage.ts | 6 +- .../Counters/commands/ViewCounterCmd.ts | 8 +- .../getOrCreateWebhookClientForChannel.ts | 6 +- .../functions/getOrCreateWebhookForChannel.ts | 13 ++- .../InternalPoster/functions/sendMessage.ts | 21 +++- .../plugins/Logs/logFunctions/logCensor.ts | 4 +- .../Logs/logFunctions/logMessageDelete.ts | 4 +- .../Logs/logFunctions/logMessageDeleteBare.ts | 4 +- .../Logs/logFunctions/logMessageDeleteBulk.ts | 4 +- .../Logs/logFunctions/logMessageEdit.ts | 4 +- .../logFunctions/logPostedScheduledMessage.ts | 4 +- .../Logs/logFunctions/logRepeatedMessage.ts | 4 +- .../Logs/logFunctions/logScheduledMessage.ts | 4 +- .../logScheduledRepeatedMessage.ts | 4 +- backend/src/plugins/Logs/util/log.ts | 2 +- .../plugins/Logs/util/onMessageDeleteBulk.ts | 8 +- .../src/plugins/Logs/util/onMessageUpdate.ts | 6 +- .../src/plugins/Mutes/functions/muteUser.ts | 7 +- .../src/plugins/Post/util/actualPostCmd.ts | 12 +- backend/src/plugins/Post/util/postMessage.ts | 12 +- backend/src/utils.ts | 4 +- backend/src/utils/canReadChannel.ts | 4 +- .../src/utils/getMissingChannelPermissions.ts | 4 +- backend/src/utils/resolveMessageTarget.ts | 6 +- 32 files changed, 151 insertions(+), 149 deletions(-) diff --git a/backend/package-lock.json b/backend/package-lock.json index bae5e80a..6fc0547c 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -14,7 +14,7 @@ "cross-env": "^5.2.0", "deep-diff": "^1.0.2", "discord-api-types": "^0.33.1", - "discord.js": "^13.7.0", + "discord.js": "^13.8.0", "dotenv": "^4.0.0", "emoji-regex": "^8.0.0", "erlpack": "github:discord/erlpack", @@ -124,16 +124,16 @@ } }, "node_modules/@discordjs/builders": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.13.0.tgz", - "integrity": "sha512-4L9y26KRNNU8Y7J78SRUN1Uhava9D8jfit/YqEaKi8gQRc7PdqKqk2poybo6RXaiyt/BgKYPfcjxT7WvzGfYCA==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.14.0.tgz", + "integrity": "sha512-+fqLIqa9wN3R+kvlld8sgG0nt04BAZxdCDP4t2qZ9TJsquLWA+xMtT8Waibb3d4li4AQS+IOfjiHAznv/dhHgQ==", "dependencies": { - "@sapphire/shapeshift": "^2.0.0", + "@sapphire/shapeshift": "^3.1.0", "@sindresorhus/is": "^4.6.0", - "discord-api-types": "^0.31.1", + "discord-api-types": "^0.33.3", "fast-deep-equal": "^3.1.3", "ts-mixer": "^6.0.1", - "tslib": "^2.3.1" + "tslib": "^2.4.0" }, "engines": { "node": ">=16.9.0" @@ -150,20 +150,15 @@ "url": "https://github.com/sindresorhus/is?sponsor=1" } }, - "node_modules/@discordjs/builders/node_modules/discord-api-types": { - "version": "0.31.2", - "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.31.2.tgz", - "integrity": "sha512-gpzXTvFVg7AjKVVJFH0oJGC0q0tO34iJGSHZNz9u3aqLxlD6LfxEs9wWVVikJqn9gra940oUTaPFizCkRDcEiA==" - }, "node_modules/@discordjs/builders/node_modules/tslib": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" }, "node_modules/@discordjs/collection": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.6.0.tgz", - "integrity": "sha512-Ieaetb36l0nmAS5X9Upqk4W7euAO6FdXPxn3I8vBAKEcoIzEZI1mcVcPfCfagGJZSgBKpENnAnKkP4GAn+MV8w==", + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.7.0.tgz", + "integrity": "sha512-R5i8Wb8kIcBAFEPLLf7LVBQKBDYUL+ekb23sOgpkpyGT+V4P7V83wTxcsqmX+PbqHt4cEHn053uMWfRqh/Z/nA==", "engines": { "node": ">=16.9.0" } @@ -209,9 +204,9 @@ } }, "node_modules/@sapphire/shapeshift": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-2.2.0.tgz", - "integrity": "sha512-UEnKgMlQyI0yY/q+lCMX0VJft9y86IsesgbIQj6e62FBYSaMVr+IaMNpi4z45Q14VnuMACbK0yrbHISNqgUYcQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-3.1.0.tgz", + "integrity": "sha512-PkxFXd3QJ1qAPS05Dy2UkVGYPm/asF1Ugt2Xyzmv4DHzO3+G7l+873C4XFFcJ9M5Je+eCMC7SSifgPTSur5QuA==", "engines": { "node": ">=v15.0.0", "npm": ">=7.0.0" @@ -1704,35 +1699,30 @@ } }, "node_modules/discord-api-types": { - "version": "0.33.1", - "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.33.1.tgz", - "integrity": "sha512-dc7Xzm3isROh77jdxikQnLzKDslOPORm2Q8odXrKgEy8Aqfd1r9ISVTU/xsHkH6bFo+Hjf1A1C5OnBtu8ghy4w==" + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.33.4.tgz", + "integrity": "sha512-Y6RMvXsHKiBgQhm/q5MgRieXc4Tzh5p/JuDyqreI48lmy+AQfO+g9Xhz0tuGBaN1FtsrLT7mD+lbFONPo5vdwA==" }, "node_modules/discord.js": { - "version": "13.7.0", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.7.0.tgz", - "integrity": "sha512-iV/An3FEB/CiBGdjWHRtgskM4UuWPq5vjhjKsrQhdVU16dbKrBxA+eIV2HWA07B3tXUGM6eco1wkr42gxxV1BA==", + "version": "13.8.0", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.8.0.tgz", + "integrity": "sha512-EPAA/2VLycYN5wSzavqa4iJ6qj3UtQFtHw5TH/60Fj29ymfEsCQVn//o1mTpwDxzwb+rPIrWhkxKIGGnjfv0Iw==", "dependencies": { - "@discordjs/builders": "^0.13.0", - "@discordjs/collection": "^0.6.0", + "@discordjs/builders": "^0.14.0", + "@discordjs/collection": "^0.7.0", "@sapphire/async-queue": "^1.3.1", "@types/node-fetch": "^2.6.1", "@types/ws": "^8.5.3", - "discord-api-types": "^0.30.0", + "discord-api-types": "^0.33.3", "form-data": "^4.0.0", "node-fetch": "^2.6.1", - "ws": "^8.6.0" + "ws": "^8.7.0" }, "engines": { "node": ">=16.6.0", "npm": ">=7.0.0" } }, - "node_modules/discord.js/node_modules/discord-api-types": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.30.0.tgz", - "integrity": "sha512-wYst0jrT8EJs2tVlwUTQ2xT0oWMjUrRMpFTkNY3NMleWyQNHgWaKhqFfxdLPdC2im9IuR5EsxcEgjhf/npeftw==" - }, "node_modules/discord.js/node_modules/form-data": { "version": "4.0.0", "license": "MIT", @@ -5323,16 +5313,16 @@ } }, "@discordjs/builders": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.13.0.tgz", - "integrity": "sha512-4L9y26KRNNU8Y7J78SRUN1Uhava9D8jfit/YqEaKi8gQRc7PdqKqk2poybo6RXaiyt/BgKYPfcjxT7WvzGfYCA==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.14.0.tgz", + "integrity": "sha512-+fqLIqa9wN3R+kvlld8sgG0nt04BAZxdCDP4t2qZ9TJsquLWA+xMtT8Waibb3d4li4AQS+IOfjiHAznv/dhHgQ==", "requires": { - "@sapphire/shapeshift": "^2.0.0", + "@sapphire/shapeshift": "^3.1.0", "@sindresorhus/is": "^4.6.0", - "discord-api-types": "^0.31.1", + "discord-api-types": "^0.33.3", "fast-deep-equal": "^3.1.3", "ts-mixer": "^6.0.1", - "tslib": "^2.3.1" + "tslib": "^2.4.0" }, "dependencies": { "@sindresorhus/is": { @@ -5340,11 +5330,6 @@ "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==" }, - "discord-api-types": { - "version": "0.31.2", - "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.31.2.tgz", - "integrity": "sha512-gpzXTvFVg7AjKVVJFH0oJGC0q0tO34iJGSHZNz9u3aqLxlD6LfxEs9wWVVikJqn9gra940oUTaPFizCkRDcEiA==" - }, "tslib": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", @@ -5353,9 +5338,9 @@ } }, "@discordjs/collection": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.6.0.tgz", - "integrity": "sha512-Ieaetb36l0nmAS5X9Upqk4W7euAO6FdXPxn3I8vBAKEcoIzEZI1mcVcPfCfagGJZSgBKpENnAnKkP4GAn+MV8w==" + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.7.0.tgz", + "integrity": "sha512-R5i8Wb8kIcBAFEPLLf7LVBQKBDYUL+ekb23sOgpkpyGT+V4P7V83wTxcsqmX+PbqHt4cEHn053uMWfRqh/Z/nA==" }, "@nodelib/fs.scandir": { "version": "2.1.3", @@ -5381,9 +5366,9 @@ "version": "1.3.1" }, "@sapphire/shapeshift": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-2.2.0.tgz", - "integrity": "sha512-UEnKgMlQyI0yY/q+lCMX0VJft9y86IsesgbIQj6e62FBYSaMVr+IaMNpi4z45Q14VnuMACbK0yrbHISNqgUYcQ==" + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-3.1.0.tgz", + "integrity": "sha512-PkxFXd3QJ1qAPS05Dy2UkVGYPm/asF1Ugt2Xyzmv4DHzO3+G7l+873C4XFFcJ9M5Je+eCMC7SSifgPTSur5QuA==" }, "@silvia-odwyer/photon-node": { "version": "0.3.1" @@ -6382,31 +6367,26 @@ } }, "discord-api-types": { - "version": "0.33.1", - "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.33.1.tgz", - "integrity": "sha512-dc7Xzm3isROh77jdxikQnLzKDslOPORm2Q8odXrKgEy8Aqfd1r9ISVTU/xsHkH6bFo+Hjf1A1C5OnBtu8ghy4w==" + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.33.4.tgz", + "integrity": "sha512-Y6RMvXsHKiBgQhm/q5MgRieXc4Tzh5p/JuDyqreI48lmy+AQfO+g9Xhz0tuGBaN1FtsrLT7mD+lbFONPo5vdwA==" }, "discord.js": { - "version": "13.7.0", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.7.0.tgz", - "integrity": "sha512-iV/An3FEB/CiBGdjWHRtgskM4UuWPq5vjhjKsrQhdVU16dbKrBxA+eIV2HWA07B3tXUGM6eco1wkr42gxxV1BA==", + "version": "13.8.0", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.8.0.tgz", + "integrity": "sha512-EPAA/2VLycYN5wSzavqa4iJ6qj3UtQFtHw5TH/60Fj29ymfEsCQVn//o1mTpwDxzwb+rPIrWhkxKIGGnjfv0Iw==", "requires": { - "@discordjs/builders": "^0.13.0", - "@discordjs/collection": "^0.6.0", + "@discordjs/builders": "^0.14.0", + "@discordjs/collection": "^0.7.0", "@sapphire/async-queue": "^1.3.1", "@types/node-fetch": "^2.6.1", "@types/ws": "^8.5.3", - "discord-api-types": "^0.30.0", + "discord-api-types": "^0.33.3", "form-data": "^4.0.0", "node-fetch": "^2.6.1", - "ws": "^8.6.0" + "ws": "^8.7.0" }, "dependencies": { - "discord-api-types": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.30.0.tgz", - "integrity": "sha512-wYst0jrT8EJs2tVlwUTQ2xT0oWMjUrRMpFTkNY3NMleWyQNHgWaKhqFfxdLPdC2im9IuR5EsxcEgjhf/npeftw==" - }, "form-data": { "version": "4.0.0", "requires": { diff --git a/backend/package.json b/backend/package.json index 348492c9..4761ec2e 100644 --- a/backend/package.json +++ b/backend/package.json @@ -29,7 +29,7 @@ "cross-env": "^5.2.0", "deep-diff": "^1.0.2", "discord-api-types": "^0.33.1", - "discord.js": "^13.7.0", + "discord.js": "^13.8.0", "dotenv": "^4.0.0", "emoji-regex": "^8.0.0", "erlpack": "github:discord/erlpack", diff --git a/backend/src/commandTypes.ts b/backend/src/commandTypes.ts index e3f1ece3..75c6225c 100644 --- a/backend/src/commandTypes.ts +++ b/backend/src/commandTypes.ts @@ -1,4 +1,4 @@ -import { GuildChannel, GuildMember, Snowflake, Util, User } from "discord.js"; +import { GuildChannel, GuildMember, Snowflake, Util, User, GuildTextBasedChannel } from "discord.js"; import { baseCommandParameterTypeHelpers, baseTypeConverters, CommandContext, TypeConversionError } from "knub"; import { createTypeHelper } from "knub-command-manager"; import { @@ -14,6 +14,8 @@ import { import { isValidTimezone } from "./utils/isValidTimezone"; import { MessageTarget, resolveMessageTarget } from "./utils/resolveMessageTarget"; import { inputPatternToRegExp } from "./validatorUtils"; +import { getChannelId } from "knub/dist/utils"; +import { disableCodeBlocks } from "knub/dist/helpers"; export const commandTypes = { ...baseTypeConverters, @@ -100,6 +102,11 @@ export const commandTypes = { return value; }, + + guildTextBasedChannel(value: string, context: CommandContext) { + // FIXME: Remove once Knub's types have been fixed + return baseTypeConverters.textChannel(value, context) as GuildTextBasedChannel; + }, }; export const commandTypeHelpers = { @@ -113,4 +120,5 @@ export const commandTypeHelpers = { anyId: createTypeHelper>(commandTypes.anyId), regex: createTypeHelper(commandTypes.regex), timezone: createTypeHelper(commandTypes.timezone), + guildTextBasedChannel: createTypeHelper(commandTypes.guildTextBasedChannel), }; diff --git a/backend/src/plugins/AutoReactions/commands/NewAutoReactionsCmd.ts b/backend/src/plugins/AutoReactions/commands/NewAutoReactionsCmd.ts index 1ab5e123..17b377b2 100644 --- a/backend/src/plugins/AutoReactions/commands/NewAutoReactionsCmd.ts +++ b/backend/src/plugins/AutoReactions/commands/NewAutoReactionsCmd.ts @@ -15,7 +15,7 @@ export const NewAutoReactionsCmd = autoReactionsCmd({ usage: "!auto_reactions 629990160477585428 👍 👎", signature: { - channel: ct.channel(), + channel: ct.guildTextBasedChannel(), reactions: ct.string({ rest: true }), }, @@ -23,7 +23,7 @@ export const NewAutoReactionsCmd = autoReactionsCmd({ const finalReactions: string[] = []; const me = pluginData.guild.members.cache.get(pluginData.client.user!.id)!; - const missingPermissions = getMissingChannelPermissions(me, args.channel as GuildChannel, requiredPermissions); + const missingPermissions = getMissingChannelPermissions(me, args.channel, requiredPermissions); if (missingPermissions) { sendErrorMessage( pluginData, diff --git a/backend/src/plugins/AutoReactions/events/AddReactionsEvt.ts b/backend/src/plugins/AutoReactions/events/AddReactionsEvt.ts index 0818953c..a959cdcf 100644 --- a/backend/src/plugins/AutoReactions/events/AddReactionsEvt.ts +++ b/backend/src/plugins/AutoReactions/events/AddReactionsEvt.ts @@ -1,4 +1,4 @@ -import { GuildChannel, Permissions } from "discord.js"; +import { GuildChannel, GuildTextBasedChannel, Permissions } from "discord.js"; import { LogType } from "../../../data/LogType"; import { isDiscordAPIError } from "../../../utils"; import { getMissingChannelPermissions } from "../../../utils/getMissingChannelPermissions"; @@ -16,7 +16,10 @@ export const AddReactionsEvt = autoReactionsEvt({ allowSelf: true, async listener({ pluginData, args: { message } }) { - const channel = await message.guild?.channels.fetch(message.channelId); + const channel = (await message.guild?.channels.fetch(message.channelId)) as + | GuildTextBasedChannel + | null + | undefined; if (!channel) { return; } @@ -37,11 +40,7 @@ export const AddReactionsEvt = autoReactionsEvt({ const me = pluginData.guild.members.cache.get(pluginData.client.user!.id)!; if (me) { - const missingPermissions = getMissingChannelPermissions( - me, - channel as GuildChannel, - readChannelPermissions | p.ADD_REACTIONS, - ); + const missingPermissions = getMissingChannelPermissions(me, channel, readChannelPermissions | p.ADD_REACTIONS); if (missingPermissions) { const logs = pluginData.getPlugin(LogsPlugin); logs.logBotAlert({ diff --git a/backend/src/plugins/Automod/actions/alert.ts b/backend/src/plugins/Automod/actions/alert.ts index 7c96dea5..8bfce04d 100644 --- a/backend/src/plugins/Automod/actions/alert.ts +++ b/backend/src/plugins/Automod/actions/alert.ts @@ -38,7 +38,7 @@ export const AlertAction = automodAction({ const channel = pluginData.guild.channels.cache.get(actionConfig.channel as Snowflake); const logs = pluginData.getPlugin(LogsPlugin); - if (channel && channel instanceof TextChannel) { + if (channel?.isText()) { const text = actionConfig.text; const theMessageLink = contexts[0].message && messageLink(pluginData.guild.id, contexts[0].message.channel_id, contexts[0].message.id); diff --git a/backend/src/plugins/Automod/actions/reply.ts b/backend/src/plugins/Automod/actions/reply.ts index 52aa491d..865ef127 100644 --- a/backend/src/plugins/Automod/actions/reply.ts +++ b/backend/src/plugins/Automod/actions/reply.ts @@ -36,7 +36,7 @@ export const ReplyAction = automodAction({ .filter((c) => c.message?.channel_id) .filter((c) => { const channel = pluginData.guild.channels.cache.get(c.message!.channel_id as Snowflake); - return channel instanceof TextChannel || channel instanceof ThreadChannel; + return channel?.isText(); }); const contextsByChannelId = contextsWithTextChannels.reduce((map: Map, context) => { diff --git a/backend/src/plugins/Automod/functions/resolveActionContactMethods.ts b/backend/src/plugins/Automod/functions/resolveActionContactMethods.ts index 5ac49703..9576d149 100644 --- a/backend/src/plugins/Automod/functions/resolveActionContactMethods.ts +++ b/backend/src/plugins/Automod/functions/resolveActionContactMethods.ts @@ -19,7 +19,7 @@ export function resolveActionContactMethods( } const channel = pluginData.guild.channels.cache.get(actionConfig.notifyChannel as Snowflake); - if (!(channel instanceof TextChannel || channel instanceof ThreadChannel)) { + if (!channel?.isText()) { throw new RecoverablePluginError(ERRORS.INVALID_USER_NOTIFICATION_CHANNEL); } diff --git a/backend/src/plugins/Censor/util/censorMessage.ts b/backend/src/plugins/Censor/util/censorMessage.ts index a9549974..6375da79 100644 --- a/backend/src/plugins/Censor/util/censorMessage.ts +++ b/backend/src/plugins/Censor/util/censorMessage.ts @@ -1,4 +1,4 @@ -import { BaseGuildTextChannel, Snowflake, TextChannel, ThreadChannel } from "discord.js"; +import { BaseGuildTextChannel, GuildTextBasedChannel, Snowflake, TextChannel, ThreadChannel } from "discord.js"; import { GuildPluginData } from "knub"; import { channelToTemplateSafeChannel, userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; import { SavedMessage } from "../../../data/entities/SavedMessage"; @@ -22,9 +22,7 @@ export async function censorMessage( } const user = await resolveUser(pluginData.client, savedMessage.user_id); - const channel = pluginData.guild.channels.resolve(savedMessage.channel_id as Snowflake)! as - | BaseGuildTextChannel - | ThreadChannel; + const channel = pluginData.guild.channels.resolve(savedMessage.channel_id as Snowflake)! as GuildTextBasedChannel; pluginData.getPlugin(LogsPlugin).logCensor({ user, diff --git a/backend/src/plugins/Counters/commands/ViewCounterCmd.ts b/backend/src/plugins/Counters/commands/ViewCounterCmd.ts index 26a2fe7c..9a4cbca5 100644 --- a/backend/src/plugins/Counters/commands/ViewCounterCmd.ts +++ b/backend/src/plugins/Counters/commands/ViewCounterCmd.ts @@ -20,17 +20,17 @@ export const ViewCounterCmd = typedGuildCommand()({ }, { counterName: ct.string(), - channel: ct.textChannel(), + channel: ct.guildTextBasedChannel(), }, { counterName: ct.string(), - channel: ct.textChannel(), + channel: ct.guildTextBasedChannel(), user: ct.resolvedUser(), }, { counterName: ct.string(), user: ct.resolvedUser(), - channel: ct.textChannel(), + channel: ct.guildTextBasedChannel(), }, ], @@ -68,7 +68,7 @@ export const ViewCounterCmd = typedGuildCommand()({ } const potentialChannel = pluginData.guild.channels.resolve(reply.content as Snowflake); - if (!potentialChannel || !(potentialChannel instanceof TextChannel)) { + if (!potentialChannel?.isText()) { sendErrorMessage(pluginData, message.channel, "Channel is not a text channel, cancelling"); return; } diff --git a/backend/src/plugins/InternalPoster/functions/getOrCreateWebhookClientForChannel.ts b/backend/src/plugins/InternalPoster/functions/getOrCreateWebhookClientForChannel.ts index cc582495..aea1523c 100644 --- a/backend/src/plugins/InternalPoster/functions/getOrCreateWebhookClientForChannel.ts +++ b/backend/src/plugins/InternalPoster/functions/getOrCreateWebhookClientForChannel.ts @@ -1,11 +1,11 @@ import { GuildPluginData } from "knub"; import { InternalPosterPluginType } from "../types"; -import { NewsChannel, TextChannel, WebhookClient } from "discord.js"; -import { getOrCreateWebhookForChannel } from "./getOrCreateWebhookForChannel"; +import { WebhookClient } from "discord.js"; +import { getOrCreateWebhookForChannel, WebhookableChannel } from "./getOrCreateWebhookForChannel"; export async function getOrCreateWebhookClientForChannel( pluginData: GuildPluginData, - channel: TextChannel | NewsChannel, + channel: WebhookableChannel, ): Promise { if (!pluginData.state.webhookClientCache.has(channel.id)) { const webhookInfo = await getOrCreateWebhookForChannel(pluginData, channel); diff --git a/backend/src/plugins/InternalPoster/functions/getOrCreateWebhookForChannel.ts b/backend/src/plugins/InternalPoster/functions/getOrCreateWebhookForChannel.ts index 8acd2887..9785271e 100644 --- a/backend/src/plugins/InternalPoster/functions/getOrCreateWebhookForChannel.ts +++ b/backend/src/plugins/InternalPoster/functions/getOrCreateWebhookForChannel.ts @@ -1,17 +1,20 @@ import { GuildPluginData } from "knub"; import { InternalPosterPluginType } from "../types"; -import { NewsChannel, Permissions, TextChannel } from "discord.js"; +import { AnyChannel, GuildChannel, MessageManager, NewsChannel, Permissions, TextChannel } from "discord.js"; import { isDiscordAPIError } from "../../../utils"; type WebhookInfo = [id: string, token: string]; +export type WebhookableChannel = Extract any }>; + +export function channelIsWebhookable(channel: AnyChannel): channel is WebhookableChannel { + return "createWebhook" in channel; +} + export async function getOrCreateWebhookForChannel( pluginData: GuildPluginData, - channel: TextChannel | NewsChannel, + channel: WebhookableChannel, ): Promise { - // tslint:disable-next-line:no-console FIXME: Here for debugging purposes - console.log(`getOrCreateWebhookForChannel(${channel.id})`); - // Database cache const fromDb = await pluginData.state.webhooks.findByChannelId(channel.id); if (fromDb) { diff --git a/backend/src/plugins/InternalPoster/functions/sendMessage.ts b/backend/src/plugins/InternalPoster/functions/sendMessage.ts index bc52ac05..283cc3dc 100644 --- a/backend/src/plugins/InternalPoster/functions/sendMessage.ts +++ b/backend/src/plugins/InternalPoster/functions/sendMessage.ts @@ -1,7 +1,7 @@ -import { Message, MessageOptions, NewsChannel, TextChannel, WebhookClient } from "discord.js"; +import { GuildTextBasedChannel, Message, MessageOptions, NewsChannel, TextChannel, WebhookClient } from "discord.js"; import { GuildPluginData } from "knub"; import { InternalPosterPluginType } from "../types"; -import { getOrCreateWebhookForChannel } from "./getOrCreateWebhookForChannel"; +import { channelIsWebhookable, getOrCreateWebhookForChannel } from "./getOrCreateWebhookForChannel"; import { APIMessage } from "discord-api-types"; import { isDiscordAPIError } from "../../../utils"; import { getOrCreateWebhookClientForChannel } from "./getOrCreateWebhookClientForChannel"; @@ -12,7 +12,7 @@ export type InternalPosterMessageResult = { }; async function sendDirectly( - channel: TextChannel | NewsChannel, + channel: GuildTextBasedChannel, content: MessageOptions, ): Promise { return channel.send(content).then((message) => ({ @@ -26,17 +26,26 @@ async function sendDirectly( */ export async function sendMessage( pluginData: GuildPluginData, - channel: TextChannel | NewsChannel, + channel: GuildTextBasedChannel, content: MessageOptions, ): Promise { return pluginData.state.queue.add(async () => { - const webhookClient = await getOrCreateWebhookClientForChannel(pluginData, channel); + let webhookClient: WebhookClient | null = null; + let threadId: string | undefined; + if (channelIsWebhookable(channel)) { + webhookClient = await getOrCreateWebhookClientForChannel(pluginData, channel); + } else if (channel.isThread() && channelIsWebhookable(channel.parent!)) { + webhookClient = await getOrCreateWebhookClientForChannel(pluginData, channel.parent!); + threadId = channel.id; + } + if (!webhookClient) { return sendDirectly(channel, content); } return webhookClient .send({ + threadId, ...content, ...(pluginData.client.user && { username: pluginData.client.user.username, @@ -50,7 +59,7 @@ export async function sendMessage( .catch(async (err) => { // Unknown Webhook if (isDiscordAPIError(err) && err.code === 10015) { - await pluginData.state.webhooks.delete(webhookClient.id); + await pluginData.state.webhooks.delete(webhookClient!.id); pluginData.state.webhookClientCache.delete(channel.id); // Fallback to regular message for this log message diff --git a/backend/src/plugins/Logs/logFunctions/logCensor.ts b/backend/src/plugins/Logs/logFunctions/logCensor.ts index 2385273f..b0131657 100644 --- a/backend/src/plugins/Logs/logFunctions/logCensor.ts +++ b/backend/src/plugins/Logs/logFunctions/logCensor.ts @@ -3,7 +3,7 @@ import { LogsPluginType } from "../types"; import { LogType } from "../../../data/LogType"; import { log } from "../util/log"; import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { BaseGuildTextChannel, ThreadChannel, User } from "discord.js"; +import { BaseGuildTextChannel, GuildTextBasedChannel, ThreadChannel, User } from "discord.js"; import { channelToTemplateSafeChannel, savedMessageToTemplateSafeSavedMessage, @@ -15,7 +15,7 @@ import { deactivateMentions, disableCodeBlocks } from "knub/dist/helpers"; interface LogCensorData { user: User | UnknownUser; - channel: BaseGuildTextChannel | ThreadChannel; + channel: GuildTextBasedChannel; reason: string; message: SavedMessage; } diff --git a/backend/src/plugins/Logs/logFunctions/logMessageDelete.ts b/backend/src/plugins/Logs/logFunctions/logMessageDelete.ts index 1b752866..6a2d642c 100644 --- a/backend/src/plugins/Logs/logFunctions/logMessageDelete.ts +++ b/backend/src/plugins/Logs/logFunctions/logMessageDelete.ts @@ -3,7 +3,7 @@ import { FORMAT_NO_TIMESTAMP, LogsPluginType } from "../types"; import { LogType } from "../../../data/LogType"; import { log } from "../util/log"; import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { BaseGuildTextChannel, ThreadChannel, User } from "discord.js"; +import { BaseGuildTextChannel, GuildTextBasedChannel, ThreadChannel, User } from "discord.js"; import { channelToTemplateSafeChannel, savedMessageToTemplateSafeSavedMessage, @@ -16,7 +16,7 @@ import { UnknownUser, useMediaUrls } from "../../../utils"; interface LogMessageDeleteData { user: User | UnknownUser; - channel: BaseGuildTextChannel | ThreadChannel; + channel: GuildTextBasedChannel; message: SavedMessage; } diff --git a/backend/src/plugins/Logs/logFunctions/logMessageDeleteBare.ts b/backend/src/plugins/Logs/logFunctions/logMessageDeleteBare.ts index 6b980951..ed49d3e4 100644 --- a/backend/src/plugins/Logs/logFunctions/logMessageDeleteBare.ts +++ b/backend/src/plugins/Logs/logFunctions/logMessageDeleteBare.ts @@ -3,12 +3,12 @@ import { LogsPluginType } from "../types"; import { LogType } from "../../../data/LogType"; import { log } from "../util/log"; import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { BaseGuildTextChannel, ThreadChannel } from "discord.js"; +import { BaseGuildTextChannel, GuildTextBasedChannel, ThreadChannel } from "discord.js"; import { channelToTemplateSafeChannel } from "../../../utils/templateSafeObjects"; interface LogMessageDeleteBareData { messageId: string; - channel: BaseGuildTextChannel | ThreadChannel; + channel: GuildTextBasedChannel; } export function logMessageDeleteBare(pluginData: GuildPluginData, data: LogMessageDeleteBareData) { diff --git a/backend/src/plugins/Logs/logFunctions/logMessageDeleteBulk.ts b/backend/src/plugins/Logs/logFunctions/logMessageDeleteBulk.ts index 01f38279..b57b526b 100644 --- a/backend/src/plugins/Logs/logFunctions/logMessageDeleteBulk.ts +++ b/backend/src/plugins/Logs/logFunctions/logMessageDeleteBulk.ts @@ -3,13 +3,13 @@ import { LogsPluginType } from "../types"; import { LogType } from "../../../data/LogType"; import { log } from "../util/log"; import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { BaseGuildTextChannel, ThreadChannel } from "discord.js"; +import { BaseGuildTextChannel, GuildTextBasedChannel, ThreadChannel } from "discord.js"; import { channelToTemplateSafeChannel } from "../../../utils/templateSafeObjects"; interface LogMessageDeleteBulkData { count: number; authorIds: string[]; - channel: BaseGuildTextChannel | ThreadChannel; + channel: GuildTextBasedChannel; archiveUrl: string; } diff --git a/backend/src/plugins/Logs/logFunctions/logMessageEdit.ts b/backend/src/plugins/Logs/logFunctions/logMessageEdit.ts index a77ce103..3aee8dbe 100644 --- a/backend/src/plugins/Logs/logFunctions/logMessageEdit.ts +++ b/backend/src/plugins/Logs/logFunctions/logMessageEdit.ts @@ -3,7 +3,7 @@ import { LogsPluginType } from "../types"; import { LogType } from "../../../data/LogType"; import { log } from "../util/log"; import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { BaseGuildTextChannel, ThreadChannel, User } from "discord.js"; +import { BaseGuildTextChannel, GuildTextBasedChannel, ThreadChannel, User } from "discord.js"; import { channelToTemplateSafeChannel, savedMessageToTemplateSafeSavedMessage, @@ -14,7 +14,7 @@ import { UnknownUser } from "../../../utils"; interface LogMessageEditData { user: User | UnknownUser; - channel: BaseGuildTextChannel | ThreadChannel; + channel: GuildTextBasedChannel; before: SavedMessage; after: SavedMessage; } diff --git a/backend/src/plugins/Logs/logFunctions/logPostedScheduledMessage.ts b/backend/src/plugins/Logs/logFunctions/logPostedScheduledMessage.ts index 52aa83ca..3000a906 100644 --- a/backend/src/plugins/Logs/logFunctions/logPostedScheduledMessage.ts +++ b/backend/src/plugins/Logs/logFunctions/logPostedScheduledMessage.ts @@ -3,12 +3,12 @@ import { LogsPluginType } from "../types"; import { LogType } from "../../../data/LogType"; import { log } from "../util/log"; import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { BaseGuildTextChannel, ThreadChannel, User } from "discord.js"; +import { BaseGuildTextChannel, GuildTextBasedChannel, ThreadChannel, User } from "discord.js"; import { channelToTemplateSafeChannel, userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; interface LogPostedScheduledMessageData { author: User; - channel: BaseGuildTextChannel | ThreadChannel; + channel: GuildTextBasedChannel; messageId: string; } diff --git a/backend/src/plugins/Logs/logFunctions/logRepeatedMessage.ts b/backend/src/plugins/Logs/logFunctions/logRepeatedMessage.ts index d17b5a55..7502b6ce 100644 --- a/backend/src/plugins/Logs/logFunctions/logRepeatedMessage.ts +++ b/backend/src/plugins/Logs/logFunctions/logRepeatedMessage.ts @@ -3,12 +3,12 @@ import { LogsPluginType } from "../types"; import { LogType } from "../../../data/LogType"; import { log } from "../util/log"; import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { BaseGuildTextChannel, ThreadChannel, User } from "discord.js"; +import { BaseGuildTextChannel, GuildTextBasedChannel, ThreadChannel, User } from "discord.js"; import { channelToTemplateSafeChannel, userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; interface LogRepeatedMessageData { author: User; - channel: BaseGuildTextChannel | ThreadChannel; + channel: GuildTextBasedChannel; datetime: string; date: string; time: string; diff --git a/backend/src/plugins/Logs/logFunctions/logScheduledMessage.ts b/backend/src/plugins/Logs/logFunctions/logScheduledMessage.ts index 27408798..54315e6f 100644 --- a/backend/src/plugins/Logs/logFunctions/logScheduledMessage.ts +++ b/backend/src/plugins/Logs/logFunctions/logScheduledMessage.ts @@ -3,12 +3,12 @@ import { LogsPluginType } from "../types"; import { LogType } from "../../../data/LogType"; import { log } from "../util/log"; import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { BaseGuildTextChannel, ThreadChannel, User } from "discord.js"; +import { BaseGuildTextChannel, GuildTextBasedChannel, ThreadChannel, User } from "discord.js"; import { channelToTemplateSafeChannel, userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; interface LogScheduledMessageData { author: User; - channel: BaseGuildTextChannel | ThreadChannel; + channel: GuildTextBasedChannel; datetime: string; date: string; time: string; diff --git a/backend/src/plugins/Logs/logFunctions/logScheduledRepeatedMessage.ts b/backend/src/plugins/Logs/logFunctions/logScheduledRepeatedMessage.ts index 55d24df3..03272f5f 100644 --- a/backend/src/plugins/Logs/logFunctions/logScheduledRepeatedMessage.ts +++ b/backend/src/plugins/Logs/logFunctions/logScheduledRepeatedMessage.ts @@ -3,12 +3,12 @@ import { LogsPluginType } from "../types"; import { LogType } from "../../../data/LogType"; import { log } from "../util/log"; import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { BaseGuildTextChannel, ThreadChannel, User } from "discord.js"; +import { BaseGuildTextChannel, GuildTextBasedChannel, ThreadChannel, User } from "discord.js"; import { channelToTemplateSafeChannel, userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; interface LogScheduledRepeatedMessageData { author: User; - channel: BaseGuildTextChannel | ThreadChannel; + channel: GuildTextBasedChannel; datetime: string; date: string; time: string; diff --git a/backend/src/plugins/Logs/util/log.ts b/backend/src/plugins/Logs/util/log.ts index 37fca40a..f95e1f07 100644 --- a/backend/src/plugins/Logs/util/log.ts +++ b/backend/src/plugins/Logs/util/log.ts @@ -83,7 +83,7 @@ export async function log( logChannelLoop: for (const [channelId, opts] of Object.entries(logChannels)) { const channel = pluginData.guild.channels.cache.get(channelId as Snowflake); - if (!channel || !(channel instanceof TextChannel)) continue; + if (!channel?.isText()) continue; if (pluginData.state.channelCooldowns.isOnCooldown(channelId)) continue; if (opts.include?.length && !opts.include.includes(typeStr)) continue; if (opts.exclude && opts.exclude.includes(typeStr)) continue; diff --git a/backend/src/plugins/Logs/util/onMessageDeleteBulk.ts b/backend/src/plugins/Logs/util/onMessageDeleteBulk.ts index 1dec0101..36ad96f1 100644 --- a/backend/src/plugins/Logs/util/onMessageDeleteBulk.ts +++ b/backend/src/plugins/Logs/util/onMessageDeleteBulk.ts @@ -1,4 +1,4 @@ -import { BaseGuildTextChannel, Snowflake, ThreadChannel } from "discord.js"; +import { BaseGuildTextChannel, GuildTextBasedChannel, Snowflake, ThreadChannel } from "discord.js"; import { GuildPluginData } from "knub"; import { SavedMessage } from "../../../data/entities/SavedMessage"; import { LogType } from "../../../data/LogType"; @@ -12,9 +12,9 @@ export async function onMessageDeleteBulk(pluginData: GuildPluginData `\`${item.user_id}\``))); diff --git a/backend/src/plugins/Logs/util/onMessageUpdate.ts b/backend/src/plugins/Logs/util/onMessageUpdate.ts index efd92d28..13d611ed 100644 --- a/backend/src/plugins/Logs/util/onMessageUpdate.ts +++ b/backend/src/plugins/Logs/util/onMessageUpdate.ts @@ -1,4 +1,4 @@ -import { BaseGuildTextChannel, MessageEmbed, Snowflake, ThreadChannel } from "discord.js"; +import { BaseGuildTextChannel, GuildTextBasedChannel, MessageEmbed, Snowflake, ThreadChannel } from "discord.js"; import { GuildPluginData } from "knub"; import cloneDeep from "lodash.clonedeep"; import { channelToTemplateSafeChannel, userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; @@ -49,9 +49,7 @@ export async function onMessageUpdate( } const user = await resolveUser(pluginData.client, savedMessage.user_id); - const channel = pluginData.guild.channels.resolve(savedMessage.channel_id as Snowflake)! as - | BaseGuildTextChannel - | ThreadChannel; + const channel = pluginData.guild.channels.resolve(savedMessage.channel_id as Snowflake)! as GuildTextBasedChannel; logMessageEdit(pluginData, { user, diff --git a/backend/src/plugins/Mutes/functions/muteUser.ts b/backend/src/plugins/Mutes/functions/muteUser.ts index 68908e30..3956be8a 100644 --- a/backend/src/plugins/Mutes/functions/muteUser.ts +++ b/backend/src/plugins/Mutes/functions/muteUser.ts @@ -183,9 +183,10 @@ export async function muteUser( } const useChannel = existingMute ? config.message_on_update : config.message_on_mute; - const channel = - config.message_channel && pluginData.guild.channels.cache.get(config.message_channel as Snowflake); - if (useChannel && channel instanceof TextChannel) { + const channel = config.message_channel + ? pluginData.guild.channels.cache.get(config.message_channel as Snowflake) + : null; + if (useChannel && channel?.isText()) { contactMethods.push({ type: "channel", channel }); } } diff --git a/backend/src/plugins/Post/util/actualPostCmd.ts b/backend/src/plugins/Post/util/actualPostCmd.ts index 054f655c..a63b1312 100644 --- a/backend/src/plugins/Post/util/actualPostCmd.ts +++ b/backend/src/plugins/Post/util/actualPostCmd.ts @@ -1,4 +1,4 @@ -import { Channel, Message, NewsChannel, TextChannel, ThreadChannel } from "discord.js"; +import { Channel, GuildTextBasedChannel, Message, NewsChannel, TextChannel, ThreadChannel } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; @@ -20,7 +20,7 @@ const MAX_REPEAT_UNTIL = moment.utc().add(100, "years"); export async function actualPostCmd( pluginData: GuildPluginData, msg: Message, - targetChannel: Channel, + targetChannel: GuildTextBasedChannel, content: StrictMessageContent, opts: { "enable-mentions"?: boolean; @@ -30,12 +30,8 @@ export async function actualPostCmd( "repeat-times"?: number; } = {}, ) { - if ( - !(targetChannel instanceof TextChannel) && - !(targetChannel instanceof NewsChannel) && - !(targetChannel instanceof ThreadChannel) - ) { - msg.channel.send(errorMessage("Specified channel is not a text channel, announcement channel, or thread")); + if (!targetChannel.isText()) { + msg.channel.send(errorMessage("Specified channel is not a text-based channel")); return; } diff --git a/backend/src/plugins/Post/util/postMessage.ts b/backend/src/plugins/Post/util/postMessage.ts index 0395867c..4a10f809 100644 --- a/backend/src/plugins/Post/util/postMessage.ts +++ b/backend/src/plugins/Post/util/postMessage.ts @@ -1,4 +1,12 @@ -import { Message, MessageAttachment, MessageOptions, NewsChannel, TextChannel, ThreadChannel } from "discord.js"; +import { + GuildTextBasedChannel, + Message, + MessageAttachment, + MessageOptions, + NewsChannel, + TextChannel, + ThreadChannel, +} from "discord.js"; import fs from "fs"; import { GuildPluginData } from "knub"; import { downloadFile } from "../../../utils"; @@ -9,7 +17,7 @@ const fsp = fs.promises; export async function postMessage( pluginData: GuildPluginData, - channel: TextChannel | NewsChannel | ThreadChannel, + channel: GuildTextBasedChannel, content: MessageOptions, attachments: MessageAttachment[] = [], enableMentions: boolean = false, diff --git a/backend/src/utils.ts b/backend/src/utils.ts index fb505743..e90c38e0 100644 --- a/backend/src/utils.ts +++ b/backend/src/utils.ts @@ -6,8 +6,10 @@ import { Guild, GuildAuditLogs, GuildAuditLogsEntry, + GuildBasedChannel, GuildChannel, GuildMember, + GuildTextBasedChannel, Invite, InviteGuild, LimitedCollection, @@ -1085,7 +1087,7 @@ export type CustomEmoji = { id: string; } & Emoji; -export type UserNotificationMethod = { type: "dm" } | { type: "channel"; channel: TextChannel | ThreadChannel }; +export type UserNotificationMethod = { type: "dm" } | { type: "channel"; channel: GuildTextBasedChannel }; export const disableUserNotificationStrings = ["no", "none", "off"]; diff --git a/backend/src/utils/canReadChannel.ts b/backend/src/utils/canReadChannel.ts index 94268c4b..043a72d2 100644 --- a/backend/src/utils/canReadChannel.ts +++ b/backend/src/utils/canReadChannel.ts @@ -1,8 +1,8 @@ -import { GuildChannel, GuildMember } from "discord.js"; +import { GuildMember, GuildTextBasedChannel } from "discord.js"; import { getMissingChannelPermissions } from "./getMissingChannelPermissions"; import { readChannelPermissions } from "./readChannelPermissions"; -export function canReadChannel(channel: GuildChannel, member: GuildMember) { +export function canReadChannel(channel: GuildTextBasedChannel, member: GuildMember) { // Not missing permissions required to read the channel = can read channel return !getMissingChannelPermissions(member, channel, readChannelPermissions); } diff --git a/backend/src/utils/getMissingChannelPermissions.ts b/backend/src/utils/getMissingChannelPermissions.ts index a1a7be9a..25f1e9e7 100644 --- a/backend/src/utils/getMissingChannelPermissions.ts +++ b/backend/src/utils/getMissingChannelPermissions.ts @@ -1,4 +1,4 @@ -import { GuildChannel, GuildMember, ThreadChannel } from "discord.js"; +import { GuildMember, GuildTextBasedChannel } from "discord.js"; import { getMissingPermissions } from "./getMissingPermissions"; /** @@ -7,7 +7,7 @@ import { getMissingPermissions } from "./getMissingPermissions"; */ export function getMissingChannelPermissions( member: GuildMember, - channel: GuildChannel | ThreadChannel, + channel: GuildTextBasedChannel, requiredPermissions: number | bigint, ): bigint { const memberChannelPermissions = channel.permissionsFor(member.id); diff --git a/backend/src/utils/resolveMessageTarget.ts b/backend/src/utils/resolveMessageTarget.ts index a7c3043c..4b24b779 100644 --- a/backend/src/utils/resolveMessageTarget.ts +++ b/backend/src/utils/resolveMessageTarget.ts @@ -1,4 +1,4 @@ -import { Snowflake, TextChannel } from "discord.js"; +import { GuildTextBasedChannel, Snowflake, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; import { getChannelIdFromMessageId } from "../data/getChannelIdFromMessageId"; import { isSnowflake } from "../utils"; @@ -7,7 +7,7 @@ const channelAndMessageIdRegex = /^(\d+)[\-\/](\d+)$/; const messageLinkRegex = /^https:\/\/(?:\w+\.)?discord(?:app)?\.com\/channels\/\d+\/(\d+)\/(\d+)$/i; export interface MessageTarget { - channel: TextChannel; + channel: GuildTextBasedChannel; messageId: string; } @@ -47,7 +47,7 @@ export async function resolveMessageTarget(pluginData: GuildPluginData, val } const channel = pluginData.guild.channels.resolve(result.channelId as Snowflake); - if (!channel || !(channel instanceof TextChannel)) { + if (!channel?.isText()) { return null; }