@@ -147,17 +147,17 @@ namespace Discord.Net.Models | |||
// | |||
/// <summary> | |||
/// Text or voice <see cref="Channel"/> position changed. | |||
/// <see cref="GuildTextChannel"/> or <see cref="VoiceChannel"/> position changed. | |||
/// </summary> | |||
Position, | |||
/// <summary> | |||
/// Text <see cref="Channel"/> topic changed. | |||
/// <see cref="GuildTextChannel"/> topic changed. | |||
/// </summary> | |||
Topic, | |||
/// <summary> | |||
/// Voice <see cref="Channel"/> bitrate changed. | |||
/// <see cref="VoiceChannel"/> bitrate changed. | |||
/// </summary> | |||
Bitrate, | |||
@@ -297,7 +297,7 @@ namespace Discord.Net.Models | |||
// | |||
/// <summary> | |||
/// New user limit in a voice <see cref="Channel"/>. | |||
/// New user limit in a <see cref="VoiceChannel"/>. | |||
/// </summary> | |||
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> | |||
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> | |||
/// The id of this <see cref="Channel"/>. | |||
/// </summary> | |||
@@ -73,13 +143,13 @@ namespace Discord.Net.Models | |||
public Optional<Snowflake?> LastMessageId { get; init; } | |||
/// <summary> | |||
/// The bitrate (in bits) of the voice <see cref="Channel"/>. | |||
/// The bitrate (in bits) of the <see cref="VoiceChannel"/>. | |||
/// </summary> | |||
[JsonPropertyName("bitrate")] | |||
public Optional<int> Bitrate { get; init; } | |||
/// <summary> | |||
/// The <see cref="User"/> limit of the voice <see cref="Channel"/>. | |||
/// The <see cref="User"/> limit of the <see cref="VoiceChannel"/>. | |||
/// </summary> | |||
[JsonPropertyName("user_limit")] | |||
public Optional<int> UserLimit { get; init; } | |||
@@ -135,13 +205,13 @@ namespace Discord.Net.Models | |||
public Optional<DateTimeOffset?> LastPinTimestamp { get; init; } | |||
/// <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> | |||
[JsonPropertyName("rtc_region")] | |||
public Optional<string?> RtcRegion { get; init; } | |||
/// <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> | |||
[JsonPropertyName("video_quality_mode")] | |||
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; } | |||
/// <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> | |||
[JsonPropertyName("guild_id")] | |||
public Snowflake GuildId { get; } | |||
/// <summary> | |||
/// The id of the associated Stage <see cref="Channel"/>. | |||
/// The id of the associated <see cref="StageChannel"/>. | |||
/// </summary> | |||
[JsonPropertyName("channel_id")] | |||
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; } | |||
/// <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. | |||
/// </summary> | |||
[JsonPropertyName("rules_channel_id")] | |||
@@ -190,7 +190,7 @@ namespace Discord.Net.Models | |||
public Optional<int> MemberCount { get; init; } | |||
/// <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> | |||
/// <remarks> | |||
/// Lacks the <see cref="VoiceState.GuildId"/>. | |||
@@ -211,8 +211,8 @@ namespace Discord.Net.Models | |||
public Optional<Channel[]> Channels { get; init; } | |||
/// <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> | |||
[JsonPropertyName("threads")] | |||
public Optional<Channel[]> Threads { get; init; } | |||
@@ -42,13 +42,13 @@ namespace Discord.Net.Models | |||
public Optional<DateTimeOffset?> PremiumSince { get; init; } | |||
/// <summary> | |||
/// Whether the user is deafened in voice <see cref="Channel"/>s. | |||
/// Whether the user is deafened in <see cref="VoiceChannel"/>s. | |||
/// </summary> | |||
[JsonPropertyName("deaf")] | |||
public bool Deaf { get; init; } | |||
/// <summary> | |||
/// Whether the user is muted in voice <see cref="Channel"/>s. | |||
/// Whether the user is muted in <see cref="VoiceChannel"/>s. | |||
/// </summary> | |||
[JsonPropertyName("mute")] | |||
public bool Mute { get; init; } | |||
@@ -9,8 +9,28 @@ namespace Discord.Net.Models | |||
/// <remarks> | |||
/// <see href="https://discord.com/developers/docs/resources/invite#invite-metadata-object-invite-metadata-structure"/> | |||
/// </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> | |||
/// Number of times this <see cref="Invite"/> has been used. | |||
/// </summary> | |||
@@ -18,7 +38,7 @@ namespace Discord.Net.Models | |||
public int Uses { get; init; } | |||
/// <summary> | |||
/// Max number of times this <see cref="Invite"/> can be used. | |||
/// Maximum number of times this <see cref="Invite"/> can be used. | |||
/// </summary> | |||
[JsonPropertyName("max_uses")] | |||
public int MaxUses { get; init; } |
@@ -11,6 +11,26 @@ namespace Discord.Net.Models | |||
/// </remarks> | |||
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> | |||
/// Id of the <see cref="Message"/>. | |||
/// </summary> | |||
@@ -182,7 +202,7 @@ namespace Discord.Net.Models | |||
public Optional<MessageInteraction> Interaction { get; init; } | |||
/// <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. | |||
/// </summary> | |||
[JsonPropertyName("thread")] | |||
@@ -14,12 +14,12 @@ namespace Discord.Net.Models | |||
Default = 0, | |||
/// <summary> | |||
/// Recipient was added to a group <see cref="Channel"/>. | |||
/// Recipient was added to a <see cref="GroupChannel"/>. | |||
/// </summary> | |||
RecipientAdd = 1, | |||
/// <summary> | |||
/// Recipient was removed from a group <see cref="Channel"/>. | |||
/// Recipient was removed from a <see cref="GroupChannel"/>. | |||
/// </summary> | |||
RecipientRemove = 2, | |||
@@ -29,12 +29,12 @@ namespace Discord.Net.Models | |||
Call = 3, | |||
/// <summary> | |||
/// Group <see cref="Channel"/> name was changed. | |||
/// <see cref="GroupChannel"/> name was changed. | |||
/// </summary> | |||
ChannelNameChange = 4, | |||
/// <summary> | |||
/// Group <see cref="Channel"/> icon was changed. | |||
/// <see cref="GroupChannel"/> icon was changed. | |||
/// </summary> | |||
ChannelIconChange = 5, | |||
@@ -96,7 +96,7 @@ namespace Discord.Net.Models | |||
GuildDiscoveryGracePeriodFinalWarning = 17, | |||
/// <summary> | |||
/// A thread <see cref="Channel"/> was created. | |||
/// A <see cref="ThreadChannel"/> was created. | |||
/// </summary> | |||
ThreadCreated = 18, | |||
@@ -111,7 +111,7 @@ namespace Discord.Net.Models | |||
ApplicationCommand = 20, | |||
/// <summary> | |||
/// Starter message for a thread <see cref="Channel"/>. | |||
/// Starter message for a <see cref="ThreadChannel"/>. | |||
/// </summary> | |||
ThreadStarterMessage = 21, | |||
@@ -10,6 +10,16 @@ namespace Discord.Net.Models | |||
/// </remarks> | |||
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> | |||
/// Times this <see cref="Models.Emoji"/> has been used to react. | |||
/// </summary> | |||
@@ -28,16 +28,357 @@ namespace Discord.Net | |||
#region Audit Log | |||
/// <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)); | |||
if (args == null) | |||
args = new(); | |||
else | |||
args.Validate(); | |||
Preconditions.NotNull(args, nameof(args)); | |||
args.Validate(); | |||
return _api.GetGuildAuditLogAsync(guildId, args, cancellationToken); | |||
} | |||
#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 | |||
/// <summary> | |||
/// Returns an audit log object for the guild. | |||
/// Gets an <see cref="AuditLog"/> for the <see cref="Guild"/>. | |||
/// </summary> | |||
/// <remarks> | |||
/// Requires the <see cref="Permissions.ViewAuditLog"/> permission. | |||
/// <see href="https://discord.com/developers/docs/resources/audit-log#get-guild-audit-log"/> | |||
/// </remarks> | |||
/// <param name="guildId"> | |||
/// The guild identifier. | |||
/// The <see cref="Guild"/> identifier. | |||
/// </param> | |||
/// <param name="args"> | |||
/// Parameters to include in the request. | |||
@@ -27,8 +27,843 @@ namespace Discord.Net.Rest | |||
/// <param name="cancellationToken"> | |||
/// Cancellation token for the request. | |||
/// </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 | |||
#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 | |||
{ | |||
/// <summary> | |||
/// Filter the log for actions made by a user. | |||
/// Filter the log for actions made by a <see cref="User"/>. | |||
/// </summary> | |||
public Optional<Snowflake> UserId { get; set; } | |||
@@ -36,6 +36,7 @@ namespace Discord.Net.Rest | |||
public void Validate() | |||
{ | |||
Preconditions.NotZero(UserId, nameof(UserId)); | |||
Preconditions.NotZero(Before, nameof(Before)); | |||
Preconditions.AtLeast(Limit, AuditLog.MinimumGetEntryAmount, 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.Collections.Generic; | |||
using System.Linq; | |||
namespace Discord.Net.Rest | |||
{ | |||
@@ -6,8 +8,8 @@ namespace Discord.Net.Rest | |||
{ | |||
// 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) | |||
{ | |||
@@ -17,6 +19,27 @@ namespace Discord.Net.Rest | |||
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 | |||
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 | |||
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) | |||
throw CreateNotNullException(name, msg); | |||
if (obj.Length == 0) | |||
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) | |||
{ | |||
@@ -57,14 +101,14 @@ namespace Discord.Net.Rest | |||
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) | |||
throw CreateNotNullException(name, msg); | |||
if (obj.Trim().Length == 0) | |||
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) | |||
{ | |||
@@ -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) | |||
{ | |||
@@ -85,7 +129,7 @@ namespace Discord.Net.Rest | |||
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) | |||
{ | |||
@@ -95,7 +139,7 @@ namespace Discord.Net.Rest | |||
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) | |||
{ | |||
@@ -105,7 +149,7 @@ namespace Discord.Net.Rest | |||
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) | |||
{ | |||
@@ -115,25 +159,25 @@ namespace Discord.Net.Rest | |||
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) | |||
return; | |||
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) | |||
return; | |||
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) | |||
return; | |||
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) | |||
return; | |||
@@ -558,5 +602,31 @@ namespace Discord.Net.Rest | |||
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); | |||
} | |||
} | |||
} |