// Package smtp provides a config wrapper around net/smtp for sending email. package smtp import ( "fmt" "net/mail" "net/smtp" ) // SMTP holds configuration for sending emails via an SMTP server. type SMTP struct { From string `yaml:"from"` Host string `yaml:"host"` Password string `yaml:"password"` Port string `yaml:"port"` User string `yaml:"user"` } // Address returns the host:port string. func (s *SMTP) Address() string { return fmt.Sprintf("%s:%s", s.Host, s.Port) } // Auth creates a PlainAuth using the configured credentials. func (s *SMTP) Auth() smtp.Auth { return smtp.PlainAuth("", s.User, s.Password, s.Host) } // Send emails the given recipients using net/smtp. // Refer to smtp.SendMail for its parameters and limitations. func (s *SMTP) Send(to []string, msg []byte) error { if err := smtp.SendMail( s.Address(), s.Auth(), s.From, to, msg, ); err != nil { return fmt.Errorf("smtp send: %w", err) } return nil } // Validate checks that all required configuration fields are set. func (s *SMTP) Validate() error { if s.From == "" { return fmt.Errorf("missing from") } if _, err := mail.ParseAddress(s.From); err != nil { return fmt.Errorf("invalid from: %w", err) } if s.Host == "" { return fmt.Errorf("missing host") } if s.Password == "" { return fmt.Errorf("missing password") } if s.Port == "" { return fmt.Errorf("missing port") } if s.User == "" { return fmt.Errorf("missing user") } return nil }