MODiX icon indicating copy to clipboard operation
MODiX copied to clipboard

Reminder Function

Open HurricanKai opened this issue 5 years ago • 2 comments

Please add a command that would simply read back an input + ping after a certain time.

HurricanKai avatar Jul 05 '20 20:07 HurricanKai

Picking this up

Hamsterland avatar Jul 11 '20 19:07 Hamsterland

So, this is the basic outline of the structure of the InfractionExpiration system I've got in-progress.

public class InfractionExpirationBehavior
    : INotificationHandler<InfractionCreatedNotification>,
        INotificationHandler<InfractionExpirationTimerTriggeredNotification>,
        INotificationHandler<ReadyNotification>
{
    // On InfractionCreatedNotification, invokes IInfractionExpirationTimer.TryScheduleTrigger()
    // On InfractionExpirationTimerTriggeredNotification and ReadyNotification, invokes IInfractionExpirationManager.ManageAsync()
}
public interface IInfractionExpirationManager
{
    // Invokes IInfractionRepository.SearchIdsAsync() to find expired infractions
    // Invokes IModerationService.ExpireInfractionAsync() for each expired infraction
    // Invokes IInfractionRepository.ReadNextExpirationAsync(), to decide whether to invoke `IInfractionExpirationTimer.TryScheduleTrigger()
    Task ManageAsync(
        CancellationToken cancellationToken);
}
public interface IInfractionExpirationTimer
{
    // Decides whether to invoke ITimer.Change() on private ITimer, which invokes `IMessageDispatcher.Dispatch(InfractionExpirationTimerTriggered)` when elapsed.
    void TryScheduleTrigger(
        DateTimeOffset timestamp);
}

Seems like this structure would be perfectly-suited for managing reminder notifications, as well. I can go ahead and extract the ITimer and ITimerFactory abstractions and PR them for you to use as well.

You'll also want (as a rough idea)...

// Abstracts all unique database operations, for testability
public interface IRemindersRepository
{
    IAsyncEnumerable<ReminderDetailViewModel>> AsyncEnumerateDetails(...);
    IAsyncEnumerable<long> AsyncEnumerateIds(...);
    Task<long> CreateAsync(...);
    Task<DateTimeOffset> ReadNextExpiration();
    Task<bool> TryDeleteAsync(long reminderId, ...);
    Task<bool> TryUpdateAsync(long reminderId, ...);
}
// Abstracts reminder-related business operations that are user-facing or reused internally in multiple places.
// Also serves as a place to perform authorization.
public interface IRemindersService
{
    Task Create(ulong userId, ...);
    Task Delete(ulong userId, long reminderId, ...);
    Task Update(ulong userId, long reminderId, ...);
}
public class RemindersModule
    : ModuleBase
{
    // Whatever commands you want to support
}
public interface IReminderDetailToEmbedFormatter
{
    // To be used by IRemindersManager, to keep rendering logic out of the business layer.
    Embed Format(ReminderDetailViewModel reminderDetail);
}

JakenVeina avatar Jul 11 '20 19:07 JakenVeina

As part of a new effort to refocus on priorities, I will close this. If you feel this is imperative to the bot, a new issue can be opened to supersede this.

patrickklaeren avatar Mar 26 '24 14:03 patrickklaeren