diff --git a/src/client/actions/ActionsManager.js b/src/client/actions/ActionsManager.js
index 0f3f53169f7a..bcb9f2744ed2 100644
--- a/src/client/actions/ActionsManager.js
+++ b/src/client/actions/ActionsManager.js
@@ -4,6 +4,7 @@ class ActionsManager {
constructor(client) {
this.client = client;
+ this.register(require('./ApplicationCommandPermissionsUpdate'));
this.register(require('./AutoModerationActionExecution'));
this.register(require('./AutoModerationRuleCreate'));
this.register(require('./AutoModerationRuleDelete'));
diff --git a/src/client/actions/ApplicationCommandPermissionsUpdate.js b/src/client/actions/ApplicationCommandPermissionsUpdate.js
new file mode 100644
index 000000000000..0aa518cafd4d
--- /dev/null
+++ b/src/client/actions/ApplicationCommandPermissionsUpdate.js
@@ -0,0 +1,34 @@
+'use strict';
+
+const Action = require('./Action');
+const { Events } = require('../../util/Constants');
+
+/**
+ * The data received in the {@link Client#event:applicationCommandPermissionsUpdate} event
+ * @typedef {Object} ApplicationCommandPermissionsUpdateData
+ * @property {Snowflake} id The id of the command or global entity that was updated
+ * @property {Snowflake} guildId The id of the guild in which permissions were updated
+ * @property {Snowflake} applicationId The id of the application that owns the command or entity being updated
+ * @property {ApplicationCommandPermissions[]} permissions The updated permissions
+ */
+
+class ApplicationCommandPermissionsUpdateAction extends Action {
+ handle(data) {
+ const client = this.client;
+ /**
+ * Emitted whenever permissions for an application command in a guild were updated.
+ * This includes permission updates for other applications in addition to the logged in client,
+ * check `data.applicationId` to verify which application the update is for
+ * @event Client#applicationCommandPermissionsUpdate
+ * @param {ApplicationCommandPermissionsUpdateData} data The updated permissions
+ */
+ client.emit(Events.APPLICATION_COMMAND_PERMISSIONS_UPDATE, {
+ permissions: data.permissions,
+ id: data.id,
+ guildId: data.guild_id,
+ applicationId: data.application_id,
+ });
+ }
+}
+
+module.exports = ApplicationCommandPermissionsUpdateAction;
diff --git a/src/client/websocket/handlers/APPLICATION_COMMAND_PERMISSIONS_UPDATE.js b/src/client/websocket/handlers/APPLICATION_COMMAND_PERMISSIONS_UPDATE.js
new file mode 100644
index 000000000000..73d4ec47f464
--- /dev/null
+++ b/src/client/websocket/handlers/APPLICATION_COMMAND_PERMISSIONS_UPDATE.js
@@ -0,0 +1,5 @@
+'use strict';
+
+module.exports = (client, packet) => {
+ client.actions.ApplicationCommandPermissionsUpdate.handle(packet.d);
+};
diff --git a/src/client/websocket/handlers/index.js b/src/client/websocket/handlers/index.js
index 7a0926499b69..62e43a991996 100644
--- a/src/client/websocket/handlers/index.js
+++ b/src/client/websocket/handlers/index.js
@@ -6,6 +6,7 @@ const handlers = Object.fromEntries([
['APPLICATION_COMMAND_CREATE', require('./APPLICATION_COMMAND_CREATE')],
['APPLICATION_COMMAND_DELETE', require('./APPLICATION_COMMAND_DELETE')],
['APPLICATION_COMMAND_UPDATE', require('./APPLICATION_COMMAND_UPDATE')],
+ ['APPLICATION_COMMAND_PERMISSIONS_UPDATE', require('./APPLICATION_COMMAND_PERMISSIONS_UPDATE')],
['AUTO_MODERATION_ACTION_EXECUTION', require('./AUTO_MODERATION_ACTION_EXECUTION')],
['AUTO_MODERATION_RULE_CREATE', require('./AUTO_MODERATION_RULE_CREATE')],
['AUTO_MODERATION_RULE_DELETE', require('./AUTO_MODERATION_RULE_DELETE')],
diff --git a/src/structures/GuildAuditLogs.js b/src/structures/GuildAuditLogs.js
index 2a736f51795c..ed4bbfa95caf 100644
--- a/src/structures/GuildAuditLogs.js
+++ b/src/structures/GuildAuditLogs.js
@@ -1,6 +1,7 @@
'use strict';
const { Collection } = require('@discordjs/collection');
+const ApplicationCommand = require('./ApplicationCommand');
const AutoModerationRule = require('./AutoModerationRule');
const { GuildScheduledEvent } = require('./GuildScheduledEvent');
const Integration = require('./Integration');
@@ -27,6 +28,7 @@ const Util = require('../util/Util');
* * STICKER
* * THREAD
* * GUILD_SCHEDULED_EVENT
+ * * APPLICATION_COMMAND
* * AUTO_MODERATION
* @typedef {string} AuditLogTargetType
*/
@@ -51,6 +53,7 @@ const Targets = {
STAGE_INSTANCE: 'STAGE_INSTANCE',
STICKER: 'STICKER',
THREAD: 'THREAD',
+ APPLICATION_COMMAND: 'APPLICATION_COMMAND',
AUTO_MODERATION: 'AUTO_MODERATION',
UNKNOWN: 'UNKNOWN',
};
@@ -105,6 +108,7 @@ const Targets = {
* * THREAD_CREATE: 110
* * THREAD_UPDATE: 111
* * THREAD_DELETE: 112
+ * * APPLICATION_COMMAND_PERMISSION_UPDATE: 121
* * AUTO_MODERATION_RULE_CREATE: 140
* * AUTO_MODERATION_RULE_UPDATE: 141
* * AUTO_MODERATION_RULE_DELETE: 142
@@ -169,6 +173,7 @@ const Actions = {
THREAD_CREATE: 110,
THREAD_UPDATE: 111,
THREAD_DELETE: 112,
+ APPLICATION_COMMAND_PERMISSION_UPDATE: 121,
AUTO_MODERATION_RULE_CREATE: 140,
AUTO_MODERATION_RULE_UPDATE: 141,
AUTO_MODERATION_RULE_DELETE: 142,
@@ -208,6 +213,17 @@ class GuildAuditLogs {
}
}
+ /**
+ * Cached application commands, includes application commands from other applications
+ * @type {Collection}
+ * @private
+ */
+ this.applicationCommands = new Collection();
+ if (data.application_commands) {
+ for (const command of data.application_commands) {
+ this.applicationCommands.set(command.id, new ApplicationCommand(guild.client, command, guild));
+ }
+ }
/**
* Cached auto moderation rules.
* @type {Collection}
@@ -255,11 +271,12 @@ class GuildAuditLogs {
* * A sticker
* * A guild scheduled event
* * A thread
+ * * An application command
* * An auto moderation rule
* * An object with an id key if target was deleted
* * An object where the keys represent either the new value or the old value
* @typedef {?(Object|Guild|Channel|User|Role|Invite|Webhook|GuildEmoji|Message|Integration|StageInstance|Sticker|
- * GuildScheduledEvent|AutoModerationRule)} AuditLogEntryTarget
+ * GuildScheduledEvent|ApplicationCommand|AutoModerationRule)} AuditLogEntryTarget
*/
/**
@@ -281,6 +298,7 @@ class GuildAuditLogs {
if (target < 100) return Targets.STICKER;
if (target < 110) return Targets.GUILD_SCHEDULED_EVENT;
if (target < 120) return Targets.THREAD;
+ if (target < 130) return Targets.APPLICATION_COMMAND;
if (target >= 140 && target < 150) return Targets.AUTO_MODERATION;
return Targets.UNKNOWN;
}
@@ -366,6 +384,7 @@ class GuildAuditLogs {
Actions.STICKER_UPDATE,
Actions.GUILD_SCHEDULED_EVENT_UPDATE,
Actions.THREAD_UPDATE,
+ Actions.APPLICATION_COMMAND_PERMISSION_UPDATE,
Actions.AUTO_MODERATION_RULE_UPDATE,
].includes(action)
) {
@@ -506,6 +525,11 @@ class GuildAuditLogsEntry {
channel: guild.client.channels.cache.get(data.options?.channel_id) ?? { id: data.options?.channel_id },
};
break;
+ case Actions.APPLICATION_COMMAND_PERMISSION_UPDATE:
+ this.extra = {
+ applicationId: data.options.application_id,
+ };
+ break;
case Actions.AUTO_MODERATION_BLOCK_MESSAGE:
case Actions.AUTO_MODERATION_FLAG_TO_CHANNEL:
case Actions.AUTO_MODERATION_USER_COMMUNICATION_DISABLED:
@@ -641,6 +665,8 @@ class GuildAuditLogsEntry {
{ id: data.target_id, guild_id: guild.id },
),
);
+ } else if (targetType === Targets.APPLICATION_COMMAND) {
+ this.target = logs?.applicationCommands.get(data.target_id) ?? { id: data.target_id };
} else if (targetType === Targets.AUTO_MODERATION) {
this.target =
guild.autoModerationRules.cache.get(data.target_id) ??
diff --git a/src/util/Constants.js b/src/util/Constants.js
index cf70715960db..06a1f1720132 100644
--- a/src/util/Constants.js
+++ b/src/util/Constants.js
@@ -174,6 +174,7 @@ exports.Opcodes = {
* * APPLICATION_COMMAND_CREATE: applicationCommandCreate (deprecated)
* * APPLICATION_COMMAND_DELETE: applicationCommandDelete (deprecated)
* * APPLICATION_COMMAND_UPDATE: applicationCommandUpdate (deprecated)
+ * * APPLICATION_COMMAND_PERMISSIONS_UPDATE: applicationCommandPermissionsUpdate
* * AUTO_MODERATION_ACTION_EXECUTION: autoModerationActionExecution
* * AUTO_MODERATION_RULE_CREATE: autoModerationRuleCreate
* * AUTO_MODERATION_RULE_DELETE: autoModerationRuleDelete
@@ -256,6 +257,7 @@ exports.Events = {
APPLICATION_COMMAND_CREATE: 'applicationCommandCreate',
APPLICATION_COMMAND_DELETE: 'applicationCommandDelete',
APPLICATION_COMMAND_UPDATE: 'applicationCommandUpdate',
+ APPLICATION_COMMAND_PERMISSIONS_UPDATE: 'applicationCommandPermissionsUpdate',
AUTO_MODERATION_ACTION_EXECUTION: 'autoModerationActionExecution',
AUTO_MODERATION_RULE_CREATE: 'autoModerationRuleCreate',
AUTO_MODERATION_RULE_DELETE: 'autoModerationRuleDelete',
@@ -368,6 +370,7 @@ exports.PartialTypes = keyMirror(['USER', 'CHANNEL', 'GUILD_MEMBER', 'MESSAGE',
* * RESUMED
* * APPLICATION_COMMAND_CREATE (deprecated)
* * APPLICATION_COMMAND_DELETE (deprecated)
+ * * APPLICATION_COMMAND_PERMISSIONS_UPDATE
* * APPLICATION_COMMAND_UPDATE (deprecated)
* * GUILD_CREATE
* * GUILD_DELETE
@@ -428,6 +431,7 @@ exports.WSEvents = keyMirror([
'APPLICATION_COMMAND_CREATE',
'APPLICATION_COMMAND_DELETE',
'APPLICATION_COMMAND_UPDATE',
+ 'APPLICATION_COMMAND_PERMISSIONS_UPDATE',
'GUILD_CREATE',
'GUILD_DELETE',
'GUILD_UPDATE',
diff --git a/typings/index.d.ts b/typings/index.d.ts
index e4547b92fe99..63a0067bf9eb 100644
--- a/typings/index.d.ts
+++ b/typings/index.d.ts
@@ -4178,6 +4178,13 @@ export interface ApplicationCommandPermissionData {
permission: boolean;
}
+export interface ApplicationCommandPermissionsUpdateData {
+ permissions: ApplicationCommandPermissions;
+ id: Snowflake;
+ guildId: Snowflake;
+ applicationId: Snowflake;
+}
+
export interface ApplicationCommandPermissions extends ApplicationCommandPermissionData {
type: ApplicationCommandPermissionType;
}
@@ -4441,6 +4448,7 @@ export interface ClientEvents extends BaseClientEvents {
applicationCommandDelete: [command: ApplicationCommand];
/** @deprecated See [this issue](https://github.com/discord/discord-api-docs/issues/3690) for more information. */
applicationCommandUpdate: [oldCommand: ApplicationCommand | null, newCommand: ApplicationCommand];
+ applicationCommandPermissionsUpdate: [data: ApplicationCommandPermissionsUpdateData];
autoModerationActionExecution: [autoModerationActionExecution: AutoModerationActionExecution];
autoModerationRuleCreate: [autoModerationRule: AutoModerationRule];
autoModerationRuleDelete: [autoModerationRule: AutoModerationRule];
@@ -4719,6 +4727,7 @@ export interface ConstantsEvents {
APPLICATION_COMMAND_CREATE: 'applicationCommandCreate';
/** @deprecated See [this issue](https://github.com/discord/discord-api-docs/issues/3690) for more information. */
APPLICATION_COMMAND_DELETE: 'applicationCommandDelete';
+ APPLICATION_COMMAND_PERMISSIONS_UPDATE: 'applicationCommandPermissionsUpdate';
/** @deprecated See [this issue](https://github.com/discord/discord-api-docs/issues/3690) for more information. */
APPLICATION_COMMAND_UPDATE: 'applicationCommandUpdate';
AUTO_MODERATION_ACTION_EXECUTION: 'autoModerationActionExecution';
@@ -5081,6 +5090,7 @@ interface GuildAuditLogsTypes {
THREAD_CREATE: ['THREAD', 'CREATE'];
THREAD_UPDATE: ['THREAD', 'UPDATE'];
THREAD_DELETE: ['THREAD', 'DELETE'];
+ APPLICATION_COMMAND_PERMISSION_UPDATE: ['APPLICATION_COMMAND_PERMISSION', 'UPDATE'];
AUTO_MODERATION_RULE_CREATE: ['AUTO_MODERATION', 'CREATE'];
AUTO_MODERATION_RULE_UPDATE: ['AUTO_MODERATION', 'UPDATE'];
AUTO_MODERATION_RULE_DELETE: ['AUTO_MODERATION', 'DELETE'];
@@ -5137,6 +5147,7 @@ export interface GuildAuditLogsIds {
110: 'THREAD_CREATE';
111: 'THREAD_UPDATE';
112: 'THREAD_DELETE';
+ 121: 'APPLICATION_COMMAND_PERMISSION_UPDATE';
140: 'AUTO_MODERATION_RULE_CREATE';
141: 'AUTO_MODERATION_RULE_UPDATE';
142: 'AUTO_MODERATION_RULE_DELETE';
@@ -5177,6 +5188,9 @@ export interface GuildAuditLogsEntryExtraField {
STAGE_INSTANCE_CREATE: StageChannel | { id: Snowflake };
STAGE_INSTANCE_DELETE: StageChannel | { id: Snowflake };
STAGE_INSTANCE_UPDATE: StageChannel | { id: Snowflake };
+ APPLICATION_COMMAND_PERMISSION_UPDATE: {
+ applicationId: Snowflake;
+ };
AUTO_MODERATION_BLOCK_MESSAGE: {
autoModerationRuleName: string;
autoModerationRuleTriggerType: AutoModerationRuleTriggerType;
@@ -5203,6 +5217,7 @@ export interface GuildAuditLogsEntryTargetField