-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSmtp.hs
More file actions
48 lines (42 loc) · 1.57 KB
/
Smtp.hs
File metadata and controls
48 lines (42 loc) · 1.57 KB
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
module Smtp where
import Text.ParserCombinators.Parsec.Rfc2822 ( Message(..), GenericMessage(..), Field(..), NameAddr(..))
import Network.Socket
import Control.Exception (bracketOnError,finally)
import System.IO
import Control.Monad (forM_)
import Format
simpleMakeMessage title content from to ct=
Message [From [NameAddr (Just from) from], To [NameAddr (Just to) to], Subject title, Date ct] content
sendMail = sendSMTP
sendSMTP :: (String -> IO()) -> String -> AddrInfo -> Message -> IO()
sendSMTP logger heloDomain smtpAddr message =
bracketOnError (socket (addrFamily smtpAddr) Stream defaultProtocol)
sClose
(\sock -> do
connect sock (addrAddress smtpAddr)
socketToHandle sock ReadWriteMode
) >>= (\ h ->
(do
let Message fields _ = message
froms = map (\(NameAddr _ addr) -> addr) $
concatMap (\f -> case f of
From from -> from
_ -> []) fields
tos = map (\(NameAddr _ addr) -> addr) $
concatMap (\f ->
case f of
To to -> to
Cc to -> to
Bcc to -> to
_ -> []) fields in
forM_ [ "EHLO " ++ heloDomain
,"MAIL FROM: " ++ angleAddr (head froms) ""
, combineMessages ["RCPT TO: " ++ to | to <- tos]
, "DATA"
, formatMessage message
, "."
, "QUIT"]
$ \ line -> hPutStr h line >> hPutStr h "\r\n" >>logger line>>logger "\r\n"
hFlush h
)`finally` hClose h
)