1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
--------------------------------------------------------------------------- --- This library contains operations for sending emails. --- The implementation might need to be adapted to the local --- environment. --- --- @author Michael Hanus --- @version February 2021 --------------------------------------------------------------------------- module Mail ( sendMail, MailOption(..), sendMailWithOptions ) where import Directory ( doesFileExist ) import FilePath ( (</>) ) import IOExts ( evalCmd ) import IO ( hClose, hPutStrLn, stderr ) import List ( splitOn ) import System.Path ( fileInPath ) --- Sends an email via mailx command. --- @param from - the email address of the sender --- @param to - the email address of the recipient --- @param subject - the subject of the email --- @param contents - the contents of the email sendMail :: String -> String -> String -> String -> IO () sendMail from to subject = sendMailWithOptions from subject [TO to] --- Options for sending emails. --- @cons CC - recipient of a carbon copy --- @cons BCC - recipient of a blind carbon copy --- @cons TO - recipient of the email data MailOption = CC String | BCC String | TO String deriving Eq --- Sends an email via mailx command and various options. --- Note that multiple options are allowed, e.g., more than one CC option --- for multiple recipient of carbon copies. --- --- Important note: The implementation of this operation is based on the --- command "mailx" and must be adapted according to your local environment! --- --- @param from - the email address of the sender --- @param subject - the subject of the email --- @param options - send options, e.g., multiple recipients --- @param contents - the contents of the email sendMailWithOptions :: String -> String -> [MailOption] -> String -> IO () sendMailWithOptions from subject options contents = do mailcmdexists <- fileInPath "mailx" if mailcmdexists then -- if mailx has the option -r: --execMailCmd ("mailx -n -r \"" ++ from ++ "\" -s \"" ++ subject++"\" "++ -- if mailx has the option -a: execMailCmd "mailx" (["-n", "-a", "From: " ++ from, "-s", subject] ++ ccs ++ bccs ++ tos) contents else error "Command 'mailx' not found in path!" where tos = [ s | TO s <- options ] ccs = concatMap (\m -> ["-a", "Cc: " ++ m]) [ s | CC s <- options ] bccs = concatMap (\m -> ["-a", "Bcc: " ++ m]) [ s | BCC s <- options ] --- Executes a command to send an email and pass the contents via stdin. --- Note that \r characters in the contents are removed due to problems --- with such contents in some Unix environments. execMailCmd :: String -> [String] -> String -> IO () execMailCmd cmd args contents = do (rc,out,err) <- evalCmd cmd args (filter isUnixChar contents) unless (rc == 0) $ putStrLn "ERROR during sending email!" unless (null out) $ putStrLn out unless (null err) $ hPutStrLn stderr err where isUnixChar c = c /= '\r' --------------------------------------------------------------------------- |