Add IMAP support for email fetching and marking as seen
Introduced IMAP functionality to enable fetching emails from an IMAP server and marking messages as seen. Updated the `EmailAccountDto` class with IMAP-related properties (`ImapServer`, `ImapPort`, `ImapUseSsl`) for configuration. Added `ReceivedEmailContext` to represent received emails and created the `IImapEmailService` interface with methods `FetchEmailsAsync` and `MarkAsSeenAsync`. Implemented the `LimilabsImapEmailService` class using Limilabs Mail.dll for IMAP operations, including connection handling, email fetching, and marking messages as seen. Added `FetchEmailsQuery` and `MarkEmailAsSeenCommand` with handlers to encapsulate IMAP logic. Updated `EmailsController` with new endpoints for fetching emails and marking messages as seen. Registered `IImapEmailService` in `DependencyInjection`. Included exception handling and logging for robust error management during IMAP operations.
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
using DigitalData.MessagingService.Application.Common.Interfaces;
|
||||
using DigitalData.MessagingService.Application.EmailAccount.Queries;
|
||||
using DigitalData.MessagingService.Abstraction;
|
||||
using DigitalData.MessagingService.Domain.Exceptions;
|
||||
using MediatR;
|
||||
|
||||
namespace DigitalData.MessagingService.Application.EmailReceiving.Queries;
|
||||
|
||||
/// <summary>
|
||||
/// Query to fetch emails from an IMAP mailbox.
|
||||
/// </summary>
|
||||
public record FetchEmailsQuery : IRequest<IEnumerable<ReceivedEmailContext>>
|
||||
{
|
||||
/// <summary>
|
||||
/// Identifies the email account to use.
|
||||
/// </summary>
|
||||
public required GetSenderQuery Account { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Mailbox folder to read from (default: "INBOX").
|
||||
/// </summary>
|
||||
public string Folder { get; init; } = "INBOX";
|
||||
|
||||
/// <summary>
|
||||
/// When <see langword="true"/> returns only unread messages.
|
||||
/// </summary>
|
||||
public bool UnseenOnly { get; init; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Maximum number of messages to retrieve (most-recent first). 0 = unlimited.
|
||||
/// </summary>
|
||||
public int MaxCount { get; init; } = 50;
|
||||
}
|
||||
|
||||
public class FetchEmailsQueryHandler(
|
||||
ISender Sender,
|
||||
IImapEmailService ImapService) : IRequestHandler<FetchEmailsQuery, IEnumerable<ReceivedEmailContext>>
|
||||
{
|
||||
public async Task<IEnumerable<ReceivedEmailContext>> Handle(FetchEmailsQuery 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.FetchEmailsAsync(
|
||||
account,
|
||||
request.Folder,
|
||||
request.UnseenOnly,
|
||||
request.MaxCount,
|
||||
cancellationToken);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user