diff --git a/email.go b/email.go index 4c2a469..69cccd3 100644 --- a/email.go +++ b/email.go @@ -235,14 +235,83 @@ func NewMSG() *Email { } // NewSMTPClient returns the client for send email +// Deprecated: Use NewSMTPServer instead func NewSMTPClient() *SMTPServer { + return NewSMTPServer("", 0) +} + +type ServerOption func(*SMTPServer) + +func WithAuthentication(auth AuthType) ServerOption { + return func(server *SMTPServer) { + server.Authentication = auth + } +} + +func WithEncryption(encryption Encryption) ServerOption { + return func(server *SMTPServer) { + server.Encryption = encryption + } +} + +func WithUsername(username string) ServerOption { + return func(server *SMTPServer) { + server.Username = username + } +} + +func WithPassword(password string) ServerOption { + return func(server *SMTPServer) { + server.Password = password + } +} + +func WithHelo(helo string) ServerOption { + return func(server *SMTPServer) { + server.Helo = helo + } +} + +func WithConnectTimeout(timeout time.Duration) ServerOption { + return func(server *SMTPServer) { + server.ConnectTimeout = timeout + } +} + +func WithSendTimeout(timeout time.Duration) ServerOption { + return func(server *SMTPServer) { + server.SendTimeout = timeout + } +} + +func WithKeepAlive(keepAlive bool) ServerOption { + return func(server *SMTPServer) { + server.KeepAlive = keepAlive + } +} + +func WithTLSConfig(tlsConfig *tls.Config) ServerOption { + return func(server *SMTPServer) { + server.TLSConfig = tlsConfig + } +} + +// NewSMTPServer returns a new SMTPServer +func NewSMTPServer(host string, port int, opts ...ServerOption) *SMTPServer { server := &SMTPServer{ Authentication: AuthAuto, Encryption: EncryptionNone, ConnectTimeout: 10 * time.Second, SendTimeout: 10 * time.Second, Helo: "localhost", + Host: host, + Port: port, + } + + for _, opt := range opts { + opt(server) } + return server } @@ -1003,10 +1072,10 @@ func SendMessage(from string, recipients []string, msg string, client *SMTPClien // send does the low level sending of the email func send(from string, to []string, msg string, client *SMTPClient) error { - //Check if client struct is not nil + // Check if client struct is not nil if client != nil { - //Check if client is not nil + // Check if client is not nil if client.Client != nil { var smtpSendChannel chan error diff --git a/email_test.go b/email_test.go index a23b9bc..d446965 100644 --- a/email_test.go +++ b/email_test.go @@ -24,12 +24,12 @@ func TestSendRace(t *testing.T) { startService(port, responses, 5*time.Second) startService(port2, responses, 0) - server := NewSMTPClient() - server.ConnectTimeout = timeout - server.SendTimeout = timeout - server.KeepAlive = false - server.Host = `127.0.0.1` - server.Port = port + server := NewSMTPServer( + `127.0.0.1`, port, + WithConnectTimeout(timeout), + WithSendTimeout(timeout), + WithKeepAlive(false), + ) smtpClient, err := server.Connect() if err != nil { diff --git a/example/example_test.go b/example/example_test.go index c2041b0..d69ec3c 100644 --- a/example/example_test.go +++ b/example/example_test.go @@ -32,34 +32,33 @@ var ( // TestSendMailWithAttachment send a simple html email. func TestSendMail(t *testing.T) { - client := mail.NewSMTPClient() - - //SMTP Client - client.Host = host - client.Port = port - client.Username = username - client.Password = password - client.Encryption = encryptionType - client.ConnectTimeout = connectTimeout - client.SendTimeout = sendTimeout - client.KeepAlive = false - - //Connect to client - smtpClient, err := client.Connect() + // SMTP Server + server := mail.NewSMTPServer( + host, port, + mail.WithUsername(username), + mail.WithPassword(password), + mail.WithEncryption(encryptionType), + mail.WithConnectTimeout(connectTimeout), + mail.WithSendTimeout(sendTimeout), + mail.WithKeepAlive(false), + ) + + // Connect to client + smtpClient, err := server.Connect() if err != nil { t.Error("Expected nil, got", err, "connecting to client") } - //NOOP command, optional, used for avoid timeout when KeepAlive is true and you aren't sending mails. - //Execute this command each 30 seconds is ideal for persistent connection + // NOOP command, optional, used for avoid timeout when KeepAlive is true and you aren't sending mails. + // Execute this command each 30 seconds is ideal for persistent connection err = smtpClient.Noop() if err != nil { t.Error("Expected nil, got", err, "noop to client") } - //Create the email message + // Create the email message email := mail.NewMSG() email.SetFrom("From Example "). @@ -69,26 +68,26 @@ func TestSendMail(t *testing.T) { email.SetBody(mail.TextHTML, htmlBody) email.AddAlternative(mail.TextPlain, "Hello Gophers!") - //Some additional options to send + // Some additional options to send email.SetSender("xhit@test.com") email.SetReplyTo("replyto@reply.com") email.SetReturnPath("test@example.com") email.AddCc("cc@example1.com") email.AddBcc("bcccc@example2.com") - //Add inline too! + // Add inline too! email.Attach(&mail.File{FilePath: "C:/Users/sdelacruz/Pictures/Gopher.png", Inline: true}) - //Attach a file with path + // Attach a file with path email.Attach(&mail.File{FilePath: "C:/Users/sdelacruz/Pictures/Gopher.png"}) - //Attach the file with a base64 + // Attach the file with a base64 email.Attach(&mail.File{B64Data: "Zm9v", Name: "filename"}) - //Set a different date in header email + // Set a different date in header email email.SetDate("2015-04-28 10:32:00 CDT") - //Send with low priority + // Send with low priority email.SetPriority(mail.PriorityLow) // always check error after send @@ -96,10 +95,10 @@ func TestSendMail(t *testing.T) { t.Error("Expected nil, got", email.Error, "generating email") } - //Pass the client to the email message to send it + // Pass the client to the email message to send it err = email.Send(smtpClient) - //Get first error + // Get first error email.GetError() if err != nil { @@ -109,27 +108,26 @@ func TestSendMail(t *testing.T) { // TestSendMultipleEmails send multiple emails in same connection. func TestSendMultipleEmails(t *testing.T) { - client := mail.NewSMTPClient() - - //SMTP Client - client.Host = host - client.Port = port - client.Username = username - client.Password = password - client.Encryption = encryptionType - client.ConnectTimeout = connectTimeout - client.SendTimeout = sendTimeout - - //For authentication you can use AuthPlain, AuthLogin or AuthCRAMMD5 - client.Authentication = mail.AuthPlain - - //KeepAlive true because the connection need to be open for multiple emails - //For avoid inactivity timeout, every 30 second you can send a NO OPERATION command to smtp client - //use smtpClient.Client.Noop() after 30 second of inactivity in this example - client.KeepAlive = true - - //Connect to client - smtpClient, err := client.Connect() + // SMTP Server + server := mail.NewSMTPServer( + host, port, + mail.WithUsername(username), + mail.WithPassword(password), + mail.WithEncryption(encryptionType), + mail.WithConnectTimeout(connectTimeout), + mail.WithSendTimeout(sendTimeout), + + // For authentication you can use AuthPlain, AuthLogin or AuthCRAMMD5 + mail.WithAuthentication(mail.AuthPlain), + + // KeepAlive true because the connection need to be open for multiple emails + // For avoid inactivity timeout, every 30 second you can send a NO OPERATION command to smtp client + // use smtpClient.Client.Noop() after 30 second of inactivity in this example + mail.WithKeepAlive(true), + ) + + // Connect to client + smtpClient, err := server.Connect() if err != nil { t.Error("Expected nil, got", err, "connecting to client") @@ -146,18 +144,18 @@ func TestSendMultipleEmails(t *testing.T) { } func sendEmail(htmlBody string, to string, smtpClient *mail.SMTPClient) error { - //Create the email message + // Create the email message email := mail.NewMSG() email.SetFrom("From Example "). AddTo(to). SetSubject("New Go Email") - //Get from each mail + // Get from each mail email.GetFrom() email.SetBody(mail.TextHTML, htmlBody) - //Send with high priority + // Send with high priority email.SetPriority(mail.PriorityHigh) // always check error after send @@ -165,27 +163,26 @@ func sendEmail(htmlBody string, to string, smtpClient *mail.SMTPClient) error { return email.Error } - //Pass the client to the email message to send it + // Pass the client to the email message to send it return email.Send(smtpClient) } // TestWithTLS using gmail port 587. func TestWithTLS(t *testing.T) { - client := mail.NewSMTPClient() - - //SMTP Client - client.Host = "smtp.gmail.com" - client.Port = 587 - client.Username = "aaa@gmail.com" - client.Password = "asdfghh" - client.Encryption = mail.EncryptionSTARTTLS - client.ConnectTimeout = 10 * time.Second - client.SendTimeout = 10 * time.Second + // SMTP Server + server := mail.NewSMTPServer( + "smtp.gmail.com", 587, + mail.WithUsername("aaa@gmail.com"), + mail.WithPassword("asdfghh"), + mail.WithEncryption(mail.EncryptionSTARTTLS), + mail.WithConnectTimeout(10*time.Second), + mail.WithSendTimeout(10*time.Second), + ) - //KeepAlive is not settted because by default is false + // KeepAlive is not settted because by default is false - //Connect to client - smtpClient, err := client.Connect() + // Connect to client + smtpClient, err := server.Connect() if err != nil { t.Error("Expected nil, got", err, "connecting to client") @@ -199,21 +196,18 @@ func TestWithTLS(t *testing.T) { // TestWithTLS using gmail port 465. func TestWithSSL(t *testing.T) { - client := mail.NewSMTPClient() - - //SMTP Client - client.Host = "smtp.gmail.com" - client.Port = 465 - client.Username = "aaa@gmail.com" - client.Password = "asdfghh" - client.Encryption = mail.EncryptionSSLTLS - client.ConnectTimeout = 10 * time.Second - client.SendTimeout = 10 * time.Second - - //KeepAlive is not settted because by default is false - - //Connect to client - smtpClient, err := client.Connect() + // SMTP Server + server := mail.NewSMTPServer( + "smtp.gmail.com", 465, + mail.WithUsername("aaa@gmail.com"), + mail.WithPassword("asdfghh"), + mail.WithEncryption(mail.EncryptionSSLTLS), + mail.WithConnectTimeout(10*time.Second), + mail.WithSendTimeout(10*time.Second), + ) + + // Connect to client + smtpClient, err := server.Connect() if err != nil { t.Error("Expected nil, got", err, "connecting to client")