{-# LANGUAGE DerivingVia #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TypeFamilies #-} module Network.Mail.Newsletter.Mailgun where import Control.Lens import Control.Monad.Catch import Control.Monad.Reader import Data.Machine import Data.Machine as M import Data.Text (Text) import Network.Mail.Mime import qualified Network.Mail.Mailgun as MG import Network.Mail.Newsletter.Class data MailgunNewsletterContext = MGNL { _mgnlMailgunContext :: MG.MailgunConfig , _mgnlName :: Address } makeLenses ''MailgunNewsletterContext instance MG.HasMailgunConfig MailgunNewsletterContext where mailgunConfig = mgnlMailgunContext newtype MailgunNewsT m a = MailgunNewsT { runMailgunNewsT :: MailgunNewsletterContext -> m a } deriving (Functor, Applicative, Monad, MonadIO, MonadThrow, MonadCatch ,MonadReader MailgunNewsletterContext) via (ReaderT MailgunNewsletterContext m) deriving (MonadTrans) via (ReaderT MailgunNewsletterContext) instance (MonadIO m, MonadThrow m) => Newsletter (MailgunNewsT m) where subscribe = M.mapping (\(addr, d) -> MG.ListMember (maybe "" id . addressName $ addr) (addressEmail addr) True d) ~> preplan ((fmap (const ())) <$> ((MG.addMembers False . addressEmail) <$> view mgnlName)) unsubscribe = M.mapping addressEmail ~> preplan (autoM <$> ((MG.removeMember . addressEmail) <$> view mgnlName)) subscribers = preplan ((MG.listMembers (Just True) . addressEmail) <$> view mgnlName) ~> M.mapping (\(MG.ListMember mn addr _ d) -> (Address (if mn=="" then Just mn else Nothing) addr, d)) sendEmail mkMail = do ml <- view mgnlName void $ MG.send Nothing [ml] (mkMail ml) sendSubscribe newUser mkMail = join $ void . MG.send Nothing [newUser] <$> (mkMail <$> view mgnlName)