From 59c2c5eada6da66f5472bef7859c3fe1975d6f91 Mon Sep 17 00:00:00 2001 From: neroduckale <100025711+neroduckale@users.noreply.github.com> Date: Tue, 12 Dec 2023 01:38:26 +0500 Subject: [PATCH 1/6] Add link to original message for activated reminders and /listremind (#203) --- src/Commands/RemindCommandGroup.cs | 37 +++++++++++++--------- src/Data/Reminder.cs | 3 +- src/Services/Update/MemberUpdateService.cs | 15 ++++++--- 3 files changed, 34 insertions(+), 21 deletions(-) diff --git a/src/Commands/RemindCommandGroup.cs b/src/Commands/RemindCommandGroup.cs index 79a583b..1966b9b 100644 --- a/src/Commands/RemindCommandGroup.cs +++ b/src/Commands/RemindCommandGroup.cs @@ -26,19 +26,21 @@ namespace Octobot.Commands; [UsedImplicitly] public class RemindCommandGroup : CommandGroup { - private readonly ICommandContext _context; + private readonly IInteractionCommandContext _context; private readonly IFeedbackService _feedback; private readonly GuildDataService _guildData; private readonly IDiscordRestUserAPI _userApi; + private readonly IDiscordRestInteractionAPI _interactionApi; public RemindCommandGroup( - ICommandContext context, GuildDataService guildData, IFeedbackService feedback, - IDiscordRestUserAPI userApi) + IInteractionCommandContext context, GuildDataService guildData, IFeedbackService feedback, + IDiscordRestUserAPI userApi, IDiscordRestInteractionAPI interactionApi) { _context = context; _guildData = guildData; _feedback = feedback; _userApi = userApi; + _interactionApi = interactionApi; } /// @@ -72,10 +74,10 @@ public class RemindCommandGroup : CommandGroup var data = await _guildData.GetData(guildId, CancellationToken); Messages.Culture = GuildSettings.Language.Get(data.Settings); - return await ListRemindersAsync(data.GetOrCreateMemberData(executorId), executor, bot, CancellationToken); + return await ListRemindersAsync(data.GetOrCreateMemberData(executorId), guildId, executor, bot, CancellationToken); } - private Task ListRemindersAsync(MemberData data, IUser executor, IUser bot, CancellationToken ct) + private Task ListRemindersAsync(MemberData data, Snowflake guildId, IUser executor, IUser bot, CancellationToken ct) { if (data.Reminders.Count == 0) { @@ -92,7 +94,8 @@ public class RemindCommandGroup : CommandGroup var reminder = data.Reminders[i]; builder.AppendBulletPointLine(string.Format(Messages.ReminderPosition, Markdown.InlineCode((i + 1).ToString()))) .AppendSubBulletPointLine(string.Format(Messages.ReminderText, Markdown.InlineCode(reminder.Text))) - .AppendSubBulletPointLine(string.Format(Messages.ReminderTime, Markdown.Timestamp(reminder.At))); + .AppendSubBulletPointLine(string.Format(Messages.ReminderTime, Markdown.Timestamp(reminder.At))) + .AppendSubBulletPointLine(string.Format(Messages.DescriptionActionJumpToMessage, $"https://discord.com/channels/{guildId.Value}/{reminder.ChannelId}/{reminder.MessageId}")); } var embed = new EmbedBuilder().WithSmallTitle( @@ -139,25 +142,29 @@ public class RemindCommandGroup : CommandGroup return await AddReminderAsync(@in, text, data, channelId, executor, CancellationToken); } - private Task AddReminderAsync( - TimeSpan @in, string text, GuildData data, + private async Task AddReminderAsync(TimeSpan @in, string text, GuildData data, Snowflake channelId, IUser executor, CancellationToken ct = default) { - var remindAt = DateTimeOffset.UtcNow.Add(@in); var memberData = data.GetOrCreateMemberData(executor.ID); + var remindAt = DateTimeOffset.UtcNow.Add(@in); + var responseResult = await _interactionApi.GetOriginalInteractionResponseAsync(_context.Interaction.ApplicationID, _context.Interaction.Token, ct); + if (!responseResult.IsDefined(out var response)) + { + return (Result)responseResult; + } memberData.Reminders.Add( new Reminder { At = remindAt, - Channel = channelId.Value, - Text = text + ChannelId = channelId.Value, + Text = text, + MessageId = response.ID.Value }); - var builder = new StringBuilder().AppendBulletPointLine(string.Format( - Messages.ReminderText, Markdown.InlineCode(text))) + var builder = new StringBuilder() + .AppendBulletPointLine(string.Format(Messages.ReminderText, Markdown.InlineCode(text))) .AppendBulletPoint(string.Format(Messages.ReminderTime, Markdown.Timestamp(remindAt))); - var embed = new EmbedBuilder().WithSmallTitle( string.Format(Messages.ReminderCreated, executor.GetTag()), executor) .WithDescription(builder.ToString()) @@ -165,7 +172,7 @@ public class RemindCommandGroup : CommandGroup .WithFooter(string.Format(Messages.ReminderPosition, memberData.Reminders.Count)) .Build(); - return _feedback.SendContextualEmbedResultAsync(embed, ct); + return await _feedback.SendContextualEmbedResultAsync(embed, ct); } /// diff --git a/src/Data/Reminder.cs b/src/Data/Reminder.cs index 42144f9..f21b222 100644 --- a/src/Data/Reminder.cs +++ b/src/Data/Reminder.cs @@ -4,5 +4,6 @@ public struct Reminder { public DateTimeOffset At { get; init; } public string Text { get; init; } - public ulong Channel { get; init; } + public ulong ChannelId { get; init; } + public ulong MessageId { get; init; } } diff --git a/src/Services/Update/MemberUpdateService.cs b/src/Services/Update/MemberUpdateService.cs index b4289ce..c3139c3 100644 --- a/src/Services/Update/MemberUpdateService.cs +++ b/src/Services/Update/MemberUpdateService.cs @@ -1,3 +1,4 @@ +using System.Text; using System.Text.RegularExpressions; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; @@ -114,7 +115,7 @@ public sealed partial class MemberUpdateService : BackgroundService for (var i = data.Reminders.Count - 1; i >= 0; i--) { - var reminderTickResult = await TickReminderAsync(data.Reminders[i], user, data, ct); + var reminderTickResult = await TickReminderAsync(data.Reminders[i], user, data, guildId, ct); failedResults.AddIfFailed(reminderTickResult); } @@ -217,17 +218,21 @@ public sealed partial class MemberUpdateService : BackgroundService [GeneratedRegex("[^0-9A-Za-zА-Яа-яЁё]")] private static partial Regex IllegalChars(); - private async Task TickReminderAsync(Reminder reminder, IUser user, MemberData data, CancellationToken ct) + private async Task TickReminderAsync(Reminder reminder, IUser user, MemberData data, Snowflake guildId, + CancellationToken ct) { if (DateTimeOffset.UtcNow < reminder.At) { return Result.FromSuccess(); } + var builder = new StringBuilder() + .AppendBulletPointLine(string.Format(Messages.DescriptionReminder, Markdown.InlineCode(reminder.Text))) + .AppendBulletPointLine(string.Format(Messages.DescriptionActionJumpToMessage, $"https://discord.com/channels/{guildId.Value}/{reminder.ChannelId}/{reminder.MessageId}")); + var embed = new EmbedBuilder().WithSmallTitle( string.Format(Messages.Reminder, user.GetTag()), user) - .WithDescription( - string.Format(Messages.DescriptionReminder, Markdown.InlineCode(reminder.Text))) + .WithDescription(builder.ToString()) .WithColour(ColorsList.Magenta) .Build(); @@ -237,7 +242,7 @@ public sealed partial class MemberUpdateService : BackgroundService } var messageResult = await _channelApi.CreateMessageAsync( - reminder.Channel.ToSnowflake(), Mention.User(user), embeds: new[] { built }, ct: ct); + reminder.ChannelId.ToSnowflake(), Mention.User(user), embeds: new[] { built }, ct: ct); if (!messageResult.IsSuccess) { return Result.FromError(messageResult); From eed08b237b0d08faf578a9cd1a084b4227666e32 Mon Sep 17 00:00:00 2001 From: Macintxsh II <95250141+mctaylors@users.noreply.github.com> Date: Tue, 12 Dec 2023 09:01:10 +0300 Subject: [PATCH 2/6] Recommend to install .NET 8 in README.md (#213) completely forgot about this while making #207 Signed-off-by: Macintxsh II <95250141+mctaylors@users.noreply.github.com> --- docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index cdd9ced..10ee63c 100644 --- a/docs/README.md +++ b/docs/README.md @@ -24,7 +24,7 @@ Veemo! I'm a general-purpose bot for moderation (formerly known as Boyfriend) wr ## Running Octobot -1. Install [.NET 7 SDK](https://dotnet.microsoft.com/en-us/download/dotnet/7.0) +1. Install [.NET 8 SDK](https://dotnet.microsoft.com/en-us/download/dotnet/8.0) 2. Go to the [Discord Developer Portal](https://discord.com/developers), create a new application and get a bot token. Don't forget to also enable all intents! 3. Clone this repository and open `Octobot` folder. ``` From 8594dfdb9bbcd77e9388b7bb02a19ca02a1cb0fd Mon Sep 17 00:00:00 2001 From: Octol1ttle Date: Wed, 13 Dec 2023 22:44:55 +0500 Subject: [PATCH 3/6] Bump Remora.Commands to fix issue with optional slash command args (#214) Fixes an exception that would occur when a slash command that has optional arguments would be called without them. See https://github.com/Remora/Remora.Discord/issues/319 for details ![image](https://github.com/LabsDevelopment/Octobot/assets/61277953/6589dee9-4bba-484e-9f77-b23dae514f45) --- Octobot.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/Octobot.csproj b/Octobot.csproj index 7d3500b..5258c89 100644 --- a/Octobot.csproj +++ b/Octobot.csproj @@ -25,6 +25,7 @@ + From b284ac28d506e2199d19e10e0d85d84bddf21f94 Mon Sep 17 00:00:00 2001 From: Octol1ttle Date: Sun, 17 Dec 2023 19:08:24 +0500 Subject: [PATCH 4/6] Disable "Convert to Primary Constructor" warning (#216) Me and other .NET developers hold the stance that primary constructors are not ready for production use, particularly with dependency injection. There are debates regarding the styling of primary constructors, but the bigger issue is that a primary constructor parameter cannot be made `readonly` (which is crucial with dependency injection). The inspection "Convert to Primary Constructor" was disabled in ReSharper CLI when we updated to .NET 8, but the warning is still present for ReSharper and Rider users. This PR disables this warning to avoid developers accidentally using a primary constructor. --- .editorconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.editorconfig b/.editorconfig index 4982036..ff9c068 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1022,7 +1022,7 @@ resharper_convert_to_constant_local_highlighting = warning resharper_convert_to_lambda_expression_highlighting = warning resharper_convert_to_local_function_highlighting = warning resharper_convert_to_null_coalescing_compound_assignment_highlighting = warning -resharper_convert_to_primary_constructor_highlighting = warning +resharper_convert_to_primary_constructor_highlighting = none resharper_convert_to_static_class_highlighting = warning resharper_convert_to_using_declaration_highlighting = warning resharper_convert_type_check_pattern_to_null_check_highlighting = warning From 9a23e1d5337e0232686feaef34cbb789b06cfe74 Mon Sep 17 00:00:00 2001 From: Macintxsh <95250141+mctaylors@users.noreply.github.com> Date: Sun, 17 Dec 2023 18:44:18 +0300 Subject: [PATCH 5/6] FeedbackServiceExtensions: Add FeedbackMessageOptions support (#219) Required for #218 --- src/Commands/AboutCommandGroup.cs | 2 +- src/Commands/BanCommandGroup.cs | 10 +++++----- src/Commands/ClearCommandGroup.cs | 4 ++-- .../Events/ErrorLoggingPostExecutionEvent.cs | 2 +- src/Commands/KickCommandGroup.cs | 6 +++--- src/Commands/MuteCommandGroup.cs | 16 ++++++++-------- src/Commands/PingCommandGroup.cs | 2 +- src/Commands/RemindCommandGroup.cs | 12 +++++------- src/Commands/SettingsCommandGroup.cs | 12 ++++++------ src/Commands/ToolsCommandGroup.cs | 8 ++++---- src/Extensions/FeedbackServiceExtensions.cs | 6 ++++-- 11 files changed, 40 insertions(+), 40 deletions(-) diff --git a/src/Commands/AboutCommandGroup.cs b/src/Commands/AboutCommandGroup.cs index e491470..45077e6 100644 --- a/src/Commands/AboutCommandGroup.cs +++ b/src/Commands/AboutCommandGroup.cs @@ -99,6 +99,6 @@ public class AboutCommandGroup : CommandGroup .WithImageUrl("https://cdn.mctaylors.ru/octobot-banner.png") .Build(); - return await _feedback.SendContextualEmbedResultAsync(embed, ct); + return await _feedback.SendContextualEmbedResultAsync(embed, ct: ct); } } diff --git a/src/Commands/BanCommandGroup.cs b/src/Commands/BanCommandGroup.cs index 3f89819..7493505 100644 --- a/src/Commands/BanCommandGroup.cs +++ b/src/Commands/BanCommandGroup.cs @@ -117,7 +117,7 @@ public class BanCommandGroup : CommandGroup var failedEmbed = new EmbedBuilder().WithSmallTitle(Messages.UserAlreadyBanned, bot) .WithColour(ColorsList.Red).Build(); - return await _feedback.SendContextualEmbedResultAsync(failedEmbed, ct); + return await _feedback.SendContextualEmbedResultAsync(failedEmbed, ct: ct); } var interactionResult @@ -132,7 +132,7 @@ public class BanCommandGroup : CommandGroup var errorEmbed = new EmbedBuilder().WithSmallTitle(interactionResult.Entity, bot) .WithColour(ColorsList.Red).Build(); - return await _feedback.SendContextualEmbedResultAsync(errorEmbed, ct); + return await _feedback.SendContextualEmbedResultAsync(errorEmbed, ct: ct); } var builder = new StringBuilder().AppendBulletPointLine(string.Format(Messages.DescriptionActionReason, reason)); @@ -190,7 +190,7 @@ public class BanCommandGroup : CommandGroup return Result.FromError(logResult.Error); } - return await _feedback.SendContextualEmbedResultAsync(embed, ct); + return await _feedback.SendContextualEmbedResultAsync(embed, ct: ct); } /// @@ -255,7 +255,7 @@ public class BanCommandGroup : CommandGroup var errorEmbed = new EmbedBuilder().WithSmallTitle(Messages.UserNotBanned, bot) .WithColour(ColorsList.Red).Build(); - return await _feedback.SendContextualEmbedResultAsync(errorEmbed, ct); + return await _feedback.SendContextualEmbedResultAsync(errorEmbed, ct: ct); } var unbanResult = await _guildApi.RemoveGuildBanAsync( @@ -281,6 +281,6 @@ public class BanCommandGroup : CommandGroup return Result.FromError(logResult.Error); } - return await _feedback.SendContextualEmbedResultAsync(embed, ct); + return await _feedback.SendContextualEmbedResultAsync(embed, ct: ct); } } diff --git a/src/Commands/ClearCommandGroup.cs b/src/Commands/ClearCommandGroup.cs index 8e1f90d..7ebd4ea 100644 --- a/src/Commands/ClearCommandGroup.cs +++ b/src/Commands/ClearCommandGroup.cs @@ -121,7 +121,7 @@ public class ClearCommandGroup : CommandGroup var failedEmbed = new EmbedBuilder().WithSmallTitle(Messages.NoMessagesToClear, bot) .WithColour(ColorsList.Red).Build(); - return await _feedback.SendContextualEmbedResultAsync(failedEmbed, ct); + return await _feedback.SendContextualEmbedResultAsync(failedEmbed, ct: ct); } var title = author is not null @@ -146,6 +146,6 @@ public class ClearCommandGroup : CommandGroup var embed = new EmbedBuilder().WithSmallTitle(title, bot) .WithColour(ColorsList.Green).Build(); - return await _feedback.SendContextualEmbedResultAsync(embed, ct); + return await _feedback.SendContextualEmbedResultAsync(embed, ct: ct); } } diff --git a/src/Commands/Events/ErrorLoggingPostExecutionEvent.cs b/src/Commands/Events/ErrorLoggingPostExecutionEvent.cs index 426fd35..2d5f606 100644 --- a/src/Commands/Events/ErrorLoggingPostExecutionEvent.cs +++ b/src/Commands/Events/ErrorLoggingPostExecutionEvent.cs @@ -65,6 +65,6 @@ public class ErrorLoggingPostExecutionEvent : IPostExecutionEvent .WithColour(ColorsList.Red) .Build(); - return await _feedback.SendContextualEmbedResultAsync(embed, ct); + return await _feedback.SendContextualEmbedResultAsync(embed, ct: ct); } } diff --git a/src/Commands/KickCommandGroup.cs b/src/Commands/KickCommandGroup.cs index f2a840d..1ef6057 100644 --- a/src/Commands/KickCommandGroup.cs +++ b/src/Commands/KickCommandGroup.cs @@ -104,7 +104,7 @@ public class KickCommandGroup : CommandGroup var embed = new EmbedBuilder().WithSmallTitle(Messages.UserNotFoundShort, bot) .WithColour(ColorsList.Red).Build(); - return await _feedback.SendContextualEmbedResultAsync(embed, CancellationToken); + return await _feedback.SendContextualEmbedResultAsync(embed, ct: CancellationToken); } return await KickUserAsync(executor, target, reason, guild, channelId, data, bot, CancellationToken); @@ -126,7 +126,7 @@ public class KickCommandGroup : CommandGroup var failedEmbed = new EmbedBuilder().WithSmallTitle(interactionResult.Entity, bot) .WithColour(ColorsList.Red).Build(); - return await _feedback.SendContextualEmbedResultAsync(failedEmbed, ct); + return await _feedback.SendContextualEmbedResultAsync(failedEmbed, ct: ct); } var dmChannelResult = await _userApi.CreateDMAsync(target.ID, ct); @@ -171,6 +171,6 @@ public class KickCommandGroup : CommandGroup string.Format(Messages.UserKicked, target.GetTag()), target) .WithColour(ColorsList.Green).Build(); - return await _feedback.SendContextualEmbedResultAsync(embed, ct); + return await _feedback.SendContextualEmbedResultAsync(embed, ct: ct); } } diff --git a/src/Commands/MuteCommandGroup.cs b/src/Commands/MuteCommandGroup.cs index 2ce06ae..6a28f38 100644 --- a/src/Commands/MuteCommandGroup.cs +++ b/src/Commands/MuteCommandGroup.cs @@ -101,7 +101,7 @@ public class MuteCommandGroup : CommandGroup var embed = new EmbedBuilder().WithSmallTitle(Messages.UserNotFoundShort, bot) .WithColour(ColorsList.Red).Build(); - return await _feedback.SendContextualEmbedResultAsync(embed, CancellationToken); + return await _feedback.SendContextualEmbedResultAsync(embed, ct: CancellationToken); } return await MuteUserAsync(executor, target, reason, duration, guildId, data, channelId, bot, CancellationToken); @@ -124,7 +124,7 @@ public class MuteCommandGroup : CommandGroup var failedEmbed = new EmbedBuilder().WithSmallTitle(interactionResult.Entity, bot) .WithColour(ColorsList.Red).Build(); - return await _feedback.SendContextualEmbedResultAsync(failedEmbed, ct); + return await _feedback.SendContextualEmbedResultAsync(failedEmbed, ct: ct); } var until = DateTimeOffset.UtcNow.Add(duration); // >:) @@ -151,7 +151,7 @@ public class MuteCommandGroup : CommandGroup string.Format(Messages.UserMuted, target.GetTag()), target) .WithColour(ColorsList.Green).Build(); - return await _feedback.SendContextualEmbedResultAsync(embed, ct); + return await _feedback.SendContextualEmbedResultAsync(embed, ct: ct); } private async Task SelectMuteMethodAsync( @@ -202,7 +202,7 @@ public class MuteCommandGroup : CommandGroup .WithDescription(Messages.DurationRequiredForTimeOuts) .WithColour(ColorsList.Red).Build(); - return await _feedback.SendContextualEmbedResultAsync(failedEmbed, ct); + return await _feedback.SendContextualEmbedResultAsync(failedEmbed, ct: ct); } var muteResult = await _guildApi.ModifyGuildMemberAsync( @@ -266,7 +266,7 @@ public class MuteCommandGroup : CommandGroup var embed = new EmbedBuilder().WithSmallTitle(Messages.UserNotFoundShort, bot) .WithColour(ColorsList.Red).Build(); - return await _feedback.SendContextualEmbedResultAsync(embed, CancellationToken); + return await _feedback.SendContextualEmbedResultAsync(embed, ct: CancellationToken); } return await RemoveMuteAsync(executor, target, reason, guildId, data, channelId, bot, CancellationToken); @@ -289,7 +289,7 @@ public class MuteCommandGroup : CommandGroup var failedEmbed = new EmbedBuilder().WithSmallTitle(interactionResult.Entity, bot) .WithColour(ColorsList.Red).Build(); - return await _feedback.SendContextualEmbedResultAsync(failedEmbed, ct); + return await _feedback.SendContextualEmbedResultAsync(failedEmbed, ct: ct); } var guildMemberResult = await _guildApi.GetGuildMemberAsync(guildId, target.ID, ct); @@ -307,7 +307,7 @@ public class MuteCommandGroup : CommandGroup var failedEmbed = new EmbedBuilder().WithSmallTitle(Messages.UserNotMuted, bot) .WithColour(ColorsList.Red).Build(); - return await _feedback.SendContextualEmbedResultAsync(failedEmbed, ct); + return await _feedback.SendContextualEmbedResultAsync(failedEmbed, ct: ct); } var removeMuteRoleAsync = @@ -337,7 +337,7 @@ public class MuteCommandGroup : CommandGroup string.Format(Messages.UserUnmuted, target.GetTag()), target) .WithColour(ColorsList.Green).Build(); - return await _feedback.SendContextualEmbedResultAsync(embed, ct); + return await _feedback.SendContextualEmbedResultAsync(embed, ct: ct); } private async Task RemoveMuteRoleAsync( diff --git a/src/Commands/PingCommandGroup.cs b/src/Commands/PingCommandGroup.cs index 84b15a0..31fa6dc 100644 --- a/src/Commands/PingCommandGroup.cs +++ b/src/Commands/PingCommandGroup.cs @@ -97,6 +97,6 @@ public class PingCommandGroup : CommandGroup .WithCurrentTimestamp() .Build(); - return await _feedback.SendContextualEmbedResultAsync(embed, ct); + return await _feedback.SendContextualEmbedResultAsync(embed, ct: ct); } } diff --git a/src/Commands/RemindCommandGroup.cs b/src/Commands/RemindCommandGroup.cs index 1966b9b..67e7910 100644 --- a/src/Commands/RemindCommandGroup.cs +++ b/src/Commands/RemindCommandGroup.cs @@ -85,7 +85,7 @@ public class RemindCommandGroup : CommandGroup .WithColour(ColorsList.Red) .Build(); - return _feedback.SendContextualEmbedResultAsync(failedEmbed, ct); + return _feedback.SendContextualEmbedResultAsync(failedEmbed, ct: ct); } var builder = new StringBuilder(); @@ -104,8 +104,7 @@ public class RemindCommandGroup : CommandGroup .WithColour(ColorsList.Cyan) .Build(); - return _feedback.SendContextualEmbedResultAsync( - embed, ct); + return _feedback.SendContextualEmbedResultAsync(embed, ct: ct); } /// @@ -172,7 +171,7 @@ public class RemindCommandGroup : CommandGroup .WithFooter(string.Format(Messages.ReminderPosition, memberData.Reminders.Count)) .Build(); - return await _feedback.SendContextualEmbedResultAsync(embed, ct); + return await _feedback.SendContextualEmbedResultAsync(embed, ct: ct); } /// @@ -215,7 +214,7 @@ public class RemindCommandGroup : CommandGroup .WithColour(ColorsList.Red) .Build(); - return _feedback.SendContextualEmbedResultAsync(failedEmbed, ct); + return _feedback.SendContextualEmbedResultAsync(failedEmbed, ct: ct); } var reminder = data.Reminders[index]; @@ -231,7 +230,6 @@ public class RemindCommandGroup : CommandGroup .WithColour(ColorsList.Green) .Build(); - return _feedback.SendContextualEmbedResultAsync( - embed, ct); + return _feedback.SendContextualEmbedResultAsync(embed, ct: ct); } } diff --git a/src/Commands/SettingsCommandGroup.cs b/src/Commands/SettingsCommandGroup.cs index 60323d7..a8891bd 100644 --- a/src/Commands/SettingsCommandGroup.cs +++ b/src/Commands/SettingsCommandGroup.cs @@ -124,7 +124,7 @@ public class SettingsCommandGroup : CommandGroup .WithColour(ColorsList.Red) .Build(); - return _feedback.SendContextualEmbedResultAsync(errorEmbed, ct); + return _feedback.SendContextualEmbedResultAsync(errorEmbed, ct: ct); } footer.Append($"{Messages.Page} {page}/{totalPages} "); @@ -149,7 +149,7 @@ public class SettingsCommandGroup : CommandGroup .WithFooter(footer.ToString()) .Build(); - return _feedback.SendContextualEmbedResultAsync(embed, ct); + return _feedback.SendContextualEmbedResultAsync(embed, ct: ct); } /// @@ -207,7 +207,7 @@ public class SettingsCommandGroup : CommandGroup .WithColour(ColorsList.Red) .Build(); - return await _feedback.SendContextualEmbedResultAsync(failedEmbed, ct); + return await _feedback.SendContextualEmbedResultAsync(failedEmbed, ct: ct); } var builder = new StringBuilder(); @@ -230,7 +230,7 @@ public class SettingsCommandGroup : CommandGroup .WithColour(ColorsList.Green) .Build(); - return await _feedback.SendContextualEmbedResultAsync(embed, ct); + return await _feedback.SendContextualEmbedResultAsync(embed, ct: ct); } /// @@ -284,7 +284,7 @@ public class SettingsCommandGroup : CommandGroup .WithColour(ColorsList.Green) .Build(); - return await _feedback.SendContextualEmbedResultAsync(embed, ct); + return await _feedback.SendContextualEmbedResultAsync(embed, ct: ct); } private async Task ResetAllSettingsAsync(JsonNode cfg, IUser bot, @@ -305,6 +305,6 @@ public class SettingsCommandGroup : CommandGroup .WithColour(ColorsList.Green) .Build(); - return await _feedback.SendContextualEmbedResultAsync(embed, ct); + return await _feedback.SendContextualEmbedResultAsync(embed, ct: ct); } } diff --git a/src/Commands/ToolsCommandGroup.cs b/src/Commands/ToolsCommandGroup.cs index be4c2c1..78058cb 100644 --- a/src/Commands/ToolsCommandGroup.cs +++ b/src/Commands/ToolsCommandGroup.cs @@ -163,7 +163,7 @@ public class ToolsCommandGroup : CommandGroup .WithFooter($"ID: {target.ID.ToString()}") .Build(); - return await _feedback.SendContextualEmbedResultAsync(embed, ct); + return await _feedback.SendContextualEmbedResultAsync(embed, ct: ct); } private static Color AppendGuildInformation(Color color, IGuildMember guildMember, StringBuilder builder) @@ -312,7 +312,7 @@ public class ToolsCommandGroup : CommandGroup .WithFooter($"ID: {guild.ID.ToString()}") .Build(); - return _feedback.SendContextualEmbedResultAsync(embed, ct); + return _feedback.SendContextualEmbedResultAsync(embed, ct: ct); } /// @@ -389,7 +389,7 @@ public class ToolsCommandGroup : CommandGroup .WithColour(embedColor) .Build(); - return _feedback.SendContextualEmbedResultAsync(embed, ct); + return _feedback.SendContextualEmbedResultAsync(embed, ct: ct); } private static readonly TimestampStyle[] AllStyles = @@ -459,6 +459,6 @@ public class ToolsCommandGroup : CommandGroup .WithColour(ColorsList.Blue) .Build(); - return _feedback.SendContextualEmbedResultAsync(embed, ct); + return _feedback.SendContextualEmbedResultAsync(embed, ct: ct); } } diff --git a/src/Extensions/FeedbackServiceExtensions.cs b/src/Extensions/FeedbackServiceExtensions.cs index 739aa34..40e0d53 100644 --- a/src/Extensions/FeedbackServiceExtensions.cs +++ b/src/Extensions/FeedbackServiceExtensions.cs @@ -1,4 +1,5 @@ using Remora.Discord.API.Objects; +using Remora.Discord.Commands.Feedback.Messages; using Remora.Discord.Commands.Feedback.Services; using Remora.Results; @@ -7,13 +8,14 @@ namespace Octobot.Extensions; public static class FeedbackServiceExtensions { public static async Task SendContextualEmbedResultAsync( - this IFeedbackService feedback, Result embedResult, CancellationToken ct = default) + this IFeedbackService feedback, Result embedResult, + FeedbackMessageOptions? options = null, CancellationToken ct = default) { if (!embedResult.IsDefined(out var embed)) { return Result.FromError(embedResult); } - return (Result)await feedback.SendContextualEmbedAsync(embed, ct: ct); + return (Result)await feedback.SendContextualEmbedAsync(embed, options, ct); } } From 541e18fff002598827e94f39c93e0142835ab617 Mon Sep 17 00:00:00 2001 From: Macintxsh <95250141+mctaylors@users.noreply.github.com> Date: Sun, 17 Dec 2023 19:47:52 +0300 Subject: [PATCH 6/6] Add ChannelApiExtensions (#217) This PR adds an extension method to make it easier to pass Result to CreateMessageAsync --------- Co-authored-by: Octol1ttle --- src/Commands/BanCommandGroup.cs | 7 +-- src/Commands/KickCommandGroup.cs | 7 +-- src/Extensions/ChannelApiExtensions.cs | 29 ++++++++++++ src/Responders/GuildLoadedResponder.cs | 29 +++++------- src/Responders/GuildMemberJoinedResponder.cs | 8 +--- src/Responders/MessageDeletedResponder.cs | 8 +--- src/Responders/MessageEditedResponder.cs | 8 +--- src/Services/Update/MemberUpdateService.cs | 11 ++--- .../Update/ScheduledEventUpdateService.cs | 44 +++++-------------- src/Services/UtilityService.cs | 15 ++----- 10 files changed, 64 insertions(+), 102 deletions(-) create mode 100644 src/Extensions/ChannelApiExtensions.cs diff --git a/src/Commands/BanCommandGroup.cs b/src/Commands/BanCommandGroup.cs index 7493505..f0da978 100644 --- a/src/Commands/BanCommandGroup.cs +++ b/src/Commands/BanCommandGroup.cs @@ -158,12 +158,7 @@ public class BanCommandGroup : CommandGroup .WithColour(ColorsList.Red) .Build(); - if (!dmEmbed.IsDefined(out var dmBuilt)) - { - return Result.FromError(dmEmbed); - } - - await _channelApi.CreateMessageAsync(dmChannel.ID, embeds: new[] { dmBuilt }, ct: ct); + await _channelApi.CreateMessageWithEmbedResultAsync(dmChannel.ID, embedResult: dmEmbed, ct: ct); } var banResult = await _guildApi.CreateGuildBanAsync( diff --git a/src/Commands/KickCommandGroup.cs b/src/Commands/KickCommandGroup.cs index 1ef6057..cad8ea9 100644 --- a/src/Commands/KickCommandGroup.cs +++ b/src/Commands/KickCommandGroup.cs @@ -140,12 +140,7 @@ public class KickCommandGroup : CommandGroup .WithColour(ColorsList.Red) .Build(); - if (!dmEmbed.IsDefined(out var dmBuilt)) - { - return Result.FromError(dmEmbed); - } - - await _channelApi.CreateMessageAsync(dmChannel.ID, embeds: new[] { dmBuilt }, ct: ct); + await _channelApi.CreateMessageWithEmbedResultAsync(dmChannel.ID, embedResult: dmEmbed, ct: ct); } var kickResult = await _guildApi.RemoveGuildMemberAsync( diff --git a/src/Extensions/ChannelApiExtensions.cs b/src/Extensions/ChannelApiExtensions.cs new file mode 100644 index 0000000..12ccf35 --- /dev/null +++ b/src/Extensions/ChannelApiExtensions.cs @@ -0,0 +1,29 @@ +using OneOf; +using Remora.Discord.API.Abstractions.Objects; +using Remora.Discord.API.Abstractions.Rest; +using Remora.Discord.API.Objects; +using Remora.Rest.Core; +using Remora.Results; + +namespace Octobot.Extensions; + +public static class ChannelApiExtensions +{ + public static async Task CreateMessageWithEmbedResultAsync(this IDiscordRestChannelAPI channelApi, + Snowflake channelId, Optional message = default, Optional nonce = default, + Optional isTextToSpeech = default, Optional> embedResult = default, + Optional allowedMentions = default, Optional messageRefenence = default, + Optional> components = default, + Optional> stickerIds = default, + Optional>> attachments = default, + Optional flags = default, CancellationToken ct = default) + { + if (!embedResult.IsDefined() || !embedResult.Value.IsDefined(out var embed)) + { + return Result.FromError(embedResult.Value); + } + + return (Result)await channelApi.CreateMessageAsync(channelId, message, nonce, isTextToSpeech, new[] { embed }, + allowedMentions, messageRefenence, components, stickerIds, attachments, flags, ct); + } +} diff --git a/src/Responders/GuildLoadedResponder.cs b/src/Responders/GuildLoadedResponder.cs index 5d5d68a..cc720c8 100644 --- a/src/Responders/GuildLoadedResponder.cs +++ b/src/Responders/GuildLoadedResponder.cs @@ -92,17 +92,19 @@ public class GuildLoadedResponder : IResponder .WithCurrentTimestamp() .WithColour(ColorsList.Blue) .Build(); - if (!embed.IsDefined(out var built)) - { - return Result.FromError(embed); - } - return (Result)await _channelApi.CreateMessageAsync( - GuildSettings.PrivateFeedbackChannel.Get(cfg), embeds: new[] { built }, ct: ct); + return await _channelApi.CreateMessageWithEmbedResultAsync( + GuildSettings.PrivateFeedbackChannel.Get(cfg), embedResult: embed, ct: ct); } private async Task SendDataLoadFailed(IGuild guild, GuildData data, IUser bot, CancellationToken ct) { + var channelResult = await _utility.GetEmergencyFeedbackChannel(guild, data, ct); + if (!channelResult.IsDefined(out var channel)) + { + return Result.FromError(channelResult); + } + var errorEmbed = new EmbedBuilder() .WithSmallTitle(Messages.DataLoadFailedTitle, bot) .WithDescription(Messages.DataLoadFailedDescription) @@ -110,18 +112,7 @@ public class GuildLoadedResponder : IResponder .WithColour(ColorsList.Red) .Build(); - if (!errorEmbed.IsDefined(out var errorBuilt)) - { - return Result.FromError(errorEmbed); - } - - var channelResult = await _utility.GetEmergencyFeedbackChannel(guild, data, ct); - if (!channelResult.IsDefined(out var channel)) - { - return Result.FromError(channelResult); - } - - return (Result)await _channelApi.CreateMessageAsync( - channel, embeds: new[] { errorBuilt }, ct: ct); + return await _channelApi.CreateMessageWithEmbedResultAsync( + channel, embedResult: errorEmbed, ct: ct); } } diff --git a/src/Responders/GuildMemberJoinedResponder.cs b/src/Responders/GuildMemberJoinedResponder.cs index 09075bf..66faa28 100644 --- a/src/Responders/GuildMemberJoinedResponder.cs +++ b/src/Responders/GuildMemberJoinedResponder.cs @@ -72,13 +72,9 @@ public class GuildMemberJoinedResponder : IResponder .WithTimestamp(gatewayEvent.JoinedAt) .WithColour(ColorsList.Green) .Build(); - if (!embed.IsDefined(out var built)) - { - return Result.FromError(embed); - } - return (Result)await _channelApi.CreateMessageAsync( - GuildSettings.PublicFeedbackChannel.Get(cfg), embeds: new[] { built }, + return await _channelApi.CreateMessageWithEmbedResultAsync( + GuildSettings.PublicFeedbackChannel.Get(cfg), embedResult: embed, allowedMentions: Octobot.NoMentions, ct: ct); } diff --git a/src/Responders/MessageDeletedResponder.cs b/src/Responders/MessageDeletedResponder.cs index 5e4870b..bfedb22 100644 --- a/src/Responders/MessageDeletedResponder.cs +++ b/src/Responders/MessageDeletedResponder.cs @@ -98,13 +98,9 @@ public class MessageDeletedResponder : IResponder .WithTimestamp(message.Timestamp) .WithColour(ColorsList.Red) .Build(); - if (!embed.IsDefined(out var built)) - { - return Result.FromError(embed); - } - return (Result)await _channelApi.CreateMessageAsync( - GuildSettings.PrivateFeedbackChannel.Get(cfg), embeds: new[] { built }, + return await _channelApi.CreateMessageWithEmbedResultAsync( + GuildSettings.PrivateFeedbackChannel.Get(cfg), embedResult: embed, allowedMentions: Octobot.NoMentions, ct: ct); } } diff --git a/src/Responders/MessageEditedResponder.cs b/src/Responders/MessageEditedResponder.cs index 3b0a6aa..16f7af4 100644 --- a/src/Responders/MessageEditedResponder.cs +++ b/src/Responders/MessageEditedResponder.cs @@ -107,13 +107,9 @@ public class MessageEditedResponder : IResponder .WithTimestamp(timestamp.Value) .WithColour(ColorsList.Yellow) .Build(); - if (!embed.IsDefined(out var built)) - { - return Result.FromError(embed); - } - return (Result)await _channelApi.CreateMessageAsync( - GuildSettings.PrivateFeedbackChannel.Get(cfg), embeds: new[] { built }, + return await _channelApi.CreateMessageWithEmbedResultAsync( + GuildSettings.PrivateFeedbackChannel.Get(cfg), embedResult: embed, allowedMentions: Octobot.NoMentions, ct: ct); } } diff --git a/src/Services/Update/MemberUpdateService.cs b/src/Services/Update/MemberUpdateService.cs index c3139c3..e7860ae 100644 --- a/src/Services/Update/MemberUpdateService.cs +++ b/src/Services/Update/MemberUpdateService.cs @@ -236,16 +236,11 @@ public sealed partial class MemberUpdateService : BackgroundService .WithColour(ColorsList.Magenta) .Build(); - if (!embed.IsDefined(out var built)) - { - return Result.FromError(embed); - } - - var messageResult = await _channelApi.CreateMessageAsync( - reminder.ChannelId.ToSnowflake(), Mention.User(user), embeds: new[] { built }, ct: ct); + var messageResult = await _channelApi.CreateMessageWithEmbedResultAsync( + reminder.ChannelId.ToSnowflake(), Mention.User(user), embedResult: embed, ct: ct); if (!messageResult.IsSuccess) { - return Result.FromError(messageResult); + return messageResult; } data.Reminders.Remove(reminder); diff --git a/src/Services/Update/ScheduledEventUpdateService.cs b/src/Services/Update/ScheduledEventUpdateService.cs index 9ec9fcf..38fe4a7 100644 --- a/src/Services/Update/ScheduledEventUpdateService.cs +++ b/src/Services/Update/ScheduledEventUpdateService.cs @@ -215,10 +215,6 @@ public sealed class ScheduledEventUpdateService : BackgroundService .WithCurrentTimestamp() .WithColour(ColorsList.White) .Build(); - if (!embed.IsDefined(out var built)) - { - return Result.FromError(embed); - } var roleMention = !GuildSettings.EventNotificationRole.Get(settings).Empty() ? Mention.Role(GuildSettings.EventNotificationRole.Get(settings)) @@ -231,8 +227,8 @@ public sealed class ScheduledEventUpdateService : BackgroundService URL: $"https://discord.com/events/{scheduledEvent.GuildID}/{scheduledEvent.ID}" ); - return (Result)await _channelApi.CreateMessageAsync( - GuildSettings.EventNotificationChannel.Get(settings), roleMention, embeds: new[] { built }, + return await _channelApi.CreateMessageWithEmbedResultAsync( + GuildSettings.EventNotificationChannel.Get(settings), roleMention, embedResult: embed, components: new[] { new ActionRowComponent(new[] { button }) }, ct: ct); } @@ -317,14 +313,9 @@ public sealed class ScheduledEventUpdateService : BackgroundService .WithCurrentTimestamp() .Build(); - if (!startedEmbed.IsDefined(out var startedBuilt)) - { - return Result.FromError(startedEmbed); - } - - return (Result)await _channelApi.CreateMessageAsync( + return await _channelApi.CreateMessageWithEmbedResultAsync( GuildSettings.EventNotificationChannel.Get(data.Settings), - content, embeds: new[] { startedBuilt }, ct: ct); + content, embedResult: startedEmbed, ct: ct); } private async Task SendScheduledEventCompletedMessage(ScheduledEventData eventData, GuildData data, @@ -348,14 +339,9 @@ public sealed class ScheduledEventUpdateService : BackgroundService .WithCurrentTimestamp() .Build(); - if (!completedEmbed.IsDefined(out var completedBuilt)) - { - return Result.FromError(completedEmbed); - } - - var createResult = (Result)await _channelApi.CreateMessageAsync( + var createResult = await _channelApi.CreateMessageWithEmbedResultAsync( GuildSettings.EventNotificationChannel.Get(data.Settings), - embeds: new[] { completedBuilt }, ct: ct); + embedResult: completedEmbed, ct: ct); if (createResult.IsSuccess) { data.ScheduledEvents.Remove(eventData.Id); @@ -380,13 +366,8 @@ public sealed class ScheduledEventUpdateService : BackgroundService .WithCurrentTimestamp() .Build(); - if (!embed.IsDefined(out var built)) - { - return Result.FromError(embed); - } - - var createResult = (Result)await _channelApi.CreateMessageAsync( - GuildSettings.EventNotificationChannel.Get(data.Settings), embeds: new[] { built }, ct: ct); + var createResult = await _channelApi.CreateMessageWithEmbedResultAsync( + GuildSettings.EventNotificationChannel.Get(data.Settings), embedResult: embed, ct: ct); if (createResult.IsSuccess) { data.ScheduledEvents.Remove(eventData.Id); @@ -445,14 +426,9 @@ public sealed class ScheduledEventUpdateService : BackgroundService .WithColour(ColorsList.Default) .Build(); - if (!earlyResult.IsDefined(out var earlyBuilt)) - { - return Result.FromError(earlyResult); - } - - return (Result)await _channelApi.CreateMessageAsync( + return await _channelApi.CreateMessageWithEmbedResultAsync( GuildSettings.EventNotificationChannel.Get(data.Settings), content, - embeds: new[] { earlyBuilt }, ct: ct); + embedResult: earlyResult, ct: ct); } } diff --git a/src/Services/UtilityService.cs b/src/Services/UtilityService.cs index d40570a..9ac481b 100644 --- a/src/Services/UtilityService.cs +++ b/src/Services/UtilityService.cs @@ -226,26 +226,19 @@ public sealed class UtilityService : IHostedService .WithColour(color) .Build(); - if (!logEmbed.IsDefined(out var logBuilt)) - { - return Result.FromError(logEmbed); - } - - var builtArray = new[] { logBuilt }; - // Not awaiting to reduce response time if (isPublic && publicChannel != channelId) { - _ = _channelApi.CreateMessageAsync( - publicChannel, embeds: builtArray, + _ = _channelApi.CreateMessageWithEmbedResultAsync( + publicChannel, embedResult: logEmbed, ct: ct); } if (privateChannel != publicChannel && privateChannel != channelId) { - _ = _channelApi.CreateMessageAsync( - privateChannel, embeds: builtArray, + _ = _channelApi.CreateMessageWithEmbedResultAsync( + privateChannel, embedResult: logEmbed, ct: ct); }