diff --git a/package.json b/package.json index 0a1723c74..cf5f0d7ae 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "dependencies": { "@discordjs/builders": "^1.4.0", "@sapphire/discord-utilities": "^3.0.0", - "@sapphire/discord.js-utilities": "6.0.2", + "@sapphire/discord.js-utilities": "6.0.3", "@sapphire/lexure": "^1.1.2", "@sapphire/pieces": "^3.6.0", "@sapphire/ratelimits": "^2.4.5", diff --git a/src/preconditions/ClientPermissions.ts b/src/preconditions/ClientPermissions.ts index 94bbcb5cd..d4af73c0e 100644 --- a/src/preconditions/ClientPermissions.ts +++ b/src/preconditions/ClientPermissions.ts @@ -1,11 +1,12 @@ +import { isNullish } from '@sapphire/utilities'; import { + BaseInteraction, ChatInputCommandInteraction, ContextMenuCommandInteraction, PermissionFlagsBits, PermissionsBitField, PermissionsString, - type BaseGuildTextChannel, - type GuildTextBasedChannel, + TextBasedChannel, type Message } from 'discord.js'; import { Identifiers } from '../lib/errors/Identifiers'; @@ -30,9 +31,9 @@ export class CorePrecondition extends AllFlowsPrecondition { ]).bitfield & PermissionsBitField.All ).freeze(); - public messageRun(message: Message, _: Command, context: PermissionPreconditionContext): AllFlowsPrecondition.Result { + public async messageRun(message: Message, _: Command, context: PermissionPreconditionContext): AllFlowsPrecondition.AsyncResult { const required = context.permissions ?? new PermissionsBitField(); - const channel = message.channel as BaseGuildTextChannel; + const { channel } = message; if (!message.client.id) { return this.error({ @@ -41,7 +42,7 @@ export class CorePrecondition extends AllFlowsPrecondition { }); } - const permissions = message.guild ? channel.permissionsFor(message.client.id) : this.dmChannelPermissions; + const permissions = await this.getPermissionsForChannel(channel, message); return this.sharedRun(required, permissions, 'message'); } @@ -53,9 +54,9 @@ export class CorePrecondition extends AllFlowsPrecondition { ): AllFlowsPrecondition.AsyncResult { const required = context.permissions ?? new PermissionsBitField(); - const channel = (await this.fetchChannelFromInteraction(interaction)) as GuildTextBasedChannel; + const channel = await this.fetchChannelFromInteraction(interaction); - const permissions = interaction.inGuild() ? channel.permissionsFor(interaction.applicationId) : this.dmChannelPermissions; + const permissions = await this.getPermissionsForChannel(channel, interaction); return this.sharedRun(required, permissions, 'chat input'); } @@ -66,13 +67,33 @@ export class CorePrecondition extends AllFlowsPrecondition { context: PermissionPreconditionContext ): AllFlowsPrecondition.AsyncResult { const required = context.permissions ?? new PermissionsBitField(); - const channel = (await this.fetchChannelFromInteraction(interaction)) as GuildTextBasedChannel; - const permissions = interaction.inGuild() ? channel.permissionsFor(interaction.applicationId) : this.dmChannelPermissions; + const channel = await this.fetchChannelFromInteraction(interaction); + + const permissions = await this.getPermissionsForChannel(channel, interaction); return this.sharedRun(required, permissions, 'context menu'); } + private async getPermissionsForChannel(channel: TextBasedChannel, messageOrInteraction: Message | BaseInteraction) { + let permissions: PermissionsBitField | null = this.dmChannelPermissions; + + if (messageOrInteraction.inGuild() && !channel.isDMBased()) { + if (!isNullish(messageOrInteraction.applicationId)) { + permissions = channel.permissionsFor(messageOrInteraction.applicationId); + } + + if (isNullish(permissions)) { + const me = await messageOrInteraction.guild?.members.fetchMe(); + if (me) { + permissions = channel.permissionsFor(me); + } + } + } + + return permissions; + } + private sharedRun(requiredPermissions: PermissionsBitField, availablePermissions: PermissionsBitField | null, commandType: string) { if (!availablePermissions) { return this.error({ diff --git a/yarn.lock b/yarn.lock index 18a41c7ce..9e6b0811b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -859,15 +859,15 @@ __metadata: languageName: node linkType: hard -"@sapphire/discord.js-utilities@npm:6.0.2": - version: 6.0.2 - resolution: "@sapphire/discord.js-utilities@npm:6.0.2" +"@sapphire/discord.js-utilities@npm:6.0.3": + version: 6.0.3 + resolution: "@sapphire/discord.js-utilities@npm:6.0.3" dependencies: "@sapphire/discord-utilities": ^3.0.0 "@sapphire/duration": ^1.0.0 "@sapphire/utilities": ^3.11.0 tslib: ^2.5.0 - checksum: 985b15b9d5f7bb2bed5e919ab7fc8a69dca9ef5baa3a44443b64558dce3303560027b0ed21a72ff849179e9181524316ffdfed6eb267020e3c10378b361c2f07 + checksum: 9b0f2cc2da626b7ade3a14087eebd03adf60ec67f1b8fdd2d16dc5cf4c08f553e29db5341e205913a7dc9c27757d6ebc729a6b311932e544d37b4f5c857513cd languageName: node linkType: hard @@ -913,7 +913,7 @@ __metadata: "@favware/npm-deprecate": ^1.0.7 "@favware/rollup-type-bundler": ^2.0.0 "@sapphire/discord-utilities": ^3.0.0 - "@sapphire/discord.js-utilities": 6.0.2 + "@sapphire/discord.js-utilities": 6.0.3 "@sapphire/eslint-config": ^4.3.8 "@sapphire/lexure": ^1.1.2 "@sapphire/pieces": ^3.6.0