예제 #1
0
        public async IAsyncEnumerable <IMailMessage> GetMessagesAsync(EmailConfig.IncomingConfig cfg, MailQuery?query = null,
                                                                      [EnumeratorCancellation] CancellationToken cancellationToken = default)
        {
            if (!new[] { MailProtocol.Imap, MailProtocol.Pop3 }.Contains(cfg.Protocol))
            {
                throw new InvalidOperationException($"Invalid email protocol: {cfg.Protocol}");
            }
            var container = await Policy
                            .Handle <SocketException>().Or <System.IO.IOException>().Or <SslHandshakeException>()
                            .WaitAndRetryAsync(_retryConfig.Max, _ => _retryConfig.Delay,
                                               (exc, delay, attempt, _) => _log.LogError(exc, Message.ConnError, attempt, cfg, delay))
                            .ExecuteAsync(token => InitContainerAsync(_client, cfg, token), cancellationToken);

            if (container == null)
            {
                throw new InvalidOperationException("Message container must be initialized properly");
            }

            var ids = await GetMessageIdsAsync(container, query?.Limit, cancellationToken);

            foreach (var id in ids)
            {
                var message = await TryOrNull(token => GetMessageAsync(container, id, token), cancellationToken,
                                              Message.ReceiveError, _retryConfig.Max, id, cfg.Username);

                if (message == null || (!query?.AutoDelete ?? false))
                {
                    continue;
                }

                _ = await TryOrNull(token => DeleteMessageAsync(container, id, token), cancellationToken,
                                    Message.DeleteError, _retryConfig.Max, id, cfg.Username);

                yield return(message.ToPort());
            }

            await _client.DisconnectAsync(true, cancellationToken);
        }
        protected override async Task <IMailFolder?> InitContainerAsync(IImapClient client, EmailConfig.IncomingConfig config, CancellationToken cancellationToken)
        {
            _ = await base.InitContainerAsync(client, config, cancellationToken);

            var mailbox = await client.GetFolderAsync(config.MailBox, cancellationToken);

            if (mailbox == null)
            {
                throw new InvalidOperationException(
                          $"Email account {config.Username} doesn't have mailbox '{config.MailBox}'");
            }
            _ = await mailbox.OpenAsync(FolderAccess.ReadWrite, cancellationToken);

            return(mailbox);
        }