Last active
November 3, 2015 19:48
-
-
Save taylorSando/979ab571923286b96662 to your computer and use it in GitHub Desktop.
Email polling
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns workzone.services.email-poll | |
(:require [clojure.tools.logging :as log] | |
[clojure.core.async :as core.async] | |
[clojure.set] | |
[workzone.model.error :as model.error] | |
[plumbing.core :refer :all] | |
[puppetlabs.trapperkeeper.core :refer [defservice]]) | |
(:import javax.mail.Flags | |
javax.mail.Message | |
javax.mail.internet.InternetAddress | |
javax.mail.Session)) | |
(defn extract-email-address [e] | |
(when e | |
(re-find #"(?i)[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?" | |
e))) | |
(defn -extract-email [msg] | |
{:subject (.getSubject msg) | |
:from (extract-email-address (javax.mail.internet.InternetAddress/toString (.getFrom msg))) | |
:to (-> msg | |
(.getRecipients javax.mail.Message$RecipientType/TO) | |
javax.mail.internet.InternetAddress/toString | |
extract-email-address) | |
:cc (-> msg | |
(.getRecipients javax.mail.Message$RecipientType/CC) | |
javax.mail.internet.InternetAddress/toString | |
extract-email-address)}) | |
(defn extract-lead-email [msg] | |
(let [e (-extract-email msg)] | |
(clojure.set/rename-keys e {:from :lead-publisher | |
:to :lead-subscriber | |
:cc :customer-email}))) | |
(defn extract-referral-email [msg] | |
(let [e (-extract-email msg)] | |
{:from-user (:from e) | |
:invited-users [(:to e) (:cc e)]})) | |
;; This should probably get split up into two functions, an extraction | |
;; function that gets the emails and returns them, and the actual | |
;; function to do the doseq email actions. Not sure if deleting | |
;; the emails has a side effect on the emails taken though. | |
(defn extract-emails [services store email-extractor email-action-fn] | |
(let [folder (. store getFolder "inbox") | |
_ (.open folder (javax.mail.Folder/READ_WRITE)) | |
messages (.getMessages folder) ] | |
(when (count messages) | |
(doseq [m messages] | |
(email-action-fn services (email-extractor m))) | |
(.setFlags | |
folder messages (javax.mail.Flags. javax.mail.Flags$Flag/DELETED) true)) | |
(.close folder true))) | |
(defnk email-poller | |
[services | |
poll-active? | |
email-store | |
email-extractor | |
email-action-fn | |
[:config host username password]] | |
(clojure.core.async/go-loop [] | |
(clojure.core.async/<! (clojure.core.async/timeout 30000)) | |
(when @poll-active? | |
(reset! email-store | |
(.getStore | |
(javax.mail.Session/getDefaultInstance (System/getProperties)) | |
"pop3s")) | |
(.connect @email-store host username password) | |
(clojure.core.async/go-loop [] | |
(clojure.core.async/<! (clojure.core.async/timeout 5000)) | |
(when (and (.isConnected @email-store) @poll-active?) | |
(try | |
(extract-emails | |
services | |
@email-store | |
email-extractor | |
email-action-fn) | |
;; Going to keep running this no matter what | |
(catch Exception e | |
(log/error (model.error/extract-exception e)))) | |
(recur))) | |
(recur)))) | |
(defprotocol EmailPollService | |
(check [this])) | |
(defservice service | |
EmailPollService | |
[[:DatomicService conn db] | |
[:LeadModel publish-email-lead] | |
[:UserReferralModel create-referral ] | |
[:EnvironmentConfigService get-in-config]] | |
(init [this context] | |
(log/trace "Initializing Email Polilng Service") | |
(let [poll-active? (atom true) | |
lead-email-store (atom nil) | |
referral-email-store (atom nil) | |
services {:dbs {:main {:db (db) :conn (conn)}}} | |
lead-poll-config | |
,{:host (get-in-config [:lead-email-server :host]) | |
:username (get-in-config [:lead-email-server :username]) | |
:password (get-in-config [:lead-email-server :password])} | |
referral-poll-config | |
,{:host (get-in-config [:referral-email-server :host]) | |
:username (get-in-config [:referral-email-server :username]) | |
:password (get-in-config [:referral-email-server :password])}] | |
(email-poller {:services services | |
:poll-active? poll-active? | |
:email-store lead-email-store | |
:email-extractor extract-lead-email | |
:email-action-fn publish-email-lead | |
:config lead-poll-config}) | |
(email-poller {:services services | |
:poll-active? poll-active? | |
:email-store referral-email-store | |
:email-extractor extract-referral-email | |
:email-action-fn create-referral | |
:config referral-poll-config}) | |
(assoc context | |
:lead-email-store lead-email-store | |
:referral-email-store referral-email-store | |
:poll-active? poll-active?))) | |
(check [this]) | |
(stop [this context] | |
(log/trace "Shutting Down Email Polling Service") | |
(when (.isConnected @(:lead-email-store context)) | |
(.close @(:lead-email-store context))) | |
(when (.isConnected @(:referral-email-store context)) | |
(.close @(:referral-email-store context))) | |
(reset! (:poll-active? context) false) | |
(dissoc context :lead-email-store :referral-email-store :poll-active?))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment