@@ -147,17 +147,17 @@ namespace Discord.Net.Models | |||||
// | // | ||||
/// <summary> | /// <summary> | ||||
/// Text or voice <see cref="Channel"/> position changed. | |||||
/// <see cref="GuildTextChannel"/> or <see cref="VoiceChannel"/> position changed. | |||||
/// </summary> | /// </summary> | ||||
Position, | Position, | ||||
/// <summary> | /// <summary> | ||||
/// Text <see cref="Channel"/> topic changed. | |||||
/// <see cref="GuildTextChannel"/> topic changed. | |||||
/// </summary> | /// </summary> | ||||
Topic, | Topic, | ||||
/// <summary> | /// <summary> | ||||
/// Voice <see cref="Channel"/> bitrate changed. | |||||
/// <see cref="VoiceChannel"/> bitrate changed. | |||||
/// </summary> | /// </summary> | ||||
Bitrate, | Bitrate, | ||||
@@ -297,7 +297,7 @@ namespace Discord.Net.Models | |||||
// | // | ||||
/// <summary> | /// <summary> | ||||
/// New user limit in a voice <see cref="Channel"/>. | |||||
/// New user limit in a <see cref="VoiceChannel"/>. | |||||
/// </summary> | /// </summary> | ||||
UserLimit, | UserLimit, | ||||
} | } | ||||
@@ -0,0 +1,9 @@ | |||||
namespace Discord.Net.Models | |||||
{ | |||||
/// <summary> | |||||
/// To be written - just a filler for xml docs for now | |||||
/// </summary> | |||||
public record CategoryChannel : GuildChannel | |||||
{ | |||||
} | |||||
} |
@@ -11,6 +11,76 @@ namespace Discord.Net.Models | |||||
/// </remarks> | /// </remarks> | ||||
public record Channel | public record Channel | ||||
{ | { | ||||
/// <summary> | |||||
/// Minimum langth of a channel name. | |||||
/// </summary> | |||||
public const int MinChannelNameLength = 1; | |||||
/// <summary> | |||||
/// Maximum langth of a channel name. | |||||
/// </summary> | |||||
public const int MaxChannelNameLength = 100; | |||||
/// <summary> | |||||
/// Minimum langth of a channel topic. | |||||
/// </summary> | |||||
public const int MinChannelTopicLength = 0; | |||||
/// <summary> | |||||
/// Maximum langth of a channel topic. | |||||
/// </summary> | |||||
public const int MaxChannelTopicLength = 1024; | |||||
/// <summary> | |||||
/// Minimum langth of a channel topic. | |||||
/// </summary> | |||||
public const int MinRateLimitPerUserDuration = 0; | |||||
/// <summary> | |||||
/// Maximum langth of a channel topic. | |||||
/// </summary> | |||||
public const int MaxRateLimitPerUserDuration = 1024; | |||||
/// <summary> | |||||
/// Minimum amount of users in channel. | |||||
/// </summary> | |||||
public const int MinUserLimit = 0; | |||||
/// <summary> | |||||
/// Maximum amount of users in channel. | |||||
/// </summary> | |||||
public const int MaxUserLimit = 99; | |||||
/// <summary> | |||||
/// Minimum bitrate for a channel. | |||||
/// </summary> | |||||
public const int MinBitrate = 8000; | |||||
/// <summary> | |||||
/// Maximum bitrate for a channel. | |||||
/// </summary> | |||||
public const int MaxBitrate = 128000; | |||||
/// <summary> | |||||
/// Minimum afk timeout duration for a channel. | |||||
/// </summary> | |||||
public const int MinAfkTimeoutDuration = 60; | |||||
/// <summary> | |||||
/// Maximum afk timeout duration for a channel. | |||||
/// </summary> | |||||
public const int MaxAFkTimeoutDuration = 3600; | |||||
/// <summary> | |||||
/// Minimum amount of messages to requests in a channel. | |||||
/// </summary> | |||||
public const int MinGetMessagesAmount = 1; | |||||
/// <summary> | |||||
/// Maximum amount of messages to requests in a channel. | |||||
/// </summary> | |||||
public const int MaxGetMessagesAmount = 100; | |||||
/// <summary> | /// <summary> | ||||
/// The id of this <see cref="Channel"/>. | /// The id of this <see cref="Channel"/>. | ||||
/// </summary> | /// </summary> | ||||
@@ -73,13 +143,13 @@ namespace Discord.Net.Models | |||||
public Optional<Snowflake?> LastMessageId { get; init; } | public Optional<Snowflake?> LastMessageId { get; init; } | ||||
/// <summary> | /// <summary> | ||||
/// The bitrate (in bits) of the voice <see cref="Channel"/>. | |||||
/// The bitrate (in bits) of the <see cref="VoiceChannel"/>. | |||||
/// </summary> | /// </summary> | ||||
[JsonPropertyName("bitrate")] | [JsonPropertyName("bitrate")] | ||||
public Optional<int> Bitrate { get; init; } | public Optional<int> Bitrate { get; init; } | ||||
/// <summary> | /// <summary> | ||||
/// The <see cref="User"/> limit of the voice <see cref="Channel"/>. | |||||
/// The <see cref="User"/> limit of the <see cref="VoiceChannel"/>. | |||||
/// </summary> | /// </summary> | ||||
[JsonPropertyName("user_limit")] | [JsonPropertyName("user_limit")] | ||||
public Optional<int> UserLimit { get; init; } | public Optional<int> UserLimit { get; init; } | ||||
@@ -135,13 +205,13 @@ namespace Discord.Net.Models | |||||
public Optional<DateTimeOffset?> LastPinTimestamp { get; init; } | public Optional<DateTimeOffset?> LastPinTimestamp { get; init; } | ||||
/// <summary> | /// <summary> | ||||
/// Voice region id for the voice <see cref="Channel"/>, automatic when set to null. | |||||
/// Voice region id for the <see cref="VoiceChannel"/>, automatic when set to null. | |||||
/// </summary> | /// </summary> | ||||
[JsonPropertyName("rtc_region")] | [JsonPropertyName("rtc_region")] | ||||
public Optional<string?> RtcRegion { get; init; } | public Optional<string?> RtcRegion { get; init; } | ||||
/// <summary> | /// <summary> | ||||
/// The camera video quality mode of the voice channel, 1 when not present. | |||||
/// The camera video quality mode of the <see cref="VoiceChannel"/>, 1 when not present. | |||||
/// </summary> | /// </summary> | ||||
[JsonPropertyName("video_quality_mode")] | [JsonPropertyName("video_quality_mode")] | ||||
public Optional<VideoQualityMode> VideoQualityMode { get; init; } | public Optional<VideoQualityMode> VideoQualityMode { get; init; } | ||||
@@ -0,0 +1,9 @@ | |||||
namespace Discord.Net.Models | |||||
{ | |||||
/// <summary> | |||||
/// To be written - just a filler for xml docs for now | |||||
/// </summary> | |||||
public record DMChannel : PrivateChannel | |||||
{ | |||||
} | |||||
} |
@@ -0,0 +1,9 @@ | |||||
namespace Discord.Net.Models | |||||
{ | |||||
/// <summary> | |||||
/// To be written - just a filler for xml docs for now | |||||
/// </summary> | |||||
public record GroupChannel : Channel | |||||
{ | |||||
} | |||||
} |
@@ -0,0 +1,9 @@ | |||||
namespace Discord.Net.Models | |||||
{ | |||||
/// <summary> | |||||
/// To be written - just a filler for xml docs for now | |||||
/// </summary> | |||||
public record GuildChannel : Channel | |||||
{ | |||||
} | |||||
} |
@@ -0,0 +1,9 @@ | |||||
namespace Discord.Net.Models | |||||
{ | |||||
/// <summary> | |||||
/// To be written - just a filler for xml docs for now | |||||
/// </summary> | |||||
public record GuildTextChannel : GuildChannel | |||||
{ | |||||
} | |||||
} |
@@ -0,0 +1,9 @@ | |||||
namespace Discord.Net.Models | |||||
{ | |||||
/// <summary> | |||||
/// To be written - just a filler for xml docs for now | |||||
/// </summary> | |||||
public record PrivateChannel : Channel | |||||
{ | |||||
} | |||||
} |
@@ -0,0 +1,9 @@ | |||||
namespace Discord.Net.Models | |||||
{ | |||||
/// <summary> | |||||
/// To be written - just a filler for xml docs for now | |||||
/// </summary> | |||||
public record StageChannel : GuildChannel | |||||
{ | |||||
} | |||||
} |
@@ -17,13 +17,13 @@ namespace Discord.Net.Models | |||||
public Snowflake Id { get; } | public Snowflake Id { get; } | ||||
/// <summary> | /// <summary> | ||||
/// The <see cref="Guild"/> id of the associated Stage <see cref="Channel"/>. | |||||
/// The <see cref="Guild"/> id of the associated <see cref="StageChannel"/>. | |||||
/// </summary> | /// </summary> | ||||
[JsonPropertyName("guild_id")] | [JsonPropertyName("guild_id")] | ||||
public Snowflake GuildId { get; } | public Snowflake GuildId { get; } | ||||
/// <summary> | /// <summary> | ||||
/// The id of the associated Stage <see cref="Channel"/>. | |||||
/// The id of the associated <see cref="StageChannel"/>. | |||||
/// </summary> | /// </summary> | ||||
[JsonPropertyName("channel_id")] | [JsonPropertyName("channel_id")] | ||||
public Snowflake ChannelId { get; } | public Snowflake ChannelId { get; } | ||||
@@ -0,0 +1,9 @@ | |||||
namespace Discord.Net.Models | |||||
{ | |||||
/// <summary> | |||||
/// To be written - just a filler for xml docs for now | |||||
/// </summary> | |||||
public record ThreadChannel : GuildChannel | |||||
{ | |||||
} | |||||
} |
@@ -0,0 +1,9 @@ | |||||
namespace Discord.Net.Models | |||||
{ | |||||
/// <summary> | |||||
/// To be written - just a filler for xml docs for now | |||||
/// </summary> | |||||
public record VoiceChannel : GuildChannel | |||||
{ | |||||
} | |||||
} |
@@ -159,7 +159,7 @@ namespace Discord.Net.Models | |||||
public int SystemChannelFlags { get; init; } | public int SystemChannelFlags { get; init; } | ||||
/// <summary> | /// <summary> | ||||
/// The id of the <see cref="Channel"/> where Community <see cref="Guild"/>s | |||||
/// The id of the <see cref="Channel"/> where Community <see cref="Guild"/>s. | |||||
/// can display rules and/or guidelines. | /// can display rules and/or guidelines. | ||||
/// </summary> | /// </summary> | ||||
[JsonPropertyName("rules_channel_id")] | [JsonPropertyName("rules_channel_id")] | ||||
@@ -190,7 +190,7 @@ namespace Discord.Net.Models | |||||
public Optional<int> MemberCount { get; init; } | public Optional<int> MemberCount { get; init; } | ||||
/// <summary> | /// <summary> | ||||
/// States of <see cref="GuildMember"/>s currently in voice <see cref="Channel"/>s. | |||||
/// States of <see cref="GuildMember"/>s currently in <see cref="VoiceChannel"/>s. | |||||
/// </summary> | /// </summary> | ||||
/// <remarks> | /// <remarks> | ||||
/// Lacks the <see cref="VoiceState.GuildId"/>. | /// Lacks the <see cref="VoiceState.GuildId"/>. | ||||
@@ -211,8 +211,8 @@ namespace Discord.Net.Models | |||||
public Optional<Channel[]> Channels { get; init; } | public Optional<Channel[]> Channels { get; init; } | ||||
/// <summary> | /// <summary> | ||||
/// All active thread <see cref="Channel"/>s in the <see cref="Guild"/> that current <see cref="User"/> | |||||
/// has permission to view. | |||||
/// All active <see cref="ThreadChannel"/>s in the <see cref="Guild"/> that the | |||||
/// current <see cref="User"/> has permission to view. | |||||
/// </summary> | /// </summary> | ||||
[JsonPropertyName("threads")] | [JsonPropertyName("threads")] | ||||
public Optional<Channel[]> Threads { get; init; } | public Optional<Channel[]> Threads { get; init; } | ||||
@@ -42,13 +42,13 @@ namespace Discord.Net.Models | |||||
public Optional<DateTimeOffset?> PremiumSince { get; init; } | public Optional<DateTimeOffset?> PremiumSince { get; init; } | ||||
/// <summary> | /// <summary> | ||||
/// Whether the user is deafened in voice <see cref="Channel"/>s. | |||||
/// Whether the user is deafened in <see cref="VoiceChannel"/>s. | |||||
/// </summary> | /// </summary> | ||||
[JsonPropertyName("deaf")] | [JsonPropertyName("deaf")] | ||||
public bool Deaf { get; init; } | public bool Deaf { get; init; } | ||||
/// <summary> | /// <summary> | ||||
/// Whether the user is muted in voice <see cref="Channel"/>s. | |||||
/// Whether the user is muted in <see cref="VoiceChannel"/>s. | |||||
/// </summary> | /// </summary> | ||||
[JsonPropertyName("mute")] | [JsonPropertyName("mute")] | ||||
public bool Mute { get; init; } | public bool Mute { get; init; } | ||||
@@ -9,8 +9,28 @@ namespace Discord.Net.Models | |||||
/// <remarks> | /// <remarks> | ||||
/// <see href="https://discord.com/developers/docs/resources/invite#invite-metadata-object-invite-metadata-structure"/> | /// <see href="https://discord.com/developers/docs/resources/invite#invite-metadata-object-invite-metadata-structure"/> | ||||
/// </remarks> | /// </remarks> | ||||
public record InviteMetadata : Invite | |||||
public record InviteWithMetadata : Invite | |||||
{ | { | ||||
/// <summary> | |||||
/// Minimum age for an invite in seconds. | |||||
/// </summary> | |||||
public const int MinAgeTime = 0; | |||||
/// <summary> | |||||
/// Maximum age for an invite in seconds. | |||||
/// </summary> | |||||
public const int MaxAgeTime = 604800; | |||||
/// <summary> | |||||
/// Minimum amount of uses for an invite. | |||||
/// </summary> | |||||
public const int MinUseCount = 0; | |||||
/// <summary> | |||||
/// Maximum amount of uses for an invite. | |||||
/// </summary> | |||||
public const int MaxUseCount = 100; | |||||
/// <summary> | /// <summary> | ||||
/// Number of times this <see cref="Invite"/> has been used. | /// Number of times this <see cref="Invite"/> has been used. | ||||
/// </summary> | /// </summary> | ||||
@@ -18,7 +38,7 @@ namespace Discord.Net.Models | |||||
public int Uses { get; init; } | public int Uses { get; init; } | ||||
/// <summary> | /// <summary> | ||||
/// Max number of times this <see cref="Invite"/> can be used. | |||||
/// Maximum number of times this <see cref="Invite"/> can be used. | |||||
/// </summary> | /// </summary> | ||||
[JsonPropertyName("max_uses")] | [JsonPropertyName("max_uses")] | ||||
public int MaxUses { get; init; } | public int MaxUses { get; init; } |
@@ -11,6 +11,26 @@ namespace Discord.Net.Models | |||||
/// </remarks> | /// </remarks> | ||||
public record Message | public record Message | ||||
{ | { | ||||
/// <summary> | |||||
/// Maximum length of the message content. | |||||
/// </summary> | |||||
public const int MaxContentLength = 2000; | |||||
/// <summary> | |||||
/// Maximum amount of embeds. | |||||
/// </summary> | |||||
public const int MaxEmbeds = 10; | |||||
/// <summary> | |||||
/// Minimum amount of messages to bulk delete. | |||||
/// </summary> | |||||
public const int MinBulkDeleteAmount = 2; | |||||
/// <summary> | |||||
/// Maximum amount of messages to bulk delete. | |||||
/// </summary> | |||||
public const int MaxBulkDeleteAmount = 100; | |||||
/// <summary> | /// <summary> | ||||
/// Id of the <see cref="Message"/>. | /// Id of the <see cref="Message"/>. | ||||
/// </summary> | /// </summary> | ||||
@@ -182,7 +202,7 @@ namespace Discord.Net.Models | |||||
public Optional<MessageInteraction> Interaction { get; init; } | public Optional<MessageInteraction> Interaction { get; init; } | ||||
/// <summary> | /// <summary> | ||||
/// The thread <see cref="Channel"/> that was started from this <see cref="Message"/>, | |||||
/// The <see cref="ThreadChannel"/> that was started from this <see cref="Message"/>, | |||||
/// includes <see cref="ThreadMember"/>s. | /// includes <see cref="ThreadMember"/>s. | ||||
/// </summary> | /// </summary> | ||||
[JsonPropertyName("thread")] | [JsonPropertyName("thread")] | ||||
@@ -14,12 +14,12 @@ namespace Discord.Net.Models | |||||
Default = 0, | Default = 0, | ||||
/// <summary> | /// <summary> | ||||
/// Recipient was added to a group <see cref="Channel"/>. | |||||
/// Recipient was added to a <see cref="GroupChannel"/>. | |||||
/// </summary> | /// </summary> | ||||
RecipientAdd = 1, | RecipientAdd = 1, | ||||
/// <summary> | /// <summary> | ||||
/// Recipient was removed from a group <see cref="Channel"/>. | |||||
/// Recipient was removed from a <see cref="GroupChannel"/>. | |||||
/// </summary> | /// </summary> | ||||
RecipientRemove = 2, | RecipientRemove = 2, | ||||
@@ -29,12 +29,12 @@ namespace Discord.Net.Models | |||||
Call = 3, | Call = 3, | ||||
/// <summary> | /// <summary> | ||||
/// Group <see cref="Channel"/> name was changed. | |||||
/// <see cref="GroupChannel"/> name was changed. | |||||
/// </summary> | /// </summary> | ||||
ChannelNameChange = 4, | ChannelNameChange = 4, | ||||
/// <summary> | /// <summary> | ||||
/// Group <see cref="Channel"/> icon was changed. | |||||
/// <see cref="GroupChannel"/> icon was changed. | |||||
/// </summary> | /// </summary> | ||||
ChannelIconChange = 5, | ChannelIconChange = 5, | ||||
@@ -96,7 +96,7 @@ namespace Discord.Net.Models | |||||
GuildDiscoveryGracePeriodFinalWarning = 17, | GuildDiscoveryGracePeriodFinalWarning = 17, | ||||
/// <summary> | /// <summary> | ||||
/// A thread <see cref="Channel"/> was created. | |||||
/// A <see cref="ThreadChannel"/> was created. | |||||
/// </summary> | /// </summary> | ||||
ThreadCreated = 18, | ThreadCreated = 18, | ||||
@@ -111,7 +111,7 @@ namespace Discord.Net.Models | |||||
ApplicationCommand = 20, | ApplicationCommand = 20, | ||||
/// <summary> | /// <summary> | ||||
/// Starter message for a thread <see cref="Channel"/>. | |||||
/// Starter message for a <see cref="ThreadChannel"/>. | |||||
/// </summary> | /// </summary> | ||||
ThreadStarterMessage = 21, | ThreadStarterMessage = 21, | ||||
@@ -10,6 +10,16 @@ namespace Discord.Net.Models | |||||
/// </remarks> | /// </remarks> | ||||
public record Reaction | public record Reaction | ||||
{ | { | ||||
/// <summary> | |||||
/// Minimum amount of users that reacted in a message. | |||||
/// </summary> | |||||
public const int MinGetReactionsAmount = 1; | |||||
/// <summary> | |||||
/// Maximum amount of users that reacted in a message. | |||||
/// </summary> | |||||
public const int MaxGetReactionsAmount = 100; | |||||
/// <summary> | /// <summary> | ||||
/// Times this <see cref="Models.Emoji"/> has been used to react. | /// Times this <see cref="Models.Emoji"/> has been used to react. | ||||
/// </summary> | /// </summary> | ||||
@@ -28,16 +28,357 @@ namespace Discord.Net | |||||
#region Audit Log | #region Audit Log | ||||
/// <inheritdoc/> | /// <inheritdoc/> | ||||
public Task<AuditLog> GetGuildAuditLogAsync(Snowflake guildId, GetGuildAuditLogParams? args = null, CancellationToken cancellationToken = default) | |||||
public Task<AuditLog> GetGuildAuditLogAsync(Snowflake guildId, GetGuildAuditLogParams args, CancellationToken cancellationToken = default) | |||||
{ | { | ||||
Preconditions.NotZero(guildId, nameof(guildId)); | Preconditions.NotZero(guildId, nameof(guildId)); | ||||
if (args == null) | |||||
args = new(); | |||||
else | |||||
args.Validate(); | |||||
Preconditions.NotNull(args, nameof(args)); | |||||
args.Validate(); | |||||
return _api.GetGuildAuditLogAsync(guildId, args, cancellationToken); | return _api.GetGuildAuditLogAsync(guildId, args, cancellationToken); | ||||
} | } | ||||
#endregion | #endregion | ||||
#region Channel | |||||
/// <inheritdoc/> | |||||
public Task<Channel> GetChannelAsync(Snowflake channelId, CancellationToken cancellationToken = default) | |||||
{ | |||||
Preconditions.NotZero(channelId, nameof(channelId)); | |||||
return _api.GetChannelAsync(channelId, cancellationToken); | |||||
} | |||||
/// <inheritdoc/> | |||||
public Task<GroupChannel> ModifyChannelAsync(Snowflake channelId, ModifyGroupChannelParams args, CancellationToken cancellationToken = default) | |||||
{ | |||||
Preconditions.NotZero(channelId, nameof(channelId)); | |||||
Preconditions.NotNull(args, nameof(args)); | |||||
args.Validate(); | |||||
return _api.ModifyChannelAsync(channelId, args, cancellationToken); | |||||
} | |||||
/// <inheritdoc/> | |||||
public Task<GuildChannel> ModifyChannelAsync(Snowflake channelId, ModifyGuildChannelParams args, CancellationToken cancellationToken = default) | |||||
{ | |||||
Preconditions.NotZero(channelId, nameof(channelId)); | |||||
Preconditions.NotNull(args, nameof(args)); | |||||
args.Validate(); | |||||
return _api.ModifyChannelAsync(channelId, args, cancellationToken); | |||||
} | |||||
/// <inheritdoc/> | |||||
public Task<ThreadChannel> ModifyChannelAsync(Snowflake channelId, ModifyThreadChannelParams args, CancellationToken cancellationToken = default) | |||||
{ | |||||
Preconditions.NotZero(channelId, nameof(channelId)); | |||||
Preconditions.NotNull(args, nameof(args)); | |||||
args.Validate(); | |||||
return _api.ModifyChannelAsync(channelId, args, cancellationToken); | |||||
} | |||||
/// <inheritdoc/> | |||||
public Task<Channel> DeleteChannelAsync(Snowflake channelId, CancellationToken cancellationToken = default) | |||||
{ | |||||
Preconditions.NotZero(channelId, nameof(channelId)); | |||||
return _api.DeleteChannelAsync(channelId, cancellationToken); | |||||
} | |||||
/// <inheritdoc/> | |||||
public Task<Message[]> GetChannelMessagesAsync(Snowflake channelId, GetChannelMessagesParams args, CancellationToken cancellationToken = default) | |||||
{ | |||||
Preconditions.NotZero(channelId, nameof(channelId)); | |||||
Preconditions.NotNull(args, nameof(args)); | |||||
args.Validate(); | |||||
return _api.GetChannelMessagesAsync(channelId, args, cancellationToken); | |||||
} | |||||
/// <inheritdoc/> | |||||
public Task<Message> GetChannelMessageAsync(Snowflake channelId, Snowflake messageId, CancellationToken cancellationToken = default) | |||||
{ | |||||
Preconditions.NotZero(channelId, nameof(channelId)); | |||||
Preconditions.NotZero(messageId, nameof(messageId)); | |||||
return _api.GetChannelMessageAsync(channelId, messageId, cancellationToken); | |||||
} | |||||
/// <inheritdoc/> | |||||
public Task<Message> CreateMessageAsync(Snowflake channelId, CreateMessageParams args, CancellationToken cancellationToken = default) | |||||
{ | |||||
Preconditions.NotZero(channelId, nameof(channelId)); | |||||
Preconditions.NotNull(args, nameof(args)); | |||||
args.Validate(); | |||||
return _api.CreateMessageAsync(channelId, args, cancellationToken); | |||||
} | |||||
/// <inheritdoc/> | |||||
public Task<Message> CrosspostMessageAsync(Snowflake channelId, Snowflake messageId, CancellationToken cancellationToken = default) | |||||
{ | |||||
Preconditions.NotZero(channelId, nameof(channelId)); | |||||
Preconditions.NotZero(messageId, nameof(messageId)); | |||||
return _api.CrosspostMessageAsync(channelId, messageId, cancellationToken); | |||||
} | |||||
/// <inheritdoc/> | |||||
public Task CreateReactionAsync(Snowflake channelId, Snowflake messageId, Emoji emoji, CancellationToken cancellationToken = default) | |||||
{ | |||||
Preconditions.NotZero(channelId, nameof(channelId)); | |||||
Preconditions.NotZero(messageId, nameof(messageId)); | |||||
Preconditions.NotNull(emoji, nameof(emoji)); | |||||
return _api.CreateReactionAsync(channelId, messageId, emoji, cancellationToken); | |||||
} | |||||
/// <inheritdoc/> | |||||
public Task DeleteOwnReactionAsync(Snowflake channelId, Snowflake messageId, Emoji emoji, CancellationToken cancellationToken = default) | |||||
{ | |||||
Preconditions.NotZero(channelId, nameof(channelId)); | |||||
Preconditions.NotZero(messageId, nameof(messageId)); | |||||
Preconditions.NotNull(emoji, nameof(emoji)); | |||||
return _api.DeleteOwnReactionAsync(channelId, messageId, emoji, cancellationToken); | |||||
} | |||||
/// <inheritdoc/> | |||||
public Task DeleteUserReactionAsync(Snowflake channelId, Snowflake messageId, Snowflake userId, Emoji emoji, CancellationToken cancellationToken = default) | |||||
{ | |||||
Preconditions.NotZero(messageId, nameof(messageId)); | |||||
Preconditions.NotZero(channelId, nameof(channelId)); | |||||
Preconditions.NotZero(userId, nameof(userId)); | |||||
Preconditions.NotNull(emoji, nameof(emoji)); | |||||
return _api.DeleteUserReactionAsync(channelId, messageId, userId, emoji, cancellationToken); | |||||
} | |||||
/// <inheritdoc/> | |||||
public Task<User[]> GetReactionsAsync(Snowflake channelId, Snowflake messageId, Emoji emoji, GetReactionsParams args, CancellationToken cancellationToken = default) | |||||
{ | |||||
Preconditions.NotZero(channelId, nameof(channelId)); | |||||
Preconditions.NotZero(messageId, nameof(messageId)); | |||||
Preconditions.NotNull(emoji, nameof(emoji)); | |||||
Preconditions.NotNull(args, nameof(args)); | |||||
args.Validate(); | |||||
return _api.GetReactionsAsync(channelId, messageId, emoji, args, cancellationToken); | |||||
} | |||||
/// <inheritdoc/> | |||||
public Task DeleteAllReactionsAsync(Snowflake channelId, Snowflake messageId, CancellationToken cancellationToken = default) | |||||
{ | |||||
Preconditions.NotZero(messageId, nameof(messageId)); | |||||
Preconditions.NotZero(channelId, nameof(channelId)); | |||||
return _api.DeleteAllReactionsAsync(messageId, channelId, cancellationToken); | |||||
} | |||||
/// <inheritdoc/> | |||||
public Task DeleteAllReactionsforEmojiAsync(Snowflake channelId, Snowflake messageId, Emoji emoji, CancellationToken cancellationToken = default) | |||||
{ | |||||
Preconditions.NotZero(channelId, nameof(channelId)); | |||||
Preconditions.NotZero(messageId, nameof(messageId)); | |||||
Preconditions.NotNull(emoji, nameof(emoji)); | |||||
return _api.DeleteAllReactionsforEmojiAsync(channelId, messageId, emoji, cancellationToken); | |||||
} | |||||
/// <inheritdoc/> | |||||
public Task<Message> EditMessageAsync(Snowflake channelId, Snowflake messageId, EditMessageParams args, CancellationToken cancellationToken = default) | |||||
{ | |||||
Preconditions.NotZero(channelId, nameof(channelId)); | |||||
Preconditions.NotZero(messageId, nameof(messageId)); | |||||
Preconditions.NotNull(args, nameof(args)); | |||||
args.Validate(); | |||||
return _api.EditMessageAsync(channelId, messageId, args, cancellationToken); | |||||
} | |||||
/// <inheritdoc/> | |||||
public Task DeleteMessageAsync(Snowflake channelId, Snowflake messageId, CancellationToken cancellationToken = default) | |||||
{ | |||||
Preconditions.NotZero(channelId, nameof(channelId)); | |||||
Preconditions.NotZero(messageId, nameof(messageId)); | |||||
return _api.DeleteMessageAsync(channelId, messageId, cancellationToken); | |||||
} | |||||
/// <inheritdoc/> | |||||
public Task BulkDeleteMessagesAsync(Snowflake channelId, BulkDeleteMessagesParams args, CancellationToken cancellationToken = default) | |||||
{ | |||||
Preconditions.NotZero(channelId, nameof(channelId)); | |||||
Preconditions.NotNull(args, nameof(args)); | |||||
args.Validate(); | |||||
return _api.BulkDeleteMessagesAsync(channelId, args, cancellationToken); | |||||
} | |||||
/// <inheritdoc/> | |||||
public Task EditChannelPermissionsAsync(Snowflake channelId, Snowflake overwriteId, EditChannelPermissionsParams args, CancellationToken cancellationToken = default) | |||||
{ | |||||
Preconditions.NotZero(channelId, nameof(channelId)); | |||||
Preconditions.NotZero(overwriteId, nameof(overwriteId)); | |||||
Preconditions.NotNull(args, nameof(args)); | |||||
args.Validate(); | |||||
return _api.EditChannelPermissionsAsync(channelId, overwriteId, args, cancellationToken); | |||||
} | |||||
/// <inheritdoc/> | |||||
public Task<InviteWithMetadata[]> GetChannelInvitesAsync(Snowflake channelId, CancellationToken cancellationToken = default) | |||||
{ | |||||
Preconditions.NotZero(channelId, nameof(channelId)); | |||||
return _api.GetChannelInvitesAsync(channelId, cancellationToken); | |||||
} | |||||
/// <inheritdoc/> | |||||
public Task<Invite> CreateChannelInviteAsync(Snowflake channelId, CreateChannelInviteParams args, CancellationToken cancellationToken = default) | |||||
{ | |||||
Preconditions.NotZero(channelId, nameof(channelId)); | |||||
Preconditions.NotNull(args, nameof(args)); | |||||
args.Validate(); | |||||
return _api.CreateChannelInviteAsync(channelId, args, cancellationToken); | |||||
} | |||||
/// <inheritdoc/> | |||||
public Task DeleteChannelPermissionAsync(Snowflake channelId, Snowflake overwriteId, CancellationToken cancellationToken = default) | |||||
{ | |||||
Preconditions.NotZero(channelId, nameof(channelId)); | |||||
Preconditions.NotZero(overwriteId, nameof(overwriteId)); | |||||
return _api.DeleteChannelPermissionAsync(channelId, overwriteId, cancellationToken); | |||||
} | |||||
/// <inheritdoc/> | |||||
public Task<FollowedChannel> FollowNewsChannelAsync(Snowflake channelId, FollowNewsChannelParams args, CancellationToken cancellationToken = default) | |||||
{ | |||||
Preconditions.NotZero(channelId, nameof(channelId)); | |||||
Preconditions.NotNull(args, nameof(args)); | |||||
args.Validate(); | |||||
return _api.FollowNewsChannelAsync(channelId, args, cancellationToken); | |||||
} | |||||
/// <inheritdoc/> | |||||
public Task TriggerTypingIndicatorAsync(Snowflake channelId, CancellationToken cancellationToken = default) | |||||
{ | |||||
Preconditions.NotZero(channelId, nameof(channelId)); | |||||
return _api.TriggerTypingIndicatorAsync(channelId, cancellationToken); | |||||
} | |||||
/// <inheritdoc/> | |||||
public Task<Message[]> GetPinnedMessagesAsync(Snowflake channelId, CancellationToken cancellationToken = default) | |||||
{ | |||||
Preconditions.NotZero(channelId, nameof(channelId)); | |||||
return _api.GetPinnedMessagesAsync(channelId, cancellationToken); | |||||
} | |||||
/// <inheritdoc/> | |||||
public Task PinMessageAsync(Snowflake channelId, Snowflake messageId, CancellationToken cancellationToken = default) | |||||
{ | |||||
Preconditions.NotZero(channelId, nameof(channelId)); | |||||
Preconditions.NotZero(messageId, nameof(messageId)); | |||||
return _api.PinMessageAsync(channelId, messageId, cancellationToken); | |||||
} | |||||
/// <inheritdoc/> | |||||
public Task UnpinMessageAsync(Snowflake channelId, Snowflake messageId, CancellationToken cancellationToken = default) | |||||
{ | |||||
Preconditions.NotZero(channelId, nameof(channelId)); | |||||
Preconditions.NotZero(messageId, nameof(messageId)); | |||||
return _api.UnpinMessageAsync(channelId, messageId, cancellationToken); | |||||
} | |||||
/// <inheritdoc/> | |||||
public Task GroupDMAddRecipientAsync(Snowflake channelId, Snowflake userId, GroupDMAddRecipientParams args, CancellationToken cancellationToken = default) | |||||
{ | |||||
Preconditions.NotZero(channelId, nameof(channelId)); | |||||
Preconditions.NotZero(userId, nameof(userId)); | |||||
Preconditions.NotNull(args, nameof(args)); | |||||
args.Validate(); | |||||
return _api.GroupDMAddRecipientAsync(channelId, userId, args, cancellationToken); | |||||
} | |||||
/// <inheritdoc/> | |||||
public Task GroupDMRemoveRecipientAsync(Snowflake channelId, Snowflake userId, CancellationToken cancellationToken = default) | |||||
{ | |||||
Preconditions.NotZero(channelId, nameof(channelId)); | |||||
Preconditions.NotZero(userId, nameof(userId)); | |||||
return _api.GroupDMRemoveRecipientAsync(channelId, userId, cancellationToken); | |||||
} | |||||
/// <inheritdoc/> | |||||
public Task<ThreadChannel> StartThreadAsync(Snowflake channelId, Snowflake messageId, StartThreadWithMessageParams args, CancellationToken cancellationToken = default) | |||||
{ | |||||
Preconditions.NotZero(channelId, nameof(channelId)); | |||||
Preconditions.NotZero(messageId, nameof(messageId)); | |||||
Preconditions.NotNull(args, nameof(args)); | |||||
args.Validate(); | |||||
return _api.StartThreadAsync(channelId, messageId, args, cancellationToken); | |||||
} | |||||
/// <inheritdoc/> | |||||
public Task<ThreadChannel> StartThreadAsync(Snowflake channelId, StartThreadWithoutMessageParams args, CancellationToken cancellationToken = default) | |||||
{ | |||||
Preconditions.NotZero(channelId, nameof(channelId)); | |||||
Preconditions.NotNull(args, nameof(args)); | |||||
args.Validate(); | |||||
return _api.StartThreadAsync(channelId, args, cancellationToken); | |||||
} | |||||
/// <inheritdoc/> | |||||
public Task JoinThreadAsync(Snowflake channelId, CancellationToken cancellationToken = default) | |||||
{ | |||||
Preconditions.NotZero(channelId, nameof(channelId)); | |||||
return _api.JoinThreadAsync(channelId, cancellationToken); | |||||
} | |||||
/// <inheritdoc/> | |||||
public Task AddThreadMemberAsync(Snowflake channelId, Snowflake userId, CancellationToken cancellationToken = default) | |||||
{ | |||||
Preconditions.NotZero(channelId, nameof(channelId)); | |||||
Preconditions.NotZero(userId, nameof(userId)); | |||||
return _api.AddThreadMemberAsync(channelId, userId, cancellationToken); | |||||
} | |||||
/// <inheritdoc/> | |||||
public Task LeaveThreadAsync(Snowflake channelId, CancellationToken cancellationToken = default) | |||||
{ | |||||
Preconditions.NotZero(channelId, nameof(channelId)); | |||||
return _api.LeaveThreadAsync(channelId, cancellationToken); | |||||
} | |||||
/// <inheritdoc/> | |||||
public Task RemoveThreadMemberAsync(Snowflake channelId, Snowflake userId, CancellationToken cancellationToken = default) | |||||
{ | |||||
Preconditions.NotZero(channelId, nameof(channelId)); | |||||
Preconditions.NotZero(userId, nameof(userId)); | |||||
return _api.RemoveThreadMemberAsync(channelId, userId, cancellationToken); | |||||
} | |||||
/// <inheritdoc/> | |||||
public Task<ThreadMember[]> ListThreadMembersAsync(Snowflake channelId, CancellationToken cancellationToken = default) | |||||
{ | |||||
Preconditions.NotZero(channelId, nameof(channelId)); | |||||
return _api.ListThreadMembersAsync(channelId, cancellationToken); | |||||
} | |||||
/// <inheritdoc/> | |||||
public Task<ThreadList> ListActiveThreadsAsync(Snowflake channelId, CancellationToken cancellationToken = default) | |||||
{ | |||||
Preconditions.NotZero(channelId, nameof(channelId)); | |||||
return _api.ListActiveThreadsAsync(channelId, cancellationToken); | |||||
} | |||||
/// <inheritdoc/> | |||||
public Task<ThreadList> ListPublicArchivedThreadsAsync(Snowflake channelId, ListPublicArchivedThreadsParams args, CancellationToken cancellationToken = default) | |||||
{ | |||||
Preconditions.NotZero(channelId, nameof(channelId)); | |||||
Preconditions.NotNull(args, nameof(args)); | |||||
args.Validate(); | |||||
return _api.ListPublicArchivedThreadsAsync(channelId, args, cancellationToken); | |||||
} | |||||
/// <inheritdoc/> | |||||
public Task<ThreadList> ListPrivateArchivedThreadsAsync(Snowflake channelId, ListPrivateArchivedThreadsParams args, CancellationToken cancellationToken = default) | |||||
{ | |||||
Preconditions.NotZero(channelId, nameof(channelId)); | |||||
Preconditions.NotNull(args, nameof(args)); | |||||
args.Validate(); | |||||
return _api.ListPrivateArchivedThreadsAsync(channelId, args, cancellationToken); | |||||
} | |||||
/// <inheritdoc/> | |||||
public Task<ThreadList> ListJoinedPrivateArchivedThreadsAsync(Snowflake channelId, ListJoinedPrivateArchivedThreadsParams args, CancellationToken cancellationToken = default) | |||||
{ | |||||
Preconditions.NotZero(channelId, nameof(channelId)); | |||||
Preconditions.NotNull(args, nameof(args)); | |||||
args.Validate(); | |||||
return _api.ListJoinedPrivateArchivedThreadsAsync(channelId, args, cancellationToken); | |||||
} | |||||
#endregion Channel | |||||
} | } | ||||
} | } |
@@ -0,0 +1,57 @@ | |||||
using System; | |||||
using System.Net; | |||||
namespace Discord.Net.Rest | |||||
{ | |||||
/// <summary> | |||||
/// Represents errors received in response to rest requests. | |||||
/// </summary> | |||||
public class DiscordRestException : Exception | |||||
{ | |||||
/// <summary> | |||||
/// HTTP status code returned. | |||||
/// </summary> | |||||
public HttpStatusCode HttpCode { get; } | |||||
/// <summary> | |||||
/// Discord JSON error code. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// <see href="https://discord.com/developers/docs/topics/opcodes-and-status-codes#json-json-error-codes"/> | |||||
/// </remarks> | |||||
public int? DiscordCode { get; } | |||||
/// <summary> | |||||
/// Reason of this error. | |||||
/// </summary> | |||||
public string? Reason { get; } | |||||
/// <summary> | |||||
/// Creates a <see cref="DiscordRestException"/> with the provided error data. | |||||
/// </summary> | |||||
/// <param name="httpCode"> | |||||
/// HTTP status code. | |||||
/// </param> | |||||
/// <param name="discordCode"> | |||||
/// Discord JSON error code. | |||||
/// </param> | |||||
/// <param name="reason"> | |||||
/// Reason of this error. | |||||
/// </param> | |||||
public DiscordRestException(HttpStatusCode httpCode, int? discordCode = null, string? reason = null) | |||||
: base(CreateMessage(httpCode, discordCode, reason)) | |||||
{ | |||||
HttpCode = httpCode; | |||||
DiscordCode = discordCode; | |||||
Reason = reason; | |||||
} | |||||
private static string CreateMessage(HttpStatusCode httpCode, int? discordCode = null, string? reason = null) | |||||
{ | |||||
if (!string.IsNullOrEmpty(reason)) | |||||
return $"The server responded with error {discordCode ?? (int)httpCode}: {reason}"; | |||||
else | |||||
return $"The server responded with error {discordCode ?? (int)httpCode}: {httpCode}"; | |||||
} | |||||
} | |||||
} |
@@ -13,13 +13,13 @@ namespace Discord.Net.Rest | |||||
#region Audit Log | #region Audit Log | ||||
/// <summary> | /// <summary> | ||||
/// Returns an audit log object for the guild. | |||||
/// Gets an <see cref="AuditLog"/> for the <see cref="Guild"/>. | |||||
/// </summary> | /// </summary> | ||||
/// <remarks> | /// <remarks> | ||||
/// Requires the <see cref="Permissions.ViewAuditLog"/> permission. | |||||
/// <see href="https://discord.com/developers/docs/resources/audit-log#get-guild-audit-log"/> | |||||
/// </remarks> | /// </remarks> | ||||
/// <param name="guildId"> | /// <param name="guildId"> | ||||
/// The guild identifier. | |||||
/// The <see cref="Guild"/> identifier. | |||||
/// </param> | /// </param> | ||||
/// <param name="args"> | /// <param name="args"> | ||||
/// Parameters to include in the request. | /// Parameters to include in the request. | ||||
@@ -27,8 +27,843 @@ namespace Discord.Net.Rest | |||||
/// <param name="cancellationToken"> | /// <param name="cancellationToken"> | ||||
/// Cancellation token for the request. | /// Cancellation token for the request. | ||||
/// </param> | /// </param> | ||||
Task<AuditLog> GetGuildAuditLogAsync(Snowflake guildId, GetGuildAuditLogParams? args = null, CancellationToken cancellationToken = default); | |||||
/// <returns> | |||||
/// A task that contains an <see cref="AuditLog"/>. | |||||
/// </returns> | |||||
Task<AuditLog> GetGuildAuditLogAsync(Snowflake guildId, GetGuildAuditLogParams args, CancellationToken cancellationToken = default); | |||||
#endregion | #endregion | ||||
#region Channel | |||||
/// <summary> | |||||
/// Gets a <see cref="Channel"/> by their identifier. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// <see href="https://discord.com/developers/docs/resources/channel#get-channel"/> | |||||
/// </remarks> | |||||
/// <param name="channelId"> | |||||
/// The <see cref="Channel"/> identifier. | |||||
/// </param> | |||||
/// <param name="cancellationToken"> | |||||
/// Cancellation token for the request. | |||||
/// </param> | |||||
/// <returns> | |||||
/// A task that contains a <see cref="Channel"/> if it exists; | |||||
/// otherwise, <see langword="null"/>. | |||||
/// </returns> | |||||
Task<Channel> GetChannelAsync(Snowflake channelId, CancellationToken cancellationToken = default); | |||||
/// <summary> | |||||
/// Updates a <see cref="GroupChannel"/>'s settings. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// <see href="https://discord.com/developers/docs/resources/channel#modify-channel"/> | |||||
/// </remarks> | |||||
/// <param name="channelId"> | |||||
/// The <see cref="GroupChannel"/> identifier. | |||||
/// </param> | |||||
/// <param name="args"> | |||||
/// Parameters to include in the request. | |||||
/// </param> | |||||
/// <param name="cancellationToken"> | |||||
/// Cancellation token for the request. | |||||
/// </param> | |||||
/// <returns> | |||||
/// A task that contains the updated <see cref="GroupChannel"/>. | |||||
/// </returns> | |||||
/// <exception cref="DiscordRestException"> | |||||
/// Thrown when invalid parameters are supplied in <paramref name="args"/>. | |||||
/// </exception> | |||||
Task<GroupChannel> ModifyChannelAsync(Snowflake channelId, ModifyGroupChannelParams args, CancellationToken cancellationToken = default); | |||||
/// <summary> | |||||
/// Updates a <see cref="GuildChannel"/>'s settings. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// <see href="https://discord.com/developers/docs/resources/channel#modify-channel"/> | |||||
/// </remarks> | |||||
/// <param name="channelId"> | |||||
/// The <see cref="GuildChannel"/> identifier. | |||||
/// </param> | |||||
/// <param name="args"> | |||||
/// Parameters to include in the request. | |||||
/// </param> | |||||
/// <param name="cancellationToken"> | |||||
/// Cancellation token for the request. | |||||
/// </param> | |||||
/// <returns> | |||||
/// A task that contains the updated <see cref="GuildChannel"/>. | |||||
/// </returns> | |||||
/// <exception cref="DiscordRestException"> | |||||
/// Thrown when invalid parameters are supplied in <paramref name="args"/>. | |||||
/// </exception> | |||||
Task<GuildChannel> ModifyChannelAsync(Snowflake channelId, ModifyGuildChannelParams args, CancellationToken cancellationToken = default); | |||||
/// <summary> | |||||
/// Updates a <see cref="ThreadChannel"/>'s settings. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// <see href="https://discord.com/developers/docs/resources/channel#modify-channel"/> | |||||
/// </remarks> | |||||
/// <param name="channelId"> | |||||
/// The <see cref="ThreadChannel"/> identifier. | |||||
/// </param> | |||||
/// <param name="args"> | |||||
/// Parameters to include in the request. | |||||
/// </param> | |||||
/// <param name="cancellationToken"> | |||||
/// Cancellation token for the request. | |||||
/// </param> | |||||
/// <returns> | |||||
/// A task that contains the updated <see cref="ThreadChannel"/>. | |||||
/// </returns> | |||||
/// <exception cref="DiscordRestException"> | |||||
/// Thrown when invalid parameters are supplied in <paramref name="args"/>. | |||||
/// </exception> | |||||
Task<ThreadChannel> ModifyChannelAsync(Snowflake channelId, ModifyThreadChannelParams args, CancellationToken cancellationToken = default); | |||||
/// <summary> | |||||
/// Deletes a <see cref="Channel"/>, or closes a <see cref="PrivateChannel"/>. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// <see href="https://discord.com/developers/docs/resources/channel#deleteclose-channel"/> | |||||
/// </remarks> | |||||
/// <param name="channelId"> | |||||
/// The <see cref="Channel"/> identifier. | |||||
/// </param> | |||||
/// <param name="cancellationToken"> | |||||
/// Cancellation token for the request. | |||||
/// </param> | |||||
/// <returns> | |||||
/// A task that contains the deleted <see cref="Channel"/>. | |||||
/// </returns> | |||||
Task<Channel> DeleteChannelAsync(Snowflake channelId, CancellationToken cancellationToken = default); | |||||
/// <summary> | |||||
/// Gets an array of <see cref="Message"/>s from a <see cref="Channel"/>. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// <see href="https://discord.com/developers/docs/resources/channel#get-channel-messages"/> | |||||
/// </remarks> | |||||
/// <param name="channelId"> | |||||
/// The <see cref="Channel"/> identifier. | |||||
/// </param> | |||||
/// <param name="args"> | |||||
/// Parameters to include in the request. | |||||
/// </param> | |||||
/// <param name="cancellationToken"> | |||||
/// Cancellation token for the request. | |||||
/// </param> | |||||
/// <returns> | |||||
/// A task that contains an array of <see cref="Message"/>s from the <see cref="Channel"/>. | |||||
/// </returns> | |||||
Task<Message[]> GetChannelMessagesAsync(Snowflake channelId, GetChannelMessagesParams args, CancellationToken cancellationToken = default); | |||||
/// <summary> | |||||
/// Gets a specific <see cref="Message"/> from a <see cref="Channel"/>. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// <see href="https://discord.com/developers/docs/resources/channel#get-channel-message"/> | |||||
/// </remarks> | |||||
/// <param name="messageId"> | |||||
/// The <see cref="Message"/> identifier. | |||||
/// </param> | |||||
/// <param name="channelId"> | |||||
/// The <see cref="Channel"/> identifier. | |||||
/// </param> | |||||
/// <param name="cancellationToken"> | |||||
/// Cancellation token for the request. | |||||
/// </param> | |||||
/// <returns> | |||||
/// A task that contains the specified <see cref="Message"/> or <see langword="null"/>. | |||||
/// </returns> | |||||
Task<Message> GetChannelMessageAsync(Snowflake channelId, Snowflake messageId, CancellationToken cancellationToken = default); | |||||
/// <summary> | |||||
/// Sends a <see cref="Message"/> to a <see cref="Channel"/>. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// <see href="https://discord.com/developers/docs/resources/channel#create-message"/> | |||||
/// </remarks> | |||||
/// <param name="channelId"> | |||||
/// The <see cref="Channel"/> identifier. | |||||
/// </param> | |||||
/// <param name="args"> | |||||
/// Parameters to include in the request. | |||||
/// </param> | |||||
/// <param name="cancellationToken"> | |||||
/// Cancellation token for the request. | |||||
/// </param> | |||||
/// <returns> | |||||
/// A task that contains the <see cref="Message"/> created. | |||||
/// </returns> | |||||
Task<Message> CreateMessageAsync(Snowflake channelId, CreateMessageParams args, CancellationToken cancellationToken = default); | |||||
/// <summary> | |||||
/// Crossposts a <see cref="Message"/> in a News <see cref="Channel"/> to following channels. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// <see href="https://discord.com/developers/docs/resources/channel#crosspost-message"/> | |||||
/// </remarks> | |||||
/// <param name="messageId"> | |||||
/// The <see cref="Message"/> identifier. | |||||
/// </param> | |||||
/// <param name="channelId"> | |||||
/// The <see cref="Channel"/> identifier. | |||||
/// </param> | |||||
/// <param name="cancellationToken"> | |||||
/// Cancellation token for the request. | |||||
/// </param> | |||||
/// <returns> | |||||
/// A task that contains the crossposted <see cref="Message"/>. | |||||
/// </returns> | |||||
Task<Message> CrosspostMessageAsync(Snowflake channelId, Snowflake messageId, CancellationToken cancellationToken = default); | |||||
/// <summary> | |||||
/// Creates a <see cref="Reaction"/> for a <see cref="Message"/>. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// <see href="https://discord.com/developers/docs/resources/channel#create-reaction"/> | |||||
/// </remarks> | |||||
/// <param name="messageId"> | |||||
/// The <see cref="Message"/> identifier. | |||||
/// </param> | |||||
/// <param name="channelId"> | |||||
/// The <see cref="Channel"/> identifier. | |||||
/// </param> | |||||
/// <param name="emoji"> | |||||
/// An <see cref="Emoji"/>. | |||||
/// </param> | |||||
/// <param name="cancellationToken"> | |||||
/// Cancellation token for the request. | |||||
/// </param> | |||||
/// <returns> | |||||
/// A task that represents this asynchronous operation. | |||||
/// </returns> | |||||
Task CreateReactionAsync(Snowflake channelId, Snowflake messageId, Emoji emoji, CancellationToken cancellationToken = default); | |||||
/// <summary> | |||||
/// Deletes a <see cref="Reaction"/> the current user has made for the <see cref="Message"/>. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// <see href="https://discord.com/developers/docs/resources/channel#delete-own-reaction"/> | |||||
/// </remarks> | |||||
/// <param name="messageId"> | |||||
/// The <see cref="Message"/> identifier. | |||||
/// </param> | |||||
/// <param name="channelId"> | |||||
/// The <see cref="Channel"/> identifier. | |||||
/// </param> | |||||
/// <param name="emoji"> | |||||
/// An <see cref="Emoji"/>. | |||||
/// </param> | |||||
/// <param name="cancellationToken"> | |||||
/// Cancellation token for the request. | |||||
/// </param> | |||||
/// <returns> | |||||
/// A task that represents this asynchronous operation. | |||||
/// </returns> | |||||
Task DeleteOwnReactionAsync(Snowflake channelId, Snowflake messageId, Emoji emoji, CancellationToken cancellationToken = default); | |||||
/// <summary> | |||||
/// Deletes another <see cref="User"/>'s <see cref="Reaction"/>. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// <see href="https://discord.com/developers/docs/resources/channel#delete-user-reaction"/> | |||||
/// </remarks> | |||||
/// <param name="messageId"> | |||||
/// The <see cref="Message"/> identifier. | |||||
/// </param> | |||||
/// <param name="channelId"> | |||||
/// The <see cref="Channel"/> identifier. | |||||
/// </param> | |||||
/// <param name="userId"> | |||||
/// The <see cref="User"/> identifier. | |||||
/// </param> | |||||
/// <param name="emoji"> | |||||
/// An <see cref="Emoji"/>. | |||||
/// </param> | |||||
/// <param name="cancellationToken"> | |||||
/// Cancellation token for the request. | |||||
/// </param> | |||||
/// <returns> | |||||
/// A task that represents this asynchronous operation. | |||||
/// </returns> | |||||
Task DeleteUserReactionAsync(Snowflake channelId, Snowflake messageId, Snowflake userId, Emoji emoji, CancellationToken cancellationToken = default); | |||||
/// <summary> | |||||
/// Gets an array of <see cref="User"/>s that reacted with this <see cref="Emoji"/>. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// <see href="https://discord.com/developers/docs/resources/channel#get-reactions"/> | |||||
/// </remarks> | |||||
/// <param name="messageId"> | |||||
/// The <see cref="Message"/> identifier. | |||||
/// </param> | |||||
/// <param name="channelId"> | |||||
/// The <see cref="Channel"/> identifier. | |||||
/// </param> | |||||
/// <param name="emoji"> | |||||
/// An <see cref="Emoji"/>. | |||||
/// </param> | |||||
/// <param name="args"> | |||||
/// Parameters to include in the request. | |||||
/// </param> | |||||
/// <param name="cancellationToken"> | |||||
/// Cancellation token for the request. | |||||
/// </param> | |||||
/// <returns> | |||||
/// A task that contains an array of <see cref="User"/>s that reacted with | |||||
/// the provided <see cref="Emoji"/>. | |||||
/// </returns> | |||||
Task<User[]> GetReactionsAsync(Snowflake channelId, Snowflake messageId, Emoji emoji, GetReactionsParams args, CancellationToken cancellationToken = default); | |||||
/// <summary> | |||||
/// Deletes all <see cref="Reaction"/>s on a <see cref="Message"/>. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// <see href="https://discord.com/developers/docs/resources/channel#delete-all-reactions"/> | |||||
/// </remarks> | |||||
/// <param name="messageId"> | |||||
/// The <see cref="Message"/> identifier. | |||||
/// </param> | |||||
/// <param name="channelId"> | |||||
/// The <see cref="Channel"/> identifier. | |||||
/// </param> | |||||
/// <param name="cancellationToken"> | |||||
/// Cancellation token for the request. | |||||
/// </param> | |||||
/// <returns> | |||||
/// A task that represents this asynchronous operation. | |||||
/// </returns> | |||||
Task DeleteAllReactionsAsync(Snowflake channelId, Snowflake messageId, CancellationToken cancellationToken = default); | |||||
/// <summary> | |||||
/// Deletes all the <see cref="Reaction"/>s for a given <see cref="Emoji"/> | |||||
/// on a <see cref="Message"/>. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// <see href="https://discord.com/developers/docs/resources/channel#delete-all-reactions-for-emoji"/> | |||||
/// </remarks> | |||||
/// <param name="messageId"> | |||||
/// The <see cref="Message"/> identifier. | |||||
/// </param> | |||||
/// <param name="channelId"> | |||||
/// The <see cref="Channel"/> identifier. | |||||
/// </param> | |||||
/// <param name="emoji"> | |||||
/// An <see cref="Emoji"/>. | |||||
/// </param> | |||||
/// <param name="cancellationToken"> | |||||
/// Cancellation token for the request. | |||||
/// </param> | |||||
/// <returns> | |||||
/// A task that represents this asynchronous operation. | |||||
/// </returns> | |||||
Task DeleteAllReactionsforEmojiAsync(Snowflake channelId, Snowflake messageId, Emoji emoji, CancellationToken cancellationToken = default); | |||||
/// <summary> | |||||
/// Edits a previously sent <see cref="Message"/>. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// <see href="https://discord.com/developers/docs/resources/channel#edit-message"/> | |||||
/// </remarks> | |||||
/// <param name="messageId"> | |||||
/// The <see cref="Message"/> identifier. | |||||
/// </param> | |||||
/// <param name="channelId"> | |||||
/// The <see cref="Channel"/> identifier. | |||||
/// </param> | |||||
/// <param name="args"> | |||||
/// Parameters to include in the request. | |||||
/// </param> | |||||
/// <param name="cancellationToken"> | |||||
/// Cancellation token for the request. | |||||
/// </param> | |||||
/// <returns> | |||||
/// A task that contains the updated <see cref="Message"/>. | |||||
/// </returns> | |||||
Task<Message> EditMessageAsync(Snowflake channelId, Snowflake messageId, EditMessageParams args, CancellationToken cancellationToken = default); | |||||
/// <summary> | |||||
/// Deletes a message. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// <see href="https://discord.com/developers/docs/resources/channel#delete-message"/> | |||||
/// </remarks> | |||||
/// <param name="messageId"> | |||||
/// The <see cref="Message"/> identifier. | |||||
/// </param> | |||||
/// <param name="channelId"> | |||||
/// The <see cref="Channel"/> identifier. | |||||
/// </param> | |||||
/// <param name="cancellationToken"> | |||||
/// Cancellation token for the request. | |||||
/// </param> | |||||
/// <returns> | |||||
/// A task that represents this asynchronous operation. | |||||
/// </returns> | |||||
Task DeleteMessageAsync(Snowflake channelId, Snowflake messageId, CancellationToken cancellationToken = default); | |||||
/// <summary> | |||||
/// Deletes multiple <see cref="Message"/>s in a single request. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// <see href="https://discord.com/developers/docs/resources/channel#bulk-delete-messages"/> | |||||
/// </remarks> | |||||
/// <param name="channelId"> | |||||
/// The <see cref="Channel"/> identifier. | |||||
/// </param> | |||||
/// <param name="args"> | |||||
/// Parameters to include in the request. | |||||
/// </param> | |||||
/// <param name="cancellationToken"> | |||||
/// Cancellation token for the request. | |||||
/// </param> | |||||
/// <returns> | |||||
/// A task that represents this asynchronous operation. | |||||
/// </returns> | |||||
/// <exception cref="DiscordRestException"> | |||||
/// Thrown when invalid parameters are supplied in <paramref name="args"/>. | |||||
/// </exception> | |||||
Task BulkDeleteMessagesAsync(Snowflake channelId, BulkDeleteMessagesParams args, CancellationToken cancellationToken = default); | |||||
/// <summary> | |||||
/// Edits the <see cref="Channel"/> permission <see cref="Overwrite"/>s for a <see cref="User"/> or <see cref="Role"/>. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// <see href="https://discord.com/developers/docs/resources/channel#edit-channel-permissions"/> | |||||
/// </remarks> | |||||
/// <param name="channelId"> | |||||
/// The <see cref="Channel"/> identifier. | |||||
/// </param> | |||||
/// <param name="overwriteId"> | |||||
/// The <see cref="Overwrite"/> identifier. | |||||
/// </param> | |||||
/// <param name="args"> | |||||
/// Parameters to include in the request. | |||||
/// </param> | |||||
/// <param name="cancellationToken"> | |||||
/// Cancellation token for the request. | |||||
/// </param> | |||||
/// <returns> | |||||
/// A task that represents this asynchronous operation. | |||||
/// </returns> | |||||
Task EditChannelPermissionsAsync(Snowflake channelId, Snowflake overwriteId, EditChannelPermissionsParams args, CancellationToken cancellationToken = default); | |||||
/// <summary> | |||||
/// Gets an array of <see cref="Invite"/>s for a <see cref="Channel"/>. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// <see href="https://discord.com/developers/docs/resources/channel#get-channel-invites"/> | |||||
/// </remarks> | |||||
/// <param name="channelId"> | |||||
/// The <see cref="Channel"/> identifier. | |||||
/// </param> | |||||
/// <param name="cancellationToken"> | |||||
/// Cancellation token for the request. | |||||
/// </param> | |||||
/// <returns> | |||||
/// A task that contains an array of <see cref="InviteWithMetadata"/>s. | |||||
/// </returns> | |||||
Task<InviteWithMetadata[]> GetChannelInvitesAsync(Snowflake channelId, CancellationToken cancellationToken = default); | |||||
/// <summary> | |||||
/// Creates a new <see cref="Invite"/> for the <see cref="Channel"/>. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// <see href="https://discord.com/developers/docs/resources/channel#create-channel-invite"/> | |||||
/// </remarks> | |||||
/// <param name="channelId"> | |||||
/// The <see cref="Channel"/> identifier. | |||||
/// </param> | |||||
/// <param name="args"> | |||||
/// Parameters to include in the request. | |||||
/// </param> | |||||
/// <param name="cancellationToken"> | |||||
/// Cancellation token for the request. | |||||
/// </param> | |||||
/// <returns> | |||||
/// A task that contains the created <see cref="Invite"/>. | |||||
/// </returns> | |||||
Task<Invite> CreateChannelInviteAsync(Snowflake channelId, CreateChannelInviteParams args, CancellationToken cancellationToken = default); | |||||
/// <summary> | |||||
/// Deletes a <see cref="Channel"/> permission <see cref="Overwrite"/> for a <see cref="User"/> or <see cref="Role"/>. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// <see href="https://discord.com/developers/docs/resources/channel#delete-channel-permission"/> | |||||
/// </remarks> | |||||
/// <param name="channelId"> | |||||
/// The <see cref="Channel"/> identifier. | |||||
/// </param> | |||||
/// <param name="overwriteId"> | |||||
/// The <see cref="Overwrite"/> identifier. | |||||
/// </param> | |||||
/// <param name="cancellationToken"> | |||||
/// Cancellation token for the request. | |||||
/// </param> | |||||
/// <returns> | |||||
/// A task that represents this asynchronous operation. | |||||
/// </returns> | |||||
Task DeleteChannelPermissionAsync(Snowflake channelId, Snowflake overwriteId, CancellationToken cancellationToken = default); | |||||
/// <summary> | |||||
/// Follow a News <see cref="Channel"/> to send <see cref="Message"/>s to a target <see cref="Channel"/>. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// <see href="https://discord.com/developers/docs/resources/channel#follow-news-channel"/> | |||||
/// </remarks> | |||||
/// <param name="channelId"> | |||||
/// The <see cref="Channel"/> identifier. | |||||
/// </param> | |||||
/// <param name="args"> | |||||
/// Parameters to include in the request. | |||||
/// </param> | |||||
/// <param name="cancellationToken"> | |||||
/// Cancellation token for the request. | |||||
/// </param> | |||||
/// <returns> | |||||
/// A task that contains the <see cref="FollowedChannel"/>. | |||||
/// </returns> | |||||
Task<FollowedChannel> FollowNewsChannelAsync(Snowflake channelId, FollowNewsChannelParams args, CancellationToken cancellationToken = default); | |||||
/// <summary> | |||||
/// Posts a typing indicator for the specified <see cref="Channel"/>. | |||||
/// </summary> | |||||
/// <param name="channelId"> | |||||
/// The <see cref="Channel"/> identifier. | |||||
/// </param> | |||||
/// <param name="cancellationToken"> | |||||
/// Cancellation token for the request. | |||||
/// </param> | |||||
/// <returns> | |||||
/// A task that represents this asynchronous operation. | |||||
/// </returns> | |||||
Task TriggerTypingIndicatorAsync(Snowflake channelId, CancellationToken cancellationToken = default); | |||||
/// <summary> | |||||
/// Gets all pinned <see cref="Message"/>s in the <see cref="Channel"/>. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// <see href="https://discord.com/developers/docs/resources/channel#get-pinned-messages"/> | |||||
/// </remarks> | |||||
/// <param name="channelId"> | |||||
/// The <see cref="Channel"/> identifier. | |||||
/// </param> | |||||
/// <param name="cancellationToken"> | |||||
/// Cancellation token for the request. | |||||
/// </param> | |||||
/// <returns> | |||||
/// A task that contains an array of all pinned <see cref="Message"/>s. | |||||
/// </returns> | |||||
Task<Message[]> GetPinnedMessagesAsync(Snowflake channelId, CancellationToken cancellationToken = default); | |||||
/// <summary> | |||||
/// Pins a <see cref="Message"/> in a <see cref="Channel"/>. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// <see href="https://discord.com/developers/docs/resources/channel#pin-message"/> | |||||
/// </remarks> | |||||
/// <param name="messageId"> | |||||
/// The <see cref="Message"/> identifier. | |||||
/// </param> | |||||
/// <param name="channelId"> | |||||
/// The <see cref="Channel"/> identifier. | |||||
/// </param> | |||||
/// <param name="cancellationToken"> | |||||
/// Cancellation token for the request. | |||||
/// </param> | |||||
/// <returns> | |||||
/// A task that represents this asynchronous operation. | |||||
/// </returns> | |||||
Task PinMessageAsync(Snowflake channelId, Snowflake messageId, CancellationToken cancellationToken = default); | |||||
/// <summary> | |||||
/// Unpins a <see cref="Message"/> in a <see cref="Channel"/>. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// <see href="https://discord.com/developers/docs/resources/channel#unpin-message"/> | |||||
/// </remarks> | |||||
/// <param name="messageId"> | |||||
/// The <see cref="Message"/> identifier. | |||||
/// </param> | |||||
/// <param name="channelId"> | |||||
/// The <see cref="Channel"/> identifier. | |||||
/// </param> | |||||
/// <param name="cancellationToken"> | |||||
/// Cancellation token for the request. | |||||
/// </param> | |||||
/// <returns> | |||||
/// A task that represents this asynchronous operation. | |||||
/// </returns> | |||||
Task UnpinMessageAsync(Snowflake channelId, Snowflake messageId, CancellationToken cancellationToken = default); | |||||
/// <summary> | |||||
/// Adds a recipient to a <see cref="GroupChannel"/> using their access token. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// <see href="https://discord.com/developers/docs/resources/channel#group-dm-add-recipient"/> | |||||
/// </remarks> | |||||
/// <param name="channelId"> | |||||
/// The <see cref="Channel"/> identifier. | |||||
/// </param> | |||||
/// <param name="userId"> | |||||
/// The <see cref="User"/> identifier. | |||||
/// </param> | |||||
/// <param name="args"> | |||||
/// Parameters to include in the request. | |||||
/// </param> | |||||
/// <param name="cancellationToken"> | |||||
/// Cancellation token for the request. | |||||
/// </param> | |||||
/// <returns> | |||||
/// A task that represents this asynchronous operation. | |||||
/// </returns> | |||||
Task GroupDMAddRecipientAsync(Snowflake channelId, Snowflake userId, GroupDMAddRecipientParams args, CancellationToken cancellationToken = default); | |||||
/// <summary> | |||||
/// Removes a recipient from a <see cref="GroupChannel"/>. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// <see href="https://discord.com/developers/docs/resources/channel#group-dm-remove-recipient"/> | |||||
/// </remarks> | |||||
/// <param name="channelId"> | |||||
/// The <see cref="Channel"/> identifier. | |||||
/// </param> | |||||
/// <param name="userId"> | |||||
/// The <see cref="User"/> identifier. | |||||
/// </param> | |||||
/// <param name="cancellationToken"> | |||||
/// Cancellation token for the request. | |||||
/// </param> | |||||
/// <returns> | |||||
/// A task that represents this asynchronous operation. | |||||
/// </returns> | |||||
Task GroupDMRemoveRecipientAsync(Snowflake channelId, Snowflake userId, CancellationToken cancellationToken = default); | |||||
/// <summary> | |||||
/// Creates a new <see cref="ThreadChannel"/> from an existing <see cref="Message"/>. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// <see href="https://discord.com/developers/docs/resources/channel#start-thread-with-message"/> | |||||
/// </remarks> | |||||
/// <param name="messageId"> | |||||
/// The <see cref="Message"/> identifier. | |||||
/// </param> | |||||
/// <param name="channelId"> | |||||
/// The <see cref="Channel"/> identifier. | |||||
/// </param> | |||||
/// <param name="args"> | |||||
/// Parameters to include in the request. | |||||
/// </param> | |||||
/// <param name="cancellationToken"> | |||||
/// Cancellation token for the request. | |||||
/// </param> | |||||
/// <returns> | |||||
/// A task that contains the created <see cref="ThreadChannel"/>. | |||||
/// </returns> | |||||
/// <exception cref="DiscordRestException"> | |||||
/// Thrown when invalid parameters are supplied in <paramref name="args"/>. | |||||
/// </exception> | |||||
Task<ThreadChannel> StartThreadAsync(Snowflake channelId, Snowflake messageId, StartThreadWithMessageParams args, CancellationToken cancellationToken = default); | |||||
/// <summary> | |||||
/// Creates a new private <see cref="ThreadChannel"/> that is not connected to an existing <see cref="Message"/>. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// <see href="https://discord.com/developers/docs/resources/channel#start-thread-without-message"/> | |||||
/// </remarks> | |||||
/// <param name="channelId"> | |||||
/// The <see cref="Channel"/> identifier. | |||||
/// </param> | |||||
/// <param name="args"> | |||||
/// Parameters to include in the request. | |||||
/// </param> | |||||
/// <param name="cancellationToken"> | |||||
/// Cancellation token for the request. | |||||
/// </param> | |||||
/// <returns> | |||||
/// A task that contains the created <see cref="ThreadChannel"/>. | |||||
/// </returns> | |||||
/// <exception cref="DiscordRestException"> | |||||
/// Thrown when invalid parameters are supplied in <paramref name="args"/>. | |||||
/// </exception> | |||||
Task<ThreadChannel> StartThreadAsync(Snowflake channelId, StartThreadWithoutMessageParams args, CancellationToken cancellationToken = default); | |||||
/// <summary> | |||||
/// Adds the current user to a <see cref="ThreadChannel"/>. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// <see href="https://discord.com/developers/docs/resources/channel#join-thread"/> | |||||
/// </remarks> | |||||
/// <param name="channelId"> | |||||
/// The <see cref="ThreadChannel"/> identifier. | |||||
/// </param> | |||||
/// <param name="cancellationToken"> | |||||
/// Cancellation token for the request. | |||||
/// </param> | |||||
/// <returns> | |||||
/// A task that represents this asynchronous operation. | |||||
/// </returns> | |||||
Task JoinThreadAsync(Snowflake channelId, CancellationToken cancellationToken = default); | |||||
/// <summary> | |||||
/// Adds another <see cref="GuildMember"/> to a <see cref="ThreadChannel"/>. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// <see href="https://discord.com/developers/docs/resources/channel#add-thread-member"/> | |||||
/// </remarks> | |||||
/// <param name="channelId"> | |||||
/// The <see cref="ThreadChannel"/> identifier. | |||||
/// </param> | |||||
/// <param name="userId"> | |||||
/// The <see cref="GuildMember"/> identifier. | |||||
/// </param> | |||||
/// <param name="cancellationToken"> | |||||
/// Cancellation token for the request. | |||||
/// </param> | |||||
/// <returns> | |||||
/// A task that represents this asynchronous operation. | |||||
/// </returns> | |||||
Task AddThreadMemberAsync(Snowflake channelId, Snowflake userId, CancellationToken cancellationToken = default); | |||||
/// <summary> | |||||
/// Removes the current user from a <see cref="ThreadChannel"/>. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// <see href="https://discord.com/developers/docs/resources/channel#leave-thread"/> | |||||
/// </remarks> | |||||
/// <param name="channelId"> | |||||
/// The <see cref="ThreadChannel"/> identifier. | |||||
/// </param> | |||||
/// <param name="cancellationToken"> | |||||
/// Cancellation token for the request. | |||||
/// </param> | |||||
/// <returns> | |||||
/// A task that represents this asynchronous operation. | |||||
/// </returns> | |||||
Task LeaveThreadAsync(Snowflake channelId, CancellationToken cancellationToken = default); | |||||
/// <summary> | |||||
/// Removes another <see cref="GuildMember"/> from a <see cref="ThreadChannel"/>. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// <see href="https://discord.com/developers/docs/resources/channel#remove-thread-member"/> | |||||
/// </remarks> | |||||
/// <param name="channelId"> | |||||
/// The <see cref="ThreadChannel"/> identifier. | |||||
/// </param> | |||||
/// <param name="userId"> | |||||
/// The <see cref="GuildMember"/> identifier. | |||||
/// </param> | |||||
/// <param name="cancellationToken"> | |||||
/// Cancellation token for the request. | |||||
/// </param> | |||||
/// <returns> | |||||
/// A task that represents this asynchronous operation. | |||||
/// </returns> | |||||
Task RemoveThreadMemberAsync(Snowflake channelId, Snowflake userId, CancellationToken cancellationToken = default); | |||||
/// <summary> | |||||
/// Gets an array of <see cref="ThreadMember"/>s that are part of the <see cref="ThreadChannel"/>. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// <see href="https://discord.com/developers/docs/resources/channel#list-thread-members"/> | |||||
/// </remarks> | |||||
/// <param name="channelId"> | |||||
/// The <see cref="ThreadChannel"/> identifier. | |||||
/// </param> | |||||
/// <param name="cancellationToken"> | |||||
/// Cancellation token for the request. | |||||
/// </param> | |||||
/// <returns> | |||||
/// A task that contains an array of <see cref="ThreadMember"/>s that are part of the | |||||
/// specified <see cref="ThreadChannel"/>. | |||||
/// </returns> | |||||
Task<ThreadMember[]> ListThreadMembersAsync(Snowflake channelId, CancellationToken cancellationToken = default); | |||||
/// <summary> | |||||
/// Gets all active <see cref="ThreadChannel"/>s in the <see cref="Channel"/>. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// <see href="https://discord.com/developers/docs/resources/channel#list-active-threads"/> | |||||
/// </remarks> | |||||
/// <param name="channelId"> | |||||
/// The <see cref="Channel"/> identifier. | |||||
/// </param> | |||||
/// <param name="cancellationToken"> | |||||
/// Cancellation token for the request. | |||||
/// </param> | |||||
/// <returns> | |||||
/// A task that contains a <see cref="ThreadList"/>. | |||||
/// </returns> | |||||
Task<ThreadList> ListActiveThreadsAsync(Snowflake channelId, CancellationToken cancellationToken = default); | |||||
/// <summary> | |||||
/// Gets archived <see cref="ThreadChannel"/>s in the <see cref="Channel"/> that are public. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// <see href="https://discord.com/developers/docs/resources/channel#list-public-archived-threads"/> | |||||
/// </remarks> | |||||
/// <param name="channelId"> | |||||
/// The <see cref="Channel"/> identifier. | |||||
/// </param> | |||||
/// <param name="args"> | |||||
/// Parameters to include in the request. | |||||
/// </param> | |||||
/// <param name="cancellationToken"> | |||||
/// Cancellation token for the request. | |||||
/// </param> | |||||
/// <returns> | |||||
/// A task that contains a <see cref="ThreadList"/>. | |||||
/// </returns> | |||||
Task<ThreadList> ListPublicArchivedThreadsAsync(Snowflake channelId, ListPublicArchivedThreadsParams args, CancellationToken cancellationToken = default); | |||||
/// <summary> | |||||
/// Gets archived <see cref="ThreadChannel"/>s in the <see cref="Channel"/> that are private. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// <see href="https://discord.com/developers/docs/resources/channel#list-private-archived-threads"/> | |||||
/// </remarks> | |||||
/// <param name="channelId"> | |||||
/// The <see cref="Channel"/> identifier. | |||||
/// </param> | |||||
/// <param name="args"> | |||||
/// Parameters to include in the request. | |||||
/// </param> | |||||
/// <param name="cancellationToken"> | |||||
/// Cancellation token for the request. | |||||
/// </param> | |||||
/// <returns> | |||||
/// A task that contains a <see cref="ThreadList"/>. | |||||
/// </returns> | |||||
Task<ThreadList> ListPrivateArchivedThreadsAsync(Snowflake channelId, ListPrivateArchivedThreadsParams args, CancellationToken cancellationToken = default); | |||||
/// <summary> | |||||
/// Gets archived <see cref="ThreadChannel"/>s in the <see cref="Channel"/> that are | |||||
/// private and the current user has joined. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// <see href="https://discord.com/developers/docs/resources/channel#list-joined-private-archived-threads"/> | |||||
/// </remarks> | |||||
/// <param name="channelId"> | |||||
/// The <see cref="Channel"/> identifier. | |||||
/// </param> | |||||
/// <param name="args"> | |||||
/// Parameters to include in the request. | |||||
/// </param> | |||||
/// <param name="cancellationToken"> | |||||
/// Cancellation token for the request. | |||||
/// </param> | |||||
/// <returns> | |||||
/// A task that contains a <see cref="ThreadList"/>. | |||||
/// </returns> | |||||
Task<ThreadList> ListJoinedPrivateArchivedThreadsAsync(Snowflake channelId, ListJoinedPrivateArchivedThreadsParams args, CancellationToken cancellationToken = default); | |||||
#endregion Channel | |||||
} | } | ||||
} | } |
@@ -8,7 +8,7 @@ namespace Discord.Net.Rest | |||||
public record GetGuildAuditLogParams | public record GetGuildAuditLogParams | ||||
{ | { | ||||
/// <summary> | /// <summary> | ||||
/// Filter the log for actions made by a user. | |||||
/// Filter the log for actions made by a <see cref="User"/>. | |||||
/// </summary> | /// </summary> | ||||
public Optional<Snowflake> UserId { get; set; } | public Optional<Snowflake> UserId { get; set; } | ||||
@@ -36,6 +36,7 @@ namespace Discord.Net.Rest | |||||
public void Validate() | public void Validate() | ||||
{ | { | ||||
Preconditions.NotZero(UserId, nameof(UserId)); | Preconditions.NotZero(UserId, nameof(UserId)); | ||||
Preconditions.NotZero(Before, nameof(Before)); | |||||
Preconditions.AtLeast(Limit, AuditLog.MinimumGetEntryAmount, nameof(Limit)); | Preconditions.AtLeast(Limit, AuditLog.MinimumGetEntryAmount, nameof(Limit)); | ||||
Preconditions.AtMost(Limit, AuditLog.MaximumGetEntryAmount, nameof(Limit)); | Preconditions.AtMost(Limit, AuditLog.MaximumGetEntryAmount, nameof(Limit)); | ||||
} | } |
@@ -0,0 +1,32 @@ | |||||
using Discord.Net.Models; | |||||
namespace Discord.Net.Rest | |||||
{ | |||||
/// <summary> | |||||
/// Parameters to add to the request. | |||||
/// </summary> | |||||
public record EditChannelPermissionsParams | |||||
{ | |||||
/// <summary> | |||||
/// The bitwise value of all allowed permissions. | |||||
/// </summary> | |||||
public Permissions Allow { get; set; } | |||||
/// <summary> | |||||
/// The bitwise value of all disallowed permissions. | |||||
/// </summary> | |||||
public Permissions Deny { get; set; } | |||||
/// <summary> | |||||
/// Type of overwrite. | |||||
/// </summary> | |||||
public OverwriteType Type { get; set; } | |||||
/// <summary> | |||||
/// Validates the data. | |||||
/// </summary> | |||||
public void Validate() | |||||
{ | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,23 @@ | |||||
using Discord.Net.Models; | |||||
namespace Discord.Net.Rest | |||||
{ | |||||
/// <summary> | |||||
/// Parameters to add to the request. | |||||
/// </summary> | |||||
public record FollowNewsChannelParams | |||||
{ | |||||
/// <summary> | |||||
/// Id of target <see cref="Channel"/>. | |||||
/// </summary> | |||||
public Snowflake WebhookChannelId { get; set; } | |||||
/// <summary> | |||||
/// Validates the data. | |||||
/// </summary> | |||||
public void Validate() | |||||
{ | |||||
Preconditions.NotZero(WebhookChannelId, nameof(WebhookChannelId)); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,28 @@ | |||||
using Discord.Net.Models; | |||||
namespace Discord.Net.Rest | |||||
{ | |||||
/// <summary> | |||||
/// Parameters to add to the request. | |||||
/// </summary> | |||||
public record GroupDMAddRecipientParams | |||||
{ | |||||
/// <summary> | |||||
/// Access token of a <see cref="User"/> that has granted your app the gdm.join scope. | |||||
/// </summary> | |||||
public string? AccessToken { get; set; } // Required property candidate | |||||
/// <summary> | |||||
/// Nickname of the <see cref="User"/> being added. | |||||
/// </summary> | |||||
public string? Nick { get; set; } // Required property candidate | |||||
/// <summary> | |||||
/// Validates the data. | |||||
/// </summary> | |||||
public void Validate() | |||||
{ | |||||
Preconditions.NotNullOrEmpty(AccessToken, nameof(AccessToken)); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,27 @@ | |||||
namespace Discord.Net.Rest | |||||
{ | |||||
/// <summary> | |||||
/// Parameters to add to the request. | |||||
/// </summary> | |||||
public record ListJoinedPrivateArchivedThreadsParams | |||||
{ | |||||
/// <summary> | |||||
/// Returns threads before this id. | |||||
/// </summary> | |||||
public Optional<Snowflake> Before { get; set; } | |||||
/// <summary> | |||||
/// Maximum number of threads to return. | |||||
/// </summary> | |||||
public Optional<int> Limit { get; set; } | |||||
/// <summary> | |||||
/// Validates the data. | |||||
/// </summary> | |||||
public void Validate() | |||||
{ | |||||
Preconditions.NotZero(Before, nameof(Before)); | |||||
Preconditions.NotZero(Limit, nameof(Limit)); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,28 @@ | |||||
using System; | |||||
namespace Discord.Net.Rest | |||||
{ | |||||
/// <summary> | |||||
/// Parameters to add to the request. | |||||
/// </summary> | |||||
public record ListPrivateArchivedThreadsParams | |||||
{ | |||||
/// <summary> | |||||
/// Returns threads before this timestamp. | |||||
/// </summary> | |||||
public Optional<DateTimeOffset> Before { get; set; } | |||||
/// <summary> | |||||
/// Maximum number of threads to return. | |||||
/// </summary> | |||||
public Optional<int> Limit { get; set; } | |||||
/// <summary> | |||||
/// Validates the data. | |||||
/// </summary> | |||||
public void Validate() | |||||
{ | |||||
Preconditions.NotZero(Limit, nameof(Limit)); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,28 @@ | |||||
using System; | |||||
namespace Discord.Net.Rest | |||||
{ | |||||
/// <summary> | |||||
/// Parameters to add to the request. | |||||
/// </summary> | |||||
public record ListPublicArchivedThreadsParams | |||||
{ | |||||
/// <summary> | |||||
/// Returns threads before this timestamp. | |||||
/// </summary> | |||||
public Optional<DateTimeOffset> Before { get; set; } | |||||
/// <summary> | |||||
/// Maximum number of threads to return. | |||||
/// </summary> | |||||
public Optional<int> Limit { get; set; } | |||||
/// <summary> | |||||
/// Validates the data. | |||||
/// </summary> | |||||
public void Validate() | |||||
{ | |||||
Preconditions.NotZero(Limit, nameof(Limit)); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,33 @@ | |||||
using Discord.Net.Models; | |||||
namespace Discord.Net.Rest | |||||
{ | |||||
/// <summary> | |||||
/// Parameters to include in a request to modify a <see cref="GroupChannel"/>. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// <see href="https://discord.com/developers/docs/resources/channel#modify-channel-json-params-group-dm"/> | |||||
/// </remarks> | |||||
public record ModifyGroupChannelParams | |||||
{ | |||||
/// <summary> | |||||
/// <see cref="Channel"/> name. | |||||
/// </summary> | |||||
public Optional<string> Name { get; set; } | |||||
/// <summary> | |||||
/// Base64 encoded icon. | |||||
/// </summary> | |||||
public Optional<string> Icon { get; set; } | |||||
/// <summary> | |||||
/// Validates the data. | |||||
/// </summary> | |||||
public void Validate() | |||||
{ | |||||
Preconditions.NotNullOrWhitespace(Name!, nameof(Name)); | |||||
Preconditions.LengthAtLeast(Name!, Channel.MinChannelNameLength, nameof(Name)); | |||||
Preconditions.LengthAtMost(Name!, Channel.MaxChannelNameLength, nameof(Name)); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,101 @@ | |||||
using Discord.Net.Models; | |||||
namespace Discord.Net.Rest | |||||
{ | |||||
/// <summary> | |||||
/// Parameters to include in a request to modify a <see cref="GuildChannel"/>. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// <see href="https://discord.com/developers/docs/resources/channel#modify-channel-json-params-guild-channel"/> | |||||
/// </remarks> | |||||
public record ModifyGuildChannelParams | |||||
{ | |||||
/// <summary> | |||||
/// <see cref="Channel"/> name. | |||||
/// </summary> | |||||
public Optional<string> Name { get; set; } | |||||
/// <summary> | |||||
/// The type of <see cref="Channel"/>. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// Only conversion between text and news is supported and only in guilds with the "NEWS" feature. | |||||
/// </remarks> | |||||
public Optional<ChannelType> Type { get; set; } | |||||
/// <summary> | |||||
/// The position of the <see cref="Channel"/> in the left-hand listing. | |||||
/// </summary> | |||||
public Optional<int?> Position { get; set; } | |||||
/// <summary> | |||||
/// <see cref="Channel"/> topic. | |||||
/// </summary> | |||||
public Optional<string?> Topic { get; set; } | |||||
/// <summary> | |||||
/// Whether the <see cref="Channel"/> is nsfw. | |||||
/// </summary> | |||||
public Optional<bool?> Nsfw { get; set; } | |||||
/// <summary> | |||||
/// Amount of seconds a <see cref="User"/> has to wait before sending another message; | |||||
/// bots, as well as <see cref="User"/>s with the permission <see cref="Permissions.ManageMessages"/> | |||||
/// or <see cref="Permissions.ManageChannels"/>, are unaffected. | |||||
/// </summary> | |||||
public Optional<int?> RateLimitPerUser { get; set; } | |||||
/// <summary> | |||||
/// The bitrate (in bits) of the <see cref="VoiceChannel"/>. | |||||
/// </summary> | |||||
public Optional<int?> Bitrate { get; set; } | |||||
/// <summary> | |||||
/// The <see cref="User"/> limit of the <see cref="VoiceChannel"/>; 0 refers to no limit, | |||||
/// 1 to 99 refers to a <see cref="User"/> limit. | |||||
/// </summary> | |||||
public Optional<int?> UserLimit { get; set; } | |||||
/// <summary> | |||||
/// <see cref="Channel"/> or category-specific permissions. | |||||
/// </summary> | |||||
public Optional<Overwrite[]?> PermissionOverwrites { get; set; } | |||||
/// <summary> | |||||
/// Id of the new parent <see cref="CategoryChannel"/> for a <see cref="Channel"/>. | |||||
/// </summary> | |||||
public Optional<Snowflake?> ParentId { get; set; } | |||||
/// <summary> | |||||
/// <see cref="Channel"/> voice region id, automatic when set to <see langword="null"/>. | |||||
/// </summary> | |||||
public Optional<string?> RtcRegion { get; set; } | |||||
/// <summary> | |||||
/// The camera video quality mode of the <see cref="VoiceChannel"/>. | |||||
/// </summary> | |||||
public Optional<int?> VideoQualityMode { get; set; } | |||||
/// <summary> | |||||
/// Validates the data. | |||||
/// </summary> | |||||
public void Validate() | |||||
{ | |||||
Preconditions.NotNullOrWhitespace(Name!, nameof(Name)); | |||||
Preconditions.LengthAtLeast(Name!, Channel.MinChannelNameLength, nameof(Name)); | |||||
Preconditions.LengthAtMost(Name!, Channel.MaxChannelNameLength, nameof(Name)); | |||||
Preconditions.MustBeOneOf(Type, new[] { ChannelType.GuildText, ChannelType.GuildNews }, nameof(Type)); | |||||
Preconditions.NotNegative(Position, nameof(Position)); | |||||
Preconditions.NotNull(Topic, nameof(Topic)); | |||||
Preconditions.LengthAtLeast(Topic, Channel.MinChannelTopicLength, nameof(Topic)); | |||||
Preconditions.LengthAtMost(Topic, Channel.MaxChannelTopicLength, nameof(Topic)); | |||||
Preconditions.AtLeast(RateLimitPerUser, Channel.MinRateLimitPerUserDuration, nameof(RateLimitPerUser)); | |||||
Preconditions.AtMost(RateLimitPerUser, Channel.MaxRateLimitPerUserDuration, nameof(RateLimitPerUser)); | |||||
Preconditions.AtLeast(Bitrate, Channel.MinBitrate, nameof(Bitrate)); | |||||
Preconditions.AtMost(Bitrate, Channel.MaxBitrate, nameof(Bitrate)); | |||||
Preconditions.AtLeast(UserLimit, Channel.MinUserLimit, nameof(UserLimit)); | |||||
Preconditions.AtMost(UserLimit, Channel.MaxUserLimit, nameof(UserLimit)); | |||||
Preconditions.NotNull(PermissionOverwrites, nameof(PermissionOverwrites)); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,57 @@ | |||||
using Discord.Net.Models; | |||||
namespace Discord.Net.Rest | |||||
{ | |||||
/// <summary> | |||||
/// Parameters to include in a request to modify a <see cref="ThreadChannel"/>. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// <see href="https://discord.com/developers/docs/resources/channel#modify-channel-json-params-guild-channel"/> | |||||
/// </remarks> | |||||
public record ModifyThreadChannelParams | |||||
{ | |||||
/// <summary> | |||||
/// <see cref="ThreadChannel"/> name. | |||||
/// </summary> | |||||
public Optional<string> Name { get; set; } | |||||
/// <summary> | |||||
/// Whether the <see cref="ThreadChannel"/> is archived. | |||||
/// </summary> | |||||
public Optional<bool> Archived { get; set; } | |||||
/// <summary> | |||||
/// Duration in minutes to automatically archive the <see cref="ThreadChannel"/> after recent activity. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// Can be set to 60, 1440, 4320, or 10080. | |||||
/// </remarks> | |||||
public Optional<int> AutoArchiveDuration { get; set; } | |||||
/// <summary> | |||||
/// When a <see cref="ThreadChannel"/> is locked, only <see cref="User"/>s with | |||||
/// <see cref="Permissions.ManageThreads"/> can unarchive it. | |||||
/// </summary> | |||||
public Optional<bool> Locked { get; set; } | |||||
/// <summary> | |||||
/// Amount of seconds a <see cref="User"/> has to wait before sending another message; | |||||
/// bots, as well as <see cref="User"/>s with the permission <see cref="Permissions.ManageMessages"/>, | |||||
/// <see cref="Permissions.ManageThreads"/>, or <see cref="Permissions.ManageChannels"/>, are unaffected. | |||||
/// </summary> | |||||
public Optional<int?> RateLimitPerUser { get; set; } | |||||
/// <summary> | |||||
/// Validates the data. | |||||
/// </summary> | |||||
public void Validate() | |||||
{ | |||||
Preconditions.NotNullOrWhitespace(Name!, nameof(Name)); | |||||
Preconditions.LengthAtLeast(Name!, Channel.MinChannelNameLength, nameof(Name)); | |||||
Preconditions.LengthAtMost(Name!, Channel.MaxChannelNameLength, nameof(Name)); | |||||
Preconditions.MustBeOneOf(AutoArchiveDuration, new[] { 60, 1440, 4320, 10080 }, nameof(AutoArchiveDuration)); | |||||
Preconditions.AtLeast(RateLimitPerUser, Channel.MinRateLimitPerUserDuration, nameof(RateLimitPerUser)); | |||||
Preconditions.AtMost(RateLimitPerUser, Channel.MaxRateLimitPerUserDuration, nameof(RateLimitPerUser)); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,37 @@ | |||||
using Discord.Net.Models; | |||||
namespace Discord.Net.Rest | |||||
{ | |||||
/// <summary> | |||||
/// Parameters to add to the request. | |||||
/// </summary> | |||||
public record StartThreadWithMessageParams | |||||
{ | |||||
/// <summary> | |||||
/// <see cref="ThreadChannel"/> name. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// Must be between 1-100, inclusive. | |||||
/// </remarks> | |||||
public string? Name { get; set; } // Required property candidate | |||||
/// <summary> | |||||
/// Duration in minutes to automatically archive the thread after recent activity. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// Can be set to: 60, 1440, 4320, 10080. | |||||
/// </remarks> | |||||
public int AutoArchiveDuration { get; set; } | |||||
/// <summary> | |||||
/// Validates the data. | |||||
/// </summary> | |||||
public void Validate() | |||||
{ | |||||
Preconditions.NotNullOrWhitespace(Name!, nameof(Name)); | |||||
Preconditions.LengthAtLeast(Name!, Channel.MinChannelNameLength, nameof(Name)); | |||||
Preconditions.LengthAtMost(Name!, Channel.MaxChannelNameLength, nameof(Name)); | |||||
Preconditions.MustBeOneOf(AutoArchiveDuration, new[] { 60, 1440, 4320, 10080 }, nameof(AutoArchiveDuration)); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,37 @@ | |||||
using Discord.Net.Models; | |||||
namespace Discord.Net.Rest | |||||
{ | |||||
/// <summary> | |||||
/// Parameters to add to the request. | |||||
/// </summary> | |||||
public record StartThreadWithoutMessageParams | |||||
{ | |||||
/// <summary> | |||||
/// <see cref="ThreadChannel"/> name. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// Must be between 1-100, inclusive. | |||||
/// </remarks> | |||||
public string? Name { get; set; } // Required property candidate | |||||
/// <summary> | |||||
/// Duration in minutes to automatically archive the thread after recent activity. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// Can be set to: 60, 1440, 4320, 10080. | |||||
/// </remarks> | |||||
public int AutoArchiveDuration { get; set; } | |||||
/// <summary> | |||||
/// Validates the data. | |||||
/// </summary> | |||||
public void Validate() | |||||
{ | |||||
Preconditions.NotNullOrWhitespace(Name!, nameof(Name)); | |||||
Preconditions.LengthAtLeast(Name!, Channel.MinChannelNameLength, nameof(Name)); | |||||
Preconditions.LengthAtMost(Name!, Channel.MaxChannelNameLength, nameof(Name)); | |||||
Preconditions.MustBeOneOf(AutoArchiveDuration, new[] { 60, 1440, 4320, 10080 }, nameof(AutoArchiveDuration)); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,73 @@ | |||||
using Discord.Net.Models; | |||||
namespace Discord.Net.Rest | |||||
{ | |||||
/// <summary> | |||||
/// Parameters to add to the request. | |||||
/// </summary> | |||||
public record CreateChannelInviteParams | |||||
{ | |||||
/// <summary> | |||||
/// Duration of <see cref="Invite"/> in seconds before expiry. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// Must be between 0 and 604800 (7 days), inclusive. Zero means never. | |||||
/// </remarks> | |||||
public Optional<int> MaxAge { get; set; } | |||||
/// <summary> | |||||
/// Maximum number of uses. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// Must be between 0 and 100, inclusive. Zero means unlimited. | |||||
/// </remarks> | |||||
public Optional<int> MaxUses { get; set; } | |||||
/// <summary> | |||||
/// Whether this <see cref="Invite"/> only grants temporary membership. | |||||
/// </summary> | |||||
public Optional<bool> Temporary { get; set; } | |||||
/// <summary> | |||||
/// If true, don't try to reuse a similar <see cref="Invite"/> (useful for | |||||
/// creating many unique one time use invites). | |||||
/// </summary> | |||||
public Optional<bool> Unique { get; set; } | |||||
/// <summary> | |||||
/// The type of target for this <see cref="VoiceChannel"/> <see cref="Invite"/>. | |||||
/// </summary> | |||||
public Optional<InviteTargetType> TargetType { get; set; } | |||||
/// <summary> | |||||
/// The id of the <see cref="User"/> whose stream to display for this <see cref="Invite"/>. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// Required if <see cref="TargetType"/> is <see cref="InviteTargetType.Stream"/>, | |||||
/// the <see cref="User"/> must be streaming in the <see cref="Channel"/>. | |||||
/// </remarks> | |||||
public Optional<Snowflake> TargetUserId { get; set; } | |||||
/// <summary> | |||||
/// The id of the embedded application to open for this <see cref="Invite"/>. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// Required if <see cref="TargetType"/> is <see cref="InviteTargetType.EmbeddedApplication"/>, | |||||
/// the application must have the <see cref="ApplicationFlags.Embedded"/> flag. | |||||
/// </remarks> | |||||
public Optional<Snowflake> TargetApplicationId { get; set; } | |||||
/// <summary> | |||||
/// Validates the data. | |||||
/// </summary> | |||||
public void Validate() | |||||
{ | |||||
Preconditions.AtLeast(MaxAge, InviteWithMetadata.MinAgeTime, nameof(MaxAge)); | |||||
Preconditions.AtMost(MaxAge, InviteWithMetadata.MaxAgeTime, nameof(MaxAge)); | |||||
Preconditions.AtLeast(MaxUses, InviteWithMetadata.MinUseCount, nameof(MaxUses)); | |||||
Preconditions.AtMost(MaxUses, InviteWithMetadata.MaxUseCount, nameof(MaxUses)); | |||||
Preconditions.NotZero(TargetUserId, nameof(TargetUserId)); | |||||
Preconditions.NotZero(TargetApplicationId, nameof(TargetApplicationId)); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,27 @@ | |||||
using Discord.Net.Models; | |||||
namespace Discord.Net.Rest | |||||
{ | |||||
/// <summary> | |||||
/// Parameters to add to the request. | |||||
/// </summary> | |||||
public record BulkDeleteMessagesParams | |||||
{ | |||||
/// <summary> | |||||
/// An array of <see cref="Message"/> ids to delete. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// Length must be between 2 and 100, inclusive. | |||||
/// </remarks> | |||||
public Snowflake[]? Messages { get; set; } // Required property candidate | |||||
/// <summary> | |||||
/// Validates the data. | |||||
/// </summary> | |||||
public void Validate() | |||||
{ | |||||
Preconditions.LengthAtLeast(Messages!, Message.MinBulkDeleteAmount, nameof(Messages)); | |||||
Preconditions.LengthAtMost(Messages!, Message.MaxBulkDeleteAmount, nameof(Messages)); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,71 @@ | |||||
using Discord.Net.Models; | |||||
namespace Discord.Net.Rest | |||||
{ | |||||
/// <summary> | |||||
/// Parameters to include in a request to create a <see cref="Message"/>. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// <see href="https://discord.com/developers/docs/resources/channel#create-message-jsonform-params"/> | |||||
/// </remarks> | |||||
public record CreateMessageParams | |||||
{ | |||||
/// <summary> | |||||
/// The <see cref="Message"/> content. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// Up to 2000 characters. | |||||
/// </remarks> | |||||
public Optional<string> Content { get; set; } | |||||
/// <summary> | |||||
/// Set the <see cref="Message"/> as a TTS one. | |||||
/// </summary> | |||||
public Optional<bool> Tts { get; set; } | |||||
/// <summary> | |||||
/// The contents of the file being sent. | |||||
/// </summary> | |||||
public Optional<MultipartFile> File { get; set; } | |||||
/// <summary> | |||||
/// Array of <see cref="Embed"/>s to include with the <see cref="Message"/>. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// Up to 10 <see cref="Embed"/>s. | |||||
/// </remarks> | |||||
public Optional<Embed[]> Embeds { get; set; } | |||||
/// <summary> | |||||
/// JSON encoded body of non-file params. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// Multipart/form-data only. | |||||
/// </remarks> | |||||
public Optional<CreateMessageParams> PayloadJson { get; set; } // TODO: Should change this to an easy way to convert to form data. | |||||
/// <summary> | |||||
/// Allowed mentions for the <see cref="Message"/>. | |||||
/// </summary> | |||||
public Optional<AllowedMentions> AlloweMentions { get; set; } | |||||
/// <summary> | |||||
/// Include to make your <see cref="Message"/> a reply. | |||||
/// </summary> | |||||
public Optional<MessageReference> MessageReference { get; set; } | |||||
/// <summary> | |||||
/// The <see cref="Component"/>s to include with the <see cref="Message"/>. | |||||
/// </summary> | |||||
public Optional<Component[]> Components { get; set; } | |||||
/// <summary> | |||||
/// Validates the data. | |||||
/// </summary> | |||||
public void Validate() | |||||
{ | |||||
Preconditions.LengthAtMost(Content!, Message.MaxContentLength, nameof(Content)); | |||||
Preconditions.LengthAtMost(Embeds!, Message.MaxEmbeds, nameof(Embeds)); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,74 @@ | |||||
using Discord.Net.Models; | |||||
namespace Discord.Net.Rest | |||||
{ | |||||
/// <summary> | |||||
/// Parameters to include in a request to edit a <see cref="Message"/>. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// <see href="https://discord.com/developers/docs/resources/channel#edit-message-jsonform-params"/> | |||||
/// </remarks> | |||||
public record EditMessageParams | |||||
{ | |||||
/// <summary> | |||||
/// The <see cref="Message"/> content. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// Up to 2000 characters. | |||||
/// </remarks> | |||||
public Optional<string?> Content { get; set; } | |||||
/// <summary> | |||||
/// Array of <see cref="Embed"/>s to include with the <see cref="Message"/>. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// Up to 10 <see cref="Embed"/>s. | |||||
/// </remarks> | |||||
public Optional<Embed[]?> Embeds { get; set; } | |||||
/// <summary> | |||||
/// Edit the <see cref="MessageFlags"/> of a <see cref="Message"/>. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// Only <see cref="MessageFlags.SuppressEmbeds"/> can currently be set/unset. | |||||
/// </remarks> | |||||
public Optional<MessageFlags?> Flags { get; set; } | |||||
/// <summary> | |||||
/// The contents of the file being sent. | |||||
/// </summary> | |||||
public Optional<MultipartFile?> File { get; set; } | |||||
/// <summary> | |||||
/// JSON encoded body of non-file params. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// Multipart/form-data only. | |||||
/// </remarks> | |||||
public Optional<CreateMessageParams?> PayloadJson { get; set; } // TODO: Should change this to an easy way to convert to form data. | |||||
/// <summary> | |||||
/// Attached files to keep. | |||||
/// </summary> | |||||
public Optional<Attachment[]?> Attachments { get; set; } | |||||
/// <summary> | |||||
/// Allowed mentions for the <see cref="Message"/>. | |||||
/// </summary> | |||||
public Optional<AllowedMentions?> AlloweMentions { get; set; } | |||||
/// <summary> | |||||
/// The <see cref="Component"/>s to include with the <see cref="Message"/>. | |||||
/// </summary> | |||||
public Optional<Component[]?> Components { get; set; } | |||||
/// <summary> | |||||
/// Validates the data. | |||||
/// </summary> | |||||
public void Validate() | |||||
{ | |||||
Preconditions.LengthAtMost(Content!, Message.MaxContentLength, nameof(Content)); | |||||
Preconditions.LengthAtMost(Embeds, Message.MaxEmbeds, nameof(Embeds)); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,44 @@ | |||||
using Discord.Net.Models; | |||||
namespace Discord.Net.Rest | |||||
{ | |||||
/// <summary> | |||||
/// Parameters to add to the request. | |||||
/// </summary> | |||||
public record GetChannelMessagesParams | |||||
{ | |||||
/// <summary> | |||||
/// Get <see cref="Message"/>s around this <see cref="Message"/> ID. | |||||
/// </summary> | |||||
public Optional<Snowflake> Around { get; set; } | |||||
/// <summary> | |||||
/// Get <see cref="Message"/>s before this <see cref="Message"/> ID. | |||||
/// </summary> | |||||
public Optional<Snowflake> Before { get; set; } | |||||
/// <summary> | |||||
/// Get <see cref="Message"/>s after this <see cref="Message"/> ID. | |||||
/// </summary> | |||||
public Optional<Snowflake> After { get; set; } | |||||
/// <summary> | |||||
/// Maximum number of <see cref="Message"/>s to return. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// Default: 50. Acceptable range: 1-100, inclusive. | |||||
/// </remarks> | |||||
public Optional<int> Limit { get; set; } | |||||
/// <summary> | |||||
/// Validates the data. | |||||
/// </summary> | |||||
public void Validate() | |||||
{ | |||||
Preconditions.NotZero(Before, nameof(Before)); | |||||
Preconditions.Exclusive(new[] { Around, Before, After }, new[] { nameof(Around), nameof(Before), nameof(After) }); | |||||
Preconditions.AtLeast(Limit, Channel.MinGetMessagesAmount, nameof(Limit)); | |||||
Preconditions.AtMost(Limit, Channel.MaxGetMessagesAmount, nameof(Limit)); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,33 @@ | |||||
using Discord.Net.Models; | |||||
namespace Discord.Net.Rest | |||||
{ | |||||
/// <summary> | |||||
/// Parameters to add to the request. | |||||
/// </summary> | |||||
public record GetReactionsParams | |||||
{ | |||||
/// <summary> | |||||
/// Get <see cref="User"/>s after this <see cref="User"/> ID. | |||||
/// </summary> | |||||
public Optional<Snowflake> After { get; set; } | |||||
/// <summary> | |||||
/// Maximum number of <see cref="User"/>s to return. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// Default: 25. Acceptable range: 1-100, inclusive. | |||||
/// </remarks> | |||||
public Optional<int> Limit { get; set; } | |||||
/// <summary> | |||||
/// Validates the data. | |||||
/// </summary> | |||||
public void Validate() | |||||
{ | |||||
Preconditions.NotZero(After, nameof(After)); | |||||
Preconditions.AtLeast(Limit, Reaction.MinGetReactionsAmount, nameof(Limit)); | |||||
Preconditions.AtMost(Limit, Reaction.MaxGetReactionsAmount, nameof(Limit)); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,20 @@ | |||||
using System.IO; | |||||
namespace Discord.Net.Rest | |||||
{ | |||||
/// <summary> | |||||
/// Represents a multipart file to send in a request. | |||||
/// </summary> | |||||
public record MultipartFile | |||||
{ | |||||
/// <summary> | |||||
/// The file stream. | |||||
/// </summary> | |||||
public Stream? Stream { get; set; } // Required property candidate | |||||
/// <summary> | |||||
/// The file name. | |||||
/// </summary> | |||||
public string? Filename { get; set; } // Required property candidate | |||||
} | |||||
} |
@@ -0,0 +1,30 @@ | |||||
using Discord.Net.Models; | |||||
namespace Discord.Net.Rest | |||||
{ | |||||
/// <summary> | |||||
/// Represents a response to list <see cref="ThreadChannel"/>s. | |||||
/// </summary> | |||||
/// <remarks> | |||||
/// <see href="https://discord.com/developers/docs/resources/channel#list-active-threads-response-body"/> | |||||
/// </remarks> | |||||
public record ThreadList | |||||
{ | |||||
/// <summary> | |||||
/// Array of <see cref="ThreadChannel"/>s returned. | |||||
/// </summary> | |||||
public ThreadChannel[]? Threads { get; init; } // Required property candidate | |||||
/// <summary> | |||||
/// Array of <see cref="ThreadMember"/>s for each returned thread the current | |||||
/// user has joined. | |||||
/// </summary> | |||||
public ThreadMember[]? Members { get; init; } // Required property candidate | |||||
/// <summary> | |||||
/// Whether there are potentially additional <see cref="ThreadChannel"/>s that | |||||
/// could be returned on a subsequent call. | |||||
/// </summary> | |||||
public bool HasMore { get; init; } | |||||
} | |||||
} |
@@ -1,4 +1,6 @@ | |||||
using System; | using System; | ||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
namespace Discord.Net.Rest | namespace Discord.Net.Rest | ||||
{ | { | ||||
@@ -6,8 +8,8 @@ namespace Discord.Net.Rest | |||||
{ | { | ||||
// Objects | // Objects | ||||
public static void NotNull<T>(T obj, string name, string? msg = null) where T : class { if (obj == null) throw CreateNotNullException(name, msg); } | |||||
public static void NotNull<T>(Optional<T> obj, string name, string? msg = null) where T : class { if (obj.IsSpecified && obj.Value == null) throw CreateNotNullException(name, msg); } | |||||
public static void NotNull<T>(T? obj, string name, string? msg = null) where T : class { if (obj == null) throw CreateNotNullException(name, msg); } | |||||
public static void NotNull<T>(Optional<T?> obj, string name, string? msg = null) where T : class { if (obj.IsSpecified && obj.Value == null) throw CreateNotNullException(name, msg); } | |||||
private static ArgumentNullException CreateNotNullException(string name, string? msg) | private static ArgumentNullException CreateNotNullException(string name, string? msg) | ||||
{ | { | ||||
@@ -17,6 +19,27 @@ namespace Discord.Net.Rest | |||||
return new ArgumentNullException(name, msg); | return new ArgumentNullException(name, msg); | ||||
} | } | ||||
public static void LengthAtLeast<T>(T[]? obj, int value, string name, string? msg = null) | |||||
{ | |||||
if (obj?.Length < value) | |||||
{ | |||||
if (msg == null) | |||||
throw new ArgumentException($"Length must be at least {value}", name); | |||||
else | |||||
throw new ArgumentException(msg, name); | |||||
} | |||||
} | |||||
public static void LengthAtMost<T>(T[]? obj, int value, string name, string? msg = null) | |||||
{ | |||||
if (obj?.Length > value) | |||||
{ | |||||
if (msg == null) | |||||
throw new ArgumentException($"Length must be at most {value}", name); | |||||
else | |||||
throw new ArgumentException(msg, name); | |||||
} | |||||
} | |||||
// Optionals | // Optionals | ||||
public static void Exclusive<T>(Optional<T>[] objs, string[] names, string? msg = null) | public static void Exclusive<T>(Optional<T>[] objs, string[] names, string? msg = null) | ||||
@@ -36,18 +59,39 @@ namespace Discord.Net.Rest | |||||
} | } | ||||
} | } | ||||
public static void LengthAtLeast<T>(Optional<T[]?> obj, int value, string name, string? msg = null) | |||||
{ | |||||
if (obj.IsSpecified && obj.Value?.Length < value) | |||||
{ | |||||
if (msg == null) | |||||
throw new ArgumentException($"Length must be at least {value}", name); | |||||
else | |||||
throw new ArgumentException(msg, name); | |||||
} | |||||
} | |||||
public static void LengthAtMost<T>(Optional<T[]?> obj, int value, string name, string? msg = null) | |||||
{ | |||||
if (obj.IsSpecified && obj.Value?.Length > value) | |||||
{ | |||||
if (msg == null) | |||||
throw new ArgumentException($"Length must be at most {value}", name); | |||||
else | |||||
throw new ArgumentException(msg, name); | |||||
} | |||||
} | |||||
// Strings | // Strings | ||||
public static void NotEmpty(string obj, string name, string? msg = null) { if (obj != null && obj.Length == 0) throw CreateNotEmptyException(name, msg); } | |||||
public static void NotEmpty(Optional<string> obj, string name, string? msg = null) { if (obj.IsSpecified && obj.Value != null && obj.Value.Length == 0) throw CreateNotEmptyException(name, msg); } | |||||
public static void NotNullOrEmpty(string obj, string name, string? msg = null) | |||||
public static void NotEmpty(string? obj, string name, string? msg = null) { if (obj != null && obj.Length == 0) throw CreateNotEmptyException(name, msg); } | |||||
public static void NotEmpty(Optional<string?> obj, string name, string? msg = null) { if (obj.IsSpecified && obj.Value != null && obj.Value.Length == 0) throw CreateNotEmptyException(name, msg); } | |||||
public static void NotNullOrEmpty(string? obj, string name, string? msg = null) | |||||
{ | { | ||||
if (obj == null) | if (obj == null) | ||||
throw CreateNotNullException(name, msg); | throw CreateNotNullException(name, msg); | ||||
if (obj.Length == 0) | if (obj.Length == 0) | ||||
throw CreateNotEmptyException(name, msg); | throw CreateNotEmptyException(name, msg); | ||||
} | } | ||||
public static void NotNullOrEmpty(Optional<string> obj, string name, string? msg = null) | |||||
public static void NotNullOrEmpty(Optional<string?> obj, string name, string? msg = null) | |||||
{ | { | ||||
if (obj.IsSpecified) | if (obj.IsSpecified) | ||||
{ | { | ||||
@@ -57,14 +101,14 @@ namespace Discord.Net.Rest | |||||
throw CreateNotEmptyException(name, msg); | throw CreateNotEmptyException(name, msg); | ||||
} | } | ||||
} | } | ||||
public static void NotNullOrWhitespace(string obj, string name, string? msg = null) | |||||
public static void NotNullOrWhitespace(string? obj, string name, string? msg = null) | |||||
{ | { | ||||
if (obj == null) | if (obj == null) | ||||
throw CreateNotNullException(name, msg); | throw CreateNotNullException(name, msg); | ||||
if (obj.Trim().Length == 0) | if (obj.Trim().Length == 0) | ||||
throw CreateNotEmptyException(name, msg); | throw CreateNotEmptyException(name, msg); | ||||
} | } | ||||
public static void NotNullOrWhitespace(Optional<string> obj, string name, string? msg = null) | |||||
public static void NotNullOrWhitespace(Optional<string?> obj, string name, string? msg = null) | |||||
{ | { | ||||
if (obj.IsSpecified) | if (obj.IsSpecified) | ||||
{ | { | ||||
@@ -75,7 +119,7 @@ namespace Discord.Net.Rest | |||||
} | } | ||||
} | } | ||||
public static void LengthAtLeast(string obj, int value, string name, string? msg = null) | |||||
public static void LengthAtLeast(string? obj, int value, string name, string? msg = null) | |||||
{ | { | ||||
if (obj?.Length < value) | if (obj?.Length < value) | ||||
{ | { | ||||
@@ -85,7 +129,7 @@ namespace Discord.Net.Rest | |||||
throw new ArgumentException(msg, name); | throw new ArgumentException(msg, name); | ||||
} | } | ||||
} | } | ||||
public static void LengthAtMost(string obj, int value, string name, string? msg = null) | |||||
public static void LengthAtMost(string? obj, int value, string name, string? msg = null) | |||||
{ | { | ||||
if (obj?.Length > value) | if (obj?.Length > value) | ||||
{ | { | ||||
@@ -95,7 +139,7 @@ namespace Discord.Net.Rest | |||||
throw new ArgumentException(msg, name); | throw new ArgumentException(msg, name); | ||||
} | } | ||||
} | } | ||||
public static void LengthGreaterThan(string obj, int value, string name, string? msg = null) | |||||
public static void LengthGreaterThan(string? obj, int value, string name, string? msg = null) | |||||
{ | { | ||||
if (obj?.Length <= value) | if (obj?.Length <= value) | ||||
{ | { | ||||
@@ -105,7 +149,7 @@ namespace Discord.Net.Rest | |||||
throw new ArgumentException(msg, name); | throw new ArgumentException(msg, name); | ||||
} | } | ||||
} | } | ||||
public static void LengthLessThan(string obj, int value, string name, string? msg = null) | |||||
public static void LengthLessThan(string? obj, int value, string name, string? msg = null) | |||||
{ | { | ||||
if (obj?.Length >= value) | if (obj?.Length >= value) | ||||
{ | { | ||||
@@ -115,25 +159,25 @@ namespace Discord.Net.Rest | |||||
throw new ArgumentException(msg, name); | throw new ArgumentException(msg, name); | ||||
} | } | ||||
} | } | ||||
public static void LengthAtLeast(Optional<string> obj, int value, string name, string? msg = null) | |||||
public static void LengthAtLeast(Optional<string?> obj, int value, string name, string? msg = null) | |||||
{ | { | ||||
if (!obj.IsSpecified) | if (!obj.IsSpecified) | ||||
return; | return; | ||||
LengthAtLeast(obj.Value, value, name, msg); | LengthAtLeast(obj.Value, value, name, msg); | ||||
} | } | ||||
public static void LengthAtMost(Optional<string> obj, int value, string name, string? msg = null) | |||||
public static void LengthAtMost(Optional<string?> obj, int value, string name, string? msg = null) | |||||
{ | { | ||||
if (!obj.IsSpecified) | if (!obj.IsSpecified) | ||||
return; | return; | ||||
LengthAtMost(obj.Value, value, name, msg); | LengthAtMost(obj.Value, value, name, msg); | ||||
} | } | ||||
public static void LengthGreaterThan(Optional<string> obj, int value, string name, string? msg = null) | |||||
public static void LengthGreaterThan(Optional<string?> obj, int value, string name, string? msg = null) | |||||
{ | { | ||||
if (!obj.IsSpecified) | if (!obj.IsSpecified) | ||||
return; | return; | ||||
LengthGreaterThan(obj.Value, value, name, msg); | LengthGreaterThan(obj.Value, value, name, msg); | ||||
} | } | ||||
public static void LengthLessThan(Optional<string> obj, int value, string name, string? msg = null) | |||||
public static void LengthLessThan(Optional<string?> obj, int value, string name, string? msg = null) | |||||
{ | { | ||||
if (!obj.IsSpecified) | if (!obj.IsSpecified) | ||||
return; | return; | ||||
@@ -558,5 +602,31 @@ namespace Discord.Net.Rest | |||||
throw new ArgumentOutOfRangeException(name, msg); | throw new ArgumentOutOfRangeException(name, msg); | ||||
} | } | ||||
} | } | ||||
// Structs | |||||
public static void MustBeOneOf<T>(T value, IEnumerable<T> allowed, string name, string? msg = null) | |||||
where T : struct | |||||
{ | |||||
if (!allowed.Contains(value)) | |||||
throw CreateMustBeOneOfException(name, msg, allowed); | |||||
} | |||||
public static void MustBeOneOf<T>(Optional<T> value, IEnumerable<T> allowed, string name, string? msg = null) | |||||
where T : struct | |||||
{ | |||||
if (value.IsSpecified && !allowed.Contains(value.Value)) | |||||
throw CreateMustBeOneOfException(name, msg, allowed); | |||||
} | |||||
private static ArgumentException CreateMustBeOneOfException<T>(string name, string? msg, IEnumerable<T> value) | |||||
where T : struct | |||||
{ | |||||
if (msg == null) | |||||
{ | |||||
var options = typeof(T).IsEnum ? string.Join(", ", value.Select(x => Enum.GetName(typeof(T), x))) : string.Join(", ", value); | |||||
return new ArgumentException($"Value must be one of the following: {options}", name); | |||||
} | |||||
else | |||||
return new ArgumentException(msg, name); | |||||
} | |||||
} | } | ||||
} | } |