Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow attaching embeds alongside a file upload. #978

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/Discord.Net.Core/Entities/Channels/IMessageChannel.cs
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
Expand All @@ -11,10 +11,10 @@ public interface IMessageChannel : IChannel
Task<IUserMessage> SendMessageAsync(string text, bool isTTS = false, Embed embed = null, RequestOptions options = null);
#if FILESYSTEM
/// <summary> Sends a file to this text channel, with an optional caption. </summary>
Task<IUserMessage> SendFileAsync(string filePath, string text = null, bool isTTS = false, RequestOptions options = null);
Task<IUserMessage> SendFileAsync(string filePath, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null);
#endif
/// <summary> Sends a file to this text channel, with an optional caption. </summary>
Task<IUserMessage> SendFileAsync(Stream stream, string filename, string text = null, bool isTTS = false, RequestOptions options = null);
Task<IUserMessage> SendFileAsync(Stream stream, string filename, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null);

/// <summary> Gets a message from this message channel with the given id, or null if not found. </summary>
Task<IMessage> GetMessageAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null);
Expand Down
22 changes: 12 additions & 10 deletions src/Discord.Net.Core/Extensions/UserExtensions.cs
@@ -1,4 +1,4 @@
using System.Threading.Tasks;
using System.Threading.Tasks;
using System.IO;

