Mapping sender, to, cc and replyTo

This commit is contained in:
dankito 2024-11-27 04:15:23 +01:00
parent 64966ea827
commit 318903db40
3 changed files with 40 additions and 8 deletions

View File

@ -3,10 +3,13 @@ package net.codinux.invoicing.email
import jakarta.mail.* import jakarta.mail.*
import jakarta.mail.event.MessageCountAdapter import jakarta.mail.event.MessageCountAdapter
import jakarta.mail.event.MessageCountEvent import jakarta.mail.event.MessageCountEvent
import jakarta.mail.internet.InternetAddress
import jakarta.mail.internet.MimeUtility
import kotlinx.coroutines.* import kotlinx.coroutines.*
import net.codinux.invoicing.email.model.EmailAccount
import net.codinux.invoicing.email.model.EmailAttachment
import net.codinux.invoicing.email.model.Email import net.codinux.invoicing.email.model.Email
import net.codinux.invoicing.email.model.EmailAccount
import net.codinux.invoicing.email.model.EmailAddress
import net.codinux.invoicing.email.model.EmailAttachment
import net.codinux.invoicing.filesystem.FileUtil import net.codinux.invoicing.filesystem.FileUtil
import net.codinux.invoicing.model.Invoice import net.codinux.invoicing.model.Invoice
import net.codinux.invoicing.reader.EInvoiceReader import net.codinux.invoicing.reader.EInvoiceReader
@ -151,9 +154,13 @@ open class EmailsFetcher(
getAttachment(part, status) getAttachment(part, status)
} }
val sender = message.from?.firstOrNull()?.let { map(it) }
val email = Email( val email = Email(
message.from?.joinToString(), message.subject ?: "", sender, message.subject ?: "",
message.sentDate?.let { map(it) }, map(message.receivedDate), status.folder.getUID(message), message.getRecipients(Message.RecipientType.TO).map { map(it) }, message.getRecipients(Message.RecipientType.CC).map { map(it) },
(message.replyTo.firstOrNull() as? InternetAddress)?.let { if (it.address != sender?.address) map(it) else null }, // only set replyTo if it differs from sender
map(message.sentDate ?: message.receivedDate), status.folder.getUID(message),
parts.any { it.mediaType == "application/pgp-encrypted" }, parts.any { it.mediaType == "application/pgp-encrypted" },
getPlainTextBody(messageBodyParts, status), getHtmlBody(messageBodyParts, status), getPlainTextBody(messageBodyParts, status), getHtmlBody(messageBodyParts, status),
attachments attachments
@ -164,6 +171,13 @@ open class EmailsFetcher(
return email return email
} }
protected open fun map(address: Address): EmailAddress =
if (address is InternetAddress) { // use MimeUtility to parse e.g. Quoted-printable names that e.g. start with "=?UTF-8?Q?"
EmailAddress(address.address, address.personal?.let { MimeUtility.decodeText(it) })
} else {
EmailAddress(address.toString())
}
protected open fun getAttachment(messagePart: MessagePart, status: FetchEmailsStatus): EmailAttachment? { protected open fun getAttachment(messagePart: MessagePart, status: FetchEmailsStatus): EmailAttachment? {
try { try {
val part = messagePart.part val part = messagePart.part

View File

@ -4,10 +4,12 @@ import java.time.Instant
import java.time.ZoneId import java.time.ZoneId
class Email( class Email(
val sender: String?, val sender: EmailAddress?,
val subject: String, val subject: String,
val sent: Instant?, val to: List<EmailAddress>,
val received: Instant, val cc: List<EmailAddress>,
val replayTo: EmailAddress?,
val date: Instant,
val messageId: Long, val messageId: Long,
val isEncrypted: Boolean = false, val isEncrypted: Boolean = false,
val plainTextBody: String?, val plainTextBody: String?,
@ -16,5 +18,5 @@ class Email(
) { ) {
val plainTextOrHtmlBody: String? by lazy { plainTextBody ?: htmlBody } val plainTextOrHtmlBody: String? by lazy { plainTextBody ?: htmlBody }
override fun toString() = "${(sent ?: received).atZone(ZoneId.systemDefault()).toLocalDate()} $sender: $subject, ${attachments.size} attachment(s)" override fun toString() = "${date.atZone(ZoneId.systemDefault()).toLocalDate()} $sender: $subject, ${attachments.size} attachment(s)"
} }

View File

@ -0,0 +1,16 @@
package net.codinux.invoicing.email.model
class EmailAddress(
/**
* The email address, like "a@b.com"
*/
val address: String,
/**
* Sender or recipient's name like "Mahatma Gandhi"
*/
val name: String? = null
) {
override fun toString() =
if (name == null) address
else "$name <$address>"
}