diff --git a/src/core/DigitalData.MessagingService.Application/Common/Interfaces/IImapEmailService.cs b/src/core/DigitalData.MessagingService.Application/Common/Interfaces/IImapEmailService.cs
index 34145aa..445127b 100644
--- a/src/core/DigitalData.MessagingService.Application/Common/Interfaces/IImapEmailService.cs
+++ b/src/core/DigitalData.MessagingService.Application/Common/Interfaces/IImapEmailService.cs
@@ -22,27 +22,6 @@ public interface IImapEmailService
MailSearchFilter filter,
CancellationToken cancellationToken = default);
- ///
- /// Fetches only the UIDs of messages matching the specified filter.
- ///
- Task> FetchEmailUidsAsync(
- EmailAccountDto account,
- MailSearchFilter filter,
- CancellationToken cancellationToken = default);
-
- ///
- /// 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,
- CancellationToken cancellationToken = default);
-
///
/// Marks a message as seen (read) on the server.
///
diff --git a/src/core/DigitalData.MessagingService.Application/EmailReceiving/Queries/FetchEmailByUidQuery.cs b/src/core/DigitalData.MessagingService.Application/EmailReceiving/Queries/FetchEmailByUidQuery.cs
deleted file mode 100644
index 9597666..0000000
--- a/src/core/DigitalData.MessagingService.Application/EmailReceiving/Queries/FetchEmailByUidQuery.cs
+++ /dev/null
@@ -1,62 +0,0 @@
-using DigitalData.MessagingService.Abstraction;
-using DigitalData.MessagingService.Application.Common.Interfaces;
-using DigitalData.MessagingService.Application.EmailAccount.Queries;
-using DigitalData.MessagingService.Domain.Exceptions;
-using MediatR;
-
-namespace DigitalData.MessagingService.Application.EmailReceiving.Queries;
-
-///
-/// Query to fetch a single email by its UID from an IMAP mailbox.
-///
-public record FetchEmailByUidQuery : IRequest
-{
- ///
- /// Identifies the email account to use.
- ///
- public required GetSenderQuery Account { get; init; }
-
- ///
- /// UID of the message to fetch.
- ///
- internal long? Uid { get; private set; } = null;
-
- public FetchEmailByUidQuery WithUid(long uid)
- {
- Uid = uid;
- return this;
- }
-
- ///
- /// Mailbox folder the message resides in (default: "INBOX").
- ///
- public string Folder { get; init; } = "INBOX";
-
- ///
- /// When , attachment data is included in the result.
- ///
- public bool WithAttachments { get; init; } = false;
-}
-
-public class FetchEmailByUidQueryHandler(
- ISender Sender,
- IImapEmailService ImapService) : IRequestHandler
-{
- public async Task Handle(FetchEmailByUidQuery request, CancellationToken cancellationToken)
- {
- var account = await Sender.Send(request.Account, cancellationToken)
- ?? throw new NotFoundException(
- $"No email account found for the given criteria (Id: {request.Account.Id}, Username: {request.Account.Username}).");
-
- if (string.IsNullOrWhiteSpace(account.ImapServer))
- throw new InvalidOperationException(
- $"IMAP is not configured for account '{account.Username}' (Id: {account.Id}). Set ImapServer in EmailAccounts configuration.");
-
- return await ImapService.FetchEmailByUidAsync(
- account,
- (long)request.Uid!,
- request.Folder,
- request.WithAttachments,
- cancellationToken);
- }
-}
diff --git a/src/core/DigitalData.MessagingService.Application/EmailReceiving/Queries/FetchEmailUidsQuery.cs b/src/core/DigitalData.MessagingService.Application/EmailReceiving/Queries/FetchEmailUidsQuery.cs
deleted file mode 100644
index 7c1d92b..0000000
--- a/src/core/DigitalData.MessagingService.Application/EmailReceiving/Queries/FetchEmailUidsQuery.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-using DigitalData.MessagingService.Application.Common.Interfaces;
-using DigitalData.MessagingService.Application.Common.Models.MailSearch;
-using DigitalData.MessagingService.Application.EmailAccount.Queries;
-using DigitalData.MessagingService.Domain.Exceptions;
-using MediatR;
-
-namespace DigitalData.MessagingService.Application.EmailReceiving.Queries;
-
-///
-/// Query to fetch only the UIDs of matching emails from an IMAP mailbox.
-///
-public record FetchEmailUidsQuery : IRequest>
-{
- ///
- /// Identifies the email account to use.
- ///
- public required GetSenderQuery Account { get; init; }
-
- ///
- /// Mail query used to filter and limit the emails retrieved.
- ///
- public MailSearchFilter Mail { get; init; } = new();
-}
-
-public class FetchEmailUidsQueryHandler(ISender Sender, IImapEmailService ImapService) : IRequestHandler>
-{
- public async Task> Handle(FetchEmailUidsQuery request, CancellationToken cancellationToken)
- {
- var account = await Sender.Send(request.Account, cancellationToken)
- ?? throw new NotFoundException(
- $"No email account found for the given criteria (Id: {request.Account.Id}, Username: {request.Account.Username}).");
-
- if (string.IsNullOrWhiteSpace(account.ImapServer))
- throw new InvalidOperationException(
- $"IMAP is not configured for account '{account.Username}' (Id: {account.Id}). Set ImapServer in EmailAccounts configuration.");
-
- return await ImapService.FetchEmailUidsAsync(
- account,
- request.Mail,
- cancellationToken);
- }
-}
diff --git a/src/presentation/DigitalData.MessagingService.API/Controllers/EmailController.cs b/src/presentation/DigitalData.MessagingService.API/Controllers/EmailController.cs
index 316bce6..720949c 100644
--- a/src/presentation/DigitalData.MessagingService.API/Controllers/EmailController.cs
+++ b/src/presentation/DigitalData.MessagingService.API/Controllers/EmailController.cs
@@ -16,6 +16,21 @@ namespace DigitalData.MessagingService.API.Controllers;
[Route("api/[controller]")]
public class EmailController(IMediator mediator) : ControllerBase
{
+ ///
+ ///
+ ///
+ public enum OnlyFilter
+ {
+ ///
+ ///
+ ///
+ HtmlBody,
+ ///
+ ///
+ ///
+ Uid,
+ }
+
#region Send
///
/// Send an email, optionally with file attachments.
@@ -72,70 +87,31 @@ public class EmailController(IMediator mediator) : ControllerBase
/// Fetch emails from an IMAP mailbox.
///
/// Query parameters for filtering and fetching emails from the IMAP mailbox.
- ///
+ ///
/// Cancellation token.
/// HTTP 200 with list of received emails.
[HttpGet]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
- public async Task FetchEmails([FromQuery] FetchEmailsQuery query, [FromQuery] bool firstHtmlBodyOnly = false, CancellationToken cancellationToken = default)
+ public async Task FetchEmails([FromQuery] FetchEmailsQuery query, [FromQuery] OnlyFilter? only = null, CancellationToken cancellationToken = default)
{
var emails = await mediator.Send(query, cancellationToken);
if(!emails.Any())
return NotFound("No emails found matching the specified criteria.");
- if (firstHtmlBodyOnly && emails.FirstOrDefault()?.HtmlBody is string htmlBody)
- return Content(htmlBody, "text/html");
-
- return Ok(emails);
- }
-
- ///
- /// Fetch only the UIDs of emails matching the given filter from an IMAP mailbox.
- ///
- /// Query parameters for filtering emails.
- /// Cancellation token.
- /// HTTP 200 with the list of matching UIDs, or HTTP 404 if none found.
- [HttpGet("uid")]
- [ProducesResponseType(StatusCodes.Status200OK)]
- [ProducesResponseType(StatusCodes.Status400BadRequest)]
- [ProducesResponseType(StatusCodes.Status404NotFound)]
- public async Task FetchEmailUids([FromQuery] FetchEmailUidsQuery query, CancellationToken cancellationToken = default)
- {
- var uids = await mediator.Send(query, cancellationToken);
-
- if (!uids.Any())
- return NotFound("No emails found matching the specified criteria.");
-
- return Ok(uids);
- }
-
- ///
- /// Fetch a single email by its UID from an IMAP mailbox.
- ///
- /// The unique identifier (UID) of the message.
- /// Query parameters including account, folder and attachment flag.
- ///
- /// Cancellation token.
- /// HTTP 200 with the matched email, or HTTP 404 if not found.
- [HttpGet("{uid:long}")]
- [ProducesResponseType(StatusCodes.Status200OK)]
- [ProducesResponseType(StatusCodes.Status400BadRequest)]
- [ProducesResponseType(StatusCodes.Status404NotFound)]
- public async Task FetchEmailByUid([FromRoute] long uid, [FromQuery] FetchEmailByUidQuery query, [FromQuery] bool htmlBodyOnly = false, CancellationToken cancellationToken = default)
- {
- var queryWithUid = query.WithUid(uid);
- var email = await mediator.Send(queryWithUid, cancellationToken);
-
- if (email is null)
- return NotFound($"No email found with UID {uid}.");
-
- if (htmlBodyOnly)
- return Content(email.HtmlBody, "text/html");
-
- return Ok(email);
+ if (only == OnlyFilter.HtmlBody)
+ {
+ if (emails.FirstOrDefault()?.HtmlBody is string htmlBody)
+ return Content(htmlBody, "text/html");
+ else
+ return NotFound();
+ }
+ else if (only == OnlyFilter.Uid)
+ return Ok(emails.Select(e => e.Uid).ToList());
+ else
+ return Ok(emails);
}
///