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 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
--------------------------------------------------------------------------- --- This library contains operations for sending emails. --- The implementation might need to be adapted to the local --- environment. --- --- @author Michael Hanus --- @version June 2023 --------------------------------------------------------------------------- module System.Mail ( MailOption(..), sendMail, sendMailWithOptions , showSendMail, showSendMailWithOptions ) where import Control.Monad ( unless ) import Data.List ( intercalate ) import System.IO ( hPutStrLn, stderr ) import System.IOExts ( evalCmd ) import System.Path ( fileInPath ) --------------------------------------------------------------------------- --- 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. --- @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] --- 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' --------------------------------------------------------------------------- -- Operations for testing and debugging. --- Shows the text (wth subject, sender, and recipient) of an email --- to be sent with the command 'sendMailWithOptions' but actually --- does not send it. --- This is useful for debugging or testing before really sending emails. --- --- @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 showSendMail :: String -> String -> String -> String -> String showSendMail from to subject = showSendMailWithOptions from subject [TO to] --- Shows the text (wth subject, sender, and recipient) of an email --- to be sent with the command 'sendMailWithOptions' but actually --- does not send it. --- This is useful for debugging or testing before really sending emails. --- --- @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 showSendMailWithOptions :: String -> String -> [MailOption] -> String -> String showSendMailWithOptions from subject options contents = unlines $ [ "From: " ++ from , "To : " ++ intercalate ", " tos ] ++ (if null ccs then [] else ["Cc : " ++ intercalate ", " ccs ]) ++ (if null bccs then [] else ["Bcc : " ++ intercalate ", " bccs]) ++ [ "Subject: " ++ subject, "", contents, "" ] where tos = [ s | TO s <- options ] ccs = [ s | CC s <- options ] bccs = [ s | BCC s <- options ] --------------------------------------------------------------------------- |