From 9e0783c37f5d254d9eb0139f5054db484f13e26a Mon Sep 17 00:00:00 2001 From: Fedor Lapshin Date: Fri, 29 Apr 2022 00:23:07 +0300 Subject: [PATCH] Application commands: Permissions v2 (#1075) * feat(interactions): default command permissions * feat: add ApplicationCommandPermissionTypeChannel * feat: add deprecation and oauth2 scope comments * feat(interactions): add GuildAllChannelsID function * feat(examples/slash_commands): application command permissions * feat(events): add ApplicationCommandPermissionsUpdate * feat: add AuditLogActionApplicationCommandPermissionUpdate * feat(interactions#GuildAllChannelsID): use strconv instead of math/big * feat(interactions#GuildAllChannelsID): error handling * feat: cosmetic changes * fix(examples/slash_commands): handle error returned by GuildAllChannelsID * fix: typo * fix: typo --- eventhandlers.go | 275 ++++++++++++++++++-------------- events.go | 5 + examples/slash_commands/main.go | 89 ++++++++++- interactions.go | 23 ++- restapi.go | 4 + structs.go | 2 + 6 files changed, 273 insertions(+), 125 deletions(-) diff --git a/eventhandlers.go b/eventhandlers.go index d0e382f..f2ec080 100644 --- a/eventhandlers.go +++ b/eventhandlers.go @@ -7,69 +7,90 @@ package discordgo // Event type values are used to match the events returned by Discord. // EventTypes surrounded by __ are synthetic and are internal to DiscordGo. const ( - channelCreateEventType = "CHANNEL_CREATE" - channelDeleteEventType = "CHANNEL_DELETE" - channelPinsUpdateEventType = "CHANNEL_PINS_UPDATE" - channelUpdateEventType = "CHANNEL_UPDATE" - connectEventType = "__CONNECT__" - disconnectEventType = "__DISCONNECT__" - eventEventType = "__EVENT__" - guildBanAddEventType = "GUILD_BAN_ADD" - guildBanRemoveEventType = "GUILD_BAN_REMOVE" - guildCreateEventType = "GUILD_CREATE" - guildDeleteEventType = "GUILD_DELETE" - guildEmojisUpdateEventType = "GUILD_EMOJIS_UPDATE" - guildIntegrationsUpdateEventType = "GUILD_INTEGRATIONS_UPDATE" - guildMemberAddEventType = "GUILD_MEMBER_ADD" - guildMemberRemoveEventType = "GUILD_MEMBER_REMOVE" - guildMemberUpdateEventType = "GUILD_MEMBER_UPDATE" - guildMembersChunkEventType = "GUILD_MEMBERS_CHUNK" - guildRoleCreateEventType = "GUILD_ROLE_CREATE" - guildRoleDeleteEventType = "GUILD_ROLE_DELETE" - guildRoleUpdateEventType = "GUILD_ROLE_UPDATE" - guildStageInstanceCreateEventType = "STAGE_INSTANCE_CREATE" - guildStageInstanceUpdateEventType = "STAGE_INSTANCE_UPDATE" - guildStageInstanceDeleteEventType = "STAGE_INSTANCE_DELETE" - guildScheduledEventCreateEventType = "GUILD_SCHEDULED_EVENT_CREATE" - guildScheduledEventDeleteEventType = "GUILD_SCHEDULED_EVENT_DELETE" - guildScheduledEventUpdateEventType = "GUILD_SCHEDULED_EVENT_UPDATE" - guildScheduledEventUserAddEventType = "GUILD_SCHEDULED_EVENT_USER_ADD" - guildScheduledEventUserRemoveEventType = "GUILD_SCHEDULED_EVENT_USER_REMOVE" - guildUpdateEventType = "GUILD_UPDATE" - interactionCreateEventType = "INTERACTION_CREATE" - inviteCreateEventType = "INVITE_CREATE" - inviteDeleteEventType = "INVITE_DELETE" - messageAckEventType = "MESSAGE_ACK" - messageCreateEventType = "MESSAGE_CREATE" - messageDeleteEventType = "MESSAGE_DELETE" - messageDeleteBulkEventType = "MESSAGE_DELETE_BULK" - messageReactionAddEventType = "MESSAGE_REACTION_ADD" - messageReactionRemoveEventType = "MESSAGE_REACTION_REMOVE" - messageReactionRemoveAllEventType = "MESSAGE_REACTION_REMOVE_ALL" - messageUpdateEventType = "MESSAGE_UPDATE" - presenceUpdateEventType = "PRESENCE_UPDATE" - presencesReplaceEventType = "PRESENCES_REPLACE" - rateLimitEventType = "__RATE_LIMIT__" - readyEventType = "READY" - relationshipAddEventType = "RELATIONSHIP_ADD" - relationshipRemoveEventType = "RELATIONSHIP_REMOVE" - resumedEventType = "RESUMED" - threadCreateEventType = "THREAD_CREATE" - threadDeleteEventType = "THREAD_DELETE" - threadListSyncEventType = "THREAD_LIST_SYNC" - threadMemberUpdateEventType = "THREAD_MEMBER_UPDATE" - threadMembersUpdateEventType = "THREAD_MEMBERS_UPDATE" - threadUpdateEventType = "THREAD_UPDATE" - typingStartEventType = "TYPING_START" - userGuildSettingsUpdateEventType = "USER_GUILD_SETTINGS_UPDATE" - userNoteUpdateEventType = "USER_NOTE_UPDATE" - userSettingsUpdateEventType = "USER_SETTINGS_UPDATE" - userUpdateEventType = "USER_UPDATE" - voiceServerUpdateEventType = "VOICE_SERVER_UPDATE" - voiceStateUpdateEventType = "VOICE_STATE_UPDATE" - webhooksUpdateEventType = "WEBHOOKS_UPDATE" + applicationCommandPermissionsUpdateEventType = "APPLICATION_COMMAND_PERMISSIONS_UPDATE" + channelCreateEventType = "CHANNEL_CREATE" + channelDeleteEventType = "CHANNEL_DELETE" + channelPinsUpdateEventType = "CHANNEL_PINS_UPDATE" + channelUpdateEventType = "CHANNEL_UPDATE" + connectEventType = "__CONNECT__" + disconnectEventType = "__DISCONNECT__" + eventEventType = "__EVENT__" + guildBanAddEventType = "GUILD_BAN_ADD" + guildBanRemoveEventType = "GUILD_BAN_REMOVE" + guildCreateEventType = "GUILD_CREATE" + guildDeleteEventType = "GUILD_DELETE" + guildEmojisUpdateEventType = "GUILD_EMOJIS_UPDATE" + guildIntegrationsUpdateEventType = "GUILD_INTEGRATIONS_UPDATE" + guildMemberAddEventType = "GUILD_MEMBER_ADD" + guildMemberRemoveEventType = "GUILD_MEMBER_REMOVE" + guildMemberUpdateEventType = "GUILD_MEMBER_UPDATE" + guildMembersChunkEventType = "GUILD_MEMBERS_CHUNK" + guildRoleCreateEventType = "GUILD_ROLE_CREATE" + guildRoleDeleteEventType = "GUILD_ROLE_DELETE" + guildRoleUpdateEventType = "GUILD_ROLE_UPDATE" + guildScheduledEventCreateEventType = "GUILD_SCHEDULED_EVENT_CREATE" + guildScheduledEventDeleteEventType = "GUILD_SCHEDULED_EVENT_DELETE" + guildScheduledEventUpdateEventType = "GUILD_SCHEDULED_EVENT_UPDATE" + guildScheduledEventUserAddEventType = "GUILD_SCHEDULED_EVENT_USER_ADD" + guildScheduledEventUserRemoveEventType = "GUILD_SCHEDULED_EVENT_USER_REMOVE" + guildUpdateEventType = "GUILD_UPDATE" + interactionCreateEventType = "INTERACTION_CREATE" + inviteCreateEventType = "INVITE_CREATE" + inviteDeleteEventType = "INVITE_DELETE" + messageAckEventType = "MESSAGE_ACK" + messageCreateEventType = "MESSAGE_CREATE" + messageDeleteEventType = "MESSAGE_DELETE" + messageDeleteBulkEventType = "MESSAGE_DELETE_BULK" + messageReactionAddEventType = "MESSAGE_REACTION_ADD" + messageReactionRemoveEventType = "MESSAGE_REACTION_REMOVE" + messageReactionRemoveAllEventType = "MESSAGE_REACTION_REMOVE_ALL" + messageUpdateEventType = "MESSAGE_UPDATE" + presenceUpdateEventType = "PRESENCE_UPDATE" + presencesReplaceEventType = "PRESENCES_REPLACE" + rateLimitEventType = "__RATE_LIMIT__" + readyEventType = "READY" + relationshipAddEventType = "RELATIONSHIP_ADD" + relationshipRemoveEventType = "RELATIONSHIP_REMOVE" + resumedEventType = "RESUMED" + stageInstanceEventCreateEventType = "STAGE_INSTANCE_EVENT_CREATE" + stageInstanceEventDeleteEventType = "STAGE_INSTANCE_EVENT_DELETE" + stageInstanceEventUpdateEventType = "STAGE_INSTANCE_EVENT_UPDATE" + threadCreateEventType = "THREAD_CREATE" + threadDeleteEventType = "THREAD_DELETE" + threadListSyncEventType = "THREAD_LIST_SYNC" + threadMemberUpdateEventType = "THREAD_MEMBER_UPDATE" + threadMembersUpdateEventType = "THREAD_MEMBERS_UPDATE" + threadUpdateEventType = "THREAD_UPDATE" + typingStartEventType = "TYPING_START" + userGuildSettingsUpdateEventType = "USER_GUILD_SETTINGS_UPDATE" + userNoteUpdateEventType = "USER_NOTE_UPDATE" + userSettingsUpdateEventType = "USER_SETTINGS_UPDATE" + userUpdateEventType = "USER_UPDATE" + voiceServerUpdateEventType = "VOICE_SERVER_UPDATE" + voiceStateUpdateEventType = "VOICE_STATE_UPDATE" + webhooksUpdateEventType = "WEBHOOKS_UPDATE" ) +// applicationCommandPermissionsUpdateEventHandler is an event handler for ApplicationCommandPermissionsUpdate events. +type applicationCommandPermissionsUpdateEventHandler func(*Session, *ApplicationCommandPermissionsUpdate) + +// Type returns the event type for ApplicationCommandPermissionsUpdate events. +func (eh applicationCommandPermissionsUpdateEventHandler) Type() string { + return applicationCommandPermissionsUpdateEventType +} + +// New returns a new instance of ApplicationCommandPermissionsUpdate. +func (eh applicationCommandPermissionsUpdateEventHandler) New() interface{} { + return &ApplicationCommandPermissionsUpdate{} +} + +// Handle is the handler for ApplicationCommandPermissionsUpdate events. +func (eh applicationCommandPermissionsUpdateEventHandler) Handle(s *Session, i interface{}) { + if t, ok := i.(*ApplicationCommandPermissionsUpdate); ok { + eh(s, t) + } +} + // channelCreateEventHandler is an event handler for ChannelCreate events. type channelCreateEventHandler func(*Session, *ChannelCreate) @@ -455,66 +476,6 @@ func (eh guildRoleUpdateEventHandler) Handle(s *Session, i interface{}) { } } -// guildStageInstanceEventCreateHandler is an event handler for StageInstanceEventCreate events. -type guildStageInstanceEventCreateHandler func(*Session, *StageInstanceEventCreate) - -// Type returns the event type for StageInstanceEventCreate events. -func (eh guildStageInstanceEventCreateHandler) Type() string { - return guildStageInstanceCreateEventType -} - -// New returns a new instance of StageInstanceEventCreate. -func (eh guildStageInstanceEventCreateHandler) New() interface{} { - return &StageInstanceEventCreate{} -} - -// Handle is the handler for StageInstanceEventCreate events. -func (eh guildStageInstanceEventCreateHandler) Handle(s *Session, i interface{}) { - if t, ok := i.(*StageInstanceEventCreate); ok { - eh(s, t) - } -} - -// guildStageInstanceEventUpdateHandler is an event handler for StageInstanceEventUpdate events. -type guildStageInstanceEventUpdateHandler func(*Session, *StageInstanceEventUpdate) - -// Type returns the event type for StageInstanceEventUpdate events. -func (eh guildStageInstanceEventUpdateHandler) Type() string { - return guildStageInstanceCreateEventType -} - -// New returns a new instance of StageInstanceEventUpdate. -func (eh guildStageInstanceEventUpdateHandler) New() interface{} { - return &StageInstanceEventUpdate{} -} - -// Handle is the handler for StageInstanceEventUpdate events. -func (eh guildStageInstanceEventUpdateHandler) Handle(s *Session, i interface{}) { - if t, ok := i.(*StageInstanceEventUpdate); ok { - eh(s, t) - } -} - -// guildStageInstanceEventDeleteHandler is an event handler for StageInstanceEventDelete events. -type guildStageInstanceEventDeleteHandler func(*Session, *StageInstanceEventDelete) - -// Type returns the event type for StageInstanceEventDelete events. -func (eh guildStageInstanceEventDeleteHandler) Type() string { - return guildStageInstanceCreateEventType -} - -// New returns a new instance of StageInstanceEventDelete. -func (eh guildStageInstanceEventDeleteHandler) New() interface{} { - return &StageInstanceEventDelete{} -} - -// Handle is the handler for StageInstanceEventDelete events. -func (eh guildStageInstanceEventDeleteHandler) Handle(s *Session, i interface{}) { - if t, ok := i.(*StageInstanceEventDelete); ok { - eh(s, t) - } -} - // guildScheduledEventCreateEventHandler is an event handler for GuildScheduledEventCreate events. type guildScheduledEventCreateEventHandler func(*Session, *GuildScheduledEventCreate) @@ -990,6 +951,66 @@ func (eh resumedEventHandler) Handle(s *Session, i interface{}) { } } +// stageInstanceEventCreateEventHandler is an event handler for StageInstanceEventCreate events. +type stageInstanceEventCreateEventHandler func(*Session, *StageInstanceEventCreate) + +// Type returns the event type for StageInstanceEventCreate events. +func (eh stageInstanceEventCreateEventHandler) Type() string { + return stageInstanceEventCreateEventType +} + +// New returns a new instance of StageInstanceEventCreate. +func (eh stageInstanceEventCreateEventHandler) New() interface{} { + return &StageInstanceEventCreate{} +} + +// Handle is the handler for StageInstanceEventCreate events. +func (eh stageInstanceEventCreateEventHandler) Handle(s *Session, i interface{}) { + if t, ok := i.(*StageInstanceEventCreate); ok { + eh(s, t) + } +} + +// stageInstanceEventDeleteEventHandler is an event handler for StageInstanceEventDelete events. +type stageInstanceEventDeleteEventHandler func(*Session, *StageInstanceEventDelete) + +// Type returns the event type for StageInstanceEventDelete events. +func (eh stageInstanceEventDeleteEventHandler) Type() string { + return stageInstanceEventDeleteEventType +} + +// New returns a new instance of StageInstanceEventDelete. +func (eh stageInstanceEventDeleteEventHandler) New() interface{} { + return &StageInstanceEventDelete{} +} + +// Handle is the handler for StageInstanceEventDelete events. +func (eh stageInstanceEventDeleteEventHandler) Handle(s *Session, i interface{}) { + if t, ok := i.(*StageInstanceEventDelete); ok { + eh(s, t) + } +} + +// stageInstanceEventUpdateEventHandler is an event handler for StageInstanceEventUpdate events. +type stageInstanceEventUpdateEventHandler func(*Session, *StageInstanceEventUpdate) + +// Type returns the event type for StageInstanceEventUpdate events. +func (eh stageInstanceEventUpdateEventHandler) Type() string { + return stageInstanceEventUpdateEventType +} + +// New returns a new instance of StageInstanceEventUpdate. +func (eh stageInstanceEventUpdateEventHandler) New() interface{} { + return &StageInstanceEventUpdate{} +} + +// Handle is the handler for StageInstanceEventUpdate events. +func (eh stageInstanceEventUpdateEventHandler) Handle(s *Session, i interface{}) { + if t, ok := i.(*StageInstanceEventUpdate); ok { + eh(s, t) + } +} + // threadCreateEventHandler is an event handler for ThreadCreate events. type threadCreateEventHandler func(*Session, *ThreadCreate) @@ -1274,6 +1295,8 @@ func handlerForInterface(handler interface{}) EventHandler { switch v := handler.(type) { case func(*Session, interface{}): return interfaceEventHandler(v) + case func(*Session, *ApplicationCommandPermissionsUpdate): + return applicationCommandPermissionsUpdateEventHandler(v) case func(*Session, *ChannelCreate): return channelCreateEventHandler(v) case func(*Session, *ChannelDelete): @@ -1362,6 +1385,12 @@ func handlerForInterface(handler interface{}) EventHandler { return relationshipRemoveEventHandler(v) case func(*Session, *Resumed): return resumedEventHandler(v) + case func(*Session, *StageInstanceEventCreate): + return stageInstanceEventCreateEventHandler(v) + case func(*Session, *StageInstanceEventDelete): + return stageInstanceEventDeleteEventHandler(v) + case func(*Session, *StageInstanceEventUpdate): + return stageInstanceEventUpdateEventHandler(v) case func(*Session, *ThreadCreate): return threadCreateEventHandler(v) case func(*Session, *ThreadDelete): @@ -1396,6 +1425,7 @@ func handlerForInterface(handler interface{}) EventHandler { } func init() { + registerInterfaceProvider(applicationCommandPermissionsUpdateEventHandler(nil)) registerInterfaceProvider(channelCreateEventHandler(nil)) registerInterfaceProvider(channelDeleteEventHandler(nil)) registerInterfaceProvider(channelPinsUpdateEventHandler(nil)) @@ -1436,6 +1466,9 @@ func init() { registerInterfaceProvider(relationshipAddEventHandler(nil)) registerInterfaceProvider(relationshipRemoveEventHandler(nil)) registerInterfaceProvider(resumedEventHandler(nil)) + registerInterfaceProvider(stageInstanceEventCreateEventHandler(nil)) + registerInterfaceProvider(stageInstanceEventDeleteEventHandler(nil)) + registerInterfaceProvider(stageInstanceEventUpdateEventHandler(nil)) registerInterfaceProvider(threadCreateEventHandler(nil)) registerInterfaceProvider(threadDeleteEventHandler(nil)) registerInterfaceProvider(threadListSyncEventHandler(nil)) diff --git a/events.go b/events.go index c90aede..17c7828 100644 --- a/events.go +++ b/events.go @@ -401,3 +401,8 @@ type InviteDelete struct { GuildID string `json:"guild_id"` Code string `json:"code"` } + +// ApplicationCommandPermissionsUpdate is the data for an ApplicationCommandPermissionsUpdate event +type ApplicationCommandPermissionsUpdate struct { + *GuildApplicationCommandPermissions +} diff --git a/examples/slash_commands/main.go b/examples/slash_commands/main.go index b464a47..9f9a6ce 100644 --- a/examples/slash_commands/main.go +++ b/examples/slash_commands/main.go @@ -1,6 +1,7 @@ package main import ( + "errors" "flag" "fmt" "log" @@ -32,7 +33,9 @@ func init() { } var ( - integerOptionMinValue = 1.0 + integerOptionMinValue = 1.0 + dmPermission = false + defaultMemberPermissions int64 = discordgo.PermissionManageServer commands = []*discordgo.ApplicationCommand{ { @@ -42,6 +45,12 @@ var ( // of the command. Description: "Basic command", }, + { + Name: "permission-overview", + Description: "Command for demonstration of default command permissions", + DefaultMemberPermissions: &defaultMemberPermissions, + DMPermission: &dmPermission, + }, { Name: "basic-command-with-files", Description: "Basic command with files", @@ -320,6 +329,84 @@ var ( }, }) }, + "permission-overview": func(s *discordgo.Session, i *discordgo.InteractionCreate) { + perms, err := s.ApplicationCommandPermissions(s.State.User.ID, i.GuildID, i.ApplicationCommandData().ID) + + var restError *discordgo.RESTError + if errors.As(err, &restError) && restError.Message != nil && restError.Message.Code == discordgo.ErrCodeUnknownApplicationCommandPermissions { + s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{ + Type: discordgo.InteractionResponseChannelMessageWithSource, + Data: &discordgo.InteractionResponseData{ + Content: ":x: No permission overwrites", + }, + }) + return + } else if err != nil { + panic(err) + } + + if err != nil { + panic(err) + } + format := "- %s %s\n" + + channels := "" + users := "" + roles := "" + + for _, o := range perms.Permissions { + emoji := "❌" + if o.Permission { + emoji = "☑" + } + + switch o.Type { + case discordgo.ApplicationCommandPermissionTypeUser: + users += fmt.Sprintf(format, emoji, "<@!"+o.ID+">") + case discordgo.ApplicationCommandPermissionTypeChannel: + allChannels, _ := discordgo.GuildAllChannelsID(i.GuildID) + + if o.ID == allChannels { + channels += fmt.Sprintf(format, emoji, "All channels") + } else { + channels += fmt.Sprintf(format, emoji, "<#"+o.ID+">") + } + case discordgo.ApplicationCommandPermissionTypeRole: + if o.ID == i.GuildID { + roles += fmt.Sprintf(format, emoji, "@everyone") + } else { + roles += fmt.Sprintf(format, emoji, "<@&"+o.ID+">") + } + } + } + + s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{ + Type: discordgo.InteractionResponseChannelMessageWithSource, + Data: &discordgo.InteractionResponseData{ + Embeds: []*discordgo.MessageEmbed{ + { + Title: "Permissions overview", + Description: "Overview of permissions for this command", + Fields: []*discordgo.MessageEmbedField{ + { + Name: "Users", + Value: users, + }, + { + Name: "Channels", + Value: channels, + }, + { + Name: "Roles", + Value: roles, + }, + }, + }, + }, + AllowedMentions: &discordgo.MessageAllowedMentions{}, + }, + }) + }, "subcommands": func(s *discordgo.Session, i *discordgo.InteractionCreate) { options := i.ApplicationCommandData().Options content := "" diff --git a/interactions.go b/interactions.go index 7164f65..7c2f824 100644 --- a/interactions.go +++ b/interactions.go @@ -9,6 +9,7 @@ import ( "io" "io/ioutil" "net/http" + "strconv" "time" ) @@ -36,7 +37,10 @@ type ApplicationCommand struct { Type ApplicationCommandType `json:"type,omitempty"` Name string `json:"name"` NameLocalizations *map[Locale]string `json:"name_localizations,omitempty"` - DefaultPermission *bool `json:"default_permission,omitempty"` + // NOTE: DefaultPermission will be soon deprecated. Use DefaultMemberPermissions and DMPermission instead. + DefaultPermission *bool `json:"default_permission,omitempty"` + DefaultMemberPermissions *int64 `json:"default_member_permissions,string,omitempty"` + DMPermission *bool `json:"dm_permission,omitempty"` // NOTE: Chat commands only. Otherwise it mustn't be set. @@ -129,6 +133,18 @@ type ApplicationCommandPermissions struct { Permission bool `json:"permission"` } +// GuildAllChannelsID is a helper function which returns guild_id-1. +// It is used in ApplicationCommandPermissions to target all the channels within a guild. +func GuildAllChannelsID(guild string) (id string, err error) { + var v uint64 + v, err = strconv.ParseUint(guild, 10, 64) + if err != nil { + return + } + + return strconv.FormatUint(v-1, 10), nil +} + // ApplicationCommandPermissionsList represents a list of ApplicationCommandPermissions, needed for serializing to JSON. type ApplicationCommandPermissionsList struct { Permissions []*ApplicationCommandPermissions `json:"permissions"` @@ -147,8 +163,9 @@ type ApplicationCommandPermissionType uint8 // Application command permission types. const ( - ApplicationCommandPermissionTypeRole ApplicationCommandPermissionType = 1 - ApplicationCommandPermissionTypeUser ApplicationCommandPermissionType = 2 + ApplicationCommandPermissionTypeRole ApplicationCommandPermissionType = 1 + ApplicationCommandPermissionTypeUser ApplicationCommandPermissionType = 2 + ApplicationCommandPermissionTypeChannel ApplicationCommandPermissionType = 3 ) // InteractionType indicates the type of an interaction event. diff --git a/restapi.go b/restapi.go index bb21ef2..1eee79c 100644 --- a/restapi.go +++ b/restapi.go @@ -2840,6 +2840,8 @@ func (s *Session) ApplicationCommandPermissions(appID, guildID, cmdID string) (p // guildID : The guild ID containing the application command // cmdID : The command ID to edit the permissions of // permissions : An object containing a list of permissions for the application command +// +// NOTE: Requires OAuth2 token with applications.commands.permissions.update scope func (s *Session) ApplicationCommandPermissionsEdit(appID, guildID, cmdID string, permissions *ApplicationCommandPermissionsList) (err error) { endpoint := EndpointApplicationCommandPermissions(appID, guildID, cmdID) @@ -2851,6 +2853,8 @@ func (s *Session) ApplicationCommandPermissionsEdit(appID, guildID, cmdID string // appID : The Application ID // guildID : The guild ID to batch edit commands of // permissions : A list of permissions paired with a command ID, guild ID, and application ID per application command +// +// NOTE: This endpoint has been disabled with updates to command permissions (Permissions v2). Please use ApplicationCommandPermissionsEdit instead. func (s *Session) ApplicationCommandPermissionsBatchEdit(appID, guildID string, permissions []*GuildApplicationCommandPermissions) (err error) { endpoint := EndpointApplicationCommandsGuildPermissions(appID, guildID) diff --git a/structs.go b/structs.go index a1e0232..9c4d0a4 100644 --- a/structs.go +++ b/structs.go @@ -1574,6 +1574,8 @@ const ( AuditLogActionThreadCreate AuditLogAction = 110 AuditLogActionThreadUpdate AuditLogAction = 111 AuditLogActionThreadDelete AuditLogAction = 112 + + AuditLogActionApplicationCommandPermissionUpdate = 121 ) // A UserGuildSettingsChannelOverride stores data for a channel override for a users guild settings.