diff --git a/discord/audit_log.go b/discord/audit_log.go index 4135c558..8a000807 100644 --- a/discord/audit_log.go +++ b/discord/audit_log.go @@ -122,6 +122,11 @@ const ( AuditLogCreatorMonetizationTermsAccepted ) +const ( + AuditLogVoiceChannelStatusCreate AuditLogEvent = iota + 192 + AuditLogVoiceChannelStatusDelete +) + // AuditLog (https://discord.com/developers/docs/resources/audit-log) These are logs of events that occurred, accessible via the Discord type AuditLog struct { ApplicationCommands []ApplicationCommand `json:"application_commands"` @@ -255,4 +260,5 @@ type OptionalAuditLogEntryInfo struct { AutoModerationRuleName *string `json:"auto_moderation_rule_name"` AutoModerationRuleTriggerType *AutoModerationTriggerType `json:"auto_moderation_rule_trigger_type,string"` IntegrationType *IntegrationType `json:"integration_type"` + Status *string `json:"status"` } diff --git a/discord/channel.go b/discord/channel.go index 3abec1d1..b5c9b333 100644 --- a/discord/channel.go +++ b/discord/channel.go @@ -442,6 +442,7 @@ type GuildVoiceChannel struct { rtcRegion string VideoQualityMode VideoQualityMode lastMessageID *snowflake.ID + status *string nsfw bool rateLimitPerUser int } @@ -463,6 +464,7 @@ func (c *GuildVoiceChannel) UnmarshalJSON(data []byte) error { c.rtcRegion = v.RTCRegion c.VideoQualityMode = v.VideoQualityMode c.lastMessageID = v.LastMessageID + c.status = v.Status c.nsfw = v.NSFW c.rateLimitPerUser = v.RateLimitPerUser return nil @@ -482,6 +484,7 @@ func (c GuildVoiceChannel) MarshalJSON() ([]byte, error) { RTCRegion: c.rtcRegion, VideoQualityMode: c.VideoQualityMode, LastMessageID: c.lastMessageID, + Status: c.status, NSFW: c.nsfw, RateLimitPerUser: c.rateLimitPerUser, }) @@ -545,6 +548,10 @@ func (c GuildVoiceChannel) Topic() *string { return nil } +func (c GuildVoiceChannel) Status() *string { + return c.status +} + func (c GuildVoiceChannel) NSFW() bool { return c.nsfw } @@ -1304,6 +1311,10 @@ type PartialChannel struct { Type ChannelType `json:"type"` } +type VoiceStatusUpdate struct { + Status string `json:"status"` +} + // VideoQualityMode https://com/developers/docs/resources/channel#channel-object-video-quality-modes type VideoQualityMode int diff --git a/discord/channels_raw.go b/discord/channels_raw.go index ac66f8d5..89555474 100644 --- a/discord/channels_raw.go +++ b/discord/channels_raw.go @@ -129,6 +129,7 @@ type guildVoiceChannel struct { RTCRegion string `json:"rtc_region"` VideoQualityMode VideoQualityMode `json:"video_quality_mode"` LastMessageID *snowflake.ID `json:"last_message_id"` + Status *string `json:"status"` NSFW bool `json:"nsfw"` RateLimitPerUser int `json:"rate_limit_per_user"` } diff --git a/discord/permissions.go b/discord/permissions.go index fe5a826a..b402dc01 100644 --- a/discord/permissions.go +++ b/discord/permissions.go @@ -63,6 +63,8 @@ const ( _ PermissionUseExternalSounds PermissionSendVoiceMessages + _ + PermissionSetVoiceChannelStatus PermissionsAllText = PermissionViewChannel | PermissionSendMessages | @@ -91,7 +93,8 @@ const ( PermissionUseSoundboard | PermissionUseExternalSounds | PermissionRequestToSpeak | - PermissionUseEmbeddedActivities + PermissionUseEmbeddedActivities | + PermissionSetVoiceChannelStatus PermissionsAllChannel = PermissionsAllText | PermissionsAllThread | @@ -168,6 +171,7 @@ var permissions = map[Permissions]string{ PermissionStream: "Video", PermissionViewGuildInsights: "View Server Insights", PermissionSendVoiceMessages: "Send Voice Messages", + PermissionSetVoiceChannelStatus: "Set Voice Channel Status", } func (p Permissions) String() string { diff --git a/events/guild_voice_events.go b/events/guild_voice_events.go index bc3a5cbb..e4e4035a 100644 --- a/events/guild_voice_events.go +++ b/events/guild_voice_events.go @@ -40,3 +40,8 @@ type VoiceServerUpdate struct { *GenericEvent gateway.EventVoiceServerUpdate } + +type VoiceChannelStatusUpdate struct { + *GenericEvent + gateway.EventVoiceChannelStatusUpdate +} diff --git a/events/listener_adapter.go b/events/listener_adapter.go index ca82951e..d79a255f 100644 --- a/events/listener_adapter.go +++ b/events/listener_adapter.go @@ -104,11 +104,12 @@ type ListenerAdapter struct { OnGuildMessageReactionRemoveAll func(event *GuildMessageReactionRemoveAll) // Guild Voice Events - OnVoiceServerUpdate func(event *VoiceServerUpdate) - OnGuildVoiceStateUpdate func(event *GuildVoiceStateUpdate) - OnGuildVoiceJoin func(event *GuildVoiceJoin) - OnGuildVoiceMove func(event *GuildVoiceMove) - OnGuildVoiceLeave func(event *GuildVoiceLeave) + OnVoiceChannelStatusUpdate func(event *VoiceChannelStatusUpdate) + OnVoiceServerUpdate func(event *VoiceServerUpdate) + OnGuildVoiceStateUpdate func(event *GuildVoiceStateUpdate) + OnGuildVoiceJoin func(event *GuildVoiceJoin) + OnGuildVoiceMove func(event *GuildVoiceMove) + OnGuildVoiceLeave func(event *GuildVoiceLeave) // Guild StageInstance Events OnStageInstanceCreate func(event *StageInstanceCreate) @@ -445,6 +446,10 @@ func (l *ListenerAdapter) OnEvent(event bot.Event) { } // Guild Voice Events + case *VoiceChannelStatusUpdate: + if listener := l.OnVoiceChannelStatusUpdate; listener != nil { + listener(e) + } case *VoiceServerUpdate: if listener := l.OnVoiceServerUpdate; listener != nil { listener(e) diff --git a/gateway/gateway_event_type.go b/gateway/gateway_event_type.go index 88ebd49c..1bd2376e 100644 --- a/gateway/gateway_event_type.go +++ b/gateway/gateway_event_type.go @@ -66,6 +66,7 @@ const ( EventTypeStageInstanceUpdate EventType = "STAGE_INSTANCE_UPDATE" EventTypeTypingStart EventType = "TYPING_START" EventTypeUserUpdate EventType = "USER_UPDATE" + EventTypeVoiceChannelStatusUpdate EventType = "VOICE_CHANNEL_STATUS_UPDATE" EventTypeVoiceStateUpdate EventType = "VOICE_STATE_UPDATE" EventTypeVoiceServerUpdate EventType = "VOICE_SERVER_UPDATE" EventTypeWebhooksUpdate EventType = "WEBHOOKS_UPDATE" diff --git a/gateway/gateway_events.go b/gateway/gateway_events.go index 34a85a6b..f59ec163 100644 --- a/gateway/gateway_events.go +++ b/gateway/gateway_events.go @@ -568,6 +568,15 @@ type EventUserUpdate struct { func (EventUserUpdate) messageData() {} func (EventUserUpdate) eventData() {} +type EventVoiceChannelStatusUpdate struct { + ID snowflake.ID `json:"id"` + GuildID snowflake.ID `json:"guild_id"` + Status *string `json:"status"` +} + +func (EventVoiceChannelStatusUpdate) messageData() {} +func (EventVoiceChannelStatusUpdate) eventData() {} + type EventVoiceStateUpdate struct { discord.VoiceState Member discord.Member `json:"member"` diff --git a/gateway/gateway_messages.go b/gateway/gateway_messages.go index 8eca2e0f..4a92f930 100644 --- a/gateway/gateway_messages.go +++ b/gateway/gateway_messages.go @@ -394,6 +394,11 @@ func UnmarshalEventData(data []byte, eventType EventType) (EventData, error) { err = json.Unmarshal(data, &d) eventData = d + case EventTypeVoiceChannelStatusUpdate: + var d EventVoiceChannelStatusUpdate + err = json.Unmarshal(data, &d) + eventData = d + case EventTypeVoiceStateUpdate: var d EventVoiceStateUpdate err = json.Unmarshal(data, &d) diff --git a/handlers/all_handlers.go b/handlers/all_handlers.go index 5e1f2b5b..cde8c5cc 100644 --- a/handlers/all_handlers.go +++ b/handlers/all_handlers.go @@ -111,6 +111,7 @@ var allEventHandlers = []bot.GatewayEventHandler{ bot.NewGatewayEventHandler(gateway.EventTypeTypingStart, gatewayHandlerTypingStart), bot.NewGatewayEventHandler(gateway.EventTypeUserUpdate, gatewayHandlerUserUpdate), + bot.NewGatewayEventHandler(gateway.EventTypeVoiceChannelStatusUpdate, gatewayHandlerVoiceChannelStatusUpdate), bot.NewGatewayEventHandler(gateway.EventTypeVoiceStateUpdate, gatewayHandlerVoiceStateUpdate), bot.NewGatewayEventHandler(gateway.EventTypeVoiceServerUpdate, gatewayHandlerVoiceServerUpdate), diff --git a/handlers/voice_handlers.go b/handlers/voice_handlers.go index ea906ccc..97f24a52 100644 --- a/handlers/voice_handlers.go +++ b/handlers/voice_handlers.go @@ -61,3 +61,10 @@ func gatewayHandlerVoiceServerUpdate(client bot.Client, sequenceNumber int, shar EventVoiceServerUpdate: event, }) } + +func gatewayHandlerVoiceChannelStatusUpdate(client bot.Client, sequenceNumber int, shardID int, event gateway.EventVoiceChannelStatusUpdate) { + client.EventManager().DispatchEvent(&events.VoiceChannelStatusUpdate{ + GenericEvent: events.NewGenericEvent(client, sequenceNumber, shardID), + EventVoiceChannelStatusUpdate: event, + }) +} diff --git a/rest/channels.go b/rest/channels.go index 3afd4556..642b1920 100644 --- a/rest/channels.go +++ b/rest/channels.go @@ -47,6 +47,8 @@ type Channels interface { PinMessage(channelID snowflake.ID, messageID snowflake.ID, opts ...RequestOpt) error UnpinMessage(channelID snowflake.ID, messageID snowflake.ID, opts ...RequestOpt) error Follow(channelID snowflake.ID, targetChannelID snowflake.ID, opts ...RequestOpt) (*discord.FollowedChannel, error) + + UpdateVoiceStatus(channelID snowflake.ID, status string, opts ...RequestOpt) error } type channelImpl struct { @@ -222,3 +224,7 @@ func (s *channelImpl) Follow(channelID snowflake.ID, targetChannelID snowflake.I err = s.client.Do(FollowChannel.Compile(nil, channelID), discord.FollowChannel{ChannelID: targetChannelID}, &followedChannel, opts...) return } + +func (s *channelImpl) UpdateVoiceStatus(channelID snowflake.ID, status string, opts ...RequestOpt) error { + return s.client.Do(UpdateVoiceStatus.Compile(nil, channelID), discord.VoiceStatusUpdate{Status: status}, nil, opts...) +} diff --git a/rest/rest_endpoints.go b/rest/rest_endpoints.go index 1cb2a12d..edc9d0bc 100644 --- a/rest/rest_endpoints.go +++ b/rest/rest_endpoints.go @@ -170,6 +170,8 @@ var ( SendTyping = NewEndpoint(http.MethodPost, "/channels/{channel.id}/typing") FollowChannel = NewEndpoint(http.MethodPost, "/channels/{channel.id}/followers") + + UpdateVoiceStatus = NewEndpoint(http.MethodPut, "/channels/{channel.id}/voice-status") ) // Threads