From e840d026aa295f694a479218c5866c75fcaa6ba5 Mon Sep 17 00:00:00 2001 From: TekH Date: Tue, 11 Aug 2026 15:51:57 +0200 Subject: [PATCH] feat(imap): add markAsSeen option to fetch queries and interface - IImapEmailService.FetchEmailsAsync / FetchEmailByUidAsync now accept a bool markAsSeen = true parameter - FetchEmailsQuery and FetchEmailByUidQuery expose MarkAsSeen { init; } = true - markAsSeen=true uses BODY[] (server sets \\Seen, legacy-compatible) - markAsSeen=false uses BODY.PEEK[] (non-destructive read, flag untouched) --- .../Common/Interfaces/IImapEmailService.cs | 10 ++++++++++ .../EmailReceiving/Queries/FetchEmailByUidQuery.cs | 6 ++++++ .../EmailReceiving/Queries/FetchEmailsQuery.cs | 7 +++++++ 3 files changed, 23 insertions(+) diff --git a/src/core/DigitalData.MessagingService.Application/Common/Interfaces/IImapEmailService.cs b/src/core/DigitalData.MessagingService.Application/Common/Interfaces/IImapEmailService.cs index 4d4e773..f5a97f1 100644 --- a/src/core/DigitalData.MessagingService.Application/Common/Interfaces/IImapEmailService.cs +++ b/src/core/DigitalData.MessagingService.Application/Common/Interfaces/IImapEmailService.cs @@ -13,10 +13,15 @@ public interface IImapEmailService /// /// Account whose IMAP settings will be used. /// Filter to apply when fetching emails. + /// + /// When (default), fetched messages are marked as \Seen on the server. + /// Set to for a non-destructive read (uses BODY.PEEK internally). + /// /// Cancellation token. Task> FetchEmailsAsync( EmailAccountDto account, MailSearchFilter filter, + bool markAsSeen = true, CancellationToken cancellationToken = default); /// @@ -30,11 +35,16 @@ public interface IImapEmailService /// /// Fetches a single email by its UID. /// + /// + /// When (default), the message is marked as \Seen on the server. + /// Set to for a non-destructive read. + /// Task FetchEmailByUidAsync( EmailAccountDto account, long uid, string folder = "INBOX", bool withAttachments = false, + bool markAsSeen = true, CancellationToken cancellationToken = default); /// diff --git a/src/core/DigitalData.MessagingService.Application/EmailReceiving/Queries/FetchEmailByUidQuery.cs b/src/core/DigitalData.MessagingService.Application/EmailReceiving/Queries/FetchEmailByUidQuery.cs index 9597666..37c4fc2 100644 --- a/src/core/DigitalData.MessagingService.Application/EmailReceiving/Queries/FetchEmailByUidQuery.cs +++ b/src/core/DigitalData.MessagingService.Application/EmailReceiving/Queries/FetchEmailByUidQuery.cs @@ -36,6 +36,11 @@ public record FetchEmailByUidQuery : IRequest /// When , attachment data is included in the result. /// public bool WithAttachments { get; init; } = false; + /// + /// When (default), the message is marked as \Seen on the server. + /// Set to for a non-destructive peek. + /// + public bool MarkAsSeen { get; init; } = true; } public class FetchEmailByUidQueryHandler( @@ -57,6 +62,7 @@ public class FetchEmailByUidQueryHandler( (long)request.Uid!, request.Folder, request.WithAttachments, + request.MarkAsSeen, cancellationToken); } } diff --git a/src/core/DigitalData.MessagingService.Application/EmailReceiving/Queries/FetchEmailsQuery.cs b/src/core/DigitalData.MessagingService.Application/EmailReceiving/Queries/FetchEmailsQuery.cs index 9b1a6bb..7074d8f 100644 --- a/src/core/DigitalData.MessagingService.Application/EmailReceiving/Queries/FetchEmailsQuery.cs +++ b/src/core/DigitalData.MessagingService.Application/EmailReceiving/Queries/FetchEmailsQuery.cs @@ -21,6 +21,12 @@ public record FetchEmailsQuery : IRequest> /// Mail query used to filter and limit the emails retrieved. /// public MailSearchFilter Mail { get; init; } = new(); + + /// + /// When (default), fetched messages are marked as \Seen on the server. + /// Set to for a non-destructive peek. + /// + public bool MarkAsSeen { get; init; } = true; } public class FetchEmailsQueryHandler( @@ -40,6 +46,7 @@ public class FetchEmailsQueryHandler( return await ImapService.FetchEmailsAsync( account, request.Mail, + request.MarkAsSeen, cancellationToken); } }