namespace Discord
Expand All @@ -8,10 +8,10 @@ public static class UserExtensions
/// <summary>
/// Sends a message to the user via DM.
/// </summary>
public static async Task<IUserMessage> SendMessageAsync(this IUser user,
string text,
public static async Task<IUserMessage> SendMessageAsync(this IUser user,
string text,
bool isTTS = false,
Embed embed = null,
Embed embed = null,
RequestOptions options = null)
{
return await (await user.GetOrCreateDMChannelAsync().ConfigureAwait(false)).SendMessageAsync(text, isTTS, embed, options).ConfigureAwait(false);
Expand All @@ -25,23 +25,25 @@ public static class UserExtensions
string filename,
string text = null,
bool isTTS = false,
Embed embed = null,
RequestOptions options = null
)
{
return await (await user.GetOrCreateDMChannelAsync().ConfigureAwait(false)).SendFileAsync(stream, filename, text, isTTS, options).ConfigureAwait(false);
return await (await user.GetOrCreateDMChannelAsync().ConfigureAwait(false)).SendFileAsync(stream, filename, text, isTTS, embed, options).ConfigureAwait(false);
}

#if FILESYSTEM
/// <summary>
/// Sends a file to the user via DM.
/// </summary>
public static async Task<IUserMessage> SendFileAsync(this IUser user,
string filePath,
string text = null,
bool isTTS = false,
public static async Task<IUserMessage> SendFileAsync(this IUser user,
string filePath,
string text = null,
bool isTTS = false,
Embed embed = null,
RequestOptions options = null)
{
return await (await user.GetOrCreateDMChannelAsync().ConfigureAwait(false)).SendFileAsync(filePath, text, isTTS, options).ConfigureAwait(false);
return await (await user.GetOrCreateDMChannelAsync().ConfigureAwait(false)).SendFileAsync(filePath, text, isTTS, embed, options).ConfigureAwait(false);
}
#endif
}
Expand Down
22 changes: 21 additions & 1 deletion src/Discord.Net.Rest/API/Rest/UploadFileParams.cs
@@ -1,18 +1,25 @@
#pragma warning disable CS1591
#pragma warning disable CS1591
using Discord.Net.Converters;
using Discord.Net.Rest;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text;

namespace Discord.API.Rest
{
internal class UploadFileParams
{
private static JsonSerializer _serializer = new JsonSerializer { ContractResolver = new DiscordContractResolver() };

public Stream File { get; }

public Optional<string> Filename { get; set; }
public Optional<string> Content { get; set; }
public Optional<string> Nonce { get; set; }
public Optional<bool> IsTTS { get; set; }
public Optional<Embed> Embed { get; set; }

public UploadFileParams(Stream file)
{
Expand All @@ -29,6 +36,19 @@ public UploadFileParams(Stream file)
d["tts"] = IsTTS.Value.ToString();
if (Nonce.IsSpecified)
d["nonce"] = Nonce.Value;
if (Embed.IsSpecified)
{
var sb = new StringBuilder(256);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any cleaner approach here? The DefaultRestClient seems to support serializing Streams here, could use a MemoryStream+StreamWriter instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really, the embed data needs to be URL encoded, something I'm not sure I can do from a MemoryStream without even more mess

using (TextWriter text = new StringWriter(sb, CultureInfo.InvariantCulture))
using (JsonWriter writer = new JsonTextWriter(text))
{
Dictionary<string, object> dictionary = new Dictionary<string, object>();
dictionary["embed"] = Embed.Value;

_serializer.Serialize(writer, dictionary);
}
d["payload_json"] = sb.ToString();
}
return d;
}
}
Expand Down
10 changes: 5 additions & 5 deletions src/Discord.Net.Rest/Entities/Channels/ChannelHelper.cs
@@ -1,4 +1,4 @@
using Discord.API.Rest;
using Discord.API.Rest;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
Expand Down Expand Up @@ -170,17 +170,17 @@ internal static class ChannelHelper

#if FILESYSTEM
public static async Task<RestUserMessage> SendFileAsync(IMessageChannel channel, BaseDiscordClient client,
string filePath, string text, bool isTTS, RequestOptions options)
string filePath, string text, bool isTTS, Embed embed, RequestOptions options)
{
string filename = Path.GetFileName(filePath);
using (var file = File.OpenRead(filePath))
return await SendFileAsync(channel, client, file, filename, text, isTTS, options).ConfigureAwait(false);
return await SendFileAsync(channel, client, file, filename, text, isTTS, embed, options).ConfigureAwait(false);
}
#endif
public static async Task<RestUserMessage> SendFileAsync(IMessageChannel channel, BaseDiscordClient client,
Stream stream, string filename, string text, bool isTTS, RequestOptions options)
Stream stream, string filename, string text, bool isTTS, Embed embed, RequestOptions options)
{
var args = new UploadFileParams(stream) { Filename = filename, Content = text, IsTTS = isTTS };
var args = new UploadFileParams(stream) { Filename = filename, Content = text, IsTTS = isTTS, Embed = embed?.ToModel() };
var model = await client.ApiClient.UploadFileAsync(channel.Id, args, options).ConfigureAwait(false);
return RestUserMessage.Create(client, channel, client.CurrentUser, model);
}
Expand Down
6 changes: 3 additions & 3 deletions src/Discord.Net.Rest/Entities/Channels/IRestMessageChannel.cs
@@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;

Expand All @@ -10,10 +10,10 @@ public interface IRestMessageChannel : IMessageChannel
new Task<RestUserMessage> SendMessageAsync(string text, bool isTTS = false, Embed embed = null, RequestOptions options = null);
#if FILESYSTEM
/// <summary> Sends a file to this text channel, with an optional caption. </summary>
new Task<RestUserMessage> SendFileAsync(string filePath, string text = null, bool isTTS = false, RequestOptions options = null);
new Task<RestUserMessage> SendFileAsync(string filePath, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null);
#endif
/// <summary> Sends a file to this text channel, with an optional caption. </summary>
new Task<RestUserMessage> SendFileAsync(Stream stream, string filename, string text = null, bool isTTS = false, RequestOptions options = null);
new Task<RestUserMessage> SendFileAsync(Stream stream, string filename, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null);

