Skip to content
FeroxFoxxo edited this page Jan 30, 2022 · 4 revisions

Introduction

Typically, the Events folder contains a maximum of three classes, though may contain more regarding circumstance.

These may include, though are optional:

Event Handler

This class contains a list of events that other classes can invoke internally. This is used if multiple classes, perhaps from different projects, need to hook into the same event. It should extend InternalEventHandler. For instance,

namespace MASZ.UserNotes.Events;

public class UserNoteEventHandler : InternalEventHandler
{
	internal readonly AsyncEvent<Func<UserNote, IUser, Task>> UserNoteCreatedEvent = new();

	public event Func<UserNote, IUser, Task> OnUserNoteCreated
	{
		add => UserNoteCreatedEvent.Add(value);
		remove => UserNoteCreatedEvent.Remove(value);
	}
}

To hook into this event, you can use _eventHandler.yourevent += METHOD.

To run this event, you can use _eventHandler.yourevent.Invoke(yourdata);. Note, you must be using MASZ.Bot.Extensions;.

Announcer

This class announces events that have happened to a guild. Such as the mod notification webhook. It typically will extend Event, and will have a service provider and the event handler for that project. For instance,

namespace MASZ.Punishments.Events;

public class PunishmentEventAnnouncer : Event
{
	private readonly PunishmentEventHandler _eventHandler;
	private readonly ILogger<PunishmentEventAnnouncer> _logger;
	private readonly IServiceProvider _serviceProvider;

	public PunishmentEventAnnouncer(PunishmentEventHandler eventHandler,
		ILogger<PunishmentEventAnnouncer> logger, IServiceProvider serviceProvider)
	{
		_eventHandler = eventHandler;
		_logger = logger;
		_serviceProvider = serviceProvider;
	}

	public void RegisterEvents()
	{
		_eventHandler.OnModCaseCommentCreated += async (a, b) => await AnnounceComment(a, b, RestAction.Created);

		_eventHandler.OnModCaseCommentUpdated += async (a, b) => await AnnounceComment(a, b, RestAction.Updated);

		_eventHandler.OnModCaseCommentDeleted += async (a, b) => await AnnounceComment(a, b, RestAction.Deleted);
	}

	private async Task AnnounceComment(ModCaseComment comment, IUser actor, RestAction action)
	{
		// NOTE: TO ACCESS SCOPED SERVICES YOU MUST USE A SCOPE

		using var scope = _serviceProvider.CreateScope();

		_logger.LogInformation(
			$"Announcing comment {comment.Id} in case {comment.ModCase.GuildId}/{comment.ModCase.CaseId}.");

		var guildConfig = await scope.ServiceProvider.GetRequiredService<GuildConfigRepository>()
			.GetGuildConfig(comment.ModCase.GuildId);

		if (!string.IsNullOrEmpty(guildConfig.ModInternalNotificationWebhook))
		{
			_logger.LogInformation(
				$"Sending internal webhook for comment {comment.ModCase.GuildId}/{comment.ModCase.CaseId}/{comment.Id} to {guildConfig.ModInternalNotificationWebhook}.");

			try
			{
				var embed = await comment.CreateCommentEmbed(action, actor, scope.ServiceProvider);
				await DiscordRest.ExecuteWebhook(guildConfig.ModInternalNotificationWebhook, embed.Build());
			}
			catch (Exception e)
			{
				_logger.LogError(e,
					$"Error while announcing comment {comment.ModCase.GuildId}/{comment.ModCase.CaseId}/{comment.Id} to {guildConfig.ModInternalNotificationWebhook}.");
			}
		}
	}
}

NOTE: If you need to create any embeds, you should be making them in the Extensions/XYZCreator.cs class.

Audit

This class sends a message directly to the audit logger of the bot, to notify that an action has been made. It should not be as detailed as an annouuncer, just stating that something has run. This is only for the use of the site admins, and should also extends and implement Event, taking reference to the AuditLogger service and the related event handler. For example,

namespace MASZ.Punishments.Events;

public class PunishmentEventAudit : Event
{
	private readonly AuditLogger _auditLogger;
	private readonly PunishmentEventHandler _punishmentEventHandler;

	public PunishmentEventAudit(AuditLogger auditLogger, PunishmentEventHandler punishmentEventHandler)
	{
		_auditLogger = auditLogger;
		_punishmentEventHandler = punishmentEventHandler;
	}

	public void RegisterEvents()
	{
		_punishmentEventHandler.OnFileUploaded += OnFileUploaded;
	}

	private Task OnFileUploaded(UploadedFile fileInfo, ModCase modCase, IUser actor)
	{
		_auditLogger.QueueLog(
			$"**File** `{fileInfo.Name}` uploaded to case {modCase.GuildId}/{modCase.CaseId} by <@{actor.Id}>.");
		return Task.CompletedTask;
	}
}