diff --git a/NetCord/AutoModerationActionMetadataProperties.cs b/NetCord/AutoModerationActionMetadataProperties.cs index e94702cd0..f592f7e84 100644 --- a/NetCord/AutoModerationActionMetadataProperties.cs +++ b/NetCord/AutoModerationActionMetadataProperties.cs @@ -5,12 +5,33 @@ namespace NetCord; [GenerateMethodsForProperties] public partial class AutoModerationActionMetadataProperties { + /// + /// The ID of the channel to which user content should be logged. + /// + /// + /// Required for an action. + /// This must be an existing channel. + /// [JsonPropertyName("channel_id")] public ulong? ChannelId { get; set; } + /// + /// The timeout duration, in seconds. + /// + /// + /// Required for an action. + /// The maximum duration is 2,419,200 seconds (4 weeks). + /// [JsonPropertyName("duration_seconds")] public int? DurationSeconds { get; set; } + /// + /// An additional explanation that will be shown to members whenever their message is blocked. + /// + /// + /// Only applies to an action. + /// The maximum length is 150 characters. + /// [JsonPropertyName("custom_message")] public string? CustomMessage { get; set; } } diff --git a/NetCord/Channels/TextChannels/Guild/ForumGuildChannel.cs b/NetCord/Channels/TextChannels/Guild/ForumGuildChannel.cs index 75127fecf..4861f1958 100644 --- a/NetCord/Channels/TextChannels/Guild/ForumGuildChannel.cs +++ b/NetCord/Channels/TextChannels/Guild/ForumGuildChannel.cs @@ -59,6 +59,10 @@ public ForumGuildChannel(JsonChannel jsonModel, ulong guildId, RestClient client /// /// The set of tags available for use in the channel. /// + /// + /// Can be set when creating or updating a channel, which determines which tags can be set on individual threads within the thread’s field. + /// When updating a or a channel, tag objects only require the name field. + /// public IReadOnlyList AvailableTags { get; } /// diff --git a/NetCord/CodeBlock.cs b/NetCord/CodeBlock.cs index 307369e91..8c54374e7 100644 --- a/NetCord/CodeBlock.cs +++ b/NetCord/CodeBlock.cs @@ -3,15 +3,30 @@ namespace NetCord; +/// +/// Represents a Discord Markdown fenced code block. +/// +/// The content of the code block. +/// The optional formatter or language identifier following the opening backticks. public class CodeBlock(string code, string? formatter = null) : ISpanFormattable, ISpanParsable { + /// + /// Gets the content of the code block. + /// public string Code { get; } = code; + + /// + /// Gets the formatter or language identifier of the code block, if present. + /// public string? Formatter { get; } = formatter; + /// public override string ToString() => $"```{Formatter}\n{Code}```"; + /// public string ToString(string? format, IFormatProvider? formatProvider) => ToString(); + /// public bool TryFormat(Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = null) { var code = Code; @@ -46,6 +61,20 @@ public bool TryFormat(Span destination, out int charsWritten, ReadOnlySpan return true; } + /// + /// Attempts to parse a Discord Markdown fenced code block. + /// + /// The characters to parse. + /// + /// Whether an apparent formatter followed only by whitespace should instead be treated as code. + /// + /// + /// When this method returns, contains the parsed code block if parsing succeeded; otherwise, . + /// + /// + /// if starts and ends with triple backticks and contains at least + /// one character between them; otherwise, . + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] // Inline so that 'strictMode' branches can be eliminated if it is a constant public static bool TryParse(ReadOnlySpan s, bool strictMode, [MaybeNullWhen(false)] out CodeBlock result) { @@ -89,12 +118,31 @@ public static bool TryParse(ReadOnlySpan s, bool strictMode, [MaybeNullWhe return isCodeBlock; } + /// + /// Attempts to parse a Discord Markdown fenced code block in strict mode. + /// + /// The characters to parse. + /// + /// When this method returns, contains the parsed code block if parsing succeeded; otherwise, . + /// + /// if parsing succeeded; otherwise, . public static bool TryParse(ReadOnlySpan s, [MaybeNullWhen(false)] out CodeBlock result) => TryParse(s, true, out result); + /// public static bool TryParse(ReadOnlySpan s, IFormatProvider? provider, [MaybeNullWhen(false)] out CodeBlock result) => TryParse(s, true, out result); + /// public static bool TryParse([NotNullWhen(true)] string? s, IFormatProvider? provider, [MaybeNullWhen(false)] out CodeBlock result) => TryParse(s.AsSpan(), true, out result); + /// + /// Parses a Discord Markdown fenced code block. + /// + /// The characters to parse. + /// + /// Whether an apparent formatter followed only by whitespace should instead be treated as code. + /// + /// The parsed code block. + /// is not a valid fenced code block. [MethodImpl(MethodImplOptions.AggressiveInlining)] // Inline so that 'strictMode' branches can be eliminated if it is a constant public static CodeBlock Parse(ReadOnlySpan s, bool strictMode) { @@ -104,9 +152,17 @@ public static CodeBlock Parse(ReadOnlySpan s, bool strictMode) throw new FormatException($"Cannot parse '{nameof(CodeBlock)}'."); } + /// + /// Parses a Discord Markdown fenced code block in strict mode. + /// + /// The characters to parse. + /// The parsed code block. + /// is not a valid fenced code block. public static CodeBlock Parse(ReadOnlySpan s) => Parse(s, true); + /// public static CodeBlock Parse(ReadOnlySpan s, IFormatProvider? provider) => Parse(s, true); + /// public static CodeBlock Parse(string s, IFormatProvider? provider) => Parse(s.AsSpan(), true); } diff --git a/NetCord/GuildFromGuildTemplateProperties.cs b/NetCord/GuildFromGuildTemplateProperties.cs index ceb4fdef5..56b07cf27 100644 --- a/NetCord/GuildFromGuildTemplateProperties.cs +++ b/NetCord/GuildFromGuildTemplateProperties.cs @@ -2,7 +2,18 @@ namespace NetCord.Rest; +/// +/// Represents properties used to create a guild from a guild template. +/// +/// +/// Discord deprecated application-driven guild creation in April 2025 +/// and removed the corresponding API endpoint in July 2025. +/// This type is retained for compatibility with +/// . +/// +/// The name of the guild. [GenerateMethodsForProperties] +[Obsolete("Discord deprecated application-driven guild creation in April 2025 and removed the corresponding API endpoint in July 2025.")] public partial class GuildFromGuildTemplateProperties(string name) { [JsonPropertyName("name")] diff --git a/NetCord/IToken.cs b/NetCord/IToken.cs index 60914524c..1f20f7a23 100644 --- a/NetCord/IToken.cs +++ b/NetCord/IToken.cs @@ -2,8 +2,18 @@ namespace NetCord; +/// +/// Represents a Discord bot token. +/// public class BotToken : IEntityToken { + /// + /// Initializes a new instance of the class. + /// + /// The raw bot token. + /// + /// is null or empty, or is not a valid bot token. + /// public BotToken(string token) { if (string.IsNullOrEmpty(token)) @@ -16,17 +26,40 @@ public BotToken(string token) RawToken = token; } + /// + /// Gets the raw bot token. + /// public string RawToken { get; } + /// + /// Gets the value to use for the HTTP Authorization header. + /// + /// + /// The value uses the Bot authentication scheme. + /// public string HttpHeaderValue => $"Bot {RawToken}"; + /// + /// Gets the entity ID encoded in the token. + /// public ulong Id { get; } + /// + /// Gets the creation time derived from . + /// public DateTimeOffset CreatedAt => Snowflake.Timestamp(Id); } +/// +/// Represents an OAuth2 bearer token. +/// public class BearerToken : IToken { + /// + /// Initializes a new instance of the class. + /// + /// The raw OAuth2 bearer token. + /// is null or empty. public BearerToken(string token) { if (string.IsNullOrEmpty(token)) @@ -35,13 +68,31 @@ public BearerToken(string token) RawToken = token; } + /// + /// Gets the raw bearer token. + /// public string RawToken { get; } + /// + /// Gets the value to use for the HTTP Authorization header. + /// + /// + /// The value uses the Bearer authentication scheme. + /// public string HttpHeaderValue => $"Bearer {RawToken}"; } +/// +/// Represents an authentication token that identifies a Discord entity. +/// public interface IEntityToken : IToken, IEntity { + /// + /// Attempts to extract the entity ID encoded in a token. + /// + /// The token to inspect. + /// When this method returns, contains the decoded entity ID if successful. + /// if the entity ID was decoded; otherwise, . [SkipLocalsInit] protected static bool TryGetTokenId(ReadOnlySpan token, out ulong id) { @@ -68,9 +119,18 @@ protected static bool TryGetTokenId(ReadOnlySpan token, out ulong id) } } +/// +/// Represents a Discord authentication token. +/// public interface IToken { + /// + /// Gets the raw token. + /// public string RawToken { get; } + /// + /// Gets the value to use for the HTTP Authorization header. + /// public string HttpHeaderValue { get; } } diff --git a/NetCord/MessagePollMediaProperties.cs b/NetCord/MessagePollMediaProperties.cs index 12483ff76..e3d260988 100644 --- a/NetCord/MessagePollMediaProperties.cs +++ b/NetCord/MessagePollMediaProperties.cs @@ -5,9 +5,22 @@ namespace NetCord; [GenerateMethodsForProperties] public partial class MessagePollMediaProperties { + /// + /// The text of the poll media. + /// + /// + /// This value should currently be non-null for both poll questions and poll answers. + /// Discord may support other forms of poll media in the future, which may not require text. + /// [JsonPropertyName("text")] public string? Text { get; set; } + /// + /// The emoji of the poll media. + /// + /// + /// This may be specified for poll answers. Poll questions currently only support . + /// [JsonPropertyName("emoji")] public EmojiProperties? Emoji { get; set; } } diff --git a/NetCord/Rest/ComponentProperties/ComponentMediaProperties.cs b/NetCord/Rest/ComponentProperties/ComponentMediaProperties.cs index 6a88721ed..127bb9028 100644 --- a/NetCord/Rest/ComponentProperties/ComponentMediaProperties.cs +++ b/NetCord/Rest/ComponentProperties/ComponentMediaProperties.cs @@ -5,6 +5,13 @@ namespace NetCord.Rest; [GenerateMethodsForProperties] public partial class ComponentMediaProperties(string url) { + /// + /// Source URL of the media item. + /// + /// + /// Supports arbitrary urls and attachment://<filename> references. + /// For a file component, only supports using the attachment:// protocol. + /// [JsonPropertyName("url")] public string Url { get; set; } = url; diff --git a/NetCord/Rest/ComponentProperties/FileDisplayProperties.cs b/NetCord/Rest/ComponentProperties/FileDisplayProperties.cs index 5e5d86e7e..47f2c6421 100644 --- a/NetCord/Rest/ComponentProperties/FileDisplayProperties.cs +++ b/NetCord/Rest/ComponentProperties/FileDisplayProperties.cs @@ -3,6 +3,10 @@ namespace NetCord.Rest; +/// +/// Represents a file component to be sent in a message. +/// +/// The file to be sent as a component. The file must be attached to the message for it to be displayed correctly, and the URL must use the attachment:// protocol. [GenerateMethodsForProperties] public partial class FileDisplayProperties(ComponentMediaProperties file) : IMessageComponentProperties, IComponentContainerComponentProperties { @@ -13,6 +17,13 @@ public partial class FileDisplayProperties(ComponentMediaProperties file) : IMes [JsonPropertyName("id")] public int? Id { get; set; } + /// + /// The file to be sent as a component. + /// + /// + /// The file must be attached to the message for it to be displayed correctly. + /// The URL must use the attachment:// protocol. + /// [JsonPropertyName("file")] public ComponentMediaProperties File { get; set; } = file; diff --git a/NetCord/Rest/ComponentProperties/FileUploadProperties.cs b/NetCord/Rest/ComponentProperties/FileUploadProperties.cs index f1f4469bf..fb14431fb 100644 --- a/NetCord/Rest/ComponentProperties/FileUploadProperties.cs +++ b/NetCord/Rest/ComponentProperties/FileUploadProperties.cs @@ -3,6 +3,10 @@ namespace NetCord.Rest; +/// +/// Represents a file upload component. +/// +/// [GenerateMethodsForProperties] public partial class FileUploadProperties(string customId) : IInteractiveComponentProperties, ILabelComponentProperties { diff --git a/NetCord/Rest/ComponentProperties/MenuProperties.cs b/NetCord/Rest/ComponentProperties/MenuProperties.cs index 836fe578d..477213f71 100644 --- a/NetCord/Rest/ComponentProperties/MenuProperties.cs +++ b/NetCord/Rest/ComponentProperties/MenuProperties.cs @@ -30,6 +30,10 @@ public abstract partial class MenuProperties(string customId) : IInteractiveComp /// /// Minimum number of items that must be chosen, default 1 (0-25). /// + /// + /// In a modal, this may be 0 when is . + /// If the menu is required, this must be at least 1 if specified. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("min_values")] public int? MinValues { get; set; } @@ -44,6 +48,9 @@ public abstract partial class MenuProperties(string customId) : IInteractiveComp /// /// Whether the menu is disabled. /// + /// + /// This only applies to menus in messages. Discord does not allow a disabled menu in a modal. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] [JsonPropertyName("disabled")] public bool Disabled { get; set; } @@ -51,6 +58,10 @@ public abstract partial class MenuProperties(string customId) : IInteractiveComp /// /// Whether the menu is required to answer in a modal. Defaults to . /// + /// + /// This only applies to menus in modals and is ignored for menus in messages. + /// When this is or omitted, must be at least 1 if specified. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("required")] public bool? Required { get; set; } diff --git a/NetCord/Rest/ForumTagProperties.cs b/NetCord/Rest/ForumTagProperties.cs index 5ce6818b6..bd153365e 100644 --- a/NetCord/Rest/ForumTagProperties.cs +++ b/NetCord/Rest/ForumTagProperties.cs @@ -5,21 +5,49 @@ namespace NetCord.Rest; [GenerateMethodsForProperties] public partial class ForumTagProperties(string name) { + /// + /// The ID of the tag. + /// + /// + /// Omit this property when creating a forum or media channel. + /// When updating a channel, it may be specified to identify which tag to update. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("id")] public ulong? Id { get; set; } + /// + /// The name of the tag. (0-20 characters) + /// [JsonPropertyName("name")] public string Name { get; set; } = name; + /// + /// Whether this tag can only be added to or removed from threads by a member with the MANAGE_THREADS permission. + /// + /// + /// This is not required when updating a forum or media channel. Otherwise must be non-null. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("moderated")] public bool? Moderated { get; set; } + /// + /// The ID of the guild's custom emoji to display for this tag. + /// + /// + /// At most one of and may be non-null. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("emoji_id")] public ulong? EmojiId { get; set; } + /// + /// The unicode character of the standard emoji to display for this tag. + /// + /// + /// At most one of and may be non-null. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("emoji_name")] public string? EmojiName { get; set; } diff --git a/NetCord/Rest/GuildEmojiOptions.cs b/NetCord/Rest/GuildEmojiOptions.cs index 717e19a55..8655e252d 100644 --- a/NetCord/Rest/GuildEmojiOptions.cs +++ b/NetCord/Rest/GuildEmojiOptions.cs @@ -2,6 +2,14 @@ namespace NetCord.Rest; +/// +/// Represents options for modifying a guild emoji. +/// +/// +/// Modifying an emoji created by the current user requires either the CREATE_GUILD_EXPRESSIONS +/// or MANAGE_GUILD_EXPRESSIONS permission. Modifying an emoji created by another user requires +/// the MANAGE_GUILD_EXPRESSIONS permission. +/// [GenerateMethodsForProperties] public partial class GuildEmojiOptions { @@ -9,10 +17,19 @@ internal GuildEmojiOptions() { } + /// + /// The new name of the emoji. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("name")] public string? Name { get; set; } + /// + /// The IDs of the roles allowed to use the emoji. + /// + /// + /// An emoji cannot have both subscription roles and non-subscription roles. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("roles")] public IEnumerable? AllowedRoles { get; set; } diff --git a/NetCord/Rest/GuildOptions.cs b/NetCord/Rest/GuildOptions.cs index 08cb5d15d..2341a6221 100644 --- a/NetCord/Rest/GuildOptions.cs +++ b/NetCord/Rest/GuildOptions.cs @@ -2,6 +2,13 @@ namespace NetCord.Rest; +/// +/// Represents options for modifying a guild. +/// +/// +/// Modifying a guild requires the MANAGE_GUILD permission. Adding or removing the +/// COMMUNITY guild feature requires the ADMINISTRATOR permission. +/// [GenerateMethodsForProperties] public partial class GuildOptions { @@ -9,82 +16,169 @@ internal GuildOptions() { } + /// + /// The new name of the guild. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("name")] public string? Name { get; set; } + /// + /// The new verification level of the guild. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("verification_level")] public VerificationLevel? VerificationLevel { get; set; } + /// + /// The new default message notification level of the guild. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("default_message_notifications")] public DefaultMessageNotificationLevel? DefaultMessageNotificationLevel { get; set; } + /// + /// The new explicit content filter level of the guild. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("explicit_content_filter")] public ContentFilter? ContentFilter { get; set; } + /// + /// The ID of the new AFK channel. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("afk_channel_id")] public ulong? AfkChannelId { get; set; } + /// + /// The new AFK timeout, in seconds. + /// + /// + /// Discord accepts 60, 300, 900, 1800, or 3600. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("afk_timeout")] public int? AfkTimeout { get; set; } + /// + /// The new guild icon. + /// + /// + /// Discord expects a 1024x1024 PNG, JPEG, or GIF image. Animated GIFs require the + /// ANIMATED_ICON guild feature. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("icon")] public ImageProperties? Icon { get; set; } + /// + /// The ID of the new guild owner. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("owner_id")] public ulong? OwnerId { get; set; } + /// + /// The new guild invite splash. + /// + /// + /// Discord expects a 16:9 PNG or JPEG image. The guild must have the + /// INVITE_SPLASH feature. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("splash")] public ImageProperties? Splash { get; set; } + /// + /// The new guild discovery splash. + /// + /// + /// Discord expects a 16:9 PNG or JPEG image. The guild must have the + /// DISCOVERABLE feature. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("discovery_splash")] public ImageProperties? DiscoverySplash { get; set; } + /// + /// The new guild banner. + /// + /// + /// Discord expects a 16:9 PNG, JPEG, or GIF image. The guild must have the + /// BANNER feature. Animated GIFs additionally require the + /// ANIMATED_BANNER feature. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("banner")] public ImageProperties? Banner { get; set; } + /// + /// The ID of the channel where guild notices such as welcome messages and boost events are posted. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("system_channel_id")] public ulong? SystemChannelId { get; set; } + /// + /// The new system channel flags. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("system_channel_flags")] public SystemChannelFlags? SystemChannelFlags { get; set; } + /// + /// The ID of the channel where a Community guild displays its rules or guidelines. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("rules_channel_id")] public ulong? RulesChannelId { get; set; } + /// + /// The ID of the channel where administrators and moderators of a Community guild receive notices from Discord. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("public_updates_channel_id")] public ulong? PublicUpdatesChannelId { get; set; } + /// + /// The preferred locale of the Community guild. + /// + /// + /// The locale is used in server discovery and notices from Discord and defaults to en-US. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("preferred_locale")] public string? PreferredLocale { get; set; } + /// + /// The enabled guild features. + /// + /// + /// Discord currently documents COMMUNITY, DISCOVERABLE, + /// INVITES_DISABLED, and RAID_ALERTS_DISABLED as mutable guild features. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("features")] public IEnumerable? Features { get; set; } + /// + /// The new description of the guild. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("description")] public string? Description { get; set; } + /// + /// Whether the guild's Server Boost progress bar should be enabled. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("premium_progress_bar_enabled")] public bool? PremiumProgressBarEnabled { get; set; } + /// + /// The ID of the channel where administrators and moderators of a Community guild receive safety alerts from Discord. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("safety_alerts_channel_id")] public ulong? SafetyAlertsChannelId { get; set; } diff --git a/NetCord/Rest/GuildProperties.cs b/NetCord/Rest/GuildProperties.cs index cb05e11ed..4ef9c87d0 100644 --- a/NetCord/Rest/GuildProperties.cs +++ b/NetCord/Rest/GuildProperties.cs @@ -2,48 +2,98 @@ namespace NetCord.Rest; +/// +/// Represents properties used to create a guild. +/// +/// +/// Discord deprecated application-driven guild creation in April 2025 +/// and removed the corresponding API endpoint in July 2025. +/// This type is retained for compatibility with +/// . +/// +/// The name of the guild. [GenerateMethodsForProperties] +[Obsolete("Discord deprecated application-driven guild creation in April 2025 and removed the corresponding API endpoint in July 2025.")] public partial class GuildProperties(string name) { + /// + /// The name of the guild. + /// + /// + /// Guild names must contain between 2 and 100 characters and cannot contain leading or trailing whitespace. + /// [JsonPropertyName("name")] public string Name { get; set; } = name; + /// + /// The icon of the guild. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("icon")] public ImageProperties? Icon { get; set; } + /// + /// The verification level required for the guild. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("verification_level")] public VerificationLevel? VerificationLevel { get; set; } + /// + /// The default message notification level of the guild. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("default_message_notifications")] public DefaultMessageNotificationLevel? DefaultMessageNotificationLevel { get; set; } + /// + /// The explicit content filter level of the guild. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("explicit_content_filter")] public ContentFilter? ContentFilter { get; set; } + /// + /// The roles to create in the guild. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("roles")] public IEnumerable? Roles { get; set; } + /// + /// The channels to create in the guild. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("channels")] public IEnumerable? Channels { get; set; } + /// + /// The ID of the AFK channel. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("afk_channel_id")] public ulong? AfkChannelId { get; set; } + /// + /// The AFK timeout, in seconds. + /// + /// + /// Discord supports AFK timeouts of 60, 300, 900, 1800, and 3600 seconds. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("afk_timeout")] public int? AfkTimeout { get; set; } + /// + /// The ID of the channel where guild notices such as welcome messages and Server Boost events are posted. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("system_channel_id")] public ulong? SystemChannelId { get; set; } + /// + /// The system channel flags of the guild. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("system_channel_flags")] public SystemChannelFlags? SystemChannelFlags { get; set; } diff --git a/NetCord/Rest/GuildScheduledEventProperties.cs b/NetCord/Rest/GuildScheduledEventProperties.cs index 0475c8157..217194215 100644 --- a/NetCord/Rest/GuildScheduledEventProperties.cs +++ b/NetCord/Rest/GuildScheduledEventProperties.cs @@ -5,34 +5,75 @@ namespace NetCord.Rest; [GenerateMethodsForProperties] public partial class GuildScheduledEventProperties(string name, GuildScheduledEventPrivacyLevel privacyLevel, DateTimeOffset scheduledStartTime, GuildScheduledEventEntityType entityType) { + /// + /// The channel ID in which the scheduled event will be hosted, or if the scheduled event is a event. + /// + /// + /// Required for a or scheduled event. + /// [JsonPropertyName("channel_id")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public ulong? ChannelId { get; set; } + /// + /// Additional metadata for the scheduled event. + /// + /// + /// Required for a scheduled event and must contain a non-null value. + /// Must be for a or scheduled event. + /// [JsonPropertyName("entity_metadata")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public GuildScheduledEventMetadataProperties? Metadata { get; set; } + /// + /// The name of the scheduled event. (1-100 characters) + /// [JsonPropertyName("name")] public string Name { get; set; } = name; + /// + /// The privacy level of the scheduled event. + /// [JsonPropertyName("privacy_level")] public GuildScheduledEventPrivacyLevel PrivacyLevel { get; set; } = privacyLevel; + /// + /// The time when the scheduled event will start. + /// [JsonPropertyName("scheduled_start_time")] public DateTimeOffset ScheduledStartTime { get; set; } = scheduledStartTime; + /// + /// The time when the scheduled event is scheduled to end. + /// + /// + /// Required for a scheduled event. + /// This field has no strict requirements for a or scheduled event. + /// [JsonPropertyName("scheduled_end_time")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public DateTimeOffset? ScheduledEndTime { get; set; } + /// + /// The description of the scheduled event. (1-1000 characters) + /// [JsonPropertyName("description")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string? Description { get; set; } + /// + /// The type of the scheduled event. + /// + /// + /// This determines the requirements for the , , and properties. + /// [JsonPropertyName("entity_type")] public GuildScheduledEventEntityType EntityType { get; set; } = entityType; + /// + /// The cover image of the scheduled event. + /// [JsonPropertyName("image")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public ImageProperties? Image { get; set; } diff --git a/NetCord/Rest/GuildUserOptions.cs b/NetCord/Rest/GuildUserOptions.cs index 01b88a8a7..ddcece868 100644 --- a/NetCord/Rest/GuildUserOptions.cs +++ b/NetCord/Rest/GuildUserOptions.cs @@ -2,6 +2,9 @@ namespace NetCord.Rest; +/// +/// Represents options for modifying a guild member. +/// [GenerateMethodsForProperties] public partial class GuildUserOptions : CurrentGuildUserOptions { @@ -9,27 +12,65 @@ internal GuildUserOptions() { } + /// + /// The IDs of the roles assigned to the member. + /// + /// + /// Modifying the member's roles requires the MANAGE_ROLES permission. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("roles")] public IEnumerable? RoleIds { get; set; } + /// + /// Whether the member should be muted in voice channels. + /// + /// + /// Requires the MUTE_MEMBERS permission. Discord returns a 400 response if the member is not connected to a voice channel. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("mute")] public bool? Muted { get; set; } + /// + /// Whether the member should be deafened in voice channels. + /// + /// + /// Requires the DEAFEN_MEMBERS permission. Discord returns a 400 response if the member is not connected to a voice channel. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("deaf")] public bool? Deafened { get; set; } + /// + /// The ID of the voice channel to move the member to. + /// + /// + /// Moving a member requires the MOVE_MEMBERS permission and permission to connect to the target channel. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("channel_id")] public ulong? ChannelId { get; set; } + /// + /// The time at which the member's communication timeout should expire. + /// + /// + /// The timeout may be up to 28 days in the future and requires the MODERATE_MEMBERS permission. + /// Discord rejects attempts to time out the guild owner or a member with the ADMINISTRATOR permission. + /// [JsonConverter(typeof(JsonConverters.NullableDateTimeOffsetConverter))] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("communication_disabled_until")] public DateTimeOffset? TimeOutUntil { get; set; } + /// + /// The guild member flags to set. + /// + /// + /// Only editable guild member flags can be changed. Discord currently marks + /// BYPASSES_VERIFICATION as editable. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("flags")] public GuildUserFlags? GuildFlags { get; set; } diff --git a/NetCord/Rest/InviteProperties.cs b/NetCord/Rest/InviteProperties.cs index 801da1f7b..a77934804 100644 --- a/NetCord/Rest/InviteProperties.cs +++ b/NetCord/Rest/InviteProperties.cs @@ -2,33 +2,83 @@ namespace NetCord.Rest; +/// +/// Represents properties used to create a channel invite. +/// [GenerateMethodsForProperties] public partial class InviteProperties : IHttpSerializable { + /// + /// The duration, in seconds, after which the invite expires. + /// + /// + /// Must be between 0 and 604800 seconds. A value of 0 means the invite never expires. + /// Discord defaults this value to 86400 seconds. + /// [JsonPropertyName("max_age")] public int? MaxAge { get; set; } + /// + /// The maximum number of times the invite can be used. + /// + /// + /// Must be between 0 and 100. A value of 0 allows unlimited uses. + /// [JsonPropertyName("max_uses")] public int? MaxUses { get; set; } + /// + /// Whether the invite grants temporary membership. + /// [JsonPropertyName("temporary")] public bool? Temporary { get; set; } + /// + /// Whether Discord should always create a unique invite instead of reusing a similar existing invite. + /// [JsonPropertyName("unique")] public bool? Unique { get; set; } + /// + /// The target type of the voice channel invite. + /// [JsonPropertyName("target_type")] public InviteTargetType? TargetType { get; set; } + /// + /// The ID of the user whose stream should be displayed for a stream invite. + /// + /// + /// Required when is a stream invite. The user must be streaming in the channel. + /// [JsonPropertyName("target_user_id")] public ulong? TargetUserId { get; set; } + /// + /// The ID of the embedded application to open for an embedded application invite. + /// + /// + /// Required when is an embedded application invite. The application must have the EMBEDDED flag. + /// [JsonPropertyName("target_application_id")] public ulong? TargetApplicationId { get; set; } + /// + /// The users allowed to see and accept the invite. + /// + /// + /// These users are serialized as the target_users_file CSV part of a multipart request. + /// Duplicate user IDs are ignored by Discord. + /// [JsonIgnore] public InviteTargetUsersProperties? TargetUsers { get; set; } + /// + /// The IDs of roles granted to users who accept the invite. + /// + /// + /// Requires the MANAGE_ROLES permission. Roles with higher permissions than the sender cannot be assigned. + /// [JsonPropertyName("role_ids")] public IEnumerable? RoleIds { get; set; } diff --git a/NetCord/Rest/RestClient.Guild.cs b/NetCord/Rest/RestClient.Guild.cs index eb62e537f..7529bba98 100644 --- a/NetCord/Rest/RestClient.Guild.cs +++ b/NetCord/Rest/RestClient.Guild.cs @@ -6,20 +6,54 @@ namespace NetCord.Rest; public partial class RestClient { + /// + /// Creates a new guild. + /// + /// The properties of the guild to create. + /// The properties of the request. + /// The token to cancel the request. + /// The created guild. + /// + /// Discord deprecated application-driven guild creation in April 2025 and removed the corresponding API endpoint in July 2025. + /// + [Obsolete("Discord deprecated application-driven guild creation in April 2025 and removed the corresponding API endpoint in July 2025.")] public async Task CreateGuildAsync(GuildProperties guildProperties, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) { using (HttpContent content = new JsonContent(guildProperties, Serialization.Default.GuildProperties)) return new(await (await SendRequestAsync(HttpMethod.Post, content, $"/guilds", null, null, properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonGuild).ConfigureAwait(false), this); } + /// + /// Gets a guild. + /// + /// The ID of the guild to get. + /// Whether to include the member counts in the response. + /// The properties of the request. + /// The token to cancel the request. + /// The retrieved guild. [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] public async Task GetGuildAsync(ulong guildId, bool withCounts = false, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => new(await (await SendRequestAsync(HttpMethod.Get, $"/guilds/{guildId}", $"?with_counts={withCounts}", new(guildId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonGuild).ConfigureAwait(false), this); + /// + /// Gets a guild preview. + /// + /// The ID of the guild to get a preview for. + /// The properties of the request. + /// The token to cancel the request. + /// The retrieved guild preview. [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] public async Task GetGuildPreviewAsync(ulong guildId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => new(await (await SendRequestAsync(HttpMethod.Get, $"/guilds/{guildId}/preview", null, new(guildId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonGuild).ConfigureAwait(false), this); + /// + /// Modifies a guild. + /// + /// The ID of the guild to modify. + /// The action to perform on the guild options. + /// The properties of the request. + /// The token to cancel the request. + /// The modified guild. [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] public async Task ModifyGuildAsync(ulong guildId, Action action, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) { @@ -29,14 +63,36 @@ public async Task ModifyGuildAsync(ulong guildId, Action + /// Deletes a guild. + /// + /// The ID of the guild to delete. + /// The properties of the request. + /// The token to cancel the request. + /// [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] public Task DeleteGuildAsync(ulong guildId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => SendRequestAsync(HttpMethod.Delete, $"/guilds/{guildId}", null, new(guildId), properties, cancellationToken: cancellationToken); + /// + /// Gets the channels of a guild. + /// + /// The ID of the guild to get channels for. + /// The properties of the request. + /// The token to cancel the request. + /// [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] public async Task> GetGuildChannelsAsync(ulong guildId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => (await (await SendRequestAsync(HttpMethod.Get, $"/guilds/{guildId}/channels", null, new(guildId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonChannelArray).ConfigureAwait(false)).Select(c => IGuildChannel.CreateFromJson(c, guildId, this)).ToArray(); + /// + /// Creates a new channel in a guild. + /// + /// The ID of the guild to create the channel in. + /// The properties of the new channel. + /// The properties of the request. + /// The token to cancel the request. + /// The created channel. [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] public async Task CreateGuildChannelAsync(ulong guildId, GuildChannelProperties channelProperties, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) { @@ -44,6 +100,14 @@ public async Task CreateGuildChannelAsync(ulong guildId, GuildCha return IGuildChannel.CreateFromJson(await (await SendRequestAsync(HttpMethod.Post, content, $"/guilds/{guildId}/channels", null, new(guildId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonChannel).ConfigureAwait(false), guildId, this); } + /// + /// Modifies the positions of channels in a guild. + /// + /// The ID of the guild to modify channel positions in. + /// The new positions of the channels. + /// The properties of the request. + /// The token to cancel the request. + /// [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] public async Task ModifyGuildChannelPositionsAsync(ulong guildId, IEnumerable positions, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) { @@ -51,15 +115,37 @@ public async Task ModifyGuildChannelPositionsAsync(ulong guildId, IEnumerable + /// Gets the active threads in a guild. + /// + /// The ID of the guild to get active threads for. + /// The properties of the request. + /// The token to cancel the request. + /// A list of the active threads in the guild. [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] public async Task> GetActiveGuildThreadsAsync(ulong guildId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => GuildThreadGenerator.CreateThreads(await (await SendRequestAsync(HttpMethod.Get, $"/guilds/{guildId}/threads/active", null, new(guildId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonRestGuildThreadResult).ConfigureAwait(false), this).ToArray(); + /// + /// Gets a guild member. + /// + /// The ID of the guild to get the member for. + /// The ID of the user to get. + /// The properties of the request. + /// The token to cancel the request. + /// The guild member. [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] [GenerateAlias([typeof(GuildUser)], nameof(GuildUser.GuildId), nameof(GuildUser.Id), Modifiers = ["new"])] public async Task GetGuildUserAsync(ulong guildId, ulong userId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => new(await (await SendRequestAsync(HttpMethod.Get, $"/guilds/{guildId}/members/{userId}", null, new(guildId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonGuildUser).ConfigureAwait(false), guildId, this); + /// + /// Gets the users in a guild. + /// + /// The ID of the guild to get the users for. + /// The properties for pagination. + /// The properties of the request. + /// An async enumerable of the guild users. [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] public IAsyncEnumerable GetGuildUsersAsync(ulong guildId, PaginationProperties? paginationProperties = null, RestRequestProperties? properties = null) { @@ -77,10 +163,28 @@ public IAsyncEnumerable GetGuildUsersAsync(ulong guildId, PaginationP properties); } + /// + /// Searches for a user in a guild. + /// + /// The ID of the guild to search in. + /// The name of the user to search for. + /// The maximum number of results to return. + /// The properties of the request. + /// The token to cancel the request. + /// A list of the users that match the search query. [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] public async Task> FindGuildUserAsync(ulong guildId, string name, int limit, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => (await (await SendRequestAsync(HttpMethod.Get, $"/guilds/{guildId}/members/search", $"?query={Uri.EscapeDataString(name)}&limit={limit}", new(guildId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonGuildUserArray).ConfigureAwait(false)).Select(u => new GuildUser(u, guildId, this)).ToArray(); + /// + /// Adds a user to a guild. + /// + /// The ID of the guild to add the user to. + /// The ID of the user to add. + /// The properties of the user to add. + /// The properties of the request. + /// The token to cancel the request. + /// The added guild user, or null if the user could not be added. [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] public async Task AddGuildUserAsync(ulong guildId, ulong userId, GuildUserProperties userProperties, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) { @@ -93,6 +197,15 @@ public async Task> FindGuildUserAsync(ulong guildId, st return new(await stream.ToObjectAsync(Serialization.Default.JsonGuildUser).ConfigureAwait(false), guildId, this); } + /// + /// Modifies a user in a guild. + /// + /// The ID of the guild to modify the user in. + /// The ID of the user to modify. + /// The action to perform on the user options. + /// The properties of the request. + /// The token to cancel the request. + /// The modified guild user. [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] [GenerateAlias([typeof(GuildUser)], nameof(GuildUser.GuildId), nameof(GuildUser.Id))] public async Task ModifyGuildUserAsync(ulong guildId, ulong userId, Action action, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) @@ -103,6 +216,14 @@ public async Task ModifyGuildUserAsync(ulong guildId, ulong userId, A return new(await (await SendRequestAsync(HttpMethod.Patch, content, $"/guilds/{guildId}/members/{userId}", null, new(guildId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonGuildUser).ConfigureAwait(false), guildId, this); } + /// + /// Modifies the current user in a guild. + /// + /// The ID of the guild to modify the current user in. + /// The action to perform on the current user options. + /// The properties of the request. + /// The token to cancel the request. + /// The modified guild user. [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] public async Task ModifyCurrentGuildUserAsync(ulong guildId, Action action, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) { @@ -112,21 +233,54 @@ public async Task ModifyCurrentGuildUserAsync(ulong guildId, Action + /// Adds a role to a user in a guild. + /// + /// The ID of the guild to add the role to. + /// The ID of the user to add the role to. + /// The ID of the role to add. + /// The properties of the request. + /// The token to cancel the request. + /// [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] [GenerateAlias([typeof(GuildUser)], nameof(GuildUser.GuildId), nameof(GuildUser.Id))] public Task AddGuildUserRoleAsync(ulong guildId, ulong userId, ulong roleId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => SendRequestAsync(HttpMethod.Put, $"/guilds/{guildId}/members/{userId}/roles/{roleId}", null, new(guildId), properties, cancellationToken: cancellationToken); + /// + /// Removes a role from a user in a guild. + /// + /// The ID of the guild to remove the role from. + /// The ID of the user to remove the role from. + /// The ID of the role to remove. + /// The properties of the request. + /// The token to cancel the request. + /// [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] [GenerateAlias([typeof(GuildUser)], nameof(GuildUser.GuildId), nameof(GuildUser.Id))] public Task RemoveGuildUserRoleAsync(ulong guildId, ulong userId, ulong roleId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => SendRequestAsync(HttpMethod.Delete, $"/guilds/{guildId}/members/{userId}/roles/{roleId}", null, new(guildId), properties, cancellationToken: cancellationToken); + /// + /// Removes a user from a guild. + /// + /// The ID of the guild to remove the user from. + /// The ID of the user to remove. + /// The properties of the request. + /// The token to cancel the request. + /// [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] [GenerateAlias([typeof(GuildUser)], nameof(GuildUser.GuildId), nameof(GuildUser.Id))] public Task KickGuildUserAsync(ulong guildId, ulong userId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => SendRequestAsync(HttpMethod.Delete, $"/guilds/{guildId}/members/{userId}", null, new(guildId), properties, cancellationToken: cancellationToken); + /// + /// Gets the bans in a guild. + /// + /// The ID of the guild to get the bans for. + /// The properties for pagination. + /// The properties of the request. + /// An async enumerable of the guild bans. [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] public IAsyncEnumerable GetGuildBansAsync(ulong guildId, PaginationProperties? paginationProperties = null, RestRequestProperties? properties = null) { @@ -149,10 +303,27 @@ public IAsyncEnumerable GetGuildBansAsync(ulong guildId, PaginationPro properties); } + /// + /// Gets a ban in a guild. + /// + /// The ID of the guild to get the ban for. + /// The ID of the user to get the ban for. + /// The properties of the request. + /// The token to cancel the request. + /// The guild ban. [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] public async Task GetGuildBanAsync(ulong guildId, ulong userId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => new(await (await SendRequestAsync(HttpMethod.Get, $"/guilds/{guildId}/bans/{userId}", null, new(guildId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonGuildBan).ConfigureAwait(false), guildId, this); + /// + /// Bans a user from a guild. + /// + /// The ID of the guild to ban the user from. + /// The ID of the user to ban. + /// The number of seconds to delete messages for. Must be between 0 and 604800 (7 days). + /// The properties of the request. + /// The token to cancel the request. + /// [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] [GenerateAlias([typeof(GuildUser)], nameof(GuildUser.GuildId), nameof(GuildUser.Id))] public async Task BanGuildUserAsync(ulong guildId, ulong userId, int deleteMessageSeconds = 0, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) @@ -161,6 +332,15 @@ public async Task BanGuildUserAsync(ulong guildId, ulong userId, int deleteMessa await SendRequestAsync(HttpMethod.Put, content, $"/guilds/{guildId}/bans/{userId}", null, new(guildId), properties, cancellationToken: cancellationToken).ConfigureAwait(false); } + /// + /// Bans multiple users from a guild. + /// + /// The ID of the guild to ban the users from. + /// The IDs of the users to ban. Up to 200 users can be banned at once. + /// The number of seconds to delete messages for. Must be between 0 and 604800 (7 days). + /// The properties of the request. + /// The token to cancel the request. + /// The result of the bulk ban operation, including the IDs of the banned users and the user IDs of failed bans. [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] public async Task BanGuildUsersAsync(ulong guildId, IEnumerable userIds, int deleteMessageSeconds = 0, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) { @@ -168,20 +348,51 @@ public async Task BanGuildUsersAsync(ulong guildId, IEnumerable
    + /// Unbans a user from a guild. + /// + /// The ID of the guild to unban the user from. + /// The ID of the user to unban. + /// The properties of the request. + /// The token to cancel the request. + /// [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] [GenerateAlias([typeof(GuildBan)], nameof(GuildBan.GuildId), $"{nameof(GuildBan.User)}.{nameof(GuildBan.User.Id)}", NameOverride = "DeleteAsync", ClientName = "client")] [GenerateAlias([typeof(GuildUser)], nameof(GuildUser.GuildId), nameof(GuildUser.Id))] public Task UnbanGuildUserAsync(ulong guildId, ulong userId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => SendRequestAsync(HttpMethod.Delete, $"/guilds/{guildId}/bans/{userId}", null, new(guildId), properties, cancellationToken: cancellationToken); + /// + /// Gets the roles of a guild. + /// + /// The ID of the guild to get the roles for. + /// The properties of the request. + /// The token to cancel the request. + /// A list of the roles in the guild. [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] public async Task> GetGuildRolesAsync(ulong guildId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => (await (await SendRequestAsync(HttpMethod.Get, $"/guilds/{guildId}/roles", null, new(guildId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonRoleArray).ConfigureAwait(false)).Select(r => new Role(r, guildId, this)).ToArray(); + /// + /// Gets a role in a guild. + /// + /// The ID of the guild to get the role for. + /// The ID of the role to get. + /// The properties of the request. + /// The token to cancel the request. + /// The role in the guild. [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] public async Task GetGuildRoleAsync(ulong guildId, ulong roleId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => new(await (await SendRequestAsync(HttpMethod.Get, $"/guilds/{guildId}/roles/{roleId}", null, new(guildId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonRole).ConfigureAwait(false), guildId, this); + /// + /// Creates a new role in a guild. + /// + /// The ID of the guild to create the role in. + /// The properties of the new role. + /// The properties of the request. + /// The token to cancel the request. + /// The created role. [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] public async Task CreateGuildRoleAsync(ulong guildId, RoleProperties guildRoleProperties, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) { @@ -189,6 +400,14 @@ public async Task CreateGuildRoleAsync(ulong guildId, RoleProperties guild return new(await (await SendRequestAsync(HttpMethod.Post, content, $"/guilds/{guildId}/roles", null, new(guildId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonRole).ConfigureAwait(false), guildId, this); } + /// + /// Modifies the positions of roles in a guild. + /// + /// The ID of the guild to modify the role positions in. + /// The new positions of the roles. + /// The properties of the request. + /// The token to cancel the request. + /// The modified roles. [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] public async Task> ModifyGuildRolePositionsAsync(ulong guildId, IEnumerable positions, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) { @@ -196,6 +415,15 @@ public async Task> ModifyGuildRolePositionsAsync(ulong guild return (await (await SendRequestAsync(HttpMethod.Patch, content, $"/guilds/{guildId}/roles", null, new(guildId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonRoleArray).ConfigureAwait(false)).Select(r => new Role(r, guildId, this)).ToArray(); } + /// + /// Modifies a role in a guild. + /// + /// The ID of the guild to modify the role in. + /// The ID of the role to modify. + /// The action to perform on the role options. + /// The properties of the request. + /// The token to cancel the request. + /// The modified role. [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] [GenerateAlias([typeof(Role)], nameof(Role.GuildId), nameof(Role.Id), TypeNameOverride = $"{nameof(Guild)}{nameof(Role)}")] public async Task ModifyGuildRoleAsync(ulong guildId, ulong roleId, Action action, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) @@ -206,11 +434,27 @@ public async Task ModifyGuildRoleAsync(ulong guildId, ulong roleId, Action return new(await (await SendRequestAsync(HttpMethod.Patch, content, $"/guilds/{guildId}/roles/{roleId}", null, new(guildId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonRole).ConfigureAwait(false), guildId, this); } + /// + /// Deletes a role from a guild. + /// + /// The ID of the guild to delete the role from. + /// The ID of the role to delete. + /// The properties of the request. + /// The token to cancel the request. + /// [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] [GenerateAlias([typeof(Role)], nameof(Role.GuildId), nameof(Role.Id), TypeNameOverride = $"{nameof(Guild)}{nameof(Role)}")] public Task DeleteGuildRoleAsync(ulong guildId, ulong roleId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => SendRequestAsync(HttpMethod.Delete, $"/guilds/{guildId}/roles/{roleId}", null, new(guildId), properties, cancellationToken: cancellationToken); + /// + /// Modifies the MFA level of a guild. + /// + /// The ID of the guild to modify the MFA level for. + /// The new MFA level of the guild. + /// The properties of the request. + /// The token to cancel the request. + /// The new MFA level of the guild. [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] public async Task ModifyGuildMfaLevelAsync(ulong guildId, MfaLevel mfaLevel, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) { @@ -218,6 +462,15 @@ public async Task ModifyGuildMfaLevelAsync(ulong guildId, MfaLevel mfa return (await (await SendRequestAsync(HttpMethod.Post, content, $"/guilds/{guildId}/mfa", null, new(guildId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonGuildMfaLevel).ConfigureAwait(false)).Level; } + /// + /// Gets the number of members that would be pruned from a guild. + /// + /// The ID of the guild to get the prune count for. + /// The number of days to consider for pruning. Must be between 1 and 30. Default is 7. + /// The roles to consider for pruning. + /// The properties of the request. + /// The token to cancel the request. + /// The number of members that would be pruned. [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] public async Task GetGuildPruneCountAsync(ulong guildId, int days, IEnumerable? roles = null, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) { @@ -232,6 +485,14 @@ public async Task GetGuildPruneCountAsync(ulong guildId, int days, IEnumera return (await (await SendRequestAsync(HttpMethod.Get, $"/guilds/{guildId}/prune", query, new(guildId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonGuildPruneCountResult).ConfigureAwait(false)).Pruned; } + /// + /// Prunes members from a guild. + /// + /// The ID of the guild to prune members from. + /// The properties of the prune operation. + /// The properties of the request. + /// The token to cancel the request. + /// The number of members that were pruned. [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] public async Task GuildPruneAsync(ulong guildId, GuildPruneProperties pruneProperties, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) { @@ -239,26 +500,70 @@ public async Task GetGuildPruneCountAsync(ulong guildId, int days, IEnumera return (await (await SendRequestAsync(HttpMethod.Post, content, $"/guilds/{guildId}/prune", null, new(guildId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonGuildPruneResult).ConfigureAwait(false)).Pruned; } + /// + /// Gets the voice regions of a guild. + /// + /// The ID of the guild to get the voice regions for. + /// The properties of the request. + /// The token to cancel the request. + /// A list of the voice regions in the guild. [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] public async Task> GetGuildVoiceRegionsAsync(ulong guildId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => (await (await SendRequestAsync(HttpMethod.Get, $"/guilds/{guildId}/regions", null, new(guildId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonVoiceRegionArray).ConfigureAwait(false)).Select(r => new VoiceRegion(r)); + /// + /// Gets the invites of a guild. + /// + /// The ID of the guild to get the invites for. + /// The properties of the request. + /// The token to cancel the request. + /// A list of the invites in the guild. [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] public async Task> GetGuildInvitesAsync(ulong guildId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => (await (await SendRequestAsync(HttpMethod.Get, $"/guilds/{guildId}/invites", null, new(guildId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonRestInviteArray).ConfigureAwait(false)).Select(i => new RestInvite(i, this)); + /// + /// Gets the integrations of a guild. + /// + /// The ID of the guild to get the integrations for. + /// The properties of the request. + /// The token to cancel the request. + /// A list of the integrations in the guild. [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] public async Task> GetGuildIntegrationsAsync(ulong guildId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => (await (await SendRequestAsync(HttpMethod.Get, $"/guilds/{guildId}/integrations", null, new(guildId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonIntegrationArray).ConfigureAwait(false)).Select(i => new Integration(i, this)).ToArray(); + /// + /// Deletes an integration from a guild. + /// + /// The ID of the guild to delete the integration from. + /// The ID of the integration to delete. + /// The properties of the request. + /// The token to cancel the request. + /// [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] public Task DeleteGuildIntegrationAsync(ulong guildId, ulong integrationId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => SendRequestAsync(HttpMethod.Delete, $"/guilds/{guildId}/integrations/{integrationId}", null, new(guildId), properties, cancellationToken: cancellationToken); + /// + /// Gets the widget settings of a guild. + /// + /// The ID of the guild to get the widget settings for. + /// The properties of the request. + /// The token to cancel the request. + /// The widget settings of the guild. [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] public async Task GetGuildWidgetSettingsAsync(ulong guildId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => new(await (await SendRequestAsync(HttpMethod.Get, $"/guilds/{guildId}/widget", null, new(guildId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonGuildWidgetSettings).ConfigureAwait(false)); + /// + /// Modifies the widget settings of a guild. + /// + /// The ID of the guild to modify the widget settings for. + /// The action to perform on the widget settings options. + /// The properties of the request. + /// The token to cancel the request. + /// The modified widget settings of the guild. [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] public async Task ModifyGuildWidgetSettingsAsync(ulong guildId, Action action, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) { @@ -268,18 +573,47 @@ public async Task ModifyGuildWidgetSettingsAsync(ulong guil return new(await (await SendRequestAsync(HttpMethod.Patch, content, $"/guilds/{guildId}/widget", null, new(guildId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonGuildWidgetSettings).ConfigureAwait(false)); } + /// + /// Gets the widget of a guild. + /// + /// The ID of the guild to get the widget for. + /// The properties of the request. + /// The token to cancel the request. + /// The widget of the guild. [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] public async Task GetGuildWidgetAsync(ulong guildId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => new(await (await SendRequestAsync(HttpMethod.Get, $"/guilds/{guildId}/widget.json", null, new(guildId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonGuildWidget).ConfigureAwait(false), this); + /// + /// Gets the vanity invite of a guild. + /// + /// The ID of the guild to get the vanity invite for. + /// The properties of the request. + /// The token to cancel the request. + /// The vanity invite of the guild. [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] public async Task GetGuildVanityInviteAsync(ulong guildId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => new(await (await SendRequestAsync(HttpMethod.Get, $"/guilds/{guildId}/vanity-url", null, new(guildId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonGuildVanityInvite).ConfigureAwait(false)); + /// + /// Gets the welcome screen of a guild. + /// + /// The ID of the guild to get the welcome screen for. + /// The properties of the request. + /// The token to cancel the request. + /// The welcome screen of the guild. [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] public async Task GetGuildWelcomeScreenAsync(ulong guildId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => new(await (await SendRequestAsync(HttpMethod.Get, $"/guilds/{guildId}/welcome-screen", null, new(guildId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonGuildWelcomeScreen).ConfigureAwait(false)); + /// + /// Modifies the welcome screen of a guild. + /// + /// The ID of the guild to modify the welcome screen for. + /// The action to perform on the welcome screen options. + /// The properties of the request. + /// The token to cancel the request. + /// The modified welcome screen of the guild. [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] public async Task ModifyGuildWelcomeScreenAsync(ulong guildId, Action action, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) { @@ -289,10 +623,25 @@ public async Task ModifyGuildWelcomeScreenAsync(ulong guildI return new(await (await SendRequestAsync(HttpMethod.Patch, content, $"/guilds/{guildId}/welcome-screen", null, new(guildId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonGuildWelcomeScreen).ConfigureAwait(false)); } + /// + /// Gets the onboarding of a guild. + /// + /// The ID of the guild to get the onboarding for. + /// The properties of the request. + /// The token to cancel the request. + /// The onboarding of the guild. [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] public async Task GetGuildOnboardingAsync(ulong guildId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => new(await (await SendRequestAsync(HttpMethod.Get, $"/guilds/{guildId}/onboarding", null, new(guildId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonGuildOnboarding).ConfigureAwait(false), this); + /// + /// Modifies the onboarding of a guild. + /// + /// The ID of the guild to modify the onboarding for. + /// The action to perform on the onboarding options. + /// The properties of the request. + /// The token to cancel the request. + /// The modified onboarding of the guild. [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] public async Task ModifyGuildOnboardingAsync(ulong guildId, Action action, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) { diff --git a/NetCord/Rest/RestClient.GuildTemplate.cs b/NetCord/Rest/RestClient.GuildTemplate.cs index 6dc04cafa..20c9a70ab 100644 --- a/NetCord/Rest/RestClient.GuildTemplate.cs +++ b/NetCord/Rest/RestClient.GuildTemplate.cs @@ -4,21 +4,62 @@ namespace NetCord.Rest; public partial class RestClient { + /// + /// Gets a guild template. + /// + /// The code of the guild template to get. + /// The properties of the request. + /// The token to cancel the request. + /// The guild template. [GenerateAlias([typeof(GuildTemplate)], nameof(GuildTemplate.Code))] public async Task GetGuildTemplateAsync(string templateCode, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => new(await (await SendRequestAsync(HttpMethod.Get, $"/guilds/templates/{templateCode}", null, null, properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonGuildTemplate).ConfigureAwait(false), this); + /// + /// Creates a guild from a guild template. + /// + /// + /// Discord deprecated application-driven guild creation in April 2025 + /// and removed the corresponding API endpoint in July 2025. + /// + /// The code of the guild template to use. + /// The properties of the guild to create. + /// The properties of the request. + /// The token to cancel the request. + /// The created guild. [GenerateAlias([typeof(GuildTemplate)], nameof(GuildTemplate.Code), NameOverride = "CreateGuildAsync")] + [Obsolete("Discord deprecated application-driven guild creation in April 2025 and removed the corresponding API endpoint in July 2025.")] public async Task CreateGuildFromGuildTemplateAsync(string templateCode, GuildFromGuildTemplateProperties guildProperties, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) { using (HttpContent content = new JsonContent(guildProperties, Serialization.Default.GuildFromGuildTemplateProperties)) return new(await (await SendRequestAsync(HttpMethod.Post, content, $"/guilds/templates/{templateCode}", null, null, properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonGuild).ConfigureAwait(false), this); } + /// + /// Gets the guild templates of a guild. + /// + /// + /// Requires the MANAGE_GUILD permission. + /// + /// The ID of the guild. + /// The properties of the request. + /// The token to cancel the request. + /// The guild templates. [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] public async Task> GetGuildTemplatesAsync(ulong guildId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => (await (await SendRequestAsync(HttpMethod.Get, $"/guilds/{guildId}/templates", null, new(guildId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonGuildTemplateArray).ConfigureAwait(false)).Select(t => new GuildTemplate(t, this)); + /// + /// Creates a guild template. + /// + /// + /// Requires the MANAGE_GUILD permission. + /// + /// The ID of the guild to create the template for. + /// The properties of the guild template. + /// The properties of the request. + /// The token to cancel the request. + /// The created guild template. [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] public async Task CreateGuildTemplateAsync(ulong guildId, GuildTemplateProperties guildTemplateProperties, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) { @@ -26,11 +67,31 @@ public async Task CreateGuildTemplateAsync(ulong guildId, GuildTe return new(await (await SendRequestAsync(HttpMethod.Post, content, $"/guilds/{guildId}/templates", null, new(guildId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonGuildTemplate).ConfigureAwait(false), this); } + /// + /// Syncs a guild template. + /// + /// The ID of the guild. + /// The code of the template. + /// The properties of the request. + /// The token to cancel the request. + /// The synced guild template. [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] [GenerateAlias([typeof(GuildTemplate)], nameof(GuildTemplate.SourceGuildId), nameof(GuildTemplate.Code))] public async Task SyncGuildTemplateAsync(ulong guildId, string templateCode, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) => new(await (await SendRequestAsync(HttpMethod.Put, $"/guilds/{guildId}/templates/{templateCode}", null, new(guildId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonGuildTemplate).ConfigureAwait(false), this); + /// + /// Modifies a guild template. + /// + /// + /// Requires the MANAGE_GUILD permission. + /// + /// The ID of the guild. + /// The code of the template. + /// The action to perform on the guild template options. + /// The properties of the request. + /// The token to cancel the request. + /// The modified guild template. [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] [GenerateAlias([typeof(GuildTemplate)], nameof(GuildTemplate.SourceGuildId), nameof(GuildTemplate.Code))] public async Task ModifyGuildTemplateAsync(ulong guildId, string templateCode, Action action, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) @@ -41,6 +102,17 @@ public async Task ModifyGuildTemplateAsync(ulong guildId, string return new(await (await SendRequestAsync(HttpMethod.Patch, content, $"/guilds/{guildId}/templates/{templateCode}", null, new(guildId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonGuildTemplate).ConfigureAwait(false), this); } + /// + /// Deletes a guild template. + /// + /// + /// Requires the MANAGE_GUILD permission. + /// + /// The ID of the guild. + /// The code of the template. + /// The properties of the request. + /// The token to cancel the request. + /// The deleted guild template. [GenerateAlias([typeof(RestGuild)], nameof(RestGuild.Id), TypeNameOverride = nameof(Guild))] [GenerateAlias([typeof(GuildTemplate)], nameof(GuildTemplate.SourceGuildId), nameof(GuildTemplate.Code))] public async Task DeleteGuildTemplateAsync(ulong guildId, string templateCode, RestRequestProperties? properties = null, CancellationToken cancellationToken = default) diff --git a/NetCord/Rest/RestError.cs b/NetCord/Rest/RestError.cs index 12c72fc41..4ea5d1941 100644 --- a/NetCord/Rest/RestError.cs +++ b/NetCord/Rest/RestError.cs @@ -3,26 +3,49 @@ namespace NetCord.Rest; +/// +/// Represents an error returned by the Discord REST API. +/// +/// The Discord API error code. +/// The human-readable error message. +/// Detailed information about the fields that caused the error, if provided. public sealed class RestError(int code, string message, IRestErrorGroup? error) { + /// + /// Gets the Discord API error code. + /// [JsonPropertyName("code")] public int Code { get; } = code; + /// + /// Gets the human-readable error message. + /// [JsonPropertyName("message")] public string Message { get; } = message; + /// + /// Gets detailed information about the fields that caused the error, if provided. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("errors")] public IRestErrorGroup? Error { get; } = error; + /// public override string ToString() => JsonSerializer.Serialize(this, Serialization.Default.RestError); } +/// +/// Represents detailed error information returned by the Discord REST API. +/// [JsonConverter(typeof(IRestErrorGroupConverter))] public interface IRestErrorGroup : IJsonSerializable { + /// + /// Converts detailed Discord REST API errors to and from JSON. + /// public class IRestErrorGroupConverter : JsonConverter { + /// public override IRestErrorGroup? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { reader.Read(); @@ -57,6 +80,7 @@ public class IRestErrorGroupConverter : JsonConverter return new RestErrorGroup(errors); } + /// public override void Write(Utf8JsonWriter writer, IRestErrorGroup value, JsonSerializerOptions options) { value.WriteTo(writer); @@ -64,8 +88,15 @@ public override void Write(Utf8JsonWriter writer, IRestErrorGroup value, JsonSer } } +/// +/// Represents a nested group of REST API errors keyed by field name or array index. +/// +/// The nested errors. public class RestErrorGroup(IReadOnlyDictionary errors) : IRestErrorGroup { + /// + /// Gets the nested errors keyed by field name or array index. + /// public IReadOnlyDictionary Errors { get; } = errors; void IJsonSerializable.WriteTo(Utf8JsonWriter writer) @@ -74,10 +105,17 @@ void IJsonSerializable.WriteTo(Utf8JsonWriter writer) } } +/// +/// Represents a group of error details associated with a field or request. +/// +/// The error details. public class RestErrorDetailGroup(IReadOnlyList errors) : IRestErrorGroup { private static readonly JsonEncodedText _errors = JsonEncodedText.Encode("_errors"); + /// + /// Gets the error details. + /// public IReadOnlyList Errors { get; } = errors; void IJsonSerializable.WriteTo(Utf8JsonWriter writer) @@ -89,11 +127,22 @@ void IJsonSerializable.WriteTo(Utf8JsonWriter writer) } } +/// +/// Represents an individual REST API error detail. +/// +/// The machine-readable error code. +/// The human-readable error message. public class RestErrorDetail(string code, string message) { + /// + /// Gets the machine-readable error code. + /// [JsonPropertyName("code")] public string Code { get; } = code; + /// + /// Gets the human-readable error message. + /// [JsonPropertyName("message")] public string Message { get; } = message; } diff --git a/NetCord/Rest/RoleOptions.cs b/NetCord/Rest/RoleOptions.cs index 3ab10a134..6981ee9e6 100644 --- a/NetCord/Rest/RoleOptions.cs +++ b/NetCord/Rest/RoleOptions.cs @@ -2,6 +2,12 @@ namespace NetCord.Rest; +/// +/// Represents options for modifying a guild role. +/// +/// +/// Modifying a guild role requires the MANAGE_ROLES permission. +/// [GenerateMethodsForProperties] public partial class RoleOptions { @@ -9,30 +15,63 @@ internal RoleOptions() { } + /// + /// The new name of the role. + /// + /// + /// The name can contain at most 100 characters. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("name")] public string? Name { get; set; } + /// + /// The new permissions of the role. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("permissions")] public Permissions? Permissions { get; set; } + /// + /// The new colors of the role. + /// + /// + /// Secondary and tertiary role colors require the guild to have the ENHANCED_ROLE_COLORS guild feature. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("colors")] public RoleColorsProperties? Colors { get; set; } + /// + /// Whether members with the role should be displayed separately in the member list. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("hoist")] public bool? Hoist { get; set; } + /// + /// The new icon of the role. + /// + /// + /// The guild must have the ROLE_ICONS guild feature. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("icon")] public ImageProperties? Icon { get; set; } + /// + /// The new Unicode emoji used as the role icon. + /// + /// + /// The guild must have the ROLE_ICONS guild feature. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("unicode_emoji")] public string? UnicodeIcon { get; set; } + /// + /// Whether the role should be mentionable. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("mentionable")] public bool? Mentionable { get; set; } diff --git a/NetCord/Rest/RoleProperties.cs b/NetCord/Rest/RoleProperties.cs index d647c3362..c5052ecac 100644 --- a/NetCord/Rest/RoleProperties.cs +++ b/NetCord/Rest/RoleProperties.cs @@ -2,33 +2,66 @@ namespace NetCord.Rest; +/// +/// Represents properties used to create a guild role. +/// [GenerateMethodsForProperties] public partial class RoleProperties { + /// + /// The name of the role. + /// + /// + /// Role names can contain at most 100 characters. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("name")] public string? Name { get; set; } + /// + /// The permissions granted to the role. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("permissions")] public Permissions? Permissions { get; set; } + /// + /// The colors of the role. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("colors")] public RoleColorsProperties? Colors { get; set; } + /// + /// Whether members with the role should be displayed separately in the member list. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("hoist")] public bool? Hoist { get; set; } + /// + /// The icon of the role. + /// + /// + /// The guild must have the ROLE_ICONS feature. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("icon")] public ImageProperties? Icon { get; set; } + /// + /// The Unicode emoji used as the role icon. + /// + /// + /// The guild must have the ROLE_ICONS feature. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("unicode_emoji")] public string? UnicodeIcon { get; set; } + /// + /// Whether the role should be mentionable. + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("mentionable")] public bool? Mentionable { get; set; } diff --git a/NetCord/Rest/WebhookOptions.cs b/NetCord/Rest/WebhookOptions.cs index 15353f19d..b990f3a74 100644 --- a/NetCord/Rest/WebhookOptions.cs +++ b/NetCord/Rest/WebhookOptions.cs @@ -12,7 +12,7 @@ internal WebhookOptions() { } - /// c + /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("name")] public string? Name { get; set; }