feature: Add support for spoiler formatting & attachments (#1255)
Resolves #1216. * Add support for spoiler formatting * Implement support for sending message attachments that are spoilers * use consistent naming * update docstring for new isSpoiler param * move extension method to be under core project, make spoiler prefix a const * typo fix * update missing xmldocs * move SpoilerPrefix const outside of interface * Add isSpoiler support to webhook client adds the isSpoiler field to uploading files with a webhook, which will only insert "SPOILER_" to the start of the filename. This does not include other fields in the payload, as this is not in the documentation, and was not observed like in the regular client
This commit is contained in:
committed by
Christopher F
parent
76f82d687b
commit
f3b20b2b6d
@@ -19,6 +19,7 @@ namespace Discord.API.Rest
|
||||
public Optional<string> Nonce { get; set; }
|
||||
public Optional<bool> IsTTS { get; set; }
|
||||
public Optional<Embed> Embed { get; set; }
|
||||
public bool IsSpoiler { get; set; } = false;
|
||||
|
||||
public UploadFileParams(Stream file)
|
||||
{
|
||||
@@ -28,7 +29,10 @@ namespace Discord.API.Rest
|
||||
public IReadOnlyDictionary<string, object> ToDictionary()
|
||||
{
|
||||
var d = new Dictionary<string, object>();
|
||||
d["file"] = new MultipartFile(File, Filename.GetValueOrDefault("unknown.dat"));
|
||||
var filename = Filename.GetValueOrDefault("unknown.dat");
|
||||
if (IsSpoiler && !filename.StartsWith(AttachmentExtensions.SpoilerPrefix))
|
||||
filename = filename.Insert(0, AttachmentExtensions.SpoilerPrefix);
|
||||
d["file"] = new MultipartFile(File, filename);
|
||||
|
||||
var payload = new Dictionary<string, object>();
|
||||
if (Content.IsSpecified)
|
||||
@@ -39,6 +43,8 @@ namespace Discord.API.Rest
|
||||
payload["nonce"] = Nonce.Value;
|
||||
if (Embed.IsSpecified)
|
||||
payload["embed"] = Embed.Value;
|
||||
if (IsSpoiler)
|
||||
payload["hasSpoiler"] = IsSpoiler.ToString();
|
||||
|
||||
var json = new StringBuilder();
|
||||
using (var text = new StringWriter(json))
|
||||
|
||||
@@ -22,6 +22,8 @@ namespace Discord.API.Rest
|
||||
public Optional<string> AvatarUrl { get; set; }
|
||||
public Optional<Embed[]> Embeds { get; set; }
|
||||
|
||||
public bool IsSpoiler { get; set; } = false;
|
||||
|
||||
public UploadWebhookFileParams(Stream file)
|
||||
{
|
||||
File = file;
|
||||
@@ -30,7 +32,11 @@ namespace Discord.API.Rest
|
||||
public IReadOnlyDictionary<string, object> ToDictionary()
|
||||
{
|
||||
var d = new Dictionary<string, object>();
|
||||
d["file"] = new MultipartFile(File, Filename.GetValueOrDefault("unknown.dat"));
|
||||
var filename = Filename.GetValueOrDefault("unknown.dat");
|
||||
if (IsSpoiler && !filename.StartsWith(AttachmentExtensions.SpoilerPrefix))
|
||||
filename = filename.Insert(0, AttachmentExtensions.SpoilerPrefix);
|
||||
|
||||
d["file"] = new MultipartFile(File, filename);
|
||||
|
||||
var payload = new Dictionary<string, object>();
|
||||
if (Content.IsSpecified)
|
||||
|
||||
@@ -199,18 +199,18 @@ namespace Discord.Rest
|
||||
/// <exception cref="IOException">An I/O error occurred while opening the file.</exception>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception>
|
||||
public static async Task<RestUserMessage> SendFileAsync(IMessageChannel channel, BaseDiscordClient client,
|
||||
string filePath, string text, bool isTTS, Embed embed, RequestOptions options)
|
||||
string filePath, string text, bool isTTS, Embed embed, RequestOptions options, bool isSpoiler)
|
||||
{
|
||||
string filename = Path.GetFileName(filePath);
|
||||
using (var file = File.OpenRead(filePath))
|
||||
return await SendFileAsync(channel, client, file, filename, text, isTTS, embed, options).ConfigureAwait(false);
|
||||
return await SendFileAsync(channel, client, file, filename, text, isTTS, embed, options, isSpoiler).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception>
|
||||
public static async Task<RestUserMessage> SendFileAsync(IMessageChannel channel, BaseDiscordClient client,
|
||||
Stream stream, string filename, string text, bool isTTS, Embed embed, RequestOptions options)
|
||||
Stream stream, string filename, string text, bool isTTS, Embed embed, RequestOptions options, bool isSpoiler)
|
||||
{
|
||||
var args = new UploadFileParams(stream) { Filename = filename, Content = text, IsTTS = isTTS, Embed = embed != null ? embed.ToModel() : Optional<API.Embed>.Unspecified };
|
||||
var args = new UploadFileParams(stream) { Filename = filename, Content = text, IsTTS = isTTS, Embed = embed != null ? embed.ToModel() : Optional<API.Embed>.Unspecified, IsSpoiler = isSpoiler };
|
||||
var model = await client.ApiClient.UploadFileAsync(channel.Id, args, options).ConfigureAwait(false);
|
||||
return RestUserMessage.Create(client, channel, client.CurrentUser, model);
|
||||
}
|
||||
|
||||
@@ -42,12 +42,12 @@ namespace Discord.Rest
|
||||
/// A task that represents an asynchronous send operation for delivering the message. The task result
|
||||
/// contains the sent message.
|
||||
/// </returns>
|
||||
new Task<RestUserMessage> SendFileAsync(string filePath, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null);
|
||||
new Task<RestUserMessage> SendFileAsync(string filePath, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false);
|
||||
/// <summary>
|
||||
/// Sends a file to this message channel with an optional caption.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method follows the same behavior as described in <see cref="IMessageChannel.SendFileAsync(Stream, string, string, bool, Embed, RequestOptions)"/>.
|
||||
/// This method follows the same behavior as described in <see cref="IMessageChannel.SendFileAsync(Stream, string, string, bool, Embed, RequestOptions, bool)"/>.
|
||||
/// Please visit its documentation for more details on this method.
|
||||
/// </remarks>
|
||||
/// <param name="stream">The <see cref="Stream" /> of the file to be sent.</param>
|
||||
@@ -60,7 +60,7 @@ namespace Discord.Rest
|
||||
/// A task that represents an asynchronous send operation for delivering the message. The task result
|
||||
/// contains the sent message.
|
||||
/// </returns>
|
||||
new Task<RestUserMessage> SendFileAsync(Stream stream, string filename, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null);
|
||||
new Task<RestUserMessage> SendFileAsync(Stream stream, string filename, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a message from this message channel.
|
||||
|
||||
@@ -121,12 +121,12 @@ namespace Discord.Rest
|
||||
/// <exception cref="NotSupportedException"><paramref name="filePath" /> is in an invalid format.</exception>
|
||||
/// <exception cref="IOException">An I/O error occurred while opening the file.</exception>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception>
|
||||
public Task<RestUserMessage> SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null)
|
||||
=> ChannelHelper.SendFileAsync(this, Discord, filePath, text, isTTS, embed, options);
|
||||
public Task<RestUserMessage> SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false)
|
||||
=> ChannelHelper.SendFileAsync(this, Discord, filePath, text, isTTS, embed, options, isSpoiler);
|
||||
/// <inheritdoc />
|
||||
/// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception>
|
||||
public Task<RestUserMessage> SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null)
|
||||
=> ChannelHelper.SendFileAsync(this, Discord, stream, filename, text, isTTS, embed, options);
|
||||
public Task<RestUserMessage> SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false)
|
||||
=> ChannelHelper.SendFileAsync(this, Discord, stream, filename, text, isTTS, embed, options, isSpoiler);
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task DeleteMessageAsync(ulong messageId, RequestOptions options = null)
|
||||
@@ -200,11 +200,11 @@ namespace Discord.Rest
|
||||
async Task<IReadOnlyCollection<IMessage>> IMessageChannel.GetPinnedMessagesAsync(RequestOptions options)
|
||||
=> await GetPinnedMessagesAsync(options).ConfigureAwait(false);
|
||||
/// <inheritdoc />
|
||||
async Task<IUserMessage> IMessageChannel.SendFileAsync(string filePath, string text, bool isTTS, Embed embed, RequestOptions options)
|
||||
=> await SendFileAsync(filePath, text, isTTS, embed, options).ConfigureAwait(false);
|
||||
async Task<IUserMessage> IMessageChannel.SendFileAsync(string filePath, string text, bool isTTS, Embed embed, RequestOptions options, bool isSpoiler)
|
||||
=> await SendFileAsync(filePath, text, isTTS, embed, options, isSpoiler).ConfigureAwait(false);
|
||||
/// <inheritdoc />
|
||||
async Task<IUserMessage> IMessageChannel.SendFileAsync(Stream stream, string filename, string text, bool isTTS, Embed embed, RequestOptions options)
|
||||
=> await SendFileAsync(stream, filename, text, isTTS, embed, options).ConfigureAwait(false);
|
||||
async Task<IUserMessage> IMessageChannel.SendFileAsync(Stream stream, string filename, string text, bool isTTS, Embed embed, RequestOptions options, bool isSpoiler)
|
||||
=> await SendFileAsync(stream, filename, text, isTTS, embed, options, isSpoiler).ConfigureAwait(false);
|
||||
/// <inheritdoc />
|
||||
async Task<IUserMessage> IMessageChannel.SendMessageAsync(string text, bool isTTS, Embed embed, RequestOptions options)
|
||||
=> await SendMessageAsync(text, isTTS, embed, options).ConfigureAwait(false);
|
||||
|
||||
@@ -123,12 +123,12 @@ namespace Discord.Rest
|
||||
/// <exception cref="NotSupportedException"><paramref name="filePath" /> is in an invalid format.</exception>
|
||||
/// <exception cref="IOException">An I/O error occurred while opening the file.</exception>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception>
|
||||
public Task<RestUserMessage> SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null)
|
||||
=> ChannelHelper.SendFileAsync(this, Discord, filePath, text, isTTS, embed, options);
|
||||
public Task<RestUserMessage> SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false)
|
||||
=> ChannelHelper.SendFileAsync(this, Discord, filePath, text, isTTS, embed, options, isSpoiler);
|
||||
/// <inheritdoc />
|
||||
/// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception>
|
||||
public Task<RestUserMessage> SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null)
|
||||
=> ChannelHelper.SendFileAsync(this, Discord, stream, filename, text, isTTS, embed, options);
|
||||
public Task<RestUserMessage> SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false)
|
||||
=> ChannelHelper.SendFileAsync(this, Discord, stream, filename, text, isTTS, embed, options, isSpoiler);
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task TriggerTypingAsync(RequestOptions options = null)
|
||||
@@ -178,11 +178,11 @@ namespace Discord.Rest
|
||||
async Task<IReadOnlyCollection<IMessage>> IMessageChannel.GetPinnedMessagesAsync(RequestOptions options)
|
||||
=> await GetPinnedMessagesAsync(options).ConfigureAwait(false);
|
||||
|
||||
async Task<IUserMessage> IMessageChannel.SendFileAsync(string filePath, string text, bool isTTS, Embed embed, RequestOptions options)
|
||||
=> await SendFileAsync(filePath, text, isTTS, embed, options).ConfigureAwait(false);
|
||||
async Task<IUserMessage> IMessageChannel.SendFileAsync(string filePath, string text, bool isTTS, Embed embed, RequestOptions options, bool isSpoiler)
|
||||
=> await SendFileAsync(filePath, text, isTTS, embed, options, isSpoiler).ConfigureAwait(false);
|
||||
|
||||
async Task<IUserMessage> IMessageChannel.SendFileAsync(Stream stream, string filename, string text, bool isTTS, Embed embed, RequestOptions options)
|
||||
=> await SendFileAsync(stream, filename, text, isTTS, embed, options).ConfigureAwait(false);
|
||||
async Task<IUserMessage> IMessageChannel.SendFileAsync(Stream stream, string filename, string text, bool isTTS, Embed embed, RequestOptions options, bool isSpoiler)
|
||||
=> await SendFileAsync(stream, filename, text, isTTS, embed, options, isSpoiler).ConfigureAwait(false);
|
||||
async Task<IUserMessage> IMessageChannel.SendMessageAsync(string text, bool isTTS, Embed embed, RequestOptions options)
|
||||
=> await SendMessageAsync(text, isTTS, embed, options).ConfigureAwait(false);
|
||||
|
||||
|
||||
@@ -129,13 +129,13 @@ namespace Discord.Rest
|
||||
/// <exception cref="NotSupportedException"><paramref name="filePath" /> is in an invalid format.</exception>
|
||||
/// <exception cref="IOException">An I/O error occurred while opening the file.</exception>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception>
|
||||
public Task<RestUserMessage> SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null)
|
||||
=> ChannelHelper.SendFileAsync(this, Discord, filePath, text, isTTS, embed, options);
|
||||
public Task<RestUserMessage> SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false)
|
||||
=> ChannelHelper.SendFileAsync(this, Discord, filePath, text, isTTS, embed, options, isSpoiler);
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception>
|
||||
public Task<RestUserMessage> SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null)
|
||||
=> ChannelHelper.SendFileAsync(this, Discord, stream, filename, text, isTTS, embed, options);
|
||||
public Task<RestUserMessage> SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false)
|
||||
=> ChannelHelper.SendFileAsync(this, Discord, stream, filename, text, isTTS, embed, options, isSpoiler);
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task DeleteMessageAsync(ulong messageId, RequestOptions options = null)
|
||||
@@ -266,12 +266,12 @@ namespace Discord.Rest
|
||||
=> await GetPinnedMessagesAsync(options).ConfigureAwait(false);
|
||||
|
||||
/// <inheritdoc />
|
||||
async Task<IUserMessage> IMessageChannel.SendFileAsync(string filePath, string text, bool isTTS, Embed embed, RequestOptions options)
|
||||
=> await SendFileAsync(filePath, text, isTTS, embed, options).ConfigureAwait(false);
|
||||
async Task<IUserMessage> IMessageChannel.SendFileAsync(string filePath, string text, bool isTTS, Embed embed, RequestOptions options, bool isSpoiler)
|
||||
=> await SendFileAsync(filePath, text, isTTS, embed, options, isSpoiler).ConfigureAwait(false);
|
||||
|
||||
/// <inheritdoc />
|
||||
async Task<IUserMessage> IMessageChannel.SendFileAsync(Stream stream, string filename, string text, bool isTTS, Embed embed, RequestOptions options)
|
||||
=> await SendFileAsync(stream, filename, text, isTTS, embed, options).ConfigureAwait(false);
|
||||
async Task<IUserMessage> IMessageChannel.SendFileAsync(Stream stream, string filename, string text, bool isTTS, Embed embed, RequestOptions options, bool isSpoiler)
|
||||
=> await SendFileAsync(stream, filename, text, isTTS, embed, options, isSpoiler).ConfigureAwait(false);
|
||||
/// <inheritdoc />
|
||||
async Task<IUserMessage> IMessageChannel.SendMessageAsync(string text, bool isTTS, Embed embed, RequestOptions options)
|
||||
=> await SendMessageAsync(text, isTTS, embed, options).ConfigureAwait(false);
|
||||
|
||||
Reference in New Issue
Block a user