diff --git a/ApplicationCommands/BirthdayModule.cs b/ApplicationCommands/BirthdayModule.cs
index 86d7906..6c7c267 100644
--- a/ApplicationCommands/BirthdayModule.cs
+++ b/ApplicationCommands/BirthdayModule.cs
@@ -3,8 +3,8 @@ using Discord.Interactions;
using System.Text;
namespace BirthdayBot.ApplicationCommands;
-[RequireGuildContext]
[Group("birthday", HelpCmdBirthday)]
+[EnabledInDm(false)]
public class BirthdayModule : BotModuleBase {
public const string HelpCmdBirthday = "Commands relating to birthdays.";
public const string HelpCmdSetDate = "Sets or updates your birthday.";
@@ -191,7 +191,7 @@ public class BirthdayModule : BotModuleBase {
await doOutput(output.ToString()).ConfigureAwait(false);
}
- [RequireBotModerator]
+ [DefaultMemberPermissions(GuildPermission.ManageGuild)]
[SlashCommand("export", HelpPfxModOnly + HelpCmdExport)]
public async Task CmdExport([Summary(description: "Specify whether to export the list in CSV format.")] bool asCsv = false) {
if (!await HasMemberCacheAsync(Context.Guild)) {
diff --git a/ApplicationCommands/BirthdayOverrideModule.cs b/ApplicationCommands/BirthdayOverrideModule.cs
index 2a6de5a..b6a059b 100644
--- a/ApplicationCommands/BirthdayOverrideModule.cs
+++ b/ApplicationCommands/BirthdayOverrideModule.cs
@@ -3,8 +3,9 @@ using Discord.Interactions;
using static BirthdayBot.Common;
namespace BirthdayBot.ApplicationCommands;
-[RequireBotModerator]
[Group("override", HelpCmdOverride)]
+[DefaultMemberPermissions(GuildPermission.ManageGuild)]
+[EnabledInDm(false)]
public class BirthdayOverrideModule : BotModuleBase {
public const string HelpCmdOverride = "Commands to set options for other users.";
const string HelpOptOvTarget = "The user whose data to modify.";
diff --git a/ApplicationCommands/ConfigModule.cs b/ApplicationCommands/ConfigModule.cs
index e64acf3..0818dd2 100644
--- a/ApplicationCommands/ConfigModule.cs
+++ b/ApplicationCommands/ConfigModule.cs
@@ -3,13 +3,13 @@ using Discord.Interactions;
using System.Text;
namespace BirthdayBot.ApplicationCommands;
-[RequireBotModerator]
[Group("config", HelpCmdConfig)]
+[DefaultMemberPermissions(GuildPermission.ManageGuild)]
+[EnabledInDm(false)]
public class ConfigModule : BotModuleBase {
public const string HelpCmdConfig = "Configure basic settings for the bot.";
public const string HelpCmdAnnounce = "Settings regarding birthday announcements.";
- public const string HelpCmdBlocking = "Settings for limiting user access.";
- public const string HelpCmdRole = "Settings for roles used by this bot.";
+ public const string HelpCmdBirthdayRole = "Set the role given to users having a birthday.";
public const string HelpCmdCheck = "Test the bot's current configuration and show the results.";
const string HelpPofxBlankUnset = " Leave blank to unset.";
@@ -118,28 +118,14 @@ public class ConfigModule : BotModuleBase {
}
}
- [Group("role", HelpPfxModOnly + HelpCmdRole)]
- public class SubCmdsConfigRole : BotModuleBase {
- [SlashCommand("set-birthday-role", HelpPfxModOnly + "Set the role given to users having a birthday.")]
- public async Task CmdSetBRole([Summary(description: HelpOptRole)]SocketRole role) {
- if (role.IsEveryone || role.IsManaged) {
- await RespondAsync(":x: This role cannot be used for this setting.", ephemeral: true);
- return;
- }
- await DoDatabaseUpdate(Context, s => s.BirthdayRole = role.Id);
- await RespondAsync($":white_check_mark: The birthday role has been set to **{role.Name}**.").ConfigureAwait(false);
- }
-
- [SlashCommand("set-moderator-role", HelpPfxModOnly + "Designate a role whose members can configure the bot." + HelpPofxBlankUnset)]
- public async Task CmdSetModRole([Summary(description: HelpOptRole)]SocketRole? role = null) {
- if (role != null && (role.IsEveryone || role.IsManaged)) {
- await RespondAsync(":x: This role cannot be used for this setting.", ephemeral: true);
- return;
- }
- await DoDatabaseUpdate(Context, s => s.ModeratorRole = role?.Id);
- await RespondAsync(":white_check_mark: The moderator role has been " +
- (role == null ? "unset." : $"set to **{role.Name}**."));
+ [SlashCommand("birthday-role", HelpPfxModOnly + HelpCmdBirthdayRole)]
+ public async Task CmdSetBRole([Summary(description: HelpOptRole)] SocketRole role) {
+ if (role.IsEveryone || role.IsManaged) {
+ await RespondAsync(":x: This role cannot be used for this setting.", ephemeral: true);
+ return;
}
+ await DoDatabaseUpdate(Context, s => s.BirthdayRole = role.Id);
+ await RespondAsync($":white_check_mark: The birthday role has been set to **{role.Name}**.").ConfigureAwait(false);
}
[SlashCommand("check", HelpPfxModOnly + HelpCmdCheck)]
diff --git a/ApplicationCommands/HelpModule.cs b/ApplicationCommands/HelpModule.cs
index 19bf614..fbd7a3b 100644
--- a/ApplicationCommands/HelpModule.cs
+++ b/ApplicationCommands/HelpModule.cs
@@ -1,6 +1,7 @@
using Discord.Interactions;
namespace BirthdayBot.ApplicationCommands;
+[EnabledInDm(true)]
public class HelpModule : BotModuleBase {
private const string TopMessage =
"Thank you for using Birthday Bot!\n" +
@@ -20,10 +21,7 @@ public class HelpModule : BotModuleBase {
$"` ⤷check` - {ConfigModule.HelpCmdCheck}\n" +
$"` ⤷announce` - {ConfigModule.HelpCmdAnnounce}\n" +
$"` ⤷` See also: `/config announce help`.\n" +
- $"` ⤷block` - {ConfigModule.HelpCmdBlocking}\n" +
- $"` ⤷add-block`, `⤷remove-block`, `⤷set-moderated`\n" +
- $"` ⤷role` - {ConfigModule.HelpCmdRole}\n" +
- $"` ⤷set-birthday-role`, `⤷set-moderator-role`\n" +
+ $"` ⤷birthday-role` - {ConfigModule.HelpCmdBirthdayRole}\n" +
$"`/override` - {BirthdayOverrideModule.HelpCmdOverride}\n" +
$"` ⤷set-birthday`, `⤷set-timezone`, `⤷remove`\n" +
"**Caution:** Skipping optional parameters __removes__ their configuration.";
diff --git a/ApplicationCommands/Preconditions/RequireBotModerator.cs b/ApplicationCommands/Preconditions/RequireBotModerator.cs
deleted file mode 100644
index a6a6589..0000000
--- a/ApplicationCommands/Preconditions/RequireBotModerator.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-using BirthdayBot.Data;
-using Discord.Interactions;
-
-namespace BirthdayBot.ApplicationCommands;
-///
-/// Precondition requiring the executing user be recognized as a bot moderator.
-/// A bot moderator has either the Manage Server permission or is a member of the designated bot moderator role.
-///
-[Obsolete("Replace with appropriate DefaultMemberPermissionsAttribute")]
-class RequireBotModeratorAttribute : PreconditionAttribute {
- public const string Error = "User did not pass the mod check.";
- public const string Reply = ":x: You must be a moderator to use this command.";
-
- public override string ErrorMessage => Error;
-
- public override Task CheckRequirementsAsync(
- IInteractionContext context, ICommandInfo commandInfo, IServiceProvider services) {
- // A bot moderator can only exist in a guild context, so we must do this check.
- // This check causes this precondition to become a functional equivalent to RequireGuildContextAttribute...
- if (context.User is not SocketGuildUser user)
- return Task.FromResult(PreconditionResult.FromError(RequireGuildContextAttribute.Error));
-
- if (user.GuildPermissions.ManageGuild) return Task.FromResult(PreconditionResult.FromSuccess());
- using var db = new BotDatabaseContext();
- var checkRole = (ulong?)db.GuildConfigurations
- .Where(g => g.GuildId == ((SocketGuild)context.Guild).Id)
- .Select(g => g.ModeratorRole).FirstOrDefault();
- if (checkRole.HasValue && user.Roles.Any(r => r.Id == checkRole.Value))
- return Task.FromResult(PreconditionResult.FromSuccess());
-
- return Task.FromResult(PreconditionResult.FromError(Error));
- }
-}
\ No newline at end of file
diff --git a/ApplicationCommands/Preconditions/RequireGuildContext.cs b/ApplicationCommands/Preconditions/RequireGuildContext.cs
deleted file mode 100644
index d4c8ab0..0000000
--- a/ApplicationCommands/Preconditions/RequireGuildContext.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using Discord.Interactions;
-
-namespace BirthdayBot.ApplicationCommands;
-///
-/// Implements the included precondition from Discord.Net, requiring a guild context while using our custom error message.
-/// Combining this with is redundant. If possible, only use the latter instead.
-///
-[Obsolete("Replace with EnableInDmAttribute")]
-class RequireGuildContextAttribute : RequireContextAttribute {
- public const string Error = "Command not received within a guild context.";
- public const string Reply = ":x: This command is only available within a server.";
-
- public override string ErrorMessage => Error;
-
- public RequireGuildContextAttribute() : base(ContextType.Guild) { }
-}
\ No newline at end of file
diff --git a/Data/GuildConfig.cs b/Data/GuildConfig.cs
index e3d747d..a4cfb1d 100644
--- a/Data/GuildConfig.cs
+++ b/Data/GuildConfig.cs
@@ -16,11 +16,6 @@ public class GuildConfig {
[Column("time_zone")]
public string? GuildTimeZone { get; set; }
- public bool Moderated { get; set; }
-
- [Obsolete("To be removed when RequireBotModeratorAttribute is also removed")]
- public ulong? ModeratorRole { get; set; }
-
public string? AnnounceMessage { get; set; }
public string? AnnounceMessagePl { get; set; }
diff --git a/Data/Migrations/20230204063321_RemoveModRole.Designer.cs b/Data/Migrations/20230204063321_RemoveModRole.Designer.cs
new file mode 100644
index 0000000..e40e799
--- /dev/null
+++ b/Data/Migrations/20230204063321_RemoveModRole.Designer.cs
@@ -0,0 +1,123 @@
+//
+using System;
+using BirthdayBot.Data;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+
+#nullable disable
+
+namespace BirthdayBot.Data.Migrations
+{
+ [DbContext(typeof(BotDatabaseContext))]
+ [Migration("20230204063321_RemoveModRole")]
+ partial class RemoveModRole
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "7.0.0")
+ .HasAnnotation("Relational:MaxIdentifierLength", 63);
+
+ NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
+
+ modelBuilder.Entity("BirthdayBot.Data.GuildConfig", b =>
+ {
+ b.Property("GuildId")
+ .HasColumnType("numeric(20,0)")
+ .HasColumnName("guild_id");
+
+ b.Property("AnnounceMessage")
+ .HasColumnType("text")
+ .HasColumnName("announce_message");
+
+ b.Property("AnnounceMessagePl")
+ .HasColumnType("text")
+ .HasColumnName("announce_message_pl");
+
+ b.Property("AnnouncePing")
+ .HasColumnType("boolean")
+ .HasColumnName("announce_ping");
+
+ b.Property("AnnouncementChannel")
+ .HasColumnType("numeric(20,0)")
+ .HasColumnName("channel_announce_id");
+
+ b.Property("BirthdayRole")
+ .HasColumnType("numeric(20,0)")
+ .HasColumnName("role_id");
+
+ b.Property("GuildTimeZone")
+ .HasColumnType("text")
+ .HasColumnName("time_zone");
+
+ b.Property("LastSeen")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("last_seen")
+ .HasDefaultValueSql("now()");
+
+ b.HasKey("GuildId")
+ .HasName("settings_pkey");
+
+ b.ToTable("settings", (string)null);
+ });
+
+ modelBuilder.Entity("BirthdayBot.Data.UserEntry", b =>
+ {
+ b.Property("GuildId")
+ .HasColumnType("numeric(20,0)")
+ .HasColumnName("guild_id");
+
+ b.Property("UserId")
+ .HasColumnType("numeric(20,0)")
+ .HasColumnName("user_id");
+
+ b.Property("BirthDay")
+ .HasColumnType("integer")
+ .HasColumnName("birth_day");
+
+ b.Property("BirthMonth")
+ .HasColumnType("integer")
+ .HasColumnName("birth_month");
+
+ b.Property("LastSeen")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("last_seen")
+ .HasDefaultValueSql("now()");
+
+ b.Property("TimeZone")
+ .HasColumnType("text")
+ .HasColumnName("time_zone");
+
+ b.HasKey("GuildId", "UserId")
+ .HasName("user_birthdays_pkey");
+
+ b.ToTable("user_birthdays", (string)null);
+ });
+
+ modelBuilder.Entity("BirthdayBot.Data.UserEntry", b =>
+ {
+ b.HasOne("BirthdayBot.Data.GuildConfig", "Guild")
+ .WithMany("UserEntries")
+ .HasForeignKey("GuildId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("user_birthdays_guild_id_fkey");
+
+ b.Navigation("Guild");
+ });
+
+ modelBuilder.Entity("BirthdayBot.Data.GuildConfig", b =>
+ {
+ b.Navigation("UserEntries");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/Data/Migrations/20230204063321_RemoveModRole.cs b/Data/Migrations/20230204063321_RemoveModRole.cs
new file mode 100644
index 0000000..f8845d4
--- /dev/null
+++ b/Data/Migrations/20230204063321_RemoveModRole.cs
@@ -0,0 +1,39 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace BirthdayBot.Data.Migrations
+{
+ ///
+ public partial class RemoveModRole : Migration
+ {
+ ///
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropColumn(
+ name: "moderated",
+ table: "settings");
+
+ migrationBuilder.DropColumn(
+ name: "moderator_role",
+ table: "settings");
+ }
+
+ ///
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.AddColumn(
+ name: "moderated",
+ table: "settings",
+ type: "boolean",
+ nullable: false,
+ defaultValue: false);
+
+ migrationBuilder.AddColumn(
+ name: "moderator_role",
+ table: "settings",
+ type: "numeric(20,0)",
+ nullable: true);
+ }
+ }
+}
diff --git a/Data/Migrations/BotDatabaseContextModelSnapshot.cs b/Data/Migrations/BotDatabaseContextModelSnapshot.cs
index c82301e..7c5bee9 100644
--- a/Data/Migrations/BotDatabaseContextModelSnapshot.cs
+++ b/Data/Migrations/BotDatabaseContextModelSnapshot.cs
@@ -58,14 +58,6 @@ namespace BirthdayBot.Data.Migrations
.HasColumnName("last_seen")
.HasDefaultValueSql("now()");
- b.Property("Moderated")
- .HasColumnType("boolean")
- .HasColumnName("moderated");
-
- b.Property("ModeratorRole")
- .HasColumnType("numeric(20,0)")
- .HasColumnName("moderator_role");
-
b.HasKey("GuildId")
.HasName("settings_pkey");
diff --git a/ShardInstance.cs b/ShardInstance.cs
index 82ffa5e..cd51665 100644
--- a/ShardInstance.cs
+++ b/ShardInstance.cs
@@ -133,35 +133,18 @@ public sealed class ShardInstance : IDisposable {
}
// Slash command logging and failed execution handling
- private async Task InteractionService_SlashCommandExecuted(SlashCommandInfo info, IInteractionContext context, IResult result) {
+ private Task InteractionService_SlashCommandExecuted(SlashCommandInfo info, IInteractionContext context, IResult result) {
string sender;
- if (context.Guild != null) {
- sender = $"{context.Guild}!{context.User}";
- } else {
- sender = $"{context.User} in non-guild context";
- }
+ if (context.Guild != null) sender = $"{context.Guild}!{context.User}";
+ else sender = $"{context.User} in non-guild context";
var logresult = $"{(result.IsSuccess ? "Success" : "Fail")}: `/{info}` by {sender}.";
if (result.Error != null) {
// Additional log information with error detail
logresult += " " + Enum.GetName(typeof(InteractionCommandError), result.Error) + ": " + result.ErrorReason;
-
- // Specific responses to errors, if necessary
- if (result.Error == InteractionCommandError.UnmetPrecondition) {
- var errReply = result.ErrorReason switch {
- RequireBotModeratorAttribute.Error => RequireBotModeratorAttribute.Reply,
- RequireGuildContextAttribute.Error => RequireGuildContextAttribute.Reply,
- _ => result.ErrorReason
- };
- await context.Interaction.RespondAsync(errReply, ephemeral: true).ConfigureAwait(false);
- } else {
- // Generic error response
- var ia = context.Interaction;
- if (ia.HasResponded) await ia.ModifyOriginalResponseAsync(p => p.Content = InternalError).ConfigureAwait(false);
- else await ia.RespondAsync(InternalError).ConfigureAwait(false);
- }
}
Log("Command", logresult);
+ return Task.CompletedTask;
}
}