mailer.go 2.0 KB

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