Support attachments in embeds
Created by: uwx
Summary
Adds support for attachments in embeds.
This is how it looks currently:
This is how it can, and should look:
Details
At the moment, the lib stores URLs in embeds as Uri objects. Seems reasonable, but not to Discord. Attachments in embeds are possible by using a weird non-standard attachment://FILENAME
protocol. This is where the problems start: According to some people pretending to own the Internet, the hostname in the URI should implicitly contain a trailing slash (or something like that) and the implementation of Uri in .NET takes this very literally. The trailing slash added by .NET, of course, makes the image URL be silently ignored. I haven't been able to figure out why the attachments in some fields work anyway, but this makes the behavior consistent.
Changes proposed
I've implemented a class DiscordUri
that functions as an union of string
(for attachment://
) or Uri
(for everything else). It includes a custom serializer and should function as a drop-in replacement for Uri. Of course, for efficiency's sake, I wouldn't recommend using it for anything other than the embeds.
I also cleaned up some spaghetti code in DiscordJson
that was making it really hard to work with.
Notes
This is the command I used to test this PR, both before and after the changes:
[Command("test420")]
public Task Test420(CommandContext ctx)
{
return ctx.RespondWithFilesAsync(embed: new DiscordEmbedBuilder
{
Author = new DiscordEmbedBuilder.EmbedAuthor
{
IconUrl = "attachment://attachment1.png",
Name = "fofof"
},
Footer = new DiscordEmbedBuilder.EmbedFooter
{
IconUrl = "attachment://attachment2.png",
Text = "foobar"
},
ImageUrl = "attachment://attachment3.png",
ThumbnailUrl = "attachment://attachment4.png",
Description = "hello there"
}, files: new Dictionary<string, Stream>
{
["attachment1.png"] = new FileStream(@"C:\Users\Rafael\Pictures\3.0.png", FileMode.Open, FileAccess.Read),
["attachment2.png"] = new FileStream(@"C:\Users\Rafael\Pictures\3.0.png", FileMode.Open, FileAccess.Read),
["attachment3.png"] = new FileStream(@"C:\Users\Rafael\Pictures\3.0.png", FileMode.Open, FileAccess.Read),
["attachment4.png"] = new FileStream(@"C:\Users\Rafael\Pictures\3.0.png", FileMode.Open, FileAccess.Read),
["attachment5.png"] = new FileStream(@"C:\Users\Rafael\Pictures\3.0.png", FileMode.Open, FileAccess.Read),
});
}