diff --git a/src/Discord.Net.Interactions/Attributes/Preconditions/RequireAppPermissionAttribute.cs b/src/Discord.Net.Interactions/Attributes/Preconditions/RequireAppPermissionAttribute.cs
new file mode 100644
index 0000000000..b1f65c81ca
--- /dev/null
+++ b/src/Discord.Net.Interactions/Attributes/Preconditions/RequireAppPermissionAttribute.cs
@@ -0,0 +1,77 @@
+using System.Threading.Tasks;
+using System;
+
+namespace Discord.Interactions;
+
+///
+/// Requires the bot to have a specific permission in the channel a command is invoked in.
+///
+[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
+public class RequireAppPermissionAttribute : PreconditionAttribute
+{
+ ///
+ /// Gets the specified of the precondition.
+ ///
+ public GuildPermission? GuildPermission { get; }
+
+ ///
+ /// Gets the specified of the precondition.
+ ///
+ public ChannelPermission? ChannelPermission { get; }
+
+ ///
+ /// Gets or sets the error message if the precondition
+ /// fails due to being run outside of a Guild channel.
+ ///
+ public string NotAGuildErrorMessage { get; set; }
+
+ ///
+ /// Requires the bot account to have a specific .
+ ///
+ ///
+ /// This precondition will always fail if the command is being invoked in a .
+ ///
+ ///
+ /// The that the bot must have. Multiple permissions can be specified
+ /// by ORing the permissions together.
+ ///
+ public RequireAppPermissionAttribute(GuildPermission permission)
+ {
+ GuildPermission = permission;
+ ChannelPermission = null;
+ }
+ ///
+ /// Requires that the bot account to have a specific .
+ ///
+ ///
+ /// The that the bot must have. Multiple permissions can be
+ /// specified by ORing the permissions together.
+ ///
+ public RequireAppPermissionAttribute(ChannelPermission permission)
+ {
+ ChannelPermission = permission;
+ GuildPermission = null;
+ }
+
+ ///
+ public override Task CheckRequirementsAsync(IInteractionContext context, ICommandInfo command, IServiceProvider services)
+ {
+ if (GuildPermission.HasValue)
+ {
+ if (context.Interaction.GuildId is null)
+ return Task.FromResult(PreconditionResult.FromError(NotAGuildErrorMessage ?? "Command must be used in a guild channel."));
+ if (context.Interaction.Permissions.Has(GuildPermission.Value))
+ return Task.FromResult(PreconditionResult.FromError(ErrorMessage ?? $"Bot requires guild permission {GuildPermission.Value}."));
+ }
+
+ if (ChannelPermission.HasValue)
+ {
+ var channelPerms = new ChannelPermissions(context.Interaction.Permissions.RawValue);
+ if (!channelPerms.Has(ChannelPermission.Value))
+ return Task.FromResult(PreconditionResult.FromError(ErrorMessage ?? $"Bot requires channel permission {ChannelPermission.Value}."));
+ }
+
+ return Task.FromResult(PreconditionResult.FromSuccess());
+ }
+
+}
diff --git a/src/Discord.Net.Interactions/Attributes/Preconditions/RequireBotPermissionAttribute.cs b/src/Discord.Net.Interactions/Attributes/Preconditions/RequireBotPermissionAttribute.cs
index 1dd3092ffc..f6d58685bf 100644
--- a/src/Discord.Net.Interactions/Attributes/Preconditions/RequireBotPermissionAttribute.cs
+++ b/src/Discord.Net.Interactions/Attributes/Preconditions/RequireBotPermissionAttribute.cs
@@ -7,6 +7,7 @@ namespace Discord.Interactions
/// Requires the bot to have a specific permission in the channel a command is invoked in.
///
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
+ [Obsolete("This attribute does not support user app interactions. Consider switching to 'RequireAppPermissionAttribute'", false)]
public class RequireBotPermissionAttribute : PreconditionAttribute
{
///
diff --git a/src/Discord.Net.Rest/Entities/Messages/CustomSticker.cs b/src/Discord.Net.Rest/Entities/Messages/CustomSticker.cs
index 6fd0f7700a..9626a8c741 100644
--- a/src/Discord.Net.Rest/Entities/Messages/CustomSticker.cs
+++ b/src/Discord.Net.Rest/Entities/Messages/CustomSticker.cs
@@ -34,6 +34,7 @@ internal CustomSticker(BaseDiscordClient client, ulong id, RestGuild guild, ulon
{
AuthorId = authorId;
Guild = guild;
+ GuildId = guild.Id;
}
internal CustomSticker(BaseDiscordClient client, ulong id, ulong guildId, ulong? authorId = null)
: base(client, id)