diff --git a/src/Discord.Net.Core/Entities/Channels/IMessageChannel.cs b/src/Discord.Net.Core/Entities/Channels/IMessageChannel.cs
index dc2441f6a..7bd9fabfc 100644
--- a/src/Discord.Net.Core/Entities/Channels/IMessageChannel.cs
+++ b/src/Discord.Net.Core/Entities/Channels/IMessageChannel.cs
@@ -31,7 +31,8 @@ namespace Discord
/// The message components to be included with this message. Used for interactions.
/// A collection of stickers to send with the message.
/// A array of s to send with this response. Max 10.
- /// A message flag to be applied to the sent message, only is permitted.
+ /// A message flag to be applied to the sent message, only
+ /// and is permitted.
///
/// A task that represents an asynchronous send operation for delivering the message. The task result
/// contains the sent message.
@@ -72,7 +73,7 @@ namespace Discord
/// The message components to be included with this message. Used for interactions.
/// A collection of stickers to send with the file.
/// A array of s to send with this response. Max 10.
- /// A message flag to be applied to the sent message, only is permitted.
+ /// A message flag to be applied to the sent message, only and is permitted.
///
/// A task that represents an asynchronous send operation for delivering the message. The task result
/// contains the sent message.
@@ -110,7 +111,7 @@ namespace Discord
/// The message components to be included with this message. Used for interactions.
/// A collection of stickers to send with the file.
/// A array of s to send with this response. Max 10.
- /// A message flag to be applied to the sent message, only is permitted.
+ /// A message flag to be applied to the sent message, only and is permitted.
///
/// A task that represents an asynchronous send operation for delivering the message. The task result
/// contains the sent message.
@@ -140,7 +141,7 @@ namespace Discord
/// The message components to be included with this message. Used for interactions.
/// A collection of stickers to send with the file.
/// A array of s to send with this response. Max 10.
- /// A message flag to be applied to the sent message, only is permitted.
+ /// A message flag to be applied to the sent message, only and is permitted.
///
/// A task that represents an asynchronous send operation for delivering the message. The task result
/// contains the sent message.
@@ -170,7 +171,7 @@ namespace Discord
/// The message components to be included with this message. Used for interactions.
/// A collection of stickers to send with the file.
/// A array of s to send with this response. Max 10.
- /// A message flag to be applied to the sent message, only is permitted.
+ /// A message flag to be applied to the sent message, only and is permitted.
///
/// A task that represents an asynchronous send operation for delivering the message. The task result
/// contains the sent message.
diff --git a/src/Discord.Net.Rest/API/Rest/CreateMessageParams.cs b/src/Discord.Net.Rest/API/Rest/CreateMessageParams.cs
index 7b0d842db..a79c7f70b 100644
--- a/src/Discord.Net.Rest/API/Rest/CreateMessageParams.cs
+++ b/src/Discord.Net.Rest/API/Rest/CreateMessageParams.cs
@@ -6,7 +6,7 @@ namespace Discord.API.Rest
internal class CreateMessageParams
{
[JsonProperty("content")]
- public string Content { get; }
+ public Optional Content { get; set; }
[JsonProperty("nonce")]
public Optional Nonce { get; set; }
@@ -31,10 +31,5 @@ namespace Discord.API.Rest
[JsonProperty("flags")]
public Optional Flags { get; set; }
-
- public CreateMessageParams(string content)
- {
- Content = content;
- }
}
}
diff --git a/src/Discord.Net.Rest/DiscordRestApiClient.cs b/src/Discord.Net.Rest/DiscordRestApiClient.cs
index 23328ba24..b8be586cf 100644
--- a/src/Discord.Net.Rest/DiscordRestApiClient.cs
+++ b/src/Discord.Net.Rest/DiscordRestApiClient.cs
@@ -816,16 +816,24 @@ namespace Discord.API
endpoint = () => $"channels/{channelId}/messages?limit={limit}";
return await SendAsync>("GET", endpoint, ids, options: options).ConfigureAwait(false);
}
+
/// Message content is too long, length must be less or equal to .
public async Task CreateMessageAsync(ulong channelId, CreateMessageParams args, RequestOptions options = null)
{
Preconditions.NotNull(args, nameof(args));
Preconditions.NotEqual(channelId, 0, nameof(channelId));
- if ((!args.Embeds.IsSpecified || args.Embeds.Value == null || args.Embeds.Value.Length == 0) && (!args.Stickers.IsSpecified || args.Stickers.Value == null || args.Stickers.Value.Length == 0))
- Preconditions.NotNullOrEmpty(args.Content, nameof(args.Content));
- if (args.Content?.Length > DiscordConfig.MaxMessageSize)
+ if ((!args.Embeds.IsSpecified || args.Embeds.Value == null || args.Embeds.Value.Length == 0)
+ && (!args.Stickers.IsSpecified || args.Stickers.Value == null || args.Stickers.Value.Length == 0)
+ && (!args.Content.IsSpecified || args.Content.Value is null || string.IsNullOrWhiteSpace(args.Content.Value))
+ && (!args.Components.IsSpecified || args.Components.Value is null || args.Components.Value.Length == 0))
+ {
+ throw new ArgumentException("At least one of 'Content', 'Embeds', 'Stickers' or 'Components' must be specified.", nameof(args));
+ }
+
+ if (args.Content.IsSpecified && args.Content.Value is not null && args.Content.Value.Length > DiscordConfig.MaxMessageSize)
throw new ArgumentException(message: $"Message content is too long, length must be less or equal to {DiscordConfig.MaxMessageSize}.", paramName: nameof(args.Content));
+
options = RequestOptions.CreateOrClone(options);
var ids = new BucketIds(channelId: channelId);
@@ -842,10 +850,14 @@ namespace Discord.API
Preconditions.NotNull(args, nameof(args));
Preconditions.NotEqual(webhookId, 0, nameof(webhookId));
- if (!args.Embeds.IsSpecified || args.Embeds.Value == null || args.Embeds.Value.Length == 0)
- Preconditions.NotNullOrEmpty(args.Content, nameof(args.Content));
+ if ((!args.Embeds.IsSpecified || args.Embeds.Value == null || args.Embeds.Value.Length == 0)
+ && (!args.Content.IsSpecified || args.Content.Value is null || string.IsNullOrWhiteSpace(args.Content.Value))
+ && (!args.Components.IsSpecified || args.Components.Value is null || args.Components.Value.Length == 0))
+ {
+ throw new ArgumentException("At least one of 'Content', 'Embeds' or 'Components' must be specified.", nameof(args));
+ }
- if (args.Content.IsSpecified && args.Content.Value?.Length > DiscordConfig.MaxMessageSize)
+ if (args.Content.IsSpecified && args.Content.Value is not null && args.Content.Value.Length > DiscordConfig.MaxMessageSize)
throw new ArgumentException(message: $"Message content is too long, length must be less or equal to {DiscordConfig.MaxMessageSize}.", paramName: nameof(args.Content));
options = RequestOptions.CreateOrClone(options);
@@ -875,6 +887,28 @@ namespace Discord.API
await SendJsonAsync("PATCH", () => $"webhooks/{webhookId}/{AuthToken}/messages/{messageId}?{WebhookQuery(false, threadId)}", args, ids, clientBucket: ClientBucketType.SendEdit, options: options).ConfigureAwait(false);
}
+ /// Message content is too long, length must be less or equal to .
+ /// This operation may only be called with a token.
+ public async Task ModifyWebhookMessageAsync(ulong webhookId, ulong messageId, UploadWebhookFileParams args, RequestOptions options = null, ulong? threadId = null)
+ {
+ if (AuthTokenType != TokenType.Webhook)
+ throw new InvalidOperationException($"This operation may only be called with a {nameof(TokenType.Webhook)} token.");
+
+ Preconditions.NotNull(args, nameof(args));
+ Preconditions.NotEqual(webhookId, 0, nameof(webhookId));
+ Preconditions.NotEqual(messageId, 0, nameof(messageId));
+
+ if (args.Embeds.IsSpecified)
+ Preconditions.AtMost(args.Embeds.Value.Length, 10, nameof(args.Embeds), "A max of 10 Embeds are allowed.");
+ if (args.Content.IsSpecified && args.Content.Value.Length > DiscordConfig.MaxMessageSize)
+ throw new ArgumentException(message: $"Message content is too long, length must be less or equal to {DiscordConfig.MaxMessageSize}.", paramName: nameof(args.Content));
+
+ options = RequestOptions.CreateOrClone(options);
+
+ var ids = new BucketIds(webhookId: webhookId);
+ await SendMultipartAsync("PATCH", () => $"webhooks/{webhookId}/{AuthToken}/messages/{messageId}?{WebhookQuery(false, threadId)}", args.ToDictionary(), ids, clientBucket: ClientBucketType.SendEdit, options: options).ConfigureAwait(false);
+ }
+
/// This operation may only be called with a token.
public async Task DeleteWebhookMessageAsync(ulong webhookId, ulong messageId, RequestOptions options = null, ulong? threadId = null)
{
@@ -897,10 +931,17 @@ namespace Discord.API
Preconditions.NotEqual(channelId, 0, nameof(channelId));
options = RequestOptions.CreateOrClone(options);
- if (args.Content.GetValueOrDefault(null) == null)
- args.Content = "";
- else if (args.Content.IsSpecified && args.Content.Value?.Length > DiscordConfig.MaxMessageSize)
- throw new ArgumentOutOfRangeException($"Message content is too long, length must be less or equal to {DiscordConfig.MaxMessageSize}.", nameof(args.Content));
+ if ((!args.Embeds.IsSpecified || args.Embeds.Value == null || args.Embeds.Value.Length == 0)
+ && (!args.Stickers.IsSpecified || args.Stickers.Value == null || args.Stickers.Value.Length == 0)
+ && (!args.Content.IsSpecified || args.Content.Value is null || string.IsNullOrWhiteSpace(args.Content.Value))
+ && (!args.MessageComponent.IsSpecified || args.MessageComponent.Value is null || args.MessageComponent.Value.Length == 0)
+ && (args.Files.Length == 0))
+ {
+ throw new ArgumentException("At least one of 'Content', 'Embeds', 'Stickers', 'Attachments' or 'Components' must be specified.", nameof(args));
+ }
+
+ if (args.Content.IsSpecified && args.Content.Value is not null && args.Content.Value.Length > DiscordConfig.MaxMessageSize)
+ throw new ArgumentException(message: $"Message content is too long, length must be less or equal to {DiscordConfig.MaxMessageSize}.", paramName: nameof(args.Content));
var ids = new BucketIds(channelId: channelId);
return await SendMultipartAsync("POST", () => $"channels/{channelId}/messages", args.ToDictionary(), ids, clientBucket: ClientBucketType.SendEdit, options: options).ConfigureAwait(false);
@@ -917,19 +958,23 @@ namespace Discord.API
Preconditions.NotEqual(webhookId, 0, nameof(webhookId));
options = RequestOptions.CreateOrClone(options);
- if (args.Content.GetValueOrDefault(null) == null)
- args.Content = "";
- else if (args.Content.IsSpecified)
+
+ if ((!args.Embeds.IsSpecified || args.Embeds.Value == null || args.Embeds.Value.Length == 0)
+ && (!args.Content.IsSpecified || args.Content.Value is null || string.IsNullOrWhiteSpace(args.Content.Value))
+ && (!args.MessageComponents.IsSpecified || args.MessageComponents.Value is null || args.MessageComponents.Value.Length == 0)
+ && (args.Files.Length == 0))
{
- if (args.Content.Value == null)
- args.Content = "";
- if (args.Content.Value?.Length > DiscordConfig.MaxMessageSize)
- throw new ArgumentOutOfRangeException($"Message content is too long, length must be less or equal to {DiscordConfig.MaxMessageSize}.", nameof(args.Content));
+ throw new ArgumentException("At least one of 'Content', 'Embeds', 'Stickers', 'Attachments' or 'Components' must be specified.", nameof(args));
}
+ if (args.Content.IsSpecified && args.Content.Value is not null && args.Content.Value.Length > DiscordConfig.MaxMessageSize)
+ throw new ArgumentException(message: $"Message content is too long, length must be less or equal to {DiscordConfig.MaxMessageSize}.", paramName: nameof(args.Content));
+
+
var ids = new BucketIds(webhookId: webhookId);
return await SendMultipartAsync("POST", () => $"webhooks/{webhookId}/{AuthToken}?{WebhookQuery(true, threadId)}", args.ToDictionary(), ids, clientBucket: ClientBucketType.SendEdit, options: options).ConfigureAwait(false);
}
+
public async Task DeleteMessageAsync(ulong channelId, ulong messageId, RequestOptions options = null)
{
Preconditions.NotEqual(channelId, 0, nameof(channelId));
@@ -939,6 +984,7 @@ namespace Discord.API
var ids = new BucketIds(channelId: channelId);
await SendAsync("DELETE", () => $"channels/{channelId}/messages/{messageId}", ids, options: options).ConfigureAwait(false);
}
+
public async Task DeleteMessagesAsync(ulong channelId, DeleteMessagesParams args, RequestOptions options = null)
{
Preconditions.NotEqual(channelId, 0, nameof(channelId));
@@ -967,8 +1013,10 @@ namespace Discord.API
Preconditions.NotEqual(channelId, 0, nameof(channelId));
Preconditions.NotEqual(messageId, 0, nameof(messageId));
Preconditions.NotNull(args, nameof(args));
+
if (args.Content.IsSpecified && args.Content.Value?.Length > DiscordConfig.MaxMessageSize)
throw new ArgumentOutOfRangeException($"Message content is too long, length must be less or equal to {DiscordConfig.MaxMessageSize}.", nameof(args.Content));
+
options = RequestOptions.CreateOrClone(options);
var ids = new BucketIds(channelId: channelId);
@@ -980,8 +1028,10 @@ namespace Discord.API
Preconditions.NotEqual(channelId, 0, nameof(channelId));
Preconditions.NotEqual(messageId, 0, nameof(messageId));
Preconditions.NotNull(args, nameof(args));
+
if (args.Content.IsSpecified && args.Content.Value?.Length > DiscordConfig.MaxMessageSize)
throw new ArgumentOutOfRangeException($"Message content is too long, length must be less or equal to {DiscordConfig.MaxMessageSize}.", nameof(args.Content));
+
options = RequestOptions.CreateOrClone(options);
var ids = new BucketIds(channelId: channelId);
@@ -1444,8 +1494,15 @@ namespace Discord.API
public async Task CreateInteractionFollowupMessageAsync(CreateWebhookMessageParams args, string token, RequestOptions options = null)
{
- if ((!args.Embeds.IsSpecified || args.Embeds.Value == null || args.Embeds.Value.Length == 0) && !args.File.IsSpecified)
- Preconditions.NotNullOrEmpty(args.Content, nameof(args.Content));
+ if ((!args.Embeds.IsSpecified || args.Embeds.Value == null || args.Embeds.Value.Length == 0)
+ && (!args.Content.IsSpecified || args.Content.Value is null || string.IsNullOrWhiteSpace(args.Content.Value))
+ && (!args.Components.IsSpecified || args.Components.Value is null || args.Components.Value.Length == 0))
+ {
+ throw new ArgumentException("At least one of 'Content', 'Embeds', 'File' or 'Components' must be specified.", nameof(args));
+ }
+
+ if (args.Content.IsSpecified && args.Content.Value is not null && args.Content.Value.Length > DiscordConfig.MaxMessageSize)
+ throw new ArgumentException(message: $"Message content is too long, length must be less or equal to {DiscordConfig.MaxMessageSize}.", paramName: nameof(args.Content));
if (args.Content.IsSpecified && args.Content.Value?.Length > DiscordConfig.MaxMessageSize)
throw new ArgumentException(message: $"Message content is too long, length must be less or equal to {DiscordConfig.MaxMessageSize}.", paramName: nameof(args.Content));
@@ -1460,9 +1517,12 @@ namespace Discord.API
public async Task CreateInteractionFollowupMessageAsync(UploadWebhookFileParams args, string token, RequestOptions options = null)
{
- if ((!args.Embeds.IsSpecified || args.Embeds.Value == null || args.Embeds.Value.Length == 0) && !args.Files.Any())
- Preconditions.NotNullOrEmpty(args.Content, nameof(args.Content));
-
+ if ((!args.Embeds.IsSpecified || args.Embeds.Value == null || args.Embeds.Value.Length == 0)
+ && (!args.Content.IsSpecified || args.Content.Value is null || string.IsNullOrWhiteSpace(args.Content.Value))
+ && (!args.MessageComponents.IsSpecified || args.MessageComponents.Value is null || args.MessageComponents.Value.Length == 0))
+ {
+ throw new ArgumentException("At least one of 'Content', 'Embeds', 'Files' or 'Components' must be specified.", nameof(args));
+ }
if (args.Content.IsSpecified && args.Content.Value?.Length > DiscordConfig.MaxMessageSize)
throw new ArgumentException(message: $"Message content is too long, length must be less or equal to {DiscordConfig.MaxMessageSize}.", paramName: nameof(args.Content));
diff --git a/src/Discord.Net.Rest/Entities/Channels/ChannelHelper.cs b/src/Discord.Net.Rest/Entities/Channels/ChannelHelper.cs
index fbfa0f3dc..1d114cb0b 100644
--- a/src/Discord.Net.Rest/Entities/Channels/ChannelHelper.cs
+++ b/src/Discord.Net.Rest/Entities/Channels/ChannelHelper.cs
@@ -301,12 +301,12 @@ namespace Discord.Rest
Preconditions.AtMost(stickers.Length, 3, nameof(stickers), "A max of 3 stickers are allowed.");
}
-
- if (flags is not MessageFlags.None and not MessageFlags.SuppressEmbeds)
+ if (flags is not MessageFlags.None and not MessageFlags.SuppressEmbeds and not MessageFlags.SuppressNotification)
throw new ArgumentException("The only valid MessageFlags are SuppressEmbeds and none.", nameof(flags));
- var args = new CreateMessageParams(text)
+ var args = new CreateMessageParams
{
+ Content = text,
IsTTS = isTTS,
Embeds = embeds.Any() ? embeds.Select(x => x.ToModel()).ToArray() : Optional.Unspecified,
AllowedMentions = allowedMentions?.ToModel(),
@@ -343,7 +343,7 @@ namespace Discord.Rest
/// is in an invalid format.
/// An I/O error occurred while opening the file.
/// Message content is too long, length must be less or equal to .
- /// The only valid are and .
+ /// The only valid are , and .
public static async Task SendFileAsync(IMessageChannel channel, BaseDiscordClient client,
string filePath, string text, bool isTTS, Embed embed, AllowedMentions allowedMentions,
MessageReference messageReference, MessageComponent components, ISticker[] stickers, RequestOptions options,
@@ -376,7 +376,7 @@ namespace Discord.Rest
=> SendFilesAsync(channel, client, new[] { attachment }, text, isTTS, embed, allowedMentions, messageReference,
components, stickers, options, embeds, flags);
- /// The only valid are and .
+ /// The only valid are , and .
public static async Task SendFilesAsync(IMessageChannel channel, BaseDiscordClient client,
IEnumerable attachments, string text, bool isTTS, Embed embed, AllowedMentions allowedMentions,
MessageReference messageReference, MessageComponent components, ISticker[] stickers, RequestOptions options,
diff --git a/src/Discord.Net.Rest/Entities/Channels/RestDMChannel.cs b/src/Discord.Net.Rest/Entities/Channels/RestDMChannel.cs
index 35c2411bd..59c502f1c 100644
--- a/src/Discord.Net.Rest/Entities/Channels/RestDMChannel.cs
+++ b/src/Discord.Net.Rest/Entities/Channels/RestDMChannel.cs
@@ -127,7 +127,7 @@ namespace Discord.Rest
/// An I/O error occurred while opening the file.
/// Message content is too long, length must be less or equal to .
/// The only valid are and .
- public Task SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null,
+ public Task SendFileAsync(string filePath, string text = null, bool isTTS = false, Embed embed = null,
RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null,
MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null,
Embed[] embeds = null, MessageFlags flags = MessageFlags.None)
@@ -135,7 +135,7 @@ namespace Discord.Rest
components, stickers, options, isSpoiler, embeds, flags);
///
/// Message content is too long, length must be less or equal to .
- public Task SendFileAsync(Stream stream, string filename, string text, bool isTTS = false,
+ public Task SendFileAsync(Stream stream, string filename, string text = null, bool isTTS = false,
Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null,
MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null,
Embed[] embeds = null, MessageFlags flags = MessageFlags.None)
@@ -144,7 +144,7 @@ namespace Discord.Rest
///
/// Message content is too long, length must be less or equal to .
- public Task SendFileAsync(FileAttachment attachment, string text, bool isTTS = false,
+ public Task SendFileAsync(FileAttachment attachment, string text = null, bool isTTS = false,
Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null,
MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null,
Embed[] embeds = null, MessageFlags flags = MessageFlags.None)
@@ -153,7 +153,7 @@ namespace Discord.Rest
///
/// Message content is too long, length must be less or equal to .
- public Task SendFilesAsync(IEnumerable attachments, string text, bool isTTS = false,
+ public Task SendFilesAsync(IEnumerable attachments, string text = null, bool isTTS = false,
Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null,
MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null,
Embed[] embeds = null, MessageFlags flags = MessageFlags.None)
diff --git a/src/Discord.Net.Rest/Entities/Channels/RestGroupChannel.cs b/src/Discord.Net.Rest/Entities/Channels/RestGroupChannel.cs
index ba4cbdb2b..38e20e8f4 100644
--- a/src/Discord.Net.Rest/Entities/Channels/RestGroupChannel.cs
+++ b/src/Discord.Net.Rest/Entities/Channels/RestGroupChannel.cs
@@ -137,7 +137,7 @@ namespace Discord.Rest
/// An I/O error occurred while opening the file.
/// Message content is too long, length must be less or equal to .
/// The only valid are and .
- public Task SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null,
+ public Task SendFileAsync(string filePath, string text = null, bool isTTS = false, Embed embed = null,
RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null,
MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null,
Embed[] embeds = null, MessageFlags flags = MessageFlags.None)
@@ -146,7 +146,7 @@ namespace Discord.Rest
///
/// Message content is too long, length must be less or equal to .
/// The only valid are and .
- public Task SendFileAsync(Stream stream, string filename, string text, bool isTTS = false,
+ public Task SendFileAsync(Stream stream, string filename, string text = null, bool isTTS = false,
Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null,
MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null,
Embed[] embeds = null, MessageFlags flags = MessageFlags.None)
@@ -155,7 +155,7 @@ namespace Discord.Rest
///
/// Message content is too long, length must be less or equal to .
/// The only valid are and .
- public Task SendFileAsync(FileAttachment attachment, string text, bool isTTS = false,
+ public Task SendFileAsync(FileAttachment attachment, string text = null, bool isTTS = false,
Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null,
MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null,
Embed[] embeds = null, MessageFlags flags = MessageFlags.None)
@@ -164,7 +164,7 @@ namespace Discord.Rest
///
/// Message content is too long, length must be less or equal to .
/// The only valid are and .
- public Task SendFilesAsync(IEnumerable attachments, string text, bool isTTS = false,
+ public Task SendFilesAsync(IEnumerable attachments, string text = null, bool isTTS = false,
Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null,
MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null,
Embed[] embeds = null, MessageFlags flags = MessageFlags.None)
diff --git a/src/Discord.Net.Rest/Entities/Channels/RestTextChannel.cs b/src/Discord.Net.Rest/Entities/Channels/RestTextChannel.cs
index 1d1e6df96..497bbfdc8 100644
--- a/src/Discord.Net.Rest/Entities/Channels/RestTextChannel.cs
+++ b/src/Discord.Net.Rest/Entities/Channels/RestTextChannel.cs
@@ -110,7 +110,7 @@ namespace Discord.Rest
///
/// Message content is too long, length must be less or equal to .
- /// The only valid are and .
+ /// The only valid are , and .
public virtual Task SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null,
RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null,
MessageComponent components = null, ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None)
@@ -142,8 +142,8 @@ namespace Discord.Rest
/// is in an invalid format.
/// An I/O error occurred while opening the file.
/// Message content is too long, length must be less or equal to .
- /// The only valid are and .
- public virtual Task SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null,
+ /// The only valid are , and .
+ public virtual Task SendFileAsync(string filePath, string text = null, bool isTTS = false, Embed embed = null,
RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null,
MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null,
Embed[] embeds = null, MessageFlags flags = MessageFlags.None)
@@ -152,8 +152,8 @@ namespace Discord.Rest
///
/// Message content is too long, length must be less or equal to .
- /// The only valid are and .
- public virtual Task SendFileAsync(Stream stream, string filename, string text, bool isTTS = false,
+ /// The only valid are , and .
+ public virtual Task SendFileAsync(Stream stream, string filename, string text = null, bool isTTS = false,
Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null,
MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null,
Embed[] embeds = null, MessageFlags flags = MessageFlags.None)
@@ -162,8 +162,8 @@ namespace Discord.Rest
///
/// Message content is too long, length must be less or equal to .
- /// The only valid are and .
- public virtual Task SendFileAsync(FileAttachment attachment, string text, bool isTTS = false,
+ /// The only valid are , and .
+ public virtual Task SendFileAsync(FileAttachment attachment, string text = null, bool isTTS = false,
Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null,
MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null,
Embed[] embeds = null, MessageFlags flags = MessageFlags.None)
@@ -172,8 +172,8 @@ namespace Discord.Rest
///
/// Message content is too long, length must be less or equal to .
- /// The only valid are and .
- public virtual Task SendFilesAsync(IEnumerable attachments, string text, bool isTTS = false,
+ /// The only valid are , and .
+ public virtual Task SendFilesAsync(IEnumerable attachments, string text = null, bool isTTS = false,
Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null,
MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null,
Embed[] embeds = null, MessageFlags flags = MessageFlags.None)
diff --git a/src/Discord.Net.WebSocket/Entities/Channels/SocketDMChannel.cs b/src/Discord.Net.WebSocket/Entities/Channels/SocketDMChannel.cs
index 47e92626b..e2031feff 100644
--- a/src/Discord.Net.WebSocket/Entities/Channels/SocketDMChannel.cs
+++ b/src/Discord.Net.WebSocket/Entities/Channels/SocketDMChannel.cs
@@ -148,7 +148,7 @@ namespace Discord.WebSocket
///
/// The only valid are and .
- public Task SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null,
+ public Task SendFileAsync(string filePath, string text = null, bool isTTS = false, Embed embed = null,
RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null,
MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null,
Embed[] embeds = null, MessageFlags flags = MessageFlags.None)
@@ -157,7 +157,7 @@ namespace Discord.WebSocket
///
/// Message content is too long, length must be less or equal to .
/// The only valid are and .
- public Task SendFileAsync(Stream stream, string filename, string text, bool isTTS = false,
+ public Task SendFileAsync(Stream stream, string filename, string text = null, bool isTTS = false,
Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null,
MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null,
Embed[] embeds = null, MessageFlags flags = MessageFlags.None)
@@ -166,7 +166,7 @@ namespace Discord.WebSocket
///
/// Message content is too long, length must be less or equal to .
/// The only valid are and .
- public Task SendFileAsync(FileAttachment attachment, string text, bool isTTS = false,
+ public Task SendFileAsync(FileAttachment attachment, string text = null, bool isTTS = false,
Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null,
MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null,
Embed[] embeds = null, MessageFlags flags = MessageFlags.None)
@@ -175,7 +175,7 @@ namespace Discord.WebSocket
///
/// Message content is too long, length must be less or equal to .
/// The only valid are and .
- public Task SendFilesAsync(IEnumerable attachments, string text, bool isTTS = false,
+ public Task SendFilesAsync(IEnumerable attachments, string text = null, bool isTTS = false,
Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null,
MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null,
Embed[] embeds = null, MessageFlags flags = MessageFlags.None)
diff --git a/src/Discord.Net.WebSocket/Entities/Channels/SocketGroupChannel.cs b/src/Discord.Net.WebSocket/Entities/Channels/SocketGroupChannel.cs
index 90dfafb00..7502a4e2f 100644
--- a/src/Discord.Net.WebSocket/Entities/Channels/SocketGroupChannel.cs
+++ b/src/Discord.Net.WebSocket/Entities/Channels/SocketGroupChannel.cs
@@ -187,7 +187,7 @@ namespace Discord.WebSocket
///
/// The only valid are and .
- public Task SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null,
+ public Task SendFileAsync(string filePath, string text = null, bool isTTS = false, Embed embed = null,
RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null,
MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null,
Embed[] embeds = null, MessageFlags flags = MessageFlags.None)
@@ -196,7 +196,7 @@ namespace Discord.WebSocket
///
/// Message content is too long, length must be less or equal to .
/// The only valid are and .
- public Task SendFileAsync(Stream stream, string filename, string text, bool isTTS = false,
+ public Task SendFileAsync(Stream stream, string filename, string text = null, bool isTTS = false,
Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null,
MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null,
Embed[] embeds = null, MessageFlags flags = MessageFlags.None)
@@ -205,7 +205,7 @@ namespace Discord.WebSocket
///
/// Message content is too long, length must be less or equal to .
/// The only valid are and .
- public Task SendFileAsync(FileAttachment attachment, string text, bool isTTS = false,
+ public Task SendFileAsync(FileAttachment attachment, string text = null, bool isTTS = false,
Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null,
MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null,
Embed[] embeds = null, MessageFlags flags = MessageFlags.None)
@@ -214,7 +214,7 @@ namespace Discord.WebSocket
///
/// Message content is too long, length must be less or equal to .
/// The only valid are and .
- public Task SendFilesAsync(IEnumerable attachments, string text, bool isTTS = false,
+ public Task SendFilesAsync(IEnumerable attachments, string text = null, bool isTTS = false,
Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null,
MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null,
Embed[] embeds = null, MessageFlags flags = MessageFlags.None)
diff --git a/src/Discord.Net.WebSocket/Entities/Channels/SocketTextChannel.cs b/src/Discord.Net.WebSocket/Entities/Channels/SocketTextChannel.cs
index 13f4e6694..5d45202e4 100644
--- a/src/Discord.Net.WebSocket/Entities/Channels/SocketTextChannel.cs
+++ b/src/Discord.Net.WebSocket/Entities/Channels/SocketTextChannel.cs
@@ -218,7 +218,7 @@ namespace Discord.WebSocket
///
/// Message content is too long, length must be less or equal to .
- /// The only valid are and .
+ /// The only valid are , and .
public virtual Task SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null,
RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null,
MessageComponent components = null, ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None)
@@ -226,8 +226,8 @@ namespace Discord.WebSocket
components, stickers, options, embeds, flags);
///
- /// The only valid are and .
- public virtual Task SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null,
+ /// The only valid are , and .
+ public virtual Task SendFileAsync(string filePath, string text = null, bool isTTS = false, Embed embed = null,
RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null,
MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null,
Embed[] embeds = null, MessageFlags flags = MessageFlags.None)
@@ -235,8 +235,8 @@ namespace Discord.WebSocket
components, stickers, options, isSpoiler, embeds, flags);
///
/// Message content is too long, length must be less or equal to .
- /// The only valid are and .
- public virtual Task SendFileAsync(Stream stream, string filename, string text, bool isTTS = false,
+ /// The only valid are , and .
+ public virtual Task SendFileAsync(Stream stream, string filename, string text = null, bool isTTS = false,
Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null,
MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null,
Embed[] embeds = null, MessageFlags flags = MessageFlags.None)
@@ -244,8 +244,8 @@ namespace Discord.WebSocket
messageReference, components, stickers, options, isSpoiler, embeds, flags);
///
/// Message content is too long, length must be less or equal to .
- /// The only valid are and .
- public virtual Task SendFileAsync(FileAttachment attachment, string text, bool isTTS = false,
+ /// The only valid are , and .
+ public virtual Task SendFileAsync(FileAttachment attachment, string text = null, bool isTTS = false,
Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null,
MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null,
Embed[] embeds = null, MessageFlags flags = MessageFlags.None)
@@ -253,8 +253,8 @@ namespace Discord.WebSocket
messageReference, components, stickers, options, embeds, flags);
///
/// Message content is too long, length must be less or equal to .
- /// The only valid are and .
- public virtual Task SendFilesAsync(IEnumerable attachments, string text, bool isTTS = false,
+ /// The only valid are , and .
+ public virtual Task SendFilesAsync(IEnumerable attachments, string text = null, bool isTTS = false,
Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null,
MessageReference messageReference = null, MessageComponent components = null, ISticker[] stickers = null,
Embed[] embeds = null, MessageFlags flags = MessageFlags.None)
diff --git a/src/Discord.Net.Webhook/DiscordWebhookClient.cs b/src/Discord.Net.Webhook/DiscordWebhookClient.cs
index 53f5b488e..af1005aea 100644
--- a/src/Discord.Net.Webhook/DiscordWebhookClient.cs
+++ b/src/Discord.Net.Webhook/DiscordWebhookClient.cs
@@ -1,5 +1,6 @@
using Discord.Logging;
using Discord.Rest;
+
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -7,195 +8,237 @@ using System.IO;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
-namespace Discord.Webhook
+namespace Discord.Webhook;
+
+///
+/// A client responsible for connecting as a Webhook.
+///
+public class DiscordWebhookClient : IDisposable
{
- /// A client responsible for connecting as a Webhook.
- public class DiscordWebhookClient : IDisposable
+ public event Func Log
{
- public event Func Log { add { _logEvent.Add(value); } remove { _logEvent.Remove(value); } }
- internal readonly AsyncEvent> _logEvent = new AsyncEvent>();
-
- private readonly ulong _webhookId;
- internal IWebhook Webhook;
- internal readonly Logger _restLogger;
-
- internal API.DiscordRestApiClient ApiClient { get; }
- internal LogManager LogManager { get; }
-
- /// Creates a new Webhook Discord client.
- public DiscordWebhookClient(IWebhook webhook)
- : this(webhook.Id, webhook.Token, new DiscordRestConfig()) { }
- /// Creates a new Webhook Discord client.
- public DiscordWebhookClient(ulong webhookId, string webhookToken)
- : this(webhookId, webhookToken, new DiscordRestConfig()) { }
- /// Creates a new Webhook Discord client.
- public DiscordWebhookClient(string webhookUrl)
- : this(webhookUrl, new DiscordRestConfig()) { }
-
- // regex pattern to match webhook urls
- private static Regex WebhookUrlRegex = new Regex(@"^.*(discord|discordapp)\.com\/api\/webhooks\/([\d]+)\/([a-z0-9_-]+)$", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
-
- /// Creates a new Webhook Discord client.
- public DiscordWebhookClient(ulong webhookId, string webhookToken, DiscordRestConfig config)
- : this(config)
- {
- _webhookId = webhookId;
- ApiClient.LoginAsync(TokenType.Webhook, webhookToken).GetAwaiter().GetResult();
- Webhook = WebhookClientHelper.GetWebhookAsync(this, webhookId).GetAwaiter().GetResult();
- }
- /// Creates a new Webhook Discord client.
- public DiscordWebhookClient(IWebhook webhook, DiscordRestConfig config)
- : this(config)
- {
- Webhook = webhook;
- _webhookId = Webhook.Id;
- }
+ add => _logEvent.Add(value);
+ remove => _logEvent.Remove(value);
+ }
- ///
- /// Creates a new Webhook Discord client.
- ///
- /// The url of the webhook.
- /// The configuration options to use for this client.
- /// Thrown if the is an invalid format.
- /// Thrown if the is null or whitespace.
- public DiscordWebhookClient(string webhookUrl, DiscordRestConfig config) : this(config)
- {
- ParseWebhookUrl(webhookUrl, out _webhookId, out string token);
- ApiClient.LoginAsync(TokenType.Webhook, token).GetAwaiter().GetResult();
- Webhook = WebhookClientHelper.GetWebhookAsync(this, _webhookId).GetAwaiter().GetResult();
- }
+ internal readonly AsyncEvent> _logEvent = new AsyncEvent>();
+
+ private readonly ulong _webhookId;
+ internal IWebhook Webhook;
+ internal readonly Logger _restLogger;
+
+ internal API.DiscordRestApiClient ApiClient { get; }
+ internal LogManager LogManager { get; }
+
+ ///
+ /// Creates a new Webhook Discord client.
+ ///
+ public DiscordWebhookClient(IWebhook webhook)
+ : this(webhook.Id, webhook.Token, new DiscordRestConfig()) { }
+
+ ///
+ /// Creates a new Webhook Discord client.
+ ///
+ public DiscordWebhookClient(ulong webhookId, string webhookToken)
+ : this(webhookId, webhookToken, new DiscordRestConfig()) { }
+
+ ///
+ /// Creates a new Webhook Discord client.
+ ///
+ public DiscordWebhookClient(string webhookUrl)
+ : this(webhookUrl, new DiscordRestConfig()) { }
+
+ // regex pattern to match webhook urls
+ private static Regex WebhookUrlRegex = new Regex(@"^.*(discord|discordapp)\.com\/api\/webhooks\/([\d]+)\/([a-z0-9_-]+)$", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
+
+ ///
+ /// Creates a new Webhook Discord client.
+ ///
+ public DiscordWebhookClient(ulong webhookId, string webhookToken, DiscordRestConfig config)
+ : this(config)
+ {
+ _webhookId = webhookId;
+ ApiClient.LoginAsync(TokenType.Webhook, webhookToken).GetAwaiter().GetResult();
+ Webhook = WebhookClientHelper.GetWebhookAsync(this, webhookId).GetAwaiter().GetResult();
+ }
+ /// Creates a new Webhook Discord client.
+ public DiscordWebhookClient(IWebhook webhook, DiscordRestConfig config)
+ : this(config)
+ {
+ Webhook = webhook;
+ _webhookId = Webhook.Id;
+ }
- private DiscordWebhookClient(DiscordRestConfig config)
- {
- ApiClient = CreateApiClient(config);
- LogManager = new LogManager(config.LogLevel);
- LogManager.Message += async msg => await _logEvent.InvokeAsync(msg).ConfigureAwait(false);
-
- _restLogger = LogManager.CreateLogger("Rest");
-
- ApiClient.RequestQueue.RateLimitTriggered += async (id, info, endpoint) =>
- {
- if (info == null)
- await _restLogger.VerboseAsync($"Preemptive Rate limit triggered: {endpoint} {(id.IsHashBucket ? $"(Bucket: {id.BucketHash})" : "")}").ConfigureAwait(false);
- else
- await _restLogger.WarningAsync($"Rate limit triggered: {endpoint} {(id.IsHashBucket ? $"(Bucket: {id.BucketHash})" : "")}").ConfigureAwait(false);
- };
- ApiClient.SentRequest += async (method, endpoint, millis) => await _restLogger.VerboseAsync($"{method} {endpoint}: {millis} ms").ConfigureAwait(false);
- }
- private static API.DiscordRestApiClient CreateApiClient(DiscordRestConfig config)
- => new API.DiscordRestApiClient(config.RestClientProvider, DiscordRestConfig.UserAgent, useSystemClock: config.UseSystemClock, defaultRatelimitCallback: config.DefaultRatelimitCallback);
- /// Sends a message to the channel for this webhook.
- /// Returns the ID of the created message.
- public Task SendMessageAsync(string text = null, bool isTTS = false, IEnumerable