----------------------------------------------------------------------------- -- | -- Module : Happstack.Util.Mail -- Copyright : Happstack.com 2009 -- License : BSD3 -- -- Maintainer : Matthew Elder -- Stability : provisional -- Portability : linux/windows -- -- Mail is a simple library with which you can add email functionality to your -- application. It assumes you have access to a smarthost which can relay all -- your mail. -- -- As an example: -- -- > import Happstack.Util.Mail -- > main :: IO () -- > main = do -- > sendSimpleMessages "10.2.23.11" "example.com" [message] -- > where message = SimpleMessage -- > [NameAddr (Just "John Doe") "johnd@example.com"] -- > [NameAddr (Just "Patch-Tag Team") "team@patch-tag.com"] -- > "My test email using Happstack.Util.Mail" -- > "Hi, this is a test email which uses Happstack." module Happstack.Util.Mail ( NameAddr(..) , SimpleMessage(..) , sendRawMessages , sendSimpleMessages ) where import Data.IORef (newIORef, readIORef) import Network.Socket (SockAddr(..) , inet_addr ) import Network.SMTP.Client import System.Log.Logger (Priority(..), logM) import System.Time ( CalendarTime(..) , getClockTime , toCalendarTime ) data SimpleMessage = SimpleMessage { from :: [NameAddr] -- ^ The sender(s) , to :: [NameAddr] -- ^ The recipient(s) , subject :: String -- ^ The subject line , body :: String -- ^ The body } deriving (Show) toMessage :: CalendarTime -> SimpleMessage -> Message toMessage ct sm = Message [From (from sm), To (to sm), Subject (subject sm), Date ct] (body sm) log' :: Priority -> String -> IO () log' = logM "Happstack.Util.Mail" -- | Simplest way to send mail. Takes the smarthost ip, the HELO domain, and a list of SimpleMessage. sendSimpleMessages :: String -- ^ IP address of the smarthost -> String -- ^ HELO domain (should be the same as your from-address-domain) -> [SimpleMessage] -- ^ List of simple messages to send -> IO () sendSimpleMessages smartHostIp heloDomain simpleMessages = do nowCT <- toCalendarTime =<< getClockTime hostAddr <- inet_addr smartHostIp let smtpSockAddr = SockAddrInet 25 hostAddr sendRawMessages smtpSockAddr heloDomain (map (toMessage nowCT) simpleMessages) -- | Use this if you need more control than sendSimpleMessages gives you. sendRawMessages :: SockAddr -- ^ SockAddr for the smarthost -> String -- ^ HELO domain (should be the same as your from-address-domain) -> [Message] -- ^ List of messages to send -> IO () sendRawMessages smtpSockAddr heloDomain messages = do log' NOTICE $ "connecting to SMTP smarthost: " ++ show smtpSockAddr sentRef <- newIORef [] sendSMTP' (log' INFO) (Just sentRef) heloDomain smtpSockAddr messages statuses <- readIORef sentRef -- If no exception was caught, statuses is guaranteed to be -- the same length as the list of input messages, therefore head won't fail here. log' NOTICE $ "attempting to send messages:\n" ++ show messages case head statuses of Nothing -> return () Just status -> log' ERROR $ "message failed: " ++ show status