/// <summary> Gets a message from this message channel with the given id, or null if not found. </summary>
Task<RestMessage> GetMessageAsync(ulong id, RequestOptions options = null);
Expand Down
20 changes: 10 additions & 10 deletions src/Discord.Net.Rest/Entities/Channels/RestDMChannel.cs
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
Expand Down Expand Up @@ -37,7 +37,7 @@ internal override void Update(Model model)
public override async Task UpdateAsync(RequestOptions options = null)
{
var model = await Discord.ApiClient.GetChannelAsync(Id, options).ConfigureAwait(false);
Update(model);
Update(model);
}
public Task CloseAsync(RequestOptions options = null)
=> ChannelHelper.DeleteAsync(this, Discord, options);
Expand Down Expand Up @@ -66,11 +66,11 @@ public Task<IReadOnlyCollection<RestMessage>> GetPinnedMessagesAsync(RequestOpti
public Task<RestUserMessage> SendMessageAsync(string text, bool isTTS = false, Embed embed = null, RequestOptions options = null)
=> ChannelHelper.SendMessageAsync(this, Discord, text, isTTS, embed, options);
#if FILESYSTEM
public Task<RestUserMessage> SendFileAsync(string filePath, string text, bool isTTS = false, RequestOptions options = null)
=> ChannelHelper.SendFileAsync(this, Discord, filePath, text, isTTS, options);
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);
#endif
public Task<RestUserMessage> SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, RequestOptions options = null)
=> ChannelHelper.SendFileAsync(this, Discord, stream, filename, text, isTTS, options);
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 TriggerTypingAsync(RequestOptions options = null)
=> ChannelHelper.TriggerTypingAsync(this, Discord, options);
Expand Down Expand Up @@ -122,11 +122,11 @@ async Task<IReadOnlyCollection<IMessage>> IMessageChannel.GetPinnedMessagesAsync
=> await GetPinnedMessagesAsync(options).ConfigureAwait(false);

#if FILESYSTEM
async Task<IUserMessage> IMessageChannel.SendFileAsync(string filePath, string text, bool isTTS, RequestOptions options)
=> await SendFileAsync(filePath, text, isTTS, 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);
#endif
async Task<IUserMessage> IMessageChannel.SendFileAsync(Stream stream, string filename, string text, bool isTTS, RequestOptions options)
=> await SendFileAsync(stream, filename, text, isTTS, options).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.SendMessageAsync(string text, bool isTTS, Embed embed, RequestOptions options)
=> await SendMessageAsync(text, isTTS, embed, options).ConfigureAwait(false);
IDisposable IMessageChannel.EnterTypingState(RequestOptions options)
Expand Down
20 changes: 10 additions & 10 deletions src/Discord.Net.Rest/Entities/Channels/RestGroupChannel.cs
@@ -1,4 +1,4 @@
using Discord.Audio;
using Discord.Audio;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
Expand All @@ -19,7 +19,7 @@ public class RestGroupChannel : RestChannel, IGroupChannel, IRestPrivateChannel,
public string Name { get; private set; }

public IReadOnlyCollection<RestGroupUser> Users => _users.ToReadOnlyCollection();
public IReadOnlyCollection<RestGroupUser> Recipients
public IReadOnlyCollection<RestGroupUser> Recipients
=> _users.Select(x => x.Value).Where(x => x.Id != Discord.CurrentUser.Id).ToReadOnlyCollection(() => _users.Count - 1);

internal RestGroupChannel(BaseDiscordClient discord, ulong id)
Expand Down Expand Up @@ -79,11 +79,11 @@ public Task<IReadOnlyCollection<RestMessage>> GetPinnedMessagesAsync(RequestOpti
public Task<RestUserMessage> SendMessageAsync(string text, bool isTTS = false, Embed embed = null, RequestOptions options = null)
=> ChannelHelper.SendMessageAsync(this, Discord, text, isTTS, embed, options);
#if FILESYSTEM
public Task<RestUserMessage> SendFileAsync(string filePath, string text, bool isTTS = false, RequestOptions options = null)
=> ChannelHelper.SendFileAsync(this, Discord, filePath, text, isTTS, options);
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);
#endif
public Task<RestUserMessage> SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, RequestOptions options = null)
=> ChannelHelper.SendFileAsync(this, Discord, stream, filename, text, isTTS, options);
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 TriggerTypingAsync(RequestOptions options = null)
=> ChannelHelper.TriggerTypingAsync(this, Discord, options);
Expand Down Expand Up @@ -132,11 +132,11 @@ async Task<IReadOnlyCollection<IMessage>> IMessageChannel.GetPinnedMessagesAsync
=> await GetPinnedMessagesAsync(options).ConfigureAwait(false);

