All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.bingoohuang.utils.mail.MailFetcher Maven / Gradle / Ivy

package com.github.bingoohuang.utils.mail;

import com.google.common.collect.Lists;
import lombok.Cleanup;
import lombok.SneakyThrows;
import lombok.val;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.jsoup.Jsoup;

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;
import java.util.List;
import java.util.Properties;

/**
 * POP3 邮箱收取。
 * 

* https://user-images.githubusercontent.com/1940588/47476178-c098f380-d851-11e8-8338-11c32d6fa6f2.png */ public class MailFetcher { private final Properties properties; private final String username; private final String password; private final MailMatcher matcher; public MailFetcher(Properties properties, MailMatcher matcher) { this.properties = properties; this.username = properties.getProperty("mail.pop3.username"); this.password = properties.getProperty("mail.pop3.password"); this.matcher = matcher; val portKey = "mail.pop3.port"; if (!this.properties.containsKey(portKey)) this.properties.put(portKey, "110"); } public MailFetcher(MailMatcher matcher) { this(createProp(), matcher); } private static Properties createProp() { val prop = new Properties(); val env = MailConfig.getEnv(); env.stringPropertyNames().forEach(k -> { if (k.startsWith("mail.pop3.")) prop.put(k, env.getProperty(k)); }); return prop; } @SneakyThrows public List fetchMails() { val session = Session.getDefaultInstance(properties); @Cleanup val store = session.getStore("pop3"); store.connect(username, password); @Cleanup val inbox = store.getFolder("INBOX"); inbox.open(Folder.READ_ONLY); return fetchInboxMessages(inbox); } @SneakyThrows private List fetchInboxMessages(Folder inbox) { int end = matcher.messageEnd(); if (end < 0) end = inbox.getMessageCount(); val inboxMessages = inbox.getMessages(matcher.messageStart(), end); List messages = Lists.newArrayList(); for (val message : inboxMessages) { val subject = message.getSubject(); if (!matcher.matchSubject(subject)) continue; val from = ((InternetAddress) message.getFrom()[0]).getAddress(); if (!matcher.matchFrom(from)) continue; val sentDate = new DateTime(message.getSentDate()); if (!matcher.matchSentDate(sentDate)) continue; val content = getTextFromMessage(message); if (!matcher.matchBodyContent(content)) continue; val attachments = parseAttachments(message); messages.add(Pop3MailMessage.builder() .messageNumber(message.getMessageNumber()) .subject(subject) .from(from) .sentDate(sentDate) .content(content) .attachments(attachments) .build()); } return messages; } @SneakyThrows private List parseAttachments(Message message) { List attachments = Lists.newArrayList(); if (message.getContent() instanceof Multipart) { val multi = (Multipart) message.getContent(); for (int j = 0; j < multi.getCount(); j++) { val bodyPart = multi.getBodyPart(j); val partFileName = bodyPart.getFileName(); if (!Part.ATTACHMENT.equalsIgnoreCase(bodyPart.getDisposition()) || StringUtils.isBlank(partFileName)) { continue; // dealing with attachments only } val fileName = MimeUtility.decodeText(partFileName); if (!matcher.matchAttachmentFileName(fileName)) continue; attachments.add(Pop3MailMessageAttachment.builder() .fileName(fileName) .inputStream(bodyPart.getInputStream()) .build()); } } return attachments; } @SneakyThrows private String getTextFromMessage(Message message) { if (message.isMimeType("text/plain")) { return message.getContent().toString(); } else if (message.isMimeType("multipart/*")) { return getTextFromMimeMultipart((MimeMultipart) message.getContent()); } return ""; } @SneakyThrows private String getTextFromMimeMultipart(MimeMultipart mimeMultipart) { val result = new StringBuilder(); val count = mimeMultipart.getCount(); for (int i = 0; i < count; i++) { val p = mimeMultipart.getBodyPart(i); if (p.isMimeType("text/plain")) { result.append("\n").append(p.getContent()); break; // without break same text appears twice in my tests } else if (p.isMimeType("text/html")) { val html = (String) p.getContent(); result.append("\n").append(Jsoup.parse(html).text()); } else if (p.getContent() instanceof MimeMultipart) { result.append(getTextFromMimeMultipart((MimeMultipart) p.getContent())); } } return result.toString(); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy