using DigitalData.MessagingService.Application.Common.Dto.MailSearch; using DigitalData.MessagingService.Application.Common.Interfaces; using DigitalData.MessagingService.Application.Common.Interfaces.Repositories; using DigitalData.MessagingService.Application.Common.Options; using DigitalData.MessagingService.Domain.Entities; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Options; namespace DigitalData.MessagingService.Infrastructure.Services.Background; public class EmailSyncWorker(IImapEmailService imapService, IOptions Options, IServiceProvider Provider) : BackgroundService { private DateFilter? _dateFilter = null; protected override async Task ExecuteAsync(CancellationToken stoppingToken) { await UpsertSeedEmailAccount(stoppingToken); if (imapService is not LimilabsImapEmailService limapService) { await Task.Delay(Timeout.Infinite, stoppingToken).ConfigureAwait(ConfigureAwaitOptions.SuppressThrowing); return; } var interval = TimeSpan.FromSeconds(Options.Value.SyncIntervalSeconds); while (!stoppingToken.IsCancellationRequested) { using var scope = Provider.CreateAsyncScope(); var emailAccountRepo = scope.ServiceProvider.GetRequiredService>(); foreach (var account in await emailAccountRepo.GetAllAsync(stoppingToken)) if (account.ImapServer is not null) { // init or update last date filter _dateFilter = _dateFilter is null ? new DateFilter { After = null, Before = DateTime.UtcNow } : new DateFilter { After = _dateFilter.Before, Before = DateTime.UtcNow }; await limapService.FetchEmailsAsync(account, new MailSearchFilter { Date = _dateFilter }, stoppingToken); } await Task.Delay(interval, stoppingToken).ConfigureAwait(ConfigureAwaitOptions.SuppressThrowing); } } public async Task UpsertSeedEmailAccount(CancellationToken stoppingToken) { using var scope = Provider.CreateAsyncScope(); var emailAccountRepo = scope.ServiceProvider.GetRequiredService>(); // init seed email accounts if not exist foreach (var account in Options.Value.Accounts) await emailAccountRepo.UpsertAsync(a => a.Username == account.Username, account, stoppingToken); } }