From c9019b63f39ea4d4da96ea91e7a3403f98669e01 Mon Sep 17 00:00:00 2001 From: Stephan Richter Date: Wed, 13 Apr 2022 15:55:41 +0200 Subject: [PATCH] working on IMAP listener --- .../de/srsoftware/widerhall/Application.java | 24 ++++ .../de/srsoftware/widerhall/Constants.java | 9 ++ .../de/srsoftware/widerhall/Forwarder.java | 15 ++ .../de/srsoftware/widerhall/ImapClient.java | 129 ++++++++++++++++++ .../srsoftware/widerhall/MessageHandler.java | 8 ++ .../de/srsoftware/widerhall/SmtpClient.java | 9 -- 6 files changed, 185 insertions(+), 9 deletions(-) create mode 100644 src/main/java/de/srsoftware/widerhall/Application.java create mode 100644 src/main/java/de/srsoftware/widerhall/Constants.java create mode 100644 src/main/java/de/srsoftware/widerhall/Forwarder.java create mode 100644 src/main/java/de/srsoftware/widerhall/ImapClient.java create mode 100644 src/main/java/de/srsoftware/widerhall/MessageHandler.java diff --git a/src/main/java/de/srsoftware/widerhall/Application.java b/src/main/java/de/srsoftware/widerhall/Application.java new file mode 100644 index 0000000..27d44a6 --- /dev/null +++ b/src/main/java/de/srsoftware/widerhall/Application.java @@ -0,0 +1,24 @@ +package de.srsoftware.widerhall; + +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; + +public class Application { + + public static void main(String[] args) throws IOException, ParseException { + var parser = new JSONParser(); + var config = Files.readString(new File("/tmp/config.json").toPath()); + JSONObject json = (JSONObject) parser.parse(config); + + //String testSender = (String) json.get("sender"); + //String testReceiver = (String) json.get("receiver"); + // new SmtpClient(json).send(json,testSender,"Stephan Richter",testReceiver,"Test","Dies ist ein Test"); + MessageHandler forward = new Forwarder(); + new ImapClient(json).addListener(forward).start(); + } +} diff --git a/src/main/java/de/srsoftware/widerhall/Constants.java b/src/main/java/de/srsoftware/widerhall/Constants.java new file mode 100644 index 0000000..ffe7c8c --- /dev/null +++ b/src/main/java/de/srsoftware/widerhall/Constants.java @@ -0,0 +1,9 @@ +package de.srsoftware.widerhall; + +public class Constants { + public static final String IMAPS = "imaps"; + public static final String PROTOCOL = "mail.store.protocol"; + public static final String HOST = "host"; + public static final String USER = "user"; + public static final String PASSWORD = "password"; +} diff --git a/src/main/java/de/srsoftware/widerhall/Forwarder.java b/src/main/java/de/srsoftware/widerhall/Forwarder.java new file mode 100644 index 0000000..5d59c6d --- /dev/null +++ b/src/main/java/de/srsoftware/widerhall/Forwarder.java @@ -0,0 +1,15 @@ +package de.srsoftware.widerhall; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.mail.Message; +import javax.mail.MessagingException; + +public class Forwarder implements MessageHandler { + private static final Logger LOG = LoggerFactory.getLogger(Forwarder.class); + @Override + public void onMessageReceived(Message message) throws MessagingException { + LOG.debug("forwarding {}",message.getSubject()); + } +} diff --git a/src/main/java/de/srsoftware/widerhall/ImapClient.java b/src/main/java/de/srsoftware/widerhall/ImapClient.java new file mode 100644 index 0000000..569071c --- /dev/null +++ b/src/main/java/de/srsoftware/widerhall/ImapClient.java @@ -0,0 +1,129 @@ +package de.srsoftware.widerhall; + +import com.sun.mail.iap.ProtocolException; +import com.sun.mail.imap.IMAPFolder; +import com.sun.mail.imap.protocol.IMAPProtocol; +import org.json.simple.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.mail.*; +import java.util.HashSet; +import java.util.Properties; + +public class ImapClient { + + private static final Logger LOG = LoggerFactory.getLogger(ImapClient.class); + private final JSONObject config; + private boolean stopped = false; + private IMAPFolder inbox; + private HashSet listeners = new HashSet<>(); + + + + private class ListeningThread extends Thread { + + private static final Logger LOG = LoggerFactory.getLogger(ListeningThread.class); + private final JSONObject config; + + ListeningThread(JSONObject config){ + this.config = config; + } + + @Override + public void run() { + while (!stopped) { + try { + openInbox(); + } catch (MessagingException e){ + LOG.warn("Connection problem:",e); + try { + sleep(1000); + } catch (InterruptedException interruptedException) { + interruptedException.printStackTrace(); + } + } + } + } + + private void openInbox() throws MessagingException { + String host = (String) config.get(Constants.HOST); + String username = (String) config.get(Constants.USER); + String password = (String) config.get(Constants.PASSWORD); + LOG.debug("Connecting and logging in…"); + Properties props = imapProps(); + Session session = Session.getInstance(props); + Store store = session.getStore(Constants.IMAPS); + store.connect(host,username,password); + LOG.debug("Connected, opening inbox:"); + inbox = (IMAPFolder)store.getFolder("INBOX"); + inbox.open(IMAPFolder.READ_WRITE); + + while (!stopped){ + handleMessages(); + LOG.debug("Idling."); + inbox.idle(true); + } + } + + private void handleMessages() throws MessagingException { + LOG.debug("reading email:"); + if (!inbox.isOpen()){ + inbox.open(IMAPFolder.READ_WRITE); + } + for (Message message : inbox.getMessages()){ + if (message.isSet(Flags.Flag.SEEN)) continue; + handle(message); + message.setFlag(Flags.Flag.SEEN,true); + } + } + + private void handle(Message message) throws MessagingException { + LOG.debug("Handling {}",message.getSubject()); + for (MessageHandler listener : listeners) listener.onMessageReceived(message); + } + + private Properties imapProps() { + Properties props = new Properties(); + props.put(Constants.PROTOCOL,Constants.IMAPS); + return props; + } + } + + private class Heartbeat extends Thread{ + + private static final Logger LOG = LoggerFactory.getLogger(Heartbeat.class); + @Override + public void run() { + while (!stopped){ + try { + sleep(300034); + if (inbox != null) continue; + LOG.debug("sending NOOP"); + inbox.doCommand(protocol -> { + protocol.simpleCommand("NOOP",null); + return null; + }); + } catch (InterruptedException | MessagingException e) { + e.printStackTrace(); + } + } + } + } + ImapClient(JSONObject config){ + this.config = config; + } + + public void start() { + LOG.debug("Creating ListeningThread…"); + new ListeningThread(config).start(); + LOG.debug("Creating Heartbeat…"); + new Heartbeat().start(); + } + + + public ImapClient addListener(MessageHandler messageHandler) { + listeners.add(messageHandler); + return this; + } +} diff --git a/src/main/java/de/srsoftware/widerhall/MessageHandler.java b/src/main/java/de/srsoftware/widerhall/MessageHandler.java new file mode 100644 index 0000000..7aa7663 --- /dev/null +++ b/src/main/java/de/srsoftware/widerhall/MessageHandler.java @@ -0,0 +1,8 @@ +package de.srsoftware.widerhall; + +import javax.mail.Message; +import javax.mail.MessagingException; + +public interface MessageHandler { + public void onMessageReceived(Message message) throws MessagingException; +} diff --git a/src/main/java/de/srsoftware/widerhall/SmtpClient.java b/src/main/java/de/srsoftware/widerhall/SmtpClient.java index 752f6e6..3fcaf50 100644 --- a/src/main/java/de/srsoftware/widerhall/SmtpClient.java +++ b/src/main/java/de/srsoftware/widerhall/SmtpClient.java @@ -62,13 +62,4 @@ public class SmtpClient { LOG.debug("…versendet"); } - public static void main(String[] args) throws IOException, ParseException, MessagingException { - var parser = new JSONParser(); - var config = Files.readString(new File("/tmp/config.json").toPath()); - JSONObject json = (JSONObject) parser.parse(config); - - String testSender = (String) json.get("sender"); - String testReceiver = (String) json.get("receiver"); - new SmtpClient(json).send(json,testSender,"Stephan Richter",testReceiver,"Test","Dies ist ein Test"); - } }