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);
|
return Ok(res);
|
||||||
}
|
}
|
||||||
#endregion Receive
|
#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