feature: Add missing interaction properties (#2325)
This commit is contained in:
@@ -52,6 +52,9 @@ namespace Discord
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the preferred locale of the invoking User.
|
/// Gets the preferred locale of the invoking User.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This property returns <see langword="null"/> if the interaction is a REST ping interaction.
|
||||||
|
/// </remarks>
|
||||||
string UserLocale { get; }
|
string UserLocale { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -67,6 +70,27 @@ namespace Discord
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
bool IsDMInteraction { get; }
|
bool IsDMInteraction { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the ID of the channel this interaction was executed in.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This property returns <see langword="null"/> if the interaction is a REST ping interaction.
|
||||||
|
/// </remarks>
|
||||||
|
ulong? ChannelId { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the ID of the guild this interaction was executed in.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This property returns <see langword="null"/> if the interaction was not executed in a guild.
|
||||||
|
/// </remarks>
|
||||||
|
ulong? GuildId { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the ID of the application this interaction is for.
|
||||||
|
/// </summary>
|
||||||
|
ulong ApplicationId { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Responds to an Interaction with type <see cref="InteractionResponseType.ChannelMessageWithSource"/>.
|
/// Responds to an Interaction with type <see cref="InteractionResponseType.ChannelMessageWithSource"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Model = Discord.API.Interaction;
|
using Model = Discord.API.Interaction;
|
||||||
@@ -17,8 +16,8 @@ namespace Discord.Rest
|
|||||||
public abstract class RestInteraction : RestEntity<ulong>, IDiscordInteraction
|
public abstract class RestInteraction : RestEntity<ulong>, IDiscordInteraction
|
||||||
{
|
{
|
||||||
// Added so channel & guild methods don't need a client reference
|
// Added so channel & guild methods don't need a client reference
|
||||||
private Func<RequestOptions, ulong, Task<IRestMessageChannel>> _getChannel = null;
|
private Func<RequestOptions, ulong, Task<IRestMessageChannel>> _getChannel;
|
||||||
private Func<RequestOptions, ulong, Task<RestGuild>> _getGuild = null;
|
private Func<RequestOptions, ulong, Task<RestGuild>> _getGuild;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public InteractionType Type { get; private set; }
|
public InteractionType Type { get; private set; }
|
||||||
@@ -56,30 +55,17 @@ namespace Discord.Rest
|
|||||||
public bool IsValidToken
|
public bool IsValidToken
|
||||||
=> InteractionHelper.CanRespondOrFollowup(this);
|
=> InteractionHelper.CanRespondOrFollowup(this);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the ID of the channel this interaction was executed in.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// <see langword="null"/> if the interaction was not executed in a guild.
|
|
||||||
/// </remarks>
|
|
||||||
public ulong? ChannelId { get; private set; } = null;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the channel that this interaction was executed in.
|
/// Gets the channel that this interaction was executed in.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// <see langword="null"/> if <see cref="DiscordRestConfig.APIOnRestInteractionCreation"/> is set to false.
|
/// This property will be <see langword="null"/> if <see cref="DiscordRestConfig.APIOnRestInteractionCreation"/> is set to false.
|
||||||
/// Call <see cref="GetChannelAsync"/> to set this property and get the interaction channel.
|
/// Call <see cref="GetChannelAsync"/> to set this property and get the interaction channel.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public IRestMessageChannel Channel { get; private set; }
|
public IRestMessageChannel Channel { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the ID of the guild this interaction was executed in if applicable.
|
public ulong? ChannelId { get; private set; }
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// <see langword="null"/> if the interaction was not executed in a guild.
|
|
||||||
/// </remarks>
|
|
||||||
public ulong? GuildId { get; private set; } = null;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the guild this interaction was executed in if applicable.
|
/// Gets the guild this interaction was executed in if applicable.
|
||||||
@@ -90,12 +76,18 @@ namespace Discord.Rest
|
|||||||
/// </remarks>
|
/// </remarks>
|
||||||
public RestGuild Guild { get; private set; }
|
public RestGuild Guild { get; private set; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public ulong? GuildId { get; private set; }
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public bool HasResponded { get; protected set; }
|
public bool HasResponded { get; protected set; }
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public bool IsDMInteraction { get; private set; }
|
public bool IsDMInteraction { get; private set; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public ulong ApplicationId { get; private set; }
|
||||||
|
|
||||||
internal RestInteraction(BaseDiscordClient discord, ulong id)
|
internal RestInteraction(BaseDiscordClient discord, ulong id)
|
||||||
: base(discord, id)
|
: base(discord, id)
|
||||||
{
|
{
|
||||||
@@ -143,32 +135,41 @@ namespace Discord.Rest
|
|||||||
|
|
||||||
internal virtual async Task UpdateAsync(DiscordRestClient discord, Model model, bool doApiCall)
|
internal virtual async Task UpdateAsync(DiscordRestClient discord, Model model, bool doApiCall)
|
||||||
{
|
{
|
||||||
IsDMInteraction = !model.GuildId.IsSpecified;
|
ChannelId = model.ChannelId.IsSpecified
|
||||||
|
? model.ChannelId.Value
|
||||||
|
: null;
|
||||||
|
|
||||||
|
GuildId = model.GuildId.IsSpecified
|
||||||
|
? model.GuildId.Value
|
||||||
|
: null;
|
||||||
|
|
||||||
|
IsDMInteraction = GuildId is null;
|
||||||
|
|
||||||
Data = model.Data.IsSpecified
|
Data = model.Data.IsSpecified
|
||||||
? model.Data.Value
|
? model.Data.Value
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
Token = model.Token;
|
Token = model.Token;
|
||||||
Version = model.Version;
|
Version = model.Version;
|
||||||
Type = model.Type;
|
Type = model.Type;
|
||||||
|
ApplicationId = model.ApplicationId;
|
||||||
|
|
||||||
if (Guild == null && model.GuildId.IsSpecified)
|
if (Guild is null && GuildId is not null)
|
||||||
{
|
{
|
||||||
GuildId = model.GuildId.Value;
|
|
||||||
if (doApiCall)
|
if (doApiCall)
|
||||||
Guild = await discord.GetGuildAsync(model.GuildId.Value);
|
Guild = await discord.GetGuildAsync(GuildId.Value);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Guild = null;
|
Guild = null;
|
||||||
_getGuild = new(async (opt, ul) => await discord.GetGuildAsync(ul, opt));
|
_getGuild = async (opt, ul) => await discord.GetGuildAsync(ul, opt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (User == null)
|
if (User is null)
|
||||||
{
|
{
|
||||||
if (model.Member.IsSpecified && model.GuildId.IsSpecified)
|
if (model.Member.IsSpecified && GuildId is not null)
|
||||||
{
|
{
|
||||||
User = RestGuildUser.Create(Discord, Guild, model.Member.Value, (Guild is null) ? model.GuildId.Value : null);
|
User = RestGuildUser.Create(Discord, Guild, model.Member.Value, GuildId);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -176,24 +177,25 @@ namespace Discord.Rest
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Channel == null && model.ChannelId.IsSpecified)
|
|
||||||
|
if (Channel is null && ChannelId is not null)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ChannelId = model.ChannelId.Value;
|
|
||||||
if (doApiCall)
|
if (doApiCall)
|
||||||
Channel = (IRestMessageChannel)await discord.GetChannelAsync(model.ChannelId.Value);
|
Channel = (IRestMessageChannel)await discord.GetChannelAsync(ChannelId.Value);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_getChannel = new(async (opt, ul) =>
|
Channel = null;
|
||||||
|
|
||||||
|
_getChannel = async (opt, ul) =>
|
||||||
{
|
{
|
||||||
if (Guild is null)
|
if (Guild is null)
|
||||||
return (IRestMessageChannel)await discord.GetChannelAsync(ul, opt);
|
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;
|
// get a guild channel if the guild is set.
|
||||||
|
return (IRestMessageChannel)await Guild.GetChannelAsync(ul, opt);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (HttpException x) when (x.DiscordCode == DiscordErrorCode.MissingPermissions) { } // ignore
|
catch (HttpException x) when (x.DiscordCode == DiscordErrorCode.MissingPermissions) { } // ignore
|
||||||
@@ -222,7 +224,7 @@ namespace Discord.Rest
|
|||||||
/// Gets the channel this interaction was executed in. Will be a DM channel if the interaction was executed in DM.
|
/// Gets the channel this interaction was executed in. Will be a DM channel if the interaction was executed in DM.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// Calling this method succesfully will populate the <see cref="Channel"/> property.
|
/// Calling this method successfully will populate the <see cref="Channel"/> property.
|
||||||
/// After this, further calls to this method will no longer call the API, and depend on the value set in <see cref="Channel"/>.
|
/// After this, further calls to this method will no longer call the API, and depend on the value set in <see cref="Channel"/>.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <param name="options">The request options for this <see langword="async"/> request.</param>
|
/// <param name="options">The request options for this <see langword="async"/> request.</param>
|
||||||
@@ -230,20 +232,16 @@ namespace Discord.Rest
|
|||||||
/// <exception cref="InvalidOperationException">Thrown if no channel can be received.</exception>
|
/// <exception cref="InvalidOperationException">Thrown if no channel can be received.</exception>
|
||||||
public async Task<IRestMessageChannel> GetChannelAsync(RequestOptions options = null)
|
public async Task<IRestMessageChannel> GetChannelAsync(RequestOptions options = null)
|
||||||
{
|
{
|
||||||
if (IsDMInteraction && Channel is null)
|
if (Channel is not null)
|
||||||
|
return Channel;
|
||||||
|
|
||||||
|
if (IsDMInteraction)
|
||||||
{
|
{
|
||||||
var channel = await User.CreateDMChannelAsync(options);
|
Channel = await User.CreateDMChannelAsync(options);
|
||||||
Channel = channel;
|
|
||||||
}
|
}
|
||||||
|
else if (ChannelId is not null)
|
||||||
else if (Channel is null)
|
|
||||||
{
|
{
|
||||||
var channel = await _getChannel(options, ChannelId.Value);
|
Channel = await _getChannel(options, ChannelId.Value) ?? throw new InvalidOperationException("The interaction channel was not able to be retrieved.");
|
||||||
|
|
||||||
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.
|
_getChannel = null; // get rid of it, we don't need it anymore.
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,20 +252,19 @@ namespace Discord.Rest
|
|||||||
/// Gets the guild this interaction was executed in if applicable.
|
/// Gets the guild this interaction was executed in if applicable.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// Calling this method succesfully will populate the <see cref="Guild"/> property.
|
/// Calling this method successfully will populate the <see cref="Guild"/> property.
|
||||||
/// After this, further calls to this method will no longer call the API, and depend on the value set in <see cref="Guild"/>.
|
/// After this, further calls to this method will no longer call the API, and depend on the value set in <see cref="Guild"/>.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <param name="options">The request options for this <see langword="async"/> request.</param>
|
/// <param name="options">The request options for this <see langword="async"/> request.</param>
|
||||||
/// <returns>The guild this interaction was executed in. <see langword="null"/> if the interaction was executed inside DM.</returns>
|
/// <returns>The guild this interaction was executed in. <see langword="null"/> if the interaction was executed inside DM.</returns>
|
||||||
public async Task<RestGuild> GetGuildAsync(RequestOptions options)
|
public async Task<RestGuild> GetGuildAsync(RequestOptions options)
|
||||||
{
|
{
|
||||||
if (IsDMInteraction)
|
if (GuildId is null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
if (Guild is null)
|
Guild ??= await _getGuild(options, GuildId.Value);
|
||||||
Guild = await _getGuild(options, GuildId.Value);
|
|
||||||
|
|
||||||
_getGuild = null; // get rid of it, we don't need it anymore.
|
_getGuild = null; // get rid of it, we don't need it anymore.
|
||||||
|
|
||||||
return Guild;
|
return Guild;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,20 +24,11 @@ namespace Discord.WebSocket
|
|||||||
/// </remarks>
|
/// </remarks>
|
||||||
public ISocketMessageChannel Channel { get; private set; }
|
public ISocketMessageChannel Channel { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the ID of the channel this interaction was used in.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// This property is exposed in cases where the bot scope is not provided, so the channel entity cannot be retrieved.
|
|
||||||
/// <br />
|
|
||||||
/// To get the channel, you can call <see cref="GetChannelAsync(RequestOptions)"/>
|
|
||||||
/// as this method makes a request for a <see cref="RestChannel"/> if nothing was found in cache.
|
|
||||||
/// </remarks>
|
|
||||||
public ulong? ChannelId { get; private set; }
|
public ulong? ChannelId { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the <see cref="SocketUser"/> who triggered this interaction.
|
/// Gets the <see cref="SocketUser"/> who triggered this interaction.
|
||||||
/// This property will be <see langword="null"/> if the bot scope isn't used.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public SocketUser User { get; private set; }
|
public SocketUser User { get; private set; }
|
||||||
|
|
||||||
@@ -74,6 +65,12 @@ namespace Discord.WebSocket
|
|||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public bool IsDMInteraction { get; private set; }
|
public bool IsDMInteraction { get; private set; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public ulong? GuildId { get; private set; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public ulong ApplicationId { get; private set; }
|
||||||
|
|
||||||
internal SocketInteraction(DiscordSocketClient client, ulong id, ISocketMessageChannel channel, SocketUser user)
|
internal SocketInteraction(DiscordSocketClient client, ulong id, ISocketMessageChannel channel, SocketUser user)
|
||||||
: base(client, id)
|
: base(client, id)
|
||||||
{
|
{
|
||||||
@@ -119,13 +116,21 @@ namespace Discord.WebSocket
|
|||||||
|
|
||||||
internal virtual void Update(Model model)
|
internal virtual void Update(Model model)
|
||||||
{
|
{
|
||||||
IsDMInteraction = !model.GuildId.IsSpecified;
|
ChannelId = model.ChannelId.IsSpecified
|
||||||
|
? model.ChannelId.Value
|
||||||
|
: null;
|
||||||
|
|
||||||
ChannelId = model.ChannelId.ToNullable();
|
GuildId = model.GuildId.IsSpecified
|
||||||
|
? model.GuildId.Value
|
||||||
|
: null;
|
||||||
|
|
||||||
|
IsDMInteraction = GuildId is null;
|
||||||
|
ApplicationId = model.ApplicationId;
|
||||||
|
|
||||||
Data = model.Data.IsSpecified
|
Data = model.Data.IsSpecified
|
||||||
? model.Data.Value
|
? model.Data.Value
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
Token = model.Token;
|
Token = model.Token;
|
||||||
Version = model.Version;
|
Version = model.Version;
|
||||||
Type = model.Type;
|
Type = model.Type;
|
||||||
@@ -133,6 +138,7 @@ namespace Discord.WebSocket
|
|||||||
UserLocale = model.UserLocale.IsSpecified
|
UserLocale = model.UserLocale.IsSpecified
|
||||||
? model.UserLocale.Value
|
? model.UserLocale.Value
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
GuildLocale = model.GuildLocale.IsSpecified
|
GuildLocale = model.GuildLocale.IsSpecified
|
||||||
? model.GuildLocale.Value
|
? model.GuildLocale.Value
|
||||||
: null;
|
: null;
|
||||||
|
|||||||
Reference in New Issue
Block a user