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:
@@ -1,4 +1,7 @@
|
||||
using DigitalData.MessagingService.Application.EmailSending.Commands;
|
||||
using DigitalData.MessagingService.Application.EmailReceiving.Queries;
|
||||
using DigitalData.MessagingService.Application.EmailReceiving.Commands;
|
||||
using DigitalData.MessagingService.Application.EmailAccount.Queries;
|
||||
using DigitalData.MessagingService.Abstraction;
|
||||
using MediatR;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
@@ -13,6 +16,7 @@ namespace DigitalData.MessagingService.API.Controllers;
|
||||
[Route("api/[controller]")]
|
||||
public class EmailsController(IMediator mediator) : ControllerBase
|
||||
{
|
||||
#region Send
|
||||
/// <summary>
|
||||
/// Send an email, optionally with file attachments.
|
||||
/// Omit the <c>attachments</c> field for a plain send.
|
||||
@@ -61,4 +65,68 @@ public class EmailsController(IMediator mediator) : ControllerBase
|
||||
|
||||
return result;
|
||||
}
|
||||
#endregion Send
|
||||
|
||||
#region Receive
|
||||
/// <summary>
|
||||
/// Fetch emails from an IMAP mailbox.
|
||||
/// </summary>
|
||||
/// <param name="accountId">Id of the email account (must have ImapServer configured).</param>
|
||||
/// <param name="folder">Mailbox folder to read (default: INBOX).</param>
|
||||
/// <param name="unseenOnly">Return only unread messages.</param>
|
||||
/// <param name="maxCount">Maximum number of messages to return (most-recent first, default: 50).</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
/// <returns>HTTP 200 with list of received emails.</returns>
|
||||
[HttpGet]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
public async Task<IActionResult> FetchEmails(
|
||||
[FromQuery] int accountId,
|
||||
[FromQuery] string folder = "INBOX",
|
||||
[FromQuery] bool unseenOnly = false,
|
||||
[FromQuery] int maxCount = 50,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var query = new FetchEmailsQuery
|
||||
{
|
||||
Account = new GetSenderQuery { Id = accountId },
|
||||
Folder = folder,
|
||||
UnseenOnly = unseenOnly,
|
||||
MaxCount = maxCount
|
||||
};
|
||||
|
||||
var emails = await mediator.Send(query, cancellationToken);
|
||||
return Ok(emails);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Mark a single IMAP message as seen (read).
|
||||
/// </summary>
|
||||
/// <param name="accountId">Id of the email account.</param>
|
||||
/// <param name="uid">UID of the message on the IMAP server.</param>
|
||||
/// <param name="folder">Mailbox folder the message resides in (default: INBOX).</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
/// <returns>HTTP 204 No Content.</returns>
|
||||
[HttpPatch("{uid}/seen")]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
public async Task<IActionResult> MarkAsSeen(
|
||||
[FromRoute] long uid,
|
||||
[FromQuery] int accountId,
|
||||
[FromQuery] string folder = "INBOX",
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var command = new MarkEmailAsSeenCommand
|
||||
{
|
||||
Account = new GetSenderQuery { Id = accountId },
|
||||
Uid = uid,
|
||||
Folder = folder
|
||||
};
|
||||
|
||||
await mediator.Send(command, cancellationToken);
|
||||
return NoContent();
|
||||
}
|
||||
#endregion Receive
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user