1package gomail 2 3import ( 4 "errors" 5 "fmt" 6 "io" 7 "net/mail" 8) 9 10// Sender is the interface that wraps the Send method. 11// 12// Send sends an email to the given addresses. 13type Sender interface { 14 Send(from string, to []string, msg io.WriterTo) error 15} 16 17// SendCloser is the interface that groups the Send and Close methods. 18type SendCloser interface { 19 Sender 20 Close() error 21} 22 23// A SendFunc is a function that sends emails to the given addresses. 24// 25// The SendFunc type is an adapter to allow the use of ordinary functions as 26// email senders. If f is a function with the appropriate signature, SendFunc(f) 27// is a Sender object that calls f. 28type SendFunc func(from string, to []string, msg io.WriterTo) error 29 30// Send calls f(from, to, msg). 31func (f SendFunc) Send(from string, to []string, msg io.WriterTo) error { 32 return f(from, to, msg) 33} 34 35// Send sends emails using the given Sender. 36func Send(s Sender, msg ...*Message) error { 37 for i, m := range msg { 38 if err := send(s, m); err != nil { 39 return fmt.Errorf("gomail: could not send email %d: %v", i+1, err) 40 } 41 } 42 43 return nil 44} 45 46func send(s Sender, m *Message) error { 47 from, err := m.getFrom() 48 if err != nil { 49 return err 50 } 51 52 to, err := m.getRecipients() 53 if err != nil { 54 return err 55 } 56 57 if err := s.Send(from, to, m); err != nil { 58 return err 59 } 60 61 return nil 62} 63 64func (m *Message) getFrom() (string, error) { 65 from := m.header["Sender"] 66 if len(from) == 0 { 67 from = m.header["From"] 68 if len(from) == 0 { 69 return "", errors.New(`gomail: invalid message, "From" field is absent`) 70 } 71 } 72 73 return parseAddress(from[0]) 74} 75 76func (m *Message) getRecipients() ([]string, error) { 77 n := 0 78 for _, field := range []string{"To", "Cc", "Bcc"} { 79 if addresses, ok := m.header[field]; ok { 80 n += len(addresses) 81 } 82 } 83 list := make([]string, 0, n) 84 85 for _, field := range []string{"To", "Cc", "Bcc"} { 86 if addresses, ok := m.header[field]; ok { 87 for _, a := range addresses { 88 addr, err := parseAddress(a) 89 if err != nil { 90 return nil, err 91 } 92 list = addAddress(list, addr) 93 } 94 } 95 } 96 97 return list, nil 98} 99 100func addAddress(list []string, addr string) []string { 101 for _, a := range list { 102 if addr == a { 103 return list 104 } 105 } 106 107 return append(list, addr) 108} 109 110func parseAddress(field string) (string, error) { 111 addr, err := mail.ParseAddress(field) 112 if err != nil { 113 return "", fmt.Errorf("gomail: invalid address %q: %v", field, err) 114 } 115 return addr.Address, nil 116} 117