func New(ctx context.Context, emailConfig email.Config, smtpConfig Config) (email.Sender, error) {
	host, portStr, _ := net.SplitHostPort(smtpConfig.Address)
	port, err := strconv.Atoi(portStr)
	if err != nil {
		return nil, err
	}
	if smtpConfig.Connections == 0 {
		smtpConfig.Connections = 1
	}
	s := &SMTP{
		ctx:         ctx,
		logger:      log.FromContext(ctx).WithField("email_provider", "SMTP"),
		emailConfig: emailConfig,
		smtpConfig:  smtpConfig,
		dialer:      gomail.NewDialer(host, port, smtpConfig.Username, smtpConfig.Password),
		tasks:       make(chan sendTask, smtpConfig.Connections*buffer),
	}
	if smtpConfig.TLSConfig != nil {
		s.dialer.TLSConfig = smtpConfig.TLSConfig.Clone()
		s.dialer.TLSConfig.ServerName, _, _ = net.SplitHostPort(s.smtpConfig.Address)
	}
	for i := 0; i < smtpConfig.Connections; i++ {
		go s.handle()
	}
	return s, nil
}
New creates a SMTP email provider.
package smtp
import (
	"context"
	"net"
	"strconv"
	"go.thethings.network/lorawan-stack/v3/pkg/email"
	"go.thethings.network/lorawan-stack/v3/pkg/log"
	gomail "gopkg.in/mail.v2"
)
type sendTask struct {
	message *gomail.Message
	result  chan error
}
type SMTP struct {
	ctx         context.Context
	logger      log.Interface
	emailConfig email.Config
	smtpConfig  Config
	dialer      *gomail.Dialer
	tasks       chan sendTask
}
func (s *SMTP) handle() {
	for {
		select {
		case <-s.ctx.Done():
			return
		case task := <-s.tasks:
			task.result <- s.dialer.DialAndSend(task.message)
		}
	}
}
var buffer = 8  