Skip to content

Commit

Permalink
Merge pull request #1038 from discord-csharp/channel-designations-ref…
Browse files Browse the repository at this point in the history
…actor

V3: Refactor channel designations, add relay service
  • Loading branch information
patrickklaeren authored Nov 13, 2024
2 parents 03e7b69 + f1daede commit 063417e
Show file tree
Hide file tree
Showing 23 changed files with 406 additions and 1,278 deletions.
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

0 comments on commit 063417e

Please sign in to comment.