Mapping sender, to, cc and replyTo
This commit is contained in:
parent
64966ea827
commit
318903db40
|
@ -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
|
||||||
|
|
|
@ -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)"
|
||||||
}
|
}
|
|
@ -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>"
|
||||||
|
}
|
Loading…
Reference in New Issue