diff --git a/src/Discord.Net.Rest/Entities/Interactions/RestInteraction.cs b/src/Discord.Net.Rest/Entities/Interactions/RestInteraction.cs index ce8902267..78c03d4b4 100644 --- a/src/Discord.Net.Rest/Entities/Interactions/RestInteraction.cs +++ b/src/Discord.Net.Rest/Entities/Interactions/RestInteraction.cs @@ -16,6 +16,10 @@ namespace Discord.Rest /// public abstract class RestInteraction : RestEntity, IDiscordInteraction { + // Added so channel & guild methods don't need a client reference + private Func> _getChannel = null; + private Func> _getGuild = null; + /// public InteractionType Type { get; private set; } @@ -64,8 +68,8 @@ namespace Discord.Rest /// Gets the channel that this interaction was executed in. /// /// - /// if is set to false - /// or if the interaction was not executed in a guild. + /// if is set to false. + /// Call to set this property and get the interaction channel. /// public IRestMessageChannel Channel { get; private set; } @@ -154,7 +158,10 @@ namespace Discord.Rest if (doApiCall) Guild = await discord.GetGuildAsync(model.GuildId.Value); else + { Guild = null; + _getGuild = new(async (opt, ul) => await discord.GetGuildAsync(ul, opt)); + } } if (User == null) @@ -177,7 +184,17 @@ namespace Discord.Rest if (doApiCall) Channel = (IRestMessageChannel)await discord.GetChannelAsync(model.ChannelId.Value); else + { + _getChannel = new(async (opt, ul) => + { + if (Guild is null) + return (IRestMessageChannel)await discord.GetChannelAsync(ul, opt); + else // get a guild channel if the guild is set. + return (IRestMessageChannel)await Guild.GetChannelAsync(ul, opt); + }); + Channel = null; + } } catch (HttpException x) when (x.DiscordCode == DiscordErrorCode.MissingPermissions) { } // ignore } @@ -201,6 +218,59 @@ namespace Discord.Rest return json.ToString(); } + /// + /// Gets the channel this interaction was executed in. Will be a DM channel if the interaction was executed in DM. + /// + /// + /// Calling this method succesfully will populate the property. + /// After this, further calls to this method will no longer call the API, and depend on the value set in . + /// + /// The request options for this request. + /// A Rest channel to send messages to. + /// Thrown if no channel can be received. + public async Task GetChannelAsync(RequestOptions options = null) + { + if (IsDMInteraction && Channel is null) + { + var channel = await User.CreateDMChannelAsync(options); + Channel = channel; + } + + else if (Channel is null) + { + var channel = await _getChannel(options, ChannelId.Value); + + if (channel is null) + throw new InvalidOperationException("The interaction channel was not able to be retrieved."); + Channel = channel; + + _getChannel = null; // get rid of it, we don't need it anymore. + } + + return Channel; + } + + /// + /// Gets the guild this interaction was executed in if applicable. + /// + /// + /// Calling this method succesfully will populate the property. + /// After this, further calls to this method will no longer call the API, and depend on the value set in . + /// + /// The request options for this request. + /// The guild this interaction was executed in. if the interaction was executed inside DM. + public async Task GetGuildAsync(RequestOptions options) + { + if (IsDMInteraction) + return null; + + if (Guild is null) + Guild = await _getGuild(options, GuildId.Value); + + _getGuild = null; // get rid of it, we don't need it anymore. + return Guild; + } + /// public abstract string Defer(bool ephemeral = false, RequestOptions options = null); ///