You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

116 lines
2.4 KiB

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