diff --git a/e-invoice-domain/src/main/kotlin/net/codinux/invoicing/email/EmailsFetcher.kt b/e-invoice-domain/src/main/kotlin/net/codinux/invoicing/email/EmailsFetcher.kt index 600d3b2..e7a73a2 100644 --- a/e-invoice-domain/src/main/kotlin/net/codinux/invoicing/email/EmailsFetcher.kt +++ b/e-invoice-domain/src/main/kotlin/net/codinux/invoicing/email/EmailsFetcher.kt @@ -6,6 +6,7 @@ import jakarta.mail.Multipart import jakarta.mail.Part import jakarta.mail.Session import jakarta.mail.Store +import jakarta.mail.UIDFolder import jakarta.mail.event.MessageCountAdapter import jakarta.mail.event.MessageCountEvent import kotlinx.coroutines.* @@ -116,19 +117,23 @@ open class EmailsFetcher( return@runBlocking emptyList() } - IntRange(1, messageCount).mapNotNull { messageNumber -> // message numbers start at 1 - async(coroutineDispatcher) { - try { - getEmail(folder.getMessage(messageNumber), status) - } catch (e: Throwable) { - log.error(e) { "Could not get email with messageNumber $messageNumber" } - status.addError(FetchEmailsErrorType.GetEmail, messageNumber, e) - null + async(coroutineDispatcher) { + val startUid = max(status.options.lastRetrievedMessageId?.let { it + 1 } ?: 0, 1) // message numbers start at 1 + + folder.getMessagesByUID(startUid, UIDFolder.MAXUID).mapNotNull { message -> + async(coroutineDispatcher) { + try { + getEmail(message, status) + } catch (e: Throwable) { + log.error(e) { "Could not get email $message" } + status.addError(FetchEmailsErrorType.GetEmail, message, e) + null + } } } - } - .awaitAll() - .filterNotNull() + .awaitAll() + .filterNotNull() + }.await() } protected open fun getEmail(message: Message, status: FetchEmailsStatus): Email? { diff --git a/e-invoice-domain/src/main/kotlin/net/codinux/invoicing/email/FetchEmailsOptions.kt b/e-invoice-domain/src/main/kotlin/net/codinux/invoicing/email/FetchEmailsOptions.kt index d066091..ceee833 100644 --- a/e-invoice-domain/src/main/kotlin/net/codinux/invoicing/email/FetchEmailsOptions.kt +++ b/e-invoice-domain/src/main/kotlin/net/codinux/invoicing/email/FetchEmailsOptions.kt @@ -4,6 +4,11 @@ import net.codinux.invoicing.email.model.Email import java.io.File open class FetchEmailsOptions( + /** + * The ID of the last retrieved message. If set, only messages newer than this ID will be fetched. + */ + val lastRetrievedMessageId: Long? = null, + val downloadMessageBody: Boolean = false, /** * Set the extension (without the dot) of files that should be downloaded. diff --git a/e-invoice-domain/src/main/kotlin/net/codinux/invoicing/email/ListenForNewMailsOptions.kt b/e-invoice-domain/src/main/kotlin/net/codinux/invoicing/email/ListenForNewMailsOptions.kt index c49421a..93b63db 100644 --- a/e-invoice-domain/src/main/kotlin/net/codinux/invoicing/email/ListenForNewMailsOptions.kt +++ b/e-invoice-domain/src/main/kotlin/net/codinux/invoicing/email/ListenForNewMailsOptions.kt @@ -16,4 +16,4 @@ open class ListenForNewMailsOptions( onError: ((FetchEmailsError) -> Unit)? = null, onEmailReceived: (Email) -> Unit -) : FetchEmailsOptions(downloadMessageBody, downloadAttachmentsWithExtensions, attachmentsDownloadDirectory, emailFolderName, connectTimeoutSeconds, onError, onEmailReceived) \ No newline at end of file +) : FetchEmailsOptions(null, downloadMessageBody, downloadAttachmentsWithExtensions, attachmentsDownloadDirectory, emailFolderName, connectTimeoutSeconds, onError, onEmailReceived) \ No newline at end of file diff --git a/e-invoice-domain/src/test/kotlin/net/codinux/invoicing/email/EmailsFetcherTest.kt b/e-invoice-domain/src/test/kotlin/net/codinux/invoicing/email/EmailsFetcherTest.kt index c2df90d..a1d19ed 100644 --- a/e-invoice-domain/src/test/kotlin/net/codinux/invoicing/email/EmailsFetcherTest.kt +++ b/e-invoice-domain/src/test/kotlin/net/codinux/invoicing/email/EmailsFetcherTest.kt @@ -27,7 +27,7 @@ class EmailsFetcherTest { @Test fun fetchAllEmails() { - val result = underTest.fetchAllEmails(emailAccount, FetchEmailsOptions(true)) + val result = underTest.fetchAllEmails(emailAccount, FetchEmailsOptions(downloadMessageBody = true)) assertThat(result.overallError).isNull() assertThat(result.emails).isNotEmpty()