package main import ( "errors" "fmt" "net/smtp" "os" "strings" "github.com/go-kit/kit/log" "github.com/go-kit/kit/log/level" "gopkg.in/ini.v1" ) // mandatory parameters to send an email type SMTPConfig struct { User string Password string Url string Port string } func NewSMTPConfig(user, password, url, port string) (SMTPConfig, error) { var config SMTPConfig if user == "" { return config, errors.New("SMTP user can't be empty") } config.User = user if password == "" { return config, errors.New("SMTP password can't be empty") } config.Password = password if url == "" { return config, errors.New("SMTP server url can't be empty") } config.Url = url if port == "" { return config, errors.New("SMTP server port can't be empty") } config.Port = port return config, nil } func (c SMTPConfig) getFullUrl() string { return fmt.Sprintf("%s:%s", c.Url, c.Port) } type Email struct { Sender string Receivers []string Subject string Content string } func NewEmail(sender string, receivers []string, subject, content string) Email { return Email{ Sender: sender, Receivers: receivers, Subject: subject, Content: content, } } func (e Email) Generate() []byte { mail := fmt.Sprintf( "To: %s\nFrom: %s\nContent-Type: text/html\nSubject: %s\n\n%s", strings.Join(e.Receivers, ","), e.Sender, e.Sender, e.Content, ) return []byte(mail) } func GetConfigPath() (string, error) { switch len(os.Args) { case 1: return "", errors.New("mailsrv must have .ini config file as first parameter") case 2: return os.Args[1], nil default: return "", errors.New("mailsrv must only have one parameter: .ini path file") } } func LoadConfig(configPath string) (SMTPConfig, error) { var config SMTPConfig configPath, err := GetConfigPath() if err != nil { return config, fmt.Errorf("unable to get the .ini config path err=%v", err) } cfg, err := ini.Load(configPath) if err != nil { return config, fmt.Errorf("unable to load the .ini config path err=%v", err) } section := cfg.Section("server") config, err = NewSMTPConfig( section.Key("username").String(), section.Key("password").String(), section.Key("url").String(), section.Key("port").String(), ) if err != nil { return config, fmt.Errorf("failed to load the SMTP configuration err=%v", err) } return config, nil } func main() { var logger log.Logger logger = log.NewLogfmtLogger(log.NewSyncWriter(os.Stderr)) logger = log.With(logger, "ts", log.DefaultTimestampUTC, "caller", log.DefaultCaller, "service", "mailsrv") configPath, err := GetConfigPath() if err != nil { level.Error(logger).Log("msg", "unable to get the .ini config path", "err", err) os.Exit(1) } config, err := LoadConfig(configPath) if err != nil { level.Error(logger).Log("msg", "unable to load the SMTP configuration", "err", err) os.Exit(1) } logger.Log("action", "send email test") content := fmt.Sprintf("Hi!

This is an e-mail test, please do not reply.

Thegux Administrator
%s", `
visit the website: thegux.fr`) email := NewEmail(config.User, []string{"receiver@receiver.com"}, "e-mail test", content) auth := smtp.PlainAuth("", config.User, config.Password, config.Url) logger.Log("action", "authentication succeed") fmt.Println(config.getFullUrl()) if err := smtp.SendMail(config.getFullUrl(), auth, email.Sender, email.Receivers, email.Generate()); err != nil { level.Error(logger).Log("msg", "error while sending email", "err", err) os.Exit(1) } logger.Log("msg", "mail send successfully") }