#if NET using AutoMapper; using DigitalData.MessagingService.Application.Common.Dto; using DigitalData.MessagingService.Application.Common.Dto.MailSearch; using DigitalData.MessagingService.Application.Common.Interfaces; using DigitalData.MessagingService.Application.Common.Interfaces.Repositories; using DigitalData.MessagingService.Application.EmailAccounts.Queries; using DigitalData.MessagingService.Domain.Entities; using DigitalData.MessagingService.Domain.Exceptions; using MediatR; using Microsoft.Extensions.Logging; namespace DigitalData.MessagingService.Application.EmailReceiving.Queries; /// /// Query to fetch emails from an IMAP mailbox. /// public record ReadEmailViaImapQuery : IRequest { /// /// Identifies the email account to use. /// public required GetEmailAccountQuery Account { get; init; } /// /// Mail query used to filter and limit the emails retrieved. /// public MailSearchFilter Mail { get; init; } = new(); } public class ReadEmailViaImapQueryHandler(IMapper Mapper, ILogger Logger, IRepository EmailAccountRepo, IReceivedEmailRepository MailRepo, IImapEmailService imapEmailService) : IRequestHandler { public async Task Handle(ReadEmailViaImapQuery request, CancellationToken cancellationToken) { var accounts = await EmailAccountRepo.FindAsync(request.Account.Id is int id ? x => x.Id == id : x => x.Username == request.Account.Username, cancellationToken: cancellationToken); if (accounts.Count() > 1) Logger.LogWarning("Multiple email accounts found for the given criteria ({Criteria}). Returning the first one.", request.Account.Id is not null ? $"Id: {request.Account.Id}" : $"Username: {request.Account.Username}"); var account = accounts.FirstOrDefault() ?? 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 BadRequestException( $"IMAP is not configured for account '{account.Username}' (Id: {account.Id}). Set ImapServer in EmailAccounts configuration."); var mails = await MailRepo.FindAsync(request.Mail, account, cancellationToken); var lastSync = imapEmailService.GetLastImapSyncDate(account.Id, request.Mail.Folder); return new ReadEmailQueryResponse { LastSync = lastSync, Emails = Mapper.Map>(mails) }; } } #endif