#if FILESYSTEM
async Task<IUserMessage> IMessageChannel.SendFileAsync(string filePath, string text, bool isTTS, RequestOptions options)
=> await SendFileAsync(filePath, text, isTTS, 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);
#endif
async Task<IUserMessage> IMessageChannel.SendFileAsync(Stream stream, string filename, string text, bool isTTS, RequestOptions options)
=> await SendFileAsync(stream, filename, text, isTTS, options).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.SendMessageAsync(string text, bool isTTS, Embed embed, RequestOptions options)
=> await SendMessageAsync(text, isTTS, embed, options).ConfigureAwait(false);
IDisposable IMessageChannel.EnterTypingState(RequestOptions options)
Expand Down
24 changes: 12 additions & 12 deletions src/Discord.Net.Rest/Entities/Channels/RestTextChannel.cs
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
Expand Down Expand Up @@ -61,11 +61,11 @@ public Task<IReadOnlyCollection<RestMessage>> GetPinnedMessagesAsync(RequestOpti
public Task<RestUserMessage> SendMessageAsync(string text, bool isTTS = false, Embed embed = null, RequestOptions options = null)
=> ChannelHelper.SendMessageAsync(this, Discord, text, isTTS, embed, options);
#if FILESYSTEM
public Task<RestUserMessage> SendFileAsync(string filePath, string text, bool isTTS = false, RequestOptions options = null)
=> ChannelHelper.SendFileAsync(this, Discord, filePath, text, isTTS, options);
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);
#endif
public Task<RestUserMessage> SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, RequestOptions options = null)
=> ChannelHelper.SendFileAsync(this, Discord, stream, filename, text, isTTS, options);
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 DeleteMessagesAsync(IEnumerable<IMessage> messages, RequestOptions options = null)
=> ChannelHelper.DeleteMessagesAsync(this, Discord, messages.Select(x => x.Id), options);
Expand Down Expand Up @@ -123,18 +123,18 @@ IAsyncEnumerable<IReadOnlyCollection<IMessage>> IMessageChannel.GetMessagesAsync
else
return AsyncEnumerable.Empty<IReadOnlyCollection<IMessage>>();
}
async Task<IReadOnlyCollection<IMessage>> IMessageChannel.GetPinnedMessagesAsync(RequestOptions options)
async Task<IReadOnlyCollection<IMessage>> IMessageChannel.GetPinnedMessagesAsync(RequestOptions options)
=> await GetPinnedMessagesAsync(options).ConfigureAwait(false);

#if FILESYSTEM
async Task<IUserMessage> IMessageChannel.SendFileAsync(string filePath, string text, bool isTTS, RequestOptions options)
=> await SendFileAsync(filePath, text, isTTS, 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);
#endif
async Task<IUserMessage> IMessageChannel.SendFileAsync(Stream stream, string filename, string text, bool isTTS, RequestOptions options)
=> await SendFileAsync(stream, filename, text, isTTS, options).ConfigureAwait(false);
async Task<IUserMessage> IMessageChannel.SendMessageAsync(string text, bool isTTS, Embed embed, RequestOptions options)
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.SendMessageAsync(string text, bool isTTS, Embed embed, RequestOptions options)
=> await SendMessageAsync(text, isTTS, embed, options).ConfigureAwait(false);
IDisposable IMessageChannel.EnterTypingState(RequestOptions options)
IDisposable IMessageChannel.EnterTypingState(RequestOptions options)
=> EnterTypingState(options);

//IGuildChannel
Expand Down