Skip to content

Commit

Permalink
Make more slash commands resilient to timeouts
Browse files Browse the repository at this point in the history
  • Loading branch information
Erisa committed Jul 30, 2024
1 parent 80398bf commit 25f500c
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 29 deletions.
2 changes: 1 addition & 1 deletion Commands/InteractionCommands/ClearInteractions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public async Task ClearSlashCommand(InteractionContext ctx,
[Option("dry_run", "Don't actually delete the messages, just output what would be deleted.")] bool dryRun = false
)
{
await ctx.CreateResponseAsync(DiscordInteractionResponseType.DeferredChannelMessageWithSource, new DiscordInteractionResponseBuilder().AsEphemeral(!dryRun));
await ctx.DeferAsync(ephemeral: !dryRun);

// If all args are unset
if (count == 0 && upTo == "" && user == default && ignoreMods == false && match == "" && botsOnly == false && humansOnly == false && attachmentsOnly == false && stickersOnly == false && linksOnly == false)
Expand Down
6 changes: 3 additions & 3 deletions Commands/InteractionCommands/LockdownInteractions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public async Task LockdownChannelCommand(
[Option("time", "The length of time to lock the channel for.")] string time = null,
[Option("lockthreads", "Whether to lock this channel's threads. Disables sending messages, but does not archive them.")] bool lockThreads = false)
{
await ctx.CreateResponseAsync(DiscordInteractionResponseType.DeferredChannelMessageWithSource, new DiscordInteractionResponseBuilder().AsEphemeral(true));
await ctx.DeferAsync(ephemeral: true);

if (ctx.Channel.Type is DiscordChannelType.PublicThread or DiscordChannelType.PrivateThread or DiscordChannelType.NewsThread)
{
Expand Down Expand Up @@ -71,7 +71,7 @@ public async Task LockdownAllCommand(
[Option("time", "The length of time to lock the channels for.")] string time = null,
[Option("lockthreads", "Whether to lock threads. Disables sending messages, but does not archive them.")] bool lockThreads = false)
{
await ctx.CreateResponseAsync(DiscordInteractionResponseType.DeferredChannelMessageWithSource, new DiscordInteractionResponseBuilder().WithContent("test deferred response"));
await ctx.DeferAsync();

ongoingLockdown = true;
await ctx.FollowUpAsync(new DiscordFollowupMessageBuilder().WithContent($"{Program.cfgjson.Emoji.Loading} Working on it, please hold..."));
Expand Down Expand Up @@ -109,7 +109,7 @@ public class UnlockCmds
[SlashCommand("channel", "Unlock the current channel. See also: lockdown")]
public async Task UnlockChannelCommand(InteractionContext ctx, [Option("reason", "The reason for the unlock.")] string reason = "")
{
await ctx.CreateResponseAsync(DiscordInteractionResponseType.DeferredChannelMessageWithSource, new DiscordInteractionResponseBuilder().AsEphemeral(true));
await ctx.DeferAsync(ephemeral: true);

var currentChannel = ctx.Channel;
if (!Program.cfgjson.LockdownEnabledChannels.Contains(currentChannel.Id))
Expand Down
8 changes: 5 additions & 3 deletions Commands/InteractionCommands/MuteInteractions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ public async Task UnmuteSlashCommand(
[Option("reason", "The reason for the unmute.")] string reason = "No reason specified."
)
{
await ctx.DeferAsync(ephemeral: false);

reason = $"[Manual unmute by {DiscordHelpers.UniqueUsername(ctx.User)}]: {reason}";

// todo: store per-guild
Expand All @@ -75,18 +77,18 @@ public async Task UnmuteSlashCommand(
if ((await Program.db.HashExistsAsync("mutes", targetUser.Id)) || (member != default && member.Roles.Contains(mutedRole)))
{
await MuteHelpers.UnmuteUserAsync(targetUser, reason, true, ctx.User);
await ctx.RespondAsync($"{Program.cfgjson.Emoji.Information} Successfully unmuted **{DiscordHelpers.UniqueUsername(targetUser)}**.");
await ctx.FollowUpAsync(new DiscordFollowupMessageBuilder().WithContent($"{Program.cfgjson.Emoji.Information} Successfully unmuted **{DiscordHelpers.UniqueUsername(targetUser)}**."));
}
else
try
{
await MuteHelpers.UnmuteUserAsync(targetUser, reason, true, ctx.User);
await ctx.CreateResponseAsync($"{Program.cfgjson.Emoji.Warning} According to Discord that user is not muted, but I tried to unmute them anyway. Hope it works.");
await ctx.FollowUpAsync(new DiscordFollowupMessageBuilder().WithContent($"{Program.cfgjson.Emoji.Warning} According to Discord that user is not muted, but I tried to unmute them anyway. Hope it works."));
}
catch (Exception e)
{
Program.discord.Logger.LogError(e, "An error occurred unmuting {user}", targetUser.Id);
await ctx.RespondAsync($"{Program.cfgjson.Emoji.Error} That user doesn't appear to be muted, *and* an error occurred while attempting to unmute them anyway. Please contact the bot owner, the error has been logged.");
await ctx.FollowUpAsync(new DiscordFollowupMessageBuilder().WithContent($"{Program.cfgjson.Emoji.Error} That user doesn't appear to be muted, *and* an error occurred while attempting to unmute them anyway. Please contact the bot owner, the error has been logged."));
}
}

Expand Down
14 changes: 9 additions & 5 deletions Commands/InteractionCommands/TrackingInteractions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ public class PermadehoistSlashCommands
[SlashCommand("add", "Track a users messages.")]
public async Task TrackingAddSlashCmd(InteractionContext ctx, [Option("member", "The member to track.")] DiscordUser discordUser)
{
await ctx.DeferAsync(ephemeral: false);

if (Program.db.SetContains("trackedUsers", discordUser.Id))
{
await ctx.RespondAsync($"{Program.cfgjson.Emoji.Error} This user is already tracked!");
await ctx.FollowUpAsync(new DiscordFollowupMessageBuilder().WithContent($"{Program.cfgjson.Emoji.Error} This user is already tracked!"));
return;
}

Expand All @@ -24,7 +26,7 @@ public async Task TrackingAddSlashCmd(InteractionContext ctx, [Option("member",

await thread.SendMessageAsync($"{Program.cfgjson.Emoji.On} Now tracking {discordUser.Mention} in this thread! :eyes:");
thread.AddThreadMemberAsync(ctx.Member);
await ctx.RespondAsync($"{Program.cfgjson.Emoji.On} Now tracking {discordUser.Mention} in {thread.Mention}!");
await ctx.FollowUpAsync(new DiscordFollowupMessageBuilder().WithContent($"{Program.cfgjson.Emoji.On} Now tracking {discordUser.Mention} in {thread.Mention}!"));

}
else
Expand All @@ -33,16 +35,18 @@ public async Task TrackingAddSlashCmd(InteractionContext ctx, [Option("member",
await Program.db.HashSetAsync("trackingThreads", discordUser.Id, thread.Id);
await thread.SendMessageAsync($"{Program.cfgjson.Emoji.On} Now tracking {discordUser.Mention} in this thread! :eyes:");
await thread.AddThreadMemberAsync(ctx.Member);
await ctx.RespondAsync($"{Program.cfgjson.Emoji.On} Now tracking {discordUser.Mention} in {thread.Mention}!");
await ctx.FollowUpAsync(new DiscordFollowupMessageBuilder().WithContent($"{Program.cfgjson.Emoji.On} Now tracking {discordUser.Mention} in {thread.Mention}!"));
}
}

[SlashCommand("remove", "Stop tracking a users messages.")]
public async Task TrackingRemoveSlashCmd(InteractionContext ctx, [Option("member", "The member to track.")] DiscordUser discordUser)
{
await ctx.DeferAsync(ephemeral: false);

if (!Program.db.SetContains("trackedUsers", discordUser.Id))
{
await ctx.RespondAsync($"{Program.cfgjson.Emoji.Error} This user is not being tracked.");
await ctx.FollowUpAsync(new DiscordFollowupMessageBuilder().WithContent($"{Program.cfgjson.Emoji.Error} This user is not being tracked."));
return;
}

Expand All @@ -57,7 +61,7 @@ await thread.ModifyAsync(thread =>
thread.IsArchived = true;
});

await ctx.RespondAsync($"{Program.cfgjson.Emoji.Off} No longer tracking {discordUser.Mention}! Thread has been archived for now.");
await ctx.FollowUpAsync(new DiscordFollowupMessageBuilder().WithContent($"{Program.cfgjson.Emoji.Off} No longer tracking {discordUser.Mention}! Thread has been archived for now."));
}
}

Expand Down
2 changes: 1 addition & 1 deletion Commands/InteractionCommands/UserNoteInteractions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public async Task AddUserNoteAsync(InteractionContext ctx,
[Option("show_all_mods", "Whether to show this note to all mods, versus just yourself. Default: true")] bool showAllMods = true,
[Option("show_once", "Whether to show this note once and then discard it. Default: false")] bool showOnce = false)
{
await ctx.CreateResponseAsync(DiscordInteractionResponseType.DeferredChannelMessageWithSource, new DiscordInteractionResponseBuilder().AsEphemeral());
await ctx.DeferAsync();

// Assemble new note
long noteId = Program.db.StringIncrement("totalWarnings");
Expand Down
43 changes: 27 additions & 16 deletions Commands/InteractionCommands/WarningInteractions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,11 @@ public async Task TransferWarningsSlashCommand(InteractionContext ctx,
[Option("force_override", "DESTRUCTIVE OPERATION: Whether to OVERRIDE and DELETE the target users existing warnings.")] bool forceOverride = false
)
{
await ctx.DeferAsync(ephemeral: false);

if (sourceUser == targetUser)
{
await ctx.RespondAsync($"{Program.cfgjson.Emoji.Error} The source and target users cannot be the same!");
await ctx.FollowUpAsync(new DiscordFollowupMessageBuilder().WithContent($"{Program.cfgjson.Emoji.Error} The source and target users cannot be the same!"));
return;
}

Expand All @@ -91,7 +93,7 @@ public async Task TransferWarningsSlashCommand(InteractionContext ctx,

if (sourceWarnings.Length == 0)
{
await ctx.RespondAsync($"{Program.cfgjson.Emoji.Error} The source user has no warnings to transfer.", await WarningHelpers.GenerateWarningsEmbedAsync(sourceUser));
await ctx.FollowUpAsync(new DiscordFollowupMessageBuilder().WithContent($"{Program.cfgjson.Emoji.Error} The source user has no warnings to transfer.").AddEmbed(await GenerateWarningsEmbedAsync(sourceUser)));
return;
}
else if (merge)
Expand All @@ -104,9 +106,9 @@ public async Task TransferWarningsSlashCommand(InteractionContext ctx,
}
else if (targetWarnings.Length > 0 && !forceOverride)
{
await ctx.RespondAsync($"{Program.cfgjson.Emoji.Warning} **CAUTION**: The target user has warnings.\n\n" +
$"If you are sure you want to **OVERRIDE** and **DELETE** these warnings, please consider the consequences before adding `force_override: True` to the command.\nIf you wish to **NOT** override the target's warnings, please use `merge: True` instead.",
await WarningHelpers.GenerateWarningsEmbedAsync(targetUser));
await ctx.FollowUpAsync(new DiscordFollowupMessageBuilder().WithContent($"{Program.cfgjson.Emoji.Warning} **CAUTION**: The target user has warnings.\n\n" +
$"If you are sure you want to **OVERRIDE** and **DELETE** these warnings, please consider the consequences before adding `force_override: True` to the command.\nIf you wish to **NOT** override the target's warnings, please use `merge: True` instead.")
.AddEmbed(await GenerateWarningsEmbedAsync(targetUser)));
return;
}
else if (targetWarnings.Length > 0 && forceOverride)
Expand All @@ -124,12 +126,12 @@ await ctx.RespondAsync($"{Program.cfgjson.Emoji.Warning} **CAUTION**: The target
operationText = "merge ";
else if (forceOverride)
operationText = "force ";
await ctx.RespondAsync($"{Program.cfgjson.Emoji.Success} Successfully {operationText}transferred warnings from {sourceUser.Mention} to {targetUser.Mention}!");
await LogChannelHelper.LogMessageAsync("mod",
new DiscordMessageBuilder()
.WithContent($"{Program.cfgjson.Emoji.Information} Warnings from {sourceUser.Mention} were {operationText}transferred to {targetUser.Mention} by `{DiscordHelpers.UniqueUsername(ctx.User)}`")
.AddEmbed(await WarningHelpers.GenerateWarningsEmbedAsync(targetUser))
);
.AddEmbed(await GenerateWarningsEmbedAsync(targetUser))
);
await ctx.FollowUpAsync(new DiscordFollowupMessageBuilder().WithContent($"{Program.cfgjson.Emoji.Success} Successfully {operationText}transferred warnings from {sourceUser.Mention} to {targetUser.Mention}!"));
}

internal partial class WarningsAutocompleteProvider : IAutocompleteProvider
Expand Down Expand Up @@ -199,7 +201,10 @@ public async Task WarndetailsSlashCommand(InteractionContext ctx,
else if (warningObject.Type == WarningType.Note)
await ctx.RespondAsync($"{Program.cfgjson.Emoji.Error} That's a note, not a warning! Try using `/note details` instead, or make sure you've got the right warning ID.", ephemeral: true);
else
await ctx.RespondAsync(null, await FancyWarnEmbedAsync(warningObject, true, userID: user.Id), ephemeral: !publicWarnings);
{
await ctx.DeferAsync(ephemeral: !publicWarnings);
await ctx.FollowUpAsync(new DiscordFollowupMessageBuilder().AddEmbed(await FancyWarnEmbedAsync(warningObject, true, userID: user.Id)));
}
}

[SlashCommand("delwarn", "Search for a warning and delete it!", defaultPermission: false)]
Expand Down Expand Up @@ -240,18 +245,22 @@ public async Task DelwarnSlashCommand(InteractionContext ctx,
}
else
{
await ctx.DeferAsync(ephemeral: !showPublic);

bool success = await DelWarningAsync(warning, targetUser.Id);
if (success)
{
await ctx.RespondAsync($"{Program.cfgjson.Emoji.Deleted} Successfully deleted warning `{StringHelpers.Pad(warnId)}` (belonging to {targetUser.Mention})", ephemeral: !showPublic);

await LogChannelHelper.LogMessageAsync("mod",
new DiscordMessageBuilder()
.WithContent($"{Program.cfgjson.Emoji.Deleted} Warning deleted:" +
$"`{StringHelpers.Pad(warnId)}` (belonging to {targetUser.Mention}, deleted by {ctx.Member.Mention})")
.AddEmbed(await FancyWarnEmbedAsync(warning, true, 0xf03916, true, targetUser.Id))
.WithAllowedMentions(Mentions.None)
);
);

await ctx.FollowUpAsync(new DiscordFollowupMessageBuilder().WithContent($"{Program.cfgjson.Emoji.Deleted} Successfully deleted warning `{StringHelpers.Pad(warnId)}` (belonging to {targetUser.Mention})"));


}
else
{
Expand Down Expand Up @@ -304,16 +313,18 @@ public async Task EditWarnSlashCommand(InteractionContext ctx,
}
else
{
await EditWarning(user, warnId, ctx.User, reason);
await ctx.RespondAsync($"{Program.cfgjson.Emoji.Information} Successfully edited warning `{StringHelpers.Pad(warnId)}` (belonging to {user.Mention})",
await FancyWarnEmbedAsync(GetWarning(user.Id, warnId), userID: user.Id), ephemeral: !showPublic);
await ctx.DeferAsync(ephemeral: !showPublic);

await LogChannelHelper.LogMessageAsync("mod",
new DiscordMessageBuilder()
.WithContent($"{Program.cfgjson.Emoji.Information} Warning edited:" +
$"`{StringHelpers.Pad(warnId)}` (belonging to {user.Mention})")
.AddEmbed(await FancyWarnEmbedAsync(GetWarning(user.Id, warnId), true, userID: user.Id))
);
);

await EditWarning(user, warnId, ctx.User, reason);
await ctx.FollowUpAsync(new DiscordFollowupMessageBuilder().WithContent($"{Program.cfgjson.Emoji.Information} Successfully edited warning `{StringHelpers.Pad(warnId)}` (belonging to {user.Mention})")
.AddEmbed(await FancyWarnEmbedAsync(GetWarning(user.Id, warnId), userID: user.Id)));
}
}
}
Expand Down

0 comments on commit 25f500c

Please sign in to comment.