diff --git a/Backend/Remora.Discord.API.Abstractions/API/Gateway/Events/Channels/IVoiceChannelStatusUpdate.cs b/Backend/Remora.Discord.API.Abstractions/API/Gateway/Events/Channels/IVoiceChannelStatusUpdate.cs new file mode 100644 index 0000000000..beb6899b8c --- /dev/null +++ b/Backend/Remora.Discord.API.Abstractions/API/Gateway/Events/Channels/IVoiceChannelStatusUpdate.cs @@ -0,0 +1,46 @@ +// +// IVoiceChannelStatusUpdate.cs +// +// Author: +// Jarl Gullberg +// +// Copyright (c) Jarl Gullberg +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +// + +using Remora.Rest.Core; + +namespace Remora.Discord.API.Abstractions.Gateway.Events; + +/// +/// Represents an update to the respective voice channel. +/// +public interface IVoiceChannelStatusUpdate : IGatewayEvent +{ + /// + /// Gets the ID of the channel being updated. + /// + Snowflake ID { get; } + + /// + /// Gets the ID of the guild. + /// + Snowflake GuildID { get; } + + /// + /// Gets the new status of the voice channel. + /// + Optional Status { get; } +} diff --git a/Backend/Remora.Discord.API.Abstractions/API/Objects/Channels/IChannel.cs b/Backend/Remora.Discord.API.Abstractions/API/Objects/Channels/IChannel.cs index aa19fdb6d0..a139d7ccc8 100644 --- a/Backend/Remora.Discord.API.Abstractions/API/Objects/Channels/IChannel.cs +++ b/Backend/Remora.Discord.API.Abstractions/API/Objects/Channels/IChannel.cs @@ -212,6 +212,11 @@ public interface IChannel : IPartialChannel /// new Optional DefaultForumLayout { get; } + /// + /// Gets the status of the channel. + /// + new Optional Status { get; } + /// Optional IPartialChannel.ID => this.ID; @@ -316,4 +321,7 @@ public interface IChannel : IPartialChannel /// Optional IPartialChannel.DefaultForumLayout => this.DefaultForumLayout; + + /// + Optional IPartialChannel.Status => this.Status; } diff --git a/Backend/Remora.Discord.API.Abstractions/API/Objects/Channels/IPartialChannel.cs b/Backend/Remora.Discord.API.Abstractions/API/Objects/Channels/IPartialChannel.cs index 9d4977a6e4..c933c0decf 100644 --- a/Backend/Remora.Discord.API.Abstractions/API/Objects/Channels/IPartialChannel.cs +++ b/Backend/Remora.Discord.API.Abstractions/API/Objects/Channels/IPartialChannel.cs @@ -137,4 +137,7 @@ public interface IPartialChannel /// Optional DefaultForumLayout { get; } + + /// + Optional Status { get; } } diff --git a/Backend/Remora.Discord.API.Abstractions/API/Rest/IDiscordRestChannelAPI.cs b/Backend/Remora.Discord.API.Abstractions/API/Rest/IDiscordRestChannelAPI.cs index f15150463d..8b8ef96c4a 100644 --- a/Backend/Remora.Discord.API.Abstractions/API/Rest/IDiscordRestChannelAPI.cs +++ b/Backend/Remora.Discord.API.Abstractions/API/Rest/IDiscordRestChannelAPI.cs @@ -47,6 +47,22 @@ public interface IDiscordRestChannelAPI /// A retrieval result which may or may not have succeeded. Task> GetChannelAsync(Snowflake channelID, CancellationToken ct = default); + /// + /// Sets the status of a given voice channel. + /// + /// The ID of the channel. + /// The status to set. + /// The reason to mark the action in the audit log with. + /// The cancellation token for this operation. + /// A modification result that may or not have succeeded. + Task SetVoiceChannelStatusAsync + ( + Snowflake channelID, + Optional status, + Optional reason = default, + CancellationToken ct = default + ); + /// /// Modifies the given channel. /// diff --git a/Backend/Remora.Discord.API/API/Gateway/Events/Channels/ChannelCreate.cs b/Backend/Remora.Discord.API/API/Gateway/Events/Channels/ChannelCreate.cs index a43a002c27..be6e6f99f3 100644 --- a/Backend/Remora.Discord.API/API/Gateway/Events/Channels/ChannelCreate.cs +++ b/Backend/Remora.Discord.API/API/Gateway/Events/Channels/ChannelCreate.cs @@ -67,5 +67,6 @@ public record ChannelCreate Optional DefaultReactionEmoji = default, Optional DefaultThreadRateLimitPerUser = default, Optional DefaultSortOrder = default, - Optional DefaultForumLayout = default + Optional DefaultForumLayout = default, + Optional Status = default ) : IChannelCreate; diff --git a/Backend/Remora.Discord.API/API/Gateway/Events/Channels/ChannelDelete.cs b/Backend/Remora.Discord.API/API/Gateway/Events/Channels/ChannelDelete.cs index e7daa340b7..2fc61d1766 100644 --- a/Backend/Remora.Discord.API/API/Gateway/Events/Channels/ChannelDelete.cs +++ b/Backend/Remora.Discord.API/API/Gateway/Events/Channels/ChannelDelete.cs @@ -67,5 +67,6 @@ public record ChannelDelete Optional DefaultReactionEmoji = default, Optional DefaultThreadRateLimitPerUser = default, Optional DefaultSortOrder = default, - Optional DefaultForumLayout = default + Optional DefaultForumLayout = default, + Optional Status = default ) : IChannelDelete; diff --git a/Backend/Remora.Discord.API/API/Gateway/Events/Channels/ChannelUpdate.cs b/Backend/Remora.Discord.API/API/Gateway/Events/Channels/ChannelUpdate.cs index 3734b175dc..8fc54378fb 100644 --- a/Backend/Remora.Discord.API/API/Gateway/Events/Channels/ChannelUpdate.cs +++ b/Backend/Remora.Discord.API/API/Gateway/Events/Channels/ChannelUpdate.cs @@ -67,5 +67,6 @@ public record ChannelUpdate Optional DefaultReactionEmoji = default, Optional DefaultThreadRateLimitPerUser = default, Optional DefaultSortOrder = default, - Optional DefaultForumLayout = default + Optional DefaultForumLayout = default, + Optional Status = default ) : IChannelUpdate; diff --git a/Backend/Remora.Discord.API/API/Gateway/Events/Channels/ThreadCreate.cs b/Backend/Remora.Discord.API/API/Gateway/Events/Channels/ThreadCreate.cs index f894ba43df..efcb06fe31 100644 --- a/Backend/Remora.Discord.API/API/Gateway/Events/Channels/ThreadCreate.cs +++ b/Backend/Remora.Discord.API/API/Gateway/Events/Channels/ThreadCreate.cs @@ -68,5 +68,6 @@ public record ThreadCreate Optional DefaultReactionEmoji = default, Optional DefaultThreadRateLimitPerUser = default, Optional DefaultSortOrder = default, - Optional DefaultForumLayout = default + Optional DefaultForumLayout = default, + Optional Status = default ) : IThreadCreate; diff --git a/Backend/Remora.Discord.API/API/Gateway/Events/Channels/ThreadDelete.cs b/Backend/Remora.Discord.API/API/Gateway/Events/Channels/ThreadDelete.cs index 2f54e11aa6..c0a01c7379 100644 --- a/Backend/Remora.Discord.API/API/Gateway/Events/Channels/ThreadDelete.cs +++ b/Backend/Remora.Discord.API/API/Gateway/Events/Channels/ThreadDelete.cs @@ -67,5 +67,6 @@ public record ThreadDelete Optional DefaultReactionEmoji = default, Optional DefaultThreadRateLimitPerUser = default, Optional DefaultSortOrder = default, - Optional DefaultForumLayout = default + Optional DefaultForumLayout = default, + Optional Status = default ) : IThreadDelete; diff --git a/Backend/Remora.Discord.API/API/Gateway/Events/Channels/ThreadUpdate.cs b/Backend/Remora.Discord.API/API/Gateway/Events/Channels/ThreadUpdate.cs index e7ea9279da..aa7a812617 100644 --- a/Backend/Remora.Discord.API/API/Gateway/Events/Channels/ThreadUpdate.cs +++ b/Backend/Remora.Discord.API/API/Gateway/Events/Channels/ThreadUpdate.cs @@ -67,5 +67,6 @@ public record ThreadUpdate Optional DefaultReactionEmoji = default, Optional DefaultThreadRateLimitPerUser = default, Optional DefaultSortOrder = default, - Optional DefaultForumLayout = default + Optional DefaultForumLayout = default, + Optional Status = default ) : IThreadUpdate; diff --git a/Backend/Remora.Discord.API/API/Gateway/Events/Channels/VoiceChannelStatusUpdate.cs b/Backend/Remora.Discord.API/API/Gateway/Events/Channels/VoiceChannelStatusUpdate.cs new file mode 100644 index 0000000000..589e45d43e --- /dev/null +++ b/Backend/Remora.Discord.API/API/Gateway/Events/Channels/VoiceChannelStatusUpdate.cs @@ -0,0 +1,34 @@ +// +// VoiceChannelStatusUpdate.cs +// +// Author: +// Jarl Gullberg +// +// Copyright (c) Jarl Gullberg +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +// + +using Remora.Discord.API.Abstractions.Gateway.Events; +using Remora.Rest.Core; + +namespace Remora.Discord.API.Gateway.Events.Channels; + +/// +public record VoiceChannelStatusUpdate +( + Snowflake ID, + Snowflake GuildID, + Optional Status +) : IVoiceChannelStatusUpdate; diff --git a/Backend/Remora.Discord.API/API/Objects/Channels/Channel.cs b/Backend/Remora.Discord.API/API/Objects/Channels/Channel.cs index 9b6ec4f736..54b98897a8 100644 --- a/Backend/Remora.Discord.API/API/Objects/Channels/Channel.cs +++ b/Backend/Remora.Discord.API/API/Objects/Channels/Channel.cs @@ -68,5 +68,6 @@ public record Channel Optional DefaultReactionEmoji = default, Optional DefaultThreadRateLimitPerUser = default, Optional DefaultSortOrder = default, - Optional DefaultForumLayout = default + Optional DefaultForumLayout = default, + Optional Status = default ) : IChannel; diff --git a/Backend/Remora.Discord.API/API/Objects/Channels/PartialChannel.cs b/Backend/Remora.Discord.API/API/Objects/Channels/PartialChannel.cs index 34f2b20f98..d5e5e21992 100644 --- a/Backend/Remora.Discord.API/API/Objects/Channels/PartialChannel.cs +++ b/Backend/Remora.Discord.API/API/Objects/Channels/PartialChannel.cs @@ -68,5 +68,6 @@ public record PartialChannel Optional DefaultReactionEmoji = default, Optional DefaultThreadRateLimitPerUser = default, Optional DefaultSortOrder = default, - Optional DefaultForumLayout = default + Optional DefaultForumLayout = default, + Optional Status = default ) : IPartialChannel; diff --git a/Backend/Remora.Discord.Caching/API/CachingDiscordRestChannelAPI.Delegations.cs b/Backend/Remora.Discord.Caching/API/CachingDiscordRestChannelAPI.Delegations.cs index 49b16d6fc1..0b228215d0 100644 --- a/Backend/Remora.Discord.Caching/API/CachingDiscordRestChannelAPI.Delegations.cs +++ b/Backend/Remora.Discord.Caching/API/CachingDiscordRestChannelAPI.Delegations.cs @@ -35,6 +35,18 @@ namespace Remora.Discord.Caching.API; public partial class CachingDiscordRestChannelAPI { + /// + public Task SetVoiceChannelStatusAsync + ( + Snowflake channelID, + Optional status, + Optional reason = default, + CancellationToken ct = default + ) + { + return _actual.SetVoiceChannelStatusAsync(channelID, status, reason, ct); + } + /// public Task> ModifyGroupDMChannelAsync ( diff --git a/Backend/Remora.Discord.Rest/API/Channels/DiscordRestChannelAPI.cs b/Backend/Remora.Discord.Rest/API/Channels/DiscordRestChannelAPI.cs index 0c56dcc928..76c599fbb9 100644 --- a/Backend/Remora.Discord.Rest/API/Channels/DiscordRestChannelAPI.cs +++ b/Backend/Remora.Discord.Rest/API/Channels/DiscordRestChannelAPI.cs @@ -80,6 +80,28 @@ public virtual Task> GetChannelAsync ); } + /// + public virtual Task SetVoiceChannelStatusAsync + ( + Snowflake channelID, + Optional status, + Optional reason = default, + CancellationToken ct = default + ) + { + if (status is { HasValue: true, Value: { Length: > 500 } }) + { + return Task.FromResult(new ArgumentOutOfRangeError(nameof(status), "The status must between 0 and 500 characters.")); + } + + return this.RestHttpClient.PatchAsync + ( + $"channels/{channelID}/voice-status", + b => b.WithJson(b => b.Write("status", status, this.JsonOptions)).WithRateLimitContext(this.RateLimitCache), + ct: ct + ); + } + /// public virtual async Task> ModifyChannelAsync (