From 0a672addcf83b322c39743ed20da7b15adc96e1e Mon Sep 17 00:00:00 2001
From: Armano den Boef <68127614+Rozen4334@users.noreply.github.com>
Date: Wed, 9 Feb 2022 02:44:55 +0100
Subject: [PATCH 1/7] Create bugreport.yml (#2080)
* Create bugreport.yml
Grabbed from Discord.Net-Labs, original by @CottageDwellingCat
* Append faq link
Co-authored-by: Quin Lynch <49576606+quinchs@users.noreply.github.com>
* Append migration guide
Co-authored-by: Quin Lynch <49576606+quinchs@users.noreply.github.com>
* Append version change
Co-authored-by: Quin Lynch <49576606+quinchs@users.noreply.github.com>
* Append body
Co-authored-by: Quin Lynch <49576606+quinchs@users.noreply.github.com>
* Fix 5/???
smh I was tired when I committed this and didnt bother making changes assuming it was already good :'')
Co-authored-by: Quin Lynch <49576606+quinchs@users.noreply.github.com>
Co-authored-by: Quin Lynch <49576606+quinchs@users.noreply.github.com>
---
.github/ISSUE_TEMPLATE/bugreport.yml | 77 ++++++++++++++++++++++++++++
1 file changed, 77 insertions(+)
create mode 100644 .github/ISSUE_TEMPLATE/bugreport.yml
diff --git a/.github/ISSUE_TEMPLATE/bugreport.yml b/.github/ISSUE_TEMPLATE/bugreport.yml
new file mode 100644
index 000000000..81cac4af7
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bugreport.yml
@@ -0,0 +1,77 @@
+name: 🐞 Bug Report
+description: File a bug report
+title: "[Bug]: "
+labels: ["bug"]
+body:
+ - type: markdown
+ attributes:
+ value: Thanks for taking the time to fill out this bug report!
+ - type: checkboxes
+ attributes:
+ label: Check The Docs
+ description: Please refer to our [FAQs](https://discordnet.dev/faq/basics/getting-started.html), [Documentation](https://discordnet.dev/api/index.html),
+ and [Migration Guide](https://discordnet.dev/guides/v2_v3_guide/v2_to_v3_guide.html) before reporting issues.
+ options:
+ - label: "I double checked the docs and couldn't find any useful information."
+ required: true
+ - type: checkboxes
+ attributes:
+ label: Verify Issue Source
+ description: If your issue is related to an exception make sure the error was thrown by Discord.Net, and not your code or another library.
+ If you get an `HttpException` with the error code `401`, then the error is caused by your bot's permissions, not dnet.
+ options:
+ - label: I verified the issue was caused by Discord.Net.
+ required: true
+ - type: checkboxes
+ attributes:
+ label: Check your intents
+ description: If your issue is related to not receiving expected events, you may have setup your gateway intents incorrectly.
+ Newer versions of Discord.Net use a more modern version of Discord's API that requires you tell it what events
+ you want to receive. Discord.Net defaults to all non-privleged intents, but if your bot requires privileged intents
+ you need specify them in your clients config. You can see what intents you need for your events
+ [here](https://discord.com/developers/docs/topics/gateway#list-of-intents).
+ options:
+ - label: I double checked that I have the required intents.
+ required: true
+ - type: textarea
+ id: description
+ attributes:
+ label: Description
+ description: A brief explination of the bug.
+ placeholder: When I start a DiscordSocketClient without stopping it, the gateway thread gets blocked.
+ validations:
+ required: true
+ - type: input
+ id: version
+ attributes:
+ label: Version
+ description: What version of Discord.Net are you using?
+ placeholder: ex. 3.1.0
+ validations:
+ required: true
+ - type: input
+ id: working-version
+ attributes:
+ label: Working Version
+ description: If this worked on an older version of Discord.Net put that version here.
+ placeholder: ex. 2.4.0
+ validations:
+ required: false
+ - type: textarea
+ id: logs
+ attributes:
+ label: Logs
+ description: Add applicable logs and/or a stacktrace here.
+ validations:
+ required: true
+ - type: textarea
+ id: sample
+ attributes:
+ label: Sample
+ description: Include a (short) code sample that reproduces your issue 100% of time (comments would be great).
+ placeholder: |
+ ```cs
+ My.Code();
+ ```
+ validations:
+ required: false
From 75e94feab0f61a8de2e06a4ec26e33af1369d08b Mon Sep 17 00:00:00 2001
From: Quin Lynch <49576606+quinchs@users.noreply.github.com>
Date: Tue, 8 Feb 2022 21:45:48 -0400
Subject: [PATCH 2/7] Add IEnumerable collection parameters instead of arrays
for MessageExtensions (#2079)
---
src/Discord.Net.Core/Extensions/MessageExtensions.cs | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/Discord.Net.Core/Extensions/MessageExtensions.cs b/src/Discord.Net.Core/Extensions/MessageExtensions.cs
index c187ecd5b..cf330c44d 100644
--- a/src/Discord.Net.Core/Extensions/MessageExtensions.cs
+++ b/src/Discord.Net.Core/Extensions/MessageExtensions.cs
@@ -1,3 +1,4 @@
+using System.Collections.Generic;
using System.Threading.Tasks;
namespace Discord
@@ -41,7 +42,7 @@ namespace Discord
///
///
///
- public static async Task AddReactionsAsync(this IUserMessage msg, IEmote[] reactions, RequestOptions options = null)
+ public static async Task AddReactionsAsync(this IUserMessage msg, IEnumerable reactions, RequestOptions options = null)
{
foreach (var rxn in reactions)
await msg.AddReactionAsync(rxn, options).ConfigureAwait(false);
@@ -67,7 +68,7 @@ namespace Discord
///
///
///
- public static async Task RemoveReactionsAsync(this IUserMessage msg, IUser user, IEmote[] reactions, RequestOptions options = null)
+ public static async Task RemoveReactionsAsync(this IUserMessage msg, IUser user, IEnumerable reactions, RequestOptions options = null)
{
foreach (var rxn in reactions)
await msg.RemoveReactionAsync(rxn, user, options).ConfigureAwait(false);
From b424bb2019147426dd8b5040dc6ad25fed96994a Mon Sep 17 00:00:00 2001
From: Quin Lynch <49576606+quinchs@users.noreply.github.com>
Date: Wed, 9 Feb 2022 00:12:07 -0400
Subject: [PATCH 3/7] Fix Current user null on reconnect (#2092)
---
src/Discord.Net.WebSocket/DiscordSocketClient.cs | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/src/Discord.Net.WebSocket/DiscordSocketClient.cs b/src/Discord.Net.WebSocket/DiscordSocketClient.cs
index 349e2714f..e8e210e1a 100644
--- a/src/Discord.Net.WebSocket/DiscordSocketClient.cs
+++ b/src/Discord.Net.WebSocket/DiscordSocketClient.cs
@@ -46,6 +46,7 @@ namespace Discord.WebSocket
private bool _isDisposed;
private GatewayIntents _gatewayIntents;
private ImmutableArray> _defaultStickers;
+ private SocketSelfUser _previousSessionUser;
///
/// Provides access to a REST-only client with a shared state from this client.
@@ -888,6 +889,7 @@ namespace Discord.WebSocket
_sessionId = data.SessionId;
_unavailableGuildCount = unavailableGuilds;
CurrentUser = currentUser;
+ _previousSessionUser = CurrentUser;
State = state;
}
catch (Exception ex)
@@ -930,6 +932,9 @@ namespace Discord.WebSocket
await GuildAvailableAsync(guild).ConfigureAwait(false);
}
+ // Restore the previous sessions current user
+ CurrentUser = _previousSessionUser;
+
await _gatewayLogger.InfoAsync("Resumed previous session").ConfigureAwait(false);
}
break;
From 97e54e10476a51fe17b2cc388d5ae5fe8add18af Mon Sep 17 00:00:00 2001
From: Quin Lynch <49576606+quinchs@users.noreply.github.com>
Date: Wed, 9 Feb 2022 00:12:22 -0400
Subject: [PATCH 4/7] Feature: Allow modifying attachments on interactions and
extend the module base (#2091)
---
.../InteractionModuleBase.cs | 53 ++++++++++++++++++-
src/Discord.Net.Rest/DiscordRestApiClient.cs | 6 +++
.../Interactions/InteractionHelper.cs | 31 ++++++++---
3 files changed, 81 insertions(+), 9 deletions(-)
diff --git a/src/Discord.Net.Interactions/InteractionModuleBase.cs b/src/Discord.Net.Interactions/InteractionModuleBase.cs
index 95e64916f..997542a2e 100644
--- a/src/Discord.Net.Interactions/InteractionModuleBase.cs
+++ b/src/Discord.Net.Interactions/InteractionModuleBase.cs
@@ -1,4 +1,7 @@
+using Discord.Rest;
using System;
+using System.Collections.Generic;
+using System.IO;
using System.Threading.Tasks;
namespace Discord.Interactions
@@ -47,18 +50,66 @@ namespace Discord.Interactions
AllowedMentions allowedMentions = null, RequestOptions options = null, MessageComponent components = null, Embed embed = null) =>
await Context.Interaction.RespondAsync(text, embeds, isTTS, ephemeral, allowedMentions, components, embed, options).ConfigureAwait(false);
+ ///
+ protected virtual Task RespondWithFileAsync(Stream fileStream, string fileName, string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false,
+ AllowedMentions allowedMentions = null, MessageComponent components = null, Embed embed = null, RequestOptions options = null)
+ => Context.Interaction.RespondWithFileAsync(fileStream, fileName, text, embeds, isTTS, ephemeral, allowedMentions, components, embed, options);
+
+ ///
+ protected virtual Task RespondWithFileAsync(string filePath, string fileName = null, string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false,
+ AllowedMentions allowedMentions = null, MessageComponent components = null, Embed embed = null, RequestOptions options = null)
+ => Context.Interaction.RespondWithFileAsync(filePath, fileName, text, embeds, isTTS, ephemeral, allowedMentions, components, embed, options);
+
+ ///
+ protected virtual Task RespondWithFileAsync(FileAttachment attachment, string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false,
+ AllowedMentions allowedMentions = null, MessageComponent components = null, Embed embed = null, RequestOptions options = null)
+ => Context.Interaction.RespondWithFileAsync(attachment, text, embeds, isTTS, ephemeral, allowedMentions, components, embed, options);
+
+ ///
+ protected virtual Task RespondWithFilesAsync(IEnumerable attachments, string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false,
+ AllowedMentions allowedMentions = null, MessageComponent components = null, Embed embed = null, RequestOptions options = null)
+ => Context.Interaction.RespondWithFilesAsync(attachments, text, embeds, isTTS, ephemeral, allowedMentions, components, embed, options);
+
///
protected virtual async Task FollowupAsync (string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false,
AllowedMentions allowedMentions = null, RequestOptions options = null, MessageComponent components = null, Embed embed = null) =>
await Context.Interaction.FollowupAsync(text, embeds, isTTS, ephemeral, allowedMentions, components, embed, options).ConfigureAwait(false);
+ ///
+ protected virtual Task FollowupWithFileAsync(Stream fileStream, string fileName, string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false,
+ AllowedMentions allowedMentions = null, MessageComponent components = null, Embed embed = null, RequestOptions options = null)
+ => Context.Interaction.FollowupWithFileAsync(fileStream, fileName, text, embeds, isTTS, ephemeral, allowedMentions, components, embed, options);
+
+ ///
+ protected virtual Task FollowupWithFileAsync(string filePath, string fileName = null, string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false,
+ AllowedMentions allowedMentions = null, MessageComponent components = null, Embed embed = null, RequestOptions options = null)
+ => Context.Interaction.FollowupWithFileAsync(filePath, fileName, text, embeds, isTTS, ephemeral, allowedMentions, components, embed, options);
+
+ ///
+ protected virtual Task FollowupWithFileAsync(FileAttachment attachment, string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false,
+ AllowedMentions allowedMentions = null, MessageComponent components = null, Embed embed = null, RequestOptions options = null)
+ => Context.Interaction.FollowupWithFileAsync(attachment, text, embeds, isTTS, ephemeral, allowedMentions, components, embed, options);
+
+ ///
+ protected virtual Task FollowupWithFilesAsync(IEnumerable attachments, string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false,
+ AllowedMentions allowedMentions = null, MessageComponent components = null, Embed embed = null, RequestOptions options = null)
+ => Context.Interaction.FollowupWithFilesAsync(attachments, text, embeds, isTTS, ephemeral, allowedMentions, components, embed, options);
+
///
protected virtual async Task ReplyAsync (string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null,
AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent components = null) =>
await Context.Channel.SendMessageAsync(text, false, embed, options, allowedMentions, messageReference, components).ConfigureAwait(false);
+ ///
+ protected virtual Task GetOriginalResponseAsync(RequestOptions options = null)
+ => Context.Interaction.GetOriginalResponseAsync(options);
+
+ ///
+ protected virtual Task ModifyOriginalResponseAsync(Action func, RequestOptions options = null)
+ => Context.Interaction.ModifyOriginalResponseAsync(func, options);
+
///
- protected virtual async Task DeleteOriginalResponseAsync ( )
+ protected virtual async Task DeleteOriginalResponseAsync()
{
var response = await Context.Interaction.GetOriginalResponseAsync().ConfigureAwait(false);
await response.DeleteAsync().ConfigureAwait(false);
diff --git a/src/Discord.Net.Rest/DiscordRestApiClient.cs b/src/Discord.Net.Rest/DiscordRestApiClient.cs
index 129465618..f6d579d79 100644
--- a/src/Discord.Net.Rest/DiscordRestApiClient.cs
+++ b/src/Discord.Net.Rest/DiscordRestApiClient.cs
@@ -1362,6 +1362,12 @@ namespace Discord.API
return await SendJsonAsync("PATCH", () => $"webhooks/{CurrentApplicationId}/{interactionToken}/messages/@original", args, new BucketIds(), options: options);
}
+ public async Task ModifyInteractionResponseAsync(UploadWebhookFileParams args, string interactionToken, RequestOptions options = null)
+ {
+ options = RequestOptions.CreateOrClone(options);
+
+ return await SendMultipartAsync("PATCH", () => $"webhooks/{CurrentApplicationId}/{interactionToken}/messages/@original", args.ToDictionary(), new BucketIds(), options: options);
+ }
public async Task DeleteInteractionResponseAsync(string interactionToken, RequestOptions options = null)
{
options = RequestOptions.CreateOrClone(options);
diff --git a/src/Discord.Net.Rest/Entities/Interactions/InteractionHelper.cs b/src/Discord.Net.Rest/Entities/Interactions/InteractionHelper.cs
index 8605bf02b..e345bfa94 100644
--- a/src/Discord.Net.Rest/Entities/Interactions/InteractionHelper.cs
+++ b/src/Discord.Net.Rest/Entities/Interactions/InteractionHelper.cs
@@ -424,16 +424,31 @@ namespace Discord.Rest
Preconditions.AtMost(apiEmbeds?.Count ?? 0, 10, nameof(args.Embeds), "A max of 10 embeds are allowed.");
- var apiArgs = new ModifyInteractionResponseParams
+ if (!args.Attachments.IsSpecified)
{
- Content = args.Content,
- Embeds = apiEmbeds?.ToArray() ?? Optional.Unspecified,
- AllowedMentions = args.AllowedMentions.IsSpecified ? args.AllowedMentions.Value?.ToModel() : Optional.Unspecified,
- Components = args.Components.IsSpecified ? args.Components.Value?.Components.Select(x => new API.ActionRowComponent(x)).ToArray() : Optional.Unspecified,
- Flags = args.Flags
- };
+ var apiArgs = new ModifyInteractionResponseParams
+ {
+ Content = args.Content,
+ Embeds = apiEmbeds?.ToArray() ?? Optional.Unspecified,
+ AllowedMentions = args.AllowedMentions.IsSpecified ? args.AllowedMentions.Value?.ToModel() : Optional.Unspecified,
+ Components = args.Components.IsSpecified ? args.Components.Value?.Components.Select(x => new API.ActionRowComponent(x)).ToArray() : Optional.Unspecified,
+ Flags = args.Flags
+ };
- return await client.ApiClient.ModifyInteractionResponseAsync(apiArgs, token, options).ConfigureAwait(false);
+ return await client.ApiClient.ModifyInteractionResponseAsync(apiArgs, token, options).ConfigureAwait(false);
+ }
+ else
+ {
+ var apiArgs = new UploadWebhookFileParams(args.Attachments.Value.ToArray())
+ {
+ Content = args.Content,
+ Embeds = apiEmbeds?.ToArray() ?? Optional.Unspecified,
+ AllowedMentions = args.AllowedMentions.IsSpecified ? args.AllowedMentions.Value?.ToModel() : Optional.Unspecified,
+ MessageComponents = args.Components.IsSpecified ? args.Components.Value?.Components.Select(x => new API.ActionRowComponent(x)).ToArray() : Optional.Unspecified,
+ };
+
+ return await client.ApiClient.ModifyInteractionResponseAsync(apiArgs, token, options).ConfigureAwait(false);
+ }
}
public static async Task DeleteInteractionResponseAsync(BaseDiscordClient client, RestInteractionMessage message, RequestOptions options = null)
From 6290f75359c1ad5b7a610601b124dd867d5dafb6 Mon Sep 17 00:00:00 2001
From: Quin Lynch <49576606+quinchs@users.noreply.github.com>
Date: Wed, 9 Feb 2022 00:12:41 -0400
Subject: [PATCH 5/7] Fix attempts to fetch channels in interactions (#2090)
* fix attempts to fetch channels in interactions
* remove test case
---
.../Entities/Interactions/RestInteraction.cs | 7 +-
.../DiscordSocketClient.cs | 70 +++++++------------
.../Entities/Interaction/SocketInteraction.cs | 4 ++
3 files changed, 35 insertions(+), 46 deletions(-)
diff --git a/src/Discord.Net.Rest/Entities/Interactions/RestInteraction.cs b/src/Discord.Net.Rest/Entities/Interactions/RestInteraction.cs
index c4d66c642..566d60d14 100644
--- a/src/Discord.Net.Rest/Entities/Interactions/RestInteraction.cs
+++ b/src/Discord.Net.Rest/Entities/Interactions/RestInteraction.cs
@@ -7,6 +7,7 @@ using System.Threading.Tasks;
using Model = Discord.API.Interaction;
using DataModel = Discord.API.ApplicationCommandInteractionData;
using Newtonsoft.Json;
+using Discord.Net;
namespace Discord.Rest
{
@@ -130,7 +131,11 @@ namespace Discord.Rest
if(Channel == null && model.ChannelId.IsSpecified)
{
- Channel = (IRestMessageChannel)await discord.GetChannelAsync(model.ChannelId.Value);
+ try
+ {
+ Channel = (IRestMessageChannel)await discord.GetChannelAsync(model.ChannelId.Value);
+ }
+ catch(HttpException x) when(x.DiscordCode == DiscordErrorCode.MissingPermissions) { } // ignore
}
UserLocale = model.UserLocale.IsSpecified
diff --git a/src/Discord.Net.WebSocket/DiscordSocketClient.cs b/src/Discord.Net.WebSocket/DiscordSocketClient.cs
index e8e210e1a..dab07d3e2 100644
--- a/src/Discord.Net.WebSocket/DiscordSocketClient.cs
+++ b/src/Discord.Net.WebSocket/DiscordSocketClient.cs
@@ -2243,57 +2243,37 @@ namespace Discord.WebSocket
channel = State.GetDMChannel(data.User.Value.Id);
}
- if (channel == null)
+ var guild = (channel as SocketGuildChannel)?.Guild;
+ if (guild != null && !guild.IsSynced)
{
- var channelModel = await Rest.ApiClient.GetChannelAsync(data.ChannelId.Value);
-
- if (data.GuildId.IsSpecified)
- channel = SocketTextChannel.Create(State.GetGuild(data.GuildId.Value), State, channelModel);
- else
- channel = (SocketChannel)SocketChannel.CreatePrivate(this, State, channelModel);
-
- State.AddChannel(channel);
+ await UnsyncedGuildAsync(type, guild.Id).ConfigureAwait(false);
+ return;
}
- if (channel is ISocketMessageChannel textChannel)
- {
- var guild = (channel as SocketGuildChannel)?.Guild;
- if (guild != null && !guild.IsSynced)
- {
- await UnsyncedGuildAsync(type, guild.Id).ConfigureAwait(false);
- return;
- }
-
- var interaction = SocketInteraction.Create(this, data, channel as ISocketMessageChannel);
+ var interaction = SocketInteraction.Create(this, data, channel as ISocketMessageChannel);
- await TimedInvokeAsync(_interactionCreatedEvent, nameof(InteractionCreated), interaction).ConfigureAwait(false);
+ await TimedInvokeAsync(_interactionCreatedEvent, nameof(InteractionCreated), interaction).ConfigureAwait(false);
- switch (interaction)
- {
- case SocketSlashCommand slashCommand:
- await TimedInvokeAsync(_slashCommandExecuted, nameof(SlashCommandExecuted), slashCommand).ConfigureAwait(false);
- break;
- case SocketMessageComponent messageComponent:
- if(messageComponent.Data.Type == ComponentType.SelectMenu)
- await TimedInvokeAsync(_selectMenuExecuted, nameof(SelectMenuExecuted), messageComponent).ConfigureAwait(false);
- if(messageComponent.Data.Type == ComponentType.Button)
- await TimedInvokeAsync(_buttonExecuted, nameof(ButtonExecuted), messageComponent).ConfigureAwait(false);
- break;
- case SocketUserCommand userCommand:
- await TimedInvokeAsync(_userCommandExecuted, nameof(UserCommandExecuted), userCommand).ConfigureAwait(false);
- break;
- case SocketMessageCommand messageCommand:
- await TimedInvokeAsync(_messageCommandExecuted, nameof(MessageCommandExecuted), messageCommand).ConfigureAwait(false);
- break;
- case SocketAutocompleteInteraction autocomplete:
- await TimedInvokeAsync(_autocompleteExecuted, nameof(AutocompleteExecuted), autocomplete).ConfigureAwait(false);
- break;
- }
- }
- else
+ switch (interaction)
{
- await UnknownChannelAsync(type, data.ChannelId.Value).ConfigureAwait(false);
- return;
+ case SocketSlashCommand slashCommand:
+ await TimedInvokeAsync(_slashCommandExecuted, nameof(SlashCommandExecuted), slashCommand).ConfigureAwait(false);
+ break;
+ case SocketMessageComponent messageComponent:
+ if (messageComponent.Data.Type == ComponentType.SelectMenu)
+ await TimedInvokeAsync(_selectMenuExecuted, nameof(SelectMenuExecuted), messageComponent).ConfigureAwait(false);
+ if (messageComponent.Data.Type == ComponentType.Button)
+ await TimedInvokeAsync(_buttonExecuted, nameof(ButtonExecuted), messageComponent).ConfigureAwait(false);
+ break;
+ case SocketUserCommand userCommand:
+ await TimedInvokeAsync(_userCommandExecuted, nameof(UserCommandExecuted), userCommand).ConfigureAwait(false);
+ break;
+ case SocketMessageCommand messageCommand:
+ await TimedInvokeAsync(_messageCommandExecuted, nameof(MessageCommandExecuted), messageCommand).ConfigureAwait(false);
+ break;
+ case SocketAutocompleteInteraction autocomplete:
+ await TimedInvokeAsync(_autocompleteExecuted, nameof(AutocompleteExecuted), autocomplete).ConfigureAwait(false);
+ break;
}
}
break;
diff --git a/src/Discord.Net.WebSocket/Entities/Interaction/SocketInteraction.cs b/src/Discord.Net.WebSocket/Entities/Interaction/SocketInteraction.cs
index b53739553..985e8e0d9 100644
--- a/src/Discord.Net.WebSocket/Entities/Interaction/SocketInteraction.cs
+++ b/src/Discord.Net.WebSocket/Entities/Interaction/SocketInteraction.cs
@@ -17,6 +17,10 @@ namespace Discord.WebSocket
///
/// The this interaction was used in.
///
+ ///
+ /// If the channel isn't cached or the bot doesn't have access to it then
+ /// this property will be .
+ ///
public ISocketMessageChannel Channel { get; private set; }
///
From d142710d2af9e593e0737e501b279b785df075d1 Mon Sep 17 00:00:00 2001
From: Quin Lynch <49576606+quinchs@users.noreply.github.com>
Date: Wed, 9 Feb 2022 00:12:54 -0400
Subject: [PATCH 6/7] fix guild feature enum (#2089)
---
src/Discord.Net.Core/Entities/Guilds/GuildFeature.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Discord.Net.Core/Entities/Guilds/GuildFeature.cs b/src/Discord.Net.Core/Entities/Guilds/GuildFeature.cs
index aec637be2..cb57b2726 100644
--- a/src/Discord.Net.Core/Entities/Guilds/GuildFeature.cs
+++ b/src/Discord.Net.Core/Entities/Guilds/GuildFeature.cs
@@ -7,7 +7,7 @@ using System.Threading.Tasks;
namespace Discord
{
[Flags]
- public enum GuildFeature
+ public enum GuildFeature : long
{
///
/// The guild has no features.
From 33efd8981dced689a5243a45012fe2fb527a3c24 Mon Sep 17 00:00:00 2001
From: Quin Lynch <49576606+quinchs@users.noreply.github.com>
Date: Wed, 9 Feb 2022 00:13:15 -0400
Subject: [PATCH 7/7] Add support for attachments (#2088)
* Enforce valid button styles
* support command option type 11
* missing '.'
* Added type converter.
Co-authored-by: Cat
Co-authored-by: CottageDwellingCat <80918250+CottageDwellingCat@users.noreply.github.com>
Co-authored-by: FeroxFoxxo
Co-authored-by: Cat
Co-authored-by: CottageDwellingCat <80918250+CottageDwellingCat@users.noreply.github.com>
---
.../Interactions/ApplicationCommandOptionType.cs | 7 ++++++-
src/Discord.Net.Interactions/InteractionService.cs | 1 +
.../TypeConverters/DefaultEntityTypeConverter.cs | 5 +++++
.../ApplicationCommandInteractionDataResolved.cs | 2 ++
.../Interactions/CommandBase/RestResolvableData.cs | 13 +++++++++++++
.../SlashCommands/RestSlashCommandDataOption.cs | 4 ++++
.../SlashCommands/SocketSlashCommandDataOption.cs | 4 ++++
.../SocketBaseCommand/SocketResolvableData.cs | 13 +++++++++++++
8 files changed, 48 insertions(+), 1 deletion(-)
diff --git a/src/Discord.Net.Core/Entities/Interactions/ApplicationCommandOptionType.cs b/src/Discord.Net.Core/Entities/Interactions/ApplicationCommandOptionType.cs
index 0f919f1f6..5bb00797b 100644
--- a/src/Discord.Net.Core/Entities/Interactions/ApplicationCommandOptionType.cs
+++ b/src/Discord.Net.Core/Entities/Interactions/ApplicationCommandOptionType.cs
@@ -53,6 +53,11 @@ namespace Discord
///
/// A .
///
- Number = 10
+ Number = 10,
+
+ ///
+ /// A .
+ ///
+ Attachment = 11
}
}
diff --git a/src/Discord.Net.Interactions/InteractionService.cs b/src/Discord.Net.Interactions/InteractionService.cs
index b394109a5..475622f0b 100644
--- a/src/Discord.Net.Interactions/InteractionService.cs
+++ b/src/Discord.Net.Interactions/InteractionService.cs
@@ -163,6 +163,7 @@ namespace Discord.Interactions
{
[typeof(IChannel)] = typeof(DefaultChannelConverter<>),
[typeof(IRole)] = typeof(DefaultRoleConverter<>),
+ [typeof(IAttachment)] = typeof(DefaultAttachmentConverter<>),
[typeof(IUser)] = typeof(DefaultUserConverter<>),
[typeof(IMentionable)] = typeof(DefaultMentionableConverter<>),
[typeof(IConvertible)] = typeof(DefaultValueConverter<>),
diff --git a/src/Discord.Net.Interactions/TypeConverters/DefaultEntityTypeConverter.cs b/src/Discord.Net.Interactions/TypeConverters/DefaultEntityTypeConverter.cs
index 9107fbf35..fb493ed72 100644
--- a/src/Discord.Net.Interactions/TypeConverters/DefaultEntityTypeConverter.cs
+++ b/src/Discord.Net.Interactions/TypeConverters/DefaultEntityTypeConverter.cs
@@ -20,6 +20,11 @@ namespace Discord.Interactions
}
}
+ internal class DefaultAttachmentConverter : DefaultEntityTypeConverter where T : class, IAttachment
+ {
+ public override ApplicationCommandOptionType GetDiscordType() => ApplicationCommandOptionType.Attachment;
+ }
+
internal class DefaultRoleConverter : DefaultEntityTypeConverter where T : class, IRole
{
public override ApplicationCommandOptionType GetDiscordType ( ) => ApplicationCommandOptionType.Role;
diff --git a/src/Discord.Net.Rest/API/Common/ApplicationCommandInteractionDataResolved.cs b/src/Discord.Net.Rest/API/Common/ApplicationCommandInteractionDataResolved.cs
index 5b4b83e23..690be6cef 100644
--- a/src/Discord.Net.Rest/API/Common/ApplicationCommandInteractionDataResolved.cs
+++ b/src/Discord.Net.Rest/API/Common/ApplicationCommandInteractionDataResolved.cs
@@ -18,5 +18,7 @@ namespace Discord.API
public Optional> Roles { get; set; }
[JsonProperty("messages")]
public Optional> Messages { get; set; }
+ [JsonProperty("attachments")]
+ public Optional> Attachments { get; set; }
}
}
diff --git a/src/Discord.Net.Rest/Entities/Interactions/CommandBase/RestResolvableData.cs b/src/Discord.Net.Rest/Entities/Interactions/CommandBase/RestResolvableData.cs
index 710207ef9..9353a8530 100644
--- a/src/Discord.Net.Rest/Entities/Interactions/CommandBase/RestResolvableData.cs
+++ b/src/Discord.Net.Rest/Entities/Interactions/CommandBase/RestResolvableData.cs
@@ -19,6 +19,9 @@ namespace Discord.Rest
internal readonly Dictionary Messages
= new Dictionary();
+ internal readonly Dictionary Attachments
+ = new Dictionary();
+
internal async Task PopulateAsync(DiscordRestClient discord, RestGuild guild, IRestMessageChannel channel, T model)
{
var resolved = model.Resolved.Value;
@@ -91,6 +94,16 @@ namespace Discord.Rest
Messages.Add(message.Id, message);
}
}
+
+ if (resolved.Attachments.IsSpecified)
+ {
+ foreach (var attachment in resolved.Attachments.Value)
+ {
+ var discordAttachment = Attachment.Create(attachment.Value);
+
+ Attachments.Add(ulong.Parse(attachment.Key), discordAttachment);
+ }
+ }
}
}
}
diff --git a/src/Discord.Net.Rest/Entities/Interactions/SlashCommands/RestSlashCommandDataOption.cs b/src/Discord.Net.Rest/Entities/Interactions/SlashCommands/RestSlashCommandDataOption.cs
index bb931f68e..cbb958968 100644
--- a/src/Discord.Net.Rest/Entities/Interactions/SlashCommands/RestSlashCommandDataOption.cs
+++ b/src/Discord.Net.Rest/Entities/Interactions/SlashCommands/RestSlashCommandDataOption.cs
@@ -43,6 +43,7 @@ namespace Discord.Rest
case ApplicationCommandOptionType.Role:
case ApplicationCommandOptionType.Channel:
case ApplicationCommandOptionType.Mentionable:
+ case ApplicationCommandOptionType.Attachment:
if (ulong.TryParse($"{model.Value.Value}", out var valueId))
{
switch (Type)
@@ -80,6 +81,9 @@ namespace Discord.Rest
}
}
break;
+ case ApplicationCommandOptionType.Attachment:
+ Value = data.ResolvableData.Attachments.FirstOrDefault(x => x.Key == valueId).Value;
+ break;
default:
Value = model.Value.Value;
break;
diff --git a/src/Discord.Net.WebSocket/Entities/Interaction/SlashCommands/SocketSlashCommandDataOption.cs b/src/Discord.Net.WebSocket/Entities/Interaction/SlashCommands/SocketSlashCommandDataOption.cs
index 265eda75b..2a44b4e03 100644
--- a/src/Discord.Net.WebSocket/Entities/Interaction/SlashCommands/SocketSlashCommandDataOption.cs
+++ b/src/Discord.Net.WebSocket/Entities/Interaction/SlashCommands/SocketSlashCommandDataOption.cs
@@ -39,6 +39,7 @@ namespace Discord.WebSocket
case ApplicationCommandOptionType.Role:
case ApplicationCommandOptionType.Channel:
case ApplicationCommandOptionType.Mentionable:
+ case ApplicationCommandOptionType.Attachment:
if (ulong.TryParse($"{model.Value.Value}", out var valueId))
{
switch (Type)
@@ -76,6 +77,9 @@ namespace Discord.WebSocket
}
}
break;
+ case ApplicationCommandOptionType.Attachment:
+ Value = data.ResolvableData.Attachments.FirstOrDefault(x => x.Key == valueId).Value;
+ break;
default:
Value = model.Value.Value;
break;
diff --git a/src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketResolvableData.cs b/src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketResolvableData.cs
index c065637ca..d722c5a13 100644
--- a/src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketResolvableData.cs
+++ b/src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketResolvableData.cs
@@ -16,6 +16,9 @@ namespace Discord.WebSocket
internal readonly Dictionary Messages
= new Dictionary();
+ internal readonly Dictionary Attachments
+ = new Dictionary();
+
internal SocketResolvableData(DiscordSocketClient discord, ulong? guildId, T model)
{
var guild = guildId.HasValue ? discord.GetGuild(guildId.Value) : null;
@@ -104,6 +107,16 @@ namespace Discord.WebSocket
Messages.Add(message.Id, message);
}
}
+
+ if (resolved.Attachments.IsSpecified)
+ {
+ foreach (var attachment in resolved.Attachments.Value)
+ {
+ var discordAttachment = Attachment.Create(attachment.Value);
+
+ Attachments.Add(ulong.Parse(attachment.Key), discordAttachment);
+ }
+ }
}
}
}