diff --git a/src/Discord.Net.Core/Entities/Channels/IMessageChannel.cs b/src/Discord.Net.Core/Entities/Channels/IMessageChannel.cs
index 0e7df3f7c..b5aa69d55 100644
--- a/src/Discord.Net.Core/Entities/Channels/IMessageChannel.cs
+++ b/src/Discord.Net.Core/Entities/Channels/IMessageChannel.cs
@@ -54,11 +54,12 @@ namespace Discord
/// Whether the message should be read aloud by Discord or not.
/// The to be sent.
/// The options to be used when sending the request.
+ /// Whether the message attachment should be hidden as a spoiler.
///
/// A task that represents an asynchronous send operation for delivering the message. The task result
/// contains the sent message.
///
- Task SendFileAsync(string filePath, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null);
+ Task SendFileAsync(string filePath, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false);
///
/// Sends a file to this message channel with an optional caption.
///
@@ -82,11 +83,12 @@ namespace Discord
/// Whether the message should be read aloud by Discord or not.
/// The to be sent.
/// The options to be used when sending the request.
+ /// Whether the message attachment should be hidden as a spoiler.
///
/// A task that represents an asynchronous send operation for delivering the message. The task result
/// contains the sent message.
///
- Task SendFileAsync(Stream stream, string filename, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null);
+ Task SendFileAsync(Stream stream, string filename, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false);
///
/// Gets a message from this message channel.
diff --git a/src/Discord.Net.Core/Extensions/AttachmentExtensions.cs b/src/Discord.Net.Core/Extensions/AttachmentExtensions.cs
new file mode 100644
index 000000000..605410769
--- /dev/null
+++ b/src/Discord.Net.Core/Extensions/AttachmentExtensions.cs
@@ -0,0 +1,15 @@
+namespace Discord
+{
+ public static class AttachmentExtensions
+ {
+ ///
+ /// The prefix applied to files to indicate that it is a spoiler.
+ ///
+ public const string SpoilerPrefix = "SPOILER_";
+ ///
+ /// Gets whether the message's attachments are spoilers or not.
+ ///
+ public static bool IsSpoiler(this IAttachment attachment)
+ => attachment.Filename.StartsWith(SpoilerPrefix);
+ }
+}
diff --git a/src/Discord.Net.Core/Format.cs b/src/Discord.Net.Core/Format.cs
index fec9b607a..07a9ec75c 100644
--- a/src/Discord.Net.Core/Format.cs
+++ b/src/Discord.Net.Core/Format.cs
@@ -4,7 +4,7 @@ namespace Discord
public static class Format
{
// Characters which need escaping
- private static readonly string[] SensitiveCharacters = { "\\", "*", "_", "~", "`" };
+ private static readonly string[] SensitiveCharacters = { "\\", "*", "_", "~", "`", "|" };
/// Returns a markdown-formatted string with bold formatting.
public static string Bold(string text) => $"**{text}**";
@@ -14,6 +14,8 @@ namespace Discord
public static string Underline(string text) => $"__{text}__";
/// Returns a markdown-formatted string with strikethrough formatting.
public static string Strikethrough(string text) => $"~~{text}~~";
+ /// Returns a string with spoiler formatting.
+ public static string Spoiler(string text) => $"||{text}||";
/// Returns a markdown-formatted URL. Only works in descriptions and fields.
public static string Url(string text, string url) => $"[{text}]({url})";
/// Escapes a URL so that a preview is not generated.
diff --git a/src/Discord.Net.Rest/API/Rest/UploadFileParams.cs b/src/Discord.Net.Rest/API/Rest/UploadFileParams.cs
index ae15aa5df..7ba21d012 100644
--- a/src/Discord.Net.Rest/API/Rest/UploadFileParams.cs
+++ b/src/Discord.Net.Rest/API/Rest/UploadFileParams.cs
@@ -19,6 +19,7 @@ namespace Discord.API.Rest
public Optional Nonce { get; set; }
public Optional IsTTS { get; set; }
public Optional