From 0e88cd35476e341c6c0a8bf5599188e5f1a55c52 Mon Sep 17 00:00:00 2001 From: Superchupu <53496941+SuperchupuDev@users.noreply.github.com> Date: Wed, 12 Jul 2023 12:26:52 +0200 Subject: [PATCH] fix: improve message permission checks --- src/classes/Detector.ts | 7 ++++--- src/events/messageCreate.ts | 11 +++++------ src/events/messageUpdate.ts | 6 ++---- src/util/index.ts | 1 + src/util/sendable.ts | 20 ++++++++++++++++++++ 5 files changed, 32 insertions(+), 13 deletions(-) create mode 100644 src/util/sendable.ts diff --git a/src/classes/Detector.ts b/src/classes/Detector.ts index 18e0a1e..84acbbf 100644 --- a/src/classes/Detector.ts +++ b/src/classes/Detector.ts @@ -1,6 +1,7 @@ import { setTimeout } from 'node:timers/promises'; import type { Application } from '#classes'; import { env } from '#env'; +import { isSendable } from '#util'; import { type APIEmbedField, type GuildMember, @@ -64,8 +65,8 @@ export class Detector { } async reply(message: Message, edited: boolean) { - const permissions = message.channel.permissionsFor(this.client.user); - if (edited || (permissions && !permissions.has(PermissionFlagsBits.SendMessages))) { + const sendable = await isSendable(message.channel); + if (edited || !sendable) { return; } @@ -226,7 +227,7 @@ export class Detector { } } - if (channel?.permissionsFor(this.client.user)?.has(PermissionFlagsBits.SendMessages) && channel.viewable) { + if (channel && (await isSendable(channel))) { await channel.send({ embeds: [ { diff --git a/src/events/messageCreate.ts b/src/events/messageCreate.ts index ccbbcbe..1dabd56 100644 --- a/src/events/messageCreate.ts +++ b/src/events/messageCreate.ts @@ -1,26 +1,25 @@ import type { Application } from '#classes'; -import { type Message, MessageType, PermissionFlagsBits } from 'discord.js'; +import { isSendable } from '#util'; +import { type Message, MessageType } from 'discord.js'; export async function run(client: Application, message: Message) { - const permissions = message.channel.permissionsFor(client.user); if ( message.author.bot || message.author.system || (message.type !== MessageType.Default && message.type !== MessageType.Reply) || - !message.content || - (permissions && !permissions.has(PermissionFlagsBits.SendMessages)) + !message.content ) { return; } - if (message.content === `<@${client.user.id}>`) { + if (message.content === `<@${client.user.id}>` && (await isSendable(message.channel))) { return message.channel.send('Hi! Type `/` to see my commands'); } const [commandName] = message.content.slice(2).split(' '); const command = client.chatInputCommands.get(commandName); - if (message.content.startsWith('h!') && command && !command.dev) { + if (message.content.startsWith('h!') && command && !command.dev && (await isSendable(message.channel))) { const commands = client.application.commands.cache.size ? client.application.commands.cache : await client.application.commands.fetch(); diff --git a/src/events/messageUpdate.ts b/src/events/messageUpdate.ts index f5bd706..9969345 100644 --- a/src/events/messageUpdate.ts +++ b/src/events/messageUpdate.ts @@ -1,5 +1,5 @@ import type { Application } from '#classes'; -import { type Message, MessageType, PermissionFlagsBits } from 'discord.js'; +import { type Message, MessageType } from 'discord.js'; export async function run(client: Application, oldMessage: Message, message: Message) { if (message.partial) { @@ -10,13 +10,11 @@ export async function run(client: Application, oldMessage: Message, messag } } - const permissions = message.channel.permissionsFor(client.user); if ( message.author.bot || message.author.system || (message.type !== MessageType.Default && message.type !== MessageType.Reply) || - !message.content || - (permissions && !permissions.has(PermissionFlagsBits.SendMessages)) + !message.content ) { return; } diff --git a/src/util/index.ts b/src/util/index.ts index 9f6b132..ec63589 100644 --- a/src/util/index.ts +++ b/src/util/index.ts @@ -1,4 +1,5 @@ export { default as changelog } from './changelog.json' assert { type: 'json' }; export * from './fetchTags.js'; export * from './files.js'; +export * from './sendable.js'; export * from './types.js'; diff --git a/src/util/sendable.ts b/src/util/sendable.ts new file mode 100644 index 0000000..1ffab92 --- /dev/null +++ b/src/util/sendable.ts @@ -0,0 +1,20 @@ +import { type GuildTextBasedChannel, PermissionFlagsBits } from 'discord.js'; + +export async function isSendable(channel: GuildTextBasedChannel) { + if (channel.isThread()) { + return channel.sendable; + } + + const permissions = channel.permissionsFor(channel.client.user); + + if (!permissions || !channel.viewable) { + return false; + } + + if (permissions.has(PermissionFlagsBits.Administrator, false)) { + return true; + } + + const clientMember = await channel.guild.members.fetchMe(); + return permissions.has(PermissionFlagsBits.SendMessages, false) && !clientMember.isCommunicationDisabled(); +}