feat(api): add IMAP send, POP3 receive, OAuth2 send/receive endpoints to EmailController
This commit is contained in:
@@ -112,4 +112,130 @@ public class EmailController(IMediator mediator) : ControllerBase
|
||||
return Ok(res);
|
||||
}
|
||||
#endregion Receive
|
||||
|
||||
#region IMAP Send
|
||||
/// <summary>
|
||||
/// Send an email using IMAP account credentials (via RabbitMQ queue).
|
||||
/// After the message is sent, it is appended to the IMAP Sent Items folder.
|
||||
/// </summary>
|
||||
/// <param name="command">Email fields as form values</param>
|
||||
/// <param name="attachments">Optional uploaded files</param>
|
||||
/// <param name="cancellationToken">Cancellation token</param>
|
||||
/// <returns>HTTP 202 Accepted with the queued event ID</returns>
|
||||
[HttpPost("imap/send")]
|
||||
[Consumes("multipart/form-data")]
|
||||
[ProducesResponseType(StatusCodes.Status202Accepted)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
public async Task<IActionResult> SendEmailViaImap(
|
||||
[FromForm] PublishEmailViaImapCommand command,
|
||||
IFormFileCollection? attachments,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var commandWithAttachments = command.WithAttachments(
|
||||
await BuildAttachmentsAsync(attachments, cancellationToken));
|
||||
|
||||
var eventId = await mediator.Send(commandWithAttachments, cancellationToken);
|
||||
return Accepted(new { Id = eventId });
|
||||
}
|
||||
#endregion IMAP Send
|
||||
|
||||
#region POP3 Receive
|
||||
/// <summary>
|
||||
/// Fetch emails from a POP3 mailbox.
|
||||
/// Triggers an on-demand POP3 sync before returning results.
|
||||
/// </summary>
|
||||
/// <param name="query">Query parameters for filtering and fetching emails from the POP3 mailbox.</param>
|
||||
/// <param name="only">Optional filter to return only specific fields.</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
/// <returns>HTTP 200 with list of received emails.</returns>
|
||||
[HttpGet("pop3")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
public async Task<IActionResult> FetchEmailsViaPop3(
|
||||
[FromQuery] ReadEmailViaPop3Query query,
|
||||
[FromQuery] OnlyFilter? only = null,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var res = await mediator.Send(query, cancellationToken);
|
||||
|
||||
if (!res.Emails.Any())
|
||||
return NotFound("No emails found matching the specified criteria.");
|
||||
|
||||
if (only == OnlyFilter.HtmlBody)
|
||||
{
|
||||
if (res.Emails.FirstOrDefault()?.HtmlBody is string htmlBody)
|
||||
return Content(htmlBody, "text/html");
|
||||
else
|
||||
return NotFound();
|
||||
}
|
||||
else if (only == OnlyFilter.Uid)
|
||||
return Ok(res.Emails.Select(e => e.Uid).ToList());
|
||||
else
|
||||
return Ok(res);
|
||||
}
|
||||
#endregion POP3 Receive
|
||||
|
||||
#region OAuth2 Send
|
||||
/// <summary>
|
||||
/// Send an email via SMTP using OAuth2 authentication (via RabbitMQ queue).
|
||||
/// The account must have <c>UseOAuth2 = true</c> and valid OAuth2 credentials configured.
|
||||
/// </summary>
|
||||
/// <param name="command">Email fields as form values</param>
|
||||
/// <param name="attachments">Optional uploaded files</param>
|
||||
/// <param name="cancellationToken">Cancellation token</param>
|
||||
/// <returns>HTTP 202 Accepted with the queued event ID</returns>
|
||||
[HttpPost("oauth2/send")]
|
||||
[Consumes("multipart/form-data")]
|
||||
[ProducesResponseType(StatusCodes.Status202Accepted)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
public async Task<IActionResult> SendEmailViaOAuth2(
|
||||
[FromForm] PublishEmailViaOAuth2Command command,
|
||||
IFormFileCollection? attachments,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var commandWithAttachments = command.WithAttachments(
|
||||
await BuildAttachmentsAsync(attachments, cancellationToken));
|
||||
|
||||
var eventId = await mediator.Send(commandWithAttachments, cancellationToken);
|
||||
return Accepted(new { Id = eventId });
|
||||
}
|
||||
#endregion OAuth2 Send
|
||||
|
||||
#region OAuth2 Receive
|
||||
/// <summary>
|
||||
/// Fetch emails from an IMAP mailbox using OAuth2 authentication.
|
||||
/// The account must have <c>UseOAuth2 = true</c> and valid OAuth2 credentials configured.
|
||||
/// </summary>
|
||||
/// <param name="query">Query parameters for filtering and fetching emails.</param>
|
||||
/// <param name="only">Optional filter to return only specific fields.</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
/// <returns>HTTP 200 with list of received emails.</returns>
|
||||
[HttpGet("oauth2/imap")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
public async Task<IActionResult> FetchEmailsViaOAuth2(
|
||||
[FromQuery] ReadEmailViaOAuth2Query query,
|
||||
[FromQuery] OnlyFilter? only = null,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var res = await mediator.Send(query, cancellationToken);
|
||||
|
||||
if (!res.Emails.Any())
|
||||
return NotFound("No emails found matching the specified criteria.");
|
||||
|
||||
if (only == OnlyFilter.HtmlBody)
|
||||
{
|
||||
if (res.Emails.FirstOrDefault()?.HtmlBody is string htmlBody)
|
||||
return Content(htmlBody, "text/html");
|
||||
else
|
||||
return NotFound();
|
||||
}
|
||||
else if (only == OnlyFilter.Uid)
|
||||
return Ok(res.Emails.Select(e => e.Uid).ToList());
|
||||
else
|
||||
return Ok(res);
|
||||
}
|
||||
#endregion OAuth2 Receive
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user