mailer.go 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. package mailer
  2. import (
  3. "fmt"
  4. "net/smtp"
  5. "strings"
  6. )
  7. type Env interface {
  8. SMTPHost() string
  9. SMTPPort() string
  10. SMTPUser() string
  11. SMTPPassword() string
  12. }
  13. type Service struct {
  14. isEnabled bool
  15. host string
  16. port string
  17. user string
  18. password string
  19. }
  20. type mailerAuth struct {
  21. username string
  22. password string
  23. }
  24. func Init(env Env) (*Service, error) {
  25. host := strings.TrimSpace(env.SMTPHost())
  26. port := strings.TrimSpace(env.SMTPPort())
  27. user := strings.TrimSpace(env.SMTPUser())
  28. password := strings.TrimSpace(env.SMTPPassword())
  29. if host == "" || port == "" || user == "" || password == "" {
  30. return &Service{}, nil
  31. }
  32. return &Service{
  33. isEnabled: true,
  34. host: host,
  35. port: port,
  36. user: user,
  37. password: password,
  38. }, nil
  39. }
  40. func (m Service) Send(recipient string, subject string, text string) error {
  41. if !m.isEnabled {
  42. return nil
  43. }
  44. msg := []byte("To: " + recipient + "\r\n" +
  45. "From: " + m.user + "\r\n" +
  46. "Subject: " + subject + "\r\n" +
  47. "Content-Type: text/plain; charset=\"UTF-8\"" + "\n\r\n" +
  48. text + "\r\n")
  49. to := []string{recipient}
  50. auth := m.GetMailerAuth(m.user, m.password)
  51. return smtp.SendMail(m.host+":"+m.port, auth, m.user, to, msg)
  52. }
  53. func (m Service) GetMailerAuth(username, password string) smtp.Auth {
  54. return &mailerAuth{username, password}
  55. }
  56. func (a *mailerAuth) Start(_ *smtp.ServerInfo) (string, []byte, error) {
  57. return "LOGIN", nil, nil
  58. }
  59. func (a *mailerAuth) Next(fromServer []byte, more bool) ([]byte, error) {
  60. command := string(fromServer)
  61. command = strings.TrimSpace(command)
  62. command = strings.TrimSuffix(command, ":")
  63. command = strings.ToLower(command)
  64. if more {
  65. if command == "username" {
  66. return []byte(a.username), nil
  67. }
  68. if command == "password" {
  69. return []byte(a.password), nil
  70. }
  71. return nil, fmt.Errorf("unexpected server challenge: %s", command)
  72. }
  73. return nil, nil
  74. }