Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V3: Refactor channel designations, add relay service #1038

Merged
merged 2 commits into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 14 additions & 9 deletions src/Modix.Bot/Behaviors/ModerationLoggingBehavior.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,14 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

using Discord;

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;

using Modix.Bot.Extensions;
using Modix.Common.Extensions;
using Modix.Data.Models.Core;
using Modix.Data.Models.Moderation;
using Modix.Data.Repositories;
using Modix.Services;
using Modix.Services.Core;
using Modix.Services.Moderation;
using Modix.Services.Utilities;
Expand All @@ -24,15 +21,19 @@ namespace Modix.Behaviors
/// </summary>
public class ModerationLoggingBehavior : IModerationActionEventHandler
{
private readonly DiscordRelayService _discordRelayService;

/// <summary>
/// Constructs a new <see cref="ModerationLoggingBehavior"/> object, with injected dependencies.
/// </summary>
public ModerationLoggingBehavior(
IServiceProvider serviceProvider,
IDiscordClient discordClient,
IDesignatedChannelService designatedChannelService,
DesignatedChannelService designatedChannelService,
DiscordRelayService discordRelayService,
IOptions<ModixConfig> config)
{
_discordRelayService = discordRelayService;
DiscordClient = discordClient;
DesignatedChannelService = designatedChannelService;
Config = config.Value;
Expand All @@ -43,7 +44,9 @@ public ModerationLoggingBehavior(
/// <inheritdoc />
public async Task OnModerationActionCreatedAsync(long moderationActionId, ModerationActionCreationData data)
{
if (!await DesignatedChannelService.AnyDesignatedChannelAsync(data.GuildId, DesignatedChannelType.ModerationLog))
var designatedChannels = await DesignatedChannelService.GetDesignatedChannelIds(data.GuildId, DesignatedChannelType.ModerationLog);

if (!designatedChannels.Any())
return;

var moderationAction = await ModerationService.GetModerationActionSummaryAsync(moderationActionId);
Expand Down Expand Up @@ -73,8 +76,10 @@ public async Task OnModerationActionCreatedAsync(long moderationActionId, Modera
moderationAction.OriginalInfractionReason,
string.IsNullOrEmpty(moderationAction.Infraction?.RescindReason) ? "" : $"for reason: ```\n{moderationAction.Infraction?.RescindReason}```");

await DesignatedChannelService.SendToDesignatedChannelsAsync(
await DiscordClient.GetGuildAsync(data.GuildId), DesignatedChannelType.ModerationLog, message);
foreach (var channel in designatedChannels)
{
await _discordRelayService.SendMessageToChannel(channel, message);
}
}

/// <summary>
Expand All @@ -85,7 +90,7 @@ await DesignatedChannelService.SendToDesignatedChannelsAsync(
/// <summary>
/// An <see cref="IDesignatedChannelService"/> for logging moderation actions.
/// </summary>
internal protected IDesignatedChannelService DesignatedChannelService { get; }
internal protected DesignatedChannelService DesignatedChannelService { get; }

/// <summary>
/// An <see cref="IModerationService"/> for performing moderation actions.
Expand Down
31 changes: 23 additions & 8 deletions src/Modix.Bot/Behaviors/PromotionLoggingHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using Modix.Common.Messaging;
using Modix.Data.Models.Core;
using Modix.Data.Models.Promotions;
using Modix.Services;
using Modix.Services.Core;
using Modix.Services.Promotions;
using Modix.Services.Utilities;
Expand All @@ -24,17 +25,21 @@ namespace Modix.Behaviors
public class PromotionLoggingHandler :
INotificationHandler<PromotionActionCreatedNotification>
{
private readonly DiscordRelayService _discordRelayService;

/// <summary>
/// Constructs a new <see cref="PromotionLoggingHandler"/> object, with injected dependencies.
/// </summary>
public PromotionLoggingHandler(
IAuthorizationService authorizationService,
DiscordSocketClient discordSocketClient,
IDesignatedChannelService designatedChannelService,
DesignatedChannelService designatedChannelService,
IUserService userService,
IPromotionsService promotionsService,
DiscordRelayService discordRelayService,
IOptions<ModixConfig> modixConfig)
{
_discordRelayService = discordRelayService;
AuthorizationService = authorizationService;
DiscordSocketClient = discordSocketClient;
DesignatedChannelService = designatedChannelService;
Expand All @@ -49,26 +54,36 @@ public async Task HandleNotificationAsync(PromotionActionCreatedNotification not
if (AuthorizationService.CurrentUserId is null)
await AuthorizationService.OnAuthenticatedAsync(DiscordSocketClient.CurrentUser);

if (await DesignatedChannelService.AnyDesignatedChannelAsync(notification.Data.GuildId, DesignatedChannelType.PromotionLog))
if (await DesignatedChannelService.HasDesignatedChannelForType(notification.Data.GuildId, DesignatedChannelType.PromotionLog))
{
var message = await FormatPromotionLogEntryAsync(notification.Id);

if (message == null)
return;

await DesignatedChannelService.SendToDesignatedChannelsAsync(
await DiscordSocketClient.GetGuildAsync(notification.Data.GuildId), DesignatedChannelType.PromotionLog, message);
var designatedChannels = await DesignatedChannelService.GetDesignatedChannelIds(notification.Data.GuildId,
DesignatedChannelType.PromotionLog);

foreach (var channel in designatedChannels)
{
await _discordRelayService.SendMessageToChannel(channel, message);
}
}

if (await DesignatedChannelService.AnyDesignatedChannelAsync(notification.Data.GuildId, DesignatedChannelType.PromotionNotifications))
if (await DesignatedChannelService.HasDesignatedChannelForType(notification.Data.GuildId, DesignatedChannelType.PromotionNotifications))
{
var embed = await FormatPromotionNotificationAsync(notification.Id, notification.Data);

if (embed == null)
return;

await DesignatedChannelService.SendToDesignatedChannelsAsync(
await DiscordSocketClient.GetGuildAsync(notification.Data.GuildId), DesignatedChannelType.PromotionNotifications, "", embed);
var designatedChannels = await DesignatedChannelService.GetDesignatedChannelIds(notification.Data.GuildId,
DesignatedChannelType.PromotionNotifications);

foreach (var channel in designatedChannels)
{
await _discordRelayService.SendMessageToChannel(channel, string.Empty, embed);
}
}
}

Expand Down Expand Up @@ -144,7 +159,7 @@ private async Task<string> FormatPromotionLogEntryAsync(long promotionActionId)
/// <summary>
/// An <see cref="IDesignatedChannelService"/> for logging moderation actions.
/// </summary>
internal protected IDesignatedChannelService DesignatedChannelService { get; }
internal protected DesignatedChannelService DesignatedChannelService { get; }

/// <summary>
/// An <see cref="IUserService"/> for retrieving user info
Expand Down
25 changes: 25 additions & 0 deletions src/Modix.Bot/Handlers/SendMessageHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System.Threading;
using System.Threading.Tasks;
using Discord;
using Discord.WebSocket;
using MediatR;
using Modix.Services;

namespace Modix.Bot.Handlers;

public class SendMessageHandler(DiscordSocketClient discordSocketClient)
: IRequestHandler<SendMessageInDiscordRequest, bool>
{
public async Task<bool> Handle(SendMessageInDiscordRequest request, CancellationToken cancellationToken)
{
var channel = await discordSocketClient.GetChannelAsync(request.ChannelId);

if (channel is ITextChannel textChannel)
{
await textChannel.SendMessageAsync(request.Message, false, request.Embed, allowedMentions: AllowedMentions.None);
return true;
}

return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,45 +9,48 @@
using Modix.Bot.Preconditions;
using Modix.Common.Extensions;
using Modix.Data.Models.Core;
using Modix.Services;
using Modix.Services.CommandHelp;
using Modix.Services.Core;

namespace Modix.Modules
namespace Modix.Bot.Modules
{
[ModuleHelp("Channel Designations", "Configures channel designation for various bot services.")]
[Group("channel-designations", "Configures channel designation for various bot services.")]
[DefaultMemberPermissions(GuildPermission.BanMembers)]
public class DesignatedChannelModule : InteractionModuleBase
public class DesignatedChannelsModule : InteractionModuleBase
{
private readonly IDesignatedChannelService _designatedChannelService;
private readonly DesignatedChannelService _designatedChannelService;
private readonly ModixConfig _config;

public DesignatedChannelModule(IDesignatedChannelService designatedChannelService, IOptions<ModixConfig> config)
public DesignatedChannelsModule(DesignatedChannelService designatedChannelService, IOptions<ModixConfig> config)
{
_designatedChannelService = designatedChannelService;
_config = config.Value;
}

[SlashCommand("list", "Lists all of the channels designated for use by the bot.")]
[RequireClaims(AuthorizationClaim.DesignatedChannelMappingRead)]
public async Task ListAsync()
public async Task List()
{
var channels = await _designatedChannelService.GetDesignatedChannelsAsync(Context.Guild.Id);

// https://mod.gg/config/channels
var url = new UriBuilder(_config.WebsiteBaseUrl)
{
Path = "/config/channels"
}.RemoveDefaultPort().ToString();
var channels = await _designatedChannelService.GetDesignatedChannels(Context.Guild.Id);

var builder = new EmbedBuilder()
{
Title = "Assigned Channel Designations",
Url = url,
Color = Color.Gold,
Timestamp = DateTimeOffset.UtcNow
};

if (!string.IsNullOrWhiteSpace(_config.WebsiteBaseUrl))
{
var url = new UriBuilder(_config.WebsiteBaseUrl)
{
Path = "/config/channels"
}.RemoveDefaultPort().ToString();

builder.Url = url;
}

foreach (var type in Enum.GetValues<DesignatedChannelType>())
{
var designatedChannels = channels
Expand All @@ -69,25 +72,25 @@ public async Task ListAsync()

[SlashCommand("add", "Assigns a designation to the given channel.")]
[RequireClaims(AuthorizationClaim.DesignatedChannelMappingCreate)]
public async Task AddAsync(
public async Task Add(
[Summary(description: "The channel to be assigned a designation.")]
IMessageChannel channel,
[Summary(description: "The designation to assign.")]
DesignatedChannelType designation)
{
await _designatedChannelService.AddDesignatedChannelAsync(Context.Guild, channel, designation);
await _designatedChannelService.AddDesignatedChannel(Context.Guild, channel, designation);
await Context.AddConfirmationAsync();
}

[SlashCommand("remove", "Removes a designation from the given channel.")]
[RequireClaims(AuthorizationClaim.DesignatedChannelMappingDelete)]
public async Task RemoveAsync(
public async Task Remove(
[Summary(description: "The channel whose designation is to be unassigned.")]
IMessageChannel channel,
[Summary(description: "The designation to be unassigned.")]
DesignatedChannelType designation)
{
await _designatedChannelService.RemoveDesignatedChannelAsync(Context.Guild, channel, designation);
await _designatedChannelService.RemoveDesignatedChannel(Context.Guild, channel, designation);
await Context.AddConfirmationAsync();
}
}
Expand Down
1 change: 0 additions & 1 deletion src/Modix.Bot/Modules/InfractionModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ public async Task SearchAsync(

var counts = await _moderationService.GetInfractionCountsForUserAsync(user.Id);

// https://modix.gg/infractions?subject=12345
var url = new UriBuilder(_config.WebsiteBaseUrl)
{
Path = "/infractions",
Expand Down
8 changes: 4 additions & 4 deletions src/Modix.Bot/Responders/StarboardReactionResponder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
using Modix.Bot.Notifications;
using Modix.Bot.Responders.MessageQuotes;
using Modix.Data.Models.Core;
using Modix.Services.Core;
using Modix.Services;
using Modix.Services.Starboard;
using Modix.Services.Utilities;

namespace Modix.Bot.Responders
{
public class StarboardReactionResponder(IStarboardService starboardService, IDesignatedChannelService designatedChannelService)
public class StarboardReactionResponder(IStarboardService starboardService, DesignatedChannelService designatedChannelService)
: INotificationHandler<ReactionAddedNotificationV3>, INotificationHandler<ReactionRemovedNotificationV3>
{
public Task Handle(ReactionAddedNotificationV3 notification, CancellationToken cancellationToken)
Expand All @@ -35,10 +35,10 @@ private async Task HandleReactionAsync(Cacheable<IUserMessage, ulong> cachedMess
}

var isIgnoredFromStarboard = await designatedChannelService
.ChannelHasDesignationAsync(channel.Guild.Id, channel.Id, DesignatedChannelType.IgnoredFromStarboard, default);
.ChannelHasDesignation(channel.Guild.Id, channel.Id, DesignatedChannelType.IgnoredFromStarboard, default);

var starboardExists = await designatedChannelService
.AnyDesignatedChannelAsync(channel.GuildId, DesignatedChannelType.Starboard);
.HasDesignatedChannelForType(channel.GuildId, DesignatedChannelType.Starboard);

if (isIgnoredFromStarboard || !starboardExists)
{
Expand Down
Loading
Loading